Skip to content

Commit 498d687

Browse files
committed
TSJR-314 - edit existing skill
1 parent be2ebd0 commit 498d687

File tree

12 files changed

+96
-39
lines changed

12 files changed

+96
-39
lines changed

src/apps/admin/src/skills-manager/components/categories-accordion/CategoriesAccordion.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FC } from 'react'
1+
import { FC, useMemo } from 'react'
22

33
import { Accordion, AccordionItem } from '../accordion'
44
import { SkillsList } from '../skills-list'
@@ -12,6 +12,7 @@ interface CategoriesAccordionProps {
1212

1313
const CategoriesAccordion: FC<CategoriesAccordionProps> = props => {
1414
const {
15+
setEditSkill,
1516
skillsFilter,
1617
setEditCategory,
1718
categories,
@@ -50,19 +51,29 @@ const CategoriesAccordion: FC<CategoriesAccordionProps> = props => {
5051
onSelect={bulkEditorCtx.toggleSkill}
5152
isSelected={bulkEditorCtx.isSkillSelected}
5253
editMode={!!bulkEditorCtx.isEditing}
54+
onEditSkill={setEditSkill}
5355
/>
5456
)}
5557
</AccordionItem>
5658
) : <></>
5759
}
5860

61+
// use a memo to persist the items rendering
62+
// otheriwse, the order and mapping of the categories
63+
// will trigger a new re-render of the accordion on each context change
64+
const accordionItems = useMemo(() => (
65+
!!bulkEditorCtx.isEditing ? (
66+
renderCategoryAccordion(bulkEditorCtx.isEditing)
67+
) : (
68+
categories
69+
.map(renderCategoryAccordion)
70+
)
71+
// eslint-disable-next-line react-hooks/exhaustive-deps
72+
), [bulkEditorCtx.isEditing, categories, groupedSkills])
73+
5974
return (
6075
<Accordion defaultOpen={props.defaultOpen}>
61-
{!!bulkEditorCtx.isEditing ? (
62-
renderCategoryAccordion(bulkEditorCtx.isEditing)
63-
) : (
64-
categories.map(renderCategoryAccordion)
65-
)}
76+
{accordionItems}
6677
</Accordion>
6778
)
6879
}

src/apps/admin/src/skills-manager/components/skill-modal/SkillModal.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { FC, ReactNode, useCallback, useMemo, useState } from 'react'
22

33
import { BaseModal, Form, formGetInputModel, FormInputModel, FormValue, LoadingSpinner } from '~/libs/ui'
44

5-
import { saveStandardizedSkill, StandardizedSkill, StandardizedSkillCategory } from '../../services'
5+
import {
6+
archiveStandardizedSkill,
7+
saveStandardizedSkill,
8+
StandardizedSkill,
9+
StandardizedSkillCategory,
10+
} from '../../services'
611

712
import { skillFormDef, SkillFormField } from './skill-form.config'
813

@@ -23,6 +28,7 @@ const SkillModal: FC<SkillModalProps> = props => {
2328
description: formGetInputModel(inputs, SkillFormField.description).value as string,
2429
id: props.skill.id as string,
2530
name: formGetInputModel(inputs, SkillFormField.name).value as string,
31+
// eslint-disable-next-line react-hooks/exhaustive-deps
2632
}), [])
2733

2834
const saveAsync = useCallback(async (request: FormValue): Promise<void> => {
@@ -39,16 +45,37 @@ const SkillModal: FC<SkillModalProps> = props => {
3945
})
4046
}, [props.onClose, props.onSave])
4147

48+
const archiveSkill = useCallback(async (): Promise<void> => {
49+
setLoading(true)
50+
51+
return archiveStandardizedSkill(props.skill)
52+
.then(() => {
53+
props.onSave.call(undefined)
54+
props.onClose.call(undefined)
55+
})
56+
.catch((e: any) => {
57+
setLoading(false)
58+
return Promise.reject(e)
59+
})
60+
}, [props.onClose, props.skill, props.onSave])
61+
4262
const formDef = useMemo(() => skillFormDef(
63+
action,
64+
archiveSkill,
4365
props.onClose,
4466
props.categories,
45-
), [props.categories, props.onClose])
67+
), [action, archiveSkill, props.categories, props.onClose])
68+
69+
const formValue = useMemo(() => ({
70+
...(props.skill as any),
71+
categoryId: props.skill.category.id,
72+
} as FormValue), [props.skill])
4673

