Compare commits
5 Commits
cb0ef7ddd5
...
36208ef071
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36208ef071 | ||
|
|
b546a0cf01 | ||
|
|
3935f6ad21 | ||
|
|
fd5ad7e88e | ||
|
|
8c957fe694 |
83
ci/i18n-completer/app.ts
Normal file
83
ci/i18n-completer/app.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
const englishI18nFilePath='../../frontend/src/locale/messages.json';
|
||||
const frenchI18nFilePath='../../frontend/src/locale/messages-fr.json';
|
||||
|
||||
interface Translations {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
interface I18nFileContent {
|
||||
locale: string;
|
||||
translations: Translations;
|
||||
};
|
||||
|
||||
interface Translation {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface I18nTranslations {
|
||||
locale: string;
|
||||
translations: Translation[];
|
||||
}
|
||||
|
||||
function readAndParseFile(filePath): I18nTranslations {
|
||||
const fileContent = fs.readFileSync(filePath);
|
||||
const parsedFileContent: I18nFileContent = JSON.parse(fileContent.toString());
|
||||
return {
|
||||
locale: parsedFileContent.locale,
|
||||
translations: Object.keys(parsedFileContent.translations)
|
||||
.map(translationKey => {
|
||||
return {
|
||||
key: translationKey,
|
||||
value: parsedFileContent.translations[translationKey]
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function findMatchingFrenchTranslation(englishTranslation: Translation, frenchI18nFileContent: I18nTranslations): Translation | undefined {
|
||||
return frenchI18nFileContent.translations.find(frenchTranslation => frenchTranslation.key === englishTranslation.key);
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
const englishI18nTranslations = readAndParseFile(englishI18nFilePath);
|
||||
const frenchI18nTranslations = readAndParseFile(frenchI18nFilePath);
|
||||
|
||||
const frenchTranslations = englishI18nTranslations.translations
|
||||
.map(englishTranslation => {
|
||||
let result: Translation;
|
||||
|
||||
const matchingFrenchTranslation = findMatchingFrenchTranslation(englishTranslation, frenchI18nTranslations);
|
||||
if (matchingFrenchTranslation?.value?.length) {
|
||||
result = matchingFrenchTranslation;
|
||||
} else {
|
||||
result = {
|
||||
key: englishTranslation.key,
|
||||
value: `<À TRADUIRE> - ${englishTranslation.value}`
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
const newFrenchI18nTranslations: I18nTranslations = {
|
||||
locale: 'fr-FR',
|
||||
translations: frenchTranslations
|
||||
};
|
||||
|
||||
const newFrenchTranslationFileContent: I18nFileContent = {
|
||||
locale: newFrenchI18nTranslations.locale,
|
||||
translations: newFrenchI18nTranslations.translations.reduce(
|
||||
(result, translation) => Object.assign(result, { [translation.key]: translation.value }),
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
fs.writeFileSync(frenchI18nFilePath, JSON.stringify(newFrenchTranslationFileContent));
|
||||
}
|
||||
|
||||
main();
|
||||
540
ci/i18n-completer/package-lock.json
generated
Normal file
540
ci/i18n-completer/package-lock.json
generated
Normal file
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"name": "i18n-completer",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "i18n-completer",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.5",
|
||||
"tsx": "^4.19.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
|
||||
"integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
|
||||
"integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
|
||||
"integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
|
||||
"integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
|
||||
"integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
|
||||
"integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.23.1",
|
||||
"@esbuild/android-arm": "0.23.1",
|
||||
"@esbuild/android-arm64": "0.23.1",
|
||||
"@esbuild/android-x64": "0.23.1",
|
||||
"@esbuild/darwin-arm64": "0.23.1",
|
||||
"@esbuild/darwin-x64": "0.23.1",
|
||||
"@esbuild/freebsd-arm64": "0.23.1",
|
||||
"@esbuild/freebsd-x64": "0.23.1",
|
||||
"@esbuild/linux-arm": "0.23.1",
|
||||
"@esbuild/linux-arm64": "0.23.1",
|
||||
"@esbuild/linux-ia32": "0.23.1",
|
||||
"@esbuild/linux-loong64": "0.23.1",
|
||||
"@esbuild/linux-mips64el": "0.23.1",
|
||||
"@esbuild/linux-ppc64": "0.23.1",
|
||||
"@esbuild/linux-riscv64": "0.23.1",
|
||||
"@esbuild/linux-s390x": "0.23.1",
|
||||
"@esbuild/linux-x64": "0.23.1",
|
||||
"@esbuild/netbsd-x64": "0.23.1",
|
||||
"@esbuild/openbsd-arm64": "0.23.1",
|
||||
"@esbuild/openbsd-x64": "0.23.1",
|
||||
"@esbuild/sunos-x64": "0.23.1",
|
||||
"@esbuild/win32-arm64": "0.23.1",
|
||||
"@esbuild/win32-ia32": "0.23.1",
|
||||
"@esbuild/win32-x64": "0.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
|
||||
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
|
||||
"integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "~0.23.0",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
},
|
||||
"bin": {
|
||||
"tsx": "dist/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
ci/i18n-completer/package.json
Normal file
17
ci/i18n-completer/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "i18n-completer",
|
||||
"version": "1.0.0",
|
||||
"main": "app.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "npx tsx app.ts",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.5.5",
|
||||
"tsx": "^4.19.1"
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,9 @@
|
||||
"build-prod-fr": "ng build --configuration=production-fr --base-href /fr/",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"i18n": "ng extract-i18n --output-path src/locale --format=json"
|
||||
"i18n": "npm run i18n-ng-extraction && npm run i18n-fr-file-completion",
|
||||
"i18n-ng-extraction": "ng extract-i18n --output-path src/locale --format=json",
|
||||
"i18n-fr-file-completion": "cd ../ci/i18n-completer && npm start && cd -"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
</div>
|
||||
<div class="footer">
|
||||
<img src="/api/pictures/{{ publication.author.image }}" [matTooltip]="publication.author.name"/>
|
||||
Publication posted by {{publication.author.name}}
|
||||
<span i18n>Publication posted by {{publication.author.name}}</span>
|
||||
<span class="publication-date">
|
||||
({{ publication.creationDate | date: 'short' : 'fr-Fr' }})
|
||||
({{ publication.creationDate | date: 'short' }})
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
<h1>Disconnection...</h1>
|
||||
<h1 i18n>Disconnection...</h1>
|
||||
<mat-spinner></mat-spinner>
|
||||
@@ -1,2 +1,11 @@
|
||||
<h1 i18n>Last publications</h1>
|
||||
<app-publication-list [publications$]="publications$"></app-publication-list>
|
||||
@if ((isLoading$ | async) === true) {
|
||||
<h2 i18n>Publications loading...</h2>
|
||||
<mat-spinner></mat-spinner>
|
||||
} @else {
|
||||
@if ((publications$ | async) != []) {
|
||||
<app-publication-list [publications$]="publications$"></app-publication-list>
|
||||
} @else {
|
||||
<h2 i18n>No any publication.</h2>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HomeComponent } from './home.component';
|
||||
|
||||
describe('HomeComponent', () => {
|
||||
let component: HomeComponent;
|
||||
let fixture: ComponentFixture<HomeComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [HomeComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HomeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,16 +1,19 @@
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { HomeService } from './home.service';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Publication } from '../../core/rest-services/publications/model/publication';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { PublicationListComponent } from '../../components/publication-list/publication-list.component';
|
||||
import { Publication } from '../../core/rest-services/publications/model/publication';
|
||||
import { HomeService } from './home.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
standalone: true,
|
||||
imports: [PublicationListComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatProgressSpinnerModule,
|
||||
PublicationListComponent
|
||||
],
|
||||
templateUrl: './home.component.html',
|
||||
styleUrl: './home.component.scss',
|
||||
providers: [HomeService]
|
||||
|
||||
@@ -26,8 +26,9 @@ export class HomeService {
|
||||
this.publicationRestService.getLatest()
|
||||
.then(publications => this.publicationsSubject.next(publications))
|
||||
.catch(error => {
|
||||
this.snackBar.open('An error occurred while retrieving latest publications...');
|
||||
console.error('An error occurred while retrieving latest publications...', error);
|
||||
const errorMessage = $localize`An error occurred while retrieving latest publications...`;
|
||||
this.snackBar.open(errorMessage, $localize`Close`, { duration: 5000 });
|
||||
console.error(errorMessage, error);
|
||||
})
|
||||
.finally(() => this.isLoadingSubject.next(false));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<form [formGroup]="loginForm" (submit)="performLogin()" ngNativeValidate>
|
||||
<h1>Login</h1>
|
||||
<h1 i18n>Login</h1>
|
||||
<div>
|
||||
<mat-icon>mail</mat-icon>
|
||||
<label for="email">
|
||||
<label for="email" i18n>
|
||||
Email address
|
||||
<span class="required">*</span>
|
||||
</label>
|
||||
@@ -10,14 +10,14 @@
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon>lock</mat-icon>
|
||||
<label for="password">
|
||||
<label for="password" i18n>
|
||||
Password
|
||||
<span class="required">*</span>
|
||||
</label>
|
||||
<input type="password" id="password" formControlName="password" required />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button type="submit">Send</button>
|
||||
<a [routerLink]="['/signin']">Create an account</a>
|
||||
<button type="submit" i18n>Send</button>
|
||||
<a [routerLink]="['/signin']" i18n>Create an account</a>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [LoginComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -66,16 +66,12 @@ export class LoginService {
|
||||
.login(state.request)
|
||||
.then((response) => {
|
||||
this.authenticationService.authenticate(response.accessToken, response.refreshToken);
|
||||
this.snackBar.open('Authentication succeeded!', 'Close', {
|
||||
duration: 5000,
|
||||
});
|
||||
this.snackBar.open($localize`Authentication succeeded!`, $localize`Close`, { duration: 5000 });
|
||||
this.router.navigate(['/home']);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
this.snackBar.open('Authentication failed.', 'Close', {
|
||||
duration: 5000,
|
||||
});
|
||||
this.snackBar.open($localize`Authentication failed.`, $localize`Close`, { duration: 5000 });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
<h1>Your publications</h1>
|
||||
<h1 i18n>Your publications</h1>
|
||||
|
||||
<a [routerLink]="['/publications/new']"
|
||||
class="new-publication"
|
||||
matTooltip="Add a new publication"
|
||||
matTooltipPosition="left">
|
||||
matTooltipPosition="left"
|
||||
i18n-matTooltip>
|
||||
+
|
||||
</a>
|
||||
|
||||
@if ((isLoading$ | async) === true) {
|
||||
<h2>Publication loading...</h2>
|
||||
<h2 i18n>Publication loading...</h2>
|
||||
<mat-spinner></mat-spinner>
|
||||
} @else {
|
||||
@if ((isLoaded$ | async) === true) {
|
||||
<app-publication-list [publications$]="publications$"></app-publication-list>
|
||||
} @else {
|
||||
<h2>There is no any publication...</h2>
|
||||
<h2 i18n>There is no any publication...</h2>
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,8 @@ export class MyPublicationsService {
|
||||
this.publicationsSubject.next(publications);
|
||||
})
|
||||
.catch(error => {
|
||||
const errorMessage = 'An error occurred while retrieving your publications...';
|
||||
this.snackBar.open(errorMessage);
|
||||
const errorMessage = $localize`An error occurred while retrieving your publications...`;
|
||||
this.snackBar.open(errorMessage, $localize`Close`, { duration: 5000 });
|
||||
console.error(errorMessage, error);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -50,7 +50,7 @@ export class MyPublicationsService {
|
||||
});
|
||||
} else {
|
||||
this.authenticationService.unauthenticate();
|
||||
this.snackBar.open('You are unauthenticated. Please, log-in first.', 'Close', { duration: 5000 });
|
||||
this.snackBar.open($localize`You are unauthenticated. Please, log-in first.`, $localize`Close`, { duration: 5000 });
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@if (isLoading) {
|
||||
<h2 i18n>Publication content loading...</h2>
|
||||
<mat-spinner></mat-spinner>
|
||||
} @else {
|
||||
@if (publication) {
|
||||
@@ -8,7 +9,10 @@
|
||||
<h1>{{ publication.title }}</h1>
|
||||
<h2>{{ publication.description }}</h2>
|
||||
@if (isAuthorAndUserEquals) {
|
||||
<a [routerLink]="['edit']" class="button action" matTooltip="Click to edit the publication">
|
||||
<a [routerLink]="['edit']"
|
||||
class="button action"
|
||||
matTooltip="Click to edit the publication"
|
||||
i18n-mapTooltip>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</a>
|
||||
}
|
||||
@@ -18,14 +22,18 @@
|
||||
<div class="metadata">
|
||||
<img src="/api/pictures/{{ publication.author.image }}" [matTooltip]="publication.author.name" />
|
||||
<div class="posting-data">
|
||||
Publication posted by {{ publication.author.name }}
|
||||
<span i18n>Publication posted by {{ publication.author.name }}</span>
|
||||
<span class="publication-date">
|
||||
({{ publication.creationDate | date: 'short' : 'fr-FR' }})
|
||||
({{ publication.creationDate | date: 'short' }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@if (isAuthorAndUserEquals) {
|
||||
<button type="button" (click)="deletePublication()" matTooltip="Click to delete the publication" matTooltipPosition="left">
|
||||
<button type="button"
|
||||
(click)="deletePublication()"
|
||||
matTooltip="Click to delete the publication"
|
||||
matTooltipPosition="left"
|
||||
i18n-mapTooltip>
|
||||
<mat-icon>delete</mat-icon>
|
||||
Delete
|
||||
</button>
|
||||
@@ -34,7 +42,7 @@
|
||||
</div>
|
||||
} @else {
|
||||
<div class="loading-failed">
|
||||
<h1>Publication failed to load...</h1>
|
||||
<h1 i18n>Publication failed to load...</h1>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,9 @@ export class PublicationComponent implements OnInit, OnDestroy {
|
||||
setTimeout(() => Prism.highlightAll(), 100);
|
||||
})
|
||||
.catch(error => {
|
||||
this.snackBar.open('An error occurred while loading publication...', 'Close', { duration: 5000 });
|
||||
console.error('An error occurred while loading publication...', error);
|
||||
const errorMessage = $localize`An error occurred while loading publication...`;
|
||||
this.snackBar.open(errorMessage, $localize`Close`, { duration: 5000 });
|
||||
console.error(errorMessage, error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
@@ -70,8 +71,8 @@ export class PublicationComponent implements OnInit, OnDestroy {
|
||||
ConfirmationDialog,
|
||||
{
|
||||
data: {
|
||||
title: 'Publication deletion',
|
||||
description: 'Are you sure you want to delete this publication?'
|
||||
title: $localize`Publication deletion`,
|
||||
description: $localize`Are you sure you want to delete this publication?`
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -80,7 +81,7 @@ export class PublicationComponent implements OnInit, OnDestroy {
|
||||
.subscribe(response => {
|
||||
if (response && this.publication?.id) {
|
||||
this.publicationRestService.delete(this.publication.id);
|
||||
this.snackBar.open('Publication deleted', 'Close', { duration: 5000 });
|
||||
this.snackBar.open($localize`Publication deleted`, $localize`Close`, { duration: 5000 });
|
||||
this.location.back();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CodikiNg</title>
|
||||
<title>Codiki</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
|
||||
|
||||
@@ -1,6 +1,31 @@
|
||||
{
|
||||
"locale": "fr-FR",
|
||||
"translations": {
|
||||
"4869473828758837325": "Dernières publications"
|
||||
"2578598149846191609": "Publication postée par {$INTERPOLATION}",
|
||||
"4011987306265136481": "Déconnexion...",
|
||||
"4869473828758837325": "Dernières publications",
|
||||
"5148998676057880041": "Chargement des publications...",
|
||||
"3688381096110057852": "Il n'y a aucune publication.",
|
||||
"8393632007890629197": "Une erreur est survenue lors du chargement des dernières publications...",
|
||||
"7819314041543176992": "Fermer",
|
||||
"2454050363478003966": "Connexion",
|
||||
"8138320902772264034": "Adresse email {$START_TAG_SPAN}*{$CLOSE_TAG_SPAN}",
|
||||
"9175472990822669391": "Mot de passe {$START_TAG_SPAN}*{$CLOSE_TAG_SPAN}",
|
||||
"6490688569532630280": "Valider",
|
||||
"2308975396733519902": "Créer un compte",
|
||||
"1037765878727976611": "Connexion réussie",
|
||||
"6034686865111167926": "Une erreur est survenue lors de la connexion.",
|
||||
"1041423751558601074": "Vos publications",
|
||||
"5463894166935799864": "Rédiger une nouvelle publication",
|
||||
"1519054954638405159": "Chargement de la liste de vos publications...",
|
||||
"5982957837973242128": "Vous n'avez rien publié...",
|
||||
"6147923540123489141": "Une erreur est survenue lors de la récupération de vos publications...",
|
||||
"3450287383703155559": "Vous n'êtes pas connecté. Veuillez vous connecter avant de réessayer.",
|
||||
"9035578711395348230": "Chargement du contenu de la publication...",
|
||||
"570282468314450588": "La publication n'a pas pu être chargée...",
|
||||
"3861667381167371965": "Une erreur est survenue lors du chargement de la publication...",
|
||||
"3189372093194446122": "Suppression de la publication",
|
||||
"7149611045520326321": "Êtes vous sûr de vouloir supprimer cette publication ?",
|
||||
"4353366709080867962": "Publication supprimée"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,31 @@
|
||||
{
|
||||
"locale": "en-UK",
|
||||
"translations": {
|
||||
"4869473828758837325": "Last publications"
|
||||
"2578598149846191609": "Publication posted by {$INTERPOLATION}",
|
||||
"4011987306265136481": "Disconnection...",
|
||||
"4869473828758837325": "Last publications",
|
||||
"5148998676057880041": "Publications loading...",
|
||||
"3688381096110057852": "No any publication.",
|
||||
"8393632007890629197": "An error occurred while retrieving latest publications...",
|
||||
"7819314041543176992": "Close",
|
||||
"2454050363478003966": "Login",
|
||||
"8138320902772264034": " Email address {$START_TAG_SPAN}*{$CLOSE_TAG_SPAN}",
|
||||
"9175472990822669391": " Password {$START_TAG_SPAN}*{$CLOSE_TAG_SPAN}",
|
||||
"6490688569532630280": "Send",
|
||||
"2308975396733519902": "Create an account",
|
||||
"1037765878727976611": "Authentication succeeded!",
|
||||
"6034686865111167926": "Authentication failed.",
|
||||
"1041423751558601074": "Your publications",
|
||||
"5463894166935799864": "Add a new publication",
|
||||
"1519054954638405159": "Publication loading...",
|
||||
"5982957837973242128": "There is no any publication...",
|
||||
"6147923540123489141": "An error occurred while retrieving your publications...",
|
||||
"3450287383703155559": "You are unauthenticated. Please, log-in first.",
|
||||
"9035578711395348230": "Publication content loading...",
|
||||
"570282468314450588": "Publication failed to load...",
|
||||
"3861667381167371965": "An error occurred while loading publication...",
|
||||
"3189372093194446122": "Publication deletion",
|
||||
"7149611045520326321": "Are you sure you want to delete this publication?",
|
||||
"4353366709080867962": "Publication deleted"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user