Skip to content

Commit e4bb311

Browse files
committed
TSJR-314 - minor skills admin fixes
1 parent 6c7a4ca commit e4bb311

File tree

10 files changed

+66
-16
lines changed

10 files changed

+66
-16
lines changed

src/apps/admin/src/skills-manager/components/accordion/accordion-item/AccordionItem.module.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
margin-right: $sp-2;
1818
}
1919

20+
.menuIcon {
21+
color: $turq-120;
22+
}
23+
2024
.titleBar {
2125
display: flex;
2226
align-items: center;

src/apps/admin/src/skills-manager/components/accordion/accordion-item/AccordionItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const AccordionItem: FC<AccordionItemProps> = props => {
4747
onAction={props.onMenuAction}
4848
className={styles.menu}
4949
>
50-
<IconOutline.DotsVerticalIcon className='icon-lg' />
50+
<IconOutline.DotsVerticalIcon className={classNames('icon-lg', styles.menuIcon)} />
5151
</ActionsMenu>
5252
)}
5353
</div>

src/apps/admin/src/skills-manager/components/bulk-editor/archive-skills-modal/ArchiveSkillsModal.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FC, useState } from 'react'
1+
import { FC, useEffect, useState } from 'react'
22

33
import { BaseModal, Button, LoadingSpinner } from '~/libs/ui'
44

@@ -29,6 +29,12 @@ const ArchiveSkillsModal: FC<ArchiveSkillsModalProps> = props => {
2929
props.onClose()
3030
}
3131

