Passed
Push — feature/application-skill-info... ( 1281e5...2fe4a1 )
by Chris
03:52
created

resources/assets/js/components/Application/Skills/SkillsHelpers.ts   A

Complexity

Total Complexity 7
Complexity/F 0

Size

Lines of Code 99
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 7
eloc 67
mnd 7
bc 7
fnc 0
dl 0
loc 99
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import { Criteria, ExperienceSkill, Skill } from "../../../models/types";
2
import { mapToObject, getId, hasKey } from "../../../helpers/queries";
3
import { IconStatus } from "../../StatusIcon";
4
5
export const getSkillOfCriteria = (
6
  criterion: Criteria,
7
  skills: Skill[],
8
): Skill | null => {
9
  const skillsById = mapToObject(skills, getId);
10
  return hasKey(skillsById, criterion.skill_id)
11
    ? skillsById[criterion.skill_id]
12
    : null;
13
};
14
15
export const getExperiencesOfSkill = (
16
  skill: Skill,
17
  experiences: ExperienceSkill[],
18
): ExperienceSkill[] =>
19
  experiences.filter((experience) => experience.skill_id === skill.id);
20
21
export interface SkillStatus {
22
  [x: string]: {
23
    experiences: {
24
      [k: string]: IconStatus;
25
    };
26
  };
27
}
28
29
export const initialStatus = (experiences: ExperienceSkill[]): SkillStatus =>
30
  experiences.reduce((status, experience: ExperienceSkill) => {
31
    if (!status[experience.skill_id]) {
32
      status[experience.skill_id] = {
33
        experiences: {
34
          [experience.experience_id]: IconStatus.DEFAULT,
35
        },
36
      };
37
    }
38
39
    status[experience.skill_id].experiences[experience.experience_id] =
40
      IconStatus.DEFAULT;
41
    return status;
42
  }, {});
43
44
/**
45
 * Return the IconStatus for the Skill based on the defined statuses of all
46
 * the nested experiences. The possibilities are COMPLETE, ERROR and DEFAULT.
47
 * If one experience has an ERROR, that will be returned. If all experiences are
48
 * COMPLETE, that will be returned. Otherwise, DEFAULT will be returned.
49
 *
50
 * @param statusShape Provided state object containing all statuses for all skills.
51
 * @param skillId Skill ID for the particular skill to check.
52
 *
53
 * @returns IconStatus
54
 */
55
export const computeParentStatus = (
56
  statusShape: SkillStatus,
57
  skillId: number,
58
): IconStatus => {
59
  if (statusShape[skillId]) {
60
    const skillStatus = statusShape[skillId];
61
    let errorCount = 0;
62
    let completeCount = 0;
63
    Object.values(skillStatus.experiences).forEach((experience) => {
64
      if (experience === IconStatus.ERROR) {
65
        errorCount += 1;
66
      }
67
      if (experience === IconStatus.COMPLETE) {
68
        completeCount += 1;
69
      }
70
    });
71
72
    if (errorCount > 0) {
73
      return IconStatus.ERROR;
74
    }
75
    if (completeCount === Object.values(skillStatus.experiences).length) {
76
      return IconStatus.COMPLETE;
77
    }
78
  }
79
80
  return IconStatus.DEFAULT;
81
};
82
83
export const statusReducer = (
84
  state: SkillStatus,
85
  action: {
86
    payload: { skillId: number; experienceId: number; status: IconStatus };
87
  },
88
): SkillStatus => {
89
  return {
90
    ...state,
91
    [action.payload.skillId]: {
92
      experiences: {
93
        ...state[action.payload.skillId].experiences,
94
        [action.payload.experienceId]: action.payload.status,
95
      },
96
    },
97
  };
98
};
99