4774
function renderForm(): ReactNode {
4875
return (
4976
<Form
5077
formDef={formDef}
51-
formValues={props.skill as unknown as FormValue}
78+
formValues={formValue}
5279
requestGenerator={generateRequest}
5380
save={saveAsync}
5481
resetFormOnUnmount

src/apps/admin/src/skills-manager/components/skill-modal/skill-form.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const mapCategoryToSelectOption = (categories: StandardizedSkillCategory[]): Inp
1313
)
1414

1515
export const skillFormDef = (
16+
action: string,
17+
onArchiveClick: () => void,
1618
onCancelClick: () => void,
1719
categories?: StandardizedSkillCategory[],
1820
): FormDefinition => ({
@@ -26,6 +28,13 @@ export const skillFormDef = (
2628
size: 'lg',
2729
type: 'button',
2830
},
31+
{
32+
buttonStyle: 'secondary',
33+
isSubmit: true,
34+
label: 'Save and add another',
35+
size: 'lg',
36+
type: 'submit',
37+
},
2938
{
3039
buttonStyle: 'primary',
3140
isSubmit: true,
@@ -34,6 +43,17 @@ export const skillFormDef = (
3443
type: 'submit',
3544
},
3645
],
46+
secondaryGroup: action === 'edit' && [
47+
{
48+
buttonStyle: 'secondary',
49+
isSubmit: false,
50+
label: 'Archive skill',
51+
onClick: onArchiveClick,
52+
size: 'lg',
53+
type: 'button',
54+
variant: 'danger',
55+
},
56+
],
3757
},
3858
groups: [
3959
{

src/apps/admin/src/skills-manager/components/skills-list/SkillsList.module.scss

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
align-items: center;
1616
gap: $sp-2;
1717

18-
.isEditMode & {
19-
cursor: pointer;
18+
cursor: pointer;
19+
transition: 0.15s ease-in-out;
20+
21+
&:hover {
22+
background: rgba($tc-black, 0.075);
2023
}
2124
}

src/apps/admin/src/skills-manager/components/skills-list/SkillsList.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ interface SkillsListProps {
1313
editMode?: boolean
1414
onSelect: (skill: StandardizedSkill) => void
1515
isSelected: (skill: StandardizedSkill) => boolean
16+
onEditSkill?: (skill: StandardizedSkill) => void
1617
}
1718

1819
const SkillsList: FC<SkillsListProps> = props => {
1920
function handleToggle(skill: StandardizedSkill): void {
2021
if (!props.editMode) {
22+
props.onEditSkill?.(skill)
2123
return
2224
}
2325

src/apps/admin/src/skills-manager/context/skills-manager.context.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { createContext, FC, ReactNode, useCallback, useContext, useMemo, useState } from 'react'
2-
import { orderBy } from 'lodash'
32
import { SWRResponse } from 'swr'
43

54
import { StandardizedSkill, StandardizedSkillCategory, useFetchCategories, useFetchSkills } from '../services'
@@ -43,7 +42,7 @@ export const SkillsManagerContext: FC<SkillsManagerContextProps> = props => {
4342
}: SWRResponse<StandardizedSkill[]> = useFetchSkills()
4443

4544
const {
46-
data: allCategories,
45+
data: allCategories = [],
4746
mutate: refetchCategories,
4847
}: SWRResponse<StandardizedSkillCategory[]> = useFetchCategories()
4948

@@ -58,7 +57,7 @@ export const SkillsManagerContext: FC<SkillsManagerContextProps> = props => {
5857

5958
const contextValue = useMemo(() => ({
6059
bulkEditorCtx,
61-
categories: orderBy(allCategories ?? [], 'name', 'asc'),
60+
categories: allCategories,
6261
editCategory,
6362
editSkill,
6463
groupedSkills,

src/apps/admin/src/skills-manager/context/use-skills.context.tsx

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/apps/admin/src/skills-manager/services/skills-categories.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const baseUrl = `${EnvironmentConfig.API.V5}/standardized-skills/categories`
99
export interface StandardizedSkillCategory extends UserSkillCategory {}
1010

1111
export const useFetchCategories = (): SWRResponse<StandardizedSkillCategory[]> => {
12-
const url = `${baseUrl}?perPage=9999`
12+
const url = `${baseUrl}?perPage=9999&sortBy=name`
1313

1414
const response = useSWR(url, xhrGetAsync<StandardizedSkillCategory[]>, {
1515
refreshInterval: 0,

src/apps/admin/src/skills-manager/services/skills.service.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { omit } from 'lodash'
22
import useSWR, { SWRResponse } from 'swr'
33

44
import { EnvironmentConfig } from '~/config'
5-
import { UserSkill, xhrGetAsync, xhrPostAsync, xhrPutAsync } from '~/libs/core'
5+
import { UserSkill, xhrDeleteAsync, xhrGetAsync, xhrPostAsync, xhrPutAsync } from '~/libs/core'
66

77
const baseUrl = `${EnvironmentConfig.API.V5}/standardized-skills/skills`
88

@@ -19,10 +19,15 @@ export const useFetchSkills = (): SWRResponse<StandardizedSkill[]> => {
1919
return response
2020
}
2121

22-
export const saveStandardizedSkill = (category: StandardizedSkill)
23-
: Promise<StandardizedSkill> => {
24-
const xhrSaveAsyncFn = category.id ? xhrPutAsync : xhrPostAsync
25-
const url = `${baseUrl}${category.id ? `/${category.id}` : ''}`
22+
export const saveStandardizedSkill = (skill: StandardizedSkill): Promise<StandardizedSkill> => {
23+
const xhrSaveAsyncFn = skill.id ? xhrPutAsync : xhrPostAsync
24+
const url = `${baseUrl}${skill.id ? `/${skill.id}` : ''}`
2625

27-
return xhrSaveAsyncFn(url, omit(category, 'id'))
26+
return xhrSaveAsyncFn(url, omit(skill, 'id'))
27+
}
28+
29+
export const archiveStandardizedSkill = (skill: StandardizedSkill): Promise<StandardizedSkill> => {
30+
const url = `${baseUrl}/${skill.id}`
31+
32+
return xhrDeleteAsync(url)
2833
}

src/libs/ui/lib/components/button/base-button/BaseButton.module.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ $btn-secondary-border-width: $border;
5353

5454
// Define variants
5555
&:global(.btn-variant-danger) {
56-
--btn-variant: #{$red-110};
57-
--btn-variant--hover: #{lighten($red-110, 10%)};
58-
--btn-variant--active: #{darken($red-110, 10%)};
56+
--btn-variant: #{$red-120};
57+
--btn-variant--hover: #{lighten($red-120, 10%)};
58+
--btn-variant--active: #{darken($red-120, 10%)};
5959
}
6060
&:global(.btn-variant-warning) {
6161
--btn-variant: #{$orange-140};

0 commit comments

Comments
 (0)