create-procode 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +266 -2
  2. package/bin/create-procode.mjs +9 -0
  3. package/package.json +30 -4
  4. package/src/args.mjs +145 -0
  5. package/src/cli.mjs +514 -0
  6. package/src/deps.mjs +208 -0
  7. package/src/log.mjs +23 -0
  8. package/src/multiLanguage.mjs +409 -0
  9. package/src/prompt.mjs +60 -0
  10. package/src/scaffold.mjs +104 -0
  11. package/templates/base/README.md.tmpl +185 -0
  12. package/templates/base/_dotenv.local.example.tmpl +8 -0
  13. package/templates/base/_dotenv.tmpl +41 -0
  14. package/templates/base/_doteslintrc.cjs.tmpl +125 -0
  15. package/templates/base/_dotgitignore.tmpl +32 -0
  16. package/templates/base/_dotnvmrc.tmpl +1 -0
  17. package/templates/base/_dotvscode/extensions.json +3 -0
  18. package/templates/base/index.html.tmpl +18 -0
  19. package/templates/base/package.json.tmpl +15 -0
  20. package/templates/base/public/favicon.svg +4 -0
  21. package/templates/base/src/AdapterProvider/AdapterFactory.ts.tmpl +21 -0
  22. package/templates/base/src/AdapterProvider/SampleContacts.ts.tmpl +136 -0
  23. package/templates/base/src/CustomAction.ts.tmpl +47 -0
  24. package/templates/base/src/CustomAuthorizationProvider.ts.tmpl +77 -0
  25. package/templates/base/src/Factory/Actions/myAction.ts.tmpl +51 -0
  26. package/templates/base/src/Factory/Actions/sampleContacts.ts.tmpl +244 -0
  27. package/templates/base/src/Factory/Actions/setField.ts.tmpl +20 -0
  28. package/templates/base/src/Factory/CustomRuleEffectFactory.ts.tmpl +30 -0
  29. package/templates/base/src/Factory/CustomValidationFactory.tsx.tmpl +24 -0
  30. package/templates/base/src/Factory/CustomWidgetFactory.tsx.tmpl +43 -0
  31. package/templates/base/src/Factory/RuleEffects/readOnlyEffect.ts.tmpl +27 -0
  32. package/templates/base/src/Factory/Validations/myValidation.ts.tmpl +52 -0
  33. package/templates/base/src/Factory/Widgets/MyWidget/index.tsx.tmpl +101 -0
  34. package/templates/base/src/Factory/Widgets/Notification/index.tsx.tmpl +53 -0
  35. package/templates/base/src/Factory/Widgets/Notification/notifiFunc.ts.tmpl +9 -0
  36. package/templates/base/src/Factory/Widgets/SectionNav/index.tsx +193 -0
  37. package/templates/base/src/Factory/Widgets/SectionNav/style.scss +139 -0
  38. package/templates/base/src/Module/Sample/Contacts.json.tmpl +965 -0
  39. package/templates/base/src/Module/index.ts.tmpl +26 -0
  40. package/templates/base/src/Screens/index.tsx.tmpl +45 -0
  41. package/templates/base/src/Utils/errorMessages.ts.tmpl +35 -0
  42. package/templates/base/src/Utils/fieldErrorMapper.ts.tmpl +46 -0
  43. package/templates/base/src/Utils/logger.ts.tmpl +21 -0
  44. package/templates/base/src/Utils/responseFormatter.ts.tmpl +39 -0
  45. package/templates/base/src/Utils/storages.ts.tmpl +35 -0
  46. package/templates/base/src/assets/styles/index.scss.tmpl +149 -0
  47. package/templates/base/src/constant.ts.tmpl +53 -0
  48. package/templates/base/src/icons.ts.tmpl +17 -0
  49. package/templates/base/src/localizationResolver.ts.tmpl +48 -0
  50. package/templates/base/src/main.tsx.tmpl +136 -0
  51. package/templates/base/src/routes.ts.tmpl +20 -0
  52. package/templates/base/src/vite-env.d.ts.tmpl +20 -0
  53. package/templates/base/tsconfig.json.tmpl +30 -0
  54. package/templates/base/tsconfig.node.json.tmpl +11 -0
  55. package/templates/base/vite.config.ts.tmpl +90 -0
  56. package/templates/multi-language/locales/fr/core.json +76 -0
  57. package/templates/multi-language/locales/fr/kendo.json +181 -0
  58. package/templates/multi-language/locales/fr/template.json +169 -0
  59. package/templates/multi-language/locales/fr/widget.json +65 -0
  60. package/templates/multi-language/locales/hi/core.json +76 -0
  61. package/templates/multi-language/locales/hi/kendo.json +181 -0
  62. package/templates/multi-language/locales/hi/template.json +169 -0
  63. package/templates/multi-language/locales/hi/widget.json +65 -0
  64. package/templates/multi-language/sample/fr.json +55 -0
  65. package/templates/multi-language/sample/hi.json +55 -0
  66. package/templates/tests/src/Module/schemas.test.ts +50 -0
  67. package/templates/tests-multi-language/src/multiLanguage/enText.ts +68 -0
  68. package/templates/tests-multi-language/src/multiLanguage/translations.test.ts +92 -0
