@tekkare/romulus 0.1.243 → 0.1.244

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 (33) hide show
  1. package/dist/module.json +1 -1
  2. package/layer/app/components/layout/alertBrandSync.vue +143 -0
  3. package/layer/app/components/layout/tool/adminTemplates.vue +261 -0
  4. package/layer/app/components/layout/tool/alerts.vue +969 -0
  5. package/layer/app/components/layout/tool/export.vue +590 -0
  6. package/layer/app/components/layout/tool/views.vue +933 -0
  7. package/layer/app/components/layout/viewEmptyState.vue +278 -0
  8. package/layer/app/components/layout/viewPill.vue +550 -0
  9. package/layer/app/composables/useAdminAccess.ts +86 -0
  10. package/layer/app/composables/useAlertBrandSync.ts +85 -0
  11. package/layer/app/composables/useAlertSource.ts +210 -0
  12. package/layer/app/composables/useAlerts.ts +345 -0
  13. package/layer/app/composables/useExportSource.ts +236 -0
  14. package/layer/app/composables/useHubrEmbedded.ts +13 -0
  15. package/layer/app/composables/usePermalink.ts +108 -0
  16. package/layer/app/composables/useSavedExports.ts +286 -0
  17. package/layer/app/composables/useViewCardActions.ts +500 -0
  18. package/layer/app/composables/useViewTemplates.ts +369 -0
  19. package/layer/app/composables/useViews.ts +574 -0
  20. package/layer/app/oip-defaults/alerts.ts +34 -0
  21. package/layer/app/oip-defaults/api.ts +18 -0
  22. package/layer/app/oip-defaults/export.ts +23 -0
  23. package/layer/app/oip-defaults/ui.ts +21 -0
  24. package/layer/app/oip-defaults/views.ts +59 -0
  25. package/layer/app/utils/alertFieldLabels.ts +191 -0
  26. package/layer/app/utils/oipScopeStore.ts +112 -0
  27. package/layer/app/utils/oipScopes.ts +376 -0
  28. package/layer/app/utils/viewPages.ts +30 -0
  29. package/layer/app/utils/viewTemplateCriteria.ts +215 -0
  30. package/layer/app/utils/viewTemplates.ts +116 -0
  31. package/layer/nuxt.config.ts +9 -0
  32. package/layer/server/api/oip/notes.get.ts +1 -1
  33. package/package.json +3 -2
