From b38b56e781d01d722aa5d695e749a517f4a90527 Mon Sep 17 00:00:00 2001 From: Yonathan K Date: Fri, 3 Feb 2023 09:01:47 -0500 Subject: [PATCH 01/20] Wrap all abbreviations sitewide with wrapAbbr() helper function --- .../ProfileFormWrapper/ProfileFormWrapper.tsx | 2 +- .../components/SelfDeclaration/HelpLink.tsx | 6 +- .../SelfDeclaration/SignAndContinue.tsx | 20 +- apps/web/src/hooks/useQuote.tsx | 19 +- apps/web/src/lang/fr.json | 528 +++++++++--------- .../HomePage/components/Featured/Block.tsx | 2 +- .../HomePage/components/Featured/Featured.tsx | 20 +- .../Opportunities/Opportunities.tsx | 40 +- apps/web/src/pages/Home/IAPHomePage/Home.tsx | 44 +- .../components/Dialog/ApplyDialog.tsx | 23 +- .../components/Dialog/LearnDialog.tsx | 35 +- .../Dialog/SelfDeclarationDialog.tsx | 20 +- .../Pools/BrowsePoolsPage/BrowsePoolsPage.tsx | 75 ++- .../pages/Pools/BrowsePoolsPage/messages.ts | 76 +-- .../PoolAdvertisementPage.tsx | 21 +- .../components/ClassificationDefinition.tsx | 179 +++--- .../EmploymentEquityForm.tsx | 20 +- .../components/ExperienceAndSkills.tsx | 20 +- .../RoleSalaryForm/RoleSalaryForm.tsx | 48 +- .../RoleSalaryPage/components/dialogs.tsx | 338 +++++++---- .../src/components/Card/CardFlat/CardFlat.tsx | 2 +- .../src/constants/localizedConstants.tsx | 28 +- frontend/common/src/helpers/nameUtils.tsx | 77 +++ frontend/common/src/lang/fr.json | 28 +- 24 files changed, 1030 insertions(+), 641 deletions(-) diff --git a/apps/web/src/components/ProfileFormWrapper/ProfileFormWrapper.tsx b/apps/web/src/components/ProfileFormWrapper/ProfileFormWrapper.tsx index 32c8471d2d6..258ce2fcb57 100644 --- a/apps/web/src/components/ProfileFormWrapper/ProfileFormWrapper.tsx +++ b/apps/web/src/components/ProfileFormWrapper/ProfileFormWrapper.tsx @@ -14,7 +14,7 @@ import SaveButton from "./SaveButton"; export interface ProfileFormWrapperProps { crumbs: BreadcrumbsProps["crumbs"]; - description?: string; + description?: React.ReactNode; title: string; metaTitle?: string; // Used to override </head> children?: React.ReactNode; diff --git a/apps/web/src/components/SelfDeclaration/HelpLink.tsx b/apps/web/src/components/SelfDeclaration/HelpLink.tsx index 9350538bf45..5c0f4163cce 100644 --- a/apps/web/src/components/SelfDeclaration/HelpLink.tsx +++ b/apps/web/src/components/SelfDeclaration/HelpLink.tsx @@ -1,5 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const contactLink = (chunks: React.ReactNode) => ( <a @@ -16,14 +17,15 @@ const HelpLink = () => { <p> {intl.formatMessage( { - id: "YZ/ZhG", + id: "pIiisf", defaultMessage: - "If you are unsure about providing your information, or if you have any questions regarding the IT Apprenticeship Program for Indigenous Peoples, please <link>contact us</link> and we would be happy to meet with you.", + "If you are unsure about providing your information, or if you have any questions regarding the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples, please <link>contact us</link> and we would be happy to meet with you.", description: "Text describing where to get help with the self-declaration form", }, { link: contactLink, + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, )} </p> diff --git a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx index 9040d77a0ef..15b1ef8e9f0 100644 --- a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx +++ b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx @@ -5,6 +5,7 @@ import { useFormContext } from "react-hook-form"; import { Input, Submit } from "@common/components/form"; import { FieldLabels } from "@common/components/form/BasicForm"; import errorMessages from "@common/messages/errorMessages"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; interface SignAndContinueProps { labels: FieldLabels; @@ -89,13 +90,18 @@ const SignAndContinue = ({ labels }: SignAndContinueProps) => { <Submit color="ia-primary" mode="solid" - text={intl.formatMessage({ - defaultMessage: - "Explore IT opportunities within the federal government", - id: "32qwlv", - description: - "Button text to submit the Indigenous self-declaration form when not Indigenous.", - })} + text={intl.formatMessage( + { + defaultMessage: + "Explore <abbreviation>IT</abbreviation> opportunities within the federal government", + id: "j3WBqJ", + description: + "Button text to submit the Indigenous self-declaration form when not Indigenous.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} /> </p> </> diff --git a/apps/web/src/hooks/useQuote.tsx b/apps/web/src/hooks/useQuote.tsx index 3591343139b..0756d577b09 100644 --- a/apps/web/src/hooks/useQuote.tsx +++ b/apps/web/src/hooks/useQuote.tsx @@ -1,9 +1,10 @@ import React from "react"; import { useIntl } from "react-intl"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; export interface Quote { content: React.ReactNode | string; - author: string; + author: string | React.ReactNode; } const useQuote = (): Quote => { @@ -11,11 +12,17 @@ const useQuote = (): Quote => { const quotes: Quote[] = [ { - author: intl.formatMessage({ - defaultMessage: "Government of Canada IT Apprentice", - id: "49UIne", - description: "author of testimonial number one", - }), + author: intl.formatMessage( + { + defaultMessage: + "Government of Canada <abbreviation>IT</abbreviation> Apprentice", + id: "pRGDLn", + description: "author of testimonial number one", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + ), content: intl.formatMessage( { defaultMessage: diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 8613bdeb2b5..0f8bc9e5490 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -59,10 +59,6 @@ "defaultMessage": "Lancement", "description": "Talent portal strategy item 4 heading" }, - "BSSYnh": { - "defaultMessage": "Nous voulons vous informer qu’entre-temps, des mises à jour sont apportées à ce site qui permettront aux personnes autochtones qui souhaitent se joindre au Programme d’apprentissage en TI de présenter une demande en ligne.", - "description": "Second paragraph for apply now dialog" - }, "CY+493": { "defaultMessage": "Pour en apprendre davantage", "description": "Button text to learn more about the program" @@ -79,30 +75,14 @@ "defaultMessage": "Stratégie", "description": "Heading for strategy for the indigenous talent portal" }, - "DgMIfz": { - "defaultMessage": "Le Programme d’apprentissage en TI vous convient-il?", - "description": "Application box heading part one" - }, "DvmNR7": { "defaultMessage": "Inscrivez-vous dès maintenant", "description": "Button text to apply for program" }, - "Dzyk1q": { - "defaultMessage": "En collaboration avec le Programme d’apprentissage en TI pour les peuples autochtones, le Portail des talents autochtones commencera par mettre l’accent sur les talents en TI et en technologie, ce qui permettra :", - "description": "Description for strategy for the indigenous talent portal" - }, - "EqVMCE": { - "defaultMessage": "Veuillez envoyer votre curriculum vitae et votre lettre de présentation expliquant votre passion pour la TI et pourquoi vous souhaitez vous joindre au programme, à : <mailLink>edsc.pda-iap.esdc@hrsdc-rhdcc.gc.ca</mailLink>. Un membre de l’équipe communiquera avec vous dans 3 à 5 jours ouvrables.", - "description": "First paragraph for apply now dialog" - }, "GnmmgR": { "defaultMessage": "Une fois votre demande présenté, un membre de l’équipe communiquera avec vous dans les 3 à 5 jours ouvrables qui suivent.", "description": "How it works, step 3 content sentence 2" }, - "qZvV7b": { - "defaultMessage": "Programme d’apprentissage en TI pour les peuples autochtones. Postulez dès aujourd’hui pour entamer votre parcours de carrière en TI.", - "description": "Homepage title for Indigenous Apprenticeship Program" - }, "Ilot3b": { "defaultMessage": "Que se passe-t-il après lorsqu’une personne achève le programme de 24 mois?", "description": "Learn more dialog question three heading" @@ -111,10 +91,6 @@ "defaultMessage": "Comment puis-je savoir si ce programme est fait pour moi?", "description": "Learn more dialog question seven heading" }, - "L9yjr3": { - "defaultMessage": "Découvrez-en davantage sur le Programme d’apprentissage en TI pour les peuples autochtones du gouvernement du Canada", - "description": "Heading for the Learn more dialog" - }, "LGSw+f": { "defaultMessage": "Tous les apprentis seront appuyés par des pairs et des mentors soigneusement sélectionnés. Les apprentis seront également invités à se joindre à un Réseau d’apprentissage pour les Autochtones, où ils auront des occasions de communiquer avec d’autres employés autochtones du gouvernement du Canada et avec d’autres apprentis autochtones qui participent à ce programme.", "description": "Learn more dialog question two paragraph two" @@ -179,10 +155,6 @@ "defaultMessage": "Bien sûr! En tant qu’employés du gouvernement du Canada, tous les apprentis auront droit à des congés annuels, à des congés de maladie et à des congés familiaux. Après six mois, les apprentis auront également accès à une assurance médicale et dentaire pour eux-mêmes et leurs personnes à charge, en plus de devenir membres du régime de pension de retraite de la fonction publique fédérale.", "description": "Learn more dialog question five paragraph one" }, - "Xhfkfg": { - "defaultMessage": "Répondre à la forte demande de talents autochtones en TI.", - "description": "Talent portal strategy item 1 content" - }, "YGM/D5": { "defaultMessage": "Le programme dure 24 mois et les apprentis ont accès à un soutien pendant leur période de participation au programme.", "description": "Learn more dialog question two paragraph one" @@ -243,22 +215,10 @@ "defaultMessage": "Que devront faire les apprentis dans le cadre du programme?", "description": "Learn more dialog question eight heading" }, - "osGGIt": { - "defaultMessage": "Programme d’apprentissage en TI pour les personnes autochtones + Portail des talents autochtones", - "description": "heading for indigenous talent portal section" - }, "p19YJ2": { "defaultMessage": "Présentez une demande dès aujourd’hui pour entreprendre une carrière en technologie de l’information.", "description": "Application box content" }, - "p2sBh3": { - "defaultMessage": "Qui peut présenter une demande pour devenir apprenti dans le cadre du Programme d’apprentissage en TI pour les peuples autochtones du gouvernement du Canada?", - "description": "Learn more dialog question one heading" - }, - "pWoAv0": { - "defaultMessage": "Le Programme d’apprentissage en TI pour les personnes autochtones est une initiative du gouvernement du Canada visant particulièrement les Premières Nations, les Inuits et les Métis. C’est un chemin vers un emploi dans la fonction publique fédérale pour les personnes autochtones qui ont une passion pour la technologie de l’information (TI).", - "description": "First paragraph about the program" - }, "pkFLpT": { "defaultMessage": "Si vous avez un intérêt et une passion pour la technologie et que vous vous identifiez comme Autochtone, ce programme est pour vous.", "description": "Learn more dialog question seven paragraph one" @@ -291,10 +251,6 @@ "defaultMessage": "En valorisant et en misant sur le potentiel d’une personne plutôt que sur son niveau de scolarité, le programme élimine l’un des plus grands obstacles qui existe en matière d’emploi dans l’économie numérique. Le programme a été élaboré par, avec et pour des personnes autochtones à travers le Canada. Il intègre les préférences et les besoins des apprenants autochtones tout en reconnaissant l’importance de la communauté.", "description": "Second paragraph about the program" }, - "yZMQ6j": { - "defaultMessage": "Nous voulons en apprendre davantage sur vous et sur votre intérêt ou votre passion dans le domaine de la TI!", - "description": "How it works, step 2 content sentence 1" - }, "zlYw3Z": { "defaultMessage": "Présentez votre profil en tant que demande", "description": "How it works, step 3 heading" @@ -315,10 +271,6 @@ "defaultMessage": "Ils sont membres des Premières Nations (avec ou sans statut), Inuit ou Métis ", "description": "IAP Requirement list item one" }, - "49UIne": { - "defaultMessage": "Apprenti en TI du Gouvernement du Canada", - "description": "author of testimonial number one" - }, "74Sg+4": { "defaultMessage": "L’exigence minimale en matière d’études est un diplôme d’études générales ou secondaires. Il n’est pas nécessaire d’avoir fait des études collégiales ou universitaires.", "description": "Learn more dialog question twelve paragraph one" @@ -379,10 +331,6 @@ "defaultMessage": "Ma communauté ou mes communautés :", "description": "Text label for list of the users selected Indigenous communities" }, - "32qwlv": { - "defaultMessage": "Explorer les occasions en matière de TI au sein du gouvernement fédéral", - "description": "Button text to submit the Indigenous self-declaration form when not Indigenous." - }, "3oW16P": { "defaultMessage": "Signature", "description": "label for the signature input on the self-declaration form" @@ -463,10 +411,6 @@ "defaultMessage": "Je suis autochtone, mais je ne trouve pas ma communauté ici", "description": "Label for not represented community" }, - "YZ/ZhG": { - "defaultMessage": "Si vous n’êtes pas sûr de vouloir fournir vos renseignements, ou si vous avez des questions concernant le programme d’apprentissage en TI pour les personnes autochtones, veuillez <link>nous contacter</link> nous serons heureux de vous rencontrer.", - "description": "Text describing where to get help with the self-declaration form" - }, "at11n5": { "defaultMessage": "Êtes-vous sûr de vouloir sélectionner : « Je suis autochtone, mais je ne trouve pas ma communauté ici? »", "description": "Title for the alert warning users about selection not represented and a represented community" @@ -475,10 +419,6 @@ "defaultMessage": "Ces occasions favorisent l’amélioration des perspectives d’emploi et des résultats économiques des peuples autochtones, conformément aux principes énoncés dans la Déclaration des Nations unies sur les droits des peuples autochtones. Elles soutiennent également le processus de réconciliation dans notre pays.", "description": "Paragraph two for the self-declaration explanation dialog" }, - "J2uivT": { - "defaultMessage": "Nous reconnaissons l’importance de la voix des autochtones au sein du gouvernement fédéral. L’objectif du programme d’apprentissage en TI destiné aux peuples autochtones est de faire entendre la voix des autochtones en créant des occasions pour les membres des Premières Nations, les Inuits et les Métis de faire partie de la fonction publique fédérale.", - "description": "Paragraph one for the self-declaration explanation dialog" - }, "h4E9+K": { "defaultMessage": "De quelle manière sera vérifié le statut?", "description": "Heading for the self-declaration verification dialog" @@ -1009,10 +949,6 @@ "defaultMessage": "Renseignements personnels", "description": "Title for Personal Information section of the About Me form" }, - "87nFC8": { - "defaultMessage": "Il y a deux types d'employés du TI-04 : ceux qui suivent un cheminement en gestion et les contributeurs individuels.", - "description": "IT-04 description precursor" - }, "8NJbCH": { "defaultMessage": "Indiquez tous les emplacements où vous êtes prêt à travailler, y compris votre emplacement actuel (si vous souhaitez y travailler).", "description": "Description text for Profile Form wrapper in Work Location Preferences Form" @@ -1093,10 +1029,6 @@ "defaultMessage": "Accueil", "description": "Link to the Homepage in the nav menu." }, - "GAjpqU": { - "defaultMessage": "Voici où vous pouvez ajouter des expériences et des compétences à votre profil. Cela pourrait aller d'aider les membres de la communauté à résoudre leurs problèmes d'ordinateur au travail à temps plein dans une organisme de TI.", - "description": "Description for the experience and skills page in applicant profile." - }, "GqVBqi": { "defaultMessage": "Détails du compte", "description": "Title for Account Details section of the About Me form" @@ -1353,10 +1285,6 @@ "defaultMessage": "Connexion à l'aide de la CléGC", "description": "Title for the login page for applicant profiles." }, - "Z9Uex5": { - "defaultMessage": "Les techniciens (TI-01) fournissent un soutien technique pour l'élaboration, la mise en œuvre, l'intégration et la maintenance de la prestation de services aux clients et aux intervenants", - "description": "blurb describing IT-01" - }, "ZSAzrR": { "defaultMessage": "Date d'expiration :", "description": "The expiry date label and colon" @@ -1441,10 +1369,6 @@ "defaultMessage": "Toute autre chose au sujet de cette expérience que vous aimeriez partager.", "description": "Description blurb for additional information on Experience form" }, - "hCgrxA": { - "defaultMessage": "Il y a deux types d'employés du TI-03 : ceux qui suivent un cheminement en gestion et les contributeurs individuels.", - "description": "IT-03 description precursor" - }, "hTJgV2": { "defaultMessage": "Tous les champs obligatoires sont remplis. Vous pouvez maintenant modifier votre statut.", "description": "Message displayed to user when user profile completed." @@ -1545,10 +1469,6 @@ "defaultMessage": "Connectez-vous à la place", "description": "Login link text on the registration page." }, - "raFdbB": { - "defaultMessage": "Les analystes (TI-02) fournissent des services techniques, des conseils, des analyses et de la recherche dans leur domaine d'expertise pour appuyer la prestation de services aux clients et aux intervenants. Les analystes de la TI se retrouvent dans tous les volets de travail.", - "description": "blurb describing IT-02" - }, "rywI3C": { "defaultMessage": "Verbal", "description": "Label displayed on the language information form verbal field." @@ -1677,22 +1597,10 @@ "defaultMessage": "Je suis bilingue (anglais et français) et <strong>je n'ai PAS</strong> complété une <languageEvaluationPageLink></languageEvaluationPageLink> officielle.", "description": "Message for the haven't completed bilingual evaluation option" }, - "+bC9lc": { - "defaultMessage": "<strong>Cheminement en gestion</strong> : Chefs d'équipe de la TI (TI-03) sont chargés de superviser le travail et les équipes de projet pour les services et les opérations de la TI dans leur domaine d'expertise afin de soutenir la prestation de services aux clients et aux intervenants. Les chefs d'équipe de la TI se trouvent dans tous les volets de travail.", - "description": "IT-03 team lead path description, ignore things in <> tags please" - }, - "VQWGkh": { - "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers principaux en TI (TI-04) fournissent des conseils techniques et une orientation stratégique d'experts dans leur domaine d'expertise en matière de fourniture de solutions et de services à des clients internes ou externes et à des intervenants.", - "description": "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please" - }, "HPDqDV": { "defaultMessage": "Je suis bilingue (anglais et français) et <strong>j'ai</strong> complété une <languageEvaluationPageLink></languageEvaluationPageLink> officielle en <strong>ANGLAIS</strong>.", "description": "Message for the completed english bilingual evaluation option" }, - "m21EOJ": { - "defaultMessage": "<strong>Cheminement en gestion</strong> : les gestionnaires de la TI (TI-04) sont responsables de la gestion du développement et de la prestation des services et des activités de TI par l'entremise de chefs d'équipe subalternes, de conseillers techniques et d'équipes de projet, pour la prestation des services aux clients et aux intervenants. Les gestionnaires de la TI se trouvent dans tous les volets de travail.", - "description": "IT-04 manager path description, ignore things in <> tags please" - }, "ofOoFQ": { "defaultMessage": "<strong>Vous n'avez pas de compte de CléGC?</strong> <a>Inscrivez-vous.</a>", "description": "Instruction on what to do if user does not have a GC Key." @@ -1709,10 +1617,6 @@ "defaultMessage": "<strong>Pourquoi ne puis-je pas modifier mon statut?</strong>", "description": "Message in My Status Form." }, - "u+9mg1": { - "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers techniques en TI (TI-03) fournissent des conseils techniques spécialisés, des recommandations et du soutien sur les solutions et les services dans leur domaine d'expertise pour appuyer la prestation de services aux clients et aux intervenants. Les conseillers techniques en TI se trouvent dans tous les volets de travail.", - "description": "IT-03 advisor description, ignore things in <> tags please" - }, "GIPciq": { "defaultMessage": "<strong>Remarque :</strong> Si vous sélectionnez plus d'un groupe visé par l'équité en matière d'emploi, TOUS les candidats qui se sont déclarés membres de N'IMPORTE LEQUEL des groupes visés par l'équité en matière d'emploi sélectionnés seront recommandés. Si vous avez des exigences plus détaillées concernant l'équité en matière d'emploi, veuillez nous en faire part dans la section des commentaires du formulaire de soumission.", "description": "Context for employment equity filter in search form." @@ -1869,10 +1773,6 @@ "defaultMessage": "Plage de salaire :", "description": "Label for pool advertisement salary range" }, - "m5hjaz": { - "defaultMessage": "Lorsque les responsables du recrutement ont des besoins en personnel informatique et que des postes se libèrent, les candidats qui répondent aux qualifications de ce processus peuvent être contactés pour une évaluation plus approfondie. Cela signifie que divers responsables peuvent vous contacter au sujet d'occasions précises dans le domaine du développement d'applications.", - "description": "Description of pool recruitment, paragraph two" - }, "mNWpoy": { "defaultMessage": "Détails supplémentaires", "description": "Title for the details section of a pool advertisement" @@ -2233,10 +2133,6 @@ "defaultMessage": "Afficher les candidatures archivées", "description": "Button text to show a users archived applications." }, - "f3Qqop": { - "defaultMessage": "Conçu par la communauté autochtone pour la communauté autochtone, ce programme recrute des candidats pour des postes de niveau d'entrée pour des possibilités d’apprentissage et de développement des TI dans l’ensemble du gouvernement.", - "description": "Description for the Indigenous Apprenticeship Program on home page" - }, "fI6Hjf": { "defaultMessage": "La préférence sera accordée aux citoyens canadiens et aux résidents permanents du Canada", "description": "Context text for required citizenship status section in About Me form, explaining preference" @@ -2361,10 +2257,6 @@ "defaultMessage": "Archiver la candidature", "description": "Titre du modèle qui apparaît lorsqu’un utilisateur tente d’archiver une candidature" }, - "zNvXSs": { - "defaultMessage": "Parcourir les emplois en TI", - "description": "Texte du lien pour les emplois en TI dans l’appel à l’action du gouvernement" - }, "zmV99R": { "defaultMessage": "Que vous envisagiez de travailler pour le gouvernement ou que vous soyez déjà employé, que vous espériez embaucher ou que vous envisagiez un rôle de direction, c’est l’endroit où venir pour faire partie de la communauté numérique du GC.", "description": "Description de la candidature sur la page d’accueil" @@ -2425,10 +2317,6 @@ "defaultMessage": "Modifier l’expérience de travail", "description": "Page title for the work experience profile form" }, - "+6QgII": { - "defaultMessage": "Conçu par la communauté autochtone, avec elle et pour elle, le programme recrute des candidats des Premières Nations, inuits et métis qui se passionnent pour les TI, pour des emplois de niveau débutant, ainsi que pour des possibilités d’apprentissage et de perfectionnement.", - "description": "Summary for Indigenous community job opportunities on Browse IT jobs page" - }, "/vsOxF": { "defaultMessage": "Mettre à jour mon profil", "description": "Link text to direct users to the profile page when logged in" @@ -2485,10 +2373,6 @@ "defaultMessage": "Votre demande à un processus sera examinée par notre équipe et, si nous trouvons une concordance quelconque, on vous invitera à une évaluation. Une fois accepté(e), les gestionnaires pourront alors communiquer avec vous avec des offres d’emploi.", "description": "Description of how the application process works, paragraph two" }, - "GZrICV": { - "defaultMessage": "Parcourez les offres dans le domaine des TI pour la communauté autochtone", - "description": "Title for Indigenous community job opportunities on Browse IT jobs page" - }, "Gil1Zj": { "defaultMessage": "Lisez l’Ambition numérique", "description": "Link text to read the Digital Ambition" @@ -2501,18 +2385,10 @@ "defaultMessage": "(À déterminer)", "description": "Message displayed when a pool has no expiry date yet" }, - "J2WrFI": { - "defaultMessage": "Parcourez les offres dans le domaine des TI", - "description": "Page title for the direct intake browse pools page." - }, "Jorewd": { "defaultMessage": "Nous publions constamment de nouvelles offres. En tenant votre profil à jour, vous pourrez soumettre des demandes à la vitesse de l’éclair le moment venu.", "description": "Text describing upcoming opportunities instructing users to update a profile when logged in" }, - "Ms6O4W": { - "defaultMessage": "Laissez notre équipe vous épargner du temps et de l’énergie en associant vos besoins à des professionnels des TI préalablement sélectionnés et possédant les compétences requises pour le poste. Tous les talents de nos bassins de dotation ont été sélectionnés à l’issue d’un processus concurrentiel. Vous pouvez donc passer directement à l’entrevue et décider s’ils conviennent à votre équipe.", - "description": "Summary for to go to the search page on Browse IT jobs page" - }, "OMDX09": { "defaultMessage": "Préparez-vous en mettant à jour votre profil.", "description": "Link text to update your profile for executive jobs in government" @@ -2533,10 +2409,6 @@ "defaultMessage": "Processus actifs de recrutement de talents", "description": "Title for the current jobs recruiting candidates" }, - "cYg+l1": { - "defaultMessage": "Vous recherchez des talents en TI de niveau débutant et vous désirez soutenir la diversité, l’inclusion et la réconciliation? Communiquez avec le programme d’apprentissage en TI pour les personnes autochtones et lancez le processus d’embauche de stagiaires autochtones dès aujourd’hui!", - "description": "Summary of the Indigenous Apprenticeship Program for the homepage" - }, "dIIccA": { "defaultMessage": "J’ai découvert le Programme d’apprentissage pour les peuples autochtones sur talent.canada.ca et j’aimerais en savoir davantage sur la façon dont je peux embaucher des stagiaires pour mon équipe.", "description": "Body of email for info on Indigenous Apprenticeship Program" @@ -2841,18 +2713,6 @@ "defaultMessage": "Vous ne voyez pas de recrutement actif correspondant à vos compétences ? Pas de problème, nous voulons toujours avoir de vos nouvelles.", "description": "summary for section with ongoing pool advertisements" }, - "4CT5zI": { - "defaultMessage": "Solutions logicielles de la TI", - "description": "Title for the 'software solutions' IT work stream" - }, - "Jwj3YC": { - "defaultMessage": "Gestionnaires et conseillers principaux (IT-04)", - "description": "Title for the 'IT-04 Manager' classification" - }, - "+ywDV8": { - "defaultMessage": "Analyste (IT-02)", - "description": "Title for the 'IT-02 Analyst' classification" - }, "7KJGSu": { "defaultMessage": "Ce volet comprend la programmation, la conception et le développement de systèmes, l’analyse des activités, la configuration, les tests et la mise en œuvre.", "description": "Title for the 'software solutions' IT work stream" @@ -2865,30 +2725,6 @@ "defaultMessage": "Ce volet comprend le développement et la maintenance de modèles de données, la conception de bases de données, la planification des capacités, la gestion des performances et la garantie de l’intégrité des données.", "description": "Title for the 'database management' IT work stream" }, - "C2iUvf": { - "defaultMessage": "Architecture intégrée de la TI", - "description": "Title for the 'enterprise architecture' IT work stream" - }, - "DVkO+D": { - "defaultMessage": "Ce volet comprend le travail avec la direction de l’architecture TI du ministère, la collaboration avec d’autres volets de TI et la recherche sur les technologies émergentes.", - "description": "Title for the 'enterprise architecture' IT work stream" - }, - "EOO6S0": { - "defaultMessage": "Services consultatifs auprès des secteurs d’activité de la TI", - "description": "Title for the 'business line advisory services' IT work stream" - }, - "ElfiAv": { - "defaultMessage": "Opérations d’infrastructure de la TI", - "description": "Title for the 'infrastructure operations' IT work stream" - }, - "xtIE4i": { - "defaultMessage": "Chefs d’équipe et conseillers techniques (IT-03)", - "description": "Title for the 'IT-03 Advisor' classification" - }, - "QN/1MR": { - "defaultMessage": "Ce volet comprend la fourniture de conseils spécialisés en matière de TI, ainsi que la collaboration avec les clients ou les fournisseurs, afin d’acquérir et de maintenir les ressources en TI qui soutiennent les opérations du GC.", - "description": "Title for the 'business line advisory services' IT work stream" - }, "RBsGRp": { "defaultMessage": "Postulez au recrutement en cours", "description": "title for section with ongoing pool advertisements" @@ -2897,30 +2733,10 @@ "defaultMessage": "Les techniciens fournissent un soutien technique dans le développement, la mise en place, l’intégration et la maintenance de la fourniture de services aux clients et aux intervenants.", "description": "Description for the 'IT-01 Technician' classification" }, - "MiBPoz": { - "defaultMessage": "Technicien (IT-01)", - "description": "Title for the 'IT-01 Technician' classification" - }, - "VX2+ET": { - "defaultMessage": "Planification et établissement de rapports en matière de TI", - "description": "Title for the 'planning and reporting' IT work stream" - }, - "aL5y0G": { - "defaultMessage": "Gestion de portefeuilles de projets de la TI", - "description": "Title for the 'project portfolio management' IT work stream" - }, "bz6geU": { "defaultMessage": "Ce volet comprend des compétences spécialisées en matière de sécurité, axées sur la programmation, l’infrastructure, les applications commerciales et les données.", "description": "Title for the 'security' IT work stream" }, - "crqgGQ": { - "defaultMessage": "Ce volet comprend la fourniture de conseils spécialisés en matière de planification de la TI et la création collaborative de produits livrables, notamment des plans stratégiques, des politiques et normes de la TI et des processus de gouvernance.", - "description": "Title for the 'planning and reporting' IT work stream" - }, - "h5CY+u": { - "defaultMessage": "Ce lot comprend le travail à temps plein sur des projets importants et formels qui nécessitent le partage et l’application rigoureuse de compétences et de connaissances en matière de gestion de projets de la TI.", - "description": "Title for the 'project portfolio management' IT work stream" - }, "Jdo3br": { "defaultMessage": "Présenter sa candidature pour les opportunités de techniciens<hidden> {name}</hidden>", "description": "Invitation to apply for the 'IT-01 Technician' classification" @@ -2937,10 +2753,6 @@ "defaultMessage": "Présenter sa candidature pour les opportunités gestionnaires et conseillers<hidden> {name}</hidden>", "description": "Invitation to apply for the 'IT-04 Manager' classification" }, - "pffFnd": { - "defaultMessage": "Gestion de bases de données de la TI", - "description": "Title for the 'database management' IT work stream" - }, "86rJAg": { "defaultMessage": "Les chefs d’équipe sont chargés de superviser le travail et les équipes de projet afin de faciliter la prestation de services aux clients et aux intervenants.", "description": "Description for the 'IT-03 Advisor' classification, paragraph 1" @@ -2949,18 +2761,6 @@ "defaultMessage": "Les conseillers techniques sont des travailleurs individuels qui fournissent des conseils et des recommandations afin d’appuyer la prestation de services.", "description": "Description for the 'IT-03 Advisor' classification, paragraph 2" }, - "svCFrY": { - "defaultMessage": "Ce volet comprend la gestion de l’infrastructure des réseaux, des ordinateurs centraux, des serveurs et du stockage, la fourniture d’un soutien de la TI et les relations avec les clients et fournisseurs.", - "description": "Title for the 'infrastructure operations' IT work stream" - }, - "uxlNWH": { - "defaultMessage": "Sécurité de la TI", - "description": "Title for the 'security' IT work stream" - }, - "d4OJ5V": { - "defaultMessage": "Il appartient aux gestionnaires de gérer l’élaboration et la prestation de services et (ou) d’opérations de TI par l’entremise de chefs d’équipe subalternes, de conseillers techniques et d’équipes de projet.", - "description": "Description for the 'IT-04 Manager' classification, paragraph 1" - }, "tDetPq": { "defaultMessage": "Les conseillers principaux sont des travailleurs individuels qui fournissent des conseils techniques spécialisés et une orientation stratégique en vue de la fourniture de solutions et de services.", "description": "Description for the 'IT-04 Manager' classification, paragraph 2" @@ -3029,34 +2829,10 @@ "defaultMessage": "Niveau 4 : Conseiller principal", "description": "title for IT-04 senior advisor dialog" }, - "44bgIY": { - "defaultMessage": "Niveau 3 : Conseiller technique (88 000 $ à 110 000 $). <openModal>En savoir plus sur TI-03</openModal>", - "description": "Checkbox label for Level IT-03 advisor selection, ignore things in <> tags please" - }, - "58BEeZ": { - "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers principaux en TI (TI-04) fournissent des conseils techniques et une orientation stratégique d'experts dans leur domaine d'expertise en matière de fourniture de solutions et de services à des clients internes ou externes et à des intervenants. Les conseillers principaux en TI se retrouvent principalement dans six volets de travail :", - "description": "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please" - }, - "6LTC0y": { - "defaultMessage": "Gestion de la base de données de la TI", - "description": "work stream example" - }, - "75nLSV": { - "defaultMessage": "Niveau 4 : Gestionnaire (101 000 $ à 126 000 $). <openModal>En savoir plus sur TI-04</openModal>", - "description": "Checkbox label for Level IT-04 manager selection, ignore things in <> tags please" - }, "DrR60L": { "defaultMessage": "J'aimerais être recommandé(e) à des emplois aux niveaux suivants :", "description": "Legend for role and salary checklist form" }, - "Eubngf": { - "defaultMessage": "Cette plateforme met l'accent sur l'embauche de talents numériques pour travailler dans des postes classifiés comme TI (technologie de l'information). Examinez les niveaux suivants dans la classification TI et <strong>sélectionnez uniquement</strong> ceux qui représentent le travail que vous voulez faire.", - "description": "Blurb describing the purpose of the form" - }, - "FayQOt": { - "defaultMessage": "Niveau 4 : Conseiller principal (101 000 $ à 126 000 $). <openModal>En savoir plus sur TI-04</openModal>", - "description": "Checkbox label for Level IT-04 senior advisor selection, ignore things in <> tags please" - }, "JCyvcW": { "defaultMessage": "Sélectionnez une langue...", "description": "Placeholder displayed on the About Me form preferred interview language" @@ -3077,26 +2853,10 @@ "defaultMessage": "Sélectionnez une langue...", "description": "Placeholder displayed on the About Me form preferred exam language" }, - "PcYOnN": { - "defaultMessage": "Niveau 2 : Analyste (de 75 000 $ à 91 000 $). <openModal>En savoir plus sur TI-02</openModal>", - "description": "Checkbox label for Level IT-02 selection, ignore things in <> tags please" - }, - "QZ9FZB": { - "defaultMessage": "Activités d'infrastructure de TI", - "description": "work stream example" - }, - "SDDp1t": { - "defaultMessage": "Solutions logicielles de la TI", - "description": "work stream example" - }, "WE0OGe": { "defaultMessage": "Niveau 3 : Conseillers techniques", "description": "title for IT-03 advisor dialog" }, - "Zn10pO": { - "defaultMessage": "Niveau 1 : Technicien(ne) (de 60 000 $ à 78 000 $). <openModal>En savoir plus sur TI-01</openModal>", - "description": "Checkbox label for Level IT-01 selection, ignore things in <> tags please" - }, "aLMroa": { "defaultMessage": "Niveau 1 : Techniciens", "description": "title for IT-01 dialog" @@ -3109,10 +2869,6 @@ "defaultMessage": "Sélectionnez votre langue d'examen écrite préférée", "description": "Legend text for required written exam language preference for exams in About Me form" }, - "hizC89": { - "defaultMessage": "Niveau 3 : Chef d'équipe (88 000 $ à 110 000 $). <openModal>En savoir plus sur TI-03</openModal>", - "description": "Checkbox label for Level IT-03 leader selection, ignore things in <> tags please" - }, "kCBLsJ": { "defaultMessage": "Rôle et salaire escomptés", "description": "Title role and salary expectations form" @@ -3121,14 +2877,6 @@ "defaultMessage": "Niveau 3 : Chef d'équipe", "description": "title for IT-03 lead dialog" }, - "nrBkon": { - "defaultMessage": "Sécurité de la TI", - "description": "work stream example" - }, - "oOcegG": { - "defaultMessage": "Architecture intégrée de la TI ", - "description": "work stream example" - }, "qSxmx0": { "defaultMessage": "Fermer", "description": "Close Confirmations" @@ -3137,18 +2885,10 @@ "defaultMessage": "Sélectionnez votre langue préférée pour l'entretien oral", "description": "Legend text for required spoken interview language preference for interviews in About Me form" }, - "tm3zLD": { - "defaultMessage": "Gestion du portefeuille de projets de TI", - "description": "work stream example" - }, "uIpPFZ": { "defaultMessage": "Les classifications gouvernementales sont des étiquettes que le gouvernement du Canada utilise pour regrouper des types de travail similaires. Dans le gouvernement du Canada, le salaire est lié à la façon dont les postes sont classés.", "description": "Description for the role and salary expectation form" }, - "vQzmUH": { - "defaultMessage": "Les techniciens en TI se retrouvent principalement dans trois filières de travail :", - "description": "Preceding list description" - }, "wRxZQV": { "defaultMessage": "Sélectionnez une langue...", "description": "Placeholder displayed on the About Me form preferred communication language" @@ -3157,10 +2897,6 @@ "defaultMessage": "Autodéclaration", "description": "Form label for a self-declaration input" }, - "okZjVr": { - "defaultMessage": "<strong>La présente section est facultative. Toutefois, afin d’être admissible au Programme d’apprentis en TI pour les peuples autochtones, vous devez vous autodéclarer en tant qu’Autochtone.</strong> Si vous êtes membre de l’un ou de plusieurs de ces groupes d’équité en matière d’emploi, et que vous ne souhaitez pas vous autodéclarer sur cette plateforme, vous n’êtes pas oblige(e) de le faire. <strong>Veuillez remplir le formulaire ci-dessous si vous répondez à ces conditions :</strong>", - "description": "Explanation that employment equity information is optional." - }, "/Y7x+s": { "defaultMessage": "Créer un bassin", "description": "Heading displayed above the Create Pool form." @@ -5502,5 +5238,269 @@ "zzwPOR": { "defaultMessage": "Langue préférée pour l'examen écrit :", "description": "Display text for the preferred written exam language field on users" + }, + "/R/S8P": { + "defaultMessage": "Ce volet comprend la fourniture de conseils spécialisés en matière de planification de la <abbreviation>TI</abbreviation> et la création collaborative de produits livrables, notamment des plans stratégiques, des politiques et normes de la <abbreviation>TI</abbreviation> et des processus de gouvernance.", + "description": "Title for the 'planning and reporting' IT work stream" + }, + "/SLyVF": { + "defaultMessage": "Les analystes (<abbreviation>TI-02</abbreviation>) fournissent des services techniques, des conseils, des analyses et de la recherche dans leur domaine d'expertise pour appuyer la prestation de services aux clients et aux intervenants. Les analystes de la <abbreviation>TI</abbreviation> se retrouvent dans tous les volets de travail.", + "description": "blurb describing IT-02" + }, + "028BJx": { + "defaultMessage": "Activités d'infrastructure de <abbreviation>TI</abbreviation>", + "description": "work stream example" + }, + "0mAZsV": { + "defaultMessage": "Parcourir les emplois en <abbreviation>TI</abbreviation>", + "description": "Link text for IT jobs in government call to action" + }, + "2MQK8R": { + "defaultMessage": "Nous voulons vous informer qu’entre-temps, des mises à jour sont apportées à ce site qui permettront aux personnes autochtones qui souhaitent se joindre au Programme d’apprentissage en <abbreviation>TI</abbreviation> de présenter une demande en ligne.", + "description": "Second paragraph for apply now dialog" + }, + "2aBKgf": { + "defaultMessage": "Il y a deux types d'employés du <abbreviation>TI-04</abbreviation> : ceux qui suivent un cheminement en gestion et les contributeurs individuels.", + "description": "IT-04 description precursor" + }, + "3gDiDK": { + "defaultMessage": "Sécurité de la <abbreviation>TI</abbreviation>", + "description": "work stream example" + }, + "69euaM": { + "defaultMessage": "Les techniciens en <abbreviation>TI</abbreviation> se retrouvent principalement dans trois filières de travail :", + "description": "Preceding list description" + }, + "6G1ESr": { + "defaultMessage": "Opérations d’infrastructure de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'infrastructure operations' IT work stream" + }, + "6UVZOY": { + "defaultMessage": "Laissez notre équipe vous épargner du temps et de l’énergie en associant vos besoins à des professionnels des <abbreviation>TI</abbreviation> préalablement sélectionnés et possédant les compétences requises pour le poste. Tous les talents de nos bassins de dotation ont été sélectionnés à l’issue d’un processus concurrentiel. Vous pouvez donc passer directement à l’entrevue et décider s’ils conviennent à votre équipe.", + "description": "Summary for to go to the search page on Browse IT jobs page" + }, + "6kSk+R": { + "defaultMessage": "Architecture intégrée de la <abbreviation>TI</abbreviation>", + "description": "work stream example" + }, + "7Kb+Uh": { + "defaultMessage": "Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les peuples autochtones. Postulez dès aujourd’hui pour entamer votre parcours de carrière en TI.", + "description": "Homepage title for Indigenous Apprenticeship Program" + }, + "7wcfnG": { + "defaultMessage": "Il y a deux types d'employés du <abbreviation>TI-03</abbreviation> : ceux qui suivent un cheminement en gestion et les contributeurs individuels.", + "description": "IT-03 description precursor" + }, + "9FKjvW": { + "defaultMessage": "En collaboration avec le Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les peuples autochtones, le Portail des talents autochtones commencera par mettre l’accent sur les talents en <abbreviation>TI</abbreviation> et en technologie, ce qui permettra :", + "description": "Description for strategy for the indigenous talent portal" + }, + "9Nf78m": { + "defaultMessage": "Qui peut présenter une demande pour devenir apprenti dans le cadre du Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les peuples autochtones du gouvernement du Canada?", + "description": "Learn more dialog question one heading" + }, + "AlRcyu": { + "defaultMessage": "Gestion de portefeuilles de projets de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'project portfolio management' IT work stream" + }, + "BxAUGH": { + "defaultMessage": "Veuillez envoyer votre curriculum vitae et votre lettre de présentation expliquant votre passion pour la <abbreviation>TI</abbreviation> et pourquoi vous souhaitez vous joindre au programme, à : <mailLink>edsc.pda-iap.esdc@hrsdc-rhdcc.gc.ca</mailLink>. Un membre de l’équipe communiquera avec vous dans 3 à 5 jours ouvrables.", + "description": "First paragraph for apply now dialog" + }, + "CIwCa3": { + "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers techniques en <abbreviation>TI</abbreviation> (<abbreviation>TI-03</abbreviation>) fournissent des conseils techniques spécialisés, des recommandations et du soutien sur les solutions et les services dans leur domaine d'expertise pour appuyer la prestation de services aux clients et aux intervenants. Les conseillers techniques en <abbreviation>TI</abbreviation> se trouvent dans tous les volets de travail.", + "description": "IT-03 advisor description, ignore things in <> tags please" + }, + "E3loNV": { + "defaultMessage": "Planification et établissement de rapports en matière de <abbreviation>TI</abbreviation>", + "description": "Title for the 'planning and reporting' IT work stream" + }, + "EGXG1j": { + "defaultMessage": "Niveau 4 : Gestionnaire (101 000 $ à 126 000 $). <openModal>En savoir plus sur <abbreviation>TI-04</abbreviation></openModal>", + "description": "Checkbox label for Level IT-04 manager selection, ignore things in <> tags please" + }, + "Ea8q/H": { + "defaultMessage": "Découvrez-en davantage sur le Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les peuples autochtones du gouvernement du Canada", + "description": "Heading for the Learn more dialog" + }, + "F5kDhX": { + "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers principaux en <abbreviation>TI</abbreviation> (<abbreviation>TI-04</abbreviation>) fournissent des conseils techniques et une orientation stratégique d'experts dans leur domaine d'expertise en matière de fourniture de solutions et de services à des clients internes ou externes et à des intervenants.", + "description": "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please" + }, + "FtJRWS": { + "defaultMessage": "Conçu par la communauté autochtone pour la communauté autochtone, ce programme recrute des candidats pour des postes de niveau d'entrée pour des possibilités d’apprentissage et de développement des <abbreviation>TI</abbreviation> dans l’ensemble du gouvernement.", + "description": "Description for the Indigenous Apprenticeship Program on home page" + }, + "GtZyhK": { + "defaultMessage": "Technicien (<abbreviation>TI-01</abbreviation>)", + "description": "Title for the 'IT-01 Technician' classification" + }, + "H8cs1r": { + "defaultMessage": "Services consultatifs auprès des secteurs d’activité de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'business line advisory services' IT work stream" + }, + "I/fGUN": { + "defaultMessage": "Analyste (<abbreviation>TI-02</abbreviation>)", + "description": "Title for the 'IT-02 Analyst' classification" + }, + "KpNUo0": { + "defaultMessage": "Gestionnaires et conseillers principaux (<abbreviation>TI-04</abbreviation>)", + "description": "Title for the 'IT-04 Manager' classification" + }, + "Ks4G8p": { + "defaultMessage": "Voici où vous pouvez ajouter des expériences et des compétences à votre profil. Cela pourrait aller d'aider les membres de la communauté à résoudre leurs problèmes d'ordinateur au travail à temps plein dans une organisme de TI.", + "description": "Description for the experience and skills page in applicant profile." + }, + "L6sIvM": { + "defaultMessage": "Niveau 3 : Chef d'équipe (88 000 $ à 110 000 $). <openModal>En savoir plus sur <abbreviation>TI-03</abbreviation></openModal>", + "description": "Checkbox label for Level IT-03 leader selection, ignore things in <> tags please" + }, + "LOvD2e": { + "defaultMessage": "Vous recherchez des talents en <abbreviation>TI</abbreviation> de niveau débutant et vous désirez soutenir la diversité, l’inclusion et la réconciliation? Communiquez avec le programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones et lancez le processus d’embauche de stagiaires autochtones dès aujourd’hui!", + "description": "Summary of the Indigenous Apprenticeship Program for the homepage" + }, + "LlgRM8": { + "defaultMessage": "Lorsque les responsables du recrutement ont des besoins en personnel informatique et que des postes se libèrent, les candidats qui répondent aux qualifications de ce processus peuvent être contactés pour une évaluation plus approfondie. Cela signifie que divers responsables peuvent vous contacter au sujet d'occasions précises dans le domaine du développement d'applications.", + "description": "Description of pool recruitment, paragraph two" + }, + "Nj6c0X": { + "defaultMessage": "<strong>La présente section est facultative. Toutefois, afin d’être admissible au Programme d’apprentis en <abbreviation>TI</abbreviation> pour les peuples autochtones, vous devez vous autodéclarer en tant qu’Autochtone.</strong> Si vous êtes membre de l’un ou de plusieurs de ces groupes d’équité en matière d’emploi, et que vous ne souhaitez pas vous autodéclarer sur cette plateforme, vous n’êtes pas oblige(e) de le faire. <strong>Veuillez remplir le formulaire ci-dessous si vous répondez à ces conditions :</strong>", + "description": "Explanation that employment equity information is optional." + }, + "ObVJ7H": { + "defaultMessage": "Gestion de la base de données de la <abbreviation>TI</abbreviation>", + "description": "work stream example" + }, + "OheHgg": { + "defaultMessage": "<strong>Contributeur individuel</strong> : Les conseillers principaux en <abbreviation>TI</abbreviation> (<abbreviation>TI-04</abbreviation>) fournissent des conseils techniques et une orientation stratégique d'experts dans leur domaine d'expertise en matière de fourniture de solutions et de services à des clients internes ou externes et à des intervenants.", + "description": "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please" + }, + "OqglGZ": { + "defaultMessage": "Ce volet comprend le travail avec la direction de l’architecture <abbreviation>TI</abbreviation> du ministère, la collaboration avec d’autres volets de <abbreviation>TI</abbreviation> et la recherche sur les technologies émergentes.", + "description": "Title for the 'enterprise architecture' IT work stream" + }, + "OvL68O": { + "defaultMessage": "Conçu par la communauté autochtone, avec elle et pour elle, le programme recrute des candidats des Premières Nations, inuits et métis qui se passionnent pour les TI, pour des emplois de niveau débutant, ainsi que pour des possibilités d’apprentissage et de perfectionnement.", + "description": "Summary for Indigenous community job opportunities on Browse IT jobs page" + }, + "QdYrqI": { + "defaultMessage": "<strong>Cheminement en gestion</strong> : Chefs d'équipe de la <abbreviation>TI</abbreviation> (<abbreviation>TI-03</abbreviation>) sont chargés de superviser le travail et les équipes de projet pour les services et les opérations de la <abbreviation>TI</abbreviation> dans leur domaine d'expertise afin de soutenir la prestation de services aux clients et aux intervenants. Les chefs d'équipe de la <abbreviation>TI</abbreviation> se trouvent dans tous les volets de travail.", + "description": "IT-03 team lead path description, ignore things in <> tags please" + }, + "RCV8Us": { + "defaultMessage": "Nous reconnaissons l’importance de la voix des autochtones au sein du gouvernement fédéral. L’objectif du programme d’apprentissage en <abbreviation>TI</abbreviation> destiné aux peuples autochtones est de faire entendre la voix des autochtones en créant des occasions pour les membres des Premières Nations, les Inuits et les Métis de faire partie de la fonction publique fédérale.", + "description": "Paragraph one for the self-declaration explanation dialog" + }, + "S02Y/P": { + "defaultMessage": "Chefs d’équipe et conseillers techniques (<abbreviation>TI-03</abbreviation>)", + "description": "Title for the 'IT-03 Advisor' classification" + }, + "Tjd942": { + "defaultMessage": "Solutions logicielles de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'software solutions' IT work stream" + }, + "UMPxOg": { + "defaultMessage": "Le Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones est une initiative du gouvernement du Canada visant particulièrement les Premières Nations, les Inuits et les Métis. C’est un chemin vers un emploi dans la fonction publique fédérale pour les personnes autochtones qui ont une passion pour la technologie de l’information (TI).", + "description": "First paragraph about the program" + }, + "W2G590": { + "defaultMessage": "Le Programme d’apprentissage en <abbreviation>TI</abbreviation> vous convient-il?", + "description": "Application box heading part one" + }, + "WgGDug": { + "defaultMessage": "Gestion du portefeuille de projets de <abbreviation>TI</abbreviation>", + "description": "work stream example" + }, + "Xdmhoo": { + "defaultMessage": "Ce volet comprend la gestion de l’infrastructure des réseaux, des ordinateurs centraux, des serveurs et du stockage, la fourniture d’un soutien de la <abbreviation>TI</abbreviation> et les relations avec les clients et fournisseurs.", + "description": "Title for the 'infrastructure operations' IT work stream" + }, + "Zd1x6H": { + "defaultMessage": "Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones + Portail des talents autochtones", + "description": "heading for indigenous talent portal section" + }, + "bNBhvY": { + "defaultMessage": "Niveau 4 : Conseiller principal (101 000 $ à 126 000 $). <openModal>En savoir plus sur <abbreviation>TI-04</abbreviation></openModal>", + "description": "Checkbox label for Level IT-04 senior advisor selection, ignore things in <> tags please" + }, + "cMDC/P": { + "defaultMessage": "Répondre à la forte demande de talents autochtones en TI.", + "description": "Talent portal strategy item 1 content" + }, + "drDPf3": { + "defaultMessage": "Parcourez les offres dans le domaine des <abbreviation>TI</abbreviation> pour la communauté autochtone", + "description": "Title for Indigenous community job opportunities on Browse IT jobs page" + }, + "eFNBND": { + "defaultMessage": "Architecture intégrée de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'enterprise architecture' IT work stream" + }, + "gxOExQ": { + "defaultMessage": "Nous voulons en apprendre davantage sur vous et sur votre intérêt ou votre passion dans le domaine de la TI!", + "description": "How it works, step 2 content sentence 1" + }, + "hKKYYL": { + "defaultMessage": "Ce lot comprend le travail à temps plein sur des projets importants et formels qui nécessitent le partage et l’application rigoureuse de compétences et de connaissances en matière de gestion de projets de la TI.", + "description": "Title for the 'project portfolio management' IT work stream" + }, + "iA1BBF": { + "defaultMessage": "Ce volet comprend la fourniture de conseils spécialisés en matière de TI, ainsi que la collaboration avec les clients ou les fournisseurs, afin d’acquérir et de maintenir les ressources en <abbreviation>TI</abbreviation> qui soutiennent les opérations du GC.", + "description": "Title for the 'business line advisory services' IT work stream" + }, + "j3OROA": { + "defaultMessage": "Les techniciens (<abbreviation>TI-01</abbreviation>) fournissent un soutien technique pour l'élaboration, la mise en œuvre, l'intégration et la maintenance de la prestation de services aux clients et aux intervenants", + "description": "blurb describing IT-01" + }, + "j3WBqJ": { + "defaultMessage": "Explorer les occasions en matière de <abbreviation>TI</abbreviation> au sein du gouvernement fédéral", + "description": "Button text to submit the Indigenous self-declaration form when not Indigenous." + }, + "jZDflg": { + "defaultMessage": "Niveau 3 : Conseiller technique (88 000 $ à 110 000 $). <openModal>En savoir plus sur <abbreviation>TI-03</abbreviation></openModal>", + "description": "Checkbox label for Level IT-03 advisor selection, ignore things in <> tags please" + }, + "oUDpNl": { + "defaultMessage": "<strong>Cheminement en gestion</strong> : les gestionnaires de la <abbreviation>TI</abbreviation> (<abbreviation>TI-04</abbreviation>) sont responsables de la gestion du développement et de la prestation des services et des activités de <abbreviation>TI</abbreviation> par l'entremise de chefs d'équipe subalternes, de conseillers techniques et d'équipes de projet, pour la prestation des services aux clients et aux intervenants. Les gestionnaires de la <abbreviation>TI</abbreviation> se trouvent dans tous les volets de travail.", + "description": "IT-04 manager path description, ignore things in <> tags please" + }, + "oZ03/b": { + "defaultMessage": "Cette plateforme met l'accent sur l'embauche de talents numériques pour travailler dans des postes classifiés comme <abbreviation>TI</abbreviation> (technologie de l'information). Examinez les niveaux suivants dans la classification <abbreviation>TI</abbreviation> et <strong>sélectionnez uniquement</strong> ceux qui représentent le travail que vous voulez faire.", + "description": "Blurb describing the purpose of the form" + }, + "pIiisf": { + "defaultMessage": "Si vous n’êtes pas sûr de vouloir fournir vos renseignements, ou si vous avez des questions concernant le programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones, veuillez <link>nous contacter</link> nous serons heureux de vous rencontrer.", + "description": "Text describing where to get help with the self-declaration form" + }, + "pRGDLn": { + "defaultMessage": "Apprenti en <abbreviation>TI</abbreviation> du Gouvernement du Canada", + "description": "author of testimonial number one" + }, + "tM1de5": { + "defaultMessage": "Parcourez les offres dans le domaine des <abbreviation>TI</abbreviation>", + "description": "Page title for the direct intake browse pools page." + }, + "uD7QTb": { + "defaultMessage": "Il appartient aux gestionnaires de gérer l’élaboration et la prestation de services et (ou) d’opérations de <abbreviation>TI</abbreviation> par l’entremise de chefs d’équipe subalternes, de conseillers techniques et d’équipes de projet.", + "description": "Description for the 'IT-04 Manager' classification, paragraph 1" + }, + "uT/A3r": { + "defaultMessage": "Niveau 2 : Analyste (de 75 000 $ à 91 000 $). <openModal>En savoir plus sur <abbreviation>TI-02</abbreviation></openModal>", + "description": "Checkbox label for Level IT-02 selection, ignore things in <> tags please" + }, + "vbEXnp": { + "defaultMessage": "Gestion de bases de données de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'database management' IT work stream" + }, + "wzoCfb": { + "defaultMessage": "Sécurité de la <abbreviation>TI</abbreviation>", + "description": "Title for the 'security' IT work stream" + }, + "xIwrND": { + "defaultMessage": "Niveau 1 : Technicien(ne) (de 60 000 $ à 78 000 $). <openModal>En savoir plus sur <abbreviation>TI-01</abbreviation></openModal>", + "description": "Checkbox label for Level IT-01 selection, ignore things in <> tags please" + }, + "y+HB+k": { + "defaultMessage": "Gestion de la base de données de la <abbreviation>TI</abbreviation>", + "description": "work stream example" } } diff --git a/apps/web/src/pages/Home/HomePage/components/Featured/Block.tsx b/apps/web/src/pages/Home/HomePage/components/Featured/Block.tsx index 5b8d9b0c4a5..f0108197787 100644 --- a/apps/web/src/pages/Home/HomePage/components/Featured/Block.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Featured/Block.tsx @@ -6,7 +6,7 @@ import Heading from "@common/components/Heading"; export interface FeatureBlockProps { content: { title: string; - summary: string; + summary: React.ReactNode; img: { path: string; }; diff --git a/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx b/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx index b3d33e4a994..5b442ef1e0d 100644 --- a/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx @@ -6,6 +6,7 @@ import imageUrl from "@common/helpers/imageUrl"; import Heading from "@common/components/Heading"; import { getLocale } from "@common/helpers/localize"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import Block from "./Block"; // Create the page component @@ -72,13 +73,18 @@ const Featured = () => { id: "nYA+Tj", description: "Title for the Indigenous tech talent feature item", }), - summary: intl.formatMessage({ - defaultMessage: - "Are you looking for entry-level IT talent and want to support diversity, inclusion, and reconciliation? Connect with the IT Apprenticeship Program for Indigenous Peoples and start the process to hire Indigenous apprentices today!", - id: "cYg+l1", - description: - "Summary of the Indigenous Apprenticeship Program for the homepage", - }), + summary: intl.formatMessage( + { + defaultMessage: + "Are you looking for entry-level <abbreviation>IT</abbreviation> talent and want to support diversity, inclusion, and reconciliation? Connect with the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples and start the process to hire Indigenous apprentices today!", + id: "LOvD2e", + description: + "Summary of the Indigenous Apprenticeship Program for the homepage", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + ), img: { path: imageUrl("/", "check_it_out_IAP_manager_callout.jpg"), }, diff --git a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx index f9174c229b7..c0873f48608 100644 --- a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx @@ -11,6 +11,7 @@ import imageUrl from "@common/helpers/imageUrl"; import { AuthenticationContext } from "@common/components/Auth"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; // Create the page component const Opportunities = () => { @@ -92,12 +93,19 @@ const Opportunities = () => { })} link={{ href: paths.allPools(), - label: intl.formatMessage({ - defaultMessage: "Browse IT jobs", - id: "zNvXSs", - description: - "Link text for IT jobs in government call to action", - }), + label: intl.formatMessage( + { + defaultMessage: + "Browse <abbreviation>IT</abbreviation> jobs", + id: "0mAZsV", + description: + "Link text for IT jobs in government call to action", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + ), }} > <p> @@ -131,13 +139,19 @@ const Opportunities = () => { }} > <p> - {intl.formatMessage({ - defaultMessage: - "Designed by the Indigenous community for the Indigenous community, this program recruits entry-level applicants for learning and development IT opportunities across government.", - id: "f3Qqop", - description: - "Description for the Indigenous Apprenticeship Program on home page", - })} + {intl.formatMessage( + { + defaultMessage: + "Designed by the Indigenous community for the Indigenous community, this program recruits entry-level applicants for learning and development <abbreviation>IT</abbreviation> opportunities across government.", + id: "FtJRWS", + description: + "Description for the Indigenous Apprenticeship Program on home page", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> <CardFlat diff --git a/apps/web/src/pages/Home/IAPHomePage/Home.tsx b/apps/web/src/pages/Home/IAPHomePage/Home.tsx index 3cb22d2417e..b1649537677 100644 --- a/apps/web/src/pages/Home/IAPHomePage/Home.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/Home.tsx @@ -6,6 +6,7 @@ import imageUrl from "@common/helpers/imageUrl"; import useQuote from "~/hooks/useQuote"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import Banner from "./components/Banner"; import Card from "./components/Card"; import CTAButtons from "./components/CTAButtons"; @@ -88,13 +89,18 @@ const Home: React.FunctionComponent = () => { alt="" /> <span data-h2-visually-hidden="base(invisible)"> - {intl.formatMessage({ - defaultMessage: - "IT Apprenticeship Program for Indigenous Peoples. Apply today to get started on your IT career journey.", - id: "qZvV7b", - description: - "Homepage title for Indigenous Apprenticeship Program", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples. Apply today to get started on your <abbreviation>IT</abbreviation> career journey.", + id: "7Kb+Uh", + description: + "Homepage title for Indigenous Apprenticeship Program", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </span> </h1> </div> @@ -192,8 +198,8 @@ const Home: React.FunctionComponent = () => { <p data-h2-margin="base(x2, 0, x1, 0)"> {intl.formatMessage({ defaultMessage: - "The IT Apprenticeship Program for Indigenous Peoples is a Government of Canada initiative specifically for First Nations, Inuit, and Métis peoples. It is pathway to employment in the federal public service for Indigenous peoples who have a passion for Information Technology (IT).", - id: "pWoAv0", + "The <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples is a Government of Canada initiative specifically for First Nations, Inuit, and Métis peoples. It is pathway to employment in the federal public service for Indigenous peoples who have a passion for Information Technology (IT).", + id: "UMPxOg", description: "First paragraph about the program", })} </p> @@ -486,8 +492,8 @@ const Home: React.FunctionComponent = () => { <span data-h2-display="base(block)"> {intl.formatMessage({ defaultMessage: - "Is the IT Apprenticeship Program right for you?", - id: "DgMIfz", + "Is the <abbreviation>IT</abbreviation> Apprenticeship Program right for you?", + id: "W2G590", description: "Application box heading part one", })} </span> @@ -568,8 +574,8 @@ const Home: React.FunctionComponent = () => { > {intl.formatMessage({ defaultMessage: - "IT Apprenticeship Program for Indigenous Peoples + The Indigenous Talent Portal", - id: "osGGIt", + "<abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples + The Indigenous Talent Portal", + id: "Zd1x6H", description: "heading for indigenous talent portal section", })} </Heading> @@ -636,8 +642,8 @@ const Home: React.FunctionComponent = () => { <p data-h2-margin="base(x1, 0, 0, 0)"> {intl.formatMessage({ defaultMessage: - "We want to learn about you and about your interest/passion in the area of IT!", - id: "yZMQ6j", + "We want to learn about you and about your interest/passion in the area of <abbreviation>IT</abbreviation>!", + id: "gxOExQ", description: "How it works, step 2 content sentence 1", })} </p> @@ -695,8 +701,8 @@ const Home: React.FunctionComponent = () => { > {intl.formatMessage({ defaultMessage: - "In collaboration with the IT Apprenticeship Program for Indigenous Peoples, the Indigenous Talent Portal will begin with a focus on IT and technology talent, which will:", - id: "Dzyk1q", + "In collaboration with the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples, the Indigenous Talent Portal will begin with a focus on <abbreviation>IT</abbreviation> and technology talent, which will:", + id: "9FKjvW", description: "Description for strategy for the indigenous talent portal", })} @@ -715,8 +721,8 @@ const Home: React.FunctionComponent = () => { <p> {intl.formatMessage({ defaultMessage: - "Address the great demand for Indigenous talent in IT.", - id: "Xhfkfg", + "Address the great demand for Indigenous talent in <abbreviation>IT</abbreviation>.", + id: "cMDC/P", description: "Talent portal strategy item 1 content", })} </p> diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx index 4fe9fb540eb..73b08cc9f71 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx @@ -3,6 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import CloseButton from "./CloseButton"; import { BasicDialogProps } from "./types"; @@ -41,22 +42,28 @@ const ApplyDialog = ({ btnProps }: BasicDialogProps) => { {intl.formatMessage( { defaultMessage: - "Please send your resume and cover letter explaining your passion for IT and why you're interested in joining the program to: <mailLink>edsc.pda-iap.esdc@hrsdc-rhdcc.gc.ca</mailLink>. A team member will contact you in 3-5 business days", - id: "EqVMCE", + "Please send your resume and cover letter explaining your passion for <abbreviation>IT</abbreviation> and why you're interested in joining the program to: <mailLink>edsc.pda-iap.esdc@hrsdc-rhdcc.gc.ca</mailLink>. A team member will contact you in 3-5 business days", + id: "BxAUGH", description: "First paragraph for apply now dialog", }, { mailLink: mailAccessor, + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, )} </p> <p data-h2-margin="base(x1, 0, 0, 0)"> - {intl.formatMessage({ - defaultMessage: - "We want to let you know that in the meantime, updates are being made on this site that will allow Indigenous peoples who are interested in joining the IT Apprenticeship Program to apply online.", - id: "BSSYnh", - description: "Second paragraph for apply now dialog", - })} + {intl.formatMessage( + { + defaultMessage: + "We want to let you know that in the meantime, updates are being made on this site that will allow Indigenous peoples who are interested in joining the <abbreviation>IT</abbreviation> Apprenticeship Program to apply online.", + id: "2MQK8R", + description: "Second paragraph for apply now dialog", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p data-h2-margin="base(x1, 0, 0, 0)"> {intl.formatMessage({ diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx index bb76fdaba57..f69269b468f 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx @@ -4,6 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import Heading from "../Heading"; import CloseButton from "./CloseButton"; @@ -25,24 +26,34 @@ const LearnDialog = ({ btnProps }: BasicDialogProps) => { </Dialog.Trigger> <Dialog.Content> <Dialog.Header color="ia-secondary"> - {intl.formatMessage({ - defaultMessage: - "Learn More About the Government of Canada IT Apprenticeship Program for Indigenous Peoples", - id: "L9yjr3", - description: "Heading for the Learn more dialog", - })} + {intl.formatMessage( + { + defaultMessage: + "Learn More About the Government of Canada <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples", + id: "Ea8q/H", + description: "Heading for the Learn more dialog", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </Dialog.Header> <Heading as="h3" data-h2-font-size="base(h6, 1.3)" data-h2-margin="base(0)" > - {intl.formatMessage({ - defaultMessage: - "Who can apply to become an apprentice as part of the Government of Canada IT Apprenticeship Program for Indigenous Peoples?", - id: "p2sBh3", - description: "Learn more dialog question one heading", - })} + {intl.formatMessage( + { + defaultMessage: + "Who can apply to become an apprentice as part of the Government of Canada <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples?", + id: "9Nf78m", + description: "Learn more dialog question one heading", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </Heading> <p data-h2-margin="base(x1, 0)"> {intl.formatMessage({ diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx index 4db7db55cfe..737501d4cac 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx @@ -4,6 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import CloseButton from "./CloseButton"; import type { BasicDialogProps } from "./types"; @@ -27,13 +28,18 @@ const SelfDeclarationDialog = ({ children, btnProps }: BasicDialogProps) => { })} </Dialog.Header> <p data-h2-margin="base(x1, 0)"> - {intl.formatMessage({ - defaultMessage: - "We recognize the importance of Indigenous voices in the federal government. The goal of the IT Apprenticeship Program for Indigenous Peoples is to amplify Indigenous voices by creating opportunities for First Nations, Inuit, and Métis peoples to join the federal public service.", - id: "J2uivT", - description: - "Paragraph one for the self-declaration explanation dialog", - })} + {intl.formatMessage( + { + defaultMessage: + "We recognize the importance of Indigenous voices in the federal government. The goal of the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples is to amplify Indigenous voices by creating opportunities for First Nations, Inuit, and Métis peoples to join the federal public service.", + id: "RCV8Us", + description: + "Paragraph one for the self-declaration explanation dialog", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p data-h2-margin="base(x1, 0)"> {intl.formatMessage({ diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx index ab7b3d04116..20f0cc0928d 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx @@ -22,6 +22,7 @@ import { import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import ActiveRecruitmentSection from "./components/ActiveRecruitmentSection/ActiveRecruitmentSection"; import OngoingRecruitmentSection from "./components/OngoingRecruitmentSection/OngoingRecruitmentSection"; @@ -52,11 +53,16 @@ export const BrowsePools: React.FC<BrowsePoolsProps> = ({ const paths = useRoutes(); const featureFlags = useFeatureFlags(); - const title = intl.formatMessage({ - defaultMessage: "Browse IT jobs", - id: "J2WrFI", - description: "Page title for the direct intake browse pools page.", - }); + const title = intl.formatMessage( + { + defaultMessage: "Browse <abbreviation>IT</abbreviation> jobs", + id: "tM1de5", + description: "Page title for the direct intake browse pools page.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + ); const crumbs = useBreadcrumbs([ { @@ -229,13 +235,18 @@ export const BrowsePools: React.FC<BrowsePoolsProps> = ({ > <CardFlat color="purple" - title={intl.formatMessage({ - defaultMessage: - "Browse IT opportunities for the Indigenous community", - id: "GZrICV", - description: - "Title for Indigenous community job opportunities on Browse IT jobs page", - })} + title={intl.formatMessage( + { + defaultMessage: + "Browse <abbreviation>IT</abbreviation> opportunities for the Indigenous community", + id: "drDPf3", + description: + "Title for Indigenous community job opportunities on Browse IT jobs page", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} link={{ href: `${paths.home()}/indigenous-it-apprentice`, mode: "outline", @@ -250,13 +261,19 @@ export const BrowsePools: React.FC<BrowsePoolsProps> = ({ }} > <p> - {intl.formatMessage({ - defaultMessage: - "Designed by, with, and for the Indigenous community, the program recruits First Nations, Inuit, and Métis applicants who have a passion for IT, for entry level employment, learning and development opportunities.", - id: "+6QgII", - description: - "Summary for Indigenous community job opportunities on Browse IT jobs page", - })} + {intl.formatMessage( + { + defaultMessage: + "Designed by, with, and for the Indigenous community, the program recruits First Nations, Inuit, and Métis applicants who have a passion for <abbreviation>IT</abbreviation>, for entry level employment, learning and development opportunities.", + id: "OvL68O", + description: + "Summary for Indigenous community job opportunities on Browse IT jobs page", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> <CardFlat @@ -279,13 +296,19 @@ export const BrowsePools: React.FC<BrowsePoolsProps> = ({ }} > <p> - {intl.formatMessage({ - defaultMessage: - "Let our team save you time and energy by matching your needs to pre-qualified IT professionals with the right skills for the job. All the talent in our pools has been qualified through a competitive process, so you can jump straight to the interview and decide if they are a good fit for your team.", - id: "Ms6O4W", - description: - "Summary for to go to the search page on Browse IT jobs page", - })} + {intl.formatMessage( + { + defaultMessage: + "Let our team save you time and energy by matching your needs to pre-qualified <abbreviation>IT</abbreviation> professionals with the right skills for the job. All the talent in our pools has been qualified through a competitive process, so you can jump straight to the interview and decide if they are a good fit for your team.", + id: "6UVZOY", + description: + "Summary for to go to the search page on Browse IT jobs page", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> </div> diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts b/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts index ad8803760f5..39d276fd465 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts @@ -3,21 +3,22 @@ import { defineMessages } from "react-intl"; const messages = defineMessages({ // title and summary for each stream businessAdvisoryServicesTitle: { - defaultMessage: "IT business line advisory services", - id: "EOO6S0", + defaultMessage: + "<abbreviation>IT</abbreviation> business line advisory services", + id: "H8cs1r", description: "Title for the 'business line advisory services' IT work stream", }, businessAdvisoryServicesSummary: { defaultMessage: - "This stream includes providing specialized IT guidance as well as working with clients and/or suppliers to acquire and sustain IT resources that support Government operation.", - id: "QN/1MR", + "This stream includes providing specialized <abbreviation>IT</abbreviation> guidance as well as working with clients and/or suppliers to acquire and sustain <abbreviation>IT</abbreviation> resources that support Government operation.", + id: "iA1BBF", description: "Title for the 'business line advisory services' IT work stream", }, databaseManagementTitle: { - defaultMessage: "IT database management", - id: "pffFnd", + defaultMessage: "<abbreviation>IT</abbreviation> database management", + id: "vbEXnp", description: "Title for the 'database management' IT work stream", }, databaseManagementSummary: { @@ -27,52 +28,53 @@ const messages = defineMessages({ description: "Title for the 'database management' IT work stream", }, enterpriseArchitectureTitle: { - defaultMessage: "IT enterprise architecture", - id: "C2iUvf", + defaultMessage: "<abbreviation>IT</abbreviation> enterprise architecture", + id: "eFNBND", description: "Title for the 'enterprise architecture' IT work stream", }, enterpriseArchitectureSummary: { defaultMessage: - "This stream includes working with the departmental IT architecture direction, collaborating with other IT streams, and conducting research into emerging technologies.", - id: "DVkO+D", + "This stream includes working with the departmental <abbreviation>IT</abbreviation> architecture direction, collaborating with other <abbreviation>IT</abbreviation> streams, and conducting research into emerging technologies.", + id: "OqglGZ", description: "Title for the 'enterprise architecture' IT work stream", }, infrastructureOperationsTitle: { - defaultMessage: "IT infrastructure operations", - id: "ElfiAv", + defaultMessage: "<abbreviation>IT</abbreviation> infrastructure operations", + id: "6G1ESr", description: "Title for the 'infrastructure operations' IT work stream", }, infrastructureOperationsSummary: { defaultMessage: - "This stream includes infrastructure management of networks, mainframes, servers, and storage, providing IT support, and client/supplier relationships.", - id: "svCFrY", + "This stream includes infrastructure management of networks, mainframes, servers, and storage, providing <abbreviation>IT</abbreviation> support, and client/supplier relationships.", + id: "Xdmhoo", description: "Title for the 'infrastructure operations' IT work stream", }, planningAndReportingTitle: { - defaultMessage: "IT planning and reporting", - id: "VX2+ET", + defaultMessage: "<abbreviation>IT</abbreviation> planning and reporting", + id: "E3loNV", description: "Title for the 'planning and reporting' IT work stream", }, planningAndReportingSummary: { defaultMessage: - "This stream includes providing specialized IT planning guidance, and the collaborative creation of deliverables that include strategic plans, IT policies and standards, and governance processes.", - id: "crqgGQ", + "This stream includes providing specialized <abbreviation>IT</abbreviation> planning guidance, and the collaborative creation of deliverables that include strategic plans, <abbreviation>IT</abbreviation> policies and standards, and governance processes.", + id: "/R/S8P", description: "Title for the 'planning and reporting' IT work stream", }, projectPortfolioManagementTitle: { - defaultMessage: "IT project portfolio management", - id: "aL5y0G", + defaultMessage: + "<abbreviation>IT</abbreviation> project portfolio management", + id: "AlRcyu", description: "Title for the 'project portfolio management' IT work stream", }, projectPortfolioSummary: { defaultMessage: - "This bucket includes working full-time on large, formal projects that require the sharing of and application of rigorous application of IT project management skills and knowledge.", - id: "h5CY+u", + "This bucket includes working full-time on large, formal projects that require the sharing of and application of rigorous application of <abbreviation>IT</abbreviation> project management skills and knowledge.", + id: "hKKYYL", description: "Title for the 'project portfolio management' IT work stream", }, securityTitle: { - defaultMessage: "IT security", - id: "uxlNWH", + defaultMessage: "<abbreviation>IT</abbreviation> security", + id: "wzoCfb", description: "Title for the 'security' IT work stream", }, securitySummary: { @@ -82,8 +84,8 @@ const messages = defineMessages({ description: "Title for the 'security' IT work stream", }, softwareSolutionsTitle: { - defaultMessage: "IT software solutions", - id: "4CT5zI", + defaultMessage: "<abbreviation>IT</abbreviation> software solutions", + id: "Tjd942", description: "Title for the 'software solutions' IT work stream", }, softwareSolutionsSummary: { @@ -95,8 +97,8 @@ const messages = defineMessages({ // title and description for each it level it01Title: { - defaultMessage: "Technician (IT-01)", - id: "MiBPoz", + defaultMessage: "Technician (<abbreviation>IT-01</abbreviation>)", + id: "GtZyhK", description: "Title for the 'IT-01 Technician' classification", }, it01Description: { @@ -113,8 +115,8 @@ const messages = defineMessages({ "Invitation to apply for the 'IT-01 Technician' classification", }, it02Title: { - defaultMessage: "Analyst (IT-02)", - id: "+ywDV8", + defaultMessage: "Analyst (<abbreviation>IT-02</abbreviation>)", + id: "I/fGUN", description: "Title for the 'IT-02 Analyst' classification", }, it02Description: { @@ -129,8 +131,9 @@ const messages = defineMessages({ description: "Invitation to apply for the 'IT-02 Analyst' classification", }, it03Title: { - defaultMessage: "Team Lead and Technical Advisor (IT-03)", - id: "xtIE4i", + defaultMessage: + "Team Lead and Technical Advisor (<abbreviation>IT-03</abbreviation>)", + id: "S02Y/P", description: "Title for the 'IT-03 Advisor' classification", }, it03Description1: { @@ -154,14 +157,15 @@ const messages = defineMessages({ description: "Invitation to apply for the 'IT-03 Advisor' classification", }, it04Title: { - defaultMessage: "Manager and Senior Advisor (IT-04)", - id: "Jwj3YC", + defaultMessage: + "Manager and Senior Advisor (<abbreviation>IT-04</abbreviation>)", + id: "KpNUo0", description: "Title for the 'IT-04 Manager' classification", }, it04Description1: { defaultMessage: - "Managers are responsible for managing the development and delivery of IT services and/or operations through subordinate team leaders, technical advisors, and project teams.", - id: "d4OJ5V", + "Managers are responsible for managing the development and delivery of <abbreviation>IT</abbreviation> services and/or operations through subordinate team leaders, technical advisors, and project teams.", + id: "uD7QTb", description: "Description for the 'IT-04 Manager' classification, paragraph 1", }, diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx index 3510e8df7cd..8a7cdcb41e3 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx @@ -45,6 +45,7 @@ import useRoutes from "~/hooks/useRoutes"; import { TALENTSEARCH_RECRUITMENT_EMAIL } from "~/constants/talentSearchConstants"; import { isAdvertisementVisible } from "~/utils/poolUtils"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import PoolInfoCard from "./components/PoolInfoCard"; import ClassificationDefinition from "./components/ClassificationDefinition"; @@ -345,13 +346,19 @@ export const PoolAdvertisementPoster = ({ })} </Text> <Text> - {intl.formatMessage({ - defaultMessage: - "When hiring managers have IT staffing needs and positions become available, applicants who meet the qualifications for this process may be contacted for further assessment. This means various managers may reach out to you about specific opportunities in the area of application development.", - id: "m5hjaz", - description: - "Description of pool recruitment, paragraph two", - })} + {intl.formatMessage( + { + defaultMessage: + "When hiring managers have <abbreviation>IT</abbreviation> staffing needs and positions become available, applicants who meet the qualifications for this process may be contacted for further assessment. This means various managers may reach out to you about specific opportunities in the area of application development.", + id: "LlgRM8", + description: + "Description of pool recruitment, paragraph two", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </Text> </Accordion.Content> </Accordion.Item> diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx index b7775a615c8..442315991cf 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx @@ -1,5 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import { GenericJobTitleKey } from "~/api/generated"; @@ -8,12 +9,17 @@ const LevelOne = () => { return ( <p> - {intl.formatMessage({ - defaultMessage: - "Technicians (IT-01) provide technical support in the development, implementation, integration, and maintenance of service delivery to clients and stakeholders", - id: "Z9Uex5", - description: "blurb describing IT-01", - })} + {intl.formatMessage( + { + defaultMessage: + "Technicians (<abbreviation>IT-01</abbreviation>) provide technical support in the development, implementation, integration, and maintenance of service delivery to clients and stakeholders", + id: "j3OROA", + description: "blurb describing IT-01", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> ); }; @@ -23,12 +29,17 @@ const LevelTwo = () => { return ( <p> - {intl.formatMessage({ - defaultMessage: - "Analysts (IT-02) provide technical services, advice, analysis, and research in their field of expertise to support service delivery to clients and stakeholders. IT analysts are found in all work streams.", - id: "raFdbB", - description: "blurb describing IT-02", - })} + {intl.formatMessage( + { + defaultMessage: + "Analysts (<abbreviation>IT-02</abbreviation>) provide technical services, advice, analysis, and research in their field of expertise to support service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> analysts are found in all work streams.", + id: "/SLyVF", + description: "blurb describing IT-02", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> ); }; @@ -39,21 +50,31 @@ const LevelThreeLead = () => { return ( <> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-03 employees: those following a management path, and individual contributors.", - id: "hCgrxA", - description: "IT-03 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-03</abbreviation> employees: those following a management path, and individual contributors.", + id: "7wcfnG", + description: "IT-03 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Management Path</strong>: IT Team Leads (IT-03) are responsible for supervising work and project teams for IT services and operations in their field of expertise to support service delivery to clients and stakeholders. IT Team Leads are found in all work streams.", - id: "+bC9lc", - description: - "IT-03 team lead path description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Management Path</strong>: <abbreviation>IT</abbreviation> Team Leads (<abbreviation>IT-03</abbreviation>) are responsible for supervising work and project teams for <abbreviation>IT</abbreviation> services and operations in their field of expertise to support service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Team Leads are found in all work streams.", + id: "QdYrqI", + description: + "IT-03 team lead path description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </> ); @@ -65,21 +86,31 @@ const LevelThreeAdvisor = () => { return ( <> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-03 employees: those following a management path, and individual contributors.", - id: "hCgrxA", - description: "IT-03 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-03</abbreviation> employees: those following a management path, and individual contributors.", + id: "7wcfnG", + description: "IT-03 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Individual Contributor</strong>: IT Technical Advisors (IT-03) provide specialized technical advice, recommendations and support on solutions and services in their field of expertise in support of service delivery to clients and stakeholders. IT Technical Advisors are found in all work streams.", - id: "u+9mg1", - description: - "IT-03 advisor description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Individual Contributor</strong>: <abbreviation>IT</abbreviation> Technical Advisors (<abbreviation>IT-03</abbreviation>) provide specialized technical advice, recommendations and support on solutions and services in their field of expertise in support of service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Technical Advisors are found in all work streams.", + id: "CIwCa3", + description: + "IT-03 advisor description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </> ); @@ -91,21 +122,31 @@ const LevelFourManager = () => { return ( <> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-04 employees: those following a management path, and individual contributors.", - id: "87nFC8", - description: "IT-04 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-04</abbreviation> employees: those following a management path, and individual contributors.", + id: "2aBKgf", + description: "IT-04 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Management Path</strong>: IT Managers (IT-04) are responsible for managing the development and delivery of IT services and/or operations through subordinate team leaders, technical advisors, and project teams, for service delivery to clients and stakeholders. IT Managers are found in all work streams.", - id: "m21EOJ", - description: - "IT-04 manager path description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Management Path</strong>: <abbreviation>IT</abbreviation> Managers (<abbreviation>IT-04</abbreviation>) are responsible for managing the development and delivery of <abbreviation>IT</abbreviation> services and/or operations through subordinate team leaders, technical advisors, and project teams, for service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Managers are found in all work streams.", + id: "oUDpNl", + description: + "IT-04 manager path description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </> ); @@ -117,21 +158,31 @@ const LevelFourAdvisor = (): JSX.Element => { return ( <> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-04 employees: those following a management path, and individual contributors.", - id: "87nFC8", - description: "IT-04 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-04</abbreviation> employees: those following a management path, and individual contributors.", + id: "2aBKgf", + description: "IT-04 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Individual Contributor</strong>: IT Senior Advisors (IT-04) provide expert technical advice and strategic direction in their field of expertise in the provision of solutions and services to internal or external clients, and stakeholders.", - id: "VQWGkh", - description: - "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Individual Contributor</strong>: <abbreviation>IT</abbreviation> Senior Advisors (<abbreviation>IT-04</abbreviation>) provide expert technical advice and strategic direction in their field of expertise in the provision of solutions and services to internal or external clients, and stakeholders.", + id: "OheHgg", + description: + "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </> ); diff --git a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx index a802403e2cc..7953d89c5ef 100644 --- a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx +++ b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx @@ -11,6 +11,7 @@ import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import EquityOptions from "./EquityOptions"; import type { EmploymentEquityUpdateHandler, EquityKeys } from "../../types"; @@ -112,13 +113,18 @@ const EmploymentEquityForm: React.FC<EmploymentEquityFormProps> = ({ </p> <Well data-h2-margin="base(x2, 0, 0, 0)"> <p data-h2-margin="base(0, 0, x.5, 0)"> - {intl.formatMessage({ - defaultMessage: - "<strong>This section is optional, however, to be considered eligible for the IT Apprenticeship Program for Indigenous Peoples, you must self declare as Indigenous.</strong> If you are a member of one or more of these employment equity groups, and you do not wish to self identify on this platform, there is no obligation to do so. <strong>Complete the form below if you meet both of these conditions:</strong>", - id: "okZjVr", - description: - "Explanation that employment equity information is optional.", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>This section is optional, however, to be considered eligible for the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples, you must self declare as Indigenous.</strong> If you are a member of one or more of these employment equity groups, and you do not wish to self identify on this platform, there is no obligation to do so. <strong>Complete the form below if you meet both of these conditions:</strong>", + id: "Nj6c0X", + description: + "Explanation that employment equity information is optional.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <ul> <li> diff --git a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx index df420b650cf..2f8b55c35cd 100644 --- a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx +++ b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx @@ -32,6 +32,7 @@ import { ExperienceType } from "~/types/experience"; import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; type MergedExperiences = Array< | AwardExperience @@ -173,13 +174,18 @@ export const ExperienceAndSkills: React.FunctionComponent< <ProfileFormWrapper prefixBreadcrumbs={!poolAdvertisement} crumbs={crumbs} - description={intl.formatMessage({ - defaultMessage: - "Here is where you can add experiences and skills to your profile. This could be anything from helping community members troubleshoot their computers to full-time employment at an IT organization.", - id: "GAjpqU", - description: - "Description for the experience and skills page in applicant profile.", - })} + description={intl.formatMessage( + { + defaultMessage: + "Here is where you can add experiences and skills to your profile. This could be anything from helping community members troubleshoot their computers to full-time employment at an <abbreviation>IT</abbreviation> organization.", + id: "Ks4G8p", + description: + "Description for the experience and skills page in applicant profile.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} title={intl.formatMessage({ defaultMessage: "My experience and skills", id: "KE49r9", diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx index f6cf3eb135c..23fdc5216e7 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx @@ -27,6 +27,7 @@ import ProfileFormWrapper, { import profileMessages from "~/messages/profileMessages"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import { DialogLevelOne, DialogLevelTwo, @@ -188,12 +189,17 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ }} > <p data-h2-margin="base(0, 0, x2, 0)"> - {intl.formatMessage({ - defaultMessage: - "This platform is focused on hiring digital talent to work in positions classified as IT (Information Technology). Look at the following levels within the IT classification and <strong>select only</strong> the ones that represent the work you want to do.", - id: "Eubngf", - description: "Blurb describing the purpose of the form", - })} + {intl.formatMessage( + { + defaultMessage: + "This platform is focused on hiring digital talent to work in positions classified as <abbreviation>IT</abbreviation> (Information Technology). Look at the following levels within the <abbreviation>IT</abbreviation> classification and <strong>select only</strong> the ones that represent the work you want to do.", + id: "oZ03/b", + description: "Blurb describing the purpose of the form", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Checklist idPrefix="expectedGenericJobTitles" @@ -209,14 +215,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 1: Technician ($60,000 to $78,000). <openModal>Learn about IT-01</openModal>", - id: "Zn10pO", + "Level 1: Technician ($60,000 to $78,000). <openModal>Learn about <abbreviation>IT-01</abbreviation></openModal>", + id: "xIwrND", description: "Checkbox label for Level IT-01 selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelOne({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, @@ -225,14 +232,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 2: Analyst ($75,000 to $91,000). <openModal>Learn about IT-02</openModal>", - id: "PcYOnN", + "Level 2: Analyst ($75,000 to $91,000). <openModal>Learn about <abbreviation>IT-02</abbreviation></openModal>", + id: "uT/A3r", description: "Checkbox label for Level IT-02 selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelTwo({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, @@ -241,14 +249,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 3: Team Leader ($88,000 to $110,000). <openModal>Learn about IT-03</openModal>", - id: "hizC89", + "Level 3: Team Leader ($88,000 to $110,000). <openModal>Learn about <abbreviation>IT-03</abbreviation></openModal>", + id: "L6sIvM", description: "Checkbox label for Level IT-03 leader selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelThreeLead({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, @@ -257,14 +266,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 3: Technical Advisor ($88,000 to $110,000). <openModal>Learn about IT-03</openModal>", - id: "44bgIY", + "Level 3: Technical Advisor ($88,000 to $110,000). <openModal>Learn about <abbreviation>IT-03</abbreviation></openModal>", + id: "jZDflg", description: "Checkbox label for Level IT-03 advisor selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelThreeAdvisor({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, @@ -273,14 +283,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 4: Senior Advisor ($101,000 to $126,000). <openModal>Learn about IT-04</openModal>", - id: "FayQOt", + "Level 4: Senior Advisor ($101,000 to $126,000). <openModal>Learn about <abbreviation>IT-04</abbreviation></openModal>", + id: "bNBhvY", description: "Checkbox label for Level IT-04 senior advisor selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelFourAdvisor({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, @@ -289,14 +300,15 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ label: intl.formatMessage( { defaultMessage: - "Level 4: Manager ($101,000 to $126,000). <openModal>Learn about IT-04</openModal>", - id: "75nLSV", + "Level 4: Manager ($101,000 to $126,000). <openModal>Learn about <abbreviation>IT-04</abbreviation></openModal>", + id: "EGXG1j", description: "Checkbox label for Level IT-04 manager selection, ignore things in <> tags please", }, { openModal: (msg: React.ReactNode) => DialogLevelFourLead({ children: msg }), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, ), }, diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx index 1b6d942edf7..021b31aec7f 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx @@ -3,6 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; export interface DialogLevelsProps { children: React.ReactNode; @@ -60,42 +61,69 @@ export const DialogLevelOne = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "Technicians (IT-01) provide technical support in the development, implementation, integration, and maintenance of service delivery to clients and stakeholders", - id: "Z9Uex5", - description: "blurb describing IT-01", - })} + {intl.formatMessage( + { + defaultMessage: + "Technicians (<abbreviation>IT-01</abbreviation>) provide technical support in the development, implementation, integration, and maintenance of service delivery to clients and stakeholders", + id: "j3OROA", + description: "blurb describing IT-01", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "IT Technicians are primarily found in three work streams: ", - id: "vQzmUH", - description: "Preceding list description", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Technicians are primarily found in three work streams: ", + id: "69euaM", + description: "Preceding list description", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <ul> <li> - {intl.formatMessage({ - defaultMessage: "IT Infrastructure Operations", - id: "QZ9FZB", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Infrastructure Operations", + id: "028BJx", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Security", - id: "nrBkon", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: "<abbreviation>IT</abbreviation> Security", + id: "3gDiDK", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Software Solutions", - id: "SDDp1t", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Software Solutions", + id: "ObVJ7H", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> </ul> <Dialog.Footer> @@ -131,12 +159,17 @@ export const DialogLevelTwo = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "Analysts (IT-02) provide technical services, advice, analysis, and research in their field of expertise to support service delivery to clients and stakeholders. IT analysts are found in all work streams.", - id: "raFdbB", - description: "blurb describing IT-02", - })} + {intl.formatMessage( + { + defaultMessage: + "Analysts (<abbreviation>IT-02</abbreviation>) provide technical services, advice, analysis, and research in their field of expertise to support service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> analysts are found in all work streams.", + id: "/SLyVF", + description: "blurb describing IT-02", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Dialog.Footer> <Dialog.Close> @@ -171,21 +204,31 @@ export const DialogLevelThreeLead = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-03 employees: those following a management path, and individual contributors.", - id: "hCgrxA", - description: "IT-03 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-03</abbreviation> employees: those following a management path, and individual contributors.", + id: "7wcfnG", + description: "IT-03 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Management Path</strong>: IT Team Leads (IT-03) are responsible for supervising work and project teams for IT services and operations in their field of expertise to support service delivery to clients and stakeholders. IT Team Leads are found in all work streams.", - id: "+bC9lc", - description: - "IT-03 team lead path description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Management Path</strong>: <abbreviation>IT</abbreviation> Team Leads (<abbreviation>IT-03</abbreviation>) are responsible for supervising work and project teams for <abbreviation>IT</abbreviation> services and operations in their field of expertise to support service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Team Leads are found in all work streams.", + id: "QdYrqI", + description: + "IT-03 team lead path description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Dialog.Footer> <Dialog.Close> @@ -220,21 +263,31 @@ export const DialogLevelThreeAdvisor = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-03 employees: those following a management path, and individual contributors.", - id: "hCgrxA", - description: "IT-03 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-03</abbreviation> employees: those following a management path, and individual contributors.", + id: "7wcfnG", + description: "IT-03 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Individual Contributor</strong>: IT Technical Advisors (IT-03) provide specialized technical advice, recommendations and support on solutions and services in their field of expertise in support of service delivery to clients and stakeholders. IT Technical Advisors are found in all work streams.", - id: "u+9mg1", - description: - "IT-03 advisor description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Individual Contributor</strong>: <abbreviation>IT</abbreviation> Technical Advisors (<abbreviation>IT-03</abbreviation>) provide specialized technical advice, recommendations and support on solutions and services in their field of expertise in support of service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Technical Advisors are found in all work streams.", + id: "CIwCa3", + description: + "IT-03 advisor description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Dialog.Footer> <Dialog.Close> @@ -269,21 +322,31 @@ export const DialogLevelFourLead = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-04 employees: those following a management path, and individual contributors.", - id: "87nFC8", - description: "IT-04 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-04</abbreviation> employees: those following a management path, and individual contributors.", + id: "2aBKgf", + description: "IT-04 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Management Path</strong>: IT Managers (IT-04) are responsible for managing the development and delivery of IT services and/or operations through subordinate team leaders, technical advisors, and project teams, for service delivery to clients and stakeholders. IT Managers are found in all work streams.", - id: "m21EOJ", - description: - "IT-04 manager path description, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Management Path</strong>: <abbreviation>IT</abbreviation> Managers (<abbreviation>IT-04</abbreviation>) are responsible for managing the development and delivery of <abbreviation>IT</abbreviation> services and/or operations through subordinate team leaders, technical advisors, and project teams, for service delivery to clients and stakeholders. <abbreviation>IT</abbreviation> Managers are found in all work streams.", + id: "oUDpNl", + description: + "IT-04 manager path description, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Dialog.Footer> <Dialog.Close> @@ -318,64 +381,109 @@ export const DialogLevelFourAdvisor = ({ children }: DialogLevelsProps) => { })} </Dialog.Header> <p> - {intl.formatMessage({ - defaultMessage: - "There are two types of IT-04 employees: those following a management path, and individual contributors.", - id: "87nFC8", - description: "IT-04 description precursor", - })} + {intl.formatMessage( + { + defaultMessage: + "There are two types of <abbreviation>IT-04</abbreviation> employees: those following a management path, and individual contributors.", + id: "2aBKgf", + description: "IT-04 description precursor", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <p> - {intl.formatMessage({ - defaultMessage: - "<strong>Individual Contributor</strong>: IT Senior Advisors (IT-04) provide expert technical advice and strategic direction in their field of expertise in the provision of solutions and services to internal or external clients, and stakeholders. IT Senior Advisors are primarily found in six work streams:", - id: "58BEeZ", - description: - "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please", - })} + {intl.formatMessage( + { + defaultMessage: + "<strong>Individual Contributor</strong>: <abbreviation>IT</abbreviation> Senior Advisors (<abbreviation>IT-04</abbreviation>) provide expert technical advice and strategic direction in their field of expertise in the provision of solutions and services to internal or external clients, and stakeholders. <abbreviation>IT</abbreviation> Senior Advisors are primarily found in six work streams:", + id: "F5kDhX", + description: + "IT-04 senior advisor description precursor to work stream list, ignore things in <> tags please", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <ul> <li> - {intl.formatMessage({ - defaultMessage: "IT Infrastructure Operations", - id: "QZ9FZB", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Infrastructure Operations", + id: "028BJx", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Security", - id: "nrBkon", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: "<abbreviation>IT</abbreviation> Security", + id: "3gDiDK", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Software Solutions", - id: "SDDp1t", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Software Solutions", + id: "ObVJ7H", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Database Management", - id: "6LTC0y", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Database Management", + id: "y+HB+k", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Enterprise Architecture", - id: "oOcegG", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Enterprise Architecture", + id: "6kSk+R", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> <li> - {intl.formatMessage({ - defaultMessage: "IT Project Portfolio Management", - id: "tm3zLD", - description: "work stream example", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Project Portfolio Management", + id: "WgGDug", + description: "work stream example", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </li> </ul> <Dialog.Footer> diff --git a/frontend/common/src/components/Card/CardFlat/CardFlat.tsx b/frontend/common/src/components/Card/CardFlat/CardFlat.tsx index 79b696d2d3b..3d7bf81ad57 100644 --- a/frontend/common/src/components/Card/CardFlat/CardFlat.tsx +++ b/frontend/common/src/components/Card/CardFlat/CardFlat.tsx @@ -8,7 +8,7 @@ import Link, { ExternalLink, type LinkProps } from "../../Link"; type CardColor = Extract<Color, "yellow" | "red" | "blue" | "black" | "purple">; interface CardFlatLinkProps extends Pick<LinkProps, "href" | "mode"> { - label: string; + label: React.ReactNode; external?: boolean; } export interface CardFlatProps { diff --git a/frontend/common/src/constants/localizedConstants.tsx b/frontend/common/src/constants/localizedConstants.tsx index 2ce7910aa78..7fa291bd1fb 100644 --- a/frontend/common/src/constants/localizedConstants.tsx +++ b/frontend/common/src/constants/localizedConstants.tsx @@ -1541,13 +1541,13 @@ export const publishingGroups = defineMessages({ description: "The publishing group called Executive Jobs", }, [PublishingGroup.ItJobs]: { - defaultMessage: "IT Jobs", - id: "C8nrGM", + defaultMessage: "<abbreviation>IT</abbreviation> Jobs", + id: "Xis88S", description: "The publishing group called IT Jobs", }, [PublishingGroup.ItJobsOngoing]: { - defaultMessage: "IT Jobs (ongoing)", - id: "1YuZjR", + defaultMessage: "<abbreviation>IT</abbreviation> Jobs (ongoing)", + id: "IKoOjC", description: "The publishing group called IT Jobs for ongoing recruitments", }, [PublishingGroup.Other]: { @@ -1565,3 +1565,23 @@ export const getPublishingGroup = ( publishingGroup, `Invalid publishing group '${publishingGroup}'`, ); + +export const abbreviations = defineMessages({ + IT: { + defaultMessage: "Information Technology", + id: "nLW9zq", + }, + AS: { + defaultMessage: "Administrative Services", + id: "6svHxg", + }, +}); + +export const getAbbreviations = ( + abbreviation: keyof typeof abbreviations, +): MessageDescriptor => + getOrThrowError( + abbreviations, + abbreviation, + `Invalid abbreviation '${abbreviation}'`, + ); diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 0d02b1d99f2..592fb74fde5 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -1,5 +1,6 @@ import React from "react"; import { IntlShape } from "react-intl"; +import { getAbbreviations } from "../constants/localizedConstants"; export const getFullNameLabel = ( firstName: string | null | undefined, @@ -76,3 +77,79 @@ export const getFullNameHtml = ( } return `${firstName} ${lastName}`; }; + +/** + * Wraps common abbreviations in abbr tags to make them more accessible + * + * @param text text to wrap + * @param intl react-intl object + * @param title abbreviation title + */ +export const wrapAbbr = ( + text: React.ReactNode, + intl: IntlShape, + title?: string, +): JSX.Element => { + const stringifyText = text && text.toString(); // grabs text from React.ReactNode (is there a better way to get text from React.ReactNode type?) + if (typeof stringifyText !== "string") { + const fallbackTitle = intl.formatMessage({ + id: "MuWdei", + defaultMessage: "Abbreviation not found.", + description: + "Message shown to user when the abbreviation text is not found.", + }); + return ( + <abbr title={fallbackTitle}> + <span aria-hidden="true">{text}</span> + </abbr> + ); + } + switch (stringifyText) { + // Regex that matches with all IT(en)/TI(fr) classification + case stringifyText.match(/[IT][TI]/)?.input: + return ( + <abbr + title={intl.formatMessage(getAbbreviations("IT"))} + aria-label={stringifyText.split("").join(" ")} + > + <span aria-hidden="true">{text}</span> + </abbr> + ); + // Regex that matches with all IT(en)/TI(fr) classification with levels + case stringifyText.match(/[IT][TI]-0\d/)?.input: + console.log(stringifyText.replace("-0", "").split("").join(" ")); + return ( + <abbr + title={intl.formatMessage(getAbbreviations("IT"))} + aria-label={stringifyText.replace("-0", "").split("").join(" ")} + > + <span aria-hidden="true">{text}</span> + </abbr> + ); + case "AS": + return ( + <abbr + title={intl.formatMessage(getAbbreviations("AS"))} + aria-label={stringifyText.split("").join(" ")} + > + <span aria-hidden="true">{text}</span> + </abbr> + ); + // Regex that matches with all AS classification with levels + case stringifyText.match(/[AS][SA]-0\d/)?.input: + return ( + <abbr + title={intl.formatMessage(getAbbreviations("AS"))} + aria-label={stringifyText.replace("-0", "").split("").join(" ")} + > + <span aria-hidden="true">{text}</span> + </abbr> + ); + default: + return ( + <abbr title={title} aria-label={(text as string).split("").join(" ")}> + <span aria-hidden="true">{text}</span> + </abbr> + ); + } +}; diff --git a/frontend/common/src/lang/fr.json b/frontend/common/src/lang/fr.json index aa03de4759c..d6111f170c5 100644 --- a/frontend/common/src/lang/fr.json +++ b/frontend/common/src/lang/fr.json @@ -1692,10 +1692,6 @@ "defaultMessage": "Compétences requises pour la demande", "description": "Title that appears when a user is missing required skills on their profile." }, - "C8nrGM": { - "defaultMessage": "Emplois en TI", - "description": "The publishing group called IT Jobs" - }, "CJy0kS": { "defaultMessage": "Compétences constituant un atout", "description": "Title that appears when a user is missing optional skills on their profile." @@ -1876,10 +1872,6 @@ "defaultMessage": "Trop de demandes, veuillez patienter une minute et réessayer.", "description": "Message displayed when number of user attempts exceeds rate limit" }, - "1YuZjR": { - "defaultMessage": "Emplois en TI (en cours)", - "description": "The publishing group called IT Jobs for ongoing recruitments" - }, "FckGRB": { "defaultMessage": "Songez à ajouter des renseignements à ces compétences représentant un atout :", "description": "Text that appears when a user is missing optional skills on their profile" @@ -1979,5 +1971,23 @@ "hWHT65": { "defaultMessage": "Pour cette procédure de candidature, vous devez remplir les conditions linguistiques suivantes :", "description": "Text that appears when a user is missing a language requirement on their profile." + }, + "nLW9zq": { + "defaultMessage": "Technologie de l’information" + }, + "6svHxg": { + "defaultMessage": "Services administratifs" + }, + "IKoOjC": { + "defaultMessage": "Emplois en <abbreviation>TI</abbreviation> (en cours)", + "description": "The publishing group called IT Jobs for ongoing recruitments" + }, + "MuWdei": { + "defaultMessage": "Abréviation non trouvée.", + "description": "Message shown to user when the abbreviation text is not found." + }, + "Xis88S": { + "defaultMessage": "Emplois en <abbreviation>TI</abbreviation>", + "description": "The publishing group called IT Jobs" } -} \ No newline at end of file +} From dab0f3b66fc0b8c9b332457a6d5bf2aa782b9654 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 10:31:20 -0500 Subject: [PATCH 02/20] Update getFullfullPoolAdvertisementTitle in poolUtils with abbr wrapper function --- frontend/common/src/helpers/poolUtils.ts | 72 -------------- frontend/common/src/helpers/poolUtils.tsx | 116 ++++++++++++++++++++++ 2 files changed, 116 insertions(+), 72 deletions(-) delete mode 100644 frontend/common/src/helpers/poolUtils.ts create mode 100644 frontend/common/src/helpers/poolUtils.tsx diff --git a/frontend/common/src/helpers/poolUtils.ts b/frontend/common/src/helpers/poolUtils.ts deleted file mode 100644 index c4da237f8a0..00000000000 --- a/frontend/common/src/helpers/poolUtils.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { IntlShape } from "react-intl"; -import { getPoolStream } from "../constants/localizedConstants"; -import { Maybe, PoolStream, PoolAdvertisement } from "../api/generated"; -import { getLocalizedName } from "./localize"; - -export interface formattedPoolPosterTitleProps { - title: Maybe<string>; - classification: Maybe<string>; - stream: Maybe<PoolStream>; - intl: IntlShape; -} - -export const formattedPoolPosterTitle = ({ - title, - classification, - stream, - intl, -}: formattedPoolPosterTitleProps): string => { - const streamString = stream - ? `${intl.formatMessage(getPoolStream(stream))}` - : ""; - const genericTitle = `${classification ?? ""} ${streamString}`.trim(); - return `${title ? `${title}` : ""}${ - genericTitle ? ` (${genericTitle})` : "" // Wrap genericTitle in parentheses if it exists - }`.trim(); -}; - -export interface formatClassificationStringProps { - group: string; - level: number; -} - -export const formatClassificationString = ({ - group, - level, -}: formatClassificationStringProps): string => { - return `${group}-0${level}`; -}; - -export const getFullPoolAdvertisementTitle = ( - intl: IntlShape, - poolAdvertisement: Maybe< - Pick<PoolAdvertisement, "name" | "classifications" | "stream"> - >, - options?: { defaultTitle?: string }, -): string => { - const fallbackTitle = - options?.defaultTitle ?? - intl.formatMessage({ - id: "D91nGW", - defaultMessage: "Job title not found.", - description: - "Message shown to user when pool name or classification are not found.", - }); - - if (poolAdvertisement === null || poolAdvertisement === undefined) - return fallbackTitle; - - const formattedClassification = poolAdvertisement?.classifications?.[0] // TODO: If a pool has multiple classifications, only the first will be shown. - ? formatClassificationString(poolAdvertisement?.classifications?.[0]) - : null; - - const specificTitle = getLocalizedName(poolAdvertisement.name, intl); - - const formattedTitle = formattedPoolPosterTitle({ - title: specificTitle, - classification: formattedClassification, - stream: poolAdvertisement.stream, - intl, - }); - return formattedTitle ?? fallbackTitle; -}; diff --git a/frontend/common/src/helpers/poolUtils.tsx b/frontend/common/src/helpers/poolUtils.tsx new file mode 100644 index 00000000000..855df935617 --- /dev/null +++ b/frontend/common/src/helpers/poolUtils.tsx @@ -0,0 +1,116 @@ +import React from "react"; +import { IntlShape } from "react-intl"; +import { getPoolStream } from "../constants/localizedConstants"; +import { + Maybe, + PoolStream, + PoolAdvertisement, + Classification, +} from "../api/generated"; +import { getLocalizedName } from "./localize"; +import { wrapAbbr } from "./nameUtils"; + +export interface formatClassificationStringProps { + group: string; + level: number; +} + +export const formatClassificationString = ({ + group, + level, +}: formatClassificationStringProps): string => { + return `${group}-0${level}`; +}; + +export interface formattedPoolPosterTitleProps { + title: Maybe<string>; + classification: Maybe<Classification>; + stream: Maybe<PoolStream>; + intl: IntlShape; +} + +export const formattedPoolPosterTitle = ({ + title, + classification, + stream, + intl, +}: formattedPoolPosterTitleProps): { + html: React.ReactNode; + label: string; +} => { + const streamString = stream + ? `${intl.formatMessage(getPoolStream(stream))}` + : ""; + + const groupAndLevel = classification + ? formatClassificationString(classification) + : null ?? ""; + + const genericTitle = `${groupAndLevel} ${streamString}`.trim(); + + return { + html: ( + <> + {`${title ? `${title}` : ""}`} ({wrapAbbr(groupAndLevel, intl)}{" "} + {streamString ? ` ${streamString}` : ""}) + </> + ), + label: `${title ? `${title}` : ""} ${ + genericTitle ? ` (${genericTitle})` : "" + }`.trim(), + }; +}; + +export const fullPoolAdvertisementTitle = ( + intl: IntlShape, + poolAdvertisement: Maybe< + Pick<PoolAdvertisement, "name" | "classifications" | "stream"> + >, + options?: { defaultTitle?: string }, +): { html: React.ReactNode; label: string } => { + const fallbackTitle = + options?.defaultTitle ?? + intl.formatMessage({ + id: "D91nGW", + defaultMessage: "Job title not found.", + description: + "Message shown to user when pool name or classification are not found.", + }); + + if (poolAdvertisement === null || poolAdvertisement === undefined) + return { + html: fallbackTitle, + label: fallbackTitle, + }; + + const specificTitle = getLocalizedName(poolAdvertisement.name, intl); + + const formattedTitle = formattedPoolPosterTitle({ + title: specificTitle, + classification: poolAdvertisement?.classifications?.[0], + stream: poolAdvertisement.stream, + intl, + }); + + return { + html: formattedTitle.html ?? fallbackTitle, + label: formattedTitle.label ?? fallbackTitle, + }; +}; + +export const getFullPoolAdvertisementTitleHtml = ( + intl: IntlShape, + poolAdvertisement: Maybe< + Pick<PoolAdvertisement, "name" | "classifications" | "stream"> + >, + options?: { defaultTitle?: string }, +): React.ReactNode => + fullPoolAdvertisementTitle(intl, poolAdvertisement, options).html; + +export const getFullPoolAdvertisementTitleLabel = ( + intl: IntlShape, + poolAdvertisement: Maybe< + Pick<PoolAdvertisement, "name" | "classifications" | "stream"> + >, + options?: { defaultTitle?: string }, +): string => fullPoolAdvertisementTitle(intl, poolAdvertisement, options).label; From 405e18f7953d7309471536d5dcee409d81bfff35 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 10:32:01 -0500 Subject: [PATCH 03/20] Fix wrapAbbr ariaLabel --- frontend/common/src/helpers/nameUtils.tsx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 592fb74fde5..5f4e27d53d4 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -105,42 +105,41 @@ export const wrapAbbr = ( ); } switch (stringifyText) { - // Regex that matches with all IT(en)/TI(fr) classification - case stringifyText.match(/[IT][TI]/)?.input: + // Regex that matches with all IT(en)/TI(fr) classification with levels + case stringifyText.match(/[IT][TI]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))} - aria-label={stringifyText.split("").join(" ")} + aria-label={stringifyText.replace("-0", "").split("").join(" ")} > <span aria-hidden="true">{text}</span> </abbr> ); - // Regex that matches with all IT(en)/TI(fr) classification with levels - case stringifyText.match(/[IT][TI]-0\d/)?.input: - console.log(stringifyText.replace("-0", "").split("").join(" ")); + // Regex that matches with all IT(en)/TI(fr) classification + case stringifyText.match(/[IT][TI]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))} - aria-label={stringifyText.replace("-0", "").split("").join(" ")} + aria-label={stringifyText.split("").join(" ")} > <span aria-hidden="true">{text}</span> </abbr> ); - case "AS": + // Regex that matches with all AS classification with levels + case stringifyText.match(/[AS][SA]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))} - aria-label={stringifyText.split("").join(" ")} + aria-label={stringifyText.replace("-0", "").split("").join(" ")} > <span aria-hidden="true">{text}</span> </abbr> ); - // Regex that matches with all AS classification with levels - case stringifyText.match(/[AS][SA]-0\d/)?.input: + case stringifyText.match(/[AS][SA]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))} - aria-label={stringifyText.replace("-0", "").split("").join(" ")} + aria-label={stringifyText.split("").join(" ")} > <span aria-hidden="true">{text}</span> </abbr> From dadbe220b033c0f088b90eeeaa7bcda43a87993f Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 10:32:54 -0500 Subject: [PATCH 04/20] Update all poolAdvertisement titles with updated helper function --- .../ApplicationPageWrapper.tsx | 2 +- .../SearchRequestTable/SearchRequestTable.tsx | 9 ++-- .../ApiManagedTable/useFilterOptions.tsx | 4 +- apps/web/src/lang/fr.json | 16 ++++++ .../ApplicationCard/ApplicationActions.tsx | 10 ++-- .../ApplicationCard/ApplicationCard.tsx | 4 +- .../ReviewApplicationPage.tsx | 4 +- .../SignAndSubmitPage/SignAndSubmitPage.tsx | 9 ++-- .../IndexPoolCandidatePage.tsx | 6 +-- .../ViewPoolCandidatePage.tsx | 9 ++-- .../ApplicationStatusForm.tsx | 4 +- .../components/PoolCard/PoolCard.tsx | 37 +++++-------- .../IndexPoolPage/components/PoolTable.tsx | 13 +++-- .../PoolAdvertisementPage.tsx | 4 +- .../pages/Pools/ViewPoolPage/ViewPoolPage.tsx | 4 +- .../components/AboutMeForm/AboutMeForm.tsx | 4 +- .../EmploymentEquityForm.tsx | 4 +- .../components/ExperienceAndSkills.tsx | 6 +-- .../ExperienceFormPage/ExperienceFormPage.tsx | 6 +-- .../GovernmentInfoForm/GovernmentInfoForm.tsx | 52 +++++++++++-------- .../LanguageInformationForm.tsx | 4 +- .../components/CandidatePoolsSection.tsx | 6 ++- .../RoleSalaryForm/RoleSalaryForm.tsx | 4 +- .../WorkLocationForm/WorkLocationForm.tsx | 4 +- .../WorkPreferencesForm.tsx | 4 +- .../SearchPage/components/SearchForm.tsx | 44 ++++++++++++++-- .../SearchPage/components/SearchPools.tsx | 4 +- .../components/ViewSearchRequest.tsx | 6 +-- .../GeneralInformationTab/AddToPoolDialog.tsx | 9 ++-- .../ChangeStatusDialog.tsx | 19 ++++--- .../GeneralInformationTab.tsx | 16 ++++-- .../components/Breadcrumbs/Breadcrumbs.tsx | 10 ++-- .../SearchRequestFilters.tsx | 23 ++++---- .../deprecated/SearchRequestFilters.tsx | 6 ++- .../ProfileSections/CandidatePoolsSection.tsx | 6 ++- .../GovernmentInformationSection.tsx | 7 ++- .../src/components/form/Select/Select.tsx | 10 +++- 37 files changed, 238 insertions(+), 151 deletions(-) diff --git a/apps/web/src/components/ApplicationPageWrapper/ApplicationPageWrapper.tsx b/apps/web/src/components/ApplicationPageWrapper/ApplicationPageWrapper.tsx index 54d74ffadc6..afbb9ed67c0 100644 --- a/apps/web/src/components/ApplicationPageWrapper/ApplicationPageWrapper.tsx +++ b/apps/web/src/components/ApplicationPageWrapper/ApplicationPageWrapper.tsx @@ -17,7 +17,7 @@ import ApplicationNavigation, { export interface ApplicationPageWrapperProps { title: string; - subtitle?: string; + subtitle?: React.ReactNode; crumbs?: BreadcrumbsProps["crumbs"]; navigation?: ApplicationNavigationProps; closingDate: PoolAdvertisement["closingDate"]; diff --git a/apps/web/src/components/SearchRequestTable/SearchRequestTable.tsx b/apps/web/src/components/SearchRequestTable/SearchRequestTable.tsx index e978930318d..f6841cb951e 100644 --- a/apps/web/src/components/SearchRequestTable/SearchRequestTable.tsx +++ b/apps/web/src/components/SearchRequestTable/SearchRequestTable.tsx @@ -6,7 +6,7 @@ import { getLocalizedName } from "@common/helpers/localize"; import { getPoolCandidateSearchStatus } from "@common/constants/localizedConstants"; import { PoolCandidateSearchStatus } from "@common/api/generated"; import Pending from "@common/components/Pending"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { formatDate, parseDateTimeUtc } from "@common/helpers/dateUtils"; import { @@ -58,6 +58,7 @@ function poolsAccessor( const pools = row.original?.applicantFilter?.pools ?? row.original?.poolCandidateFilter?.pools; + const filteredPools = pools?.filter(notEmpty); return filteredPools?.length ? ( <span> @@ -66,7 +67,7 @@ function poolsAccessor( pool && ( <React.Fragment key={pool.id}> <a href={paths.poolCandidateTable(pool.id)}> - {getFullPoolAdvertisementTitle(intl, pool)} + {getFullPoolAdvertisementTitleHtml(intl, pool)} </a> {index > 0 && ", "} </React.Fragment> @@ -87,8 +88,8 @@ export const SearchRequestTable = ({ const paths = useRoutes(); const localizedTransformPoolToPosterTitle = useCallback( - (pool: Parameters<typeof getFullPoolAdvertisementTitle>[1]) => - getFullPoolAdvertisementTitle(intl, pool), + (pool: Parameters<typeof getFullPoolAdvertisementTitleHtml>[1]) => + getFullPoolAdvertisementTitleHtml(intl, pool), [intl], ); diff --git a/apps/web/src/components/Table/ApiManagedTable/useFilterOptions.tsx b/apps/web/src/components/Table/ApiManagedTable/useFilterOptions.tsx index c5bae5659c9..2b4c7973143 100644 --- a/apps/web/src/components/Table/ApiManagedTable/useFilterOptions.tsx +++ b/apps/web/src/components/Table/ApiManagedTable/useFilterOptions.tsx @@ -19,7 +19,7 @@ import { enumToOptions } from "@common/helpers/formUtils"; import { notEmpty } from "@common/helpers/util"; import useLocale from "@common/hooks/useLocale"; import { commonMessages } from "@common/messages"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleLabel } from "@common/helpers/poolUtils"; import { WorkRegion, @@ -62,7 +62,7 @@ export default function useFilterOptions(enableEducationType = false) { const optionsData = { pools: filterRes.data?.pools.filter(notEmpty).map((pool) => ({ value: pool.id, - label: getFullPoolAdvertisementTitle(intl, pool), + label: getFullPoolAdvertisementTitleLabel(intl, pool), })), languageAbility: enumToOptions(LanguageAbility).map(({ value }) => ({ value, diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 0f8bc9e5490..e89c9c98ce5 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -5502,5 +5502,21 @@ "y+HB+k": { "defaultMessage": "Gestion de la base de données de la <abbreviation>TI</abbreviation>", "description": "work stream example" + }, + "1c+inU": { + "defaultMessage": "Technicien(ne) T I 1 (60 000 $ à 78 000 $)", + "description": "IT-01 classification aria label including titles and salaries" + }, + "BkHx2X": { + "defaultMessage": "Analyste T I 2 (75 000 $ à 91 000 $)", + "description": "IT-02 classification aria label including titles and salaries" + }, + "++WV3O": { + "defaultMessage": "Conseiller technique ou Chef d'équipe T I 3 (88 000 $ à 110 000 $)", + "description": "IT-03 classification aria label including titles and salaries" + }, + "Ix0KgU": { + "defaultMessage": "Conseiller principal ou Manager Gestionnaire I T 4 (101 000 $ à 126 000 $)", + "description": "IT-04 classification aria label including titles and salaries" } } diff --git a/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationActions.tsx b/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationActions.tsx index fd5a7ff7d4f..211eb228c9c 100644 --- a/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationActions.tsx +++ b/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationActions.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import { Button, Link } from "@common/components"; import AlertDialog from "@common/components/AlertDialog"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import useRoutes from "~/hooks/useRoutes"; @@ -35,7 +35,7 @@ const ContinueAction = ({ show, application }: ContinueActionProps) => { description: "Link text to continue a specific application", }, { - name: getFullPoolAdvertisementTitle(intl, poolAdvertisement), + name: getFullPoolAdvertisementTitleHtml(intl, poolAdvertisement), }, )} </Link> @@ -66,7 +66,7 @@ const SeeAdvertisementAction = ({ description: "Link text to see an applications advertisement", }, { - name: getFullPoolAdvertisementTitle(intl, advertisement), + name: getFullPoolAdvertisementTitleHtml(intl, advertisement), }, )} </Link> @@ -85,7 +85,7 @@ const DeleteAction = ({ show, application, onDelete }: DeleteActionProps) => { return null; } - const name = getFullPoolAdvertisementTitle( + const name = getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ); @@ -172,7 +172,7 @@ const ArchiveAction = ({ return null; } - const name = getFullPoolAdvertisementTitle( + const name = getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ); diff --git a/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationCard.tsx b/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationCard.tsx index dacf973cd2a..b47bedef003 100644 --- a/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationCard.tsx +++ b/apps/web/src/pages/Applications/MyApplicationsPage/components/ApplicationCard/ApplicationCard.tsx @@ -8,7 +8,7 @@ import { } from "@common/helpers/dateUtils"; import { notEmpty } from "@common/helpers/util"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { type PoolCandidate, PoolCandidateStatus } from "~/api/generated"; @@ -61,7 +61,7 @@ const ApplicationCard = ({ <div> <h2 data-h2-font-size="base(h5)" data-h2-margin="base(0, 0, x0.5, 0)"> {application.poolAdvertisement - ? getFullPoolAdvertisementTitle( + ? getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ) diff --git a/apps/web/src/pages/Applications/ReviewApplicationPage/ReviewApplicationPage.tsx b/apps/web/src/pages/Applications/ReviewApplicationPage/ReviewApplicationPage.tsx index 9edf57e8566..fc5d216bfb6 100644 --- a/apps/web/src/pages/Applications/ReviewApplicationPage/ReviewApplicationPage.tsx +++ b/apps/web/src/pages/Applications/ReviewApplicationPage/ReviewApplicationPage.tsx @@ -16,7 +16,7 @@ import { notEmpty } from "@common/helpers/util"; import { Link } from "@common/components"; import { flattenExperienceSkills } from "@common/types/ExperienceUtils"; import { categorizeSkill, getMissingSkills } from "@common/helpers/skillUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { getMissingLanguageRequirements } from "@common/helpers/languageUtils"; import LanguageInformationSection from "@common/components/UserProfile/ProfileSections/LanguageInformationSection"; @@ -79,7 +79,7 @@ export const ReviewApplication: React.FunctionComponent< hasExperiences ? flattenExperienceSkills(experiences) : [], ).length === 0 && missingLanguageRequirements.length === 0; - const jobTitle = getFullPoolAdvertisementTitle(intl, poolAdvertisement); + const jobTitle = getFullPoolAdvertisementTitleHtml(intl, poolAdvertisement); return ( <> diff --git a/apps/web/src/pages/Applications/SignAndSubmitPage/SignAndSubmitPage.tsx b/apps/web/src/pages/Applications/SignAndSubmitPage/SignAndSubmitPage.tsx index 8fd6725530a..b9d5daeddf6 100644 --- a/apps/web/src/pages/Applications/SignAndSubmitPage/SignAndSubmitPage.tsx +++ b/apps/web/src/pages/Applications/SignAndSubmitPage/SignAndSubmitPage.tsx @@ -21,7 +21,7 @@ import { notEmpty } from "@common/helpers/util"; import { categorizeSkill, getMissingSkills } from "@common/helpers/skillUtils"; import { getMissingLanguageRequirements } from "@common/helpers/languageUtils"; import { flattenExperienceSkills } from "@common/types/ExperienceUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import useRoutes from "~/hooks/useRoutes"; import { @@ -236,7 +236,7 @@ export interface SignAndSubmitFormProps { poolAdvertisementId: string; userId: string; closingDate: PoolAdvertisement["closingDate"]; - jobTitle: string; + jobTitle: string | React.ReactNode; isApplicationComplete: boolean; handleSubmitApplication: ( id: string, @@ -394,7 +394,10 @@ const SignAndSubmitPage = () => { }); const jobTitle = data?.poolCandidate?.poolAdvertisement - ? getFullPoolAdvertisementTitle(intl, data.poolCandidate.poolAdvertisement) + ? getFullPoolAdvertisementTitleHtml( + intl, + data.poolCandidate.poolAdvertisement, + ) : intl.formatMessage({ defaultMessage: "Error, job title not found.", id: "oDyHaL", diff --git a/apps/web/src/pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage.tsx b/apps/web/src/pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage.tsx index af86e1ceb08..42c90af4da8 100644 --- a/apps/web/src/pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage.tsx +++ b/apps/web/src/pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage.tsx @@ -6,7 +6,7 @@ import PageHeader from "@common/components/PageHeader"; import { Squares2X2Icon } from "@heroicons/react/24/outline"; import Breadcrumbs from "@common/components/Breadcrumbs"; import Pending from "@common/components/Pending"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { Scalars, useGetPoolAdvertisementQuery } from "~/api/generated"; import useRoutes from "~/hooks/useRoutes"; @@ -39,7 +39,7 @@ export const IndexPoolCandidatePage = () => { }, { title: - getFullPoolAdvertisementTitle(intl, data?.poolAdvertisement) || + getFullPoolAdvertisementTitleHtml(intl, data?.poolAdvertisement) || intl.formatMessage({ defaultMessage: "Pool name not found", id: "HGMl3y", @@ -76,7 +76,7 @@ export const IndexPoolCandidatePage = () => { "Subtitle on pool candidates page indicating which pool candidates are from", }, { - poolName: getFullPoolAdvertisementTitle( + poolName: getFullPoolAdvertisementTitleHtml( intl, data?.poolAdvertisement, ), diff --git a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx index e3eeacecf05..4a3cd785074 100644 --- a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx +++ b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx @@ -14,7 +14,7 @@ import Breadcrumbs, { BreadcrumbsProps } from "@common/components/Breadcrumbs"; import UserProfile from "@common/components/UserProfile"; import { Applicant } from "@common/api/generated"; import TableOfContents from "@common/components/TableOfContents"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import useRoutes from "~/hooks/useRoutes"; import { @@ -57,7 +57,7 @@ export const ViewPoolCandidate = ({ href: paths.poolTable(), }, { - title: getFullPoolAdvertisementTitle(intl, poolCandidate.pool), + title: getFullPoolAdvertisementTitleHtml(intl, poolCandidate.pool), href: paths.poolView(poolCandidate.pool.id), }, { @@ -213,7 +213,10 @@ export const ViewPoolCandidate = ({ }, { submittedAt: poolCandidate.submittedAt, - poolName: getFullPoolAdvertisementTitle(intl, poolCandidate.pool), + poolName: getFullPoolAdvertisementTitleHtml( + intl, + poolCandidate.pool, + ), }, )} </p> diff --git a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ApplicationStatusForm/ApplicationStatusForm.tsx b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ApplicationStatusForm/ApplicationStatusForm.tsx index bab1afe1385..8d5304051a6 100644 --- a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ApplicationStatusForm/ApplicationStatusForm.tsx +++ b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ApplicationStatusForm/ApplicationStatusForm.tsx @@ -14,7 +14,7 @@ import { getPoolCandidateStatus } from "@common/constants/localizedConstants"; import { strToFormDate } from "@common/helpers/dateUtils"; import { commonMessages } from "@common/messages"; import { emptyToNull } from "@common/helpers/util"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { PoolCandidateStatus, @@ -195,7 +195,7 @@ export const ApplicationStatusForm = ({ "Label for the notes field on the pool candidate application", }, { - poolName: getFullPoolAdvertisementTitle( + poolName: getFullPoolAdvertisementTitleHtml( intl, application.pool, ), diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/components/PoolCard/PoolCard.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/components/PoolCard/PoolCard.tsx index 332ce4ab805..aba368c4a28 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/components/PoolCard/PoolCard.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/components/PoolCard/PoolCard.tsx @@ -17,33 +17,16 @@ import { } from "@common/helpers/localize"; import { notEmpty } from "@common/helpers/util"; import { commonMessages } from "@common/messages"; -import { - formatClassificationString, - getFullPoolAdvertisementTitle, -} from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { PoolAdvertisement } from "~/api/generated"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import IconLabel from "./IconLabel"; import "./pool-card.css"; -const getClassificationStrings = (pool: PoolAdvertisement) => { - if (!pool.classifications) return null; - - return pool.classifications - .map((classification) => { - if (!classification) return undefined; - - return formatClassificationString({ - group: classification.group, - level: classification.level, - }); - }) - .filter(notEmpty); -}; - const getSalaryRanges = (pool: PoolAdvertisement, locale: string) => { if (!pool.classifications) return null; @@ -70,8 +53,14 @@ const PoolCard = ({ pool, headingLevel = "h3" }: PoolCardProps) => { const locale = getLocale(intl); const paths = useRoutes(); - const classifications = getClassificationStrings(pool); - const classification = classifications?.length ? classifications[0] : null; + const { classifications } = pool; + const classification = classifications ? classifications[0] : null; + + let classificationAbbr; // type wrangling the complex type into a string + if (classification) { + const { group, level } = classification; + classificationAbbr = wrapAbbr(`${group}-0${level}`, intl); + } const salaryRanges = getSalaryRanges(pool, locale); const nullMessage = intl.formatMessage(commonMessages.notAvailable); @@ -103,7 +92,7 @@ const PoolCard = ({ pool, headingLevel = "h3" }: PoolCardProps) => { data-h2-font-size="base(h6) l-tablet(h4, 1.2)" data-h2-layer="base(2, relative)" > - {classification || nullMessage} + {classificationAbbr || nullMessage} </span> </div> </div> @@ -122,7 +111,7 @@ const PoolCard = ({ pool, headingLevel = "h3" }: PoolCardProps) => { data-h2-margin="base(0, 0, x1, 0) p-tablet(0)" style={{ wordBreak: "break-word" }} > - {getFullPoolAdvertisementTitle(intl, pool)} + {getFullPoolAdvertisementTitleHtml(intl, pool)} </Heading> <div data-h2-flex-grow="p-tablet(1)" @@ -230,7 +219,7 @@ const PoolCard = ({ pool, headingLevel = "h3" }: PoolCardProps) => { description: "Message on link that say to apply to a recruitment advertisement", }, - { name: classifications ? classifications[0] : "" }, + { name: classificationAbbr }, )} </Link> </p> diff --git a/apps/web/src/pages/Pools/IndexPoolPage/components/PoolTable.tsx b/apps/web/src/pages/Pools/IndexPoolPage/components/PoolTable.tsx index fac4b231732..e633b2664aa 100644 --- a/apps/web/src/pages/Pools/IndexPoolPage/components/PoolTable.tsx +++ b/apps/web/src/pages/Pools/IndexPoolPage/components/PoolTable.tsx @@ -8,9 +8,9 @@ import { FromArray } from "@common/types/utilityTypes"; import Pending from "@common/components/Pending"; import { getAdvertisementStatus } from "@common/constants/localizedConstants"; import { commonMessages } from "@common/messages"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { formatDate, parseDateTimeUtc } from "@common/helpers/dateUtils"; -import { getFullNameHtml } from "@common/helpers/nameUtils"; +import { getFullNameHtml, wrapAbbr } from "@common/helpers/nameUtils"; import useRoutes from "~/hooks/useRoutes"; import { GetPoolsQuery, Maybe, Pool, useGetPoolsQuery } from "~/api/generated"; @@ -41,7 +41,7 @@ function poolCandidatesLinkAccessor( id: "6R9N+h", description: "Text for a link to the Pool Candidates table", }, - { label: getFullPoolAdvertisementTitle(intl, pool) }, + { label: getFullPoolAdvertisementTitleHtml(intl, pool) }, )} </Link> ); @@ -50,7 +50,7 @@ function poolCandidatesLinkAccessor( function viewLinkAccessor(url: string, pool: Pool, intl: IntlShape) { return ( <Link href={url} type="link"> - {getFullPoolAdvertisementTitle(intl, pool)} + {getFullPoolAdvertisementTitleHtml(intl, pool)} </Link> ); } @@ -188,7 +188,10 @@ export const PoolTable = ({ pools }: PoolTableProps) => { color="primary" mode="outline" > - {classification?.group}‑{classification?.level} + {wrapAbbr( + `${classification?.group}-0${classification?.level}`, + intl, + )} </Pill> ); }), diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx index 8a7cdcb41e3..dd6f413b5be 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx @@ -32,7 +32,7 @@ import { categorizeSkill } from "@common/helpers/skillUtils"; import { notEmpty } from "@common/helpers/util"; import { formatClassificationString, - getFullPoolAdvertisementTitle, + getFullPoolAdvertisementTitleLabel, } from "@common/helpers/poolUtils"; import { AuthorizationContext } from "@common/components/Auth"; import SEO from "@common/components/SEO/SEO"; @@ -167,7 +167,7 @@ export const PoolAdvertisementPoster = ({ level: classification?.level, }); } - const fullTitle = getFullPoolAdvertisementTitle(intl, poolAdvertisement); + const fullTitle = getFullPoolAdvertisementTitleLabel(intl, poolAdvertisement); const canApply = poolAdvertisement.advertisementStatus && poolAdvertisement.advertisementStatus === AdvertisementStatus.Published; diff --git a/apps/web/src/pages/Pools/ViewPoolPage/ViewPoolPage.tsx b/apps/web/src/pages/Pools/ViewPoolPage/ViewPoolPage.tsx index 5a2808d24ba..ba71df91e6f 100644 --- a/apps/web/src/pages/Pools/ViewPoolPage/ViewPoolPage.tsx +++ b/apps/web/src/pages/Pools/ViewPoolPage/ViewPoolPage.tsx @@ -32,7 +32,7 @@ import { parseDateTimeUtc, relativeClosingDate, } from "@common/helpers/dateUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import SEO from "@common/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; @@ -63,7 +63,7 @@ export const ViewPool = ({ pool }: ViewPoolProps): JSX.Element => { } }, [linkCopied, setLinkCopied]); - const poolName = getFullPoolAdvertisementTitle(intl, pool); + const poolName = getFullPoolAdvertisementTitleHtml(intl, pool); const classification = pool.classifications ? pool.classifications[0] : null; const essentialOccupationalSkills = pool.essentialSkills?.filter((skill) => { diff --git a/apps/web/src/pages/Profile/AboutMePage/components/AboutMeForm/AboutMeForm.tsx b/apps/web/src/pages/Profile/AboutMePage/components/AboutMeForm/AboutMeForm.tsx index eb5ee89a62f..64c70abe94f 100644 --- a/apps/web/src/pages/Profile/AboutMePage/components/AboutMeForm/AboutMeForm.tsx +++ b/apps/web/src/pages/Profile/AboutMePage/components/AboutMeForm/AboutMeForm.tsx @@ -14,7 +14,7 @@ import { getArmedForcesStatusesProfile, } from "@common/constants/localizedConstants"; import { emptyToNull } from "@common/helpers/util"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import profileMessages from "~/messages/profileMessages"; import useRoutes from "~/hooks/useRoutes"; @@ -180,7 +180,7 @@ const AboutMeForm: React.FunctionComponent<AboutMeFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx index 7953d89c5ef..80a2dc636c4 100644 --- a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx +++ b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import Well from "@common/components/Well"; import { navigationMessages } from "@common/messages"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { User, PoolCandidate } from "~/api/generated"; import useRoutes from "~/hooks/useRoutes"; @@ -52,7 +52,7 @@ const EmploymentEquityForm: React.FC<EmploymentEquityFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx index 2f8b55c35cd..d2010c05bd4 100644 --- a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx +++ b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx @@ -16,7 +16,7 @@ import Well from "@common/components/Well"; import { notEmpty } from "@common/helpers/util"; import { navigationMessages } from "@common/messages"; import { flattenExperienceSkills } from "@common/types/ExperienceUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { AwardExperience, @@ -132,7 +132,7 @@ export const ExperienceAndSkills: React.FunctionComponent< const hasExperiences = notEmpty(experiences); - let crumbs = [ + let crumbs: { label: string | React.ReactNode; url: string }[] = [ { label: intl.formatMessage({ defaultMessage: "Experience and Skills", @@ -155,7 +155,7 @@ export const ExperienceAndSkills: React.FunctionComponent< url: paths.applications(applicantId), }, { - label: getFullPoolAdvertisementTitle(intl, poolAdvertisement), + label: getFullPoolAdvertisementTitleHtml(intl, poolAdvertisement), url: paths.pool(poolAdvertisement.id), }, { diff --git a/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx b/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx index 44a1cdd5a4d..a33139b3560 100644 --- a/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx +++ b/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx @@ -13,7 +13,7 @@ import { removeFromSessionStorage } from "@common/helpers/storageUtils"; import { ThrowNotFound } from "@common/components/NotFound"; import Pending from "@common/components/Pending"; import { notEmpty } from "@common/helpers/util"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { categorizeSkill } from "@common/helpers/skillUtils"; import { Maybe, SkillCategory } from "@common/api/generated"; @@ -88,7 +88,7 @@ export const ExperienceForm: React.FunctionComponent<ExperienceFormProps> = ({ applicationId ? `?applicationId=${applicationId}` : `` }`; - let crumbs = [ + let crumbs: { label: string | React.ReactNode; url: string }[] = [ { label: intl.formatMessage({ defaultMessage: "Experience and Skills", @@ -116,7 +116,7 @@ export const ExperienceForm: React.FunctionComponent<ExperienceFormProps> = ({ let irrelevantSkills: Maybe<Skill[]> = []; if (poolAdvertisement) { - const advertisementTitle = getFullPoolAdvertisementTitle( + const advertisementTitle = getFullPoolAdvertisementTitleHtml( intl, poolAdvertisement, ); diff --git a/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx b/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx index c4f66f62747..66d0093d8f2 100644 --- a/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx +++ b/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx @@ -11,11 +11,11 @@ import { enumToOptions, objectsToSortedOptions, } from "@common/helpers/formUtils"; -import { getLocale } from "@common/helpers/localize"; +import { getLocale, getLocalizedName } from "@common/helpers/localize"; import { toast } from "@common/components/Toast"; import ExternalLink from "@common/components/Link/ExternalLink"; import { FieldLabels } from "@common/components/form/BasicForm"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { Classification, @@ -31,6 +31,7 @@ import profileMessages from "~/messages/profileMessages"; import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; +import uniqBy from "lodash/uniqBy"; type FormValues = { govEmployeeYesNo?: "yes" | "no"; @@ -236,26 +237,31 @@ export const GovernmentInfoFormFields: React.FunctionComponent< "priorityEntitlementYesNo", ]); - // create array of objects containing the classifications, then map it into an array of strings, and then remove duplicates, and then map into Select options - // https://stackoverflow.com/questions/11246758/how-to-get-unique-values-in-an-array#comment87157537_42123984 - const classGroupsWithDupes: { value: string; label: string }[] = - classifications.map((classification) => { - return { - value: classification.id, - label: - classification.group || - intl.formatMessage({ - defaultMessage: "Error: classification group not found.", - id: "YA/7nb", - description: - "Error message if classification group is not defined.", - }), - }; - }); - const mapped = classGroupsWithDupes.map((x) => x.label); - const noDupes = Array.from(new Set(mapped)); - const groupOptions = noDupes.map((options) => { - return { value: options, label: options }; + const classGroupsWithDupes: { + label: string; + ariaLabel: string; + }[] = classifications.map((classification) => { + return { + label: + classification.group || + intl.formatMessage({ + defaultMessage: "Error: classification group not found.", + id: "YA/7nb", + description: "Error message if classification group is not defined.", + }), + ariaLabel: `${getLocalizedName( + classification.name, + intl, + )} ${classification.group.split("").join(" ")}`, + }; + }); + const noDupes = uniqBy(classGroupsWithDupes, "label"); + const groupOptions = noDupes.map(({ label, ariaLabel }) => { + return { + value: label, + label, + ariaLabel, + }; }); // generate classification levels from the selected group @@ -546,7 +552,7 @@ const GovernmentInfoForm: React.FunctionComponent<GovernmentInfoFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/LanguageInfoPage/components/LanguageInformationForm/LanguageInformationForm.tsx b/apps/web/src/pages/Profile/LanguageInfoPage/components/LanguageInformationForm/LanguageInformationForm.tsx index 4f1b94c73a4..d4cd661d84d 100644 --- a/apps/web/src/pages/Profile/LanguageInfoPage/components/LanguageInformationForm/LanguageInformationForm.tsx +++ b/apps/web/src/pages/Profile/LanguageInfoPage/components/LanguageInformationForm/LanguageInformationForm.tsx @@ -8,7 +8,7 @@ import omit from "lodash/omit"; import { toast } from "@common/components/Toast"; import { errorMessages, navigationMessages } from "@common/messages"; import { BasicForm, Checklist } from "@common/components/form"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { Applicant, @@ -198,7 +198,7 @@ const LanguageInformationForm: React.FunctionComponent<{ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/ProfilePage/components/CandidatePoolsSection.tsx b/apps/web/src/pages/Profile/ProfilePage/components/CandidatePoolsSection.tsx index 0ecba5d9459..d8c40fd3606 100644 --- a/apps/web/src/pages/Profile/ProfilePage/components/CandidatePoolsSection.tsx +++ b/apps/web/src/pages/Profile/ProfilePage/components/CandidatePoolsSection.tsx @@ -2,7 +2,7 @@ import React from "react"; import { useIntl } from "react-intl"; import Well from "@common/components/Well"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { PoolCandidate } from "~/api/generated"; @@ -33,7 +33,9 @@ const CandidatePoolsSection: React.FunctionComponent<{ data-h2-padding="base(x1, 0)" > <div> - <p>{getFullPoolAdvertisementTitle(intl, poolCandidate?.pool)}</p> + <p> + {getFullPoolAdvertisementTitleHtml(intl, poolCandidate?.pool)} + </p> </div> <div> <p> diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx index 23fdc5216e7..7ec98e618f4 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx @@ -11,7 +11,7 @@ import { unpackMaybes } from "@common/helpers/formUtils"; import { toast } from "@common/components/Toast"; import Well from "@common/components/Well"; import { ExternalLink } from "@common/components/Link"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { GenericJobTitle, @@ -141,7 +141,7 @@ const RoleSalaryForm: React.FunctionComponent<RoleSalaryFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/WorkLocationPage/components/WorkLocationForm/WorkLocationForm.tsx b/apps/web/src/pages/Profile/WorkLocationPage/components/WorkLocationForm/WorkLocationForm.tsx index 6bf688d7687..ff42f9f29f0 100644 --- a/apps/web/src/pages/Profile/WorkLocationPage/components/WorkLocationForm/WorkLocationForm.tsx +++ b/apps/web/src/pages/Profile/WorkLocationPage/components/WorkLocationForm/WorkLocationForm.tsx @@ -8,7 +8,7 @@ import { getWorkRegionsDetailed } from "@common/constants/localizedConstants"; import { enumToOptions } from "@common/helpers/formUtils"; import { errorMessages, navigationMessages } from "@common/messages"; import { toast } from "@common/components/Toast"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { CreateUserInput, @@ -103,7 +103,7 @@ const WorkLocationForm: React.FC<WorkLocationFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/Profile/WorkPreferencesPage/components/WorkPreferencesForm/WorkPreferencesForm.tsx b/apps/web/src/pages/Profile/WorkPreferencesPage/components/WorkPreferencesForm/WorkPreferencesForm.tsx index 87ea0372737..3aba558e4aa 100644 --- a/apps/web/src/pages/Profile/WorkPreferencesPage/components/WorkPreferencesForm/WorkPreferencesForm.tsx +++ b/apps/web/src/pages/Profile/WorkPreferencesPage/components/WorkPreferencesForm/WorkPreferencesForm.tsx @@ -10,7 +10,7 @@ import { OperationalRequirementV2, } from "@common/constants/localizedConstants"; import { toast } from "@common/components/Toast"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { PoolCandidate, @@ -148,7 +148,7 @@ const WorkPreferencesForm: React.FC<WorkPreferencesFormProps> = ({ url: paths.applications(application.user.id), }, { - label: getFullPoolAdvertisementTitle( + label: getFullPoolAdvertisementTitleHtml( intl, application.poolAdvertisement, ), diff --git a/apps/web/src/pages/SearchRequests/SearchPage/components/SearchForm.tsx b/apps/web/src/pages/SearchRequests/SearchPage/components/SearchForm.tsx index aef6537bb3d..e0a03ae45d0 100644 --- a/apps/web/src/pages/SearchRequests/SearchPage/components/SearchForm.tsx +++ b/apps/web/src/pages/SearchRequests/SearchPage/components/SearchForm.tsx @@ -88,6 +88,35 @@ const classificationLabels: Record<string, MessageDescriptor> = defineMessages({ }, }); +const classificationAriaLabels: Record<string, MessageDescriptor> = + defineMessages({ + "IT-01": { + defaultMessage: "Technician I T 1 ($60,000 to $78,000)", + id: "1c+inU", + description: + "IT-01 classification aria label including titles and salaries", + }, + "IT-02": { + defaultMessage: "Analyst I T 2 ($75,000 to $91,000)", + id: "BkHx2X", + description: + "IT-02 classification aria label including titles and salaries", + }, + "IT-03": { + defaultMessage: + "Technical Advisor or Team Leader I T 3 ($88,000 to $110,000)", + id: "++WV3O", + description: + "IT-03 classification aria label including titles and salaries", + }, + "IT-04": { + defaultMessage: "Senior Advisor or Manager I T 4 ($101,000 to $126,000)", + id: "Ix0KgU", + description: + "IT-04 classification aria label including titles and salaries", + }, + }); + const durationSelectionToEnum = ( selection: string | null, ): PositionDuration[] | null => { @@ -204,11 +233,15 @@ const SearchForm = React.forwardRef<SearchFormRef, SearchFormProps>( }, [watch, classificationMap, onUpdateApplicantFilter, pools, state]); const getClassificationLabel = React.useCallback( - (group: string, level: number): string => { + ( + group: string, + level: number, + labels: Record<string, MessageDescriptor>, + ): string => { const key = `${group}-0${level}`; return !hasKey(classificationLabels, key) ? key - : intl.formatMessage(classificationLabels[key]); + : intl.formatMessage(labels[key]); }, [intl], ); @@ -217,7 +250,12 @@ const SearchForm = React.forwardRef<SearchFormRef, SearchFormProps>( () => classifications.map(({ group, level }) => ({ value: classificationToKey({ group, level }), - label: getClassificationLabel(group, level), + label: getClassificationLabel(group, level, classificationLabels), + ariaLabel: getClassificationLabel( + group, + level, + classificationAriaLabels, + ), })), [classifications, getClassificationLabel], ); diff --git a/apps/web/src/pages/SearchRequests/SearchPage/components/SearchPools.tsx b/apps/web/src/pages/SearchRequests/SearchPage/components/SearchPools.tsx index 1c25dc0592f..8efb8993dff 100644 --- a/apps/web/src/pages/SearchRequests/SearchPage/components/SearchPools.tsx +++ b/apps/web/src/pages/SearchRequests/SearchPage/components/SearchPools.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import { Button } from "@common/components"; import { getLocale } from "@common/helpers/localize"; import { getFullNameHtml } from "@common/helpers/nameUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { SimpleClassification } from "~/types/pool"; import { Pool } from "~/api/generated"; @@ -39,7 +39,7 @@ const SearchPools: React.FunctionComponent<SearchPoolsProps> = ({ aria-labelledby={`search_pool_${pool.id}`} > <p data-h2-font-weight="base(700)" id={`search_pool_${pool.id}`}> - {getFullPoolAdvertisementTitle(intl, pool)} + {getFullPoolAdvertisementTitleHtml(intl, pool)} </p> <p data-h2-margin="base(x.5, 0, x1, 0)"> {intl.formatMessage( diff --git a/apps/web/src/pages/SearchRequests/ViewSearchRequestPage/components/ViewSearchRequest.tsx b/apps/web/src/pages/SearchRequests/ViewSearchRequestPage/components/ViewSearchRequest.tsx index 80919edfb36..7010d0454fb 100644 --- a/apps/web/src/pages/SearchRequests/ViewSearchRequestPage/components/ViewSearchRequest.tsx +++ b/apps/web/src/pages/SearchRequests/ViewSearchRequestPage/components/ViewSearchRequest.tsx @@ -9,7 +9,7 @@ import { getPoolCandidateSearchStatus } from "@common/constants/localizedConstan import Pending from "@common/components/Pending"; import NotFound from "@common/components/NotFound"; import { formatDate, parseDateTimeUtc } from "@common/helpers/dateUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import Heading from "@common/components/Heading/Heading"; import { @@ -133,12 +133,12 @@ const ManagerInfo: React.FunctionComponent<{ content={ applicantFilter ? applicantFilter?.pools?.map((pool) => - getFullPoolAdvertisementTitle(intl, pool, { + getFullPoolAdvertisementTitleHtml(intl, pool, { defaultTitle: nonApplicableMessage, }), ) : poolCandidateFilter?.pools?.map((pool) => - getFullPoolAdvertisementTitle(intl, pool, { + getFullPoolAdvertisementTitleHtml(intl, pool, { defaultTitle: nonApplicableMessage, }), ) diff --git a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/AddToPoolDialog.tsx b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/AddToPoolDialog.tsx index e5c19065593..755e52591f6 100644 --- a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/AddToPoolDialog.tsx +++ b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/AddToPoolDialog.tsx @@ -7,7 +7,10 @@ import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; import { toast } from "@common/components/Toast"; import { getFullNameHtml } from "@common/helpers/nameUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { + getFullPoolAdvertisementTitleLabel, + getFullPoolAdvertisementTitleHtml, +} from "@common/helpers/poolUtils"; import { Input } from "@common/components/form"; import { commonMessages, errorMessages } from "@common/messages"; import { currentDate } from "@common/helpers/formUtils"; @@ -119,7 +122,7 @@ export const AddToPoolDialog: React.FC<AddToPoolDialogProps> = ({ <ul> {rejectedRequests.map((rejected) => ( <li key={rejected.pool.id}> - {getFullPoolAdvertisementTitle(intl, rejected.pool)} + {getFullPoolAdvertisementTitleHtml(intl, rejected.pool)} </li> ))} </ul> @@ -150,7 +153,7 @@ export const AddToPoolDialog: React.FC<AddToPoolDialogProps> = ({ .map((pool) => { return { value: pool.id, - label: getFullPoolAdvertisementTitle(intl, pool), + label: getFullPoolAdvertisementTitleLabel(intl, pool), }; }); diff --git a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeStatusDialog.tsx b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeStatusDialog.tsx index 0be917adc22..701209545ac 100644 --- a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeStatusDialog.tsx +++ b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeStatusDialog.tsx @@ -7,7 +7,10 @@ import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; import { toast } from "@common/components/Toast"; import { getFullNameHtml } from "@common/helpers/nameUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { + getFullPoolAdvertisementTitleHtml, + getFullPoolAdvertisementTitleLabel, +} from "@common/helpers/poolUtils"; import { Select } from "@common/components/form"; import { commonMessages, errorMessages } from "@common/messages"; import { enumToOptions } from "@common/helpers/formUtils"; @@ -137,9 +140,13 @@ export const ChangeStatusDialog: React.FC<ChangeStatusDialogProps> = ({ <ul> {rejectedRequests.map((r) => ( <li key={r.poolCandidate.id}> - {getFullPoolAdvertisementTitle(intl, r.poolCandidate.pool, { - defaultTitle: r.poolCandidate.id, - })} + {getFullPoolAdvertisementTitleHtml( + intl, + r.poolCandidate.pool, + { + defaultTitle: r.poolCandidate.id, + }, + )} </li> ))} </ul> @@ -202,7 +209,7 @@ export const ChangeStatusDialog: React.FC<ChangeStatusDialogProps> = ({ })} </p> <p data-h2-font-weight="base(700)"> - - {getFullPoolAdvertisementTitle(intl, selectedCandidate?.pool)} + - {getFullPoolAdvertisementTitleHtml(intl, selectedCandidate?.pool)} </p> <FormProvider {...methods}> <form onSubmit={handleSubmit(submitForm)}> @@ -278,7 +285,7 @@ export const ChangeStatusDialog: React.FC<ChangeStatusDialogProps> = ({ .map((pool) => { return { value: pool.id, - label: getFullPoolAdvertisementTitle(intl, pool), + label: getFullPoolAdvertisementTitleLabel(intl, pool), }; })} /> diff --git a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/GeneralInformationTab.tsx b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/GeneralInformationTab.tsx index dcbc7d62adb..ee6871ecb72 100644 --- a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/GeneralInformationTab.tsx +++ b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/GeneralInformationTab.tsx @@ -23,7 +23,7 @@ import { Button, Link } from "@common/components"; import { BasicForm, TextArea } from "@common/components/form"; import Heading from "@common/components/Heading"; import { getFullNameHtml } from "@common/helpers/nameUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import useRoutes from "~/hooks/useRoutes"; import { @@ -107,7 +107,7 @@ const PoolStatusTable: React.FC<SectionWithPoolsProps> = ({ user, pools }) => { > {candidate.pool ? ( <Link href={paths.poolView(candidate.pool.id)}> - {getFullPoolAdvertisementTitle(intl, candidate.pool)} + {getFullPoolAdvertisementTitleHtml(intl, candidate.pool)} </Link> ) : ( "" @@ -401,7 +401,10 @@ const NotesSection: React.FC<BasicSectionProps> = ({ user }) => { "Toast notification for successful update of candidates notes in specified pool", }, { - poolName: getFullPoolAdvertisementTitle(intl, candidate.pool), + poolName: getFullPoolAdvertisementTitleHtml( + intl, + candidate.pool, + ), }, ), ); @@ -417,7 +420,10 @@ const NotesSection: React.FC<BasicSectionProps> = ({ user }) => { "Toast notification for failed update of candidates notes in specified pool", }, { - poolName: getFullPoolAdvertisementTitle(intl, candidate.pool), + poolName: getFullPoolAdvertisementTitleHtml( + intl, + candidate.pool, + ), }, ), ); @@ -459,7 +465,7 @@ const NotesSection: React.FC<BasicSectionProps> = ({ user }) => { defaultMessage: "Notes", id: "CSDdh/", description: "Title for a pool candidates notes field", - })} - ${getFullPoolAdvertisementTitle( + })} - ${getFullPoolAdvertisementTitleHtml( intl, candidate.pool, )}`} diff --git a/frontend/common/src/components/Breadcrumbs/Breadcrumbs.tsx b/frontend/common/src/components/Breadcrumbs/Breadcrumbs.tsx index 81ca315c570..644e8af9092 100644 --- a/frontend/common/src/components/Breadcrumbs/Breadcrumbs.tsx +++ b/frontend/common/src/components/Breadcrumbs/Breadcrumbs.tsx @@ -3,7 +3,7 @@ import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/solid"; import Link from "../Link"; interface BreadcrumbLink { - title: string; + title: React.ReactNode; href?: string; } @@ -48,14 +48,14 @@ const Breadcrumbs: React.FunctionComponent<BreadcrumbsProps> = ({ links }) => { data-h2-display="base(flex)" data-h2-align-items="base(center)" href={previousStep.href || "#"} - key={previousStep.title} + key={previousStep.href} > {previousStep.title} </Link> </> ) : ( links.map((link, index) => ( - <Fragment key={link.title}> + <Fragment key={link.href}> {index > 0 && ( <span data-h2-padding="base(0, x.25)" @@ -70,12 +70,12 @@ const Breadcrumbs: React.FunctionComponent<BreadcrumbsProps> = ({ links }) => { data-h2-display="base(flex)" data-h2-align-items="base(center)" href={link.href} - key={link.title} + key={link.href} > {link.title} </Link> ) : ( - <span data-h2-font-weight="base(700)" key={link.title}> + <span data-h2-font-weight="base(700)" key={link.href}> {link.title} </span> )} diff --git a/frontend/common/src/components/SearchRequestFilters/SearchRequestFilters.tsx b/frontend/common/src/components/SearchRequestFilters/SearchRequestFilters.tsx index 1ea38c23464..b9c192a694a 100644 --- a/frontend/common/src/components/SearchRequestFilters/SearchRequestFilters.tsx +++ b/frontend/common/src/components/SearchRequestFilters/SearchRequestFilters.tsx @@ -2,6 +2,7 @@ import uniqueId from "lodash/uniqueId"; import isEmpty from "lodash/isEmpty"; import * as React from "react"; import { useIntl } from "react-intl"; +import { wrapAbbr } from "../../helpers/nameUtils"; import { notEmpty } from "../../helpers/util"; import { ApplicantFilter, @@ -25,7 +26,7 @@ export type SimpleClassification = Pick<Classification, "group" | "level">; export interface FilterBlockProps { title: string; - content?: Maybe<string> | Maybe<string[]>; + content?: Maybe<string | React.ReactNode> | Maybe<string[]>; children?: React.ReactNode; } @@ -36,7 +37,9 @@ const FilterBlock: React.FunctionComponent<FilterBlockProps> = ({ }) => { const intl = useIntl(); - const emptyArrayOutput = (input: string | string[] | null | undefined) => { + const emptyArrayOutput = ( + input: string | React.ReactNode | string[] | null | undefined, + ) => { return input && !isEmpty(input) ? ( <p data-h2-display="base(inline)" data-h2-color="base(dt-black)"> {input} @@ -120,12 +123,9 @@ const ApplicantFilters: React.FC<{ const intl = useIntl(); const locale = getLocale(intl); // else set values if filters prop is of ApplicantFilterInput type - const classificationsFromBrowserHistory: string[] | undefined = - selectedClassifications?.map( - (classification) => - `${classification?.group.toLocaleUpperCase()}-0${ - classification?.level - }`, + const classificationsFromBrowserHistory: React.ReactNode[] | undefined = + selectedClassifications?.map((classification) => + wrapAbbr(`${classification?.group}-0${classification?.level}`, intl), ); const pools = applicantFilter?.pools?.filter(notEmpty); @@ -139,11 +139,8 @@ const ApplicantFilters: React.FC<{ ) || []; const classificationsFromApplicantFilter = classifications .filter(notEmpty) - .map( - (classification) => - `${classification?.group.toLocaleUpperCase()}-0${ - classification?.level - }`, + .map((classification) => + wrapAbbr(`${classification?.group}-0${classification?.level}`, intl), ); const skills: string[] | undefined = applicantFilter?.skills?.map((skill) => { diff --git a/frontend/common/src/components/SearchRequestFilters/deprecated/SearchRequestFilters.tsx b/frontend/common/src/components/SearchRequestFilters/deprecated/SearchRequestFilters.tsx index 90c3e86a5e1..0657369f8fd 100644 --- a/frontend/common/src/components/SearchRequestFilters/deprecated/SearchRequestFilters.tsx +++ b/frontend/common/src/components/SearchRequestFilters/deprecated/SearchRequestFilters.tsx @@ -15,7 +15,7 @@ import { export interface FilterBlockProps { title: string; - content: Maybe<string> | Maybe<string[]>; + content: Maybe<string | React.ReactNode> | Maybe<string[]>; } const FilterBlock: React.FunctionComponent<FilterBlockProps> = ({ @@ -24,7 +24,9 @@ const FilterBlock: React.FunctionComponent<FilterBlockProps> = ({ }) => { const intl = useIntl(); - const emptyArrayOutput = (input: string | string[] | null | undefined) => { + const emptyArrayOutput = ( + input: string | React.ReactNode | string[] | null | undefined, + ) => { return input && !isEmpty(input) ? ( <p data-h2-display="base(inline)" data-h2-color="base(dt-black)"> {input} diff --git a/frontend/common/src/components/UserProfile/ProfileSections/CandidatePoolsSection.tsx b/frontend/common/src/components/UserProfile/ProfileSections/CandidatePoolsSection.tsx index 4fa92d80a08..9f71564c48e 100644 --- a/frontend/common/src/components/UserProfile/ProfileSections/CandidatePoolsSection.tsx +++ b/frontend/common/src/components/UserProfile/ProfileSections/CandidatePoolsSection.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; -import { getFullPoolAdvertisementTitle } from "../../../helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "../../../helpers/poolUtils"; import Well from "../../Well"; import { unpackMaybes } from "../../../helpers/formUtils"; import type { Applicant } from "../../../api/generated"; @@ -37,7 +37,9 @@ const CandidatePoolsSection: React.FC<CandidatePoolsSectionProps> = ({ data-h2-padding="base(x1, 0)" > <div> - <p>{getFullPoolAdvertisementTitle(intl, poolCandidate?.pool)}</p> + <p> + {getFullPoolAdvertisementTitleHtml(intl, poolCandidate?.pool)} + </p> </div> <div> <p> diff --git a/frontend/common/src/components/UserProfile/ProfileSections/GovernmentInformationSection.tsx b/frontend/common/src/components/UserProfile/ProfileSections/GovernmentInformationSection.tsx index 3c31da673a1..7282f73c604 100644 --- a/frontend/common/src/components/UserProfile/ProfileSections/GovernmentInformationSection.tsx +++ b/frontend/common/src/components/UserProfile/ProfileSections/GovernmentInformationSection.tsx @@ -1,6 +1,7 @@ import React from "react"; import { useIntl } from "react-intl"; +import { wrapAbbr } from "../../../helpers/nameUtils"; import Well from "../../Well"; import { enumToOptions } from "../../../helpers/formUtils"; import messages from "../../../messages/commonMessages"; @@ -96,8 +97,10 @@ const GovernmentInformationSection: React.FunctionComponent<{ })} </span> <span data-h2-font-weight="base(700)"> - {applicant.currentClassification?.group}- - {applicant.currentClassification?.level} + {wrapAbbr( + `${applicant.currentClassification?.group}-${applicant.currentClassification?.level}`, + intl, + )} </span> </p> </div> diff --git a/frontend/common/src/components/form/Select/Select.tsx b/frontend/common/src/components/form/Select/Select.tsx index 73ce4d5c3e9..f4be11a6efa 100644 --- a/frontend/common/src/components/form/Select/Select.tsx +++ b/frontend/common/src/components/form/Select/Select.tsx @@ -6,8 +6,10 @@ import { useFieldState, useFieldStateStyles } from "../../../helpers/formUtils"; export interface Option { value: string | number; - label: string; + label: React.ReactNode; disabled?: boolean; + /** Aria labels for alternate text that will be read by assistive technologies. */ + ariaLabel?: string; } export interface SelectProps @@ -80,7 +82,11 @@ const Select: React.FunctionComponent<SelectProps> = ({ </option> )} {options.map((option) => ( - <option key={option.value} value={option.value}> + <option + aria-label={option.ariaLabel} + key={option.value} + value={option.value} + > {option.label} </option> ))} From 1e56b90bbb4cee01cf47a7a87dd8fd913746c5c4 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 11:03:13 -0500 Subject: [PATCH 05/20] Fix poolUtils tests --- frontend/common/src/helpers/poolUtils.test.ts | 37 ++++++++----------- frontend/common/src/helpers/poolUtils.tsx | 2 +- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/frontend/common/src/helpers/poolUtils.test.ts b/frontend/common/src/helpers/poolUtils.test.ts index d974a68f01e..24ffb59280b 100644 --- a/frontend/common/src/helpers/poolUtils.test.ts +++ b/frontend/common/src/helpers/poolUtils.test.ts @@ -1,4 +1,5 @@ import { createIntl, createIntlCache } from "react-intl"; +import { fakeClassifications } from "../fakeData"; import { PoolStream } from "../api/generated"; import { formattedPoolPosterTitle } from "./poolUtils"; @@ -13,12 +14,12 @@ describe("poolUtils tests", () => { ); const baseInputs = { title: "Web Developer", - classification: "IT-01", + classification: fakeClassifications()[0], stream: PoolStream.SoftwareSolutions, intl, }; test("should combine title, classification and stream if all are provided", () => { - expect(formattedPoolPosterTitle(baseInputs)).toBe( + expect(formattedPoolPosterTitle(baseInputs).label).toBe( "Web Developer (IT-01 Software Solutions)", ); }); @@ -27,53 +28,47 @@ describe("poolUtils tests", () => { formattedPoolPosterTitle({ ...baseInputs, title: null, - }), + }).label, ).toBe("(IT-01 Software Solutions)"); expect( formattedPoolPosterTitle({ ...baseInputs, title: undefined, - }), + }).label, ).toBe("(IT-01 Software Solutions)"); expect( formattedPoolPosterTitle({ ...baseInputs, title: "", - }), + }).label, ).toBe("(IT-01 Software Solutions)"); }); - test("should just be ignore classification if it is null, undefined or empty", () => { + test("should just be ignore classification if it is null or undefined", () => { expect( formattedPoolPosterTitle({ ...baseInputs, classification: null, - }), + }).label, ).toBe("Web Developer (Software Solutions)"); expect( formattedPoolPosterTitle({ ...baseInputs, classification: undefined, - }), - ).toBe("Web Developer (Software Solutions)"); - expect( - formattedPoolPosterTitle({ - ...baseInputs, - classification: "", - }), + }).label, ).toBe("Web Developer (Software Solutions)"); }); - test("should just be ignore stream if it is null, undefined or empty", () => { + test("should just be ignore stream if it is null or undefined", () => { expect( formattedPoolPosterTitle({ ...baseInputs, stream: null, - }), + }).label, ).toBe("Web Developer (IT-01)"); expect( formattedPoolPosterTitle({ ...baseInputs, stream: undefined, - }), + }).label, ).toBe("Web Developer (IT-01)"); }); test("should leave out parentheses entirely if classification and stream are both empty", () => { @@ -82,24 +77,24 @@ describe("poolUtils tests", () => { ...baseInputs, classification: undefined, stream: null, - }), + }).label, ).toBe("Web Developer"); expect( formattedPoolPosterTitle({ ...baseInputs, classification: null, stream: undefined, - }), + }).label, ).toBe("Web Developer"); }); test("should return empty string if title, classification all empty", () => { expect( formattedPoolPosterTitle({ title: "", - classification: "", + classification: null, stream: null, intl, - }), + }).label, ).toBe(""); }); }); diff --git a/frontend/common/src/helpers/poolUtils.tsx b/frontend/common/src/helpers/poolUtils.tsx index 855df935617..75717013a6b 100644 --- a/frontend/common/src/helpers/poolUtils.tsx +++ b/frontend/common/src/helpers/poolUtils.tsx @@ -56,7 +56,7 @@ export const formattedPoolPosterTitle = ({ </> ), label: `${title ? `${title}` : ""} ${ - genericTitle ? ` (${genericTitle})` : "" + genericTitle ? `(${genericTitle})` : "" }`.trim(), }; }; From 706cd9c463806872dc0ea2deb47ea5843ef991d7 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 14:34:07 -0500 Subject: [PATCH 06/20] Add aria-label to span instead of abbr --- frontend/common/src/helpers/nameUtils.tsx | 42 ++++++++++------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 5f4e27d53d4..6aef0390ad5 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -100,7 +100,7 @@ export const wrapAbbr = ( }); return ( <abbr title={fallbackTitle}> - <span aria-hidden="true">{text}</span> + <span>{text}</span> </abbr> ); } @@ -108,46 +108,42 @@ export const wrapAbbr = ( // Regex that matches with all IT(en)/TI(fr) classification with levels case stringifyText.match(/[IT][TI]-0\d/)?.input: return ( - <abbr - title={intl.formatMessage(getAbbreviations("IT"))} - aria-label={stringifyText.replace("-0", "").split("").join(" ")} - > - <span aria-hidden="true">{text}</span> + <abbr title={intl.formatMessage(getAbbreviations("IT"))}> + <span + aria-label={stringifyText.replace("-0", "").split("").join(" ")} + > + {text} + </span> </abbr> ); // Regex that matches with all IT(en)/TI(fr) classification case stringifyText.match(/[IT][TI]/)?.input: return ( - <abbr - title={intl.formatMessage(getAbbreviations("IT"))} - aria-label={stringifyText.split("").join(" ")} - > - <span aria-hidden="true">{text}</span> + <abbr title={intl.formatMessage(getAbbreviations("IT"))}> + <span aria-label={stringifyText.split("").join(" ")}>{text}</span> </abbr> ); // Regex that matches with all AS classification with levels case stringifyText.match(/[AS][SA]-0\d/)?.input: return ( - <abbr - title={intl.formatMessage(getAbbreviations("AS"))} - aria-label={stringifyText.replace("-0", "").split("").join(" ")} - > - <span aria-hidden="true">{text}</span> + <abbr title={intl.formatMessage(getAbbreviations("AS"))}> + <span + aria-label={stringifyText.replace("-0", "").split("").join(" ")} + > + {text} + </span> </abbr> ); case stringifyText.match(/[AS][SA]/)?.input: return ( - <abbr - title={intl.formatMessage(getAbbreviations("AS"))} - aria-label={stringifyText.split("").join(" ")} - > - <span aria-hidden="true">{text}</span> + <abbr title={intl.formatMessage(getAbbreviations("AS"))}> + <span aria-label={stringifyText.split("").join(" ")}>{text}</span> </abbr> ); default: return ( - <abbr title={title} aria-label={(text as string).split("").join(" ")}> - <span aria-hidden="true">{text}</span> + <abbr title={title}> + <span aria-label={(text as string).split("").join(" ")}>{text}</span> </abbr> ); } From 537023d0efaaf8f907dac94001cfea9f3be8ec64 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 15:03:22 -0500 Subject: [PATCH 07/20] Update old poolAdvertisement title helper --- .../components/GeneralInformationTab/ChangeDateDialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeDateDialog.tsx b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeDateDialog.tsx index 586972627d5..839d1804357 100644 --- a/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeDateDialog.tsx +++ b/apps/web/src/pages/Users/ViewUserPage/components/GeneralInformationTab/ChangeDateDialog.tsx @@ -9,7 +9,7 @@ import { getFullNameHtml } from "@common/helpers/nameUtils"; import { Input } from "@common/components/form"; import { commonMessages, errorMessages } from "@common/messages"; import { currentDate } from "@common/helpers/formUtils"; -import { getFullPoolAdvertisementTitle } from "@common/helpers/poolUtils"; +import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; import { Applicant, @@ -117,7 +117,7 @@ export const ChangeDateDialog: React.FC<ChangeDateDialogProps> = ({ })} </p> <p data-h2-font-weight="base(800)"> - - {getFullPoolAdvertisementTitle(intl, selectedCandidate.pool)} + - {getFullPoolAdvertisementTitleHtml(intl, selectedCandidate.pool)} </p> <FormProvider {...methods}> <form onSubmit={handleSubmit(submitForm)}> From 468e0fb453795411adcd92f3bc37f9ee3a8c3423 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 20:59:17 -0500 Subject: [PATCH 08/20] Miscellaneous fixes to breaking tests --- apps/web/src/lang/fr.json | 36 +- apps/web/src/pages/Home/IAPHomePage/Home.tsx | 108 ++++-- .../OngoingRecruitmentSection.test.tsx | 2 +- .../OngoingRecruitmentSection.tsx | 365 +++++++++++++----- .../pages/Pools/BrowsePoolsPage/messages.ts | 41 ++ .../src/constants/localizedConstants.tsx | 8 +- frontend/common/src/helpers/poolUtils.tsx | 2 +- frontend/common/src/lang/fr.json | 8 +- 8 files changed, 428 insertions(+), 142 deletions(-) diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 4197f018509..fb8fb2ed64b 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -5395,8 +5395,8 @@ "defaultMessage": "Solutions logicielles de la <abbreviation>TI</abbreviation>", "description": "Title for the 'software solutions' IT work stream" }, - "UMPxOg": { - "defaultMessage": "Le Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones est une initiative du gouvernement du Canada visant particulièrement les Premières Nations, les Inuits et les Métis. C’est un chemin vers un emploi dans la fonction publique fédérale pour les personnes autochtones qui ont une passion pour la technologie de l’information (TI).", + "b3v0nI": { + "defaultMessage": "Le Programme d’apprentissage en <abbreviation>TI</abbreviation> pour les personnes autochtones est une initiative du gouvernement du Canada visant particulièrement les Premières Nations, les Inuits et les Métis. C’est un chemin vers un emploi dans la fonction publique fédérale pour les personnes autochtones qui ont une passion pour la technologie de l’information (<abbreviation>TI</abbreviation>).", "description": "First paragraph about the program" }, "W2G590": { @@ -5420,7 +5420,7 @@ "description": "Checkbox label for Level IT-04 senior advisor selection, ignore things in <> tags please" }, "cMDC/P": { - "defaultMessage": "Répondre à la forte demande de talents autochtones en TI.", + "defaultMessage": "Répondre à la forte demande de talents autochtones en <abbreviation>TI</abbreviation>.", "description": "Talent portal strategy item 1 content" }, "drDPf3": { @@ -5432,7 +5432,7 @@ "description": "Title for the 'enterprise architecture' IT work stream" }, "gxOExQ": { - "defaultMessage": "Nous voulons en apprendre davantage sur vous et sur votre intérêt ou votre passion dans le domaine de la TI!", + "defaultMessage": "Nous voulons en apprendre davantage sur vous et sur votre intérêt ou votre passion dans le domaine de la <abbreviation>TI</abbreviation>!", "description": "How it works, step 2 content sentence 1" }, "hKKYYL": { @@ -5610,5 +5610,33 @@ "weLwJA": { "defaultMessage": "Recherche de talent", "description": "Link text for the search page breadcrumb" + }, + "AR+sqf": { + "defaultMessage": "Gestion de bases de données de la TI", + "description": "Label for the 'database management' IT work stream" + }, + "YbkM7u": { + "defaultMessage": "Architecture intégrée de la TI", + "description": "Label for the 'enterprise architecture' IT work stream" + }, + "i8DgUB": { + "defaultMessage": "Opérations d’infrastructure de la TI", + "description": "Label for the 'infrastructure operations' IT work stream" + }, + "NHjbIl": { + "defaultMessage": "Planification et établissement de rapports en matière de TI", + "description": "Label for the 'planning and reporting' IT work stream" + }, + "lCHx90": { + "defaultMessage": "Gestion de portefeuilles de projets de la TI", + "description": "Label for the 'project portfolio management' IT work stream" + }, + "/2Vhvl": { + "defaultMessage": "Sécurité de la TI", + "description": "Label for the 'security' IT work stream" + }, + "QSTaWO": { + "defaultMessage": "Solutions logicielles de la TI", + "description": "Label for the 'software solutions' IT work stream" } } diff --git a/apps/web/src/pages/Home/IAPHomePage/Home.tsx b/apps/web/src/pages/Home/IAPHomePage/Home.tsx index b1649537677..1e99e8e26d0 100644 --- a/apps/web/src/pages/Home/IAPHomePage/Home.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/Home.tsx @@ -196,12 +196,18 @@ const Home: React.FunctionComponent = () => { })} </Heading> <p data-h2-margin="base(x2, 0, x1, 0)"> - {intl.formatMessage({ - defaultMessage: - "The <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples is a Government of Canada initiative specifically for First Nations, Inuit, and Métis peoples. It is pathway to employment in the federal public service for Indigenous peoples who have a passion for Information Technology (IT).", - id: "UMPxOg", - description: "First paragraph about the program", - })} + {intl.formatMessage( + { + defaultMessage: + "The <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples is a Government of Canada initiative specifically for First Nations, Inuit, and Métis peoples. It is pathway to employment in the federal public service for Indigenous peoples who have a passion for Information Technology (<abbreviation>IT</abbreviation>).", + id: "b3v0nI", + description: "First paragraph about the program", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> <p data-h2-margin="base(x1, 0)"> {intl.formatMessage({ @@ -490,12 +496,18 @@ const Home: React.FunctionComponent = () => { data-h2-font-size="base(h3, 1)" > <span data-h2-display="base(block)"> - {intl.formatMessage({ - defaultMessage: - "Is the <abbreviation>IT</abbreviation> Apprenticeship Program right for you?", - id: "W2G590", - description: "Application box heading part one", - })} + {intl.formatMessage( + { + defaultMessage: + "Is the <abbreviation>IT</abbreviation> Apprenticeship Program right for you?", + id: "W2G590", + description: "Application box heading part one", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </span> <span> {intl.formatMessage({ @@ -572,12 +584,17 @@ const Home: React.FunctionComponent = () => { color="white" data-h2-margin="base(0, 0, x3, 0) p-tablet(x3, 0)" > - {intl.formatMessage({ - defaultMessage: - "<abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples + The Indigenous Talent Portal", - id: "Zd1x6H", - description: "heading for indigenous talent portal section", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples + The Indigenous Talent Portal", + id: "Zd1x6H", + description: "heading for indigenous talent portal section", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </Heading> <Heading as="h3" color="white"> {intl.formatMessage({ @@ -640,12 +657,18 @@ const Home: React.FunctionComponent = () => { })} > <p data-h2-margin="base(x1, 0, 0, 0)"> - {intl.formatMessage({ - defaultMessage: - "We want to learn about you and about your interest/passion in the area of <abbreviation>IT</abbreviation>!", - id: "gxOExQ", - description: "How it works, step 2 content sentence 1", - })} + {intl.formatMessage( + { + defaultMessage: + "We want to learn about you and about your interest/passion in the area of <abbreviation>IT</abbreviation>!", + id: "gxOExQ", + description: "How it works, step 2 content sentence 1", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> <p data-h2-margin="base(x1, 0, 0, 0)"> {intl.formatMessage({ @@ -699,13 +722,18 @@ const Home: React.FunctionComponent = () => { data-h2-color="base(ia-white)" data-h2-max-width="base(38rem)" > - {intl.formatMessage({ - defaultMessage: - "In collaboration with the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples, the Indigenous Talent Portal will begin with a focus on <abbreviation>IT</abbreviation> and technology talent, which will:", - id: "9FKjvW", - description: - "Description for strategy for the indigenous talent portal", - })} + {intl.formatMessage( + { + defaultMessage: + "In collaboration with the <abbreviation>IT</abbreviation> Apprenticeship Program for Indigenous Peoples, the Indigenous Talent Portal will begin with a focus on <abbreviation>IT</abbreviation> and technology talent, which will:", + id: "9FKjvW", + description: + "Description for strategy for the indigenous talent portal", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </div> <div data-h2-flex-grid="base(flex-start, x3, x2)"> @@ -719,12 +747,18 @@ const Home: React.FunctionComponent = () => { })} > <p> - {intl.formatMessage({ - defaultMessage: - "Address the great demand for Indigenous talent in <abbreviation>IT</abbreviation>.", - id: "cMDC/P", - description: "Talent portal strategy item 1 content", - })} + {intl.formatMessage( + { + defaultMessage: + "Address the great demand for Indigenous talent in <abbreviation>IT</abbreviation>.", + id: "cMDC/P", + description: "Talent portal strategy item 1 content", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </Card> </div> diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.test.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.test.tsx index def4f563a8e..69fbbc1b01c 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.test.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.test.tsx @@ -76,7 +76,7 @@ describe("BrowsePoolsPage", () => { fireEvent.click( await screen.getByRole("button", { - name: /IT business line advisory services/i, + name: /business line advisory services/i, }), ); diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx index 0eac446a426..1d970804bc2 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx @@ -15,18 +15,20 @@ import { getId, notEmpty, uniqueItems } from "@common/helpers/util"; import { PoolAdvertisement, useMySkillsQuery } from "~/api/generated"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; import messages from "../../messages"; // the shape of the data model to populate this component interface StreamViewModel { key: PoolStream; - title: string; - summary: string; + title: React.ReactNode; + label: React.ReactNode; + summary: React.ReactNode; classifications: { - title: string; + title: React.ReactNode; description: React.ReactNode; poolAdvertisement: PoolAdvertisement | undefined; - applyMessage: string; + applyMessage: React.ReactNode; }[]; } @@ -99,16 +101,26 @@ const OngoingRecruitmentSection = ({ .map(getId); const mySkillIds = uniqueItems(mySkillIdsWithDuplicates ?? []); + const abbreviation = (text: React.ReactNode) => wrapAbbr(text, intl); + + // this great big object is all the data to populate the accordions // this great big object is all the data to populate the accordions const streams: StreamViewModel[] = [ // IT business line advisory services bucket { key: PoolStream.BusinessAdvisoryServices, - title: intl.formatMessage(messages.businessAdvisoryServicesTitle), - summary: intl.formatMessage(messages.businessAdvisoryServicesSummary), + title: intl.formatMessage(messages.businessAdvisoryServicesTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.businessAdvisoryServicesLabel), + summary: intl.formatMessage(messages.businessAdvisoryServicesSummary, { + abbreviation, + }), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -117,11 +129,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.businessAdvisoryServicesTitle), + name: intl.formatMessage(messages.businessAdvisoryServicesTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -130,11 +146,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.businessAdvisoryServicesTitle), + name: intl.formatMessage(messages.businessAdvisoryServicesTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -152,15 +172,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.businessAdvisoryServicesTitle), + name: intl.formatMessage(messages.businessAdvisoryServicesTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -174,7 +200,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.businessAdvisoryServicesTitle), + name: intl.formatMessage(messages.businessAdvisoryServicesTitle, { + abbreviation, + }), }), }, ], @@ -182,11 +210,16 @@ const OngoingRecruitmentSection = ({ // IT database management { key: PoolStream.DatabaseManagement, - title: intl.formatMessage(messages.databaseManagementTitle), + title: intl.formatMessage(messages.databaseManagementTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.databaseManagementLabel), summary: intl.formatMessage(messages.databaseManagementSummary), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -195,11 +228,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.databaseManagementTitle), + name: intl.formatMessage(messages.databaseManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -208,11 +245,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.databaseManagementTitle), + name: intl.formatMessage(messages.databaseManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -230,15 +271,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.databaseManagementTitle), + name: intl.formatMessage(messages.databaseManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -252,7 +299,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.databaseManagementTitle), + name: intl.formatMessage(messages.databaseManagementTitle, { + abbreviation, + }), }), }, ], @@ -260,11 +309,18 @@ const OngoingRecruitmentSection = ({ // IT enterprise architecture { key: PoolStream.EnterpriseArchitecture, - title: intl.formatMessage(messages.enterpriseArchitectureTitle), - summary: intl.formatMessage(messages.enterpriseArchitectureSummary), + title: intl.formatMessage(messages.enterpriseArchitectureTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.enterpriseArchitectureLabel), + summary: intl.formatMessage(messages.enterpriseArchitectureSummary, { + abbreviation, + }), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -273,11 +329,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.enterpriseArchitectureTitle), + name: intl.formatMessage(messages.enterpriseArchitectureTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -286,11 +346,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.enterpriseArchitectureTitle), + name: intl.formatMessage(messages.enterpriseArchitectureTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -308,15 +372,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.enterpriseArchitectureTitle), + name: intl.formatMessage(messages.enterpriseArchitectureTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -330,7 +400,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.enterpriseArchitectureTitle), + name: intl.formatMessage(messages.enterpriseArchitectureTitle, { + abbreviation, + }), }), }, ], @@ -338,11 +410,18 @@ const OngoingRecruitmentSection = ({ // IT infrastructure operations { key: PoolStream.InfrastructureOperations, - title: intl.formatMessage(messages.infrastructureOperationsTitle), - summary: intl.formatMessage(messages.infrastructureOperationsSummary), + title: intl.formatMessage(messages.infrastructureOperationsTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.infrastructureOperationsLabel), + summary: intl.formatMessage(messages.infrastructureOperationsSummary, { + abbreviation, + }), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -351,11 +430,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.infrastructureOperationsTitle), + name: intl.formatMessage(messages.infrastructureOperationsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -364,11 +447,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.infrastructureOperationsTitle), + name: intl.formatMessage(messages.infrastructureOperationsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -386,15 +473,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.infrastructureOperationsTitle), + name: intl.formatMessage(messages.infrastructureOperationsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -408,7 +501,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.infrastructureOperationsTitle), + name: intl.formatMessage(messages.infrastructureOperationsTitle, { + abbreviation, + }), }), }, ], @@ -416,11 +511,18 @@ const OngoingRecruitmentSection = ({ // IT planning and reporting { key: PoolStream.PlanningAndReporting, - title: intl.formatMessage(messages.planningAndReportingTitle), - summary: intl.formatMessage(messages.planningAndReportingSummary), + title: intl.formatMessage(messages.planningAndReportingTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.planningAndReportingLabel), + summary: intl.formatMessage(messages.planningAndReportingSummary, { + abbreviation, + }), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -429,11 +531,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.planningAndReportingTitle), + name: intl.formatMessage(messages.planningAndReportingTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -442,11 +548,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.planningAndReportingTitle), + name: intl.formatMessage(messages.planningAndReportingTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -464,15 +574,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.planningAndReportingTitle), + name: intl.formatMessage(messages.planningAndReportingTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -486,7 +602,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.planningAndReportingTitle), + name: intl.formatMessage(messages.planningAndReportingTitle, { + abbreviation, + }), }), }, ], @@ -494,11 +612,18 @@ const OngoingRecruitmentSection = ({ // IT project portfolio management { key: PoolStream.ProjectPortfolioManagement, - title: intl.formatMessage(messages.projectPortfolioManagementTitle), - summary: intl.formatMessage(messages.projectPortfolioSummary), + title: intl.formatMessage(messages.projectPortfolioManagementTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.projectPortfolioManagementLabel), + summary: intl.formatMessage(messages.projectPortfolioSummary, { + abbreviation, + }), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -507,11 +632,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.projectPortfolioManagementTitle), + name: intl.formatMessage(messages.projectPortfolioManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -520,11 +649,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.projectPortfolioManagementTitle), + name: intl.formatMessage(messages.projectPortfolioManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -542,15 +675,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.projectPortfolioManagementTitle), + name: intl.formatMessage(messages.projectPortfolioManagementTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -564,7 +703,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.projectPortfolioManagementTitle), + name: intl.formatMessage(messages.projectPortfolioManagementTitle, { + abbreviation, + }), }), }, ], @@ -572,11 +713,16 @@ const OngoingRecruitmentSection = ({ // IT security { key: PoolStream.Security, - title: intl.formatMessage(messages.securityTitle), + title: intl.formatMessage(messages.securityTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.securityLabel), summary: intl.formatMessage(messages.securitySummary), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -585,11 +731,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.securityTitle), + name: intl.formatMessage(messages.securityTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -598,11 +748,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.securityTitle), + name: intl.formatMessage(messages.securityTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -620,15 +774,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.securityTitle), + name: intl.formatMessage(messages.securityTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -643,7 +803,9 @@ const OngoingRecruitmentSection = ({ ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.securityTitle), + name: intl.formatMessage(messages.securityTitle, { + abbreviation, + }), }), }, ], @@ -651,11 +813,16 @@ const OngoingRecruitmentSection = ({ // IT software solutions { key: PoolStream.SoftwareSolutions, - title: intl.formatMessage(messages.softwareSolutionsTitle), + title: intl.formatMessage(messages.softwareSolutionsTitle, { + abbreviation, + }), + label: intl.formatMessage(messages.softwareSolutionsLabel), summary: intl.formatMessage(messages.softwareSolutionsSummary), classifications: [ { - title: intl.formatMessage(messages.it01Title), + title: intl.formatMessage(messages.it01Title, { + abbreviation, + }), description: intl.formatMessage(messages.it01Description), poolAdvertisement: selectPoolForSection( pools, @@ -664,11 +831,15 @@ const OngoingRecruitmentSection = ({ 1, ), applyMessage: intl.formatMessage(messages.it01ApplyMessage, { - name: intl.formatMessage(messages.softwareSolutionsTitle), + name: intl.formatMessage(messages.softwareSolutionsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it02Title), + title: intl.formatMessage(messages.it02Title, { + abbreviation, + }), description: intl.formatMessage(messages.it02Description), poolAdvertisement: selectPoolForSection( pools, @@ -677,11 +848,15 @@ const OngoingRecruitmentSection = ({ 2, ), applyMessage: intl.formatMessage(messages.it02ApplyMessage, { - name: intl.formatMessage(messages.softwareSolutionsTitle), + name: intl.formatMessage(messages.softwareSolutionsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it03Title), + title: intl.formatMessage(messages.it03Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> @@ -699,15 +874,21 @@ const OngoingRecruitmentSection = ({ 3, ), applyMessage: intl.formatMessage(messages.it03ApplyMessage, { - name: intl.formatMessage(messages.softwareSolutionsTitle), + name: intl.formatMessage(messages.softwareSolutionsTitle, { + abbreviation, + }), }), }, { - title: intl.formatMessage(messages.it04Title), + title: intl.formatMessage(messages.it04Title, { + abbreviation, + }), description: ( <> <p data-h2-margin="base(0, 0, x0.75, 0)"> - {intl.formatMessage(messages.it04Description1)} + {intl.formatMessage(messages.it04Description1, { + abbreviation, + })} </p> <p data-h2-margin="base(0, 0, x0.75, 0)"> {intl.formatMessage(messages.it04Description2)} @@ -721,7 +902,9 @@ const OngoingRecruitmentSection = ({ 4, ), applyMessage: intl.formatMessage(messages.it04ApplyMessage, { - name: intl.formatMessage(messages.softwareSolutionsTitle), + name: intl.formatMessage(messages.softwareSolutionsTitle, { + abbreviation, + }), }), }, ], @@ -802,7 +985,7 @@ const OngoingRecruitmentSection = ({ }, ...streamsWithAvailablePools.map((stream) => ({ value: stream.key, - label: stream.title, + label: stream.label, })), ]} trackUnsaved={false} @@ -875,7 +1058,7 @@ const OngoingRecruitmentSection = ({ ) .map((classification) => ( <div - key={classification.title} + key={`${classification.title}`} data-h2-padding="base(0,0,x1, 0)" > <h4 diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts b/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts index 39d276fd465..97b10ade3fd 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/messages.ts @@ -9,6 +9,12 @@ const messages = defineMessages({ description: "Title for the 'business line advisory services' IT work stream", }, + businessAdvisoryServicesLabel: { + defaultMessage: "IT business line advisory services", + id: "ZOEHxi", + description: + "Label for the 'business line advisory services' IT work stream", + }, businessAdvisoryServicesSummary: { defaultMessage: "This stream includes providing specialized <abbreviation>IT</abbreviation> guidance as well as working with clients and/or suppliers to acquire and sustain <abbreviation>IT</abbreviation> resources that support Government operation.", @@ -21,6 +27,11 @@ const messages = defineMessages({ id: "vbEXnp", description: "Title for the 'database management' IT work stream", }, + databaseManagementLabel: { + defaultMessage: "IT database management", + id: "AR+sqf", + description: "Label for the 'database management' IT work stream", + }, databaseManagementSummary: { defaultMessage: "This stream includes developing and maintaining data models, database design, capacity planning, performance management, and ensuring data integrity.", @@ -32,6 +43,11 @@ const messages = defineMessages({ id: "eFNBND", description: "Title for the 'enterprise architecture' IT work stream", }, + enterpriseArchitectureLabel: { + defaultMessage: "IT enterprise architecture", + id: "YbkM7u", + description: "Label for the 'enterprise architecture' IT work stream", + }, enterpriseArchitectureSummary: { defaultMessage: "This stream includes working with the departmental <abbreviation>IT</abbreviation> architecture direction, collaborating with other <abbreviation>IT</abbreviation> streams, and conducting research into emerging technologies.", @@ -43,6 +59,11 @@ const messages = defineMessages({ id: "6G1ESr", description: "Title for the 'infrastructure operations' IT work stream", }, + infrastructureOperationsLabel: { + defaultMessage: "IT infrastructure operations", + id: "i8DgUB", + description: "Label for the 'infrastructure operations' IT work stream", + }, infrastructureOperationsSummary: { defaultMessage: "This stream includes infrastructure management of networks, mainframes, servers, and storage, providing <abbreviation>IT</abbreviation> support, and client/supplier relationships.", @@ -54,6 +75,11 @@ const messages = defineMessages({ id: "E3loNV", description: "Title for the 'planning and reporting' IT work stream", }, + planningAndReportingLabel: { + defaultMessage: "IT planning and reporting", + id: "NHjbIl", + description: "Label for the 'planning and reporting' IT work stream", + }, planningAndReportingSummary: { defaultMessage: "This stream includes providing specialized <abbreviation>IT</abbreviation> planning guidance, and the collaborative creation of deliverables that include strategic plans, <abbreviation>IT</abbreviation> policies and standards, and governance processes.", @@ -66,6 +92,11 @@ const messages = defineMessages({ id: "AlRcyu", description: "Title for the 'project portfolio management' IT work stream", }, + projectPortfolioManagementLabel: { + defaultMessage: "IT project portfolio management", + id: "lCHx90", + description: "Label for the 'project portfolio management' IT work stream", + }, projectPortfolioSummary: { defaultMessage: "This bucket includes working full-time on large, formal projects that require the sharing of and application of rigorous application of <abbreviation>IT</abbreviation> project management skills and knowledge.", @@ -77,6 +108,11 @@ const messages = defineMessages({ id: "wzoCfb", description: "Title for the 'security' IT work stream", }, + securityLabel: { + defaultMessage: "IT security", + id: "/2Vhvl", + description: "Label for the 'security' IT work stream", + }, securitySummary: { defaultMessage: "This stream includes specialized security skills that focus in programming, infrastructure, business applications, and data.", @@ -88,6 +124,11 @@ const messages = defineMessages({ id: "Tjd942", description: "Title for the 'software solutions' IT work stream", }, + softwareSolutionsLabel: { + defaultMessage: "IT software solutions", + id: "QSTaWO", + description: "Label for the 'software solutions' IT work stream", + }, softwareSolutionsSummary: { defaultMessage: "This stream includes programming, systems design and development, business analysis, configuration, testing, and implementation.", diff --git a/frontend/common/src/constants/localizedConstants.tsx b/frontend/common/src/constants/localizedConstants.tsx index 7fa291bd1fb..0059bd57b53 100644 --- a/frontend/common/src/constants/localizedConstants.tsx +++ b/frontend/common/src/constants/localizedConstants.tsx @@ -1541,13 +1541,13 @@ export const publishingGroups = defineMessages({ description: "The publishing group called Executive Jobs", }, [PublishingGroup.ItJobs]: { - defaultMessage: "<abbreviation>IT</abbreviation> Jobs", - id: "Xis88S", + defaultMessage: "IT Jobs", + id: "C8nrGM", description: "The publishing group called IT Jobs", }, [PublishingGroup.ItJobsOngoing]: { - defaultMessage: "<abbreviation>IT</abbreviation> Jobs (ongoing)", - id: "IKoOjC", + defaultMessage: "IT Jobs (ongoing)", + id: "1YuZjR", description: "The publishing group called IT Jobs for ongoing recruitments", }, [PublishingGroup.Other]: { diff --git a/frontend/common/src/helpers/poolUtils.tsx b/frontend/common/src/helpers/poolUtils.tsx index 75717013a6b..0171e4da741 100644 --- a/frontend/common/src/helpers/poolUtils.tsx +++ b/frontend/common/src/helpers/poolUtils.tsx @@ -51,7 +51,7 @@ export const formattedPoolPosterTitle = ({ return { html: ( <> - {`${title ? `${title}` : ""}`} ({wrapAbbr(groupAndLevel, intl)}{" "} + {`${title ? `${title}` : ""}`} ({wrapAbbr(groupAndLevel, intl)} {streamString ? ` ${streamString}` : ""}) </> ), diff --git a/frontend/common/src/lang/fr.json b/frontend/common/src/lang/fr.json index d6111f170c5..46e375afb79 100644 --- a/frontend/common/src/lang/fr.json +++ b/frontend/common/src/lang/fr.json @@ -1978,16 +1978,16 @@ "6svHxg": { "defaultMessage": "Services administratifs" }, - "IKoOjC": { - "defaultMessage": "Emplois en <abbreviation>TI</abbreviation> (en cours)", + "1YuZjR": { + "defaultMessage": "Emplois en TI (en cours)", "description": "The publishing group called IT Jobs for ongoing recruitments" }, "MuWdei": { "defaultMessage": "Abréviation non trouvée.", "description": "Message shown to user when the abbreviation text is not found." }, - "Xis88S": { - "defaultMessage": "Emplois en <abbreviation>TI</abbreviation>", + "C8nrGM": { + "defaultMessage": "Emplois en TI", "description": "The publishing group called IT Jobs" } } From 782191e2ccc811748bd60b4b9f2a3306e009298f Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 3 Feb 2023 21:24:09 -0500 Subject: [PATCH 09/20] Fix translation --- apps/web/src/lang/fr.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index fb8fb2ed64b..340a556f98c 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -5335,6 +5335,10 @@ "defaultMessage": "Services consultatifs auprès des secteurs d’activité de la <abbreviation>TI</abbreviation>", "description": "Title for the 'business line advisory services' IT work stream" }, + "ZOEHxi": { + "defaultMessage": "Services consultatifs auprès des secteurs d’activité de la TI", + "description": "Label for the 'business line advisory services' IT work stream" + }, "I/fGUN": { "defaultMessage": "Analyste (<abbreviation>TI-02</abbreviation>)", "description": "Title for the 'IT-02 Analyst' classification" From cd6190ee80e2895306a1d880f0cdc43aad10ff38 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Wed, 8 Feb 2023 11:00:27 -0500 Subject: [PATCH 10/20] Fix relative path imports --- apps/web/src/components/SelfDeclaration/HelpLink.tsx | 2 +- apps/web/src/components/SelfDeclaration/SignAndContinue.tsx | 2 +- apps/web/src/hooks/useQuote.tsx | 2 +- .../src/pages/Home/HomePage/components/Featured/Featured.tsx | 2 +- .../Home/HomePage/components/Opportunities/Opportunities.tsx | 2 +- apps/web/src/pages/Home/IAPHomePage/Home.tsx | 2 +- .../pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx | 2 +- .../pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx | 2 +- .../IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx | 2 +- apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx | 2 +- .../OngoingRecruitmentSection/OngoingRecruitmentSection.tsx | 2 +- .../pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx | 2 +- .../components/ClassificationDefinition.tsx | 2 +- .../components/EmploymentEquityForm/EmploymentEquityForm.tsx | 2 +- .../ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx | 2 +- .../RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx | 2 +- .../web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/web/src/components/SelfDeclaration/HelpLink.tsx b/apps/web/src/components/SelfDeclaration/HelpLink.tsx index 5c0f4163cce..3139c372e29 100644 --- a/apps/web/src/components/SelfDeclaration/HelpLink.tsx +++ b/apps/web/src/components/SelfDeclaration/HelpLink.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const contactLink = (chunks: React.ReactNode) => ( <a diff --git a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx index 15b1ef8e9f0..10cb4c75fc4 100644 --- a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx +++ b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx @@ -5,7 +5,7 @@ import { useFormContext } from "react-hook-form"; import { Input, Submit } from "@common/components/form"; import { FieldLabels } from "@common/components/form/BasicForm"; import errorMessages from "@common/messages/errorMessages"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" interface SignAndContinueProps { labels: FieldLabels; diff --git a/apps/web/src/hooks/useQuote.tsx b/apps/web/src/hooks/useQuote.tsx index 0756d577b09..0b6a1197c82 100644 --- a/apps/web/src/hooks/useQuote.tsx +++ b/apps/web/src/hooks/useQuote.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; export interface Quote { content: React.ReactNode | string; diff --git a/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx b/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx index 5b442ef1e0d..12d1a78c3c0 100644 --- a/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Featured/Featured.tsx @@ -6,7 +6,7 @@ import imageUrl from "@common/helpers/imageUrl"; import Heading from "@common/components/Heading"; import { getLocale } from "@common/helpers/localize"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import Block from "./Block"; // Create the page component diff --git a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx index c0873f48608..4f04cdf4d1b 100644 --- a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx @@ -11,7 +11,7 @@ import imageUrl from "@common/helpers/imageUrl"; import { AuthenticationContext } from "@common/components/Auth"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; // Create the page component const Opportunities = () => { diff --git a/apps/web/src/pages/Home/IAPHomePage/Home.tsx b/apps/web/src/pages/Home/IAPHomePage/Home.tsx index 1e99e8e26d0..b21d50206ad 100644 --- a/apps/web/src/pages/Home/IAPHomePage/Home.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/Home.tsx @@ -6,7 +6,7 @@ import imageUrl from "@common/helpers/imageUrl"; import useQuote from "~/hooks/useQuote"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import Banner from "./components/Banner"; import Card from "./components/Card"; import CTAButtons from "./components/CTAButtons"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx index 73b08cc9f71..8221e89f512 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import CloseButton from "./CloseButton"; import { BasicDialogProps } from "./types"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx index f69269b468f..f026853f0fa 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import Heading from "../Heading"; import CloseButton from "./CloseButton"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx index 737501d4cac..6576e56bfaf 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import CloseButton from "./CloseButton"; import type { BasicDialogProps } from "./types"; diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx index 20f0cc0928d..2ebef0ae485 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx @@ -22,7 +22,7 @@ import { import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import ActiveRecruitmentSection from "./components/ActiveRecruitmentSection/ActiveRecruitmentSection"; import OngoingRecruitmentSection from "./components/OngoingRecruitmentSection/OngoingRecruitmentSection"; diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx index 1d970804bc2..f238c7c1623 100644 --- a/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx +++ b/apps/web/src/pages/Pools/BrowsePoolsPage/components/OngoingRecruitmentSection/OngoingRecruitmentSection.tsx @@ -15,7 +15,7 @@ import { getId, notEmpty, uniqueItems } from "@common/helpers/util"; import { PoolAdvertisement, useMySkillsQuery } from "~/api/generated"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import messages from "../../messages"; // the shape of the data model to populate this component diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx index dd6f413b5be..2d01a359422 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx @@ -45,7 +45,7 @@ import useRoutes from "~/hooks/useRoutes"; import { TALENTSEARCH_RECRUITMENT_EMAIL } from "~/constants/talentSearchConstants"; import { isAdvertisementVisible } from "~/utils/poolUtils"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import PoolInfoCard from "./components/PoolInfoCard"; import ClassificationDefinition from "./components/ClassificationDefinition"; diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx index 442315991cf..8700078a53a 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/components/ClassificationDefinition.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useIntl } from "react-intl"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import { GenericJobTitleKey } from "~/api/generated"; diff --git a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx index c6b9cd84732..74a6611fb29 100644 --- a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx +++ b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx @@ -12,7 +12,7 @@ import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import EquityOptions from "./EquityOptions"; import type { EmploymentEquityUpdateHandler, EquityKeys } from "../../types"; diff --git a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx index d9320a3f06e..750eef08d35 100644 --- a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx +++ b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx @@ -32,7 +32,7 @@ import { ExperienceType } from "~/types/experience"; import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" type MergedExperiences = Array< | AwardExperience diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx index 5713c986cb7..a7c99d428c7 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx @@ -27,7 +27,7 @@ import ProfileFormWrapper, { import profileMessages from "~/messages/profileMessages"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" import { DialogLevelOne, DialogLevelTwo, diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx index 021b31aec7f..3704e75ec7b 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils" export interface DialogLevelsProps { children: React.ReactNode; From 24598c9b8573cc46629739db0c1f62e176e6d6db Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Wed, 8 Feb 2023 13:48:12 -0500 Subject: [PATCH 11/20] Add logging warning if string is not passed to abbreviation rich text formatter tag --- frontend/common/src/helpers/nameUtils.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 6aef0390ad5..391f130848f 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -98,6 +98,10 @@ export const wrapAbbr = ( description: "Message shown to user when the abbreviation text is not found.", }); + // eslint-disable-next-line no-console + console.warn( + "Error using wrapAbbr(): You must provide a string to <abbreviation />", + ); return ( <abbr title={fallbackTitle}> <span>{text}</span> From 36b98187f75d90dd52410f857bfdaec5637fa281 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Wed, 8 Feb 2023 14:03:44 -0500 Subject: [PATCH 12/20] Add splitAndJoin utility function --- .../GovernmentInfoForm/GovernmentInfoForm.tsx | 8 +++--- frontend/common/src/helpers/nameUtils.tsx | 28 +++++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx b/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx index 903d5328f60..559a16c293f 100644 --- a/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx +++ b/apps/web/src/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm.tsx @@ -16,6 +16,7 @@ import { toast } from "@common/components/Toast"; import ExternalLink from "@common/components/Link/ExternalLink"; import { FieldLabels } from "@common/components/form/BasicForm"; import { getFullPoolAdvertisementTitleHtml } from "@common/helpers/poolUtils"; +import { splitAndJoin } from "@common/helpers/nameUtils"; import { Classification, @@ -249,10 +250,9 @@ export const GovernmentInfoFormFields: React.FunctionComponent< id: "YA/7nb", description: "Error message if classification group is not defined.", }), - ariaLabel: `${getLocalizedName( - classification.name, - intl, - )} ${classification.group.split("").join(" ")}`, + ariaLabel: `${getLocalizedName(classification.name, intl)} ${splitAndJoin( + classification.group, + )}`, }; }); const noDupes = uniqBy(classGroupsWithDupes, "label"); diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 391f130848f..905c83c4d03 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -78,12 +78,26 @@ export const getFullNameHtml = ( return `${firstName} ${lastName}`; }; +/** + * Split a string into substrings using the specified separator, and then join all the elements into a string, separated by the specified separator string. + * + * @param text + * @param split + * @param join + * + * @return string + */ +export const splitAndJoin = (text: string, split?: string, join?: string) => + text.split(split || "").join(join || " "); + /** * Wraps common abbreviations in abbr tags to make them more accessible * * @param text text to wrap * @param intl react-intl object * @param title abbreviation title + * + * @returns jsx.element */ export const wrapAbbr = ( text: React.ReactNode, @@ -113,9 +127,7 @@ export const wrapAbbr = ( case stringifyText.match(/[IT][TI]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))}> - <span - aria-label={stringifyText.replace("-0", "").split("").join(" ")} - > + <span aria-label={splitAndJoin(stringifyText.replace("-0", ""))}> {text} </span> </abbr> @@ -124,16 +136,14 @@ export const wrapAbbr = ( case stringifyText.match(/[IT][TI]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))}> - <span aria-label={stringifyText.split("").join(" ")}>{text}</span> + <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> ); // Regex that matches with all AS classification with levels case stringifyText.match(/[AS][SA]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))}> - <span - aria-label={stringifyText.replace("-0", "").split("").join(" ")} - > + <span aria-label={splitAndJoin(stringifyText.replace("-0", ""))}> {text} </span> </abbr> @@ -141,13 +151,13 @@ export const wrapAbbr = ( case stringifyText.match(/[AS][SA]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))}> - <span aria-label={stringifyText.split("").join(" ")}>{text}</span> + <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> ); default: return ( <abbr title={title}> - <span aria-label={(text as string).split("").join(" ")}>{text}</span> + <span aria-label={splitAndJoin(text as string)}>{text}</span> </abbr> ); } From 4813b35273ed12e3203cd3a5b0479c88c97755a3 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Wed, 8 Feb 2023 14:09:52 -0500 Subject: [PATCH 13/20] Add warning to wrapAbbr if abbr title is missing --- frontend/common/src/helpers/nameUtils.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 905c83c4d03..616c0fb6453 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -114,7 +114,7 @@ export const wrapAbbr = ( }); // eslint-disable-next-line no-console console.warn( - "Error using wrapAbbr(): You must provide a string to <abbreviation />", + "Error using wrapAbbr(). You must provide a string to <abbreviation />", ); return ( <abbr title={fallbackTitle}> @@ -155,6 +155,12 @@ export const wrapAbbr = ( </abbr> ); default: + if (title === undefined) { + // eslint-disable-next-line no-console + console.warn( + "<abbr /> is missing a title. You must provide a title to wrapAbbr() parameters.", + ); + } return ( <abbr title={title}> <span aria-label={splitAndJoin(text as string)}>{text}</span> From 30a69f30d526b8537756dac5b53600e08edf7b74 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Wed, 8 Feb 2023 16:43:55 -0500 Subject: [PATCH 14/20] Wrap rest of abbreviations in abbr tag --- apps/web/src/lang/fr.json | 50 ++++++----- .../AccessibilityStatementPage.tsx | 23 ++++-- .../CreateAccountPage/CreateAccountPage.tsx | 20 +++-- .../Auth/LoggedOutPage/LoggedOutPage.tsx | 18 ++-- .../src/pages/Auth/LoginPage/LoginPage.tsx | 79 ++++++++++++------ .../pages/Auth/RegisterPage/RegisterPage.tsx | 82 +++++++++++++------ .../Home/AdminHomePage/AdminHomePage.tsx | 20 +++-- .../Home/HomePage/components/About/About.tsx | 60 +++++++++----- .../Home/HomePage/components/Hero/Hero.tsx | 34 +++++--- .../Opportunities/Opportunities.tsx | 44 +++++++--- .../components/OtherRequirementsSection.tsx | 6 ++ .../DiversityEquityInclusionSection.tsx | 12 +-- .../src/constants/localizedConstants.tsx | 12 ++- frontend/common/src/helpers/nameUtils.tsx | 8 +- frontend/common/src/lang/fr.json | 5 +- 15 files changed, 319 insertions(+), 154 deletions(-) diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index aa78b31bfb9..92b6475bcc9 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -1277,9 +1277,13 @@ "defaultMessage": "Toute langue (anglais ou français)", "description": "No preference for language ability - will accept English or French" }, - "Z3prc4": { + "4RXJ4p": { "defaultMessage": "Connexion à l'aide de la CléGC", - "description": "Title for the login page for applicant profiles." + "description": "Seo title for the login page for applicant profiles." + }, + "iNFweP": { + "defaultMessage": "Connexion à l'aide de la CléGC", + "description": "Page title for the login page for applicant profiles." }, "ZSAzrR": { "defaultMessage": "Date d'expiration :", @@ -1537,9 +1541,13 @@ "defaultMessage": "J'envisagerais d'accepter un emploi qui :", "description": "Legend for optional work preferences check list in work preferences form" }, - "zILELf": { + "H4ug6o": { + "defaultMessage": "S'inscrire à l'aide de la CléGC", + "description": "Seo title for the registration page for applicant profiles." + }, + "YXs6l6": { "defaultMessage": "S'inscrire à l'aide de la CléGC", - "description": "Title for the registration page for applicant profiles." + "description": "Page title for the registration page for applicant profiles." }, "/JQ6DD": { "defaultMessage": "Filtre des exigences en matière d'études", @@ -1893,8 +1901,8 @@ "defaultMessage": "Emplacement : Option à distance", "description": "Pool advertisement location requirement, Remote option" }, - "l3tT4m": { - "defaultMessage": "Derrière la plateforme Talents numériques du GC, il y a toute une équipe qui assure le développement et la conception d'outils, la sélection des candidats, la gestion de talents, le placement des cadres et le soutien aux gestionnaires d'embauche dans leur quête de talents pour offrir des services aux Canadiens.", + "w1Lego": { + "defaultMessage": "Derrière la plateforme Talents numériques du <abbreviation>GC</abbreviation>, il y a toute une équipe qui assure le développement et la conception d'outils, la sélection des candidats, la gestion de talents, le placement des cadres et le soutien aux gestionnaires d'embauche dans leur quête de talents pour offrir des services aux Canadiens.", "description": "Description for the Digital Community Management" }, "+cBKDC": { @@ -1965,8 +1973,8 @@ "defaultMessage": "En savoir plus", "description": "Heading for the about section of the homepage" }, - "951Oju": { - "defaultMessage": "Découvrez les dernières perspectives d’emploi du GC dans le domaine du numérique et de la technologie, des candidats en début de carrière aux professionnels chevronnés ayant plusieurs années d'expérience de travail. Les possibilités d’emploi peuvent varier de postes de niveau d’entrée à des postes de niveau supérieur.", + "jAFzzR": { + "defaultMessage": "Découvrez les dernières perspectives d’emploi du <abbreviation>GC</abbreviation> dans le domaine du numérique et de la technologie, des candidats en début de carrière aux professionnels chevronnés ayant plusieurs années d'expérience de travail. Les possibilités d’emploi peuvent varier de postes de niveau d’entrée à des postes de niveau supérieur.", "description": "Description for the digital government job opportunities" }, "9KOwXq": { @@ -1993,8 +2001,8 @@ "defaultMessage": "Continuer vers l’étape 2", "description": "Button message on footer of review my application page." }, - "EWCP4t": { - "defaultMessage": "Si vous êtes prêt à assumer un rôle de leadership numérique en agissant concrètement pour les Canadiens, vous trouverez des possibilités d'emplois pour des postes de gestions à travers le GC à tous les niveaux jusqu'aux postes de directeur principal de l’information.", + "YEarCb": { + "defaultMessage": "Si vous êtes prêt à assumer un rôle de leadership numérique en agissant concrètement pour les Canadiens, vous trouverez des possibilités d'emplois pour des postes de gestions à travers le <abbreviation>GC</abbreviation> à tous les niveaux jusqu'aux postes de directeur principal de l’information.", "description": "Description for executive jobs in government" }, "FFD16/": { @@ -2045,8 +2053,8 @@ "defaultMessage": "Erreur : la suppression de la candidature a échoué", "description": "Message displayed to user after application fails to get deleted." }, - "MS9dB9": { - "defaultMessage": "Talents numériques du GC", + "eSPoJw": { + "defaultMessage": "Talents numériques du <abbreviation>GC</abbreviation>", "description": "Application title" }, "NjHXGh": { @@ -2153,8 +2161,8 @@ "defaultMessage": "En savoir plus<hidden> sur la façon dont la plateforme a été créée</hidden>", "description": "Link text to learn more about the platform creation" }, - "s3Uz7q": { - "defaultMessage": "Talents numériques du GC n’est qu’une des nombreuses initiatives menées par le bureau de la dirigeante principale de l’information du Canada (BDPI). Apprenez-en davantage sur le rôle du BDPI au sein du gouvernement du Canada. Consultez l’Ambition numérique du Canada 2022 pour connaître la direction future du BDPI.", + "h7URQB": { + "defaultMessage": "Talents numériques du <abbreviation>GC</abbreviation> n’est qu’une des nombreuses initiatives menées par le bureau de la dirigeante principale de l’information du Canada (BDPI). Apprenez-en davantage sur le rôle du BDPI au sein du gouvernement du Canada. Consultez l’Ambition numérique du Canada 2022 pour connaître la direction future du BDPI.", "description": "Description of the Office of the Chief Information Officer" }, "jcl2s9": { @@ -2225,8 +2233,8 @@ "defaultMessage": "Inscrivez-vous<hidden> au programme d’apprentissage destiné aux Autochtones</hidden> maintenant", "description": "Link text to apply for the Indigenous Apprenticeship Program" }, - "GSzckJ": { - "defaultMessage": "Curieux de savoir comment la plateforme Talents numériques du GC a été développée? Vous voulez en savoir plus sur les idées, les conceptions et la philosophie de celle-ci? Découvrez le chemin parcouru depuis le pilote expérimental du Nuage de talents du GC jusqu’à la plateforme d’aujourd’hui.", + "bKRX6C": { + "defaultMessage": "Curieux de savoir comment la plateforme Talents numériques du <abbreviation>GC</abbreviation> a été développée? Vous voulez en savoir plus sur les idées, les conceptions et la philosophie de celle-ci? Découvrez le chemin parcouru depuis le pilote expérimental du Nuage de talents du <abbreviation>GC</abbreviation> jusqu’à la plateforme d’aujourd’hui.", "description": "Description of how the platform was created." }, "ww86SN": { @@ -2249,8 +2257,8 @@ "defaultMessage": "Archiver la candidature", "description": "Titre du modèle qui apparaît lorsqu’un utilisateur tente d’archiver une candidature" }, - "zmV99R": { - "defaultMessage": "Que vous envisagiez de travailler pour le gouvernement ou que vous soyez déjà employé, que vous espériez embaucher ou que vous envisagiez un rôle de direction, c’est l’endroit où venir pour faire partie de la communauté numérique du GC.", + "58Z5Ld": { + "defaultMessage": "Que vous envisagiez de travailler pour le gouvernement ou que vous soyez déjà employé, que vous espériez embaucher ou que vous envisagiez un rôle de direction, c’est l’endroit où venir pour faire partie de la communauté numérique du <abbreviation>GC</abbreviation>.", "description": "Description de la candidature sur la page d’accueil" }, "zqIEuu": { @@ -2529,8 +2537,8 @@ "defaultMessage": "Énoncé sur l’accessibilité", "description": "Title for the websites accessibility statement" }, - "s2+FXu": { - "defaultMessage": "Talent numérique du GC s’engage à créer un service numérique accessible et inclusif. Au cœur de la conception et du développement de notre plateforme, nous nous efforçons de créer des possibilités d'emploi égales pour tous. Pour nous, construire des services accessibles signifie répondre aux besoins du plus grand nombre de personnes possible, y compris les cas marginaux. En fait, nous travaillons dans toutes les disciplines –recherche, développement, conception et accessibilité – pour nous assurer que notre service est intentionnel, accessible et inclusif par sa conception.", + "fNnKNn": { + "defaultMessage": "Talent numérique du <abbreviation>GC</abbreviation> s’engage à créer un service numérique accessible et inclusif. Au cœur de la conception et du développement de notre plateforme, nous nous efforçons de créer des possibilités d'emploi égales pour tous. Pour nous, construire des services accessibles signifie répondre aux besoins du plus grand nombre de personnes possible, y compris les cas marginaux. En fait, nous travaillons dans toutes les disciplines –recherche, développement, conception et accessibilité – pour nous assurer que notre service est intentionnel, accessible et inclusif par sa conception.", "description": "Opening paragraph for accessibility statement" }, "vC9NsS": { @@ -2538,7 +2546,7 @@ "description": "Title for the accessibility standards" }, "tu2Z17": { - "defaultMessage": "L’équipe de Talent numérique GC adhère aux <digitalStandardsLink>normes numériques inclusives du gouvernement du Canada</digitalStandardsLink> (GC).", + "defaultMessage": "L’équipe de Talent numérique <abbreviation>GC</abbreviation> adhère aux <digitalStandardsLink>normes numériques inclusives du gouvernement du Canada</digitalStandardsLink> (GC).", "description": "Paragraph describing accessibility standards" }, "ztQSF+": { diff --git a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx index fc49563c2ca..2b24cf12d24 100644 --- a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx +++ b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx @@ -9,6 +9,7 @@ import { getLocale, Locales } from "@common/helpers/localize"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const digitalStandardsLink = (locale: Locales, chunks: React.ReactNode) => ( <ExternalLink @@ -223,12 +224,17 @@ const AccessibilityStatementPage = () => { data-h2-margin="base:children[p:not(:first-child), ul](x.5, 0, 0, 0)" > <p> - {intl.formatMessage({ - id: "s2+FXu", - defaultMessage: - "GC Digital Talent is committed to building an accessible and inclusive digital service. At the heart of our platform design and development is an endeavour to create equal employment opportunities for all. To us, building accessible services means meeting the needs of as many people as possible, including edge cases. We are working across all disciplines - research, development, design, and accessibility - to ensure our service is intentional, accessible, and inclusive.", - description: "Opening paragraph for accessibility statement", - })} + {intl.formatMessage( + { + id: "fNnKNn", + defaultMessage: + "<abbreviation>GC</abbrevation> Digital Talent is committed to building an accessible and inclusive digital service. At the heart of our platform design and development is an endeavour to create equal employment opportunities for all. To us, building accessible services means meeting the needs of as many people as possible, including edge cases. We are working across all disciplines - research, development, design, and accessibility - to ensure our service is intentional, accessible, and inclusive.", + description: "Opening paragraph for accessibility statement", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <Heading level="h2" size="h3" data-h2-margin="base(x2, 0, x1, 0)"> {intl.formatMessage({ @@ -241,13 +247,14 @@ const AccessibilityStatementPage = () => { {intl.formatMessage( { defaultMessage: - "The GC Digital Talent team follows inclusive <digitalStandardsLink>Government of Canada Digital Standards</digitalStandardsLink>.", - id: "tu2Z17", + "The <abbreviation>GC</abbreviation> Digital Talent team follows inclusive <digitalStandardsLink>Government of Canada Digital Standards</digitalStandardsLink>.", + id: "a3c78j", description: "Paragraph describing accessibility standards", }, { digitalStandardsLink: (chunks: React.ReactNode) => digitalStandardsLink(locale, chunks), + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), }, )} </p> diff --git a/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx b/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx index 50dced56804..854589d3a41 100644 --- a/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx +++ b/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx @@ -30,6 +30,7 @@ import { getGovernmentInfoLabels, GovernmentInfoFormFields, } from "~/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; type FormValues = Pick< UpdateUserAsUserInput, @@ -132,13 +133,18 @@ export const CreateAccountForm: React.FunctionComponent< })} </Alert.Title> <p> - {intl.formatMessage({ - defaultMessage: - "Welcome to the Digital Talent platform. Moving forward, you can log into your profile using the same GC Key username and password.", - id: "0O/eV0", - description: - "Message for successful login alert in create account page.", - })} + {intl.formatMessage( + { + defaultMessage: + "Welcome to the Digital Talent platform. Moving forward, you can log into your profile using the same <abbreviation>GC</abbreviation> Key username and password.", + id: "8+PCdN", + description: + "Message for successful login alert in create account page.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </Alert.Root> <BasicForm diff --git a/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx b/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx index 9cd8dfc9f67..8f64a6926e6 100644 --- a/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx +++ b/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx @@ -11,6 +11,7 @@ import { getLocale } from "@common/helpers/localize"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const LoggedOutPage: React.FC = () => { const intl = useIntl(); @@ -49,12 +50,17 @@ const LoggedOutPage: React.FC = () => { })} </Alert.Title> <p> - {intl.formatMessage({ - defaultMessage: - "Remember, to sign back in, you'll need to use your GC Key username and password. We hope to see you soon!", - id: "6UCzgs", - description: "Message displayed to a user after logging out.", - })} + {intl.formatMessage( + { + defaultMessage: + "Remember, to sign back in, you'll need to use your <abbreviation>GC</abbreviation> Key username and password. We hope to see you soon!", + id: "ocCSfi", + description: "Message displayed to a user after logging out.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </Alert.Root> <h2 data-h2-margin="base(x3, 0, x1, 0)"> diff --git a/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx b/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx index 1a4005b18e4..229ef58004f 100644 --- a/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx +++ b/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx @@ -10,6 +10,7 @@ import SEO from "@common/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const keyRegistrationLink = (path: string, chunks: React.ReactNode) => ( <a href={path}>{chunks}</a> @@ -25,12 +26,25 @@ const LoginPage: React.FC = () => { getLocale(intl), ); - const pageTitle = intl.formatMessage({ + const abbreviation = (text: React.ReactNode) => wrapAbbr(text, intl); + + const seoTitle = intl.formatMessage({ defaultMessage: "Login using GC Key", - id: "Z3prc4", - description: "Title for the login page for applicant profiles.", + id: "4RXJ4p", + description: "Seo title for the login page for applicant profiles.", }); + const pageTitle = intl.formatMessage( + { + defaultMessage: "Login using <abbreviation>GC</abbreviation> Key", + id: "iNFweP", + description: "Page title for the login page for applicant profiles.", + }, + { + abbreviation, + }, + ); + const crumbs = useBreadcrumbs([ { label: pageTitle, @@ -40,39 +54,50 @@ const LoginPage: React.FC = () => { return ( <> - <SEO title={pageTitle} /> + <SEO title={seoTitle} /> <Hero title={pageTitle} crumbs={crumbs} /> <div data-h2-padding="base(x3, 0)"> <div data-h2-container="base(center, small, x1) p-tablet(center, small, x2)"> <p> - {intl.formatMessage({ - defaultMessage: - "You can log into your Digital Talent profile using your existing GC Key, even if you’ve never used this platform before.", - id: "K7wsxV", - description: "Instructions on how to login with GC Key.", - })} + {intl.formatMessage( + { + defaultMessage: + "You can log into your Digital Talent profile using your existing <abbreviation>GC</abbreviation> Key, even if you’ve never used this platform before.", + id: "lgsXDg", + description: "Instructions on how to login with GC Key.", + }, + { + abbreviation, + }, + )} </p> <p data-h2-margin="base(x.5, 0, 0, 0)"> - {intl.formatMessage({ - defaultMessage: - "If you’re unsure whether you have an existing GC Key account, continue to the website and try logging in. If you can’t remember your password, you can also reset it there.", - id: "Q2+VXx", - description: - "Instructions on what to do if user doesn't know if they have a GC Key", - })} + {intl.formatMessage( + { + defaultMessage: + "If you’re unsure whether you have an existing <abbreviation>GC</abbreviation> Key account, continue to the website and try logging in. If you can’t remember your password, you can also reset it there.", + id: "kJdLk3", + description: + "Instructions on what to do if user doesn't know if they have a GC Key", + }, + { + abbreviation, + }, + )} </p> <p data-h2-margin="base(x.5, 0, 0, 0)"> {intl.formatMessage( { defaultMessage: - "<strong>Don't have a GC Key account?</strong> <a>Register for one.</a>", - id: "ofOoFQ", + "<strong>Don't have a <abbreviation>GC</abbreviation> Key account?</strong> <a>Register for one.</a>", + id: "veXICB", description: "Instruction on what to do if user does not have a GC Key.", }, { a: (chunks: React.ReactNode) => keyRegistrationLink(loginPath, chunks), + abbreviation, }, )} </p> @@ -105,11 +130,17 @@ const LoginPage: React.FC = () => { type="button" color="primary" > - {intl.formatMessage({ - defaultMessage: "Continue to GC Key and Login", - id: "CZcsxM", - description: "GC Key login link text on the login page.", - })} + {intl.formatMessage( + { + defaultMessage: + "Continue to <abbreviation>GC</abbreviation> Key and Login", + id: "78J7jF", + description: "GC Key login link text on the login page.", + }, + { + abbreviation, + }, + )} </ExternalLink> </p> </div> diff --git a/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx b/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx index fdf7309ddfc..acfcc2752de 100644 --- a/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx +++ b/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx @@ -9,6 +9,7 @@ import { useApiRoutes } from "@common/hooks/useApiRoutes"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const keyRegistrationLink = (path: string, chunks: React.ReactNode) => ( <a href={path}>{chunks}</a> @@ -20,12 +21,26 @@ const RegisterPage: React.FC = () => { const apiPaths = useApiRoutes(); const loginPath = apiPaths.login(paths.myProfile(), getLocale(intl)); - const pageTitle = intl.formatMessage({ + const abbreviation = (text: React.ReactNode) => wrapAbbr(text, intl); + + const seoTitle = intl.formatMessage({ defaultMessage: "Register using GC Key", - id: "zILELf", - description: "Title for the registration page for applicant profiles.", + id: "H4ug6o", + description: "Seo title for the registration page for applicant profiles.", }); + const pageTitle = intl.formatMessage( + { + defaultMessage: "Register using <abbreviation>GC</abbreviation> Key", + id: "YXs6l6", + description: + "Page title for the registration page for applicant profiles.", + }, + { + abbreviation, + }, + ); + const crumbs = useBreadcrumbs([ { label: pageTitle, @@ -35,39 +50,50 @@ const RegisterPage: React.FC = () => { return ( <> - <SEO title={pageTitle} /> + <SEO title={seoTitle} /> <Hero title={pageTitle} crumbs={crumbs} /> <div data-h2-padding="base(x3, 0)"> <div data-h2-container="base(center, small, x1) p-tablet(center, small, x2)"> <p> - {intl.formatMessage({ - defaultMessage: - "You can log into your Digital Talent profile using your existing GC Key, even if you've never used this platform before.", - id: "c3CV4P", - description: "Instructions on how to login with GC Key.", - })} + {intl.formatMessage( + { + defaultMessage: + "You can log into your Digital Talent profile using your existing <abbreviation>GC</abbreviation> Key, even if you've never used this platform before.", + id: "5KRzTl", + description: "Instructions on how to login with GC Key.", + }, + { + abbreviation, + }, + )} </p> <p data-h2-margin="base(x.5, 0, 0, 0)"> - {intl.formatMessage({ - defaultMessage: - "If you're unsure whether you have an existing GC Key account, continue to the website and try logging in. If you can't remember your password, you can also reset it there.", - id: "pcnr9A", - description: - "Instructions on what to do if user doesn't know if they have a GC Key", - })} + {intl.formatMessage( + { + defaultMessage: + "If you're unsure whether you have an existing <abbreviation>GC</abbreviation> Key account, continue to the website and try logging in. If you can't remember your password, you can also reset it there.", + id: "5uOWv0", + description: + "Instructions on what to do if user doesn't know if they have a GC Key", + }, + { + abbreviation, + }, + )} </p> <p data-h2-margin="base(x.5, 0, 0, 0)"> {intl.formatMessage( { defaultMessage: - "<strong>Don't have a GC Key account?</strong> <a>Register for one.</a>", - id: "ofOoFQ", + "<strong>Don't have a <abbreviation>GC</abbreviation> Key account?</strong> <a>Register for one.</a>", + id: "veXICB", description: "Instruction on what to do if user does not have a GC Key.", }, { a: (chunks: React.ReactNode) => keyRegistrationLink(loginPath, chunks), + abbreviation, }, )} </p> @@ -94,12 +120,18 @@ const RegisterPage: React.FC = () => { type="button" color="primary" > - {intl.formatMessage({ - defaultMessage: "Continue to GC Key and Register", - id: "9yMdpm", - description: - "GC Key registration link text on the registration page.", - })} + {intl.formatMessage( + { + defaultMessage: + "Continue to <abbreviation>GC</abbreviation> Key and Register", + id: "ATDtfb", + description: + "GC Key registration link text on the registration page.", + }, + { + abbreviation, + }, + )} </ExternalLink> </p> </div> diff --git a/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx b/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx index 76dc7c0c8ea..61f8e39296d 100644 --- a/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx +++ b/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx @@ -14,6 +14,7 @@ import { useApiRoutes } from "@common/hooks/useApiRoutes"; import useAuth from "@common/hooks/useAuth"; import useRoutes from "~/hooks/useRoutes"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const AdminHomePage = () => { const intl = useIntl(); @@ -47,13 +48,18 @@ const AdminHomePage = () => { })} </PageHeader> <p> - {intl.formatMessage({ - defaultMessage: - "Welcome to GC Digital Talent, please log in to continue.", - id: "Nfy1HK", - description: - "Instructional text for the talent cloud pool manager portal home page.", - })} + {intl.formatMessage( + { + defaultMessage: + "Welcome to <abbreviation>GC</abbreviation> Digital Talent, please log in to continue.", + id: "MsFCeF", + description: + "Instructional text for the talent cloud pool manager portal home page.", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> <div data-h2-margin="base(x2, 0, 0, 0)"> <div data-h2-flex-grid="base(top, x2)"> diff --git a/apps/web/src/pages/Home/HomePage/components/About/About.tsx b/apps/web/src/pages/Home/HomePage/components/About/About.tsx index 71dc132382c..38ca1e112c2 100644 --- a/apps/web/src/pages/Home/HomePage/components/About/About.tsx +++ b/apps/web/src/pages/Home/HomePage/components/About/About.tsx @@ -5,6 +5,7 @@ import { NewspaperIcon } from "@heroicons/react/24/outline"; import Heading from "@common/components/Heading"; import { CardFlat } from "@common/components/Card"; import useLocale from "@common/hooks/useLocale"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const About = () => { const intl = useIntl(); @@ -62,13 +63,19 @@ const About = () => { }} > <p> - {intl.formatMessage({ - defaultMessage: - "GC Digital Talent is only one of the many initiatives being led by the Office of the Chief Information Officer of Canada (OCIO). Learn more about OCIO's role in the Government of Canada. Check out Canada's Digital Ambition 2022 to see where OCIO is heading in the future.", - id: "s3Uz7q", - description: - "Description of the Office of the Chief Information Officer", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>GC</abbreviation> Digital Talent is only one of the many initiatives being led by the Office of the Chief Information Officer of Canada (OCIO). Learn more about OCIO's role in the Government of Canada. Check out Canada's Digital Ambition 2022 to see where OCIO is heading in the future.", + id: "h7URQB", + description: + "Description of the Office of the Chief Information Officer", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> <CardFlat @@ -93,13 +100,19 @@ const About = () => { }} > <p> - {intl.formatMessage({ - defaultMessage: - "Behind the GC Digital Talent platform is a whole team of people designing, developing, screening applicants, talent managing employees, placing executives, and helping managers find the talent they need to deliver services to Canadians.", - id: "l3tT4m", - description: - "Description for the Digital Community Management", - })} + {intl.formatMessage( + { + defaultMessage: + "Behind the <abbreviation>GC</abbreviation> Digital Talent platform is a whole team of people designing, developing, screening applicants, talent managing employees, placing executives, and helping managers find the talent they need to deliver services to Canadians.", + id: "w1Lego", + description: + "Description for the Digital Community Management", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> <CardFlat @@ -122,12 +135,19 @@ const About = () => { }} > <p> - {intl.formatMessage({ - defaultMessage: - "Curious about how the GC Digital Talent platform was developed? Want to learn more about the ideas, designs, and philosophy going on behind the scenes? Check out the path from Talent Cloud's experimental pilot to today's full-scale platform.", - id: "GSzckJ", - description: "Description of how the platform was created.", - })} + {intl.formatMessage( + { + defaultMessage: + "Curious about how the <abbreviation>GC</abbreviation> Digital Talent platform was developed? Want to learn more about the ideas, designs, and philosophy going on behind the scenes? Check out the path from Talent Cloud's experimental pilot to today's full-scale platform.", + id: "bKRX6C", + description: + "Description of how the platform was created.", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> </div> diff --git a/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx b/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx index 8d022bf4532..66e432f52bd 100644 --- a/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx @@ -9,6 +9,7 @@ import useRoutes from "~/hooks/useRoutes"; import CallToAction from "~/components/CallToAction/CallToAction"; import "./hero.css"; +import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const landscapeRandomize = (index?: number | undefined) => { const items = [ @@ -51,11 +52,17 @@ const Hero = ({ defaultImage }: HeroProps) => { data-h2-text-align="base(center) p-tablet(left)" > <Heading level="h1" data-h2-margin="base(0, 0, x0.5, 0)"> - {intl.formatMessage({ - defaultMessage: "GC Digital Talent", - id: "MS9dB9", - description: "Application title", - })} + {intl.formatMessage( + { + defaultMessage: + "<abbreviation>GC</abbreviation> Digital Talent", + id: "eSPoJw", + description: "Application title", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </Heading> <p data-h2-font-size="base(h6, 1.4)" @@ -63,12 +70,17 @@ const Hero = ({ defaultImage }: HeroProps) => { data-h2-margin="base(x1, 0, x2, 0)" data-h2-max-width="p-tablet(50%)" > - {intl.formatMessage({ - defaultMessage: - "Whether you're thinking about joining government or already an employee, hoping to hire or considering an executive role, this is the place to come to be part of the GC digital community.", - id: "zmV99R", - description: "Description of the application on the homepage", - })} + {intl.formatMessage( + { + defaultMessage: + "Whether you're thinking about joining government or already an employee, hoping to hire or considering an executive role, this is the place to come to be part of the <abbreviation>GC</abbreviation> digital community.", + id: "58Z5Ld", + description: "Description of the application on the homepage", + }, + { + abbreviation: (text: React.ReactNode) => wrapAbbr(text, intl), + }, + )} </p> </div> <div diff --git a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx index 4f04cdf4d1b..b38e6423cc1 100644 --- a/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Opportunities/Opportunities.tsx @@ -109,13 +109,19 @@ const Opportunities = () => { }} > <p> - {intl.formatMessage({ - defaultMessage: - "Check out the latest GC opportunities in digital and tech, from entry level to management. Find a team, make a difference, and be inspired.", - id: "951Oju", - description: - "Description for the digital government job opportunities", - })} + {intl.formatMessage( + { + defaultMessage: + "Check out the latest <abbreviation>GC</abbreviation> opportunities in digital and tech, from entry level to management. Find a team, make a difference, and be inspired.", + id: "jAFzzR", + description: + "Description for the digital government job opportunities", + }, + { + abbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> <CardFlat @@ -187,12 +193,24 @@ const Opportunities = () => { })} </p> <p> - {intl.formatMessage({ - defaultMessage: - "From entry-level executives to CIO opportunities across the GC, this is the place to come if you're ready to take on a digital leadership role making a difference for Canadians.", - id: "EWCP4t", - description: "Description for executive jobs in government", - })} + {intl.formatMessage( + { + defaultMessage: + "From entry-level executives to <cioAbbreviation>CIO</cioAbbreviation> opportunities across the <gcAbbreviation>GC</gcAbbreviation>, this is the place to come if you're ready to take on a digital leadership role making a difference for Canadians.", + id: "YEarCb", + description: "Description for executive jobs in government", + }, + { + cioAbbreviation: (text: React.ReactNode) => + wrapAbbr( + text, + intl, + "Chief Information Officer of Canada", + ), + gcAbbreviation: (text: React.ReactNode) => + wrapAbbr(text, intl), + }, + )} </p> </CardFlat> </div> diff --git a/apps/web/src/pages/Pools/EditPoolPage/components/OtherRequirementsSection.tsx b/apps/web/src/pages/Pools/EditPoolPage/components/OtherRequirementsSection.tsx index 00aab67618e..f359e0c749a 100644 --- a/apps/web/src/pages/Pools/EditPoolPage/components/OtherRequirementsSection.tsx +++ b/apps/web/src/pages/Pools/EditPoolPage/components/OtherRequirementsSection.tsx @@ -290,6 +290,12 @@ const OtherRequirementsSection = ({ options={enumToOptions(PublishingGroup).map(({ value }) => ({ value, label: intl.formatMessage(getPublishingGroup(value)), + ariaLabel: intl + .formatMessage(getPublishingGroup(value)) + .replace( + intl.locale === "en" ? "IT" : "TI", + intl.locale === "en" ? "I T" : "T I", + ), }))} disabled={formDisabled} /> diff --git a/frontend/common/src/components/UserProfile/ProfileSections/DiversityEquityInclusionSection.tsx b/frontend/common/src/components/UserProfile/ProfileSections/DiversityEquityInclusionSection.tsx index 26df1d1546c..7171147b175 100644 --- a/frontend/common/src/components/UserProfile/ProfileSections/DiversityEquityInclusionSection.tsx +++ b/frontend/common/src/components/UserProfile/ProfileSections/DiversityEquityInclusionSection.tsx @@ -94,8 +94,8 @@ const DiversityEquityInclusionSection: React.FunctionComponent<{ <div data-h2-padding="base(x1, 0, 0, 0)" data-h2-display="p-tablet(flex)" - data-h2-align-items="base:(center)" - data-h2-justify-content="base:(space-between)" + data-h2-align-items="base(center)" + data-h2-justify-content="base(space-between)" > <ul data-h2-padding="base(0, 0, 0, x1)"> <li> @@ -119,7 +119,7 @@ const DiversityEquityInclusionSection: React.FunctionComponent<{ <li> <span data-h2-font-weight="base(700)" - data-h2-color="base:(dt-primary)" + data-h2-color="base(dt-primary)" > {intl.formatMessage( { @@ -139,8 +139,8 @@ const DiversityEquityInclusionSection: React.FunctionComponent<{ </ul> <div data-h2-display="base(flex)" - data-h2-justify-content="base:(center)" - data-h2-flex-wrap="base:(no-wrap)" + data-h2-justify-content="base(center)" + data-h2-flex-wrap="base(no-wrap)" > {nonLegacyIndigenousCommunities.map((community) => { switch (community) { @@ -216,7 +216,7 @@ const DiversityEquityInclusionSection: React.FunctionComponent<{ )} <p data-h2-padding="base(x1, 0, 0, 0)" - data-h2-color="base:(ia-gray.dark)" + data-h2-color="base(ia-gray.dark)" > {intl.formatMessage({ defaultMessage: diff --git a/frontend/common/src/constants/localizedConstants.tsx b/frontend/common/src/constants/localizedConstants.tsx index 65beff26286..0598a5003ec 100644 --- a/frontend/common/src/constants/localizedConstants.tsx +++ b/frontend/common/src/constants/localizedConstants.tsx @@ -1568,14 +1568,18 @@ export const getPublishingGroup = ( ); export const abbreviations = defineMessages({ - IT: { - defaultMessage: "Information Technology", - id: "nLW9zq", - }, AS: { defaultMessage: "Administrative Services", id: "6svHxg", }, + GC: { + defaultMessage: "Government of Canada", + id: "t9i8Ml", + }, + IT: { + defaultMessage: "Information Technology", + id: "nLW9zq", + }, }); export const getAbbreviations = ( diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 616c0fb6453..3b6d66added 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -154,6 +154,12 @@ export const wrapAbbr = ( <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> ); + case stringifyText.match("GC")?.input: + return ( + <abbr title={intl.formatMessage(getAbbreviations("GC"))}> + <span aria-label={splitAndJoin(stringifyText)}>{text}</span> + </abbr> + ); default: if (title === undefined) { // eslint-disable-next-line no-console @@ -163,7 +169,7 @@ export const wrapAbbr = ( } return ( <abbr title={title}> - <span aria-label={splitAndJoin(text as string)}>{text}</span> + <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> ); } diff --git a/frontend/common/src/lang/fr.json b/frontend/common/src/lang/fr.json index 48970a14826..c14d82e472b 100644 --- a/frontend/common/src/lang/fr.json +++ b/frontend/common/src/lang/fr.json @@ -773,7 +773,7 @@ "description": "Current Location label and colon" }, "shPV27": { - "defaultMessage": "A achevé une évaluation officielle du GC :", + "defaultMessage": "A achevé une évaluation officielle du <abbreviation>GC</abbreviation> :", "description": "Completed a government of canada abbreviation evaluation label and colon" }, "spP+Tz": { @@ -2006,6 +2006,9 @@ "6svHxg": { "defaultMessage": "Services administratifs" }, + "t9i8Ml": { + "defaultMessage": "Gouvernement du Canada" + }, "1YuZjR": { "defaultMessage": "Emplois en TI (en cours)", "description": "The publishing group called IT Jobs for ongoing recruitments" From 2a2951650b58b279242180153b6f11bf14c70f66 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Thu, 9 Feb 2023 10:18:45 -0500 Subject: [PATCH 15/20] Fix e2e tests --- apps/e2e/cypress/e2e/talentsearch/direct-intake.cy.js | 2 +- apps/e2e/cypress/e2e/talentsearch/search-workflows.cy.js | 6 +++--- .../e2e/talentsearch/submit-application-workflows.cy.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/e2e/cypress/e2e/talentsearch/direct-intake.cy.js b/apps/e2e/cypress/e2e/talentsearch/direct-intake.cy.js index ac403fecbac..f203e09423d 100644 --- a/apps/e2e/cypress/e2e/talentsearch/direct-intake.cy.js +++ b/apps/e2e/cypress/e2e/talentsearch/direct-intake.cy.js @@ -14,7 +14,7 @@ describe("Talentsearch Direct Intake Page", () => { ].forEach(restrictedPath => { cy.visit(restrictedPath) cy.wait("@gqlbrowsePoolAdvertisementsQuery"); - cy.findByRole("heading", { name: /browse it jobs/i }) + cy.findByRole("heading", { name: /browse i t jobs/i }) .should("exist") .and("be.visible"); }) diff --git a/apps/e2e/cypress/e2e/talentsearch/search-workflows.cy.js b/apps/e2e/cypress/e2e/talentsearch/search-workflows.cy.js index d5eb625bdfb..5f33a453b3c 100644 --- a/apps/e2e/cypress/e2e/talentsearch/search-workflows.cy.js +++ b/apps/e2e/cypress/e2e/talentsearch/search-workflows.cy.js @@ -40,7 +40,7 @@ describe("Talent Search Workflow Tests", () => { const searchFindsMySingleCandidate = () => { cy.findByRole("article", { - name: `Cypress Test Pool EN 1 ${uniqueTestId} (IT-01 Business Line Advisory Services)`, + name: `Cypress Test Pool EN 1 ${uniqueTestId} (I T 1 Business Line Advisory Services)`, }).within(() => { cy.contains("There is 1 matching candidate in this pool"); @@ -53,7 +53,7 @@ describe("Talent Search Workflow Tests", () => { const searchRejectsMySingleCandidate = () => { cy.findByRole("article", { - name: `Cypress Test Pool 1 EN ${uniqueTestId} (IT-01 Business Line Advisory Services)`, + name: `Cypress Test Pool 1 EN ${uniqueTestId} (I T 1 Business Line Advisory Services)`, }).should("not.exist"); }; @@ -250,7 +250,7 @@ describe("Talent Search Workflow Tests", () => { }); cy.findByRole("article", { - name: `Cypress Test Pool EN 1 ${uniqueTestId} (IT-01 Business Line Advisory Services)`, + name: `Cypress Test Pool EN 1 ${uniqueTestId} (I T 1 Business Line Advisory Services)`, }).within(() => { // Finding this button is sensitive to "dom detached" errors. // Must not try to click it unless we know there are no inflight searches. diff --git a/apps/e2e/cypress/e2e/talentsearch/submit-application-workflows.cy.js b/apps/e2e/cypress/e2e/talentsearch/submit-application-workflows.cy.js index d18dd7fe4ee..4df3431ec79 100644 --- a/apps/e2e/cypress/e2e/talentsearch/submit-application-workflows.cy.js +++ b/apps/e2e/cypress/e2e/talentsearch/submit-application-workflows.cy.js @@ -139,7 +139,7 @@ describe("Submit Application Workflow Tests", () => { // Browse pools page - placeholder so it could change cy.wait("@gqlbrowsePoolAdvertisementsQuery"); - cy.findByRole("heading", { name: /browse it jobs/i }) + cy.findByRole("heading", { name: /browse i t jobs/i }) .should("exist") .and("be.visible"); cy.get("@testPoolAdvertisementId").then((testPoolAdvertisementId) => { From cdd384099b1da3dd0f34d39969ea70ca9753f81b Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Thu, 9 Feb 2023 10:19:39 -0500 Subject: [PATCH 16/20] Fix more relative path imports --- apps/web/src/components/SelfDeclaration/SignAndContinue.tsx | 2 +- apps/web/src/lang/fr.json | 2 +- .../AccessibilityStatementPage.tsx | 6 +++--- .../src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx | 2 +- apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx | 2 +- apps/web/src/pages/Auth/LoginPage/LoginPage.tsx | 2 +- apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx | 2 +- apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx | 2 +- apps/web/src/pages/Home/HomePage/components/About/About.tsx | 2 +- apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx | 2 +- apps/web/src/pages/Home/IAPHomePage/Home.tsx | 2 +- .../Home/IAPHomePage/components/Dialog/ApplyDialog.tsx | 2 +- .../Home/IAPHomePage/components/Dialog/LearnDialog.tsx | 2 +- .../IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx | 2 +- .../EmploymentEquityForm/EmploymentEquityForm.tsx | 2 +- .../components/ExperienceAndSkills.tsx | 2 +- .../components/RoleSalaryForm/RoleSalaryForm.tsx | 2 +- .../src/pages/Profile/RoleSalaryPage/components/dialogs.tsx | 2 +- 18 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx index 10cb4c75fc4..c2ecaad3e9c 100644 --- a/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx +++ b/apps/web/src/components/SelfDeclaration/SignAndContinue.tsx @@ -5,7 +5,7 @@ import { useFormContext } from "react-hook-form"; import { Input, Submit } from "@common/components/form"; import { FieldLabels } from "@common/components/form/BasicForm"; import errorMessages from "@common/messages/errorMessages"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; interface SignAndContinueProps { labels: FieldLabels; diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 92b6475bcc9..ca9eca0189e 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -2537,7 +2537,7 @@ "defaultMessage": "Énoncé sur l’accessibilité", "description": "Title for the websites accessibility statement" }, - "fNnKNn": { + "rnPvJN": { "defaultMessage": "Talent numérique du <abbreviation>GC</abbreviation> s’engage à créer un service numérique accessible et inclusif. Au cœur de la conception et du développement de notre plateforme, nous nous efforçons de créer des possibilités d'emploi égales pour tous. Pour nous, construire des services accessibles signifie répondre aux besoins du plus grand nombre de personnes possible, y compris les cas marginaux. En fait, nous travaillons dans toutes les disciplines –recherche, développement, conception et accessibilité – pour nous assurer que notre service est intentionnel, accessible et inclusif par sa conception.", "description": "Opening paragraph for accessibility statement" }, diff --git a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx index 2b24cf12d24..2f7c5c1bafd 100644 --- a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx +++ b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx @@ -6,10 +6,10 @@ import Heading from "@common/components/Heading"; import { ExternalLink } from "@common/components/Link"; import imageUrl from "@common/helpers/imageUrl"; import { getLocale, Locales } from "@common/helpers/localize"; +import { wrapAbbr } from "@common/helpers/nameUtils"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; const digitalStandardsLink = (locale: Locales, chunks: React.ReactNode) => ( <ExternalLink @@ -226,9 +226,9 @@ const AccessibilityStatementPage = () => { <p> {intl.formatMessage( { - id: "fNnKNn", + id: "rnPvJN", defaultMessage: - "<abbreviation>GC</abbrevation> Digital Talent is committed to building an accessible and inclusive digital service. At the heart of our platform design and development is an endeavour to create equal employment opportunities for all. To us, building accessible services means meeting the needs of as many people as possible, including edge cases. We are working across all disciplines - research, development, design, and accessibility - to ensure our service is intentional, accessible, and inclusive.", + "<abbreviation>GC</abbreviation> Digital Talent is committed to building an accessible and inclusive digital service. At the heart of our platform design and development is an endeavour to create equal employment opportunities for all. To us, building accessible services means meeting the needs of as many people as possible, including edge cases. We are working across all disciplines - research, development, design, and accessibility - to ensure our service is intentional, accessible, and inclusive.", description: "Opening paragraph for accessibility statement", }, { diff --git a/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx b/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx index 854589d3a41..429dc9fd105 100644 --- a/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx +++ b/apps/web/src/pages/Auth/CreateAccountPage/CreateAccountPage.tsx @@ -30,7 +30,7 @@ import { getGovernmentInfoLabels, GovernmentInfoFormFields, } from "~/pages/Profile/GovernmentInfoPage/components/GovernmentInfoForm/GovernmentInfoForm"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; type FormValues = Pick< UpdateUserAsUserInput, diff --git a/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx b/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx index 8f64a6926e6..5984cd3800d 100644 --- a/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx +++ b/apps/web/src/pages/Auth/LoggedOutPage/LoggedOutPage.tsx @@ -11,7 +11,7 @@ import { getLocale } from "@common/helpers/localize"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const LoggedOutPage: React.FC = () => { const intl = useIntl(); diff --git a/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx b/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx index 229ef58004f..e24fc5635cc 100644 --- a/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx +++ b/apps/web/src/pages/Auth/LoginPage/LoginPage.tsx @@ -10,7 +10,7 @@ import SEO from "@common/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const keyRegistrationLink = (path: string, chunks: React.ReactNode) => ( <a href={path}>{chunks}</a> diff --git a/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx b/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx index acfcc2752de..d5592f7e699 100644 --- a/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx +++ b/apps/web/src/pages/Auth/RegisterPage/RegisterPage.tsx @@ -9,7 +9,7 @@ import { useApiRoutes } from "@common/hooks/useApiRoutes"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const keyRegistrationLink = (path: string, chunks: React.ReactNode) => ( <a href={path}>{chunks}</a> diff --git a/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx b/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx index 61f8e39296d..43db7e2bd7f 100644 --- a/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx +++ b/apps/web/src/pages/Home/AdminHomePage/AdminHomePage.tsx @@ -14,7 +14,7 @@ import { useApiRoutes } from "@common/hooks/useApiRoutes"; import useAuth from "@common/hooks/useAuth"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const AdminHomePage = () => { const intl = useIntl(); diff --git a/apps/web/src/pages/Home/HomePage/components/About/About.tsx b/apps/web/src/pages/Home/HomePage/components/About/About.tsx index 38ca1e112c2..5df6caede92 100644 --- a/apps/web/src/pages/Home/HomePage/components/About/About.tsx +++ b/apps/web/src/pages/Home/HomePage/components/About/About.tsx @@ -5,7 +5,7 @@ import { NewspaperIcon } from "@heroicons/react/24/outline"; import Heading from "@common/components/Heading"; import { CardFlat } from "@common/components/Card"; import useLocale from "@common/hooks/useLocale"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const About = () => { const intl = useIntl(); diff --git a/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx b/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx index 66e432f52bd..fa097ca862d 100644 --- a/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx +++ b/apps/web/src/pages/Home/HomePage/components/Hero/Hero.tsx @@ -9,7 +9,7 @@ import useRoutes from "~/hooks/useRoutes"; import CallToAction from "~/components/CallToAction/CallToAction"; import "./hero.css"; -import { wrapAbbr } from "~/../../../frontend/common/src/helpers/nameUtils"; +import { wrapAbbr } from "@common/helpers/nameUtils"; const landscapeRandomize = (index?: number | undefined) => { const items = [ diff --git a/apps/web/src/pages/Home/IAPHomePage/Home.tsx b/apps/web/src/pages/Home/IAPHomePage/Home.tsx index b21d50206ad..77e10ac5f5d 100644 --- a/apps/web/src/pages/Home/IAPHomePage/Home.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/Home.tsx @@ -6,7 +6,7 @@ import imageUrl from "@common/helpers/imageUrl"; import useQuote from "~/hooks/useQuote"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import Banner from "./components/Banner"; import Card from "./components/Card"; import CTAButtons from "./components/CTAButtons"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx index 8221e89f512..517f1bf6c47 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/ApplyDialog.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import CloseButton from "./CloseButton"; import { BasicDialogProps } from "./types"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx index f026853f0fa..f864d986e56 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/LearnDialog.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import Heading from "../Heading"; import CloseButton from "./CloseButton"; diff --git a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx index 6576e56bfaf..03600e34202 100644 --- a/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx +++ b/apps/web/src/pages/Home/IAPHomePage/components/Dialog/SelfDeclarationDialog.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl"; import Button from "@common/components/Button"; import Dialog from "@common/components/Dialog"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import CloseButton from "./CloseButton"; import type { BasicDialogProps } from "./types"; diff --git a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx index 74a6611fb29..8c8248c5008 100644 --- a/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx +++ b/apps/web/src/pages/Profile/EmploymentEquityPage/components/EmploymentEquityForm/EmploymentEquityForm.tsx @@ -12,7 +12,7 @@ import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import EquityOptions from "./EquityOptions"; import type { EmploymentEquityUpdateHandler, EquityKeys } from "../../types"; diff --git a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx index 750eef08d35..25b84bb8607 100644 --- a/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx +++ b/apps/web/src/pages/Profile/ExperienceAndSkillsPage/components/ExperienceAndSkills.tsx @@ -32,7 +32,7 @@ import { ExperienceType } from "~/types/experience"; import ProfileFormWrapper, { ProfileFormFooter, } from "~/components/ProfileFormWrapper/ProfileFormWrapper"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; type MergedExperiences = Array< | AwardExperience diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx index a7c99d428c7..1dd1c48e476 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/RoleSalaryForm/RoleSalaryForm.tsx @@ -27,7 +27,7 @@ import ProfileFormWrapper, { import profileMessages from "~/messages/profileMessages"; import useRoutes from "~/hooks/useRoutes"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; import { DialogLevelOne, DialogLevelTwo, diff --git a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx index 3704e75ec7b..f1634c78e96 100644 --- a/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx +++ b/apps/web/src/pages/Profile/RoleSalaryPage/components/dialogs.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl"; import Dialog from "@common/components/Dialog"; import Button from "@common/components/Button"; -import { wrapAbbr } from "@common/helpers/nameUtils" +import { wrapAbbr } from "@common/helpers/nameUtils"; export interface DialogLevelsProps { children: React.ReactNode; From 86102a7499b8f4babe3d36646b97c939a6f16f80 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Thu, 9 Feb 2023 10:42:24 -0500 Subject: [PATCH 17/20] Fix translations --- apps/web/src/lang/fr.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index ca9eca0189e..44936a6968f 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -861,7 +861,7 @@ "defaultMessage": "Expérience supprimée", "description": "Message displayed to user after experience deleted." }, - "0O/eV0": { + "8+PCdN": { "defaultMessage": "Bienvenue sur la plateforme Talent numérique. À l'avenir, vous pouvez vous connecter à votre profil en utilisant le même nom d'utilisateur et le même mot de passe que cléGC.", "description": "Message for successful login alert in create account page." }, @@ -917,7 +917,7 @@ "defaultMessage": "Postes en français", "description": "Message for the french positions option" }, - "6UCzgs": { + "ocCSfi": { "defaultMessage": "N'oubliez pas que, pour vous reconnecter, vous devez utiliser votre nom d'utilisateur et votre mot de passe de la CléGC. Nous espérons vous voir bientôt!", "description": "Message displayed to a user after logging out." }, @@ -953,7 +953,7 @@ "defaultMessage": "Sélectionnez un niveau...", "description": "Placeholder displayed on the language information form comprehension field." }, - "9yMdpm": { + "ATDtfb": { "defaultMessage": "Continuer vers CléGC et s'inscrire", "description": "GC Key registration link text on the registration page." }, @@ -989,7 +989,7 @@ "defaultMessage": "ID :", "description": "The ID and colon" }, - "CZcsxM": { + "78J7jF": { "defaultMessage": "Continuer vers CléGC et se connecter", "description": "GC Key login link text on the login page." }, @@ -1069,7 +1069,7 @@ "defaultMessage": "Ces renseignements personnels supplémentaires ne seront utilisés qu'à des fins de communication.", "description": "Description for Personal Information section of the About Me form" }, - "K7wsxV": { + "lgsXDg": { "defaultMessage": "Vous pouvez vous connecter à votre profil Talent numérique à l'aide de votre CléGC existante, même si vous n'avez jamais utilisé cette plateforme auparavant.", "description": "Instructions on how to login with GC Key." }, @@ -1157,7 +1157,7 @@ "defaultMessage": "Faites-nous savoir si vous voulez être contacté(e) pour de nouveaux emplois. Veuillez mettre à jour ce statut si votre situation change.", "description": "Description for My Status Form" }, - "Q2+VXx": { + "kJdLk3": { "defaultMessage": "Si vous n'êtes pas sûr(e) d'avoir un compte CléGC existant, continuez vers le site Web et essayez de vous connecter. Si vous ne pouvez pas vous souvenir de votre mot de passe, vous pouvez également le réinitialiser là.", "description": "Instructions on what to do if user doesn't know if they have a GC Key" }, @@ -1309,7 +1309,7 @@ "defaultMessage": "Préférence pour le lieu de travail", "description": "Display Text for the current page in Work Location Preference Form Page" }, - "c3CV4P": { + "5KRzTl": { "defaultMessage": "Vous pouvez vous connecter à votre profil Talent numérique à l'aide de votre CléGC existante, même si vous n'avez jamais utilisé cette plateforme auparavant.", "description": "Instructions on how to login with GC Key." }, @@ -1445,7 +1445,7 @@ "defaultMessage": "2. Compétences affichées pendant cette expérience", "description": "Title for skills on Experience form" }, - "pcnr9A": { + "5uOWv0": { "defaultMessage": "Si vous n'êtes pas sûr(e) d'avoir un compte CléGC existant, continuez vers le site Web et essayez de vous connecter. Si vous ne pouvez pas vous souvenir de votre mot de passe, vous pouvez également le réinitialiser là.", "description": "Instructions on what to do if user doesn't know if they have a GC Key" }, @@ -1605,7 +1605,7 @@ "defaultMessage": "Je suis bilingue (anglais et français) et <strong>j'ai</strong> complété une <languageEvaluationPageLink></languageEvaluationPageLink> officielle en <strong>ANGLAIS</strong>.", "description": "Message for the completed english bilingual evaluation option" }, - "ofOoFQ": { + "veXICB": { "defaultMessage": "<strong>Vous n'avez pas de compte de CléGC?</strong> <a>Inscrivez-vous.</a>", "description": "Instruction on what to do if user does not have a GC Key." }, @@ -2545,7 +2545,7 @@ "defaultMessage": "Nos normes", "description": "Title for the accessibility standards" }, - "tu2Z17": { + "a3c78j": { "defaultMessage": "L’équipe de Talent numérique <abbreviation>GC</abbreviation> adhère aux <digitalStandardsLink>normes numériques inclusives du gouvernement du Canada</digitalStandardsLink> (GC).", "description": "Paragraph describing accessibility standards" }, @@ -3740,7 +3740,7 @@ "defaultMessage": "Choisir un bassin :", "description": "Second section of text on the add user to pool dialog" }, - "Nfy1HK": { + "MsFCeF": { "defaultMessage": "Bienvenue à Talent numérique du GC, veuillez vous connecter pour continuer.", "description": "Instructional text for the talent cloud pool manager portal home page." }, From ec7eac054b5d919ebe96a90a38288ac4c5955538 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Thu, 9 Feb 2023 12:28:14 -0500 Subject: [PATCH 18/20] fix auth e2e test --- apps/e2e/cypress/e2e/admin/auth.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/admin/auth.cy.js b/apps/e2e/cypress/e2e/admin/auth.cy.js index 8db4270824e..81aeefce3cb 100644 --- a/apps/e2e/cypress/e2e/admin/auth.cy.js +++ b/apps/e2e/cypress/e2e/admin/auth.cy.js @@ -109,7 +109,7 @@ describe('Auth flows (development)', () => { const initialPath = '/en/admin/users' cy.visit(initialPath) onLoginInfoPage() - cy.findByRole('link', { name: /Continue to GC Key and Login/i}).click() + cy.findByRole('link', { name: /Continue to G C Key and Login/i}).click() onAuthLoginPage() loginViaUI('admin') From 4d2fa8fcdf1d425e4b7c34de779e3a25c1ace6f6 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Fri, 10 Feb 2023 14:45:59 -0500 Subject: [PATCH 19/20] Fix message with CIO abbreviation --- apps/web/src/lang/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 44936a6968f..706e990322c 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -2002,7 +2002,7 @@ "description": "Button message on footer of review my application page." }, "YEarCb": { - "defaultMessage": "Si vous êtes prêt à assumer un rôle de leadership numérique en agissant concrètement pour les Canadiens, vous trouverez des possibilités d'emplois pour des postes de gestions à travers le <abbreviation>GC</abbreviation> à tous les niveaux jusqu'aux postes de directeur principal de l’information.", + "defaultMessage": "Si vous êtes prêt à assumer un rôle de leadership numérique en agissant concrètement pour les Canadiens, vous trouverez des possibilités d'emplois pour des postes de gestions à travers le <gcAbbreviation>GC</gcAbbreviation> à tous les niveaux jusqu'aux postes de directeur principal de l’information.", "description": "Description for executive jobs in government" }, "FFD16/": { From 78adc9d344031397c0e9bcc6faa4ced6f85eae15 Mon Sep 17 00:00:00 2001 From: Yonathan K <yoni.kid15@gmail.com> Date: Mon, 13 Feb 2023 11:35:26 -0500 Subject: [PATCH 20/20] Ensure fallback title is used for edge cases --- frontend/common/src/helpers/nameUtils.tsx | 31 ++++++++--------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/frontend/common/src/helpers/nameUtils.tsx b/frontend/common/src/helpers/nameUtils.tsx index 3b6d66added..d3b94748ca0 100644 --- a/frontend/common/src/helpers/nameUtils.tsx +++ b/frontend/common/src/helpers/nameUtils.tsx @@ -104,18 +104,14 @@ export const wrapAbbr = ( intl: IntlShape, title?: string, ): JSX.Element => { + const fallbackTitle = intl.formatMessage({ + id: "MuWdei", + defaultMessage: "Abbreviation not found.", + description: + "Message shown to user when the abbreviation text is not found.", + }); const stringifyText = text && text.toString(); // grabs text from React.ReactNode (is there a better way to get text from React.ReactNode type?) if (typeof stringifyText !== "string") { - const fallbackTitle = intl.formatMessage({ - id: "MuWdei", - defaultMessage: "Abbreviation not found.", - description: - "Message shown to user when the abbreviation text is not found.", - }); - // eslint-disable-next-line no-console - console.warn( - "Error using wrapAbbr(). You must provide a string to <abbreviation />", - ); return ( <abbr title={fallbackTitle}> <span>{text}</span> @@ -123,7 +119,7 @@ export const wrapAbbr = ( ); } switch (stringifyText) { - // Regex that matches with all IT(en)/TI(fr) classification with levels + // Regex that matches all IT(en)/TI(fr) classifications with levels case stringifyText.match(/[IT][TI]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))}> @@ -132,14 +128,14 @@ export const wrapAbbr = ( </span> </abbr> ); - // Regex that matches with all IT(en)/TI(fr) classification + // Regex that matches all IT(en)/TI(fr) classifications case stringifyText.match(/[IT][TI]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("IT"))}> <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> ); - // Regex that matches with all AS classification with levels + // Regex that matches all AS(en)/SA(fr) classifications with levels case stringifyText.match(/[AS][SA]-0\d/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))}> @@ -148,6 +144,7 @@ export const wrapAbbr = ( </span> </abbr> ); + // Regex that matches all AS(en)/SA(fr) classifications case stringifyText.match(/[AS][SA]/)?.input: return ( <abbr title={intl.formatMessage(getAbbreviations("AS"))}> @@ -161,14 +158,8 @@ export const wrapAbbr = ( </abbr> ); default: - if (title === undefined) { - // eslint-disable-next-line no-console - console.warn( - "<abbr /> is missing a title. You must provide a title to wrapAbbr() parameters.", - ); - } return ( - <abbr title={title}> + <abbr title={title ?? fallbackTitle}> <span aria-label={splitAndJoin(stringifyText)}>{text}</span> </abbr> );