diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1cfd83c7bee..62ee7dd05e7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -81,7 +81,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: "8.2" + php-version: "8.3" extensions: bcmath - name: Install composer dependencies diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index da8eb11cccb..39fcea2c055 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -42,7 +42,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: "8.2" + php-version: "8.3" extensions: bcmath coverage: pcov diff --git a/.github/workflows/translations.yml b/.github/workflows/translations.yml index 8d754b5fdb5..ca798b5e7b1 100644 --- a/.github/workflows/translations.yml +++ b/.github/workflows/translations.yml @@ -52,7 +52,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: "8.2" + php-version: "8.3" extensions: bcmath - name: Install composer dependencies diff --git a/.gitignore b/.gitignore index a9cad7c54fa..dc3ece736b3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ hydrogen-logs .jekyll-cache .turbo .env +hostingstart.html diff --git a/api/Dockerfile b/api/Dockerfile index 6ed2a64848b..2110f47a724 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.2.9-apache-bullseye as base +FROM php:8.3.9-apache-bullseye as base # Install pdo_pgsql extension. RUN apt-get update \ diff --git a/api/app/Generators/PoolCandidateCsvGenerator.php b/api/app/Generators/PoolCandidateCsvGenerator.php index a9eb147e1cb..214cb3abe3b 100644 --- a/api/app/Generators/PoolCandidateCsvGenerator.php +++ b/api/app/Generators/PoolCandidateCsvGenerator.php @@ -11,10 +11,12 @@ use App\Enums\CitizenshipStatus; use App\Enums\EstimatedLanguageAbility; use App\Enums\EvaluatedLanguageAbility; +use App\Enums\FinalDecision; use App\Enums\GovEmployeeType; use App\Enums\IndigenousCommunity; use App\Enums\Language; use App\Enums\OperationalRequirement; +use App\Enums\OverallAssessmentStatus; use App\Enums\PoolCandidateStatus; use App\Enums\PoolSkillType; use App\Enums\PriorityWeight; @@ -54,6 +56,8 @@ class PoolCandidateCsvGenerator extends CsvGenerator implements FileGeneratorInt protected array $RODData = []; + protected array $finalDecisions = []; + protected array $generatedHeaders = [ 'general_questions' => [], 'screening_questions' => [], @@ -274,6 +278,32 @@ public function generate(): self } } } + + $decision = null; + if (is_null($candidate->computed_final_decision) || $candidate->computed_final_decision === FinalDecision::TO_ASSESS->name) { + if (! isset($candidate->computed_assessment_status['overallAssessmentStatus'])) { + $decision = Lang::get('final_decision.to_assess', [], $this->lang); + } else { + if ($candidate->computed_assessment_status['overallAssessmentStatus'] === OverallAssessmentStatus::DISQUALIFIED->name) { + $decision = Lang::get('final_decision.disqualified_pending', [], $this->lang); + } elseif ($candidate->computed_assessment_status['currentStep'] === null) { + $decision = Lang::get('final_decision.qualified_pending', [], $this->lang); + } else { + $decision = Lang::get('final_decision.to_assess', [], $this->lang) + .$this->colon() + .Lang::get('common.step', [], $this->lang) + .' ' + .$candidate->computed_assessment_status['currentStep']; + } + } + } else { + $decision = $this->localizeEnum($candidate->computed_final_decision, FinalDecision::class); + } + + $this->finalDecisions[] = [ + 'candidate' => $currentCandidate, + 'value' => $decision, + ]; } // 1 is added to the key to account for the header row @@ -398,6 +428,7 @@ private function generatePoolHeaders() ); } } + $this->generatedHeaders['ROD_details'][] = $this->localizeHeading('final_decision'); } } }); @@ -448,6 +479,12 @@ private function generatePoolCells(Worksheet $sheet, int $columnCount) } } } + $currentColumn++; + if (isset($this->finalDecisions)) { + foreach ($this->finalDecisions as $row) { + $sheet->setCellValue([$currentColumn, $row['candidate'] + 1], $row['value']); + } + } } } diff --git a/api/app/GraphQL/Validators/UpdateUserAsUserInputValidator.php b/api/app/GraphQL/Validators/UpdateUserAsUserInputValidator.php index 42383ab0fc3..6091e3dcffc 100644 --- a/api/app/GraphQL/Validators/UpdateUserAsUserInputValidator.php +++ b/api/app/GraphQL/Validators/UpdateUserAsUserInputValidator.php @@ -45,8 +45,8 @@ public function rules(): array */ Rule::unique('users', 'email')->ignore($this->arg('id'), 'id'), Rule::unique('users', 'work_email')->ignore($this->arg('id'), 'id'), - // Note: Domains should be kept in sync with the workEmailDomainRegex - 'ends_with:gc.ca,canada.ca,elections.ca,ccc.ca,canadapost-postescanada.ca,gg.ca', + // Note: Should be kept in sync with the workEmailDomainRegex + 'regex:/@([A-Za-z0-9-]+\.)*(gc\.ca|canada\.ca|elections\.ca|ccc\.ca|canadapost-postescanada\.ca|gg\.ca)$/i', ], 'sub' => [ 'sometimes', diff --git a/api/app/Models/PoolCandidate.php b/api/app/Models/PoolCandidate.php index 0369f6fb6f7..477d46ca04b 100644 --- a/api/app/Models/PoolCandidate.php +++ b/api/app/Models/PoolCandidate.php @@ -1149,6 +1149,11 @@ public function computeFinalDecision() $status = $this->pool_candidate_status; $decision = null; + // Short circuit for a case which shouldn't really come up. A PoolCandidate should never go from non-draft back to draft, but just in case... + if ($status === PoolCandidateStatus::DRAFT->name || $status === PoolCandidateStatus::DRAFT_EXPIRED->name) { + return ['decision' => null, 'weight' => null]; + } + if (in_array($status, PoolCandidateStatus::toAssessGroup())) { $assessmentStatus = $this->computed_assessment_status; $overallStatus = null; @@ -1199,6 +1204,7 @@ public function computeFinalDecision() FinalDecision::DISQUALIFIED->name => 210, FinalDecision::QUALIFIED_REMOVED->name => 220, FinalDecision::TO_ASSESS_REMOVED->name => 230, + FinalDecision::DISQUALIFIED_REMOVED->name => 235, // I don't think this can be reached right now. FinalDecision::REMOVED->name => 240, FinalDecision::QUALIFIED_EXPIRED->name => 250, default => $this->unMatchedDecision($decision) diff --git a/api/composer.json b/api/composer.json index 6f8ebc4c040..a3dbf2da0d0 100644 --- a/api/composer.json +++ b/api/composer.json @@ -9,7 +9,7 @@ ], "license": "AGPL-3.0", "require": { - "php": "^8.2", + "php": "^8.3", "doctrine/dbal": "^3.1", "gctc-ntgc/laravel-scout-postgres-tsvector": "^1.0", "guzzlehttp/guzzle": "^7.4", @@ -62,7 +62,7 @@ "sort-packages": true, "optimize-autoloader": true, "platform": { - "php": "8.2.9" + "php": "8.3.9" }, "allow-plugins": { "composer/package-versions-deprecated": true diff --git a/api/composer.lock b/api/composer.lock index 683d2c8da17..ac080e346ad 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e5780e843af50fb14b19207b662e66f4", + "content-hash": "4a9d3132053a7edd33a435393ecdbd94", "packages": [ { "name": "amphp/amp", @@ -2971,13 +2971,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "10.x-dev" - }, "laravel": { "providers": [ "Laravel\\Scout\\ScoutServiceProvider" ] + }, + "branch-alias": { + "dev-master": "10.x-dev" } }, "autoload": { @@ -3273,16 +3273,16 @@ }, { "name": "league/commonmark", - "version": "2.5.3", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0" + "reference": "d150f911e0079e90ae3c106734c93137c184f932" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d150f911e0079e90ae3c106734c93137c184f932", + "reference": "d150f911e0079e90ae3c106734c93137c184f932", "shasum": "" }, "require": { @@ -3307,8 +3307,9 @@ "phpstan/phpstan": "^1.8.2", "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 || ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "symfony/finder": "^5.3 | ^6.0 | ^7.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", "vimeo/psalm": "^4.24.0 || ^5.0.0" }, @@ -3318,7 +3319,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.6-dev" + "dev-main": "2.7-dev" } }, "autoload": { @@ -3375,7 +3376,7 @@ "type": "tidelift" } ], - "time": "2024-08-16T11:46:16+00:00" + "time": "2024-12-07T15:34:16+00:00" }, { "name": "league/config", @@ -4732,16 +4733,16 @@ }, { "name": "nuwave/lighthouse", - "version": "v6.45.1", + "version": "v6.46.0", "source": { "type": "git", "url": "https://github.com/nuwave/lighthouse.git", - "reference": "6ed0ed1984f4e4be2be431fc355ead84310e2b43" + "reference": "104d2a271ef244a36b7de8afae519daa16f628a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nuwave/lighthouse/zipball/6ed0ed1984f4e4be2be431fc355ead84310e2b43", - "reference": "6ed0ed1984f4e4be2be431fc355ead84310e2b43", + "url": "https://api.github.com/repos/nuwave/lighthouse/zipball/104d2a271ef244a36b7de8afae519daa16f628a9", + "reference": "104d2a271ef244a36b7de8afae519daa16f628a9", "shasum": "" }, "require": { @@ -4858,7 +4859,7 @@ "type": "patreon" } ], - "time": "2024-11-27T08:12:23+00:00" + "time": "2024-12-04T11:28:10+00:00" }, { "name": "phpoffice/math", @@ -8058,8 +8059,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9415,16 +9416,16 @@ }, { "name": "webonyx/graphql-php", - "version": "v15.18.1", + "version": "v15.19.0", "source": { "type": "git", "url": "https://github.com/webonyx/graphql-php.git", - "reference": "a167afab66d8aa74b7f552759c0bbd906afb4134" + "reference": "5203bf29c8be0280e8d0925538a310202bc10f29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/a167afab66d8aa74b7f552759c0bbd906afb4134", - "reference": "a167afab66d8aa74b7f552759c0bbd906afb4134", + "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/5203bf29c8be0280e8d0925538a310202bc10f29", + "reference": "5203bf29c8be0280e8d0925538a310202bc10f29", "shasum": "" }, "require": { @@ -9437,12 +9438,12 @@ "amphp/http-server": "^2.1", "dms/phpunit-arraysubset-asserts": "dev-master", "ergebnis/composer-normalize": "^2.28", - "friendsofphp/php-cs-fixer": "3.64.0", + "friendsofphp/php-cs-fixer": "3.65.0", "mll-lab/php-cs-fixer-config": "^5.9.2", "nyholm/psr7": "^1.5", "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "1.12.10", + "phpstan/phpstan": "1.12.12", "phpstan/phpstan-phpunit": "1.4.1", "phpstan/phpstan-strict-rules": "1.6.1", "phpunit/phpunit": "^9.5 || ^10.5.21 || ^11", @@ -9477,7 +9478,7 @@ ], "support": { "issues": "https://github.com/webonyx/graphql-php/issues", - "source": "https://github.com/webonyx/graphql-php/tree/v15.18.1" + "source": "https://github.com/webonyx/graphql-php/tree/v15.19.0" }, "funding": [ { @@ -9485,7 +9486,7 @@ "type": "open_collective" } ], - "time": "2024-11-13T16:21:54+00:00" + "time": "2024-12-04T19:14:22+00:00" } ], "packages-dev": [ @@ -10238,16 +10239,16 @@ }, { "name": "phpmyadmin/sql-parser", - "version": "5.10.1", + "version": "5.10.2", "source": { "type": "git", "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17" + "reference": "72afbce7e4b421593b60d2eb7281e37a50734df8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/b14fd66496a22d8dd7f7e2791edd9e8674422f17", - "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/72afbce7e4b421593b60d2eb7281e37a50734df8", + "reference": "72afbce7e4b421593b60d2eb7281e37a50734df8", "shasum": "" }, "require": { @@ -10321,7 +10322,7 @@ "type": "other" } ], - "time": "2024-11-10T04:10:31+00:00" + "time": "2024-12-05T15:04:09+00:00" }, { "name": "phpstan/phpstan", @@ -11772,15 +11773,15 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.2" + "php": "^8.3" }, - "platform-dev": {}, + "platform-dev": [], "platform-overrides": { - "php": "8.2.9" + "php": "8.3.9" }, "plugin-api-version": "2.6.0" } diff --git a/api/lang/en/common.php b/api/lang/en/common.php index 4b094630e26..c29de0d4d66 100644 --- a/api/lang/en/common.php +++ b/api/lang/en/common.php @@ -21,4 +21,5 @@ 'not_sure' => 'Not sure', 'expected_end_date' => '(Expected end date)', 'not_found' => 'Not found', + 'step' => 'Step', ]; diff --git a/api/lang/en/headings.php b/api/lang/en/headings.php index 4b0405d3553..8048d9dfd1c 100644 --- a/api/lang/en/headings.php +++ b/api/lang/en/headings.php @@ -80,4 +80,5 @@ 'decision' => 'Decision', 'decision_details' => 'Decision details', 'decision_notes' => 'Decision notes', + 'final_decision' => 'Final decision', ]; diff --git a/api/lang/fr/common.php b/api/lang/fr/common.php index b94fa40a3a7..2aab12122e8 100644 --- a/api/lang/fr/common.php +++ b/api/lang/fr/common.php @@ -21,4 +21,5 @@ 'not_sure' => 'Pas certain', 'expected_end_date' => '(Date de fin prévue)', 'not_found' => 'Introuvable', + 'step' => 'Étape', ]; diff --git a/api/lang/fr/headings.php b/api/lang/fr/headings.php index 1243ba6c60f..6bedefc13d4 100644 --- a/api/lang/fr/headings.php +++ b/api/lang/fr/headings.php @@ -79,4 +79,5 @@ 'decision' => 'Décision', 'decision_details' => 'Détails de la décision', 'decision_notes' => 'Notes de décision', + 'final_decision' => 'Décision finale', ]; diff --git a/api/schema-directives.graphql b/api/schema-directives.graphql index 2b90b79c8cf..d0f4cff6f6a 100644 --- a/api/schema-directives.graphql +++ b/api/schema-directives.graphql @@ -685,7 +685,7 @@ directive @hide( Specify which environments must not use this field, e.g. ["production"]. """ env: [String!]! -) repeatable on FIELD_DEFINITION +) repeatable on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION | OBJECT # Directive class: Nuwave\Lighthouse\Schema\Directives\InDirective """ @@ -1083,7 +1083,7 @@ directive @show( Specify which environments may use this field, e.g. ["testing"]. """ env: [String!]! -) repeatable on FIELD_DEFINITION +) repeatable on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION | OBJECT # Directive class: Nuwave\Lighthouse\Schema\Directives\SpreadDirective """ diff --git a/apps/web/src/components/AdminContentWrapper/AdminContentWrapper.tsx b/apps/web/src/components/AdminContentWrapper/AdminContentWrapper.tsx index 14f601ae331..309751710a6 100644 --- a/apps/web/src/components/AdminContentWrapper/AdminContentWrapper.tsx +++ b/apps/web/src/components/AdminContentWrapper/AdminContentWrapper.tsx @@ -1,12 +1,25 @@ import { ReactNode } from "react"; interface AdminContentWrapperProps { + table?: boolean; children: ReactNode; } -const AdminContentWrapper = ({ children }: AdminContentWrapperProps) => ( -
-
{children}
+const AdminContentWrapper = ({ table, children }: AdminContentWrapperProps) => ( +
+ {children}
); diff --git a/apps/web/src/components/Hero/Hero.tsx b/apps/web/src/components/Hero/Hero.tsx index c7a03597027..15795e01e8a 100644 --- a/apps/web/src/components/Hero/Hero.tsx +++ b/apps/web/src/components/Hero/Hero.tsx @@ -30,7 +30,7 @@ const paddingMap = { interface NavTab { url: string; - label: string; + label: ReactNode; } interface HeroSharedProps { @@ -41,6 +41,8 @@ interface HeroSharedProps { buttonLinks?: ButtonLinkType[]; children?: ReactNode; centered?: boolean; + status?: ReactNode; + additionalContent?: ReactNode; } type HeroWithNavTabsProps = HeroSharedProps & { @@ -63,6 +65,8 @@ const Hero = (props: HeroWithNavTabsProps | HeroWithOverlapProps) => { buttonLinks, children, centered = false, + status, + additionalContent, } = props; // conditional props const navTabs = "navTabs" in props ? props.navTabs : null; @@ -217,6 +221,24 @@ const Hero = (props: HeroWithNavTabsProps | HeroWithOverlapProps) => {
) : null} +
+ {status} +
+ {additionalContent ? ( + <> +
+ {additionalContent} +
+ + ) : null} {children ? ( <> diff --git a/apps/web/src/components/HeroDeprecated/HeroDeprecated.stories.tsx b/apps/web/src/components/HeroDeprecated/HeroDeprecated.stories.tsx deleted file mode 100644 index 9db52fa4cf2..00000000000 --- a/apps/web/src/components/HeroDeprecated/HeroDeprecated.stories.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { StoryFn, Meta } from "@storybook/react"; - -import { allModes } from "@gc-digital-talent/storybook-helpers"; - -import Hero from "./HeroDeprecated"; - -export default { - component: Hero, - args: { - title: "Hero", - subtitle: "Subtitle", - crumbs: [ - { - label: "Home", - url: "#home", - }, - { - label: "One", - url: "#one", - }, - { - label: "Two", - url: "#two", - }, - { - label: "Three", - url: "#three", - }, - ], - }, - parameters: { - chromatic: { - modes: { - light: allModes.light, - "light mobile": allModes["light mobile"], - dark: allModes.dark, - "light iap": allModes["light iap desktop"], - "dark iap": allModes["dark iap desktop"], - }, - }, - }, -} as Meta; - -const Template: StoryFn = (args) => ; - -export const Default = Template.bind({}); - -export const Overlap = Template.bind({}); -Overlap.args = { - centered: true, - children: ( -
-

Replace Me

-
- ), -}; diff --git a/apps/web/src/components/HeroDeprecated/HeroDeprecated.tsx b/apps/web/src/components/HeroDeprecated/HeroDeprecated.tsx deleted file mode 100644 index e724c8398f3..00000000000 --- a/apps/web/src/components/HeroDeprecated/HeroDeprecated.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import { ReactNode, useEffect, useRef } from "react"; -import { useIntl } from "react-intl"; - -import { - Heading, - type HeadingRef, - Breadcrumbs, - type BreadcrumbsProps, - Flourish, - Crumb, -} from "@gc-digital-talent/ui"; -import { uiMessages } from "@gc-digital-talent/i18n"; - -import BackgroundGraphic from "./BackgroundPattern"; - -const paddingMap = new Map([ - [ - "default", - { - "data-h2-padding": "base(x4, 0)", - }, - ], - [ - "image", - { - "data-h2-padding": - "base(x3, 0, 50vh, 0) p-tablet(x3, 0, 60vh, 0) l-tablet(x4, 0)", - }, - ], - [ - "overlap", - { - "data-h2-padding": "base(x4, 0, x8, 0)", - }, - ], -]); - -interface HeroProps { - imgPath?: string; - title: ReactNode; - subtitle?: ReactNode; - crumbs?: BreadcrumbsProps["crumbs"]; - simpleCrumbs?: boolean; - children?: ReactNode; - centered?: boolean; - linkSlot?: ReactNode; -} - -const HeroDeprecated = ({ - imgPath, - title, - subtitle, - crumbs, - children, - linkSlot, - centered = false, - simpleCrumbs = false, -}: HeroProps) => { - const intl = useIntl(); - const headingRef = useRef(null); - const showImg = imgPath && !centered && !children; - const breadCrumbs = - crumbs && crumbs.length > 0 ? : null; - const textAlignment = centered - ? { - "data-h2-text-align": "base(center)", - } - : { - "data-h2-text-align": "base(center) l-tablet(left)", - }; - let padding = paddingMap.get("default"); - if (showImg) { - padding = paddingMap.get("image"); - } else if (children) { - padding = paddingMap.get("overlap"); - } - - useEffect(() => { - if (headingRef.current) { - headingRef.current.focus(); - } - }, []); - - return ( - <> -
-
-
-   -
-
-
-
-
-
-   -
-
-
-
- - {title} - - {subtitle && ( -

- {subtitle} -

- )} - {linkSlot && ( -
- {linkSlot} -
- )} - {simpleCrumbs && crumbs && ( - - )} -
-
- {showImg ? ( -
- ) : ( -
- {children ? ( - <> - -
- {children} -
- - ) : ( - breadCrumbs - )} - - ); -}; - -export default HeroDeprecated; diff --git a/apps/web/src/components/HeroDeprecated/index.ts b/apps/web/src/components/HeroDeprecated/index.ts deleted file mode 100644 index 8dc32a4f3c6..00000000000 --- a/apps/web/src/components/HeroDeprecated/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import Hero from "./HeroDeprecated"; - -export default Hero; diff --git a/apps/web/src/components/Layout/AdminLayout/AdminLayout.stories.tsx b/apps/web/src/components/Layout/AdminLayout/AdminLayout.stories.tsx deleted file mode 100644 index abd1cd61936..00000000000 --- a/apps/web/src/components/Layout/AdminLayout/AdminLayout.stories.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { useMemo } from "react"; -import { Meta, StoryFn } from "@storybook/react"; -import { faker } from "@faker-js/faker/locale/en"; - -import { - AuthorizationContext, - AuthenticationContext, - useAuthentication, - useAuthorization, - ROLE_NAME, - RoleName, -} from "@gc-digital-talent/auth"; -import { allModes } from "@gc-digital-talent/storybook-helpers"; - -import AdminLayout from "./AdminLayout"; - -const availableRoles = Object.values(ROLE_NAME); - -interface AdminLayoutArgs { - loggedIn: boolean; - roles: RoleName[]; -} - -export default { - component: AdminLayout, - args: { - loggedIn: true, - roles: availableRoles, - }, - argTypes: { - roles: { - control: "check", - options: availableRoles, - }, - }, - parameters: { - chromatic: { - modes: { - light: allModes.light, - }, - }, - }, -} as Meta; - -const Template: StoryFn = (args) => { - const { loggedIn, roles } = args; - const authenticationState = useAuthentication(); - const authorizationState = useAuthorization(); - - const mockAuthenticationState = useMemo( - () => ({ - ...authenticationState, - loggedIn, - }), - [loggedIn, authenticationState], - ); - const mockAuthorizationState = useMemo( - () => ({ - ...authorizationState, - roleAssignments: roles.map((roleName) => ({ - id: faker.string.uuid(), - role: { - id: faker.string.uuid(), - name: roleName, - }, - })), - }), - [roles, authorizationState], - ); - - return ( - - - - - - ); -}; - -export const LoggedIn = Template.bind({}); -LoggedIn.args = { - loggedIn: true, -}; - -export const LoggedOut = Template.bind({}); -LoggedOut.args = { - loggedIn: false, - roles: [], -}; diff --git a/apps/web/src/components/Layout/AdminLayout/AdminLayout.tsx b/apps/web/src/components/Layout/AdminLayout/AdminLayout.tsx deleted file mode 100644 index e16fcd8844f..00000000000 --- a/apps/web/src/components/Layout/AdminLayout/AdminLayout.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { useLocation } from "react-router"; -import { useIntl } from "react-intl"; - -import { useLogger } from "@gc-digital-talent/logger"; - -import useLayoutTheme from "~/hooks/useLayoutTheme"; -import useErrorMessages from "~/hooks/useErrorMessages"; - -import Layout from "../Layout"; - -export const Component = () => { - const intl = useIntl(); - useLayoutTheme("default"); - - return ( - - ); -}; - -export const ErrorBoundary = () => { - const location = useLocation(); - const error = useErrorMessages(); - const logger = useLogger(); - - logger.notice( - JSON.stringify({ - message: "ErrorPage triggered", - pathname: location.pathname, - error, - }), - ); - - return ( -
-
-
-
-

- {error.messages.title} -

- {error.messages.body} -
-
-
-
- ); -}; - -Component.displayName = "AdminLayout"; -ErrorBoundary.displayName = "AdminErrorBoundary"; - -export default Component; diff --git a/apps/web/src/components/Router.tsx b/apps/web/src/components/Router.tsx index fab735fb7af..7136dabd25b 100644 --- a/apps/web/src/components/Router.tsx +++ b/apps/web/src/components/Router.tsx @@ -532,340 +532,273 @@ const createRoute = (locale: Locales) => ], }, { - path: "*", - loader: () => { - throw new NotFoundError(); - }, - }, - ], - }, - { - path: "*", - loader: () => { - throw new NotFoundError(); - }, - }, - ], - }, - { - path: `${locale}/admin`, - lazy: () => import("./Layout/AdminLayout/AdminLayout"), - children: [ - { - async lazy() { - const { ErrorBoundary } = await import( - "./Layout/AdminLayout/AdminLayout" - ); - return { ErrorBoundary }; - }, - children: [ - { - index: true, - lazy: () => - import("../pages/AdminDashboardPage/AdminDashboardPage"), - }, - { - path: "users", + path: "admin", children: [ { index: true, lazy: () => - import("../pages/Users/IndexUserPage/IndexUserPage"), + import("../pages/AdminDashboardPage/AdminDashboardPage"), }, { - path: ":userId", - lazy: () => import("../pages/Users/UserLayout"), + path: "users", children: [ { index: true, lazy: () => - import( - "../pages/Users/UserInformationPage/UserInformationPage" - ), - }, - { - path: "profile", - lazy: () => - import( - "../pages/Users/AdminUserProfilePage/AdminUserProfilePage" - ), + import("../pages/Users/IndexUserPage/IndexUserPage"), }, { - path: "edit", - lazy: () => - import("../pages/Users/UpdateUserPage/UpdateUserPage"), + path: ":userId", + lazy: () => import("../pages/Users/UserLayout"), + children: [ + { + index: true, + lazy: () => + import( + "../pages/Users/UserInformationPage/UserInformationPage" + ), + }, + { + path: "profile", + lazy: () => + import( + "../pages/Users/AdminUserProfilePage/AdminUserProfilePage" + ), + }, + { + path: "edit", + lazy: () => + import( + "../pages/Users/UpdateUserPage/UpdateUserPage" + ), + }, + ], }, ], }, - ], - }, - { - path: "communities", - children: [ - { - index: true, - lazy: () => - import( - "../pages/Communities/IndexCommunityPage/IndexCommunityPage" - ), - }, - { - path: "create", - lazy: () => - import( - "../pages/Communities/CreateCommunityPage/CreateCommunityPage" - ), - }, { - path: ":communityId", - lazy: () => import("../pages/Communities/CommunityLayout"), + path: "communities", children: [ { index: true, lazy: () => import( - "../pages/Communities/ViewCommunityPage/ViewCommunityPage" + "../pages/Communities/IndexCommunityPage/IndexCommunityPage" ), }, { - path: "manage-access", + path: "create", lazy: () => import( - "../pages/Communities/CommunityMembersPage/CommunityMembersPage" + "../pages/Communities/CreateCommunityPage/CreateCommunityPage" ), }, { - path: "edit", + path: ":communityId", lazy: () => - import( - "../pages/Communities/UpdateCommunityPage/UpdateCommunityPage" - ), + import("../pages/Communities/CommunityLayout"), + children: [ + { + index: true, + lazy: () => + import( + "../pages/Communities/ViewCommunityPage/ViewCommunityPage" + ), + }, + { + path: "manage-access", + lazy: () => + import( + "../pages/Communities/CommunityMembersPage/CommunityMembersPage" + ), + }, + { + path: "edit", + lazy: () => + import( + "../pages/Communities/UpdateCommunityPage/UpdateCommunityPage" + ), + }, + ], }, ], }, - ], - }, - { - path: "teams", - children: [ { - index: true, - lazy: () => - import("../pages/Teams/IndexTeamPage/IndexTeamPage"), - }, - { - path: "create", - lazy: () => - import("../pages/Teams/CreateTeamPage/CreateTeamPage"), - }, - { - path: ":teamId", - lazy: () => import("../pages/Teams/TeamLayout"), + path: "teams", children: [ { index: true, lazy: () => - import("../pages/Teams/ViewTeamPage/ViewTeamPage"), + import("../pages/Teams/IndexTeamPage/IndexTeamPage"), }, { - path: "edit", + path: "create", lazy: () => - import("../pages/Teams/UpdateTeamPage/UpdateTeamPage"), + import("../pages/Teams/CreateTeamPage/CreateTeamPage"), }, { - path: "members", - lazy: () => - import( - "../pages/Teams/TeamMembersPage/TeamMembersPage" - ), + path: ":teamId", + lazy: () => import("../pages/Teams/TeamLayout"), + children: [ + { + index: true, + lazy: () => + import("../pages/Teams/ViewTeamPage/ViewTeamPage"), + }, + { + path: "edit", + lazy: () => + import( + "../pages/Teams/UpdateTeamPage/UpdateTeamPage" + ), + }, + { + path: "members", + lazy: () => + import( + "../pages/Teams/TeamMembersPage/TeamMembersPage" + ), + }, + ], }, ], }, - ], - }, - { - path: "pools", - children: [ - { - index: true, - lazy: () => - import("../pages/Pools/IndexPoolPage/IndexPoolPage"), - }, { - path: "create", - lazy: () => - import("../pages/Pools/CreatePoolPage/CreatePoolPage"), - }, - { - path: ":poolId", - lazy: () => import("../pages/Pools/PoolLayout"), + path: "pools", children: [ { index: true, lazy: () => - import("../pages/Pools/ViewPoolPage/ViewPoolPage"), + import("../pages/Pools/IndexPoolPage/IndexPoolPage"), }, { - path: "edit", + path: "create", lazy: () => - import("../pages/Pools/EditPoolPage/EditPoolPage"), + import("../pages/Pools/CreatePoolPage/CreatePoolPage"), }, { - path: "pool-candidates", + path: ":poolId", + lazy: () => import("../pages/Pools/PoolLayout"), children: [ { index: true, + lazy: () => + import("../pages/Pools/ViewPoolPage/ViewPoolPage"), + }, + { + path: "edit", + lazy: () => + import("../pages/Pools/EditPoolPage/EditPoolPage"), + }, + { + path: "pool-candidates", + children: [ + { + index: true, + lazy: () => + import( + "../pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage" + ), + }, + ], + }, + { + path: "screening", + lazy: () => + import( + "../pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage" + ), + }, + { + path: "manage-access", lazy: () => import( - "../pages/PoolCandidates/IndexPoolCandidatePage/IndexPoolCandidatePage" + "../pages/Pools/ManageAccessPage/ManageAccessPage" + ), + }, + { + path: "plan", + lazy: () => + import( + "../pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage" ), }, ], }, - { - path: "screening", - lazy: () => - import( - "../pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage" - ), - }, - { - path: "manage-access", - lazy: () => - import( - "../pages/Pools/ManageAccessPage/ManageAccessPage" - ), - }, - { - path: "plan", - lazy: () => - import( - "../pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage" - ), - }, ], }, - ], - }, - { - path: "pools/:poolId/preview", - lazy: () => - import( - "../pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage" - ), - }, - { - path: "pool-candidates", - lazy: () => - import( - "../pages/PoolCandidates/AllPoolCandidatesPage/AllPoolCandidatesPage" - ), - }, - { - path: "candidates/:poolCandidateId/application", - lazy: () => - import( - "../pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage" - ), - }, - { - path: "talent-requests", - children: [ - { - index: true, - lazy: () => - import( - "../pages/SearchRequests/IndexSearchRequestPage/IndexSearchRequestPage" - ), - }, { - path: ":searchRequestId", + path: "pools/:poolId/preview", lazy: () => import( - "../pages/SearchRequests/ViewSearchRequestPage/ViewSearchRequestPage" + "../pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage" ), }, - ], - }, - { - path: "training-opportunities", - children: [ { - index: true, + path: "pool-candidates", lazy: () => import( - "../pages/TrainingOpportunities/IndexTrainingOpportunitiesPage" + "../pages/PoolCandidates/AllPoolCandidatesPage/AllPoolCandidatesPage" ), }, { - path: "create", + path: "candidates/:poolCandidateId/application", lazy: () => import( - "../pages/TrainingOpportunities/CreateTrainingOpportunityPage" + "../pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage" ), }, { - path: ":trainingOpportunityId", + path: "talent-requests", children: [ { index: true, lazy: () => import( - "../pages/TrainingOpportunities/ViewTrainingOpportunityPage" + "../pages/SearchRequests/IndexSearchRequestPage/IndexSearchRequestPage" ), }, { - path: "edit", + path: ":searchRequestId", lazy: () => import( - "../pages/TrainingOpportunities/UpdateTrainingOpportunityPage" + "../pages/SearchRequests/ViewSearchRequestPage/ViewSearchRequestPage" ), }, ], }, - ], - }, - { - path: "settings", - children: [ - { - index: true, - loader: () => { - throw new NotFoundError(); - }, - }, { - path: "classifications", + path: "training-opportunities", children: [ { index: true, lazy: () => import( - "../pages/Classifications/IndexClassificationPage" + "../pages/TrainingOpportunities/IndexTrainingOpportunitiesPage" ), }, { path: "create", lazy: () => import( - "../pages/Classifications/CreateClassificationPage" + "../pages/TrainingOpportunities/CreateTrainingOpportunityPage" ), }, { - path: ":classificationId", + path: ":trainingOpportunityId", children: [ { index: true, lazy: () => import( - "../pages/Classifications/ViewClassificationPage" + "../pages/TrainingOpportunities/ViewTrainingOpportunityPage" ), }, { path: "edit", lazy: () => import( - "../pages/Classifications/UpdateClassificationPage" + "../pages/TrainingOpportunities/UpdateTrainingOpportunityPage" ), }, ], @@ -873,99 +806,164 @@ const createRoute = (locale: Locales) => ], }, { - path: "departments", + path: "settings", children: [ { index: true, - lazy: () => - import("../pages/Departments/IndexDepartmentPage"), - }, - { - path: "create", - lazy: () => - import("../pages/Departments/CreateDepartmentPage"), + loader: () => { + throw new NotFoundError(); + }, }, { - path: ":departmentId", + path: "classifications", children: [ { index: true, lazy: () => - import("../pages/Departments/ViewDepartmentPage"), + import( + "../pages/Classifications/IndexClassificationPage" + ), }, { - path: "edit", + path: "create", lazy: () => - import("../pages/Departments/UpdateDepartmentPage"), + import( + "../pages/Classifications/CreateClassificationPage" + ), + }, + { + path: ":classificationId", + children: [ + { + index: true, + lazy: () => + import( + "../pages/Classifications/ViewClassificationPage" + ), + }, + { + path: "edit", + lazy: () => + import( + "../pages/Classifications/UpdateClassificationPage" + ), + }, + ], }, ], }, - ], - }, - { - path: "skills", - children: [ - { - index: true, - lazy: () => import("../pages/Skills/IndexSkillPage"), - }, - { - path: "create", - lazy: () => import("../pages/Skills/CreateSkillPage"), - }, { - path: ":skillId", + path: "departments", children: [ { index: true, - lazy: () => import("../pages/Skills/ViewSkillPage"), + lazy: () => + import("../pages/Departments/IndexDepartmentPage"), }, { - path: "edit", - lazy: () => import("../pages/Skills/UpdateSkillPage"), + path: "create", + lazy: () => + import("../pages/Departments/CreateDepartmentPage"), + }, + { + path: ":departmentId", + children: [ + { + index: true, + lazy: () => + import( + "../pages/Departments/ViewDepartmentPage" + ), + }, + { + path: "edit", + lazy: () => + import( + "../pages/Departments/UpdateDepartmentPage" + ), + }, + ], }, ], }, - ], - }, - { - path: "skill-families", - children: [ - { - index: true, - lazy: () => - import("../pages/SkillFamilies/IndexSkillFamilyPage"), - }, { - path: "create", - lazy: () => - import("../pages/SkillFamilies/CreateSkillFamilyPage"), + path: "skills", + children: [ + { + index: true, + lazy: () => import("../pages/Skills/IndexSkillPage"), + }, + { + path: "create", + lazy: () => import("../pages/Skills/CreateSkillPage"), + }, + { + path: ":skillId", + children: [ + { + index: true, + lazy: () => + import("../pages/Skills/ViewSkillPage"), + }, + { + path: "edit", + lazy: () => + import("../pages/Skills/UpdateSkillPage"), + }, + ], + }, + ], }, { - path: ":skillFamilyId", + path: "skill-families", children: [ { index: true, lazy: () => import( - "../pages/SkillFamilies/ViewSkillFamilyPage" + "../pages/SkillFamilies/IndexSkillFamilyPage" ), }, { - path: "edit", + path: "create", lazy: () => import( - "../pages/SkillFamilies/UpdateSkillFamilyPage" + "../pages/SkillFamilies/CreateSkillFamilyPage" ), }, + { + path: ":skillFamilyId", + children: [ + { + index: true, + lazy: () => + import( + "../pages/SkillFamilies/ViewSkillFamilyPage" + ), + }, + { + path: "edit", + lazy: () => + import( + "../pages/SkillFamilies/UpdateSkillFamilyPage" + ), + }, + ], + }, ], }, + { + path: "announcements", + lazy: () => + import("../pages/AnnouncementsPage/AnnouncementsPage"), + }, ], }, { - path: "announcements", - lazy: () => - import("../pages/AnnouncementsPage/AnnouncementsPage"), + path: "*", + loader: () => { + throw new NotFoundError(); + }, }, ], }, @@ -977,8 +975,15 @@ const createRoute = (locale: Locales) => }, ], }, + { + path: "*", + loader: () => { + throw new NotFoundError(); + }, + }, ], }, + { path: `${locale}/indigenous-it-apprentice`, lazy: () => import("./Layout/IAPLayout"), diff --git a/apps/web/src/components/ThemeSwitcher/ThemeSwitcher.stories.tsx b/apps/web/src/components/ThemeSwitcher/ThemeSwitcher.stories.tsx index 4e187a8e526..3eecc817b55 100644 --- a/apps/web/src/components/ThemeSwitcher/ThemeSwitcher.stories.tsx +++ b/apps/web/src/components/ThemeSwitcher/ThemeSwitcher.stories.tsx @@ -1,14 +1,26 @@ -import { Meta, StoryFn } from "@storybook/react"; +import type { Meta, StoryObj } from "@storybook/react"; -import { OverlayOrDialogDecorator } from "@gc-digital-talent/storybook-helpers"; +import { + allModes, + OverlayOrDialogDecorator, +} from "@gc-digital-talent/storybook-helpers"; import ThemeSwitcher from "./ThemeSwitcher"; -export default { +const meta = { component: ThemeSwitcher, decorators: [OverlayOrDialogDecorator], -} as Meta; + parameters: { + chromatic: { + modes: { + light: allModes.light, + dark: allModes.dark, + }, + }, + }, +} satisfies Meta; +export default meta; -const Template: StoryFn = () => ; +type Story = StoryObj; -export const Default = Template.bind({}); +export const Default: Story = {}; diff --git a/apps/web/src/lang/fr.json b/apps/web/src/lang/fr.json index 09cbe7d66d0..24681bdb04d 100644 --- a/apps/web/src/lang/fr.json +++ b/apps/web/src/lang/fr.json @@ -519,6 +519,10 @@ "defaultMessage": "Candidats du bassin", "description": "Title for pool candidates" }, + "0Wx0kW": { + "defaultMessage": "Il s’agit du carrefour de l’administrateur de Talents numériques du GC. À partir d’ici, il est possible de recruter et gérer des talents, trouver des ressources et ajuster les paramètres de la plateforme.", + "description": "Subtitle for the admin dashboard page" + }, "0YZeO0": { "defaultMessage": "Embauché(e) (occasionnel)", "description": "Status for an application that has been hired with a casual contract" @@ -1887,10 +1891,6 @@ "defaultMessage": "Comment les données d’autodéclaration sont-elles utilisées?", "description": "Title for how self-declaration data is used section" }, - "7nxtBm": { - "defaultMessage": "Il s’agit du carrefour de l’administrateur de la plateforme des talents numériques du GC à partir d’où il est possible de gérer, trier et recruter le talent pour le GC.", - "description": "Subtitle for the admin dashboard page" - }, "7oq1Qa": { "defaultMessage": "Décision finale", "description": "Title displayed on the Pool Candidates table final decision column" @@ -4083,10 +4083,6 @@ "defaultMessage": "Comment vous avez pu mettre en œuvre la compétence « {skillName} » dans le cadre de cette expérience", "description": "Heading for a single skill on an experience." }, - "J8kIar": { - "defaultMessage": "Recruter et gérer des employés en TI au gouvernement du Canada.", - "description": "Meta tag description for Admin site" - }, "J9HjFN": { "defaultMessage": "Le Programme a été conçu pour répondre aux efforts de réconciliation et pour bâtir une relation renouvelée qui est fondée sur les droits, le respect, la collaboration et le partenariat avec les peuples autochtones.", "description": "How it works, step 1 content paragraph 1" @@ -5539,6 +5535,10 @@ "defaultMessage": "Identifiant de processus copié", "description": "Button text to indicate that a specific qualified recruitment's ID has been copied" }, + "QOf3kT": { + "defaultMessage": "Voici votre tableau de bord de la collectivité. Vous pouvez y recruter et gérer des talents, et trouver des ressources.", + "description": "Subtitle for the community dashboard page" + }, "QQXvOh": { "defaultMessage": "Notre engagement à l’égard de l’accessibilité", "description": "Title for the accessibility commitment section." @@ -11822,10 +11822,6 @@ "defaultMessage": "Il s’agit d’une plateforme conçue pour offrir des possibilités d’emploi aux Autochtones d’une manière qui reconnaît et met en valeur leurs talents, leurs idées, leurs compétences et leur passion uniques.", "description": "Talent portal information sentence 2" }, - "wHX/8C": { - "defaultMessage": "Admin", - "description": "Title tag for Admin site" - }, "wIccbA": { "defaultMessage": "Signaler un bogue", "description": "Support form subject field bug option label" diff --git a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx index 1ce7f438a8a..f3a89819294 100644 --- a/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx +++ b/apps/web/src/pages/AccessibilityStatementPage/AccessibilityStatementPage.tsx @@ -4,7 +4,7 @@ import { ReactNode } from "react"; import { Heading, Link, TableOfContents } from "@gc-digital-talent/ui"; import { getLocale, Locales } from "@gc-digital-talent/i18n"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import { wrapAbbr } from "~/utils/nameUtils"; diff --git a/apps/web/src/pages/AdminDashboardPage/AdminDashboard.test.tsx b/apps/web/src/pages/AdminDashboardPage/AdminDashboard.test.tsx index 1ca23f65612..41f6afbbcff 100644 --- a/apps/web/src/pages/AdminDashboardPage/AdminDashboard.test.tsx +++ b/apps/web/src/pages/AdminDashboardPage/AdminDashboard.test.tsx @@ -34,9 +34,15 @@ describe("Render dashboard page", () => { renderComponent("platform_admin"); // card sections - expect(screen.getByText(/recruitment/i)).toBeInTheDocument(); - expect(screen.getByText(/resources/i)).toBeInTheDocument(); - expect(screen.getByText(/administration/i)).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /recruitment/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /resources/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /administration/i, level: 2 }), + ).toBeInTheDocument(); // recruitment links expect( @@ -114,9 +120,15 @@ describe("Render dashboard page", () => { renderComponent("community_admin"); // card sections - expect(screen.getByText(/recruitment/i)).toBeInTheDocument(); - expect(screen.getByText(/resources/i)).toBeInTheDocument(); - expect(screen.getByText(/administration/i)).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /recruitment/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /resources/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /administration/i, level: 2 }), + ).toBeInTheDocument(); // recruitment links expect( @@ -194,9 +206,15 @@ describe("Render dashboard page", () => { renderComponent("process_operator"); // card sections - expect(screen.getByText(/recruitment/i)).toBeInTheDocument(); - expect(screen.getByText(/resources/i)).toBeInTheDocument(); - expect(screen.getByText(/administration/i)).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /recruitment/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /resources/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /administration/i, level: 2 }), + ).toBeInTheDocument(); // recruitment links expect( @@ -274,9 +292,15 @@ describe("Render dashboard page", () => { renderComponent("community_recruiter"); // card sections - expect(screen.getByText(/recruitment/i)).toBeInTheDocument(); - expect(screen.getByText(/resources/i)).toBeInTheDocument(); - expect(screen.getByText(/administration/i)).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /recruitment/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /resources/i, level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: /administration/i, level: 2 }), + ).toBeInTheDocument(); // recruitment links expect( diff --git a/apps/web/src/pages/AdminDashboardPage/AdminDashboardPage.tsx b/apps/web/src/pages/AdminDashboardPage/AdminDashboardPage.tsx index fd45e40ca1f..0adb32ed54d 100644 --- a/apps/web/src/pages/AdminDashboardPage/AdminDashboardPage.tsx +++ b/apps/web/src/pages/AdminDashboardPage/AdminDashboardPage.tsx @@ -39,17 +39,17 @@ import SEO from "~/components/SEO/SEO"; import { getFullNameHtml } from "~/utils/nameUtils"; import useRoutes from "~/hooks/useRoutes"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import adminMessages from "~/messages/adminMessages"; import permissionConstants from "~/constants/permissionConstants"; +import Hero from "~/components/Hero"; import { orderRoles } from "../Communities/CommunityMembersPage/helpers"; const subTitle = defineMessage({ defaultMessage: - "This is the administrator hub of the GC Digital Talent platform, manage, sort and recruit talent to the GoC.", - id: "7nxtBm", + "This is the administrator hub of GC Digital Talent. Here you can recruit and manage talent, find resources, and adjust platform settings.", + id: "0Wx0kW", description: "Subtitle for the admin dashboard page", }); @@ -231,7 +231,7 @@ export const DashboardPage = ({ currentUser }: DashboardPageProps) => { title={intl.formatMessage(pageTitles.dashboard)} description={intl.formatMessage(subTitle)} /> - { +export const AdminDashboardPageApi = () => { const [{ data, fetching, error }] = useQuery({ query: AdminDashboard_Query, }); @@ -382,10 +382,8 @@ export const DashboardPageApi = () => { export const Component = () => ( - + ); Component.displayName = "AdminDashboardPage"; - -export default DashboardPageApi; diff --git a/apps/web/src/pages/Applications/ApplicationLayout.tsx b/apps/web/src/pages/Applications/ApplicationLayout.tsx index 283489fd28e..b8b7dd8df5b 100644 --- a/apps/web/src/pages/Applications/ApplicationLayout.tsx +++ b/apps/web/src/pages/Applications/ApplicationLayout.tsx @@ -16,7 +16,7 @@ import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql"; import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import IapContactDialog from "~/components/Dialog/IapContactDialog"; import useRoutes from "~/hooks/useRoutes"; import useCurrentPage from "~/hooks/useCurrentPage"; diff --git a/apps/web/src/pages/Auth/RegistrationPages/EmployeeInformationPage/EmployeeInformationPage.tsx b/apps/web/src/pages/Auth/RegistrationPages/EmployeeInformationPage/EmployeeInformationPage.tsx index 067117fa418..91ff03e397b 100644 --- a/apps/web/src/pages/Auth/RegistrationPages/EmployeeInformationPage/EmployeeInformationPage.tsx +++ b/apps/web/src/pages/Auth/RegistrationPages/EmployeeInformationPage/EmployeeInformationPage.tsx @@ -36,7 +36,7 @@ import { } from "@gc-digital-talent/i18n"; import { getFromSessionStorage } from "@gc-digital-talent/storage"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import SEO from "~/components/SEO/SEO"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import useRoutes from "~/hooks/useRoutes"; @@ -524,7 +524,7 @@ export const EmployeeInformationForm = ({ title={intl.formatMessage(messages.title)} subtitle={intl.formatMessage(messages.subtitle)} crumbs={crumbs} - simpleCrumbs + overlap >
{ title={intl.formatMessage(messages.title)} subtitle={intl.formatMessage(messages.subtitle)} crumbs={crumbs} - simpleCrumbs + overlap >
{ title={intl.formatMessage(messages.title)} subtitle={intl.formatMessage(messages.subtitle)} crumbs={crumbs} - simpleCrumbs + overlap >
{ <> -
+ -
+ ); }; diff --git a/apps/web/src/pages/Communities/IndexCommunityPage/IndexCommunityPage.tsx b/apps/web/src/pages/Communities/IndexCommunityPage/IndexCommunityPage.tsx index 1284f235051..74526d8a589 100644 --- a/apps/web/src/pages/Communities/IndexCommunityPage/IndexCommunityPage.tsx +++ b/apps/web/src/pages/Communities/IndexCommunityPage/IndexCommunityPage.tsx @@ -8,6 +8,7 @@ import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; import Hero from "~/components/Hero"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import CommunityTableApi from "./components/CommunityTable/CommunityTable"; @@ -29,11 +30,9 @@ const IndexCommunityPage = () => { <> -
-
- -
-
+ + + ); }; diff --git a/apps/web/src/pages/CommunityDashboardPage/CommunityDashboardPage.tsx b/apps/web/src/pages/CommunityDashboardPage/CommunityDashboardPage.tsx index 1c64778f7a7..4a2af8e9484 100644 --- a/apps/web/src/pages/CommunityDashboardPage/CommunityDashboardPage.tsx +++ b/apps/web/src/pages/CommunityDashboardPage/CommunityDashboardPage.tsx @@ -1,8 +1,384 @@ -import { ROLE_NAME } from "@gc-digital-talent/auth"; +import { defineMessage, IntlShape, useIntl } from "react-intl"; +import { useQuery } from "urql"; +import RocketLaunchIcon from "@heroicons/react/24/outline/RocketLaunchIcon"; +import BookOpenIcon from "@heroicons/react/24/outline/BookOpenIcon"; +import ComputerDesktopIcon from "@heroicons/react/24/outline/ComputerDesktopIcon"; +import CogIcon from "@heroicons/react/24/outline/CogIcon"; +import uniqBy from "lodash/uniqBy"; +import { + CardBasic, + Chip, + Chips, + Heading, + Link, + Pending, +} from "@gc-digital-talent/ui"; +import { + useAuthorization, + hasRole, + ROLE_NAME, + RoleName, +} from "@gc-digital-talent/auth"; +import { + Maybe, + Role, + RoleAssignment, + User, + graphql, +} from "@gc-digital-talent/graphql"; +import { + commonMessages, + getLocalizedName, + navigationMessages, +} from "@gc-digital-talent/i18n"; +import { unpackMaybes } from "@gc-digital-talent/helpers"; + +import pageTitles from "~/messages/pageTitles"; +import SEO from "~/components/SEO/SEO"; +import { getFullNameHtml } from "~/utils/nameUtils"; +import useRoutes from "~/hooks/useRoutes"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; +import AdminHero from "~/components/HeroDeprecated/AdminHero"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; +import adminMessages from "~/messages/adminMessages"; +import permissionConstants from "~/constants/permissionConstants"; + +import { orderRoles } from "../Communities/CommunityMembersPage/helpers"; + +const subTitle = defineMessage({ + defaultMessage: + "This is your community dashboard where you can recruit and manage talent, and find resources.", + id: "QOf3kT", + description: "Subtitle for the community dashboard page", +}); + +interface RoleChipsProps { + roles: Role[]; + intl: IntlShape; +} + +// short-circuit hasRole if no roles were required so an empty array +const hasRolesHandleNoRolesRequired = ( + checkRole: RoleName | RoleName[], + userRoles: Maybe<(Maybe | undefined)[]> | undefined, +): boolean => { + if (Array.isArray(checkRole) && checkRole.length === 0) { + return true; + } + return hasRole(checkRole, userRoles); +}; + +const RoleChips = ({ roles, intl }: RoleChipsProps) => { + const uniqueRoles = uniqBy(roles, "name"); + const roleChips = uniqueRoles + ? orderRoles(uniqueRoles, intl).map((role) => ( + + {getLocalizedName(role.displayName, intl)} + + )) + : null; + + return roleChips ? {roleChips} : null; +}; + +export interface DashboardPageProps { + currentUser?: User | null; +} + +export const DashboardPage = ({ currentUser }: DashboardPageProps) => { + const intl = useIntl(); + const adminRoutes = useRoutes(); + const { roleAssignments } = useAuthorization(); -import { DashboardPageApi } from "../AdminDashboardPage/AdminDashboardPage"; + interface CardLinkInfo { + label: string; + href: string; + roles: RoleName[]; + } + + // recruitment section + const recruitmentCollection: CardLinkInfo[] = [ + { + label: intl.formatMessage(navigationMessages.candidates), + href: adminRoutes.poolCandidates(), + roles: permissionConstants.viewCandidates, + }, + { + label: intl.formatMessage(navigationMessages.processes), + href: adminRoutes.poolTable(), + roles: permissionConstants.viewProcesses, + }, + { + label: intl.formatMessage(pageTitles.talentRequests), + href: adminRoutes.searchRequestTable(), + roles: permissionConstants.viewRequests, + }, + ]; + const recruitmentCollectionFiltered = recruitmentCollection.filter((item) => + hasRolesHandleNoRolesRequired(item.roles, roleAssignments), + ); + const recruitmentCollectionSorted = recruitmentCollectionFiltered.sort( + (a, b) => { + const aName = a.label; + const bName = b.label; + return aName.localeCompare(bName); + }, + ); + + // resources section + const resourcesCollection: CardLinkInfo[] = [ + { + label: intl.formatMessage(navigationMessages.skillsLibrary), + href: adminRoutes.skills(), + roles: [], + }, + { + label: intl.formatMessage({ + defaultMessage: "Job templates library", + id: "MySfL/", + description: "Label for link to job templates library", + }), + href: adminRoutes.jobPosterTemplates(), + roles: [], + }, + ]; + const resourcesCollectionFiltered = resourcesCollection.filter((item) => + hasRolesHandleNoRolesRequired(item.roles, roleAssignments), + ); + const resourcesCollectionSorted = resourcesCollectionFiltered.sort((a, b) => { + const aName = a.label; + const bName = b.label; + return aName.localeCompare(bName); + }); + + // administration section + const administrationCollection: CardLinkInfo[] = [ + { + label: intl.formatMessage(pageTitles.announcements), + href: adminRoutes.announcements(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(adminMessages.classifications), + href: adminRoutes.classificationTable(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(adminMessages.departments), + href: adminRoutes.departmentTable(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(navigationMessages.skills), + href: adminRoutes.skillTable(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(adminMessages.skillFamilies), + href: adminRoutes.skillFamilyTable(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(pageTitles.teams), + href: adminRoutes.teamTable(), + roles: [ + ROLE_NAME.PoolOperator, + ROLE_NAME.CommunityManager, + ROLE_NAME.PlatformAdmin, + ], + }, + { + label: intl.formatMessage(pageTitles.trainingOpportunities), + href: adminRoutes.trainingOpportunitiesIndex(), + roles: [ROLE_NAME.PlatformAdmin], + }, + { + label: intl.formatMessage(navigationMessages.users), + href: adminRoutes.userTable(), + roles: permissionConstants.viewUsers, + }, + { + label: intl.formatMessage(pageTitles.communities), + href: adminRoutes.communityTable(), + roles: [ + ROLE_NAME.CommunityAdmin, + ROLE_NAME.CommunityRecruiter, + ROLE_NAME.PlatformAdmin, + ], + }, + ]; + const administrationCollectionFiltered = administrationCollection.filter( + (item) => hasRolesHandleNoRolesRequired(item.roles, roleAssignments), + ); + const administrationCollectionSorted = administrationCollectionFiltered.sort( + (a, b) => { + const aName = a.label; + const bName = b.label; + return aName.localeCompare(bName); + }, + ); + + // own roles, filtered + const ownRoles = unpackMaybes(roleAssignments) + .map((roleAssign) => roleAssign.role) + .filter((role) => !!role) + .filter((role) => !["guest", "base_user", "applicant"].includes(role.name)); + + return ( + <> + + + +
+ {recruitmentCollectionSorted.length > 0 && ( +
+ + {intl.formatMessage({ + defaultMessage: "Recruitment", + id: "UNEVD9", + description: "Header for section called recruitment", + })} + + +
    + {recruitmentCollectionSorted.map((item) => ( +
  • + + {item.label} + +
  • + ))} +
+
+
+ )} +
+ + {intl.formatMessage({ + defaultMessage: "Resources", + id: "nGSUzp", + description: "Card title for a 'resources' card", + })} + + +
    + {resourcesCollectionSorted.map((item) => ( +
  • + + {item.label} + +
  • + ))} +
+
+
+ {administrationCollectionSorted.length > 0 && ( +
+ + {intl.formatMessage({ + defaultMessage: "Administration", + id: "CdJQ7z", + description: "Header for section called administration", + })} + + +
    + {administrationCollectionSorted.map((item) => ( +
  • + + {item.label} + +
  • + ))} +
+
+
+ )} +
+
+ + {intl.formatMessage({ + defaultMessage: "Your roles", + id: "IJlJF1", + description: + "Header for section displaying logged in user's roles", + })} + + +
+
+ + ); +}; + +const CommunityDashboard_Query = graphql(/* GraphQL */ ` + query CommunityDashboard_Query { + me { + id + firstName + lastName + } + } +`); + +export const CommunityDashboardPageApi = () => { + const [{ data, fetching, error }] = useQuery({ + query: CommunityDashboard_Query, + }); + + return ( + + + + ); +}; export const Component = () => ( ( ROLE_NAME.ProcessOperator, ]} > - + ); Component.displayName = "CommunityDashboardPage"; - -export default DashboardPageApi; diff --git a/apps/web/src/pages/Departments/IndexDepartmentPage.tsx b/apps/web/src/pages/Departments/IndexDepartmentPage.tsx index ac29d426d89..157a62749a9 100644 --- a/apps/web/src/pages/Departments/IndexDepartmentPage.tsx +++ b/apps/web/src/pages/Departments/IndexDepartmentPage.tsx @@ -8,6 +8,7 @@ import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; import Hero from "~/components/Hero"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import DepartmentTableApi from "./components/DepartmentTable"; @@ -29,11 +30,9 @@ export const DepartmentPage = () => { <> -
-
- -
-
+ + + ); }; diff --git a/apps/web/src/pages/DirectiveForms/DigitalServicesContractingQuestionnaire/DigitalServicesContractingQuestionnairePage.tsx b/apps/web/src/pages/DirectiveForms/DigitalServicesContractingQuestionnaire/DigitalServicesContractingQuestionnairePage.tsx index 463f4ee0ef7..e7fef8d0d02 100644 --- a/apps/web/src/pages/DirectiveForms/DigitalServicesContractingQuestionnaire/DigitalServicesContractingQuestionnairePage.tsx +++ b/apps/web/src/pages/DirectiveForms/DigitalServicesContractingQuestionnaire/DigitalServicesContractingQuestionnairePage.tsx @@ -17,7 +17,7 @@ import { ROLE_NAME } from "@gc-digital-talent/auth"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import { pageTitle as directiveHomePageTitle } from "../../DirectivePage/DirectivePage"; diff --git a/apps/web/src/pages/DirectivePage/DirectivePage.tsx b/apps/web/src/pages/DirectivePage/DirectivePage.tsx index a1795658d40..ec3a34b866d 100644 --- a/apps/web/src/pages/DirectivePage/DirectivePage.tsx +++ b/apps/web/src/pages/DirectivePage/DirectivePage.tsx @@ -22,7 +22,7 @@ import { getLocale, } from "@gc-digital-talent/i18n"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import SEO from "~/components/SEO/SEO"; @@ -119,26 +119,20 @@ export const Component = () => { title={intl.formatMessage(pageTitle)} subtitle={intl.formatMessage(pageSubtitle)} crumbs={crumbs} - linkSlot={ - <> - - {readDirectiveMessage} - - - {intl.formatMessage(navigationMessages.findTalent)} - - - } + buttonLinks={[ + { + icon: NewspaperIcon, + text: readDirectiveMessage, + url: directiveUrl, + color: "quaternary", + }, + { + icon: MagnifyingGlassCircleIcon, + text: intl.formatMessage(navigationMessages.findTalent), + url: paths.search(), + color: "secondary", + }, + ]} />
{ const intl = useIntl(); @@ -37,11 +37,8 @@ export const AllPoolCandidatesPage = () => { return ( <> - - + + { poolId: Scalars["ID"]["output"]; @@ -53,7 +53,7 @@ export const IndexPoolCandidatePage = () => { const currentPool = data?.pool ?? null; return ( - + <> { })} description={formattedSubTitle} /> - -

{formattedSubTitle}

- -
-
+ + +

{formattedSubTitle}

+ +
+
+ ); }; diff --git a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx index 5a605eb441c..c0077a929b7 100644 --- a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx +++ b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/ViewPoolCandidatePage.tsx @@ -27,7 +27,6 @@ import useRoutes from "~/hooks/useRoutes"; import useRequiredParams from "~/hooks/useRequiredParams"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import PoolStatusTable from "~/components/PoolStatusTable/PoolStatusTable"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import { getCandidateStatusChip } from "~/utils/poolCandidate"; import { getFullPoolTitleLabel } from "~/utils/poolUtils"; import { getFullNameLabel } from "~/utils/nameUtils"; @@ -38,6 +37,7 @@ import RequireAuth from "~/components/RequireAuth/RequireAuth"; import ErrorBoundary from "~/components/ErrorBoundary/ErrorBoundary"; import pageTitles from "~/messages/pageTitles"; import { JobPlacementOptionsFragmentType } from "~/components/PoolCandidatesTable/JobPlacementDialog"; +import Hero from "~/components/Hero"; import CareerTimelineSection from "./components/CareerTimelineSection/CareerTimelineSection"; import ApplicationInformation from "./components/ApplicationInformation/ApplicationInformation"; @@ -188,10 +188,10 @@ export const ViewPoolCandidate = ({ return ( <> - } - > - - - + additionalContent={} + /> + - + {intl.formatMessage({ defaultMessage: "More actions", id: "QaMkP7", @@ -291,7 +290,7 @@ export const ViewPoolCandidate = ({ {intl.formatMessage(screeningAndAssessmentTitle)} diff --git a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ProfileDetails/ProfileDetails.tsx b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ProfileDetails/ProfileDetails.tsx index cda1fed8e99..1dcf3b29b67 100644 --- a/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ProfileDetails/ProfileDetails.tsx +++ b/apps/web/src/pages/PoolCandidates/ViewPoolCandidatePage/components/ProfileDetails/ProfileDetails.tsx @@ -59,7 +59,7 @@ const ProfileDetails = ({ userQuery }: ProfileDetailsProps) => { data-h2-gap="base(0, x.5)" data-h2-color="base(black)" data-h2-background="base(linear-gradient(92deg, rgba(175, 103, 255, 0.10) 1.42%, rgba(0, 195, 183, 0.10) 98.58%))" - data-h2-margin="base(x1, 0)" + data-h2-margin-top="base(x1)" >

diff --git a/apps/web/src/pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage.tsx b/apps/web/src/pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage.tsx index d664d67bff5..70ae13ac3db 100644 --- a/apps/web/src/pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage.tsx +++ b/apps/web/src/pages/Pools/AssessmentPlanBuilderPage/AssessmentPlanBuilderPage.tsx @@ -97,43 +97,37 @@ export const AssessmentPlanBuilder = ({ }); return ( - <> - - - - - - - {intl.formatMessage(organizeSectionTitle)} - - - - - {intl.formatMessage(skillSummarySectionTitle)} - - - - - {intl.formatMessage({ - defaultMessage: "Back to process details", - id: "nPPUMW", - description: "Link text to go back to the process details page", - })} - - + + + + + + {intl.formatMessage(organizeSectionTitle)} + + + + + {intl.formatMessage(skillSummarySectionTitle)} + + + + + {intl.formatMessage({ + defaultMessage: "Back to process details", + id: "nPPUMW", + description: "Link text to go back to the process details page", + })} + + - - - - - - - + + + + + + ); }; @@ -239,14 +233,20 @@ export const AssessmentPlanBuilderPage = () => { }; return ( - - - {content()} - - + <> + + + + {content()} + + + ); }; diff --git a/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx b/apps/web/src/pages/Pools/BrowsePoolsPage/BrowsePoolsPage.tsx index 21dd5907035..6b2037d6bf6 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 { unpackMaybes } from "@gc-digital-talent/helpers"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import { wrapAbbr } from "~/utils/nameUtils"; diff --git a/apps/web/src/pages/Pools/CreatePoolPage/CreatePoolPage.tsx b/apps/web/src/pages/Pools/CreatePoolPage/CreatePoolPage.tsx index 4aa59b400b5..2d94b63c5f5 100644 --- a/apps/web/src/pages/Pools/CreatePoolPage/CreatePoolPage.tsx +++ b/apps/web/src/pages/Pools/CreatePoolPage/CreatePoolPage.tsx @@ -26,12 +26,12 @@ import { import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import SEO from "~/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; import messages from "~/messages/adminMessages"; import permissionConstants from "~/constants/permissionConstants"; +import Hero from "~/components/Hero"; const CreatePoolClassification_Fragment = graphql(/* GraphQL */ ` fragment CreatePoolClassification on Classification { @@ -395,10 +395,10 @@ const CreatePoolPage = () => { return ( <> - diff --git a/apps/web/src/pages/Pools/IndexPoolPage/IndexPoolPage.tsx b/apps/web/src/pages/Pools/IndexPoolPage/IndexPoolPage.tsx index c12d80dd554..f6459c582e6 100644 --- a/apps/web/src/pages/Pools/IndexPoolPage/IndexPoolPage.tsx +++ b/apps/web/src/pages/Pools/IndexPoolPage/IndexPoolPage.tsx @@ -5,10 +5,10 @@ import { ROLE_NAME } from "@gc-digital-talent/auth"; import useRoutes from "~/hooks/useRoutes"; import SEO from "~/components/SEO/SEO"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; +import Hero from "~/components/Hero"; import PoolTableApi from "./components/PoolTable"; @@ -30,11 +30,8 @@ export const PoolPage = () => { return ( <> - - + + diff --git a/apps/web/src/pages/Pools/ManageAccessPage/ManageAccessPage.tsx b/apps/web/src/pages/Pools/ManageAccessPage/ManageAccessPage.tsx index e296d38e23e..27f93fa7a38 100644 --- a/apps/web/src/pages/Pools/ManageAccessPage/ManageAccessPage.tsx +++ b/apps/web/src/pages/Pools/ManageAccessPage/ManageAccessPage.tsx @@ -1,6 +1,6 @@ import { useMemo } from "react"; import { ColumnDef, createColumnHelper } from "@tanstack/react-table"; -import { useIntl } from "react-intl"; +import { defineMessage, useIntl } from "react-intl"; import { useQuery } from "urql"; import { Pending, ThrowNotFound } from "@gc-digital-talent/ui"; @@ -28,6 +28,12 @@ import { ManageAccessPageFragment, PoolTeamMember } from "./components/types"; import { ManageAccessPage_PoolFragment } from "./components/operations"; import AddPoolMembershipDialog from "./components/AddPoolMembershipDialog"; +const pageTitle = defineMessage({ + defaultMessage: "Process members", + id: "wYohzF", + description: "Page title for the manage process members page", +}); + const columnHelper = createColumnHelper(); interface ManageAccessPoolProps { @@ -50,12 +56,6 @@ const ManageAccessPool = ({ poolQuery }: ManageAccessPoolProps) => { [pool.roleAssignments], ); - const pageTitle = intl.formatMessage({ - defaultMessage: "Process members", - id: "wYohzF", - description: "Page title for the manage process members page", - }); - let columns = [ columnHelper.accessor( (member) => getFullNameLabel(member.firstName, member.lastName, intl), @@ -105,9 +105,8 @@ const ManageAccessPool = ({ poolQuery }: ManageAccessPoolProps) => { return ( <> - { } const ManageAccessPoolPage = () => { + const intl = useIntl(); const { poolId } = useRequiredParams("poolId"); const [{ data, fetching, error }] = useQuery({ query: ManageAccessPage_PoolQuery, @@ -168,11 +168,14 @@ const ManageAccessPoolPage = () => { const pool = data?.pool; return ( - - - {pool ? : } - - + <> + + + + {pool ? : } + + + ); }; diff --git a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx index ed305554e2c..b38941eed9e 100644 --- a/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx +++ b/apps/web/src/pages/Pools/PoolAdvertisementPage/PoolAdvertisementPage.tsx @@ -54,7 +54,7 @@ import { isAdvertisementVisible, } from "~/utils/poolUtils"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import EducationRequirements from "~/components/EducationRequirements/EducationRequirements"; diff --git a/apps/web/src/pages/Pools/PoolLayout.tsx b/apps/web/src/pages/Pools/PoolLayout.tsx index c025881f40c..0e1b703f531 100644 --- a/apps/web/src/pages/Pools/PoolLayout.tsx +++ b/apps/web/src/pages/Pools/PoolLayout.tsx @@ -29,10 +29,10 @@ import { } from "~/utils/poolUtils"; import { PageNavKeys } from "~/types/pool"; import useRequiredParams from "~/hooks/useRequiredParams"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import { PageNavInfo } from "~/types/pages"; import { getAssessmentPlanStatus } from "~/validators/pool/assessmentPlan"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; +import Hero from "~/components/Hero"; export const PoolLayout_Fragment = graphql(/* GraphQL */ ` fragment PoolLayout on Pool { @@ -153,28 +153,22 @@ const PoolHeader = ({ poolQuery }: PoolHeaderProps) => { return ( <> - !page.crumbs) - .map((page) => ({ - label: page.link.label ?? page.title, - url: page.link.url, - })), - } + crumbs={currentPage?.crumbs ?? undefined} + navTabs={ + !currentPage?.crumbs + ? Array.from(pages.values()) + .filter((page) => !page.crumbs) + .map((page) => ({ + label: page.link.label ?? page.title, + url: page.link.url, + })) + : undefined } - contentRight={ - (currentPage?.link.url.includes("edit") ?? + status={ + (currentPage?.link.url.includes("edit") || currentPage?.link.url.includes("plan")) && badge.label && ( diff --git a/apps/web/src/pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage.tsx b/apps/web/src/pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage.tsx index ddce3dc20e1..4f2730fd466 100644 --- a/apps/web/src/pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage.tsx +++ b/apps/web/src/pages/Pools/ScreeningAndEvaluationPage/ScreeningAndEvaluationPage.tsx @@ -161,7 +161,7 @@ const ScreeningAndEvaluationPage = () => { }, [lastPage]); return ( - + {data?.pool ? (
- + {pageTitle}

diff --git a/apps/web/src/pages/PrivacyPolicy/PrivacyPolicy.tsx b/apps/web/src/pages/PrivacyPolicy/PrivacyPolicy.tsx index 86cb9ccdb6a..3d8fbf54341 100644 --- a/apps/web/src/pages/PrivacyPolicy/PrivacyPolicy.tsx +++ b/apps/web/src/pages/PrivacyPolicy/PrivacyPolicy.tsx @@ -4,7 +4,7 @@ import { ReactNode } from "react"; import { Flourish, Heading, Link } from "@gc-digital-talent/ui"; import { Locales, getLocale } from "@gc-digital-talent/i18n"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; diff --git a/apps/web/src/pages/Profile/AccountSettings/AccountSettingsPage.tsx b/apps/web/src/pages/Profile/AccountSettings/AccountSettingsPage.tsx index 9d18d8e6403..750998227d1 100644 --- a/apps/web/src/pages/Profile/AccountSettings/AccountSettingsPage.tsx +++ b/apps/web/src/pages/Profile/AccountSettings/AccountSettingsPage.tsx @@ -16,7 +16,7 @@ import { unpackMaybes } from "@gc-digital-talent/helpers"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import profileMessages from "~/messages/profileMessages"; import AccountManagement from "./AccountManagement"; diff --git a/apps/web/src/pages/Profile/CareerTimelineAndRecruitmentPage/components/CareerTimelineAndRecruitment.tsx b/apps/web/src/pages/Profile/CareerTimelineAndRecruitmentPage/components/CareerTimelineAndRecruitment.tsx index 3cb91add605..9495986d869 100644 --- a/apps/web/src/pages/Profile/CareerTimelineAndRecruitmentPage/components/CareerTimelineAndRecruitment.tsx +++ b/apps/web/src/pages/Profile/CareerTimelineAndRecruitmentPage/components/CareerTimelineAndRecruitment.tsx @@ -16,7 +16,7 @@ import { } from "@gc-digital-talent/graphql"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import { PAGE_SECTION_ID, titles } from "~/constants/sections/careerTimeline"; diff --git a/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx b/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx index de792e4ea64..1001bbbbb9a 100644 --- a/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx +++ b/apps/web/src/pages/Profile/ExperienceFormPage/ExperienceFormPage.tsx @@ -42,7 +42,7 @@ import type { ExperienceMutationResponse, } from "~/types/experience"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import ErrorSummary from "~/components/ExperienceFormFields/ErrorSummary"; import ExperienceDetails from "~/components/ExperienceFormFields/ExperienceDetails"; import AdditionalDetails from "~/components/ExperienceFormFields/AdditionalDetails"; @@ -297,7 +297,7 @@ export interface ExperienceFormProps { edit?: boolean; experienceQuery?: FragmentType; experienceId?: string; - experienceType: ExperienceType; + experienceType?: ExperienceType; skillsQuery: FragmentType[]; userId: string; } @@ -321,7 +321,7 @@ export const ExperienceForm = ({ const skills = getFragment(ExperienceFormSkill_Fragment, skillsQuery); const defaultValues = - experienceId && experience + experienceId && experience && experienceType ? queryResultToDefaultValues(experienceType, experience) : { experienceType }; @@ -759,7 +759,7 @@ const ExperienceFormContainer = ({ edit }: ExperienceFormContainerProps) => { edit={edit} experienceQuery={experience} experienceId={experienceId} - experienceType={experienceType ?? "personal"} + experienceType={experienceType} skillsQuery={skills} userId={userAuthInfo?.id ?? ""} /> diff --git a/apps/web/src/pages/Profile/ProfilePage/ProfilePage.tsx b/apps/web/src/pages/Profile/ProfilePage/ProfilePage.tsx index 256ff7fac3e..355faf7c4bc 100644 --- a/apps/web/src/pages/Profile/ProfilePage/ProfilePage.tsx +++ b/apps/web/src/pages/Profile/ProfilePage/ProfilePage.tsx @@ -6,7 +6,7 @@ import { navigationMessages } from "@gc-digital-talent/i18n"; import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql"; import { ROLE_NAME } from "@gc-digital-talent/auth"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import useRoutes from "~/hooks/useRoutes"; import profileMessages from "~/messages/profileMessages"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; diff --git a/apps/web/src/pages/ProfileAndApplicationsPage/components/ProfileAndApplicationsHeading.tsx b/apps/web/src/pages/ProfileAndApplicationsPage/components/ProfileAndApplicationsHeading.tsx index 4ff6f68d9a0..f5c66cf17c1 100644 --- a/apps/web/src/pages/ProfileAndApplicationsPage/components/ProfileAndApplicationsHeading.tsx +++ b/apps/web/src/pages/ProfileAndApplicationsPage/components/ProfileAndApplicationsHeading.tsx @@ -21,7 +21,7 @@ import { import { navigationMessages } from "@gc-digital-talent/i18n"; import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import useRoutes, { FromIapDraftQueryKey, FromIapSuccessQueryKey, @@ -245,7 +245,6 @@ const DashboardHeading = ({ userQuery }: DashboardHeadingProps) => { return ( { ), }, )} + overlap + centered > {searchParams.get(FromIapDraftQueryKey) === "true" && ( { const intl = useIntl(); @@ -29,11 +29,8 @@ export const IndexSearchRequestPage = () => { return ( <> - - + + diff --git a/apps/web/src/pages/SearchRequests/RequestConfirmationPage/RequestConfirmationPage.tsx b/apps/web/src/pages/SearchRequests/RequestConfirmationPage/RequestConfirmationPage.tsx index 047cb9b6de4..bf739fbc6f9 100644 --- a/apps/web/src/pages/SearchRequests/RequestConfirmationPage/RequestConfirmationPage.tsx +++ b/apps/web/src/pages/SearchRequests/RequestConfirmationPage/RequestConfirmationPage.tsx @@ -11,7 +11,7 @@ import { } from "@gc-digital-talent/ui"; import { Scalars } from "@gc-digital-talent/graphql"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import SEO from "~/components/SEO/SEO"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; diff --git a/apps/web/src/pages/SearchRequests/RequestPage/RequestPage.tsx b/apps/web/src/pages/SearchRequests/RequestPage/RequestPage.tsx index dd7f2ffb6ff..0bfd35ccb5b 100644 --- a/apps/web/src/pages/SearchRequests/RequestPage/RequestPage.tsx +++ b/apps/web/src/pages/SearchRequests/RequestPage/RequestPage.tsx @@ -6,7 +6,7 @@ import { Classification, } from "@gc-digital-talent/graphql"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import { FormValues as SearchFormValues } from "~/types/searchRequest"; import CreateRequest from "./components/RequestForm"; @@ -31,7 +31,6 @@ export const Component = () => { return (

{ description: "Subtitle displayed on hero for Search and Request pages.", })} + centered + overlap >
- + {intl.formatMessage({ defaultMessage: "Manager Information", id: "UEsexn", @@ -476,10 +476,10 @@ export const ViewSearchRequest = ({ return ( <> - {wasEmpty && ( diff --git a/apps/web/src/pages/SkillFamilies/IndexSkillFamilyPage.tsx b/apps/web/src/pages/SkillFamilies/IndexSkillFamilyPage.tsx index ff53d170cfd..bd96c917273 100644 --- a/apps/web/src/pages/SkillFamilies/IndexSkillFamilyPage.tsx +++ b/apps/web/src/pages/SkillFamilies/IndexSkillFamilyPage.tsx @@ -8,6 +8,7 @@ import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; import Hero from "~/components/Hero"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import SkillFamilyTableApi from "./components/SkillFamilyTable"; @@ -30,11 +31,9 @@ const IndexSkillFamilyPage = () => { <> -
-
- -
-
+ + + ); }; diff --git a/apps/web/src/pages/Skills/IndexSkillPage.tsx b/apps/web/src/pages/Skills/IndexSkillPage.tsx index 0e98aec2c8d..6d6703f9942 100644 --- a/apps/web/src/pages/Skills/IndexSkillPage.tsx +++ b/apps/web/src/pages/Skills/IndexSkillPage.tsx @@ -8,6 +8,7 @@ import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; import Hero from "~/components/Hero"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import SkillTableApi from "./components/SkillTable"; @@ -30,11 +31,9 @@ export const IndexSkillPage = () => { <> -
-
- -
-
+ + + ); }; diff --git a/apps/web/src/pages/Skills/SkillPage.tsx b/apps/web/src/pages/Skills/SkillPage.tsx index 328c4691fd5..0c6b5a611f4 100644 --- a/apps/web/src/pages/Skills/SkillPage.tsx +++ b/apps/web/src/pages/Skills/SkillPage.tsx @@ -6,7 +6,7 @@ import { navigationMessages } from "@gc-digital-talent/i18n"; import SEO from "~/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import { INITIAL_STATE } from "~/components/Table/ResponsiveTable/constants"; import skillBrowserMessages from "~/components/SkillBrowser/messages"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; diff --git a/apps/web/src/pages/Skills/SkillPortfolioPage.tsx b/apps/web/src/pages/Skills/SkillPortfolioPage.tsx index 724da2b57c0..c0bd4faacfe 100644 --- a/apps/web/src/pages/Skills/SkillPortfolioPage.tsx +++ b/apps/web/src/pages/Skills/SkillPortfolioPage.tsx @@ -10,7 +10,7 @@ import { FragmentType, graphql } from "@gc-digital-talent/graphql"; import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; diff --git a/apps/web/src/pages/Skills/SkillShowcasePage.tsx b/apps/web/src/pages/Skills/SkillShowcasePage.tsx index ce04199eb70..3b57c9a0aad 100644 --- a/apps/web/src/pages/Skills/SkillShowcasePage.tsx +++ b/apps/web/src/pages/Skills/SkillShowcasePage.tsx @@ -16,7 +16,7 @@ import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql"; import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import SkillRankCard from "~/components/SkillRankCard/SkillRankCard"; import useRoutes from "~/hooks/useRoutes"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; diff --git a/apps/web/src/pages/Skills/UpdateUserSkillPage.tsx b/apps/web/src/pages/Skills/UpdateUserSkillPage.tsx index 742b3f98c9d..ed1badd079f 100644 --- a/apps/web/src/pages/Skills/UpdateUserSkillPage.tsx +++ b/apps/web/src/pages/Skills/UpdateUserSkillPage.tsx @@ -35,7 +35,7 @@ import { import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import UserSkillFormFields from "~/components/UserSkillFormFields/UserSkillFormFields"; import ExperienceCard from "~/components/ExperienceCard/ExperienceCard"; import ExperienceSkillFormDialog from "~/components/ExperienceSkillFormDialog/ExperienceSkillFormDialog"; diff --git a/apps/web/src/pages/Skills/components/UpdateSkillShowcase.tsx b/apps/web/src/pages/Skills/components/UpdateSkillShowcase.tsx index a9a6036fb26..6516bd394b3 100644 --- a/apps/web/src/pages/Skills/components/UpdateSkillShowcase.tsx +++ b/apps/web/src/pages/Skills/components/UpdateSkillShowcase.tsx @@ -23,7 +23,7 @@ import { } from "@gc-digital-talent/graphql"; import SEO from "~/components/SEO/SEO"; -import Hero from "~/components/HeroDeprecated/HeroDeprecated"; +import Hero from "~/components/Hero"; import SkillBrowserDialog from "~/components/SkillBrowser/SkillBrowserDialog"; import { FormValues as SkillBrowserDialogFormValues } from "~/components/SkillBrowser/types"; diff --git a/apps/web/src/pages/SupportPage/SupportPage.tsx b/apps/web/src/pages/SupportPage/SupportPage.tsx index 972ad03f0f2..c092ab2211b 100644 --- a/apps/web/src/pages/SupportPage/SupportPage.tsx +++ b/apps/web/src/pages/SupportPage/SupportPage.tsx @@ -2,7 +2,7 @@ import { useIntl } from "react-intl"; import { useTheme } from "@gc-digital-talent/theme"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import flourishTopLight from "~/assets/img/support_top_light.webp"; diff --git a/apps/web/src/pages/Teams/CreateTeamPage/CreateTeamPage.tsx b/apps/web/src/pages/Teams/CreateTeamPage/CreateTeamPage.tsx index 8aed0b83b3f..b06c4383fb6 100644 --- a/apps/web/src/pages/Teams/CreateTeamPage/CreateTeamPage.tsx +++ b/apps/web/src/pages/Teams/CreateTeamPage/CreateTeamPage.tsx @@ -9,10 +9,10 @@ import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; import useRoutes from "~/hooks/useRoutes"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; +import Hero from "~/components/Hero"; import CreateTeamForm from "./components/CreateTeamForm"; @@ -87,10 +87,10 @@ const CreateTeamPage = () => { return ( <> - diff --git a/apps/web/src/pages/Teams/IndexTeamPage/IndexTeamPage.tsx b/apps/web/src/pages/Teams/IndexTeamPage/IndexTeamPage.tsx index 0ff30e9ccff..d4c982798f7 100644 --- a/apps/web/src/pages/Teams/IndexTeamPage/IndexTeamPage.tsx +++ b/apps/web/src/pages/Teams/IndexTeamPage/IndexTeamPage.tsx @@ -5,10 +5,10 @@ import { ROLE_NAME } from "@gc-digital-talent/auth"; import useRoutes from "~/hooks/useRoutes"; import SEO from "~/components/SEO/SEO"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; +import Hero from "~/components/Hero"; import TeamTableApi from "./components/TeamTable/TeamTable"; @@ -38,12 +38,12 @@ const IndexTeamPage = () => { return ( <> - - + diff --git a/apps/web/src/pages/Teams/TeamLayout.tsx b/apps/web/src/pages/Teams/TeamLayout.tsx index 1a56d519d98..5f1ce503aa9 100644 --- a/apps/web/src/pages/Teams/TeamLayout.tsx +++ b/apps/web/src/pages/Teams/TeamLayout.tsx @@ -11,11 +11,11 @@ import { FragmentType, getFragment, graphql } from "@gc-digital-talent/graphql"; import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useRoutes from "~/hooks/useRoutes"; import useCurrentPage from "~/hooks/useCurrentPage"; import useRequiredParams from "~/hooks/useRequiredParams"; import { PageNavInfo } from "~/types/pages"; +import Hero from "~/components/Hero"; import RequireAuth from "../../components/RequireAuth/RequireAuth"; @@ -98,16 +98,13 @@ const TeamHeader = ({ teamQuery }: TeamHeaderProps) => { return ( <> - ({ - label: page.link.label ?? page.title, - url: page.link.url, - })), - }} + navTabs={Array.from(pages.values()).map((page) => ({ + label: page.link.label ?? page.title, + url: page.link.url, + }))} /> ); diff --git a/apps/web/src/pages/Teams/ViewTeamPage/ViewTeamPage.tsx b/apps/web/src/pages/Teams/ViewTeamPage/ViewTeamPage.tsx index 3ccf52b28ea..6538ff91a9d 100644 --- a/apps/web/src/pages/Teams/ViewTeamPage/ViewTeamPage.tsx +++ b/apps/web/src/pages/Teams/ViewTeamPage/ViewTeamPage.tsx @@ -35,7 +35,7 @@ export const ViewTeamContent = ({ teamQuery }: ViewTeamContentProps) => { <> - + ); }; diff --git a/apps/web/src/pages/TermsAndConditions/TermsAndConditions.tsx b/apps/web/src/pages/TermsAndConditions/TermsAndConditions.tsx index 68dae7cb67f..f390bd16e54 100644 --- a/apps/web/src/pages/TermsAndConditions/TermsAndConditions.tsx +++ b/apps/web/src/pages/TermsAndConditions/TermsAndConditions.tsx @@ -10,7 +10,7 @@ import { } from "@gc-digital-talent/ui"; import { Locales, getLocale } from "@gc-digital-talent/i18n"; -import Hero from "~/components/HeroDeprecated"; +import Hero from "~/components/Hero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import heroImg from "~/assets/img/accessibility-statement-header.webp"; diff --git a/apps/web/src/pages/TrainingOpportunities/IndexTrainingOpportunitiesPage.tsx b/apps/web/src/pages/TrainingOpportunities/IndexTrainingOpportunitiesPage.tsx index dc933693d38..1da00e83473 100644 --- a/apps/web/src/pages/TrainingOpportunities/IndexTrainingOpportunitiesPage.tsx +++ b/apps/web/src/pages/TrainingOpportunities/IndexTrainingOpportunitiesPage.tsx @@ -8,6 +8,7 @@ import SEO from "~/components/SEO/SEO"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import useRoutes from "~/hooks/useRoutes"; import pageTitles from "~/messages/pageTitles"; +import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import TrainingOpportunitiesTable from "./components/TrainingOpportunitiesTable"; @@ -32,12 +33,9 @@ export const IndexTrainingOpportunitiesPage = () => { <> -
+ -
+
); }; diff --git a/apps/web/src/pages/Users/IndexUserPage/IndexUserPage.tsx b/apps/web/src/pages/Users/IndexUserPage/IndexUserPage.tsx index fd57ad82d5c..3859f8b2e2b 100644 --- a/apps/web/src/pages/Users/IndexUserPage/IndexUserPage.tsx +++ b/apps/web/src/pages/Users/IndexUserPage/IndexUserPage.tsx @@ -5,10 +5,10 @@ import { ROLE_NAME } from "@gc-digital-talent/auth"; import SEO from "~/components/SEO/SEO"; import AdminContentWrapper from "~/components/AdminContentWrapper/AdminContentWrapper"; import useRoutes from "~/hooks/useRoutes"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import useBreadcrumbs from "~/hooks/useBreadcrumbs"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; import pageTitles from "~/messages/pageTitles"; +import Hero from "~/components/Hero"; import UserTable from "./components/UserTable"; @@ -38,12 +38,12 @@ export const IndexUserPage = () => { return ( <> - - + diff --git a/apps/web/src/pages/Users/UpdateUserPage/UpdateUserPage.tsx b/apps/web/src/pages/Users/UpdateUserPage/UpdateUserPage.tsx index 9ef731a56c8..0a7af8e76d2 100644 --- a/apps/web/src/pages/Users/UpdateUserPage/UpdateUserPage.tsx +++ b/apps/web/src/pages/Users/UpdateUserPage/UpdateUserPage.tsx @@ -401,7 +401,7 @@ const UpdateUserPage = () => { const availableRoles = unpackMaybes(data?.roles); return ( - + <> { description: "Page title for the user edit page", })} /> - - {data?.user ? ( - <> - - - - {intl.formatMessage(adminMessages.rolesAndPermissions)} - - - - - - - {intl.formatMessage({ - defaultMessage: "Advanced tools", - id: "KoKXUw", - description: "Heading for making major changes to a user", - })} - - - - ) : ( - -

- {intl.formatMessage( - { - defaultMessage: "User {userId} not found.", - id: "0SoKjt", - description: "Message displayed for user not found.", - }, - { userId }, - )} -

-
- )} -
-
+ + + {data?.user ? ( + <> + + + + {intl.formatMessage(adminMessages.rolesAndPermissions)} + + + + + + + {intl.formatMessage({ + defaultMessage: "Advanced tools", + id: "KoKXUw", + description: "Heading for making major changes to a user", + })} + + + + ) : ( + +

+ {intl.formatMessage( + { + defaultMessage: "User {userId} not found.", + id: "0SoKjt", + description: "Message displayed for user not found.", + }, + { userId }, + )} +

+
+ )} +
+
+ ); }; diff --git a/apps/web/src/pages/Users/UserInformationPage/UserInformationPage.tsx b/apps/web/src/pages/Users/UserInformationPage/UserInformationPage.tsx index 7ace87c66e7..05f0ff27e89 100644 --- a/apps/web/src/pages/Users/UserInformationPage/UserInformationPage.tsx +++ b/apps/web/src/pages/Users/UserInformationPage/UserInformationPage.tsx @@ -511,7 +511,7 @@ export const UserInformation = ({ ]; return ( - + {items.map((item) => ( diff --git a/apps/web/src/pages/Users/UserLayout.tsx b/apps/web/src/pages/Users/UserLayout.tsx index 09b20e0cf1d..b6001107219 100644 --- a/apps/web/src/pages/Users/UserLayout.tsx +++ b/apps/web/src/pages/Users/UserLayout.tsx @@ -15,8 +15,8 @@ import useRequiredParams from "~/hooks/useRequiredParams"; import useCurrentPage from "~/hooks/useCurrentPage"; import { getFullNameHtml } from "~/utils/nameUtils"; import { PageNavInfo } from "~/types/pages"; -import AdminHero from "~/components/HeroDeprecated/AdminHero"; import RequireAuth from "~/components/RequireAuth/RequireAuth"; +import Hero from "~/components/Hero"; type PageNavKeys = "profile" | "info" | "edit"; @@ -85,16 +85,13 @@ const UserHeader = ({ user }: UserHeaderProps) => { return ( <> - ({ - label: page.link.label ?? page.title, - url: page.link.url, - })), - }} + navTabs={Array.from(pages.values()).map((page) => ({ + label: page.link.label ?? page.title, + url: page.link.url, + }))} /> {userDeleted ? ( > /usr/local/etc/php/conf.d/php.ini RUN apt-get update \ && apt-get install --yes --no-install-recommends supervisor cron postgresql-client \ - && apt-get --yes autoremove \ && apt-get clean diff --git a/packages/helpers/src/constants/regularExpressions.ts b/packages/helpers/src/constants/regularExpressions.ts index d1b1c36d60d..8f3619eb07a 100644 --- a/packages/helpers/src/constants/regularExpressions.ts +++ b/packages/helpers/src/constants/regularExpressions.ts @@ -8,7 +8,7 @@ export const keyStringRegex = /^[a-z]+[_a-z0-9]*$/; // See: https://regex101.com/r/EAZ8ha/6 export const phoneNumberRegex = /^\+[1-9]\d{1,14}$/; -// See: https://regex101.com/r/T8IYJU/3 +// See: https://regex101.com/r/T8IYJU/6 // Note: This should be kept in sync with the check in the UpdateUserInputValidator export const workEmailDomainRegex = - /(gc\.ca|canada\.ca|elections\.ca|ccc\.ca|canadapost-postescanada\.ca|gg\.ca)$/i; + /@([A-Za-z0-9-]+\.)*(gc\.ca|canada\.ca|elections\.ca|ccc\.ca|canadapost-postescanada\.ca|gg\.ca)$/i;