diff --git a/src/apps/learn/src/lib/components/skill-tags/SkillTags.tsx b/src/apps/learn/src/lib/components/skill-tags/SkillTags.tsx index a869762f1..cbc54de95 100644 --- a/src/apps/learn/src/lib/components/skill-tags/SkillTags.tsx +++ b/src/apps/learn/src/lib/components/skill-tags/SkillTags.tsx @@ -5,7 +5,7 @@ import { Tooltip } from '~/libs/ui' import { EnvironmentConfig } from '~/config' import { SkillLabel } from '..' -import { TCAEMSISkillType } from '../../data-providers' +import { TCASkillType } from '../../data-providers' import styles from './SkillTags.module.scss' @@ -15,7 +15,7 @@ interface SkillTagsProps { label?: string theme?: 'white' | 'gray' | undefined skills?: Array | null | undefined - emsiSkills?: TCAEMSISkillType[] + emsiSkills?: TCASkillType[] } const SkillTags: FC = (props: SkillTagsProps) => { @@ -24,7 +24,7 @@ const SkillTags: FC = (props: SkillTagsProps) => { const label: string = props.label ?? 'skills taught' const tcaEMSIEnabled: boolean = EnvironmentConfig.ENABLE_EMSI_SKILLS || false - const skills: string[] | TCAEMSISkillType[] = tcaEMSIEnabled ? (props.emsiSkills || []) : (props.skills || []) + const skills: string[] | TCASkillType[] = tcaEMSIEnabled ? (props.emsiSkills || []) : (props.skills || []) return (
@@ -32,7 +32,7 @@ const SkillTags: FC = (props: SkillTagsProps) => { {label} )} {skills?.slice(0, expandCount) - .map((skill: string | TCAEMSISkillType) => ( + .map((skill: string | TCASkillType) => ( - emsiSkills: Array + emsiSkills: Array estimatedCompletionTimeValue: number estimatedCompletionTimeUnits: string fccCourseUuid: string diff --git a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/index.ts b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/index.ts index 13e3b668f..db94899b4 100644 --- a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/index.ts +++ b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/index.ts @@ -17,4 +17,4 @@ export * from './tca-certification-progress' export * from './tca-certification-enrollment-base.model' export * from './tca-certification-validation' export * from './tca-certification-enrollment' -export * from './tca-emsi-skill-type' +export * from './tca-skill-type' diff --git a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-certification.model.ts b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-certification.model.ts index 0661d69f6..ef6e9d0ae 100644 --- a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-certification.model.ts +++ b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-certification.model.ts @@ -5,7 +5,7 @@ import { TCACertificationCompletionTimeRange } from './tca-certification-complet import { TCACertificationProvider } from './tca-certification-provider.model' import { TCACertificationProviderBase } from './tca-certification-provider.model-base' import { TCACertificationResource } from './tca-certification-resource.model' -import { TCAEMSISkillType } from './tca-emsi-skill-type' +import { TCASkillType } from './tca-skill-type' export interface TCACertification { certificationCategory: TCACertificationCategory @@ -16,7 +16,7 @@ export interface TCACertification { createdAt: Date dashedName: string description: string - emsiSkills: Array + emsiSkills: Array id: number introText: string learnerLevel: TCACertificationLearnLevel diff --git a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-emsi-skill-type.ts b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-skill-type.ts similarity index 75% rename from src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-emsi-skill-type.ts rename to src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-skill-type.ts index 12b67f1c3..4f331194a 100644 --- a/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-emsi-skill-type.ts +++ b/src/apps/learn/src/lib/data-providers/tca-certifications-provider/tca-skill-type.ts @@ -1,4 +1,4 @@ -export type TCAEMSISkillType = { +export type TCASkillType = { assessed: boolean confidence: number emsiId: string diff --git a/src/apps/learn/src/welcome/tc-certifications/cert-card/TCCertCard.tsx b/src/apps/learn/src/welcome/tc-certifications/cert-card/TCCertCard.tsx index 014058619..e2b38ecd9 100644 --- a/src/apps/learn/src/welcome/tc-certifications/cert-card/TCCertCard.tsx +++ b/src/apps/learn/src/welcome/tc-certifications/cert-card/TCCertCard.tsx @@ -19,7 +19,7 @@ import { TCACertification, TCACertificationProgress, TCACertificationProviderBase, - TCAEMSISkillType, + TCASkillType, } from '../../../lib' import styles from './TCCertCard.module.scss' @@ -43,7 +43,7 @@ const TCCertCard: FC = (props: TCCertCardProps) => { skills: string[], providers: Array, dashedName: string - emsiSkills: TCAEMSISkillType[] + emsiSkills: TCASkillType[] } = props.certification const isEnrolled: boolean = props.progress?.status === 'enrolled' diff --git a/src/apps/onboarding/src/models/MemberInfo.ts b/src/apps/onboarding/src/models/MemberInfo.ts index 8de57ff6d..41e301d5e 100644 --- a/src/apps/onboarding/src/models/MemberInfo.ts +++ b/src/apps/onboarding/src/models/MemberInfo.ts @@ -1,5 +1,6 @@ -import { MemberEmsiSkill, MemberMaxRating } from '~/apps/talent-search/src/lib/models' +import { MemberMaxRating } from '~/apps/talent-search/src/lib/models' import { MemberStats } from '~/libs/core' +import { Skill } from '~/libs/shared' import MemberAddress from './MemberAddress' @@ -13,7 +14,7 @@ export default interface MemberInfo { email: string accountAge: number maxRating: MemberMaxRating - emsiSkills: Array + emsiSkills: Array stats: Array addresses?: MemberAddress[] country: string diff --git a/src/apps/onboarding/src/pages/skills/index.tsx b/src/apps/onboarding/src/pages/skills/index.tsx index 8d931d7b3..064e02cc7 100644 --- a/src/apps/onboarding/src/pages/skills/index.tsx +++ b/src/apps/onboarding/src/pages/skills/index.tsx @@ -16,12 +16,12 @@ export const PageSkillsContent: FC<{ }> = props => { const navigate: any = useNavigate() const [loading, setLoading] = useState(false) - const { formInput: emsiFormInput, saveSkills: saveEmsiSkills }: MemberSkillEditor = useMemberSkillEditor() + const editor: MemberSkillEditor = useMemberSkillEditor() async function saveSkills(): Promise { setLoading(true) try { - await saveEmsiSkills() + await editor.saveSkills() } catch (error) { } @@ -46,7 +46,7 @@ export const PageSkillsContent: FC<{ Understanding your skills will allow us to connect you to the right opportunities.
- {emsiFormInput} + {editor.formInput}
diff --git a/src/apps/profiles/src/member-profile/MemberProfile.context.tsx b/src/apps/profiles/src/member-profile/MemberProfile.context.tsx index 052f3562b..a27f799d0 100644 --- a/src/apps/profiles/src/member-profile/MemberProfile.context.tsx +++ b/src/apps/profiles/src/member-profile/MemberProfile.context.tsx @@ -1,11 +1,11 @@ import { createContext, FC, ReactNode, useContext, useMemo } from 'react' -import { UserEMSISkill } from '~/libs/core' +import { Skill } from '~/libs/shared' export interface MemberProfileContextValue { isTalentSearch?: boolean skillsRenderer?: ( - skills: Pick[] + skills: Pick[] ) => ReactNode } diff --git a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx index 015f2feec..cb70e6251 100644 --- a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx +++ b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx @@ -2,7 +2,7 @@ import { Dispatch, FC, SetStateAction, useEffect, useMemo, useState } from 'reac import { useSearchParams } from 'react-router-dom' import { orderBy } from 'lodash' -import { UserEMSISkill, UserProfile } from '~/libs/core' +import { UserProfile } from '~/libs/core' import { ExpandableList, HowSkillsWorkModal, isSkillVerified, Skill, SkillPill } from '~/libs/shared' import { Button } from '~/libs/ui' @@ -27,11 +27,11 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp const { skillsRenderer, isTalentSearch }: MemberProfileContextValue = useMemberProfileContext() - const memberEMSISkills: UserEMSISkill[] = useMemo(() => orderBy( + const memberSkills: Skill[] = useMemo(() => orderBy( props.profile.emsiSkills ?? [], [isSkillVerified, 'name'], ['desc', 'asc'], - ) as UserEMSISkill[], [props.profile.emsiSkills]) + ) as Skill[], [props.profile.emsiSkills]) const [isEditMode, setIsEditMode]: [boolean, Dispatch>] = useState(false) @@ -76,7 +76,7 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp

Skills

{ - canEdit && memberEMSISkills.length > 0 && ( + canEdit && memberSkills.length > 0 && ( @@ -92,22 +92,22 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp
- {skillsRenderer && memberEMSISkills.length > 0 && skillsRenderer(memberEMSISkills)} - {!skillsRenderer && memberEMSISkills.length > 0 && ( + {skillsRenderer && memberSkills.length > 0 && skillsRenderer(memberSkills)} + {!skillsRenderer && memberSkills.length > 0 && ( { - memberEMSISkills - .map(memberEMSISkill => ( + memberSkills + .map(memberSkill => ( )) } )} - {!memberEMSISkills.length && ( + {!memberSkills.length && ( = (props: MemberSkillsInfoProp )}
- {canEdit && !memberEMSISkills.length && ( + {canEdit && !memberSkills.length && ( = (props: ModifySkillsModalP const [isSaving, setIsSaving]: [boolean, Dispatch>] = useState(false) - const { formInput: emsiFormInput, saveSkills: saveEmsiSkills }: MemberSkillEditor = useMemberSkillEditor() + const editor: MemberSkillEditor = useMemberSkillEditor() function handleModifySkillsSave(): void { setIsSaving(true) - saveEmsiSkills() + editor.saveSkills() .then(() => { toast.success('Skills updated successfully.', { position: toast.POSITION.BOTTOM_RIGHT }) props.onSave() @@ -63,7 +63,7 @@ const ModifySkillsModal: FC = (props: ModifySkillsModalP Understanding your skills will allow us to connect you to the right opportunities.

- {emsiFormInput} + {editor.formInput}
diff --git a/src/apps/talent-search/src/components/popular-skills/PopularSkills.tsx b/src/apps/talent-search/src/components/popular-skills/PopularSkills.tsx index fdd256287..039cc6a4d 100644 --- a/src/apps/talent-search/src/components/popular-skills/PopularSkills.tsx +++ b/src/apps/talent-search/src/components/popular-skills/PopularSkills.tsx @@ -9,22 +9,22 @@ import styles from './PopularSkills.module.scss' // TODO: Make this configurable, or read from a service. We need to discuss // how we want to handle this. const popularSkills: Skill[] = [ - { emsiId: 'KS120076FGP5WGWYMP0F', name: 'Java (Programming Language)' }, - { emsiId: 'KS126QY605N7YVHFYCTW', name: 'MySQL' }, - { emsiId: 'KS127296VDYS7ZFWVC46', name: 'Node.js' }, - { emsiId: 'KS121F45VPV8C9W3QFYH', name: 'Cascading Style Sheets (CSS)' }, - { emsiId: 'KS1200771D9CR9LB4MWW', name: 'JavaScript (Programming Language)' }, - { emsiId: 'KS1261Z68KSKR1X31KS3', name: 'Machine Learning' }, - { emsiId: 'KS120SX72T8B5VLXS1VN', name: 'Unit Testing' }, - { emsiId: 'KS120H6772VQ0MQ5RLVD', name: 'Angular (Web Framework)' }, - { emsiId: 'KS1200B62W5ZF38RJ7TD', name: '.NET Framework' }, - { emsiId: 'KS125LS6N7WP4S6SFTCK', name: 'Python (Programming Language)' }, - { emsiId: 'KS120GZ5YXC6YVM1NGPR', name: 'Android (Operating System)' }, - { emsiId: 'ES5269FD2583B0B9875C', name: 'Figma (Design Software)' }, - { emsiId: 'KS120V86MZWV9Z9LKQY3', name: 'Microsoft Azure' }, - { emsiId: 'KS1206V6K46N1SDVJGBD', name: 'Adobe Illustrator' }, - { emsiId: 'KSY4WFI1S164RQUBSPCC', name: 'Docker (Software)' }, - { emsiId: 'KSDJCA4E89LB98JAZ7LZ', name: 'React.js' }, + { id: 'f81d2a78-ff52-4c77-8cdb-8863601b87c7', name: 'Java (Programming Language)' }, + { id: '1aabc882-c28d-4b56-8546-5e961b53bf5d', name: 'MySQL' }, + { id: 'b3181231-af8f-4a44-aff2-97fe00c57d76', name: 'Node.js' }, + { id: '4328c534-ba51-4589-a3e7-7b5ba76d2b55', name: 'Cascading Style Sheets (CSS)' }, + { id: 'e3b2b1f1-6bbf-4989-b53d-d8531a10ea5d', name: 'JavaScript (Programming Language)' }, + { id: '41ffc4d5-2e43-45e1-af36-ae7a23b47c21', name: 'Machine Learning' }, + { id: '047203fc-8c85-4be0-be0b-0e2fe11c3a16', name: 'Unit Testing' }, + { id: '8c6703bd-63dd-4f6d-9cf0-5b411e531a9f', name: 'Angular (Web Framework)' }, + { id: '34ec4bf0-0b44-4d04-9f11-e3daa2c045ce', name: '.NET Framework' }, + { id: 'a9bb69aa-edc2-4d5f-8141-de33a139f119', name: 'Python (Programming Language)' }, + { id: '67c623db-09e4-499d-800b-24868b1eb85b', name: 'Android (Operating System)' }, + { id: '36292f61-c359-42a4-89b9-95245ee494ea', name: 'Figma (Design Software)' }, + { id: 'cf39f07c-0e7a-48a2-acec-21834900c437', name: 'Microsoft Azure' }, + { id: 'b33f8342-8015-4244-afea-5fd089bf52a6', name: 'Adobe Illustrator' }, + { id: 'f21aecd2-5c67-4783-97a4-a77c67cf4f67', name: 'Docker (Software)' }, + { id: '43baf79e-3632-4b04-889a-7202cbf62a6c', name: 'React.js' }, ] interface PopularSkillsProps { @@ -41,7 +41,7 @@ const PopularSkills: FC = props => { // Either delete the value from the list, if we're toggling one that's already in the list // Or add the new item to the list props.selectedSkills.forEach(filterSkill => { - if (filterSkill.emsiId === skill.emsiId) { + if (filterSkill.id === skill.id) { deleted = true } else { newFilter.push(filterSkill) @@ -59,7 +59,7 @@ const PopularSkills: FC = props => { }, [props.onChange, props.selectedSkills]) function isSelected(skill: Skill): boolean { - return !!props.selectedSkills.find(s => s.emsiId === skill.emsiId) + return !!props.selectedSkills.find(s => s.id === skill.id) } return ( @@ -69,7 +69,7 @@ const PopularSkills: FC = props => {
{popularSkills.map(skill => ( [] + profileSkills: Pick[] queriedSkills: Skill[] } const ProfileSkillsMatch: FC = props => { const isMatchingSkill = useIsMatchingSkill(props.queriedSkills) - const matchedSkills = (props.profileSkills as unknown as EmsiSkill[]).filter(isMatchingSkill) - const unMatchedSkills = (props.profileSkills as unknown as EmsiSkill[]).filter(s => !isMatchingSkill(s)) + const matchedSkills = props.profileSkills.filter(isMatchingSkill) + const unMatchedSkills = props.profileSkills.filter(s => !isMatchingSkill(s)) const provenMatched = matchedSkills.filter(isSkillVerified) const selfSkillmatched = matchedSkills.filter(s => !isSkillVerified(s)) - const missingSkills = props.queriedSkills.filter(qs => !matchedSkills.find(ms => ms.skillId === qs.emsiId)) + const missingSkills = props.queriedSkills.filter(qs => !matchedSkills.find(ms => ms.id === qs.id)) return (
@@ -41,7 +40,7 @@ const ProfileSkillsMatch: FC = props => {
{provenMatched.map(skill => ( - + ))}
@@ -54,7 +53,7 @@ const ProfileSkillsMatch: FC = props => {
{selfSkillmatched.map(skill => ( - + ))}
@@ -82,7 +81,7 @@ const ProfileSkillsMatch: FC = props => {
{unMatchedSkills.map(skill => ( - + ))}
diff --git a/src/apps/talent-search/src/components/search-input/SearchInput.tsx b/src/apps/talent-search/src/components/search-input/SearchInput.tsx index 6dd084542..e1dcae54e 100644 --- a/src/apps/talent-search/src/components/search-input/SearchInput.tsx +++ b/src/apps/talent-search/src/components/search-input/SearchInput.tsx @@ -2,7 +2,7 @@ import { FC, MouseEvent, Ref, useMemo } from 'react' import classNames from 'classnames' import { IconOutline, InputMultiselectOption } from '~/libs/ui' -import { EmsiSkill, EmsiSkillSources, InputSkillSelector, Skill } from '~/libs/shared' +import { InputSkillSelector, Skill, SkillSources } from '~/libs/shared' import { SKILL_SEARCH_LIMIT } from '../../config' @@ -18,16 +18,16 @@ interface SearchInputProps { } const SearchInput: FC = props => { - const emsiSkills: EmsiSkill[] = useMemo(() => props.skills.map(s => ({ + const skills: Skill[] = useMemo(() => props.skills.map(s => ({ + id: s.id, name: s.name, - skillId: s.emsiId, - skillSources: [EmsiSkillSources.selfPicked], + skillSources: [SkillSources.selfPicked], })), [props.skills]) function onChange(ev: any): void { const options = (ev.target.value as unknown) as InputMultiselectOption[] props.onChange(options.map(v => ({ - emsiId: v.value, + id: v.value, name: v.label as string, }))) } @@ -41,13 +41,13 @@ const SearchInput: FC = props => { const searchIcon = useMemo(() => (
- ), [props.onSearch, emsiSkills]) + ), [props.onSearch, skills]) return (
@@ -58,13 +58,13 @@ const SearchInput: FC = props => { useWrapper={false} theme='clear' dropdownIcon={searchIcon} - value={emsiSkills} + value={skills} onChange={onChange} onSubmit={props.onSearch} inputRef={props.inputRef} limit={SKILL_SEARCH_LIMIT} /> - {emsiSkills.length >= SKILL_SEARCH_LIMIT && ( + {skills.length >= SKILL_SEARCH_LIMIT && (
{`You can only search up to ${SKILL_SEARCH_LIMIT} skills at one time`}
diff --git a/src/apps/talent-search/src/components/talent-card/TalentCard.tsx b/src/apps/talent-search/src/components/talent-card/TalentCard.tsx index f5feac5bb..0ff6a0fee 100644 --- a/src/apps/talent-search/src/components/talent-card/TalentCard.tsx +++ b/src/apps/talent-search/src/components/talent-card/TalentCard.tsx @@ -129,7 +129,7 @@ const TalentCard: FC = props => {
+0 more matched skill
{matchedSkills.length > 0 && matchedSkills.map(skill => ( diff --git a/src/apps/talent-search/src/lib/models/Member.ts b/src/apps/talent-search/src/lib/models/Member.ts index 793e5e1a6..5798a4da3 100644 --- a/src/apps/talent-search/src/lib/models/Member.ts +++ b/src/apps/talent-search/src/lib/models/Member.ts @@ -1,6 +1,7 @@ +import { Skill } from '~/libs/shared' + import { MemberDisplayName } from './MemberDisplayName' import MemberAddress from './MemberAddress' -import MemberEmsiSkill from './MemberEmsiSkill' import MemberMaxRating from './MemberMaxRating' import MemberStats from './MemberStats' @@ -12,7 +13,7 @@ export default interface Member { createdAt: number; description: string; email: string; - emsiSkills: Array ; + emsiSkills: Array ; firstName: string; handle: string; homeCountryCode: string; diff --git a/src/apps/talent-search/src/lib/models/MemberEmsiSkill.ts b/src/apps/talent-search/src/lib/models/MemberEmsiSkill.ts deleted file mode 100644 index df133b182..000000000 --- a/src/apps/talent-search/src/lib/models/MemberEmsiSkill.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { EmsiSkillSources } from '~/libs/shared' - -export default interface MemberEmsiSkill { - skillSources: EmsiSkillSources[]; - skillSubcategory: EmsiSkillSources; - skillId: string - name: string; - category: string; -} diff --git a/src/apps/talent-search/src/lib/models/index.ts b/src/apps/talent-search/src/lib/models/index.ts index f244db5b4..4179a1aca 100644 --- a/src/apps/talent-search/src/lib/models/index.ts +++ b/src/apps/talent-search/src/lib/models/index.ts @@ -1,5 +1,4 @@ export type { default as Member } from './Member' -export type { default as MemberEmsiSkill } from './MemberEmsiSkill' export type { default as MemberMaxRating } from './MemberMaxRating' export type { default as MemberStats } from './MemberStats' export { MemberDisplayName } from './MemberDisplayName' diff --git a/src/apps/talent-search/src/lib/services/use-fetch-talent-matches.ts b/src/apps/talent-search/src/lib/services/use-fetch-talent-matches.ts index a91ed3a8e..4d6f4fe13 100644 --- a/src/apps/talent-search/src/lib/services/use-fetch-talent-matches.ts +++ b/src/apps/talent-search/src/lib/services/use-fetch-talent-matches.ts @@ -23,7 +23,7 @@ export function useFetchTalentMatches( pageSize: number, ): TalentMatchesResponse { const searchParams = [ - ...skills.map(s => `skillId=${s.emsiId}`), + ...skills.map(s => `id=${s.id}`), 'sortBy=skillScore', 'includeStats=false', `page=${page}`, diff --git a/src/apps/talent-search/src/lib/utils/search-query.tsx b/src/apps/talent-search/src/lib/utils/search-query.tsx index 237d9b0f1..f93bd9eab 100644 --- a/src/apps/talent-search/src/lib/utils/search-query.tsx +++ b/src/apps/talent-search/src/lib/utils/search-query.tsx @@ -5,14 +5,14 @@ import { Skill } from '~/libs/shared' export const encodeUrlQuerySearch = (skills: Skill[]): string => ( skills - .map(s => `q=${encodeURIComponent(`${s.name}::${s.emsiId}`)}`) + .map(s => `q=${encodeURIComponent(`${s.name}::${s.id}`)}`) .join('&') ) export const parseUrlQuerySearch = (params: string[]): Skill[] => ( params.map(p => { - const [name, emsiId] = p.split('::') - return { emsiId, name } + const [name, id] = p.split('::') + return { id, name } }) ) diff --git a/src/apps/talent-search/src/lib/utils/skills.utils.tsx b/src/apps/talent-search/src/lib/utils/skills.utils.tsx index 25b373f46..772749cff 100644 --- a/src/apps/talent-search/src/lib/utils/skills.utils.tsx +++ b/src/apps/talent-search/src/lib/utils/skills.utils.tsx @@ -1,12 +1,12 @@ import { useCallback } from 'react' -import { EmsiSkill, Skill } from '~/libs/shared' +import { Skill } from '~/libs/shared' -export type IsMatchingSkillFn = (skill: EmsiSkill) => boolean +export type IsMatchingSkillFn = (skill: Pick) => boolean export const useIsMatchingSkill = (skills: Skill[]): IsMatchingSkillFn => { - const isMatchingSkill = useCallback((skill: EmsiSkill) => ( - !!skills.find(s => skill.skillId === s.emsiId) + const isMatchingSkill = useCallback((skill: Pick) => ( + !!skills.find(s => skill.id === s.id) ), [skills]) return isMatchingSkill diff --git a/src/apps/talent-search/src/routes/talent-page/TalentPage.tsx b/src/apps/talent-search/src/routes/talent-page/TalentPage.tsx index b077a0bfe..4bd1d2eb6 100644 --- a/src/apps/talent-search/src/routes/talent-page/TalentPage.tsx +++ b/src/apps/talent-search/src/routes/talent-page/TalentPage.tsx @@ -2,14 +2,14 @@ import { FC, ReactNode } from 'react' import { Location, useLocation } from 'react-router-dom' import { MemberProfileContext, MemberProfilePage } from '@profiles/member-profile' -import { UserEMSISkill } from '~/libs/core' +import { Skill } from '~/libs/shared' import { ProfileSkillsMatch } from '../../components/profile-skills-match' const TalentPage: FC = () => { const { state }: Location = useLocation() - function skillsRenderer(profileSkills: Pick[]): ReactNode { + function skillsRenderer(profileSkills: Pick[]): ReactNode { return ( ({ id: skillKey, ...data.skills[skillKey] })) - // sort by challenge verified first - .sort((a, b) => b.sources.indexOf('CHALLENGE') - a.sources.indexOf('CHALLENGE')) : undefined - - return skills -} diff --git a/src/libs/core/lib/profile/profile-functions/rating.functions.ts b/src/libs/core/lib/profile/profile-functions/rating.functions.ts index 4ee00920f..05d1c6620 100644 --- a/src/libs/core/lib/profile/profile-functions/rating.functions.ts +++ b/src/libs/core/lib/profile/profile-functions/rating.functions.ts @@ -1,7 +1,5 @@ import { CSSProperties } from 'react' -import { EMSISkillSources } from '../user-skill.model' - export const TC_RATING_COLORS: Array<{ color: string, limit: number }> = [{ color: '#555555' /* Grey */, limit: 900, @@ -32,7 +30,3 @@ export function ratingToCSScolor(rating: number): CSSProperties { color, } } - -export function isVerifiedSkill(skillOriginSources: EMSISkillSources[]): boolean { - return skillOriginSources.includes('TCACertified') || skillOriginSources.includes('ChallengeWin') -} diff --git a/src/libs/core/lib/profile/user-profile.model.ts b/src/libs/core/lib/profile/user-profile.model.ts index 63db0e186..f5ccd0e9b 100644 --- a/src/libs/core/lib/profile/user-profile.model.ts +++ b/src/libs/core/lib/profile/user-profile.model.ts @@ -1,4 +1,4 @@ -import { UserEMSISkill } from './user-skill.model' +import { UserSkill } from './user-skill.model' export type TC_TRACKS = 'DEVELOP' | 'DESIGN' | 'DATA_SCIENCE' @@ -15,7 +15,7 @@ export interface UserProfile { description: string diceEnabled: boolean email: string - emsiSkills: Array + emsiSkills: Array firstName: string handle: string handleLower: string diff --git a/src/libs/core/lib/profile/user-skill.model.ts b/src/libs/core/lib/profile/user-skill.model.ts index 2ad685542..9d454b519 100644 --- a/src/libs/core/lib/profile/user-skill.model.ts +++ b/src/libs/core/lib/profile/user-skill.model.ts @@ -1,25 +1,19 @@ -export type skillSources = 'USER_ENTERED' | 'CHALLENGE' - -export type UserSkill = { - id: number - hidden: boolean - score: number - sources: skillSources[] - tagName: string +export enum SkillSources { + selfPicked = 'SelfPicked', + challengeWin = 'ChallengeWin', + tcaCertified = 'TCACertified', } -export type EMSISkillSources = 'TCACertified' | 'SelfPicked' | 'ChallengeWin' - -export type UserEMSISkill = { +export type UserSkill = { id: string name: string - skillCategory: { + skillCategory?: { name: string id: number } - skillId: string - skillSources: Array - skillSubcategory: { + skillId?: string + skillSources?: SkillSources[] + skillSubcategory?: { name: string id: number } diff --git a/src/libs/shared/lib/components/input-skill-selector/InputSkillSelector.tsx b/src/libs/shared/lib/components/input-skill-selector/InputSkillSelector.tsx index 20f539681..a9683575d 100644 --- a/src/libs/shared/lib/components/input-skill-selector/InputSkillSelector.tsx +++ b/src/libs/shared/lib/components/input-skill-selector/InputSkillSelector.tsx @@ -3,12 +3,12 @@ import { noop } from 'lodash' import { InputMultiselect, InputMultiselectOption, InputMultiselectThemes } from '~/libs/ui' -import { autoCompleteSkills, EmsiSkill, isSkillVerified } from '../../services/emsi-skills' +import { autoCompleteSkills, isSkillVerified, Skill } from '../../services/standard-skills' -const mapEmsiSkillToInputOption = (skill: EmsiSkill): InputMultiselectOption => ({ +const mapSkillToInputOption = (skill: Skill): InputMultiselectOption => ({ ...skill, label: skill.name, - value: skill.skillId, + value: skill.id, verified: isSkillVerified(skill), }) @@ -22,7 +22,7 @@ const fetchSkills = (queryTerm: string): Promise => ( .then(skills => ( skills.map(skill => ({ label: skill.name, - value: skill.emsiId, + value: skill.id, })) )) ) @@ -35,7 +35,7 @@ interface InputSkillSelectorProps { readonly loading?: boolean readonly onChange?: (event: ChangeEvent) => void readonly placeholder?: string - readonly value?: EmsiSkill[] + readonly value?: Skill[] readonly theme?: InputMultiselectThemes readonly useWrapper?: boolean readonly dropdownIcon?: ReactNode @@ -54,7 +54,7 @@ const InputSkillSelector: FC = props => ( onFetchOptions={fetchSkills} name='skills' onChange={props.onChange ?? noop} - value={props.value?.map(mapEmsiSkillToInputOption)} + value={props.value?.map(mapSkillToInputOption)} loading={props.loading} theme={props.theme} useWrapper={props.useWrapper} diff --git a/src/libs/shared/lib/components/member-skill-editor/use-member-skill-editor.tsx b/src/libs/shared/lib/components/member-skill-editor/use-member-skill-editor.tsx index 22279a336..613683028 100644 --- a/src/libs/shared/lib/components/member-skill-editor/use-member-skill-editor.tsx +++ b/src/libs/shared/lib/components/member-skill-editor/use-member-skill-editor.tsx @@ -4,13 +4,13 @@ import { differenceWith } from 'lodash' import { profileContext, ProfileContextData } from '~/libs/core' import { - createMemberEmsiSkills, - EmsiSkill, - EmsiSkillSources, + createMemberSkills, fetchMemberSkills, isSkillVerified, - updateMemberEmsiSkills, -} from '../../services/emsi-skills' + Skill, + SkillSources, + updateMemberSkills, +} from '../../services/standard-skills' import { InputSkillSelector } from '../input-skill-selector' export interface MemberSkillEditor { @@ -22,11 +22,11 @@ export interface MemberSkillEditor { * Hook to provide functionality for using the member skill editor * Usage example: * ``` - * const { formInput: emsiFormInput, saveSkills: saveEmsiSkills }: MemberSkillEditor = useMemberSkillEditor() + * const editor: MemberSkillEditor = useMemberSkillEditor() * ... * <> - * {emsiFormInput} - * + * {editor.formInput} + * * * ``` * @returns @@ -36,31 +36,31 @@ export const useMemberSkillEditor = ({ limit, }: {limit?: number} = {}): MemberSkillEditor => { const { profile }: ProfileContextData = useContext(profileContext) - const [isEmsiInitialized, setIsEmsiInitialized] = useState(false) - const [skills, setSkills] = useState([]) + const [isInitialized, setIsInitialized] = useState(false) + const [skills, setSkills] = useState([]) const [loading, setLoading] = useState(true) const [, setError] = useState() - // Function that saves the updated emsi skills, will be called from outside + // Function that saves the updated skills, will be called from outside const saveSkills = useCallback(async () => { if (!profile?.userId) { return } - const emsiSkills = skills.map(s => ({ emsiId: s.skillId, name: s.name, sources: s.skillSources })) - if (!isEmsiInitialized) { - await createMemberEmsiSkills(profile.userId, emsiSkills) - setIsEmsiInitialized(true) + const memberSkills = skills.map(s => ({ id: s.id, name: s.name, sources: s.skillSources })) + if (!isInitialized) { + await createMemberSkills(profile.userId, memberSkills) + setIsInitialized(true) return } - await updateMemberEmsiSkills(profile.userId, emsiSkills) - }, [isEmsiInitialized, profile?.userId, skills]) + await updateMemberSkills(profile.userId, memberSkills) + }, [isInitialized, profile?.userId, skills]) // Handle user changes const handleRemoveSkill = useCallback((skillId: string): void => { - const skill = skills.find(s => s.skillId === skillId) + const skill = skills.find(s => s.id === skillId) if (!skill) { return } @@ -69,25 +69,25 @@ export const useMemberSkillEditor = ({ return } - setSkills(skills.filter(s => s.skillId !== skillId)) + setSkills(skills.filter(s => s.id !== skillId)) }, [skills]) const handleAddSkill = useCallback((skillData: any): void => { - if (skills.find(s => s.skillId === skillData.value)) { + if (skills.find(s => s.id === skillData.value)) { return } setSkills([...skills, { + id: skillData.value, name: skillData.label, - skillId: skillData.value, - skillSources: [EmsiSkillSources.selfPicked], + skillSources: [SkillSources.selfPicked], }]) }, [skills]) const handleOnChange = useCallback(({ target: { value } }: any): void => { - const removed = differenceWith(skills, value, (s, v: any) => s.skillId === v.value) + const removed = differenceWith(skills, value, (s, v: any) => s.id === v.value) if (removed.length) { - removed.map(s => handleRemoveSkill(s.skillId)) + removed.map(s => handleRemoveSkill(s.id)) } const added = differenceWith(value, skills, (v: any, s: any) => v.value === s.skillId) @@ -96,7 +96,7 @@ export const useMemberSkillEditor = ({ } }, [handleAddSkill, handleRemoveSkill, skills]) - // Load member's emsi skills, set loading state & isEmsiInitialized + // Load member's skills, set loading state & isInitialized useEffect(() => { if (!profile?.userId) { return undefined @@ -108,13 +108,13 @@ export const useMemberSkillEditor = ({ setError(e?.message ?? e) return [] }) - .then(emsiSkills => { + .then(savedSkills => { if (!mounted) { return } - setIsEmsiInitialized(emsiSkills?.length > 0) - setSkills(emsiSkills) + setIsInitialized(savedSkills?.length > 0) + setSkills(savedSkills) setLoading(false) }) diff --git a/src/libs/shared/lib/services/emsi-skills/skill.model.ts b/src/libs/shared/lib/services/emsi-skills/skill.model.ts deleted file mode 100644 index c221cb8b0..000000000 --- a/src/libs/shared/lib/services/emsi-skills/skill.model.ts +++ /dev/null @@ -1,16 +0,0 @@ -export enum EmsiSkillSources { - selfPicked = 'SelfPicked', - challengeWin = 'ChallengeWin', -} - -export interface Skill { - name: string; - emsiId: string; - skillSources?: EmsiSkillSources[]; -} - -export interface EmsiSkill { - name: string; - skillId: string; - skillSources: EmsiSkillSources[] -} diff --git a/src/libs/shared/lib/services/emsi-skills/skills.utils.ts b/src/libs/shared/lib/services/emsi-skills/skills.utils.ts deleted file mode 100644 index 8a54ee068..000000000 --- a/src/libs/shared/lib/services/emsi-skills/skills.utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { EmsiSkill, EmsiSkillSources } from './skill.model' - -export const isSkillVerified = (skill: Pick): boolean => ( - !!skill.skillSources?.includes(EmsiSkillSources.challengeWin) -) diff --git a/src/libs/shared/lib/services/index.ts b/src/libs/shared/lib/services/index.ts index ef94db4f5..b7999a344 100644 --- a/src/libs/shared/lib/services/index.ts +++ b/src/libs/shared/lib/services/index.ts @@ -1 +1 @@ -export * from './emsi-skills' +export * from './standard-skills' diff --git a/src/libs/shared/lib/services/emsi-skills/index.ts b/src/libs/shared/lib/services/standard-skills/index.ts similarity index 59% rename from src/libs/shared/lib/services/emsi-skills/index.ts rename to src/libs/shared/lib/services/standard-skills/index.ts index a80550778..97cfcafe3 100644 --- a/src/libs/shared/lib/services/emsi-skills/index.ts +++ b/src/libs/shared/lib/services/standard-skills/index.ts @@ -1,3 +1,3 @@ export * from './skill.model' -export * from './emsi-skills.service' +export * from './standard-skills.service' export * from './skills.utils' diff --git a/src/libs/shared/lib/services/standard-skills/skill.model.ts b/src/libs/shared/lib/services/standard-skills/skill.model.ts new file mode 100644 index 000000000..e70eba5e1 --- /dev/null +++ b/src/libs/shared/lib/services/standard-skills/skill.model.ts @@ -0,0 +1,2 @@ +export { SkillSources } from '~/libs/core' +export type { UserSkill as Skill } from '~/libs/core' diff --git a/src/libs/shared/lib/services/standard-skills/skills.utils.ts b/src/libs/shared/lib/services/standard-skills/skills.utils.ts new file mode 100644 index 000000000..f64e15054 --- /dev/null +++ b/src/libs/shared/lib/services/standard-skills/skills.utils.ts @@ -0,0 +1,5 @@ +import { Skill, SkillSources } from './skill.model' + +export const isSkillVerified = (skill: Pick): boolean => ( + !!skill.skillSources?.includes(SkillSources.challengeWin) +) diff --git a/src/libs/shared/lib/services/emsi-skills/emsi-skills.service.ts b/src/libs/shared/lib/services/standard-skills/standard-skills.service.ts similarity index 73% rename from src/libs/shared/lib/services/emsi-skills/emsi-skills.service.ts rename to src/libs/shared/lib/services/standard-skills/standard-skills.service.ts index 067cab1c4..a1bf91e85 100644 --- a/src/libs/shared/lib/services/emsi-skills/emsi-skills.service.ts +++ b/src/libs/shared/lib/services/standard-skills/standard-skills.service.ts @@ -1,7 +1,7 @@ import { EnvironmentConfig } from '~/config' import { xhrGetAsync, xhrPostAsync, xhrPutAsync } from '~/libs/core' -import { EmsiSkill, Skill } from './skill.model' +import { Skill } from './skill.model' const baseUrl = `${EnvironmentConfig.API.V5}/emsi-skills/member-emsi-skills` @@ -20,20 +20,20 @@ export type FetchMemberSkillsConfig = { export async function fetchMemberSkills( userId: string | number | undefined, config: FetchMemberSkillsConfig, -): Promise { +): Promise { const url = `${baseUrl}/${userId}?pageFlag=${!config.skipPagination}` return xhrGetAsync(url) } -export async function createMemberEmsiSkills(userId: number, skills: Skill[]): Promise { +export async function createMemberSkills(userId: number, skills: Skill[]): Promise { return xhrPostAsync(baseUrl, { - emsiSkills: skills, + skills, userId, }) } -export async function updateMemberEmsiSkills(userId: string | number, skills: Skill[]): Promise { +export async function updateMemberSkills(userId: string | number, skills: Skill[]): Promise { return xhrPutAsync(`${baseUrl}/${userId}`, { - emsiSkills: skills, + skills, }) }