diff --git a/src/api/skills.js b/src/api/skills.js new file mode 100644 index 000000000..aa5cc4529 --- /dev/null +++ b/src/api/skills.js @@ -0,0 +1,49 @@ +import { TC_API_URL, SKILL_PROVIDER_ID } 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/skills?skillProviderId=${SKILL_PROVIDER_ID}&perPage=${skillPageSize}&orderBy=name&page=${page}`) +} diff --git a/src/projects/detail/components/SkillsQuestion/SkillsQuestionBase.jsx b/src/projects/detail/components/SkillsQuestion/SkillsQuestionBase.jsx index 684f11c0a..2c99acac5 100644 --- a/src/projects/detail/components/SkillsQuestion/SkillsQuestionBase.jsx +++ b/src/projects/detail/components/SkillsQuestion/SkillsQuestionBase.jsx @@ -3,11 +3,8 @@ import _ from 'lodash' import SkillsCheckboxGroup from './SkillsCheckboxGroup' import Select from '../../../../components/Select/Select' import './SkillsQuestion.scss' -import { axiosInstance as axios } from '../../../../api/requestInterceptor' -import { TC_API_URL, SKILL_PROVIDER_ID } from '../../../../config/constants' import { createFilter } from 'react-select' - -let cachedOptions +import { getSkills } from '../../../../api/skills' /** * If `categoriesMapping` is defined - filter options using selected categories. @@ -42,7 +39,7 @@ class SkillsQuestion extends React.PureComponent { constructor(props) { super(props) this.state = { - options: cachedOptions || [], + options: [], availableOptions: [], customOptionValue: '', } @@ -51,20 +48,13 @@ class SkillsQuestion extends React.PureComponent { } componentWillMount() { - if (!cachedOptions) { - axios.get(`${TC_API_URL}/v5/skills?skillProviderId=${SKILL_PROVIDER_ID}&perPage=100&orderBy=name`) - .then(resp => { - const options = _.get(resp, 'data', []) - - cachedOptions = options.map((option) => ({ - skillId: option.id, - name: option.name - })) - this.updateOptions(cachedOptions) - }) - } else { - this.updateOptions(cachedOptions) - } + getSkills().then(skills => { + const options = skills.map(skill => ({ + skillId: skill.id, + name: skill.name + })) + this.updateOptions(options) + }) } componentWillReceiveProps(nextProps) {