Skip to content

Commit 260cc4a

Browse files
authored
Merge pull request #1333 from bcgov/cherry-pick-enhancements
Cherry pick enhancements
2 parents 50d0e9d + a8e2a66 commit 260cc4a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+811
-683
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npm run validate-colors

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package-lock.json

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"cy-run": "cypress run",
1717
"e2e-chrome": "cypress run --browser chrome --headed",
1818
"storybook": "storybook dev -p 6006",
19-
"build-storybook": "storybook build"
19+
"build-storybook": "storybook build",
20+
"prepare": "husky",
21+
"validate-colors": "tsx scripts/validate-colors.ts"
2022
},
2123
"dependencies": {
2224
"@mdi/font": "^7.3.67",
@@ -35,9 +37,9 @@
3537
},
3638
"devDependencies": {
3739
"@chromatic-com/storybook": "^4.0.1",
40+
"@storybook/addon-docs": "^9.0.17",
3841
"@storybook/addon-vitest": "^9.0.17",
3942
"@storybook/vue3-vite": "^9.0.17",
40-
"@storybook/addon-docs": "^9.0.17",
4143
"@tsconfig/node18": "^18.2.4",
4244
"@types/lodash": "^4.17.20",
4345
"@types/luxon": "^3.6.2",
@@ -58,13 +60,15 @@
5860
"eslint-plugin-storybook": "^9.0.17",
5961
"eslint-plugin-unused-imports": "^4.1.4",
6062
"eslint-plugin-vue": "^10.3.0",
63+
"husky": "^9.1.7",
6164
"openapicmd": "^2.6.1",
6265
"playwright": "^1.53.1",
63-
"storybook": "^9.0.17",
64-
"vitest": "^3.2.4",
6566
"sass": "^1.86.3",
67+
"storybook": "^9.0.17",
68+
"tsx": "^4.20.3",
6669
"typescript": "~5.8.3",
6770
"vite": "^7.0.2",
71+
"vitest": "^3.2.4",
6872
"vue-eslint-parser": "^10.2.0",
6973
"vue-tsc": "^3.0.3"
7074
},
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env node
2+
3+
import fs from "fs";
4+
import path from "path";
5+
6+
interface ColorMap {
7+
[key: string]: string;
8+
}
9+
10+
function extractColorsFromTheme(filePath: string): ColorMap {
11+
const content = fs.readFileSync(filePath, "utf-8");
12+
const colors: ColorMap = {};
13+
14+
const colorMatches = content.match(/(["']?)([^"'\s]+)\1\s*:\s*"#([A-Fa-f0-9]{6})"/g);
15+
16+
if (colorMatches) {
17+
colorMatches.forEach((match) => {
18+
const [, , key, value] = match.match(/(["']?)([^"'\s]+)\1\s*:\s*"#([A-Fa-f0-9]{6})"/) || [];
19+
if (key && value) {
20+
colors[key] = value.toLowerCase();
21+
}
22+
});
23+
}
24+
25+
return colors;
26+
}
27+
28+
function extractColorsFromScss(filePath: string): ColorMap {
29+
const content = fs.readFileSync(filePath, "utf-8");
30+
const colors: ColorMap = {};
31+
32+
// Extract colors from SCSS file
33+
const colorMatches = content.match(/\$([^:]+):\s*#([A-Fa-f0-9]{6})/g);
34+
35+
if (colorMatches) {
36+
colorMatches.forEach((match) => {
37+
const [, key, value] = match.match(/\$([^:]+):\s*#([A-Fa-f0-9]{6})/) || [];
38+
if (key && value) {
39+
colors[key] = value.toLowerCase();
40+
}
41+
});
42+
}
43+
44+
return colors;
45+
}
46+
47+
function compareColors(
48+
themeColors: ColorMap,
49+
scssColors: ColorMap,
50+
): {
51+
missingInScss: string[];
52+
missingInTheme: string[];
53+
mismatched: Array<{ key: string; themeValue: string; scssValue: string }>;
54+
} {
55+
const missingInScss: string[] = [];
56+
const missingInTheme: string[] = [];
57+
const mismatched: Array<{ key: string; themeValue: string; scssValue: string }> = [];
58+
59+
// Check for colors in theme but not in SCSS
60+
Object.keys(themeColors).forEach((key) => {
61+
if (!scssColors[key]) {
62+
missingInScss.push(key);
63+
} else if (themeColors[key] !== scssColors[key]) {
64+
mismatched.push({
65+
key,
66+
themeValue: themeColors[key],
67+
scssValue: scssColors[key],
68+
});
69+
}
70+
});
71+
72+
// Check for colors in SCSS but not in theme
73+
Object.keys(scssColors).forEach((key) => {
74+
if (!themeColors[key]) {
75+
missingInTheme.push(key);
76+
}
77+
});
78+
79+
return { missingInScss, missingInTheme, mismatched };
80+
}
81+
82+
function main() {
83+
const themePath = path.join(process.cwd(), "src/styles/ecer-theme.ts");
84+
const scssPath = path.join(process.cwd(), "src/styles/_colors.scss");
85+
86+
if (!fs.existsSync(themePath)) {
87+
console.error("❌ Theme file not found:", themePath);
88+
process.exit(1);
89+
}
90+
91+
if (!fs.existsSync(scssPath)) {
92+
console.error("❌ SCSS colors file not found:", scssPath);
93+
process.exit(1);
94+
}
95+
96+
console.log("🔍 Validating color consistency...\n");
97+
98+
const themeColors = extractColorsFromTheme(themePath);
99+
const scssColors = extractColorsFromScss(scssPath);
100+
101+
console.log(`📊 Found ${Object.keys(themeColors).length} colors in theme file`);
102+
console.log(`📊 Found ${Object.keys(scssColors).length} colors in SCSS file\n`);
103+
104+
const comparison = compareColors(themeColors, scssColors);
105+
106+
let hasErrors = false;
107+
108+
if (comparison.missingInScss.length > 0) {
109+
console.log("❌ Colors missing in SCSS file:");
110+
comparison.missingInScss.forEach((color) => {
111+
console.log(` - ${color}: #${themeColors[color]}`);
112+
});
113+
console.log("");
114+
hasErrors = true;
115+
}
116+
117+
if (comparison.missingInTheme.length > 0) {
118+
console.log("❌ Colors missing in theme file:");
119+
comparison.missingInTheme.forEach((color) => {
120+
console.log(` - ${color}: #${scssColors[color]}`);
121+
});
122+
console.log("");
123+
hasErrors = true;
124+
}
125+
126+
if (comparison.mismatched.length > 0) {
127+
console.log("❌ Colors with mismatched values:");
128+
comparison.mismatched.forEach(({ key, themeValue, scssValue }) => {
129+
console.log(` - ${key}: theme=#${themeValue}, scss=#${scssValue}`);
130+
});
131+
console.log("");
132+
hasErrors = true;
133+
}
134+
135+
if (hasErrors) {
136+
console.log("💡 To fix these issues:");
137+
console.log(" 1. Add missing colors to the appropriate file");
138+
console.log(" 2. Update mismatched color values to match");
139+
console.log(" 3. Run this script again to verify\n");
140+
process.exit(1);
141+
} else {
142+
console.log("✅ All colors are consistent between theme and SCSS files!");
143+
}
144+
}
145+
146+
if (require.main === module) {
147+
main();
148+
}

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/AcknowledgementBanner.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<v-divider :thickness="3" color="warning" class="border-opacity-100"></v-divider>
44
<v-card :rounded="'0'" flat :color="backgroundColour" :style="{ 'min-height': '100px' }" class="d-flex justify-center border-xl">
55
<v-container>
6-
<p class="align-self-center">{{ title }}</p>
6+
<p class="align-self-center white">{{ title }}</p>
77
</v-container>
88
</v-card>
99
<v-divider :thickness="3" color="warning" class="border-opacity-100"></v-divider>

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/AddProfessionalDevelopment.vue

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<template>
22
<v-container>
3-
<v-breadcrumbs class="pl-0" :items="items" color="primary">
4-
<template #divider>/</template>
5-
</v-breadcrumbs>
3+
<Breadcrumb />
64
<div class="d-flex flex-column ga-3">
75
<h1 class="mt-5">Professional development</h1>
86
<v-row>
@@ -270,7 +268,7 @@ import type { Components } from "@/types/openapi";
270268
import { formatDate } from "@/utils/format";
271269
import { isNumber } from "@/utils/formInput";
272270
import * as Rules from "@/utils/formRules";
273-
271+
import Breadcrumb from "@/components/Breadcrumb.vue";
274272
import type { FileItem } from "./UploadFileItem.vue";
275273
276274
interface ProfessionalDevelopmentData {
@@ -281,7 +279,7 @@ interface ProfessionalDevelopmentData {
281279
282280
export default defineComponent({
283281
name: "AddProfessionalDevelopment",
284-
components: { FileUploader, EceTextField, EceDateInput },
282+
components: { FileUploader, EceTextField, EceDateInput, Breadcrumb },
285283
props: {
286284
applicationId: {
287285
type: String,
@@ -309,36 +307,13 @@ export default defineComponent({
309307
};
310308
},
311309
data() {
312-
const items = [
313-
{
314-
title: "Home",
315-
disabled: false,
316-
href: "/",
317-
},
318-
{
319-
title: "Application",
320-
disabled: false,
321-
href: `/manage-application/${this.applicationId}`,
322-
},
323-
{
324-
title: "Professional development",
325-
disabled: false,
326-
href: `/manage-application/${this.applicationId}/professional-development`,
327-
},
328-
{
329-
title: "Add",
330-
disabled: true,
331-
href: `/manage-application/${this.applicationId}/professional-development/add`,
332-
},
333-
];
334-
335310
const professionalDevelopment: ProfessionalDevelopmentData & Components.Schemas.ProfessionalDevelopment = {
336311
selection: [],
337312
areAttachedFilesValid: true,
338313
isFileUploadInProgress: false,
339314
};
340315
341-
return { items, professionalDevelopment, Rules };
316+
return { professionalDevelopment, Rules };
342317
},
343318
computed: {
344319
applicationType() {

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/ApplicationCertificationTypeHeader.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<template>
22
<div>
3-
<h1 v-if="isLaborMobility">{{ `Transfer certification to ${certificationType}` }}</h1>
4-
<h1 v-else-if="isRenewal">{{ `Application to renew ${certificationType} certification` }}</h1>
5-
<h1 v-else>{{ `Application for ${certificationType} certification` }}</h1>
6-
<div v-if="certificationTypes.includes(CertificationType.FIVE_YEAR)" role="doc-subtitle">
3+
<h1 class="white" v-if="isLaborMobility">{{ `Transfer certification to ${certificationType}` }}</h1>
4+
<h1 class="white" v-else-if="isRenewal">{{ `Application to renew ${certificationType} certification` }}</h1>
5+
<h1 class="white" v-else>{{ `Application for ${certificationType} certification` }}</h1>
6+
<div class="white" v-if="certificationTypes.includes(CertificationType.FIVE_YEAR)" role="doc-subtitle">
77
{{ certificationTypeSubtitleForFiveYear }}
88
</div>
99
</div>

0 commit comments

Comments
 (0)