Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Test] Release/2.39.3 #12502

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 17 additions & 18 deletions api/app/Generators/ApplicationDocGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,22 @@ public function generate(): self

$snapshot = $candidate->profile_snapshot;
$user = User::hydrateSnapshot($snapshot);
$experiences = isset($snapshot['experiences']) ? Experience::hydrateSnapshot($snapshot['experiences']) : [];
$snapshotExperiences = isset($snapshot['experiences']) ? $snapshot['experiences'] : [];

// the snapshot stores the department and classification models connected by relation
// to render with GeneratesUserDoc or use hydrateSnapshot, map the models to a string with the appropriate property name per $hydrationFields
foreach ($snapshotExperiences as &$experience) {
if ($experience['__typename'] === 'WorkExperience') {
if (isset($experience['department'])) {
$experience['departmentId'] = $experience['department']['id'];
}
if (isset($experience['classification'])) {
$experience['classificationId'] = $experience['classification']['id'];
}
}
}
$experiences = Experience::hydrateSnapshot($snapshotExperiences);

$section->addTitle($user->getFullName(), 2);

$section->addTitle($this->localizeHeading('education_requirement'), 3);
Expand Down Expand Up @@ -88,23 +103,7 @@ public function generate(): self
});
}

if (isset($snapshot['experiences'])) {
$snapshotExperiences = $snapshot['experiences'];

// the snapshot stores the department and classification models connected by relation
// to render with GeneratesUserDoc, map the model to a string with the appropriate property name
foreach ($snapshotExperiences as &$experience) {
if ($experience['__typename'] === 'WorkExperience') {
if (isset($experience['department'])) {
$experience['departmentId'] = $experience['department']['id'];
}
if (isset($experience['classification'])) {
$experience['classificationId'] = $experience['classification']['id'];
}
}
}

$experiences = Experience::hydrateSnapshot($snapshotExperiences);
if ($experiences && count($experiences) > 0) {
$this->experiences($section, collect($experiences), false, 2);
}

Expand Down
4 changes: 4 additions & 0 deletions api/app/Models/Experience.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ protected function makeJsonPropertyStringAttribute(string $propertyName): Attrib
);
}