@@ -0,0 +1,20 @@
1
+ import type { CoreProps } from "procode-lowcode-core";
2
+
3
+ /**
4
+ * Extra routes beside the core's own `<base>/:parentslug/*` and
5
+ * `section/:childslug/*`. Each renders the schema getSchemaBySlugService
6
+ * returns for its `customSlug`, so register that slug in src/Module/index.ts
7
+ * too, or the route shows the 404 screen.
8
+ *
9
+ * parentSimblingRoutes beside :parentslug e.g. { path: "dashboard", customSlug: "home-dashboard" }
10
+ * childSimblingRoutes beside section/:childslug
11
+ * childNestedRoutes under the child route
12
+ *
13
+ * ("Simbling" is the library's spelling.) Module scope on purpose: a new object
14
+ * on any render rebuilds the router and remounts the whole app.
15
+ */
16
+ export const customRoute: NonNullable<CoreProps["customRoute"]> = {
17
+ parentSimblingRoutes: [],
18
+ childSimblingRoutes: [],
19
+ childNestedRoutes: [],
20
+ };
@@ -0,0 +1,20 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_APPLICATION_CODE: string;
5
+ readonly VITE_HOMEPAGE: string;
6
+ readonly VITE_CENTRAL_SERVICE_BASE_URL: string;
7
+ readonly VITE_PROJECT_ENVIROMENT: string;
8
+ readonly VITE_TOOL_BASE_URL: string;
9
+ readonly VITE_TOOL_SCHEMA_FETCH: string;
10
+ readonly VITE_AUTH_URL: string;
11
+ readonly VITE_BASE_LOGOUT_URL?: string;
12
+ readonly VITE_HEADER_SLUG: string;
13
+ readonly VITE_FOOTER_SLUG: string;
14
+ readonly VITE_NOTIFICATION_VISIBLE_DURATION?: string;
15
+ readonly VITE_HARDCODED_TOKEN?: string;
16
+ }
17
+
18
+ interface ImportMeta {
19
+ readonly env: ImportMetaEnv;
20
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": false,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "allowSyntheticDefaultImports": true,
13
+
14
+ /* Screens are imported .json files — required, not optional. */
15
+ "resolveJsonModule": true,
16
+
17
+ "isolatedModules": true,
18
+ "noEmit": true,
19
+ "jsx": "react-jsx",
20
+ "esModuleInterop": true,
21
+
22
+ /* Linting */
23
+ "strict": true,
24
+ "noUnusedLocals": true,
25
+ "noUnusedParameters": true,
26
+ "noFallthroughCasesInSwitch": true
27
+ },
28
+ "include": ["src"],
29
+ "references": [{ "path": "./tsconfig.node.json" }]
30
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true,
8
+ "strict": true
9
+ },
10
+ "include": ["vite.config.ts"]
11
+ }
@@ -0,0 +1,90 @@
1
+ /// <reference types="vitest" /> // @tests
2
+ import { fileURLToPath } from "node:url";
3
+ import { defineConfig, loadEnv } from "vite";
4
+ import react from "@vitejs/plugin-react";
5
+
6
+ // https://vitejs.dev/config/
7
+ export default defineConfig(({ command, mode }) => {
8
+ // A personal dev token must never ship. `vite build` reads .env.local like
9
+ // `vite dev` does, so a VITE_HARDCODED_TOKEN left there would be compiled into
10
+ // dist/ and every user of the build would act as that developer. Refuse
11
+ // instead. (ALLOW_TOKEN_IN_BUILD=1 overrides it for a throwaway local build.)
12
+ const env = loadEnv(mode, process.cwd(), "");
13
+ if (command === "build" && env.VITE_HARDCODED_TOKEN && process.env.ALLOW_TOKEN_IN_BUILD !== "1") {
14
+ throw new Error(
15
+ "VITE_HARDCODED_TOKEN is set (usually in .env.local). Remove it before building — " +
16
+ "a built app authenticates from the AuthToken cookie. For a throwaway local build only: ALLOW_TOKEN_IN_BUILD=1.",
17
+ );
18
+ }
19
+
20
+ return {
21
+ // Must match VITE_HOMEPAGE in .env. The app is served from this segment, so a
22
+ // screen lives at <base>/<slug> — e.g. __BASE_PATH_SLASH__sample.
23
+ base: "__BASE_PATH_SLASH__",
24
+
25
+ plugins: [react()],
26
+
27
+ resolve: {
28
+ alias: [
29
+ {
30
+ // procode-lowcode-core exports "./styles" as src/Assets/styles/index.scss,
31
+ // but the package ships the folder as src/assets/. Windows and macOS
32
+ // ignore the case and build; Linux (CI, Docker) fails the @import. This
33
+ // points the import at the real path on every OS.
34
+ find: /^procode-lowcode-core\/styles$/,
35
+ replacement: fileURLToPath(
36
+ new URL("./node_modules/procode-lowcode-core/src/assets/styles/index.scss", import.meta.url),
37
+ ),
38
+ },
39
+ ],
40
+ },
41
+
42
+ build: {
43
+ // Must stay >= es2018. Object rest/spread is an ES2018 feature, and the
44
+ // es2015 downlevel transform miscompiles a `const` that declares two rest
45
+ // patterns at once — it drops bindings and emits a bare `{} = null`, which
46
+ // throws "Cannot destructure 'null' as it is null" at runtime. Kendo's
47
+ // CalendarCell.shouldComponentUpdate is written that way, so the date picker
48
+ // crashes on open in built bundles only — never in dev, which skips this
49
+ // transform. Do not lower this to chase bundle size.
50
+ target: "es2020",
51
+ minify: false,
52
+ },
53
+
54
+ esbuild: {
55
+ target: "es2020",
56
+ },
57
+
58
+ // The two runtime libraries ship CommonJS-interop shapes that Vite's dep
59
+ // scanner does not find on its own; pre-bundling them keeps dev reloads fast
60
+ // and avoids "outdated optimize dep" full-page reloads on every save.
61
+ optimizeDeps: {
62
+ include: ["procode-lowcode-kendo-widget", "procode-lowcode-core"],
63
+ },
64
+
65
+ // Some transitive dependencies still reference the Node `global`.
66
+ define: {
67
+ global: "globalThis",
68
+ },
69
+
70
+ server: {
71
+ fs: {
72
+ allow: ["..", "."],
73
+ },
74
+ },
75
+
76
+ // @tests-start
77
+ // `npm test` (vitest). The ProCode packages ship sources that import SCSS and
78
+ // JSON; inlining them lets Vite transform them in the test run as it does in
79
+ // the app — without this every test importing a package fails to load.
80
+ test: {
81
+ include: ["src/**/*.test.ts"],
82
+ server: {
83
+ deps: {
84
+ inline: [/procode-/],
85
+ },
86
+ },
87
+ },
88
+ // @tests-end
89
+ };
90
+ });
@@ -0,0 +1,76 @@
1
+ {
2
+ "validation.required": "Ce champ est obligatoire",
3
+ "validation.email": "L'adresse e-mail est invalide",
4
+ "validation.bulkEmail": "Une ou plusieurs adresses e-mail sont invalides",
5
+ "validation.alphanumericSpace": "Seuls les lettres, les chiffres et les espaces sont autorisés",
6
+ "validation.maxChars": "{maxCharCount} caractères maximum",
7
+ "validation.minChars": "{minCharCount} caractères minimum",
8
+ "validation.greaterThan": "La valeur doit être supérieure à {value}",
9
+ "validation.greaterThanEqual": "La valeur doit être supérieure ou égale à {value}",
10
+ "validation.lessThan": "La valeur doit être inférieure à {value}",
11
+ "validation.lessThanEqual": "La valeur doit être inférieure ou égale à {value}",
12
+ "validation.between": "La valeur doit être comprise entre {min} et {max}",
13
+ "validation.notBetween": "La valeur ne doit pas être comprise entre {min} et {max}",
14
+ "validation.invalidNumber": "Valeur numérique invalide",
15
+ "validation.invalidDate": "Valeur de date invalide",
16
+ "validation.invalidList": "Valeur de liste invalide",
17
+ "validation.invalidValue": "Valeur {dataType} invalide",
18
+ "validation.itemCount_one": "{count} élément",
19
+ "validation.itemCount_other": "{count} éléments",
20
+ "validation.misconfigured.comparisonValueMissing": "Validation mal configurée : la valeur de comparaison est absente",
21
+ "validation.misconfigured.minBoundaryMissing": "Validation mal configurée : la borne minimale est absente",
22
+ "validation.misconfigured.maxBoundaryMissing": "Validation mal configurée : la borne maximale est absente",
23
+ "validation.misconfigured.maxCharCountMissing": "Validation mal configurée : le paramètre maxCharCount est absent",
24
+ "validation.misconfigured.minCharCountMissing": "Validation mal configurée : le paramètre minCharCount est absent",
25
+ "action.notAvailable": "Cette action n'est pas disponible. Veuillez contacter le support.",
26
+ "action.denied": "Vous n'avez pas l'autorisation d'effectuer cette action.",
27
+ "action.permissionsLoading": "Les autorisations sont encore en cours de chargement. Veuillez réessayer.",
28
+ "screen.denied": "Vous n'avez pas l'autorisation de consulter cet écran.",
29
+ "screen.loadError": "Une erreur s'est produite lors du chargement de cet écran.",
30
+ "screen.oops": "Oups !",
31
+ "screen.notFoundTitle": "404 - PAGE INTROUVABLE",
32
+ "screen.notFoundDescription": "La page que vous recherchez a peut-être été supprimée, renommée ou est temporairement indisponible.",
33
+ "screen.unexpectedError": "Une erreur inattendue s'est produite.",
34
+ "locale.label": "Langue",
35
+ "http.GET.200": "Récupération réussie",
36
+ "http.GET.204": "Aucun contenu",
37
+ "http.GET.400": "Requête incorrecte",
38
+ "http.GET.401": "Non autorisé",
39
+ "http.GET.404": "Entité introuvable",
40
+ "http.GET.415": "Type de média non pris en charge",
41
+ "http.GET.500": "Erreur",
42
+ "http.POST.201": "Création réussie",
43
+ "http.POST.204": "Aucun contenu",
44
+ "http.POST.400": "Requête incorrecte",
45
+ "http.POST.401": "Non autorisé",
46
+ "http.POST.409": "Entrée en double",
47
+ "http.POST.415": "Type de média non pris en charge",
48
+ "http.POST.422": "Erreur de validation",
49
+ "http.POST.500": "Erreur",
50
+ "http.PUT.201": "Mise à jour réussie",
51
+ "http.PUT.204": "Aucun contenu",
52
+ "http.PUT.400": "Requête incorrecte",
53
+ "http.PUT.401": "Non autorisé",
54
+ "http.PUT.404": "Entité introuvable",
55
+ "http.PUT.409": "Entrée en double",
56
+ "http.PUT.415": "Type de média non pris en charge",
57
+ "http.PUT.422": "Erreur de validation",
58
+ "http.PUT.500": "Erreur",
59
+ "http.PATCH.201": "Mise à jour réussie",
60
+ "http.PATCH.204": "Aucun contenu",
61
+ "http.PATCH.400": "Requête incorrecte",
62
+ "http.PATCH.401": "Non autorisé",
63
+ "http.PATCH.404": "Entité introuvable",
64
+ "http.PATCH.409": "Entrée en double",
65
+ "http.PATCH.415": "Type de média non pris en charge",
66
+ "http.PATCH.422": "Erreur de validation",
67
+ "http.PATCH.500": "Erreur",
68
+ "http.DELETE.200": "Suppression réussie",
69
+ "http.DELETE.204": "Aucun contenu",
70
+ "http.DELETE.401": "Non autorisé",
71
+ "http.DELETE.404": "Entité introuvable",
72
+ "http.DELETE.409": "Entrée en double",
73
+ "http.DELETE.415": "Type de média non pris en charge",
74
+ "http.DELETE.422": "Erreur de validation",
75
+ "http.DELETE.500": "Erreur"
76
+ }
@@ -0,0 +1,181 @@
1
+ {
2
+ "grid.noRecords": "Aucun enregistrement disponible",
3
+ "grid.groupPanelEmpty": "Faites glisser un en-tête de colonne ici pour grouper par cette colonne",
4
+ "grid.groupExpand": "Développer le groupe",
5
+ "grid.groupCollapse": "Réduire le groupe",
6
+ "grid.detailExpand": "Développer la ligne de détail",
7
+ "grid.detailCollapse": "Réduire la ligne de détail",
8
+ "grid.filterApplyButton": "Appliquer",
9
+ "grid.filterClearButton": "Effacer",
10
+ "grid.filterClearAllButton": "Effacer tous les filtres",
11
+ "grid.filterResetButton": "Réinitialiser",
12
+ "grid.filterSubmitButton": "Filtrer",
13
+ "grid.filterTitle": "Filtre",
14
+ "grid.filterAriaLabel": "Filtre",
15
+ "grid.filterChooseOperator": "Choisir un opérateur",
16
+ "grid.filterSelectAll": "Tout sélectionner",
17
+ "grid.filterCheckAll": "Tout cocher",
18
+ "grid.filterEqOperator": "Est égal à",
19
+ "grid.filterNotEqOperator": "Est différent de",
20
+ "grid.filterIsNullOperator": "Est nul",
21
+ "grid.filterIsNotNullOperator": "N'est pas nul",
22
+ "grid.filterIsEmptyOperator": "Est vide",
23
+ "grid.filterIsNotEmptyOperator": "N'est pas vide",
24
+ "grid.filterStartsWithOperator": "Commence par",
25
+ "grid.filterContainsOperator": "Contient",
26
+ "grid.filterNotContainsOperator": "Ne contient pas",
27
+ "grid.filterEndsWithOperator": "Se termine par",
28
+ "grid.filterGteOperator": "Est supérieur ou égal à",
29
+ "grid.filterGtOperator": "Est supérieur à",
30
+ "grid.filterLteOperator": "Est inférieur ou égal à",
31
+ "grid.filterLtOperator": "Est inférieur à",
32
+ "grid.filterIsTrue": "Est vrai",
33
+ "grid.filterIsFalse": "Est faux",
34
+ "grid.filterBooleanAll": "(Tous)",
35
+ "grid.filterAfterOrEqualOperator": "Est postérieur ou égal à",
36
+ "grid.filterAfterOperator": "Est postérieur à",
37
+ "grid.filterBeforeOperator": "Est antérieur à",
38
+ "grid.filterBeforeOrEqualOperator": "Est antérieur ou égal à",
39
+ "grid.filterAndLogic": "Et",
40
+ "grid.filterOrLogic": "Ou",
41
+ "grid.sortAscending": "Tri croissant",
42
+ "grid.sortDescending": "Tri décroissant",
43
+ "grid.sortAriaLabel": "Triable",
44
+ "grid.groupPanelAriaLabel": "Panneau de regroupement",
45
+ "grid.gridAriaLabel": "Tableau",
46
+ "grid.selectRow": "Sélectionner la ligne",
47
+ "grid.columnMenu": "Menu de colonne",
48
+ "grid.searchPlaceholder": "Rechercher",
49
+ "grid.searchboxPlaceholder": "Rechercher...",
50
+ "grid.pagerItemsPerPage": "éléments par page",
51
+ "grid.pagerInfo": "{0} - {1} sur {2} éléments",
52
+ "grid.pagerFirstPage": "Aller à la première page",
53
+ "grid.pagerPreviousPage": "Aller à la page précédente",
54
+ "grid.pagerNextPage": "Aller à la page suivante",
55
+ "grid.pagerLastPage": "Aller à la dernière page",
56
+ "grid.pagerPage": "Page",
57
+ "grid.pagerOf": "sur",
58
+ "grid.pagerPageSizeAriaLabel": "Taille de page",
59
+ "grid.pagerPageNumberLabel": "Saisir un numéro de page",
60
+ "grid.pagerMoreButtonLabel": "Plus de pages",
61
+ "pager.itemsPerPage": "éléments par page",
62
+ "pager.pageSelection": "Sélectionner la page",
63
+ "pager.info": "{0} - {1} sur {2} éléments",
64
+ "pager.firstPage": "Aller à la première page",
65
+ "pager.previousPage": "Aller à la page précédente",
66
+ "pager.nextPage": "Aller à la page suivante",
67
+ "pager.lastPage": "Aller à la dernière page",
68
+ "pager.page": "Page",
69
+ "pager.of": "sur",
70
+ "pager.pageLabel": "Page",
71
+ "pager.ariaLabel": "Pagination",
72
+ "pager.pageSizeAriaLabel": "Taille de page",
73
+ "pager.mobileSelect": "Sélectionner",
74
+ "pager.moreButtonLabel": "Plus de pages",
75
+ "pager.pageNumberLabel": "Saisir un numéro de page",
76
+ "sort.ariaLabel": "Triable",
77
+ "filter.ariaLabel": "Filtre",
78
+ "filter.eqOperator": "Est égal à",
79
+ "filter.notEqOperator": "Est différent de",
80
+ "filter.isNullOperator": "Est nul",
81
+ "filter.isNotNullOperator": "N'est pas nul",
82
+ "filter.isEmptyOperator": "Est vide",
83
+ "filter.isNotEmptyOperator": "N'est pas vide",
84
+ "filter.startsWithOperator": "Commence par",
85
+ "filter.containsOperator": "Contient",
86
+ "filter.notContainsOperator": "Ne contient pas",
87
+ "filter.endsWithOperator": "Se termine par",
88
+ "filter.gteOperator": "Est supérieur ou égal à",
89
+ "filter.gtOperator": "Est supérieur à",
90
+ "filter.lteOperator": "Est inférieur ou égal à",
91
+ "filter.ltOperator": "Est inférieur à",
92
+ "filter.isTrue": "Est vrai",
93
+ "filter.isFalse": "Est faux",
94
+ "filter.afterOrEqualOperator": "Est postérieur ou égal à",
95
+ "filter.afterOperator": "Est postérieur à",
96
+ "filter.beforeOperator": "Est antérieur à",
97
+ "filter.beforeOrEqualOperator": "Est antérieur ou égal à",
98
+ "filter.andLogic": "Et",
99
+ "filter.orLogic": "Ou",
100
+ "calendar.today": "Aujourd'hui",
101
+ "calendar.titleAriaLabel": "Aller à la vue parente :",
102
+ "datepicker.toggleCalendar": "Afficher/masquer le calendrier",
103
+ "datepicker.selectDate": "Sélectionner une date",
104
+ "dateinput.increment": "Augmenter la valeur",
105
+ "dateinput.decrement": "Diminuer la valeur",
106
+ "dateinput.clear": "effacer",
107
+ "multiviewcalendar.prevView": "Aller à la vue précédente",
108
+ "multiviewcalendar.nextView": "Aller à la vue suivante",
109
+ "timepicker.now": "MAINTENANT",
110
+ "timepicker.set": "Définir",
111
+ "timepicker.cancel": "Annuler",
112
+ "timepicker.selectNow": "Sélectionner l'heure actuelle",
113
+ "timepicker.toggleTimeSelector": "Afficher/masquer le sélecteur d'heure",
114
+ "timepicker.toggleClock": "Afficher/masquer l'horloge",
115
+ "timepicker.selectTime": "Sélectionner une heure",
116
+ "datetimepicker.date": "Date",
117
+ "datetimepicker.time": "Heure",
118
+ "datetimepicker.cancel": "Annuler",
119
+ "datetimepicker.set": "Définir",
120
+ "datetimepicker.toggleDateTimeSelector": "Afficher/masquer le sélecteur de date et d'heure",
121
+ "datetimepicker.selectDateAndTime": "Sélectionner la date et l'heure",
122
+ "daterangepicker.cancel": "Annuler",
123
+ "daterangepicker.set": "Définir",
124
+ "daterangepicker.start": "Début",
125
+ "daterangepicker.end": "Fin",
126
+ "daterangepicker.selectStartDate": "Date de début",
127
+ "daterangepicker.selectEndDate": "Date de fin",
128
+ "daterangepicker.swapStartEnd": "Inverser les valeurs de début et de fin",
129
+ "dropdowns.clear": "effacer",
130
+ "dropdowns.nodata": "AUCUNE DONNÉE TROUVÉE.",
131
+ "dropdowns.dropDownListArrowBtnAriaLabel": "sélectionner",
132
+ "dropdowns.dropDownListAdaptiveFilterPlaceholder": "Filtrer",
133
+ "dropdowns.listFilterAriaLabel": "Rechercher",
134
+ "dropdowns.autoCompleteListAriaLabel": "Suggestions",
135
+ "dropdowns.listAriaLabel": "Options",
136
+ "dropdowns.selectAllText": "Tout sélectionner",
137
+ "dropdowns.itemsSelectedText": "{0} éléments sélectionnés",
138
+ "dropdowns.summaryTagText": "+{0} de plus",
139
+ "dropdowns.comboArrowBtnAriaLabelExpand": "développer la liste déroulante",
140
+ "dropdowns.comboArrowBtnAriaLabelCollapse": "réduire la liste déroulante",
141
+ "upload.cancel": "Annuler",
142
+ "upload.clearSelectedFiles": "Effacer",
143
+ "upload.dropFilesHere": "Déposez les fichiers ici pour les téléverser",
144
+ "upload.dropZoneHint": "Glissez-déposez les fichiers ici pour les téléverser.",
145
+ "upload.headerStatusUploaded": "Terminé",
146
+ "upload.headerStatusUploading": "Téléversement...",
147
+ "upload.invalidFileExtension": "Type de fichier non autorisé.",
148
+ "upload.invalidFiles": "Fichier(s) invalide(s). Veuillez vérifier les conditions de téléversement.",
149
+ "upload.invalidMaxFileSize": "Fichier trop volumineux.",
150
+ "upload.invalidMinFileSize": "Fichier trop petit.",
151
+ "upload.remove": "Retirer",
152
+ "upload.retry": "Réessayer",
153
+ "upload.select": "Sélectionner des fichiers...",
154
+ "upload.selectTitle": "Appuyez pour sélectionner d'autres fichiers",
155
+ "upload.selectNoFilesTitle": "Aucun fichier sélectionné",
156
+ "upload.uploadSelectedFiles": "Téléverser",
157
+ "upload.total": "Total",
158
+ "upload.files": "fichiers",
159
+ "upload.statusUploaded": "Fichier(s) téléversé(s) avec succès.",
160
+ "upload.statusUploadFailed": "Échec du téléversement du ou des fichiers.",
161
+ "upload.dropZoneNote": "Seuls {0} fichiers sont autorisés.",
162
+ "dialogs.windowMaximizeButton": "agrandir",
163
+ "dialogs.windowMinimizeButton": "réduire",
164
+ "dialogs.windowRestoreButton": "restaurer",
165
+ "dialogs.windowCloseButton": "fermer",
166
+ "numerictextbox.increment": "Augmenter la valeur",
167
+ "numerictextbox.decrement": "Diminuer la valeur",
168
+ "slider.increment": "Augmenter",
169
+ "slider.decrement": "Diminuer",
170
+ "slider.dragTitle": "Glisser",
171
+ "slider.ariaLabel": "Curseur",
172
+ "switch.ariaLabel": "Basculer la valeur",
173
+ "checkbox.optionalText": "(Facultatif)",
174
+ "rating.ariaLabel": "Note",
175
+ "flatColorPicker.cancelBtn": "Annuler",
176
+ "flatColorPicker.applyBtn": "Appliquer",
177
+ "flatColorPicker.clearBtn": "Effacer la couleur",
178
+ "colorPicker.adaptiveTitle": "Choisir une couleur",
179
+ "colorPicker.ariaLabel": "Sélecteur de couleur",
180
+ "splitButton.toggleDropdown": "Afficher/masquer la liste"
181
+ }
@@ -0,0 +1,169 @@
1
+ {
2
+ "languageSelector.label": "Langue",
3
+ "languageSelector.current": "Langue : {language}",
4
+ "alert.yes": "Oui",
5
+ "alert.no": "Non",
6
+ "alert.ok": "OK",
7
+ "menu.noImage": "Aucune image",
8
+ "tabs.scrollBack": "Faire défiler les onglets vers l'arrière",
9
+ "tabs.scrollForward": "Faire défiler les onglets vers l'avant",
10
+ "stepper.progress": "Progression",
11
+ "stepper.optional": "Facultatif",
12
+ "stepper.stepLabel": "Étape {n}",
13
+ "stepper.needsAttention": ", nécessite votre attention",
14
+ "stepper.completed": ", terminée",
15
+ "toolbar.common.close": "Fermer",
16
+ "toolbar.common.clearSearch": "Effacer la recherche",
17
+ "toolbar.common.searchPlaceholder": "Saisissez votre recherche ici . . .",
18
+ "toolbar.globalSearch.search": "Rechercher",
19
+ "toolbar.advancedSearch.button": "Recherche avancée",
20
+ "toolbar.advancedSearch.filterHeader": "Filtre",
21
+ "toolbar.advancedSearch.operatorHeader": "Opérateur",
22
+ "toolbar.advancedSearch.valueHeader": "Valeur",
23
+ "toolbar.advancedSearch.selectFilter": "Sélectionner un filtre...",
24
+ "toolbar.advancedSearch.selectOperator": "Sélectionner un opérateur...",
25
+ "toolbar.advancedSearch.add": "Ajouter",
26
+ "toolbar.advancedSearch.addRow": "Ajouter une ligne de filtre",
27
+ "toolbar.advancedSearch.remove": "Supprimer",
28
+ "toolbar.advancedSearch.removeRow": "Supprimer cette ligne de filtre",
29
+ "toolbar.advancedSearch.clearFilter": "Effacer le filtre",
30
+ "toolbar.advancedSearch.cancel": "Annuler",
31
+ "toolbar.advancedSearch.applyFilter": "Appliquer le filtre",
32
+ "toolbar.advancedSearch.operators.equal": "Égal à",
33
+ "toolbar.advancedSearch.operators.notEqual": "Différent de",
34
+ "toolbar.advancedSearch.operators.includes": "Contient",
35
+ "toolbar.advancedSearch.operators.notIncludes": "Ne contient pas",
36
+ "toolbar.advancedSearch.operators.isEmpty": "Est vide",
37
+ "toolbar.advancedSearch.operators.isNotEmpty": "N'est pas vide",
38
+ "toolbar.advancedSearch.operators.greaterThan": "Est supérieur à",
39
+ "toolbar.advancedSearch.operators.greaterThanOrEqual": "Est supérieur ou égal à",
40
+ "toolbar.advancedSearch.operators.lessThan": "Est inférieur à",
41
+ "toolbar.advancedSearch.operators.lessThanOrEqual": "Est inférieur ou égal à",
42
+ "toolbar.advancedSearch.operators.between": "Entre",
43
+ "toolbar.advancedSearch.operators.notBetween": "Pas entre",
44
+ "toolbar.advancedSearch.operators.inList": "Dans la liste",
45
+ "toolbar.advancedSearch.operators.notInList": "Pas dans la liste",
46
+ "toolbar.advancedSearch.value.selectValues": "Sélectionner des valeurs",
47
+ "toolbar.advancedSearch.value.selectValue": "Sélectionner une valeur...",
48
+ "toolbar.advancedSearch.value.typeValue": "Saisir une valeur...",
49
+ "toolbar.advancedSearch.value.from": "De",
50
+ "toolbar.advancedSearch.value.to": "À",
51
+ "toolbar.advancedSearch.value.true": "Vrai",
52
+ "toolbar.advancedSearch.value.false": "Faux",
53
+ "toolbar.advancedSearch.rowError.chooseFilter": "Choisissez un filtre pour cette ligne.",
54
+ "toolbar.advancedSearch.rowError.chooseOperator": "Choisissez un opérateur pour cette ligne.",
55
+ "toolbar.advancedSearch.rowError.enterValue": "Saisissez une valeur pour cette ligne.",
56
+ "toolbar.advancedSearch.criteria.label": "Critères de correspondance",
57
+ "toolbar.advancedSearch.criteria.reset": "Réinitialiser aux lignes ci-dessus",
58
+ "toolbar.advancedSearch.criteria.copy": "Copier l'expression",
59
+ "toolbar.advancedSearch.criteria.hint": "Reliez les lignes ci-dessus avec AND / OR et groupez-les avec des parenthèses — ((1) OR (2)) AND (3).",
60
+ "toolbar.advancedSearch.criteria.errors.empty": "Saisissez une expression de critères — par exemple {example}.",
61
+ "toolbar.advancedSearch.criteria.errors.stray": "\"{token}\" ne fait pas partie d'une expression de critères. Utilisez des jetons de ligne comme {row} reliés par AND ou OR.",
62
+ "toolbar.advancedSearch.criteria.errors.incomplete": "L'expression de critères est incomplète — elle se termine là où une ligne était attendue.",
63
+ "toolbar.advancedSearch.criteria.errors.bareNumber": "Mettez les numéros de ligne entre parenthèses — écrivez ({number}), pas {number}.",
64
+ "toolbar.advancedSearch.criteria.errors.logicNeedsRows": "\"{operator}\" doit avoir une ligne de chaque côté.",
65
+ "toolbar.advancedSearch.criteria.errors.unmatchedClose": "\")\" sans correspondance dans l'expression de critères.",
66
+ "toolbar.advancedSearch.criteria.errors.unclosedOpen": "\"(\" non fermée dans l'expression de critères.",
67
+ "toolbar.advancedSearch.criteria.errors.leftover": "\"{token}\" reste en trop à la fin de l'expression de critères.",
68
+ "toolbar.advancedSearch.criteria.errors.outOfRangeSingle": "({row}) n'est pas une ligne de filtre — ce filtre n'a qu'une ligne, {first}.",
69
+ "toolbar.advancedSearch.criteria.errors.outOfRange": "({row}) n'est pas une ligne de filtre — utilisez {first} à {last}.",
70
+ "toolbar.advancedSearch.criteria.errors.duplicate": "({row}) est utilisée plus d'une fois — nommez chaque ligne de filtre exactement une fois.",
71
+ "toolbar.advancedSearch.criteria.errors.missing_one": "{rows} manque dans les critères — chaque ligne de filtre doit être utilisée, ou supprimée.",
72
+ "toolbar.advancedSearch.criteria.errors.missing_other": "{rows} manquent dans les critères — chaque ligne de filtre doit être utilisée, ou supprimée.",
73
+ "toolbar.export.button": "Exporter",
74
+ "toolbar.export.headerList": "Liste des en-têtes",
75
+ "toolbar.export.optionTitle": "{type} - {scope}",
76
+ "toolbar.export.previousExports": "Exports précédents",
77
+ "toolbar.export.download": "Télécharger",
78
+ "toolbar.export.downloadAria": "Télécharger l'export",
79
+ "toolbar.export.failed": "Échec",
80
+ "toolbar.export.failedAria": "Échec de l'export",
81
+ "toolbar.export.inProcess": "En cours",
82
+ "toolbar.export.inProcessAria": "Export en cours",
83
+ "toolbar.export.delete": "Supprimer",
84
+ "toolbar.export.deleteAria": "Supprimer l'export",
85
+ "toolbar.groupBy.button": "Grouper par",
86
+ "toolbar.groupBy.popupTitle": "Sélectionner un ou plusieurs groupes",
87
+ "toolbar.groupBy.label": "Grouper par",
88
+ "toolbar.groupBy.placeholder": "Sélectionner un groupe",
89
+ "toolbar.groupBy.saveAndContinue": "Enregistrer et continuer",
90
+ "toolbar.quickFilter.button": "Filtre rapide",
91
+ "toolbar.quickFilter.filter": "Filtre",
92
+ "toolbar.quickFilter.select": "Sélectionner...",
93
+ "toolbar.reset.button": "Réinitialiser",
94
+ "toolbar.setting.button": "Paramètres",
95
+ "toolbar.setting.columnChooser": "Sélecteur de colonnes",
96
+ "toolbar.setting.changeToGrid": "Passer en vue grille",
97
+ "toolbar.setting.changeToCard": "Passer en vue cartes",
98
+ "toolbar.columnChooser.restore": "Restaurer",
99
+ "toolbar.columnChooser.apply": "Appliquer",
100
+ "toolbar.columnChooser.searchColumns": "Rechercher des colonnes",
101
+ "toolbar.columnChooser.noFieldsFound": "Aucun champ trouvé",
102
+ "toolbar.columnChooser.selectedCount_one": "{count} colonne sélectionnée",
103
+ "toolbar.columnChooser.selectedCount_other": "{count} colonnes sélectionnées",
104
+ "toolbar.columnChooser.noneSelected": "Aucun champ sélectionné",
105
+ "toolbar.columnChooser.includeInCard": "Inclure dans la carte",
106
+ "toolbar.columnChooser.freeze": "Figer",
107
+ "toolbar.columnChooser.removeColumn": "Retirer la colonne",
108
+ "toolbar.views.systemDefault": "Par défaut (système)",
109
+ "toolbar.views.selectView": "Sélectionner une vue",
110
+ "toolbar.views.unsavedChanges": "Modifications non enregistrées",
111
+ "toolbar.views.createView": "+ Créer une vue",
112
+ "toolbar.views.deleteTitle": "Supprimer la vue",
113
+ "toolbar.views.deleteConfirm": "Voulez-vous vraiment supprimer \"{name}\" ?",
114
+ "toolbar.views.deleteBody": "Cette action est irréversible.",
115
+ "toolbar.views.edit": "Modifier",
116
+ "toolbar.views.renameAria": "Renommer la vue",
117
+ "toolbar.views.delete": "Supprimer",
118
+ "toolbar.views.deleteAria": "Supprimer la vue",
119
+ "toolbar.views.save": "Enregistrer",
120
+ "toolbar.views.saveAria": "Enregistrer la vue",
121
+ "toolbar.views.default": "Par défaut",
122
+ "toolbar.views.setDefault": "Définir par défaut",
123
+ "toolbar.views.setDefaultAria": "Définir comme vue par défaut",
124
+ "toolbar.views.createTitle": "Créer une nouvelle vue",
125
+ "toolbar.views.editTitle": "Modifier la vue",
126
+ "toolbar.views.viewName": "Nom de la vue",
127
+ "toolbar.views.namePlaceholder": "Saisissez ici...",
128
+ "toolbar.views.startWith": "Commencer avec",
129
+ "toolbar.views.startWithAria": "Commencer avec",
130
+ "toolbar.views.copyFrom": "Copier depuis",
131
+ "toolbar.views.create": "Créer",
132
+ "toolbar.views.loadingSummary": "Chargement de la configuration de la vue…",
133
+ "toolbar.views.currentEmpty": "Seule la configuration par défaut de l'écran est appliquée pour le moment — c'est elle qui sera enregistrée",
134
+ "toolbar.views.copyEmpty": "Cette vue n'a encore rien d'enregistré — la nouvelle vue partira de la configuration par défaut",
135
+ "toolbar.views.willBeSaved": "Sera enregistré",
136
+ "toolbar.views.source.currentLabel": "Configuration actuelle",
137
+ "toolbar.views.source.currentHint": "Crée la vue et enregistre tout ce qui est appliqué en ce moment — vos modifications et les valeurs par défaut de l'écran",
138
+ "toolbar.views.source.defaultLabel": "Configuration par défaut",
139
+ "toolbar.views.source.defaultHint": "Crée une vue vide qui s'ouvre sur la configuration par défaut de l'écran",
140
+ "toolbar.views.source.copyLabel": "Copier une vue existante",
141
+ "toolbar.views.source.copyHint": "Crée la vue avec la configuration enregistrée d'une autre vue",
142
+ "toolbar.views.nameError.required": "Obligatoire",
143
+ "toolbar.views.nameError.tooLong": "{max} caractères maximum",
144
+ "toolbar.views.errors.duplicateName": "Un écran portant le même nom existe déjà. Veuillez choisir un autre nom.",
145
+ "toolbar.views.errors.createWithConfigFailed": "La vue n'a pas pu être créée avec la configuration sélectionnée. Veuillez réessayer.",
146
+ "toolbar.views.errors.createFailed": "Une erreur inattendue s'est produite lors de la création de l'écran.",
147
+ "toolbar.views.errors.renameFailed": "Une erreur inattendue s'est produite lors du renommage de l'écran.",
148
+ "toolbar.views.summary.search": "Recherche \"{query}\"",
149
+ "toolbar.views.summary.advancedFilters_one": "{count} filtre avancé",
150
+ "toolbar.views.summary.advancedFilters_other": "{count} filtres avancés",
151
+ "toolbar.views.summary.quickFilters_one": "{count} filtre rapide",
152
+ "toolbar.views.summary.quickFilters_other": "{count} filtres rapides",
153
+ "toolbar.views.summary.columnFilters_one": "{count} filtre de colonne",
154
+ "toolbar.views.summary.columnFilters_other": "{count} filtres de colonne",
155
+ "toolbar.views.summary.columns_one": "{count} colonne",
156
+ "toolbar.views.summary.columns_other": "{count} colonnes",
157
+ "toolbar.views.summary.sortedBy_one": "Trié par {count} champ",
158
+ "toolbar.views.summary.sortedBy_other": "Trié par {count} champs",
159
+ "toolbar.views.summary.groupedByCount_one": "Groupé par {count} champ",
160
+ "toolbar.views.summary.groupedByCount_other": "Groupé par {count} champs",
161
+ "toolbar.views.summary.groupedBy": "Groupé par {name}",
162
+ "toolbar.views.summary.groupedByMore": "Groupé par {name} +{more}",
163
+ "toolbar.views.summary.widgetDefault": "{summary} (valeur par défaut du widget)",
164
+ "toolbar.views.summary.gridView": "Vue grille",
165
+ "toolbar.views.summary.cardView": "Vue cartes",
166
+ "toolbar.views.summary.allRowsPerPage": "Toutes les lignes par page",
167
+ "toolbar.views.summary.rowsPerPage_one": "{count} ligne par page",
168
+ "toolbar.views.summary.rowsPerPage_other": "{count} lignes par page"
169
+ }