From dc0438e910593b0ef82ea679a716170b4fb6251f Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Tue, 17 Oct 2023 07:42:10 +1100 Subject: [PATCH 1/8] Update skill selector when creating gigs to new standardised skills https://topcoder.atlassian.net/browse/TSJR-61 --- src/api/skills.js | 49 ------------------- src/api/skills.ts | 19 +++++++ src/components/Select/Select.jsx | 11 +++++ .../SkillsQuestion/SkillsQuestionBase.jsx | 33 ++++++++----- 4 files changed, 50 insertions(+), 62 deletions(-) delete mode 100644 src/api/skills.js create mode 100644 src/api/skills.ts diff --git a/src/api/skills.js b/src/api/skills.js deleted file mode 100644 index cdb90e2ef..000000000 --- a/src/api/skills.js +++ /dev/null @@ -1,49 +0,0 @@ -import { TC_API_URL } from '../config/constants' -import { axiosInstance as axios } from './requestInterceptor' - -const skillPageSize = 100 -let cachedSkillsAsPromise - -/** - * Loads and caches all the skills the first time. Returns the skills list from the cache from the second time. - */ -export function getSkills() { - cachedSkillsAsPromise = cachedSkillsAsPromise || getAllSkills().catch(ex => { - console.error('Error loading skills', ex) - cachedSkillsAsPromise = null - return [] - }) - - return cachedSkillsAsPromise -} - -/** - * Recursively loads all the pages from skills api. - */ -function getAllSkills() { - let skills = [] - - return new Promise((resolve, reject) => { - const loop = (page) => getSkillsPage(page) - .then((skillResponse) => { - skills = skills.concat(skillResponse.data) - if (skillResponse.data.length === skillPageSize) { - page++ - loop(page) - } else { - resolve(skills) - } - }) - .catch(ex => reject(ex)) - - loop(1) - }) -} - -/** - * Loads the skills in the given page. - * @param {number} page The page number to load - */ -function getSkillsPage(page) { - return axios.get(`${TC_API_URL}/v5/taas-teams/skills?perPage=${skillPageSize}&orderBy=name&page=${page}`) -} diff --git a/src/api/skills.ts b/src/api/skills.ts new file mode 100644 index 000000000..a2151dfa1 --- /dev/null +++ b/src/api/skills.ts @@ -0,0 +1,19 @@ +import _ from 'lodash' +import { TC_API_URL } from '../config/constants' +import { axiosInstance as axios } from './requestInterceptor' +import qs from 'query-string' + + +/** + * Api request for fetching skills + * + * @param {String} term search key + * + * @returns {Promise<*>} + */ +export const searchSkills = async (term) => { + const skills = await axios.get(`${TC_API_URL}/v5/emsi-skills/skills/auto-complete?${qs.stringify({ + term + })}`) + return _.get(skills, 'data', []) +} diff --git a/src/components/Select/Select.jsx b/src/components/Select/Select.jsx index 3c2e470ae..68ebeeffe 100644 --- a/src/components/Select/Select.jsx +++ b/src/components/Select/Select.jsx @@ -9,6 +9,7 @@ import React from 'react' import ReactSelect from 'react-select' import CreatableSelect from 'react-select/lib/Creatable' +import Async from 'react-select/lib/Async' import './Select.scss' const Select = (props) => { @@ -30,6 +31,16 @@ const Select = (props) => { classNamePrefix="react-select" /> ) + } else if (props.asyncOption) { + return ( + + ) } else { return ( { + searchSkills(inputValue).then( + (skills) => { + const suggestedOptions = skills.map((skillItem) => ({ + label: skillItem.name, + name: skillItem.name, + value: skillItem.id + })) + return callback(suggestedOptions) + }) + .catch(() => { + return callback(null) + }) +}, 150) /** * If `categoriesMapping` is defined - filter options using selected categories. @@ -48,13 +63,6 @@ class SkillsQuestion extends React.PureComponent { } componentWillMount() { - getSkills().then(skills => { - const options = skills.map(skill => ({ - skillId: skill.id, - name: skill.name - })) - this.updateOptions(options) - }) } componentWillReceiveProps(nextProps) { @@ -205,7 +213,7 @@ class SkillsQuestion extends React.PureComponent { />) : null}