Skip to content

Commit

Permalink
[Feature] Career development form (#12680)
Browse files Browse the repository at this point in the history
* Add localized constants

* Add form labels

* Add career development section

* Add context messages to fields

* Refactor form

* Update fragments

* Wrap words overflowing in goals work style form

* Pass userid to career development section

* Remove keep dirty

* Make separator decorative

* Make exec interest copy static

* Fix string conversion

* Inline display lists

* Move arrays into props

* Fix order of form fields

* Move nested map outside

* Use bool check icon from components folder

* Pass user id to goals work style section component

* Use empty to validate execInterest

* Refactor fragment locations

* Fix status on form and page table contents

* Use useAuth to get user id

* Add translations

* Clean up props

---------

Co-authored-by: Yoni K <[email protected]>
  • Loading branch information
yonikid15 and Yoni K authored Feb 14, 2025
1 parent 91d8d2d commit 35fba13
Show file tree
Hide file tree
Showing 14 changed files with 1,517 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IntlShape } from "react-intl";
import uniqBy from "lodash/uniqBy";

import { empty } from "@gc-digital-talent/helpers";
import { boolToYesNo } from "@gc-digital-talent/helpers";
import { commonMessages, getLocalizedName } from "@gc-digital-talent/i18n";
import {
Classification,
Expand Down Expand Up @@ -124,14 +124,6 @@ export const formValuesToSubmitData = (
};

export const dataToFormValues = (data: PartialUser): FormValues => {
const boolToYesNo = (
bool: boolean | null | undefined,
): "yes" | "no" | undefined => {
if (empty(bool)) {
return undefined;
}
return bool ? "yes" : "no";
};
return {
govEmployeeYesNo: boolToYesNo(data?.isGovEmployee),
priorityEntitlementYesNo: boolToYesNo(data?.hasPriorityEntitlement),
Expand Down
68 changes: 68 additions & 0 deletions apps/web/src/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -2499,6 +2499,10 @@
"defaultMessage": "Écrire le nom ici",
"description": "Placeholder text for user name input in the delete user dialog"
},
"B524m1": {
"defaultMessage": "État du mentorat",
"description": "Label for an employee profile career development preference field"
},
"B6SqfX": {
"defaultMessage": "Sauvegardez le changement d'état",
"description": "Button label displayed that saves the users status selection."
Expand Down Expand Up @@ -2691,6 +2695,10 @@
"defaultMessage": "Accessibilité et mesures d’adaptation",
"description": "Title of the accessibility and accommodations information dialog"
},
"CKxLR/": {
"defaultMessage": "La mise à jour des préférences en matière de développement de carrière a échoué.",
"description": "Message displayed when a user fails to update the employee profile information"
},
"CM70i0": {
"defaultMessage": "<strong>Les postes à distance</strong> vous offre la possibilité de travailler à temps plein depuis le lieu de votre choix (p. ex., bureau à domicile) au Canada.",
"description": "Definition for 'remote positions'"
Expand Down Expand Up @@ -3067,6 +3075,10 @@
"defaultMessage": "Aidez les gestionnaires à comprendre vos occasions potentielles d’apprentissage de compétences comportementales.",
"description": "Page description for the improve behavioural skills page"
},
"ECAM6A": {
"defaultMessage": "Les préférences en matière de développement de carrière ont été mises à jour avec succès!",
"description": "Message displayed when a user successfully updates employee profile information"
},
"EG5WpQ": {
"defaultMessage": "Erreur : impossible de mettre à jour les paramètres",
"description": "Message displayed when an error occurs while updating notification settings."
Expand Down Expand Up @@ -3187,6 +3199,10 @@
"defaultMessage": "Ce tableau présente une liste de tous les candidats à ce processus.",
"description": "Descriptive text about the list of pool candidates in the admin portal."
},
"Ey8cB4": {
"defaultMessage": "Préférences en matière de développement de carrière",
"description": "Title for career development preferences section"
},
"EyH6FY": {
"defaultMessage": "Sélectionnez les expériences pertinentes",
"description": "Legend for the checklist in the application education page."
Expand Down Expand Up @@ -3715,6 +3731,10 @@
"defaultMessage": "Ensemble, nous sommes en mesure de tirer parti de la diversité des expériences et des idées que les personnes autochtones apportent à la fonction publique et de contribuer à la réconciliation au Canada.",
"description": "Paragraph 2 of the 'A commitment to diverse digital talent' section"
},
"I+TGU3": {
"defaultMessage": "État du coaching des cadres",
"description": "Label for an employee profile career development preference field"
},
"I2CtZJ": {
"defaultMessage": "Les commentaires ou les contributions seront supprimés s’ils :",
"description": "Comments or contributions list title"
Expand Down Expand Up @@ -3799,6 +3819,10 @@
"defaultMessage": "Pour cette possibilité, les demandes doivent être soumises au plus tard, le :",
"description": "Second paragraph for pool deadlines dialog"
},
"IQiTZd": {
"defaultMessage": "Intérêt pour les possibilités de mentorat",
"description": "Label for an employee profile career development preference field"
},
"IReTZe": {
"defaultMessage": "Modifier les rôles dans le processus",
"description": "Label for the form to edit a users process membership"
Expand Down Expand Up @@ -6111,6 +6135,10 @@
"defaultMessage": "Options de perfectionnement professionnel et en leadership",
"description": "Label for users interest in development programs for a community"
},
"Uj7TE2": {
"defaultMessage": "La présente section de votre profil vous permet de manifester votre intérêt pour une variété d'options particulières liées au recrutement, au mentorat et aux possibilités de promotion.",
"description": "Describes the career development preferences of employee profile"
},
"UjkAHp": {
"defaultMessage": "Agent(e) P M 3",
"description": "PM-03 classification aria label including titles"
Expand Down Expand Up @@ -6478,6 +6506,10 @@
"defaultMessage": "Souhaitez-vous annuler cette décision et régler le statut du candidat à « En cours d’évaluation »?",
"description": "Confirmation text for reinstating a candidate"
},
"WoZ3pB": {
"defaultMessage": "Les postes au niveau de la direction m'intéressent.",
"description": "The executive interest described as interested."
},
"WovyCU": {
"defaultMessage": "Ajouter un rôle dans la collectivité",
"description": "Header for the form to add a community membership to a user"
Expand Down Expand Up @@ -8322,6 +8354,10 @@
"defaultMessage": "Annonce à l’échelle du site",
"description": "Page title for the update sitewide announcement page"
},
"gDoGSs": {
"defaultMessage": "Intérêt pour des postes au niveau de la direction",
"description": "Label for an employee profile career development preference field"
},
"gEnOmo": {
"defaultMessage": "Avant que nous considérions qu'un produit est prêt à être lancé, nous travaillons avec <fableLink>Fable Tech Labs</fableLink> pour nous assurer que nos produits et nos fonctionnalités sont évalués par des utilisateurs qui ont besoin de technologies informatiques adaptées pour accéder au Web. Il s'agit d'une étape importante pour s'assurer que nos produits conviennent à de vraies personnes.",
"description": "Text describing our user testing for accessibility"
Expand Down Expand Up @@ -9318,6 +9354,10 @@
"defaultMessage": "Au moins une question est requise dans le cadre de cette évaluation. Veuillez l’ajouter ici.",
"description": "description of 'screening questions' section of the 'assessment details' dialog"
},
"lW24T5": {
"defaultMessage": "Intérêt pour les promotions et les mutations latérales",
"description": "Label for an employee profile career development preference field"
},
"lZ8lct": {
"defaultMessage": "Process mis en signet.",
"description": "Alert displayed to the user when they mark a pool as bookmarked."
Expand Down Expand Up @@ -9486,6 +9526,10 @@
"defaultMessage": "Trouver une compétence",
"description": "Title for the find a skill dialog"
},
"mMiZ3q": {
"defaultMessage": "Cette section contient des questions qui sont actuellement sans réponse. Cliquez sur le bouton « Modifiez » pour réviser vos réponses dans les champs pertinents.",
"description": "Message for unanswered required questions in this section"
},
"mNNgEF": {
"defaultMessage": "Êtes-vous sûr(e) de vouloir vous déconnecter?",
"description": "Question displayed when authenticated user lands on /logged-out."
Expand Down Expand Up @@ -10386,6 +10430,10 @@
"defaultMessage": "Titre du poste (français)",
"description": "Label for process French title"
},
"rBtIUo": {
"defaultMessage": "Enregistrez les préférences en matière de développement de carrière",
"description": "Text on a button to save career development preferences form"
},
"rCpVpZ": {
"defaultMessage": "Vous avez indiqué que vous répondiez aux <strong>exigences minimales en matière d’expérience ou d’études (2 années d’études post-secondaires)</strong> en mentionnant les expériences suivantes sur votre parcours professionnel :",
"description": "Message on education requirements card on the application review page."
Expand Down Expand Up @@ -10670,6 +10718,10 @@
"defaultMessage": "Ce candidat a revendiqué le <strong>statut de vétéran</strong>.",
"description": "Message for a candidates veteran status claim"
},
"sxCR5N": {
"defaultMessage": "Seuls les membres du personnel admissibles seront pris en considération pour les possibilités de coaching des cadres. L'admissibilité dépend de votre classification et de votre structure organisationnelle.",
"description": "Context for an employee profile career development preference field"
},
"sycoGU": {
"defaultMessage": "Pas nécessairement. La plupart des possibilités d’apprentissage peuvent être réalisées en travaillant de la maison, pourvu qu’il y ait une connexion à Internet. Certains postes ont des exigences propres à l’emplacement. Nous accordons une importance à la famille et à la communauté, et nous encourageons les gens à se joindre à notre famille sans avoir à quitter la leur, et à faire partie de notre communauté tout en restant dans la leur. Parlez à votre gestionnaire d’embauche de votre situation ou de vos préférences, et nous ferons de notre mieux pour travailler avec vous afin de trouver une solution appropriée.",
"description": "Learn more dialog question six paragraph one"
Expand Down Expand Up @@ -11042,6 +11094,10 @@
"defaultMessage": "Annulation des modifications",
"description": "Button text to cancel editing a profile section"
},
"vFV5N8": {
"defaultMessage": "Les postes au niveau de la direction ne m'intéressent pas.",
"description": "The executive interest described as not interested."
},
"vJ/8Mk": {
"defaultMessage": "Identification des talents numériques – Tables rondes sur la gestion des talents",
"description": "Button text to open section describing identification of digital talents"
Expand Down Expand Up @@ -11106,6 +11162,10 @@
"defaultMessage": "l'informatique en nuage;",
"description": "Third item in list of certification topics section"
},
"vaxlr+": {
"defaultMessage": "Types d'organisations pour lesquelles vous aimeriez travailler",
"description": "Label for an employee profile career development preference field"
},
"vbiWgW": {
"defaultMessage": "Politiques connexes",
"description": "Heading for the related policies card"
Expand Down Expand Up @@ -11222,6 +11282,10 @@
"defaultMessage": "Signaler un bogue",
"description": "Support form subject field bug option label"
},
"wJ5KIL": {
"defaultMessage": "Intérêt pour le coaching des cadres",
"description": "Label for an employee profile career development preference field"
},
"wJnIJx": {
"defaultMessage": "Groupe",
"description": "Label displayed on classification group input"
Expand Down Expand Up @@ -11466,6 +11530,10 @@
"defaultMessage": "Erreur : la mise à jour du processus a échoué",
"description": "Message displayed to user after pool fails to get updated."
},
"xnxf8m": {
"defaultMessage": "Le fait de manifester son intérêt ne garantit pas la prise en considération d'une candidature à un poste au niveau de la direction. Votre intérêt, combiné à votre expérience professionnelle et à vos compétences, aide les recruteurs à déterminer si vous correspondez au profil recherché.",
"description": "Context for an employee profile career development preference field"
},
"xtNiNu": {
"defaultMessage": "Cette section sert à définir les évaluations qui seront utilisées dans le cadre de votre processus d’évaluation. Veillez à ce que chaque compétence essentielle soit évaluée au moins une fois pour compléter votre plan d’évaluation.",
"description": "Introduction to the organize section in the assessment plan builder, paragraph 1"
Expand Down
53 changes: 41 additions & 12 deletions apps/web/src/pages/EmployeeProfile/EmployeeProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { useQuery } from "urql";
import ChartBarSquareIcon from "@heroicons/react/24/outline/ChartBarSquareIcon";

import { commonMessages, navigationMessages } from "@gc-digital-talent/i18n";
import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql";
import {
EmployeeProfilePageQuery,
getFragment,
graphql,
} from "@gc-digital-talent/graphql";
import {
Heading,
Pending,
Expand All @@ -21,9 +25,15 @@ import RequireAuth from "~/components/RequireAuth/RequireAuth";
import { isVerifiedGovEmployee } from "~/utils/userUtils";
import profileMessages from "~/messages/profileMessages";
import StatusItem from "~/components/StatusItem/StatusItem";
import {
hasAllEmptyFields,
hasEmptyRequiredFields,
} from "~/validators/employeeProfile/careerDevelopment";

import messages from "./messages";
import GoalsWorkStyleSection from "./components/GoalsWorkStyleSection/GoalsWorkStyleSection";
import CareerDevelopmentSection from "./components/CareerDevelopmentSection/CareerDevelopmentSection";
import { EmployeeProfileCareerDevelopment_Fragment } from "./components/CareerDevelopmentSection/utils";

const SECTION_ID = {
CAREER_PLANNING: "career-planning-section",
Expand All @@ -39,26 +49,30 @@ const EmployeeProfile_Fragment = graphql(/** GraphQL */ `
isWorkEmailVerified
employeeProfile {
...EmployeeProfileGoalsWorkStyle
...EmployeeProfileCareerDevelopment
}
}
`);

interface EmployeeProfileProps {
userQuery: FragmentType<typeof EmployeeProfile_Fragment>;
employeeProfileQuery: EmployeeProfilePageQuery;
}

const EmployeeProfile = ({ userQuery }: EmployeeProfileProps) => {
const EmployeeProfile = ({ employeeProfileQuery }: EmployeeProfileProps) => {
const intl = useIntl();
const paths = useRoutes();
const user = getFragment(EmployeeProfile_Fragment, userQuery);
const { isGovEmployee, workEmail, isWorkEmailVerified } = user;
const user = getFragment(EmployeeProfile_Fragment, employeeProfileQuery.me);

if (!user.employeeProfile) {
if (!user?.employeeProfile) {
throw new NotFoundError();
}

if (
!isVerifiedGovEmployee({ isGovEmployee, workEmail, isWorkEmailVerified })
!isVerifiedGovEmployee({
isGovEmployee: user.isGovEmployee,
workEmail: user.workEmail,
isWorkEmailVerified: user.isWorkEmailVerified,
})
) {
throw new UnauthorizedError(
intl.formatMessage({
Expand Down Expand Up @@ -99,6 +113,11 @@ const EmployeeProfile = ({ userQuery }: EmployeeProfileProps) => {
],
});

const careerDevelopment = getFragment(
EmployeeProfileCareerDevelopment_Fragment,
user.employeeProfile,
);

return (
<>
<SEO title={pageTitle} description={subtitle} />
Expand All @@ -125,7 +144,13 @@ const EmployeeProfile = ({ userQuery }: EmployeeProfileProps) => {
<StatusItem
asListItem={false}
title={intl.formatMessage(messages.careerDevelopment)}
status="success"
status={
hasAllEmptyFields(careerDevelopment)
? "optional"
: hasEmptyRequiredFields(careerDevelopment)
? "error"
: "success"
}
scrollTo={SECTION_ID.CAREER_DEVELOPMENT}
/>
</TableOfContents.ListItem>
Expand Down Expand Up @@ -176,9 +201,12 @@ const EmployeeProfile = ({ userQuery }: EmployeeProfileProps) => {
})}
</p>
</TableOfContents.Section>
<TableOfContents.Section
id={SECTION_ID.CAREER_DEVELOPMENT}
></TableOfContents.Section>
<TableOfContents.Section id={SECTION_ID.CAREER_DEVELOPMENT}>
<CareerDevelopmentSection
employeeProfileQuery={user.employeeProfile}
careerDevelopmentOptionsQuery={employeeProfileQuery}
/>
</TableOfContents.Section>
<TableOfContents.Section
id={SECTION_ID.DREAM_ROLE}
></TableOfContents.Section>
Expand All @@ -200,6 +228,7 @@ const EmployeeProfilePage_Query = graphql(/** GraphQL */ `
me {
...EmployeeProfile
}
...EmployeeProfileCareerDevelopmentOptions
}
`);

Expand All @@ -212,7 +241,7 @@ const EmployeeProfilePage = () => {
return (
<Pending fetching={fetching} error={error}>
{data?.me ? (
<EmployeeProfile userQuery={data.me} />
<EmployeeProfile employeeProfileQuery={data} />
) : (
<ThrowNotFound
message={intl.formatMessage(profileMessages.userNotFound)}
Expand Down
Loading

0 comments on commit 35fba13

Please sign in to comment.