From 4cb819c6e003120d759984471ad5505e3defb7ff Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 08:20:43 -0600 Subject: [PATCH 01/11] Initial transition of member skill data structure. Something is not right with my flyway migration. --- .../services/member_skill/MemberSkill.java | 25 +++-- .../member_skill/MemberSkillController.java | 6 +- .../member_skill/MemberSkillCreateDTO.java | 3 +- .../V119__alter_member_skills_table.sql | 11 +++ .../resources/db/dev/R__Load_testing_data.sql | 5 + web-ui/src/components/skills/SkillLevel.css | 6 ++ web-ui/src/components/skills/SkillLevel.jsx | 95 +++++++++++++++++++ web-ui/src/components/skills/SkillSection.jsx | 74 ++++++++++----- 8 files changed, 185 insertions(+), 40 deletions(-) create mode 100644 server/src/main/resources/db/common/V119__alter_member_skills_table.sql create mode 100644 web-ui/src/components/skills/SkillLevel.css create mode 100644 web-ui/src/components/skills/SkillLevel.jsx diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java index 6158ec8a7e..c8de6139e4 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java @@ -54,25 +54,20 @@ public class MemberSkill { @Schema(description = "the last used date of the skill") private LocalDate lastuseddate; - public MemberSkill() { - } + @Column(name="interested") + @TypeDef(type = DataType.BOOLEAN) + @Schema(description = "the member interest") + private boolean interested; - public MemberSkill(UUID memberid, UUID skillid) { - this.memberid = memberid; - this.skillid = skillid; - } - - public MemberSkill(UUID id, UUID memberid, UUID skillid) { - this.id = id; - this.memberid = memberid; - this.skillid = skillid; + public MemberSkill() { } - public MemberSkill(UUID memberid, UUID skillid, String skilllevel, LocalDate lastuseddate) { + public MemberSkill(UUID memberid, UUID skillid, String skilllevel, LocalDate lastuseddate, boolean interested) { this.memberid = memberid; this.skillid = skillid; this.skilllevel = skilllevel; this.lastuseddate = lastuseddate; + this.interested = interested; } @Override @@ -84,12 +79,13 @@ public boolean equals(Object o) { Objects.equals(memberid, that.memberid) && Objects.equals(skillid, that.skillid) && Objects.equals(skilllevel, that.skilllevel) && - Objects.equals(lastuseddate, that.lastuseddate); + Objects.equals(lastuseddate, that.lastuseddate) && + Objects.equals(interested, that.interested); } @Override public int hashCode() { - return Objects.hash(id, memberid, skillid, skilllevel, lastuseddate); + return Objects.hash(id, memberid, skillid, skilllevel, lastuseddate, interested); } @Override @@ -100,6 +96,7 @@ public String toString() { ", skillid=" + skillid + '\'' + ", skilllevel=" + skilllevel + '\'' + ", lastuseddate=" + lastuseddate + + ", interested=" + interested + '}'; } } diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java index fbd76f7558..4a7ae5fff5 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java @@ -45,7 +45,11 @@ public MemberSkillController(MemberSkillServices memberSkillServices) { @Post public HttpResponse createAMemberSkill(@Body @Valid @NotNull MemberSkillCreateDTO memberSkill, HttpRequest request) { MemberSkill createdMemberSkill = memberSkillsService.save( - new MemberSkill(memberSkill.getMemberid(), memberSkill.getSkillid(), memberSkill.getSkilllevel(), memberSkill.getLastuseddate()) + new MemberSkill(memberSkill.getMemberid(), + memberSkill.getSkillid(), + memberSkill.getSkilllevel(), + memberSkill.getLastuseddate(), + memberSkill.interested) ); return HttpResponse.created(createdMemberSkill) .headers(headers -> headers.location(URI.create(String.format("%s/%s", request.getPath(), createdMemberSkill.getId())))); diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java index 4ba04d4a3f..5f7dbd9890 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java @@ -26,7 +26,8 @@ public class MemberSkillCreateDTO { private String skilllevel; @Schema(description = "the last used date of the skill") - private LocalDate lastuseddate; + @Schema(description = "the member interest") + public boolean interested; } diff --git a/server/src/main/resources/db/common/V119__alter_member_skills_table.sql b/server/src/main/resources/db/common/V119__alter_member_skills_table.sql new file mode 100644 index 0000000000..dc6855e4ab --- /dev/null +++ b/server/src/main/resources/db/common/V119__alter_member_skills_table.sql @@ -0,0 +1,11 @@ +ALTER TABLE member_skills ADD COLUMN interested boolean DEFAULT false; + +-- If the original skilllevel was 'interested', set the new column value to true +UPDATE member_skills SET interested = true WHERE skilllevel = '1'; + +-- Transition old skill levels to the new range +UPDATE member_skills SET skilllevel = '0' WHERE skilllevel = '1'; +UPDATE member_skills SET skilllevel = '1' WHERE skilllevel = '2'; +UPDATE member_skills SET skilllevel = '2' WHERE skilllevel = '3' OR + skilllevel = '4'; +UPDATE member_skills SET skilllevel = '3' WHERE skilllevel = '5'; diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 8c0ada2f68..1b943173f7 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -1698,6 +1698,11 @@ INSERT INTO member_skills -- Revolver Ocelot, Java VALUES ('d27b679c-3aa8-4c4d-b08e-4eda63cea23f', '105f2968-a182-45a3-892c-eeff76383fe0', '06c03df3-85fe-4fc3-979e-9f1f6ba74a03', '5', '2022-08-01'); +INSERT INTO member_skills -- Faux Freddy, CSS +(id, memberid, skillid, skilllevel, lastuseddate) +VALUES +('fabd11fa-2268-4e72-a2ad-e13aaaaaaa5b', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '6b56f0aa-09aa-4b09-bb81-03481af7e49f', '1', '2018-06-01'); + INSERT INTO kudos (id, message, senderid, teamid, datecreated, dateapproved, publiclyvisible) VALUES diff --git a/web-ui/src/components/skills/SkillLevel.css b/web-ui/src/components/skills/SkillLevel.css new file mode 100644 index 0000000000..3cba16f126 --- /dev/null +++ b/web-ui/src/components/skills/SkillLevel.css @@ -0,0 +1,6 @@ +.skill-level-container { + width: 100%; + display: flex; + flex-direction: row; + align-items: flex-start; +} diff --git a/web-ui/src/components/skills/SkillLevel.jsx b/web-ui/src/components/skills/SkillLevel.jsx new file mode 100644 index 0000000000..06e5b1c718 --- /dev/null +++ b/web-ui/src/components/skills/SkillLevel.jsx @@ -0,0 +1,95 @@ +import { debounce } from 'lodash/function'; +import React, { useState } from 'react'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { + Checkbox, + FormControl, + FormControlLabel, + IconButton, + TextField, + Typography +} from '@mui/material'; +import RadioGroup from '@mui/material/RadioGroup'; +import Radio from '@mui/material/Radio'; +import { styled } from '@mui/material/styles'; + +import './SkillLevel.css'; + +const PREFIX = 'SkillLevel'; +const classes = { + hidden: `${PREFIX}-hidden` +}; + +const Root = styled('span')(() => ({ + [`& .${classes.hidden}`]: { + display: 'none' + }, + '@media screen and (max-width: 900px)': { + width: '100%' + } +})); + +const SkillLevel = ({ + id, + name, + startLevel, + lastUsedDate, + onDelete, + onUpdate +}) => { + let [currCheck, setCurrCheck] = useState(!lastUsedDate); + let [lastUsed, setLastUsed] = useState(lastUsedDate); + let [skillLevel, setSkillLevel] = useState(startLevel); + + const datePickerVisibility = () => { + setCurrCheck(!currCheck); + }; + + const updateLevel = (e, value) => { + setSkillLevel(value); + updateSkillLevel(e, value); + } + + const updateSkillLevel = debounce((event, value) => { + onUpdate(lastUsed, value, id); + }, 1500); + + const updateLastUsed = debounce(value => { + setLastUsed(value); + onUpdate(value, skillLevel, id); + }, 1500); + + const formatDate = date => { + if (!date) return; + let dateString = date[0] + '-'; + dateString = dateString + (date[1] < 10 ? '0' + date[1] : date[1]) + '-'; + dateString = dateString + (date[2] < 10 ? '0' + date[2] : date[2]); + return dateString; + }; + + return ( + <> + + + {name} + +
+ + } label="None"/> + } label="Novice"/> + } label="Practitioner"/> + } label="Expert"/> + + onDelete(id)} size="large"> + + +
+
+ + ); +}; +export default SkillLevel; diff --git a/web-ui/src/components/skills/SkillSection.jsx b/web-ui/src/components/skills/SkillSection.jsx index c83bda5f45..e13c4c1d38 100644 --- a/web-ui/src/components/skills/SkillSection.jsx +++ b/web-ui/src/components/skills/SkillSection.jsx @@ -20,7 +20,7 @@ import { updateMemberSkill } from '../../api/memberskill.js'; import { getSkill, createSkill } from '../../api/skill.js'; -import SkillSlider from './SkillSlider'; +import SkillLevel from './SkillLevel'; import { Avatar, @@ -36,7 +36,10 @@ import { List, ListItem, Modal, - TextField + TextField, + Switch, + FormControlLabel, + Grid, } from '@mui/material'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; import BuildIcon from '@mui/icons-material/Build'; @@ -132,7 +135,8 @@ const SkillSection = ({ userId }) => { return; } const res = await createMemberSkill( - { skillid: curSkill.id, memberid: userId, skilllevel: 3 }, + { skillid: curSkill.id, memberid: userId, + skilllevel: 2, interested: true }, csrf ); const data = @@ -180,6 +184,19 @@ const SkillSection = ({ userId }) => { }; const filter = createFilterOptions(); + const handleInterest = async (id, interested) => { + if (csrf && interested) { + const mSkill = { ...myMemberSkills.find(s => s.skillid === id) }; + mSkill.interested = interested; + await updateMemberSkill(mSkill, csrf); + const copy = [ + ...myMemberSkills.filter(skill => skill.id !== mSkill.id), + mSkill + ]; + dispatch({ type: UPDATE_MEMBER_SKILLS, payload: copy }); + } + }; + const SkillSelector = () => ( { - + {mySkills && mySkills.map(memberSkill => { return ( - - { - handleOpenDeleteConfirmation(); - setSelectedSkillId(id); - }} - onUpdate={handleUpdate} - /> - + + + +
+ { + handleOpenDeleteConfirmation(); + setSelectedSkillId(id); + }} + onUpdate={handleUpdate} + /> + handleInterest(memberSkill.id, !memberSkill.interested)} />} + label="Interested in learning or doing more with this skill?" + /> +
+
+
+
); })} -
+
From 63d5737fac37c9726c523646d0b508352f789d80 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 08:41:09 -0600 Subject: [PATCH 02/11] Figured out the lombok getter name. --- .../checkins/services/member_skill/MemberSkillController.java | 2 +- .../checkins/services/member_skill/MemberSkillCreateDTO.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java index 4a7ae5fff5..ab890b3415 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillController.java @@ -49,7 +49,7 @@ public HttpResponse createAMemberSkill(@Body @Valid @NotNull Member memberSkill.getSkillid(), memberSkill.getSkilllevel(), memberSkill.getLastuseddate(), - memberSkill.interested) + memberSkill.isInterested()) ); return HttpResponse.created(createdMemberSkill) .headers(headers -> headers.location(URI.create(String.format("%s/%s", request.getPath(), createdMemberSkill.getId())))); diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java index 5f7dbd9890..a32b92b545 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkillCreateDTO.java @@ -29,5 +29,5 @@ public class MemberSkillCreateDTO { private LocalDate lastuseddate; @Schema(description = "the member interest") - public boolean interested; + private boolean interested; } From a1d8e3775ad018a62e15fb3eca10a4c4467f7006 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 09:02:31 -0600 Subject: [PATCH 03/11] Fixed issues with "interested" not being populated. --- web-ui/src/components/skills/SkillSection.jsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/web-ui/src/components/skills/SkillSection.jsx b/web-ui/src/components/skills/SkillSection.jsx index e13c4c1d38..3054c798d4 100644 --- a/web-ui/src/components/skills/SkillSection.jsx +++ b/web-ui/src/components/skills/SkillSection.jsx @@ -79,6 +79,7 @@ const SkillSection = ({ userId }) => { let thisSkill = await getSkill(memberSkill.skillid, csrf); thisSkill.lastuseddate = memberSkill.lastuseddate; thisSkill.skilllevel = memberSkill.skilllevel; + thisSkill.interested = memberSkill.interested; return thisSkill; }; @@ -91,6 +92,7 @@ const SkillSection = ({ userId }) => { let skill = result.payload.data; skill.skilllevel = result.skilllevel; skill.lastuseddate = result.lastuseddate; + skill.interested = result.interested; return skill; }); currentUserSkills.sort((a, b) => a.name.localeCompare(b.name)); @@ -313,13 +315,9 @@ const SkillSection = ({ userId }) => { {mySkills && mySkills.map(memberSkill => { return ( - + - -
+ { onChange={() => handleInterest(memberSkill.id, !memberSkill.interested)} />} label="Interested in learning or doing more with this skill?" /> -
-
+
); From cf0ab5df5b63339c18ca5d6b02ed7b78742296bf Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 09:09:29 -0600 Subject: [PATCH 04/11] Updated test snapshot. --- web-ui/src/pages/__snapshots__/ProfilePage.test.jsx.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-ui/src/pages/__snapshots__/ProfilePage.test.jsx.snap b/web-ui/src/pages/__snapshots__/ProfilePage.test.jsx.snap index 257c38b7cf..11e6d6d4b9 100644 --- a/web-ui/src/pages/__snapshots__/ProfilePage.test.jsx.snap +++ b/web-ui/src/pages/__snapshots__/ProfilePage.test.jsx.snap @@ -729,8 +729,8 @@ exports[`renders correctly 1`] = `
-
    Date: Wed, 8 Jan 2025 09:38:40 -0600 Subject: [PATCH 05/11] Updated skill levels to match new values. --- .../member_skill/skillsreport/SkillLevel.java | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillLevel.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillLevel.java index f258c49d93..a565da5150 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillLevel.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillLevel.java @@ -3,17 +3,15 @@ import com.objectcomputing.checkins.exceptions.BadArgException; public enum SkillLevel { - INTERESTED(1), - NOVICE(2), - INTERMEDIATE(3), - ADVANCED(4), - EXPERT(5); - - public static final String INTERESTED_LEVEL = "1"; - public static final String NOVICE_LEVEL = "2"; - public static final String INTERMEDIATE_LEVEL = "3"; - public static final String ADVANCED_LEVEL = "4"; - public static final String EXPERT_LEVEL = "5"; + NONE(0), + NOVICE(1), + PRACTITIONER(2), + EXPERT(3); + + public static final String NONE_LEVEL = "0"; + public static final String NOVICE_LEVEL = "1"; + public static final String PRACTITIONER_LEVEL = "2"; + public static final String EXPERT_LEVEL = "3"; private final int value; @@ -26,16 +24,14 @@ public int getValue() { } public static SkillLevel convertFromString(String level) { - final String levelLc = level != null ? level.toLowerCase() : "3"; + final String levelLc = level != null ? level.toLowerCase() : PRACTITIONER_LEVEL; switch (levelLc) { - case INTERESTED_LEVEL: - return SkillLevel.INTERESTED; + case NONE_LEVEL: + return SkillLevel.NONE; case NOVICE_LEVEL: return SkillLevel.NOVICE; - case INTERMEDIATE_LEVEL: - return SkillLevel.INTERMEDIATE; - case ADVANCED_LEVEL: - return SkillLevel.ADVANCED; + case PRACTITIONER_LEVEL: + return SkillLevel.PRACTITIONER; case EXPERT_LEVEL: return SkillLevel.EXPERT; default: From 862810cf55dae96e75404af835229e3b10499c1e Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 09:39:17 -0600 Subject: [PATCH 06/11] Updates to fix tests. --- .../services/member_skill/MemberSkill.java | 13 ++++++ .../services/fixture/MemberSkillFixture.java | 6 ++- .../SkillsReportControllerTest.java | 8 ++-- .../SkillsReportServicesImplTest.java | 42 +++++++++---------- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java index c8de6139e4..3875cab79d 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/MemberSkill.java @@ -62,6 +62,19 @@ public class MemberSkill { public MemberSkill() { } + // Used in tests + public MemberSkill(UUID memberid, UUID skillid) { + this.memberid = memberid; + this.skillid = skillid; + } + + // Used in tests + public MemberSkill(UUID id, UUID memberid, UUID skillid) { + this.id = id; + this.memberid = memberid; + this.skillid = skillid; + } + public MemberSkill(UUID memberid, UUID skillid, String skilllevel, LocalDate lastuseddate, boolean interested) { this.memberid = memberid; this.skillid = skillid; diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/MemberSkillFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/MemberSkillFixture.java index de45c88870..1c5ffa10c6 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/MemberSkillFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/MemberSkillFixture.java @@ -9,6 +9,10 @@ public interface MemberSkillFixture extends RepositoryFixture{ default MemberSkill createMemberSkill(MemberProfile memberProfile, Skill skill, String skillLevel, LocalDate lastUsedDate) { - return getMemberSkillRepository().save(new MemberSkill(memberProfile.getId(), skill.getId(), skillLevel, lastUsedDate)); + return getMemberSkillRepository().save(new MemberSkill(memberProfile.getId(), skill.getId(), skillLevel, lastUsedDate, true)); + } + + default MemberSkill createMemberSkill(MemberProfile memberProfile, Skill skill, String skillLevel, LocalDate lastUsedDate, boolean interested) { + return getMemberSkillRepository().save(new MemberSkill(memberProfile.getId(), skill.getId(), skillLevel, lastUsedDate, interested)); } } diff --git a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java index f4875e7db7..19631775ce 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java @@ -50,13 +50,13 @@ void testValidRequestNonEmptyResponse() { final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); - final MemberSkill memberSkill = createMemberSkill(memberProfile, skill, SkillLevel.ADVANCED_LEVEL, LocalDate.now()); + final MemberSkill memberSkill = createMemberSkill(memberProfile, skill, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now()); final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); final List skillLevelDTOList = new ArrayList<>(); final SkillLevelDTO skillLevelDTO = new SkillLevelDTO(); skillLevelDTO.setId(skill.getId()); - skillLevelDTO.setLevel(SkillLevel.INTERMEDIATE); + skillLevelDTO.setLevel(SkillLevel.PRACTITIONER); skillLevelDTOList.add(skillLevelDTO); skillsReportRequestDTO.setSkills(skillLevelDTOList); @@ -84,7 +84,7 @@ void testValidRequestEmptyResponse() { final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); - createMemberSkill(memberProfile, skill, SkillLevel.INTERMEDIATE_LEVEL, null); + createMemberSkill(memberProfile, skill, SkillLevel.PRACTITIONER_LEVEL, null); final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); final List skillLevelDTOList = new ArrayList<>(); @@ -116,7 +116,7 @@ void testInvalidRequestSkillNotExist() { final SkillLevelDTO skillLevelDTO = new SkillLevelDTO(); final UUID skillId = UUID.randomUUID(); skillLevelDTO.setId(skillId); - skillLevelDTO.setLevel(SkillLevel.ADVANCED); + skillLevelDTO.setLevel(SkillLevel.PRACTITIONER); skillLevelDTOList.add(skillLevelDTO); skillsReportRequestDTO.setSkills(skillLevelDTOList); diff --git a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportServicesImplTest.java b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportServicesImplTest.java index 17e64ee385..e805939841 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportServicesImplTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportServicesImplTest.java @@ -77,7 +77,7 @@ void finalizeMocks() throws Exception { void testReportSkillNotExist() { final SkillLevelDTO dto = new SkillLevelDTO(); dto.setId(UUID.randomUUID()); - dto.setLevel(SkillLevel.INTERMEDIATE); + dto.setLevel(SkillLevel.PRACTITIONER); final List skills = new ArrayList<>(); skills.add(dto); @@ -127,15 +127,15 @@ void testReport() { final UUID memberId3 = UUID.randomUUID(); final UUID memberId4 = UUID.randomUUID(); - final MemberSkill ms1 = new MemberSkill(memberId1, skillId1, SkillLevel.INTERMEDIATE_LEVEL, LocalDate.now()); - final MemberSkill ms2 = new MemberSkill(memberId1, skillId2, SkillLevel.ADVANCED_LEVEL, LocalDate.now()); - final MemberSkill ms3 = new MemberSkill(memberId2, skillId3, SkillLevel.NOVICE_LEVEL, LocalDate.now()); - final MemberSkill ms4 = new MemberSkill(memberId2, skillId4, SkillLevel.EXPERT_LEVEL, LocalDate.now()); - final MemberSkill ms5 = new MemberSkill(memberId3, skillId2, SkillLevel.INTERESTED_LEVEL, LocalDate.now()); - final MemberSkill ms6 = new MemberSkill(memberId3, skillId3, SkillLevel.ADVANCED_LEVEL, LocalDate.now()); - final MemberSkill ms7 = new MemberSkill(memberId4, skillId1, SkillLevel.ADVANCED_LEVEL, LocalDate.now()); - final MemberSkill ms8 = new MemberSkill(memberId4, skillId2, SkillLevel.INTERMEDIATE_LEVEL, LocalDate.now()); - final MemberSkill ms9 = new MemberSkill(memberId4, skillId4, SkillLevel.EXPERT_LEVEL, LocalDate.now()); + final MemberSkill ms1 = new MemberSkill(memberId1, skillId1, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now(), true); + final MemberSkill ms2 = new MemberSkill(memberId1, skillId2, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now(), false); + final MemberSkill ms3 = new MemberSkill(memberId2, skillId3, SkillLevel.NOVICE_LEVEL, LocalDate.now(), true); + final MemberSkill ms4 = new MemberSkill(memberId2, skillId4, SkillLevel.EXPERT_LEVEL, LocalDate.now(), false); + final MemberSkill ms5 = new MemberSkill(memberId3, skillId2, SkillLevel.NONE_LEVEL, LocalDate.now(), true); + final MemberSkill ms6 = new MemberSkill(memberId3, skillId3, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now(), false); + final MemberSkill ms7 = new MemberSkill(memberId4, skillId1, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now(), true); + final MemberSkill ms8 = new MemberSkill(memberId4, skillId2, SkillLevel.PRACTITIONER_LEVEL, LocalDate.now(), false); + final MemberSkill ms9 = new MemberSkill(memberId4, skillId4, SkillLevel.EXPERT_LEVEL, LocalDate.now(), true); final List skillList1 = new ArrayList<>(); skillList1.add(ms1); @@ -183,10 +183,10 @@ void testReport() { final SkillLevelDTO dto2 = new SkillLevelDTO(); final SkillLevelDTO dto3 = new SkillLevelDTO(); dto1.setId(skillId1); - dto1.setLevel(SkillLevel.INTERMEDIATE); + dto1.setLevel(SkillLevel.PRACTITIONER); dto2.setId(skillId2); dto3.setId(skillId3); - dto3.setLevel(SkillLevel.ADVANCED); + dto3.setLevel(SkillLevel.PRACTITIONER); final List requestedSkills1 = new ArrayList<>(); requestedSkills1.add(dto1); @@ -250,9 +250,9 @@ void testReport() { final SkillLevelDTO dto4 = new SkillLevelDTO(); final SkillLevelDTO dto5 = new SkillLevelDTO(); dto4.setId(skillId2); - dto4.setLevel(SkillLevel.INTERMEDIATE); + dto4.setLevel(SkillLevel.PRACTITIONER); dto5.setId(skillId4); - dto5.setLevel(SkillLevel.ADVANCED); + dto5.setLevel(SkillLevel.PRACTITIONER); final List requestedSkills2 = new ArrayList<>(); requestedSkills2.add(dto4); @@ -270,7 +270,7 @@ void testReport() { for (SkillLevelDTO skill : response4.getTeamMembers().get(0).getSkills()) { assertTrue(skill.getId().equals(skillId2) || skill.getId().equals(skillId4)); if (skill.getId().equals(skillId2)) { - assertEquals(SkillLevel.convertFromString(SkillLevel.INTERMEDIATE_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } else { assertEquals(SkillLevel.convertFromString(SkillLevel.EXPERT_LEVEL), skill.getLevel()); } @@ -287,9 +287,9 @@ private void assertReturnedMember1(TeamMemberSkillDTO elem, UUID skillId1, UUID for (SkillLevelDTO skill : elem.getSkills()) { assertTrue(skill.getId().equals(skillId1) || skill.getId().equals(skillId2)); if (skill.getId().equals(skillId1)) { - assertEquals(SkillLevel.convertFromString(SkillLevel.INTERMEDIATE_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } else { - assertEquals(SkillLevel.convertFromString(SkillLevel.ADVANCED_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } } } @@ -300,9 +300,9 @@ private void assertReturnedMember3(TeamMemberSkillDTO elem, UUID skillId2, UUID for (SkillLevelDTO skill : elem.getSkills()) { assertTrue(skill.getId().equals(skillId2) || skill.getId().equals(skillId3)); if (skill.getId().equals(skillId2)) { - assertEquals(SkillLevel.convertFromString(SkillLevel.INTERESTED_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.NONE_LEVEL), skill.getLevel()); } else { - assertEquals(SkillLevel.convertFromString(SkillLevel.ADVANCED_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } } } @@ -313,9 +313,9 @@ private void assertReturnedMember4(TeamMemberSkillDTO elem, UUID skillId1, UUID for (SkillLevelDTO skill : elem.getSkills()) { assertTrue(skill.getId().equals(skillId1) || skill.getId().equals(skillId2)); if (skill.getId().equals(skillId1)) { - assertEquals(SkillLevel.convertFromString(SkillLevel.ADVANCED_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } else { - assertEquals(SkillLevel.convertFromString(SkillLevel.INTERMEDIATE_LEVEL), skill.getLevel()); + assertEquals(SkillLevel.convertFromString(SkillLevel.PRACTITIONER_LEVEL), skill.getLevel()); } } } From 66b5fd017ed2d1f3ca9a87661b9420c3cbbdfc9b Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 09:46:00 -0600 Subject: [PATCH 07/11] Fixed a bug where we could only set interested to true. --- web-ui/src/components/skills/SkillSection.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-ui/src/components/skills/SkillSection.jsx b/web-ui/src/components/skills/SkillSection.jsx index 3054c798d4..99f446f4fb 100644 --- a/web-ui/src/components/skills/SkillSection.jsx +++ b/web-ui/src/components/skills/SkillSection.jsx @@ -187,7 +187,7 @@ const SkillSection = ({ userId }) => { const filter = createFilterOptions(); const handleInterest = async (id, interested) => { - if (csrf && interested) { + if (csrf) { const mSkill = { ...myMemberSkills.find(s => s.skillid === id) }; mSkill.interested = interested; await updateMemberSkill(mSkill, csrf); From 8b3188a031e62eec9da720f1f4dd475d3413e5b7 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 8 Jan 2025 10:07:32 -0600 Subject: [PATCH 08/11] Removed unused components. --- .../discrete_slider/DiscreteSlider.jsx | 153 ------------------ .../DiscreteSlider.stories.jsx | 27 ---- .../discrete_slider/DiscreteSlider.test.tsx | 37 ----- .../DiscreteSlider.test.tsx.snap | 19 --- web-ui/src/components/skills/SkillSlider.css | 21 --- web-ui/src/components/skills/SkillSlider.jsx | 105 ------------ 6 files changed, 362 deletions(-) delete mode 100644 web-ui/src/components/discrete_slider/DiscreteSlider.jsx delete mode 100644 web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx delete mode 100644 web-ui/src/components/discrete_slider/DiscreteSlider.test.tsx delete mode 100644 web-ui/src/components/discrete_slider/__snapshots__/DiscreteSlider.test.tsx.snap delete mode 100644 web-ui/src/components/skills/SkillSlider.css delete mode 100644 web-ui/src/components/skills/SkillSlider.jsx diff --git a/web-ui/src/components/discrete_slider/DiscreteSlider.jsx b/web-ui/src/components/discrete_slider/DiscreteSlider.jsx deleted file mode 100644 index e907980211..0000000000 --- a/web-ui/src/components/discrete_slider/DiscreteSlider.jsx +++ /dev/null @@ -1,153 +0,0 @@ -import React from 'react'; -import { styled } from '@mui/material/styles'; -import Typography from '@mui/material/Typography'; -import Slider from '@mui/material/Slider'; -import Tooltip from '@mui/material/Tooltip'; - -const Root = styled('div')(({ theme }) => ({ - '& .MuiSlider-markLabel': { - [theme.breakpoints.down('md')]: { - fontSize: '0.525rem' - }, - [theme.breakpoints.between('sm', 'lg')]: { - fontSize: '0.525rem' - }, - [theme.breakpoints.between('md', 'xl')]: { - fontSize: '0.775rem' - }, - [theme.breakpoints.up('lg')]: { - fontSize: '0.875rem' - } - } -})); - -const DiscreteSlider = ({ - title, - onChange, - onChangeCommitted, - inMarks, - inStartPos -}) => { - const defaultMarks = [ - { - value: 1, - label: 'Interested', - tooltip: - 'You have an interest in this skill and, perhaps, common knowledge or an understanding of its basic techniques and concepts.', - tooltipChildren: ['Focus on learning.'] - }, - { - value: 2, - label: 'Novice', - tooltip: - 'You have the level of experience gained in a classroom, experimental scenarios, or via other training. You are expected to need help when performing this skill.', - tooltipChildren: [ - 'Focus on developing through experience.', - 'You understand and can discuss terminology, concepts, principles and issues related to this skill.', - 'You rely heavily on reference and resource materials to be effective with this skill.' - ] - }, - { - value: 3, - label: 'Intermediate', - tooltip: - 'You are able to successfully complete tasks in this competency as requested. Help from an expert may be required from time to time, but you can usually perform the skill independently.', - tooltipChildren: [ - 'Focus on applying and enhancing knowledge or skill.', - 'You have applied this competency to situations, while occasionally needing minimal guidance to perform successfully.', - 'You understand and can discuss the application and implications of changes to processes and procedures in this area.' - ] - }, - { - value: 4, - label: 'Advanced', - tooltip: - 'You can perform the actions associated with this skill without assistance. You are certainly recognized within your immediate organization as "a person to ask" when difficult questions arise regarding this skill.', - tooltipChildren: [ - 'Focus on broad organizational/professional issues.', - 'You have consistently provided relevant ideas and perspectives on process or practice improvements as relate to this skill.', - 'You are capable of coaching others in the application of this skill.', - 'You participate in senior level discussions regarding this skill.', - 'You assist in the development of reference and resource materials related to this skill.' - ] - }, - { - value: 5, - label: 'Expert', - tooltip: - 'You are known as an expert in this area. You can provide guidance, troubleshoot and answer questions related to this skill.', - tooltipChildren: [ - 'Focus on the strategic.', - 'You have demonstrated consistent excellence in applying this competency across multiple projects or organizations.', - 'You are considered the “go to” person for this skill within OCI or externally.', - 'You create new applications for or lead the development of reference and resource materials for this skill.', - 'You are able to explain relevant topics, issues, process elements, and trends in sufficient detail during discussions and presentations as to foster a greater understanding among internal and external colleagues.' - ] - } - ]; - - const marks = inMarks ? inMarks : defaultMarks; - - const formatTooltipTitle = (title, children) => { - return ( -
    -
    {title}
    -
      - {children && - children.map(child => { - return
    • {child}
    • ; - })} -
    -
    - ); - }; - - const ValueLabelComponent = props => { - let thisMark = marks.find(mark => mark.value === props.value); - if (!thisMark) { - return ''; - } - return ( - - {props.children} - - ); - }; - - const startPos = inStartPos - ? Number(inStartPos) - : Math.ceil(marks.length / 2); - - return ( -
    - - {title} - - - `${value}`} - step={null} - marks={marks} - onChange={onChange} - onChangeCommitted={onChangeCommitted} - /> - -
    - ); -}; - -export default DiscreteSlider; diff --git a/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx b/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx deleted file mode 100644 index 355c5ade79..0000000000 --- a/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import DiscreteSlider from './DiscreteSlider'; - -export default { - title: 'Check Ins/DiscreteSlider', - component: DiscreteSlider -}; -const Template = args => ; - -export const DefaultSlider = Template.bind({}); -DefaultSlider.args = { - title: 'Some skill', - lastUsed: undefined -}; - -export const SliderWithChangeHandler = Template.bind({}); -SliderWithChangeHandler.args = { - onChangeCommitted: (event, value) => { - window.alert(value); - } -}; - -export const SliderWithLastUsed = Template.bind({}); -SliderWithLastUsed.args = { - title: 'Other Skill', - lastUsed: 'Currently Used' -}; diff --git a/web-ui/src/components/discrete_slider/DiscreteSlider.test.tsx b/web-ui/src/components/discrete_slider/DiscreteSlider.test.tsx deleted file mode 100644 index cec6492351..0000000000 --- a/web-ui/src/components/discrete_slider/DiscreteSlider.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -// @ts-ignore -import DiscreteSlider from './DiscreteSlider'; - -vi.mock('@mui/material/Slider', () => { - return { - default: () => (props: any) => { - const { onChange, 'data-testid': testId, ...rest } = props; - - return ( - { - onChange(null, parseInt(event.target.value, 10)); - }} - {...rest} - /> - ); - } - }; -}); - -describe('DiscreteSlider', () => { - it('renders slider with title', () => { - // @ts-ignore - snapshot(, { - createNodeMock: (element: any) => { - if (element.type === 'div') { - return { - addEventListener: vi.fn() - }; - } - } - }); - }); -}); diff --git a/web-ui/src/components/discrete_slider/__snapshots__/DiscreteSlider.test.tsx.snap b/web-ui/src/components/discrete_slider/__snapshots__/DiscreteSlider.test.tsx.snap deleted file mode 100644 index 34e4af06e8..0000000000 --- a/web-ui/src/components/discrete_slider/__snapshots__/DiscreteSlider.test.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`DiscreteSlider > renders slider with title 1`] = ` -
    -
    -

    - Some skill -

    -
    -
    -
    -`; diff --git a/web-ui/src/components/skills/SkillSlider.css b/web-ui/src/components/skills/SkillSlider.css deleted file mode 100644 index 7e1df842b3..0000000000 --- a/web-ui/src/components/skills/SkillSlider.css +++ /dev/null @@ -1,21 +0,0 @@ -.date-box-hidden { - display: none; -} - -.skill-slider-container { - width: 100%; - display: flex; - flex-direction: row; - align-items: flex-start; -} - -.discrete-slider { - margin-right: 10px; - width: 40rem; -} - -@media screen and (max-width: 900px) { - .discrete-slider { - width: 90%; - } -} diff --git a/web-ui/src/components/skills/SkillSlider.jsx b/web-ui/src/components/skills/SkillSlider.jsx deleted file mode 100644 index 9cee1fa6d7..0000000000 --- a/web-ui/src/components/skills/SkillSlider.jsx +++ /dev/null @@ -1,105 +0,0 @@ -import { debounce } from 'lodash/function'; -import React, { useState } from 'react'; -import DeleteIcon from '@mui/icons-material/Delete'; -import { - Checkbox, - FormControl, - FormControlLabel, - IconButton, - TextField, - Typography -} from '@mui/material'; -import { styled } from '@mui/material/styles'; -import DiscreteSlider from '../discrete_slider/DiscreteSlider'; - -import './SkillSlider.css'; - -const PREFIX = 'SkillSlider'; -const classes = { - hidden: `${PREFIX}-hidden` -}; - -const Root = styled('span')(() => ({ - [`& .${classes.hidden}`]: { - display: 'none' - }, - '@media screen and (max-width: 900px)': { - width: '100%' - } -})); - -const SkillSlider = ({ - id, - name, - startLevel, - lastUsedDate, - onDelete, - onUpdate -}) => { - let [currCheck, setCurrCheck] = useState(!lastUsedDate); - let [lastUsed, setLastUsed] = useState(lastUsedDate); - let [skillLevel, setSkillLevel] = useState(startLevel); - - const datePickerVisibility = () => { - setCurrCheck(!currCheck); - }; - - const updateLevel = (e, value) => setSkillLevel(value); - - const updateSkillLevel = debounce((event, value) => { - onUpdate(lastUsed, value, id); - }, 1500); - - const updateLastUsed = debounce(value => { - setLastUsed(value); - onUpdate(value, skillLevel, id); - }, 1500); - - const formatDate = date => { - if (!date) return; - let dateString = date[0] + '-'; - dateString = dateString + (date[1] < 10 ? '0' + date[1] : date[1]) + '-'; - dateString = dateString + (date[2] < 10 ? '0' + date[2] : date[2]); - return dateString; - }; - - return ( - <> - - - {name} - -
    - - onDelete(id)} size="large"> - - -
    - {false && ( - - } - label="Currently Used" - labelPlacement="top" - checked={currCheck} - onChange={datePickerVisibility} - /> - - )} - {false && ( - updateLastUsed(value)} - defaultValue={formatDate(lastUsed)} - /> - )} -
    - - ); -}; -export default SkillSlider; From 2aac0acc57cdbaab5cf167303a0bf58680dfff89 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Thu, 9 Jan 2025 12:25:49 -0600 Subject: [PATCH 09/11] Removed the default value for the "interested" column. --- .../resources/db/common/V119__alter_member_skills_table.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/resources/db/common/V119__alter_member_skills_table.sql b/server/src/main/resources/db/common/V119__alter_member_skills_table.sql index dc6855e4ab..14769d6001 100644 --- a/server/src/main/resources/db/common/V119__alter_member_skills_table.sql +++ b/server/src/main/resources/db/common/V119__alter_member_skills_table.sql @@ -1,4 +1,4 @@ -ALTER TABLE member_skills ADD COLUMN interested boolean DEFAULT false; +ALTER TABLE member_skills ADD COLUMN interested boolean; -- If the original skilllevel was 'interested', set the new column value to true UPDATE member_skills SET interested = true WHERE skilllevel = '1'; From 8d472653222ce5c0521ec5a54dcc2fced736c8a3 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Fri, 10 Jan 2025 12:32:34 -0600 Subject: [PATCH 10/11] Bumped to the next number. --- ...ember_skills_table.sql => V120__alter_member_skills_table.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server/src/main/resources/db/common/{V119__alter_member_skills_table.sql => V120__alter_member_skills_table.sql} (100%) diff --git a/server/src/main/resources/db/common/V119__alter_member_skills_table.sql b/server/src/main/resources/db/common/V120__alter_member_skills_table.sql similarity index 100% rename from server/src/main/resources/db/common/V119__alter_member_skills_table.sql rename to server/src/main/resources/db/common/V120__alter_member_skills_table.sql From 873f99733a2abd024beee034facc62ef7769d63d Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Fri, 14 Feb 2025 12:55:51 -0600 Subject: [PATCH 11/11] Renamed the flyway sql file to avoid collision. --- ...ember_skills_table.sql => V121__alter_member_skills_table.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server/src/main/resources/db/common/{V120__alter_member_skills_table.sql => V121__alter_member_skills_table.sql} (100%) diff --git a/server/src/main/resources/db/common/V120__alter_member_skills_table.sql b/server/src/main/resources/db/common/V121__alter_member_skills_table.sql similarity index 100% rename from server/src/main/resources/db/common/V120__alter_member_skills_table.sql rename to server/src/main/resources/db/common/V121__alter_member_skills_table.sql