/**
* @param mixed $snapshot the snapshot
* @return array array of experiences
*/
public static function hydrateSnapshot(mixed $snapshot): Model|array
{
$experiences = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { HTMLProps, ReactNode } from "react";

import { Link, Heading, HeadingLevel, CardBasic } from "@gc-digital-talent/ui";
import { getLocale } from "@gc-digital-talent/i18n";
import { assertUnreachable } from "@gc-digital-talent/helpers";

import applicationMessages from "~/messages/applicationMessages";
import {
Expand All @@ -12,6 +13,7 @@ import {
foreignDegreeLink,
postSecondaryLink,
} from "~/utils/educationUtils";
import { ClassificationGroup } from "~/types/classificationGroup";

type TextProps = HTMLProps<HTMLParagraphElement>;

Expand Down Expand Up @@ -65,7 +67,7 @@ const Or = (props: HTMLProps<HTMLDivElement>) => {

interface EducationRequirementsProps {
isIAP: boolean;
classificationGroup?: string;
classificationGroup: ClassificationGroup;
headingAs?: HeadingLevel;
}

Expand Down Expand Up @@ -280,7 +282,7 @@ const EducationRequirements = ({
</CardBasic>
</Wrapper>
);
default:
case "IT":
return (
<Wrapper>
<CardBasic>
Expand Down Expand Up @@ -352,6 +354,8 @@ const EducationRequirements = ({
</CardBasic>
</Wrapper>
);
default:
return assertUnreachable(classificationGroup); // exhaustive switch
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ import {
getSkillLevelName,
} from "@gc-digital-talent/i18n";
import { toast } from "@gc-digital-talent/toast";
import { useLogger } from "@gc-digital-talent/logger";

import { getExperienceSkills } from "~/utils/skillUtils";
import { getEducationRequirementOptions } from "~/utils/educationUtils";
import { isIAPPool } from "~/utils/poolUtils";
import poolCandidateMessages from "~/messages/poolCandidateMessages";
import {
ClassificationGroup,
isClassificationGroup,
} from "~/types/classificationGroup";

import useLabels from "./useLabels";
import ExperienceCard from "../ExperienceCard/ExperienceCard";
Expand Down Expand Up @@ -345,6 +350,7 @@ export const ScreeningDecisionDialog = ({
}: ScreeningDecisionDialogProps) => {
const intl = useIntl();
const locale = getLocale(intl);
const logger = useLogger();
const dialogType = useDialogType(
educationRequirement ? undefined : { type: assessmentStep?.type },
);
Expand Down Expand Up @@ -386,7 +392,16 @@ export const ScreeningDecisionDialog = ({
getExperienceSkills(unpackMaybes(parsedSnapshot?.experiences), skill)
.length > 0;

const classificationGroup = poolCandidate.pool.classification?.group;
let classificationGroup: ClassificationGroup;

if (isClassificationGroup(poolCandidate.pool.classification?.group)) {
classificationGroup = poolCandidate.pool.classification?.group;
} else {
logger.error(
`Unexpected classification: ${poolCandidate.pool.classification?.group}`,
);
classificationGroup = "IT";
}

const educationRequirementOption = getEducationRequirementOptions(
intl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ import {
EducationRequirementOption,
Experience,
} from "@gc-digital-talent/graphql";
import { useLogger } from "@gc-digital-talent/logger";

import applicationMessages from "~/messages/applicationMessages";
import { isEducationExperience } from "~/utils/experienceUtils";
import useRoutes from "~/hooks/useRoutes";
import { GetPageNavInfo } from "~/types/applicationStep";
import { ExperienceForDate } from "~/types/experience";
import { getEducationRequirementOptions } from "~/utils/educationUtils";
import {
ClassificationGroup,
isClassificationGroup,
} from "~/types/classificationGroup";

import useUpdateApplicationMutation from "../useUpdateApplicationMutation";
import { ApplicationPageProps } from "../ApplicationApi";
Expand Down Expand Up @@ -88,6 +93,7 @@ const ApplicationEducation = ({
const intl = useIntl();
const locale = getLocale(intl);
const paths = useRoutes();
const logger = useLogger();
const navigate = useNavigate();
const { followingPageUrl, currentStepOrdinal, isIAP, classificationGroup } =
useApplicationContext();
Expand Down Expand Up @@ -210,6 +216,15 @@ const ApplicationEducation = ({
}
};

let classificationGroupTyped: ClassificationGroup;

if (isClassificationGroup(classificationGroup)) {
classificationGroupTyped = classificationGroup;
} else {
logger.error(`Unexpected classification: ${classificationGroup}`);
classificationGroupTyped = "IT";
}

return (
<>
<Heading
Expand Down Expand Up @@ -265,7 +280,7 @@ const ApplicationEducation = ({
items={getEducationRequirementOptions(
intl,
locale,
classificationGroup,
classificationGroupTyped,
isIAP,
)}
rules={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ import {
getFragment,
graphql,
} from "@gc-digital-talent/graphql";
import { useLogger } from "@gc-digital-talent/logger";

import EducationRequirements from "~/components/EducationRequirements/EducationRequirements";
import { isInNullState } from "~/validators/process/classification";
import useToggleSectionInfo from "~/hooks/useToggleSectionInfo";
import { wrapAbbr } from "~/utils/nameUtils";
import {
ClassificationGroup,
isClassificationGroup,
} from "~/types/classificationGroup";

import { SectionProps } from "../types";

Expand Down Expand Up @@ -85,7 +90,16 @@ const EducationRequirementsSection = ({
emptyRequired: isNull, // Not a required field
fallbackIcon: TagIcon,
});
const classificationGroup = pool.classification?.group;
const logger = useLogger();

let classificationGroup: ClassificationGroup;

if (isClassificationGroup(pool.classification?.group)) {
classificationGroup = pool.classification.group;
} else {
logger.error(`Unexpected classification: ${pool.classification?.group}`);
classificationGroup = "IT";
}
const classificationAbbr = pool.classification
? wrapAbbr(`${classificationGroup}-0${pool.classification.level}`, intl)
: "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
FragmentType,
getFragment,
} from "@gc-digital-talent/graphql";
import { useLogger } from "@gc-digital-talent/logger";

import {
formatClassificationString,
Expand All @@ -63,6 +64,10 @@ import ApplicationLink, {
ApplicationLinkProps,
} from "~/components/ApplicationLink/ApplicationLink";
import SkillAccordion from "~/components/PoolSkillAccordion/PoolSkillAccordion";
import {
ClassificationGroup,
isClassificationGroup,
} from "~/types/classificationGroup";

import Text from "./components/Text";
import DataRow from "./components/DataRow";
Expand Down Expand Up @@ -309,6 +314,7 @@ export const PoolPoster = ({
const intl = useIntl();
const locale = getLocale(intl);
const paths = useRoutes();
const logger = useLogger();
const notAvailable = intl.formatMessage(commonMessages.notAvailable);
const [moreInfoValue, setMoreInfoValue] = useState<string[]>([]);
const [skillsValue, setSkillsValue] = useState<string[]>([]);
Expand Down Expand Up @@ -492,7 +498,14 @@ export const PoolPoster = ({
},
};

const classificationGroup = pool.classification?.group;
let classificationGroup: ClassificationGroup;

if (isClassificationGroup(pool.classification?.group)) {
classificationGroup = pool.classification.group;
} else {
logger.error(`Unexpected classification: ${pool.classification?.group}`);
classificationGroup = "IT";
}

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import {
WorkStream,
} from "@gc-digital-talent/graphql";
import { commonMessages } from "@gc-digital-talent/i18n";
import { useLogger } from "@gc-digital-talent/logger";

import { FormValues } from "~/types/searchRequest";
import useRoutes from "~/hooks/useRoutes";
import { isClassificationGroup } from "~/types/classificationGroup";

import { formValuesToData } from "../utils";
import { useCandidateCount, useInitialFilters } from "../hooks";
Expand Down Expand Up @@ -61,8 +63,15 @@ export const SearchForm = ({
const intl = useIntl();
const navigate = useNavigate();
const paths = useRoutes();
const logger = useLogger();
const { defaultValues, initialFilters } = useInitialFilters();

classifications.forEach(({ group }) => {
if (!isClassificationGroup(group)) {
logger.error(`Unexpected classification: ${group}`);
}
});

const [applicantFilter, setApplicantFilter] =
useState<ApplicantFilterInput>(initialFilters);

Expand Down
17 changes: 17 additions & 0 deletions apps/web/src/types/classificationGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const CLASSIFICATION_GROUP = [
"AS",
"CR",
"EC",
"EX",
"IT",
"PM",
] as const; // List of classification groups that we expect need to be handled.

export type ClassificationGroup = (typeof CLASSIFICATION_GROUP)[number];

export const isClassificationGroup = (x: unknown): x is ClassificationGroup => {
return (
typeof x === "string" &&
CLASSIFICATION_GROUP.includes(x as ClassificationGroup)
);
};
9 changes: 7 additions & 2 deletions apps/web/src/utils/educationUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { Locales } from "@gc-digital-talent/i18n";
import { Link } from "@gc-digital-talent/ui";
import { Radio } from "@gc-digital-talent/forms";
import { EducationRequirementOption } from "@gc-digital-talent/graphql";
import { assertUnreachable } from "@gc-digital-talent/helpers";

import applicationMessages from "~/messages/applicationMessages";
import { ClassificationGroup } from "~/types/classificationGroup";

export const foreignDegreeLink = (chunks: ReactNode, locale: Locales) => {
const href =
Expand Down Expand Up @@ -93,7 +95,7 @@ const appliedWorkListMessages = (isIAP = false) => [
export const getEducationRequirementOptions = (
intl: IntlShape,
locale: Locales,
classificationGroup?: string,
classificationGroup: ClassificationGroup,
isIAP = false,
): Radio[] => {
switch (classificationGroup) {
Expand Down Expand Up @@ -198,6 +200,7 @@ export const getEducationRequirementOptions = (
),
},
];
case "AS":
case "PM":
return [
{
Expand Down Expand Up @@ -277,7 +280,7 @@ export const getEducationRequirementOptions = (
),
},
];
default:
case "IT":
return [
{
value: EducationRequirementOption.AppliedWork,
Expand Down Expand Up @@ -349,5 +352,7 @@ export const getEducationRequirementOptions = (
),
},
];
default:
return assertUnreachable(classificationGroup); // exhaustive switch
}
};
Loading