32+
useEffect(() => {
33+
if (!props.skills.length) {
34+
props.onClose.call(undefined)
35+
}
36+
}, [props.onClose, props.skills])
37+
3238
return (
3339
<BaseModal
3440
onClose={props.onClose}

src/apps/admin/src/skills-manager/components/bulk-editor/move-skills-modal/MoveSkillsModal.tsx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import { ChangeEvent, FC, useMemo, useState } from 'react'
1+
import { ChangeEvent, FC, useEffect, useMemo, useState } from 'react'
22
import { noop } from 'lodash'
3+
import { toast } from 'react-toastify'
34

45
import { BaseModal, Button, InputSelectReact, LoadingSpinner } from '~/libs/ui'
56

67
import { SkillsManagerContextValue, useSkillsManagerContext } from '../../../context'
7-
import { bulkUpdateStandardizedSkills, StandardizedSkill } from '../../../services'
8+
import {
9+
bulkUpdateStandardizedSkills,
10+
saveStandardizedSkillCategory,
11+
StandardizedSkill,
12+
StandardizedSkillCategory,
13+
} from '../../../services'
814
import { mapCategoryToSelectOption } from '../../../lib'
915
import { SkillsList } from '../../skills-list'
1016

@@ -21,6 +27,7 @@ const MoveSkillsModal: FC<MoveSkillsModalProps> = props => {
2127

2228
const {
2329
bulkEditorCtx: context,
30+
refetchCategories,
2431
categories,
2532
}: SkillsManagerContextValue = useSkillsManagerContext()
2633

@@ -45,6 +52,26 @@ const MoveSkillsModal: FC<MoveSkillsModalProps> = props => {
4552
props.onClose()
4653
}
4754

55+
async function handleNewCategory(categoryName: string): Promise<void> {
56+
setIsLoading(true)
57+
58+
const newCategory = await saveStandardizedSkillCategory(
59+
{ description: ' ', name: categoryName } as StandardizedSkillCategory,
60+
)
61+
62+
refetchCategories()
63+
64+
setCategoryId(newCategory.id)
65+
toast.success(`Category with name '${categoryName}' created!`)
66+
setIsLoading(false)
67+
}
68+
69+
useEffect(() => {
70+
if (!props.skills.length) {
71+
props.onClose.call(undefined)
72+
}
73+
}, [props.onClose, props.skills])
74+
4875
return (
4976
<BaseModal
5077
onClose={props.onClose}
@@ -91,12 +118,16 @@ const MoveSkillsModal: FC<MoveSkillsModalProps> = props => {
91118
<h2>To:</h2>
92119
</div>
93120
<InputSelectReact
121+
creatable
94122
label='Skill Category'
95123
placeholder='Select category'
96124
options={categoryOptions}
97-
value={categoryId}
98-
name='to'
125+
name='categoryTo'
99126
onChange={handleCategoryChange}
127+
createLabel={function label(v: string) { return `Create new category "${v}"` }}
128+
onCreateOption={handleNewCategory}
129+
value={categoryId}
130+
tabIndex={0}
100131
/>
101132
</div>
102133

src/apps/admin/src/skills-manager/components/bulk-editor/replace-skills-modal/ReplaceSkillsModal.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeEvent, FC, useState } from 'react'
1+
import { ChangeEvent, FC, useEffect, useState } from 'react'
22
import { find } from 'lodash'
33

44
import { BaseModal, Button, InputRadio, LoadingSpinner } from '~/libs/ui'
@@ -50,6 +50,12 @@ const ReplaceSkillsModal: FC<ReplaceSkillsModalProps> = props => {
5050
setType(t)
5151
}
5252

53+
useEffect(() => {
54+
if (!props.skills.length) {
55+
props.onClose.call(undefined)
56+
}
57+
}, [props.onClose, props.skills])
58+
5359
return (
5460
<BaseModal
5561
onClose={props.onClose}

src/apps/admin/src/skills-manager/components/category-modal/CategoryModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const CategoryModal: FC<CategoryModalProps> = props => {
5757
toast.success(`Category ${props.category.name} archived successfully!`)
5858
})
5959
.catch((e: any) => {
60-
setError(e.message)
60+
setError((e.message ?? '').replace(/with id [a-z0-9-]+/i, ''))
6161
setLoading(false)
6262
return Promise.reject(e)
6363
})

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { find } from 'lodash'
1+
import { escapeRegExp } from 'lodash'
22

33
import { customValidatorRequired, FormDefinition, InputValue } from '~/libs/ui'
44

@@ -16,7 +16,8 @@ export const validateUniqueCategoryName = (
1616
category: StandardizedSkillCategory,
1717
) => (
1818
(value: InputValue): string | undefined => {
19-
const match = find(categories, { name: value }) as StandardizedSkillCategory | undefined
19+
const filterRegex = new RegExp(`^${escapeRegExp((value as string || '').trim())}$`, 'i')
20+
const match = categories.find(cat => filterRegex.test(cat.name))
2021
return match && match.id !== category.id
2122
? 'A category with the same name already exists!' : undefined
2223
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const SkillModal: FC<SkillModalProps> = props => {
6161
}, [props.skill.id, refetchSkills, setEditSkill, action])
6262

6363
const addAnother = useCallback(async (): Promise<void> => {
64-
setTimeout(setEditSkill, 100, {} as StandardizedSkill)
64+
setTimeout(setEditSkill, 750, {} as StandardizedSkill)
6565
}, [setEditSkill])
6666

6767
const archiveSkill = useCallback(async (): Promise<void> => {
@@ -95,7 +95,7 @@ const SkillModal: FC<SkillModalProps> = props => {
9595
.then(() => {
9696
refetchSkills()
9797
setEditSkill()
98-
toast.success(`Skill ${props.skill.name} archived successfully!`)
98+
toast.success(`Skill ${props.skill.name} restored successfully!`)
9999
})
100100
.catch((e: any) => {
101101
setIsLoading(false)

src/apps/admin/src/skills-manager/components/skill-modals/skill-form/SkillForm.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ChangeEvent, FC, ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
2-
import { find, pick } from 'lodash'
2+
import { escapeRegExp, pick } from 'lodash'
33
import { toast } from 'react-toastify'
44

55
import { Button, FormInputAutocompleteOption, InputSelectReact, InputText, InputTextarea } from '~/libs/ui'
@@ -67,8 +67,10 @@ const SkillForm: FC<SkillFormProps> = props => {
6767
function validateName(): void {
6868
const name = formValue.name?.trim() ?? ''
6969
const isValid = name.length > 0
70-
const similarSkill = find(skillsList, { name })
71-
const isDuplicate = similarSkill && similarSkill.id !== props.skill?.id
70+
const filterRegex = new RegExp(`^${escapeRegExp(name)}$`, 'i')
71+
const similarSkill = skillsList.find(skill => filterRegex.test(skill.name))
72+
const isDuplicate = !!similarSkill && similarSkill.id !== props.skill?.id
73+
7274
const error = !isValid ? 'Skill name is required!' : (
7375
isDuplicate ? 'A skill with the same name already exists!' : undefined
7476
)

src/libs/ui/lib/components/form/form-groups/form-input/input-textarea/InputTextarea.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const InputTextarea: FC<InputTextareaProps> = (props: InputTextareaProps) => (
3535
<textarea
3636
autoComplete={props.autocomplete}
3737
className={styles['form-input-textarea']}
38-
defaultValue={props.value}
38+
value={props.value ?? ''}
3939
disabled={!!props.disabled}
4040
name={props.name}
4141
onBlur={props.onBlur}

0 commit comments

Comments
 (0)