@@ -0,0 +1,116 @@
1
+ /**
2
+ * viewTemplates - les vues prêtes a l'emploi fournies par Tekkare.
3
+ *
4
+ * Un template est une vue que personne n'a enregistree : un jeu de criteres
5
+ * ecrit ici, applique comme une vue temporaire (sans identifiant, cf.
6
+ * `isTemporaryView`). L'utilisateur le demarre, le retouche, et l'enregistre
7
+ * dans ses vues s'il veut le garder. Rien ne part en base tant qu'il ne le
8
+ * demande pas.
9
+ *
10
+ * Les criteres se construisent avec la langue de l'ecran, jamais en dur :
11
+ * - les filtres tapent `status_fr` ou `status_en` selon la locale, et la vue
12
+ * stocke le libelle affiche (« Insuffisant » / « Insufficient ») ;
13
+ * - un filtre booleen (`CheckFilter`) stocke `"<libelle du filtre>: true"`,
14
+ * donc « Oncologie: true » en francais et « Oncology: true » en anglais ;
15
+ * - sur la page Prix, c'est le NOM du filtre qui est traduit.
16
+ * D'ou le contexte `{ lang, t }` passe a chaque `criteria()`.
17
+ *
18
+ * Les valeurs sont celles des index : elles ont ete relevees par agregation,
19
+ * pas devinees (cf. la page projet du vault). Une valeur inventee ne filtre
20
+ * rien et le template ouvre un ecran vide.
21
+ */
22
+
23
+ import { VIEW_TEMPLATES } from "#oip-app/views";
24
+
25
+ export type ViewTemplateTone = "primary" | "success" | "warning" | "danger" | "info";
26
+
27
+ export interface ViewTemplateContext {
28
+ lang: "fr" | "en";
29
+ t: (key: string) => string;
30
+ /**
31
+ * Une cle i18n existe-t-elle. Les templates en dur n'en ont pas besoin
32
+ * (leurs cles sont ecrites ici, donc sures) ; ceux publies depuis l'app,
33
+ * si : ils relisent une cle rangee en base, qu'un renommage a pu perimer.
34
+ */
35
+ te: (key: string) => boolean;
36
+ }
37
+
38
+ /** Un critere de vue. `values` est un tableau, sauf pour la periode. */
39
+ export interface ViewTemplateCriterion {
40
+ filter: string;
41
+ values: string[] | string;
42
+ }
43
+
44
+ export interface ViewTemplate {
45
+ /** Identifiant stable : il sert de cle de carte, jamais d'id de vue. */
46
+ id: string;
47
+ /** Chemin de la page, sans prefixe de langue ni barre finale. */
48
+ page: string;
49
+ /** Icone Phosphor de la pastille. */
50
+ icon: string;
51
+ tone?: ViewTemplateTone;
52
+ title: Record<"fr" | "en", string>;
53
+ description: Record<"fr" | "en", string>;
54
+ criteria: (ctx: ViewTemplateContext) => ViewTemplateCriterion[];
55
+ /**
56
+ * Le template se demarre par un lien profond plutot qu'en posant les
57
+ * criteres a l'ecran.
58
+ *
59
+ * Les pages du portail « Medicaments France » ne portent pas des filtres
60
+ * mais une selection de produits, et personne ne la resout dans la page :
61
+ * c'est le middleware `03.scope-from-query` qui expanse un code ATC en
62
+ * liste de marques, remplit les listes par source (`medicamBrandList`,
63
+ * `susBrandList`...) et pose la vue temporaire. Un template de panier est
64
+ * donc l'URL qui le declenche, ce qui evite d'y figer une liste de marques
65
+ * qui vieillirait a chaque nouvelle AMM.
66
+ */
67
+ deepLink?: boolean;
68
+ /**
69
+ * Publie pour l'espace du lecteur nommement, et non pour tout le monde :
70
+ * la carte le dit (« Créé pour vous »).
71
+ */
72
+ forYou?: boolean;
73
+ }
74
+
75
+ /**
76
+ * Parametre d'URL qui dit de quel template vient le perimetre pose. Le
77
+ * middleware du lien profond le recopie sur la vue temporaire, la pastille de
78
+ * la barre nomme alors le template plutot que de dire « Vue temporaire », et la
79
+ * navigation le garde avec les autres cles de perimetre (cf. useDrugsNav).
80
+ */
81
+ export const VIEW_TEMPLATE_QUERY_PARAM = "template";
82
+
83
+ /**
84
+ * Critere de vue vers parametre d'URL (template en lien profond) et
85
+ * parametres a nettoyer avant d'en poser de nouveaux : metier de l'app, cf.
86
+ * contrat #oip-app/views.
87
+ */
88
+ export { VIEW_TEMPLATE_QUERY_KEYS, VIEW_TEMPLATE_QUERY_RESET } from "#oip-app/views";
89
+
90
+ /**
91
+ * Chemin comparable : sans prefixe de langue (`/en/price`), sans barre finale.
92
+ * Les pages declarent `route.path`, qui porte les deux.
93
+ */
94
+ export function normalizePage(path: string): string {
95
+ return String(path ?? "")
96
+ .replace(/^\/(?:en|fr)(?=\/|$)/, "")
97
+ .replace(/\/$/, "");
98
+ }
99
+
100
+ /**
101
+ * Un template du catalogue par identifiant, quelle que soit sa page : la
102
+ * pastille nomme le template dont vient la vue, et la vue suit le lecteur
103
+ * d'une page du portail a l'autre alors que l'identifiant porte la page de
104
+ * depart.
105
+ */
106
+ export function viewTemplateById(id: string): ViewTemplate | undefined {
107
+ return VIEW_TEMPLATES.find((template) => template.id === id);
108
+ }
109
+
110
+ /** Les templates d'une page, dans l'ordre du catalogue. */
111
+ export function viewTemplatesFor(page: string): ViewTemplate[] {
112
+ const wanted = normalizePage(page);
113
+ return VIEW_TEMPLATES.filter(
114
+ (template) => template.page === wanted,
115
+ );
116
+ }
@@ -8,7 +8,16 @@
8
8
  // pas dans `modules` : l'app les enregistre deja avec ses options (romulus
9
9
  // sans baseStyles, ses locales), et un second enregistrement par le layer
10
10
  // les reinstallerait avec les options par defaut.
11
+ import { fileURLToPath } from "node:url";
12
+
11
13
  export default defineNuxtConfig({
14
+ // Contrat avec l'app pour ce qui lui est propre (client API, bandeau,
15
+ // tables metier des vues et des alertes). Par defaut, les valeurs neutres
16
+ // du layer ; une app pointe `#oip-app` vers son dossier `app/oip` dans son
17
+ // propre nuxt.config, et sa valeur l'emporte.
18
+ alias: {
19
+ "#oip-app": fileURLToPath(new URL("./app/oip-defaults", import.meta.url)),
20
+ },
12
21
  future: {
13
22
  compatibilityVersion: 4,
14
23
  },
@@ -146,7 +146,7 @@ export default defineEventHandler(async (event): Promise<ApiNote[]> => {
146
146
  // tout le portail. Sans sujet de cette app, la note n'est pas la sienne.
147
147
  const paths = (row.linked_subjects ?? [])
148
148
  .map((link) => link.OipSubject_subject_id)
149
- .filter((subject) => appUrls.includes(subject?.app?.prod_url))
149
+ .filter((subject) => appUrls.includes(subject?.app?.prod_url ?? ""))
150
150
  .map((subject) => (subject!.relative_path ?? "").trim())
151
151
  .filter(Boolean);
152
152
  const sources = (row.linked_sources ?? [])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekkare/romulus",
3
- "version": "0.1.243",
3
+ "version": "0.1.244",
4
4
  "description": "Romulus Design System - Nuxt module by Tekkare",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "import": "./dist/runtime/utils/*.js"
19
19
  },
20
20
  "./layer": "./layer/nuxt.config.ts",
21
- "./layer-utils/*": "./layer/app/utils/*.ts"
21
+ "./layer-utils/*": "./layer/app/utils/*.ts",
22
+ "./layer-composables/*": "./layer/app/composables/*.ts"
22
23
  },
23
24
  "main": "./dist/module.cjs",
24
25
  "module": "./dist/module.mjs",