@tekkare/romulus 0.1.184 → 0.1.186
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.
package/dist/module.json
CHANGED
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
voudrait dire autant de requetes et autant de references sur le meme jeu
|
|
15
15
|
de documents, et plusieurs messages le meme matin pour le meme produit ;
|
|
16
16
|
- la cadence appartient au mail. La pastille de l'app encaisse au fil de
|
|
17
|
-
l'eau, elle n'a pas de digest
|
|
17
|
+
l'eau, elle n'a pas de digest ;
|
|
18
|
+
- une alerte de produit ne choisit ni champs ni declencheurs : ils sont deja
|
|
19
|
+
forces a « tout » (cf. `watchesProduct`), le formulaire ne fait que les
|
|
20
|
+
cacher. Choisir « seulement l'apparition » sur une marque suivie partout
|
|
21
|
+
ferait manquer un dereboursement.
|
|
18
22
|
-->
|
|
19
23
|
<script setup lang="ts">
|
|
20
24
|
import { computed, ref, watch } from 'vue'
|
|
@@ -103,20 +107,27 @@ const emit = defineEmits<{
|
|
|
103
107
|
'select-view': [id: string]
|
|
104
108
|
/** Saisie du selecteur de marques, a porter jusqu'a l'index. */
|
|
105
109
|
'search-brands': [value: string]
|
|
110
|
+
/**
|
|
111
|
+
* Le formulaire s'ecarte de sa reference de depart. L'appelant n'a pas
|
|
112
|
+
* acces aux refs internes (titre, marques, declencheurs...) : c'est le
|
|
113
|
+
* seul moyen pour lui de savoir s'il y a quelque chose a perdre avant de
|
|
114
|
+
* fermer.
|
|
115
|
+
*/
|
|
116
|
+
'update:dirty': [value: boolean]
|
|
106
117
|
}>()
|
|
107
118
|
|
|
108
119
|
const FR = {
|
|
109
120
|
kind: 'Que surveiller',
|
|
110
121
|
kindView: 'Une vue',
|
|
111
122
|
kindViewHint: 'Un écran filtré, aussi fin que vous voulez, mais limité à cette page.',
|
|
112
|
-
kindProduct: '
|
|
123
|
+
kindProduct: 'Alerte 360°',
|
|
113
124
|
kindProductHint: 'Une à {max} marques, suivies partout : prix, avis HAS, indications, ANSM, PUT, MITM, Journal officiel, ventes ville et hospitalières.',
|
|
114
125
|
brands: 'Marques surveillées',
|
|
115
126
|
brandsSearch: 'Rechercher',
|
|
116
127
|
brandsHint: 'Cherchez par marque, molécule, classe ATC ou laboratoire. L’alerte couvre tout le hub pour chaque marque retenue.',
|
|
117
128
|
brandsRequired: 'Choisissez au moins une marque.',
|
|
118
129
|
brandsTooMany: 'Une alerte suit {max} marques au maximum.',
|
|
119
|
-
productFields: '
|
|
130
|
+
productFields: 'Rien à choisir : une alerte de marque suit tout, tous champs et tous déclencheurs confondus (nouvel élément, changement de valeur, sortie du périmètre).',
|
|
120
131
|
screenOption: 'Écran actuel (une vue sera créée)',
|
|
121
132
|
viewSelect: 'Vue à surveiller',
|
|
122
133
|
viewApplied: 'La vue choisie est appliquée à l’écran : c’est lui qui fournit la requête surveillée.',
|
|
@@ -162,14 +173,14 @@ const EN = {
|
|
|
162
173
|
kind: 'What to watch',
|
|
163
174
|
kindView: 'A view',
|
|
164
175
|
kindViewHint: 'A filtered screen, as precise as you like, but tied to that page.',
|
|
165
|
-
kindProduct: '
|
|
176
|
+
kindProduct: '360° alert',
|
|
166
177
|
kindProductHint: 'One to {max} brands, watched everywhere: prices, HAS opinions, indications, ANSM, PUT, MITM, official journal, retail and hospital sales.',
|
|
167
178
|
brands: 'Watched brands',
|
|
168
179
|
brandsSearch: 'Search',
|
|
169
180
|
brandsHint: 'Search by brand, molecule, ATC class or company. The alert covers the whole hub for each brand kept.',
|
|
170
181
|
brandsRequired: 'Pick at least one brand.',
|
|
171
182
|
brandsTooMany: 'An alert watches at most {max} brands.',
|
|
172
|
-
productFields: '
|
|
183
|
+
productFields: 'Nothing to choose: a brand alert watches everything, every field and every trigger (new item, value change, left the scope).',
|
|
173
184
|
screenOption: 'Current screen (a view will be created)',
|
|
174
185
|
viewSelect: 'View to watch',
|
|
175
186
|
viewApplied: 'The chosen view is applied to the screen: the screen is what provides the watched query.',
|
|
@@ -249,7 +260,19 @@ watch(brandSearch, (value) => emit('search-brands', value))
|
|
|
249
260
|
const watchesProduct = computed(() => kind.value === 'product')
|
|
250
261
|
|
|
251
262
|
const title = ref(props.initial?.title ?? props.viewTitle)
|
|
252
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Une alerte de produit suit tout, declencheurs compris : le choix ne se pose
|
|
265
|
+
* pas plus que celui des champs, et cocher que « nouvel element » laisserait
|
|
266
|
+
* croire qu'un changement de prix sur une marque deja suivie ne compte pas.
|
|
267
|
+
*/
|
|
268
|
+
const ALL_TRIGGERS: RmAlertTrigger[] = ['appeared', 'changed', 'disappeared']
|
|
269
|
+
const triggers = ref<RmAlertTrigger[]>(
|
|
270
|
+
props.initial?.triggers ??
|
|
271
|
+
(kind.value === 'product' ? ALL_TRIGGERS : ['appeared']),
|
|
272
|
+
)
|
|
273
|
+
watch(kind, (value) => {
|
|
274
|
+
if (value === 'product') triggers.value = ALL_TRIGGERS
|
|
275
|
+
})
|
|
253
276
|
const watchedFields = ref<string[]>(
|
|
254
277
|
(props.initial?.watchedFields ?? []).filter((field) => field !== RM_ALERT_ANY_FIELD),
|
|
255
278
|
)
|
|
@@ -264,6 +287,37 @@ const initialFields = JSON.stringify([...(props.initial?.watchedFields ?? [])].s
|
|
|
264
287
|
/** Titre libre des que l'utilisateur y touche : on ne l'ecrase plus. */
|
|
265
288
|
const titleTouched = ref(props.mode === 'edit')
|
|
266
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Etat de depart, capture une seule fois : ce a quoi `dirty` compare le
|
|
292
|
+
* formulaire. Le titre n'y figure pas, il se suit par `titleTouched` (il
|
|
293
|
+
* bouge tout seul tant que l'utilisateur n'y a pas touche, cf. plus bas).
|
|
294
|
+
*/
|
|
295
|
+
const baseline = {
|
|
296
|
+
kind: kind.value,
|
|
297
|
+
brands: JSON.stringify([...brands.value].sort()),
|
|
298
|
+
triggers: JSON.stringify([...triggers.value].sort()),
|
|
299
|
+
watchedFields: JSON.stringify([...watchedFields.value].sort()),
|
|
300
|
+
anyField: anyField.value,
|
|
301
|
+
emailOn: emailOn.value,
|
|
302
|
+
cadence: cadence.value,
|
|
303
|
+
selectedViewId: selectedViewId.value,
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const dirty = computed(
|
|
307
|
+
() =>
|
|
308
|
+
titleTouched.value ||
|
|
309
|
+
kind.value !== baseline.kind ||
|
|
310
|
+
JSON.stringify([...brands.value].sort()) !== baseline.brands ||
|
|
311
|
+
JSON.stringify([...triggers.value].sort()) !== baseline.triggers ||
|
|
312
|
+
JSON.stringify([...watchedFields.value].sort()) !== baseline.watchedFields ||
|
|
313
|
+
anyField.value !== baseline.anyField ||
|
|
314
|
+
emailOn.value !== baseline.emailOn ||
|
|
315
|
+
cadence.value !== baseline.cadence ||
|
|
316
|
+
selectedViewId.value !== baseline.selectedViewId,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
watch(dirty, (value) => emit('update:dirty', value), { immediate: true })
|
|
320
|
+
|
|
267
321
|
watch(
|
|
268
322
|
() => props.viewTitle,
|
|
269
323
|
(value) => {
|
|
@@ -495,7 +549,7 @@ function submit() {
|
|
|
495
549
|
{{ watchesProduct ? `${T.brands} : ${brands.join(', ')}` : `${T.view} : ${viewTitle}` }}
|
|
496
550
|
</p>
|
|
497
551
|
|
|
498
|
-
<fieldset class="rm-alert-form__group" data-field="triggers">
|
|
552
|
+
<fieldset v-if="!watchesProduct" class="rm-alert-form__group" data-field="triggers">
|
|
499
553
|
<legend class="rm-alert-form__label">{{ T.triggers }}</legend>
|
|
500
554
|
<p class="rm-alert-form__hint">{{ T.triggersHint }}</p>
|
|
501
555
|
<RmCheckbox
|
|
@@ -512,7 +566,7 @@ function submit() {
|
|
|
512
566
|
/>
|
|
513
567
|
</fieldset>
|
|
514
568
|
|
|
515
|
-
<p v-if="watchesProduct
|
|
569
|
+
<p v-if="watchesProduct" class="rm-alert-form__hint">
|
|
516
570
|
{{ T.productFields }}
|
|
517
571
|
</p>
|
|
518
572
|
|