@icure/form 1.1.26 → 2.0.1

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 (43) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/components/common/metadata-buttons-bar.js +66 -15
  3. package/components/common/metadata-buttons-bar.js.map +1 -1
  4. package/components/icure-button/index.js +66 -15
  5. package/components/icure-button/index.js.map +1 -1
  6. package/components/icure-button-group/index.js +66 -15
  7. package/components/icure-button-group/index.js.map +1 -1
  8. package/components/icure-date-picker/index.js +66 -15
  9. package/components/icure-date-picker/index.js.map +1 -1
  10. package/components/icure-dropdown-field/index.js +66 -15
  11. package/components/icure-dropdown-field/index.js.map +1 -1
  12. package/components/icure-form/index.js +66 -15
  13. package/components/icure-form/index.js.map +1 -1
  14. package/components/icure-form/renderer/form/form-selection-button.d.ts +6 -1
  15. package/components/icure-form/renderer/form/form-selection-button.js +1126 -58
  16. package/components/icure-form/renderer/form/form-selection-button.js.map +1 -1
  17. package/components/icure-form/renderer/form/form.js +22 -19
  18. package/components/icure-form/renderer/form/form.js.map +1 -1
  19. package/components/icure-label/index.js +66 -15
  20. package/components/icure-label/index.js.map +1 -1
  21. package/components/icure-text-field/index.js +66 -15
  22. package/components/icure-text-field/index.js.map +1 -1
  23. package/components/model/index.d.ts +7 -1
  24. package/components/model/index.js +47 -3
  25. package/components/model/index.js.map +1 -1
  26. package/components/themes/default/index.js +2 -0
  27. package/components/themes/default/index.js.map +1 -1
  28. package/components/themes/icure-blue/index.js +2 -0
  29. package/components/themes/icure-blue/index.js.map +1 -1
  30. package/components/themes/kendo/index.js +2 -0
  31. package/components/themes/kendo/index.js.map +1 -1
  32. package/generic/model.d.ts +6 -5
  33. package/generic/model.js.map +1 -1
  34. package/icure/form-values-container.d.ts +26 -17
  35. package/icure/form-values-container.js +96 -58
  36. package/icure/form-values-container.js.map +1 -1
  37. package/package.json +1 -1
  38. package/utils/fields-values-provider.d.ts +2 -8
  39. package/utils/fields-values-provider.js +4 -14
  40. package/utils/fields-values-provider.js.map +1 -1
  41. package/utils/form-value-container.d.ts +1 -1
  42. package/utils/form-value-container.js +25 -36
  43. package/utils/form-value-container.js.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import { Contact, Form as ICureForm, Service } from '@icure/api';
2
- import { FormValuesContainer, FormValuesContainerMutation, ID, Version, VersionedData } from '../generic';
2
+ import { FormValuesContainer, Version, VersionedData } from '../generic';
3
3
  import { ServiceMetadata } from './model';
4
4
  import { FieldMetadata, FieldValue, Validator } from '../components/model';
5
5
  /** This class is a bridge between the ICure API and the generic FormValuesContainer interface.
@@ -24,14 +24,16 @@ import { FieldMetadata, FieldValue, Validator } from '../components/model';
24
24
  export declare class BridgedFormValuesContainer implements FormValuesContainer<FieldValue, FieldMetadata> {
25
25
  private responsible;
26
26
  private interpreter?;
27
+ private initialValuesProvider;
27
28
  private dependentValuesProvider;
28
29
  private validatorsProvider;
29
30
  private language;
30
31
  private changeListeners;
31
32
  private contact;
32
33
  private contactFormValuesContainer;
33
- private _children;
34
- get children(): BridgedFormValuesContainer[];
34
+ private _id;
35
+ private mutateAndNotify;
36
+ toString(): string;
35
37
  /**
36
38
  * Creates an instance of BridgedFormValuesContainer.
37
39
  * @param responsible The id of the data owner responsible for the creation of the values
@@ -42,11 +44,12 @@ export declare class BridgedFormValuesContainer implements FormValuesContainer<F
42
44
  * @param validatorsProvider A function that provides the validators for a given anchorId and templateId
43
45
  * @param language The language in which the values are displayed
44
46
  * @param changeListeners The listeners that will be notified when the values change
47
+ * @param initialValuesProvider A lambda that provides the initial values of the form
45
48
  */
46
49
  constructor(responsible: string, contactFormValuesContainer: ContactFormValuesContainer, interpreter?: (<T, S extends {
47
50
  [key: string]: unknown;
48
51
  [key: symbol]: unknown;
49
- }>(formula: string, sandbox: S) => T | undefined) | undefined, contact?: Contact, dependentValuesProvider?: (anchorId: string | undefined, templateId: string) => {
52
+ }>(formula: string, sandbox: S) => T | undefined) | undefined, contact?: Contact, initialValuesProvider?: (fvc: BridgedFormValuesContainer, anchorId?: string, templateId?: string) => [FieldValue, FieldMetadata][], dependentValuesProvider?: (anchorId: string | undefined, templateId: string | undefined) => {
50
53
  metadata: FieldMetadata;
51
54
  formula: string;
52
55
  }[], validatorsProvider?: (anchorId: string | undefined, templateId: string) => {
@@ -60,19 +63,20 @@ export declare class BridgedFormValuesContainer implements FormValuesContainer<F
60
63
  unregisterChangeListener(listener: (newValue: BridgedFormValuesContainer) => void): void;
61
64
  getValues(revisionsFilter: (id: string, history: Version<FieldMetadata>[]) => (string | null)[]): VersionedData<FieldValue>;
62
65
  getMetadata(id: string, revisions: (string | null)[]): VersionedData<FieldMetadata>;
63
- private mutateAndNotify;
66
+ private forceValues;
64
67
  private computeDependentValues;
65
- setValue(label: string, language: string, fv?: FieldValue, id?: string, metadata?: FieldMetadata): FormValuesContainerMutation<FieldValue, FieldMetadata, BridgedFormValuesContainer, ID>;
66
- setMetadata(meta: FieldMetadata, id?: string | undefined): FormValuesContainerMutation<FieldValue, FieldMetadata, BridgedFormValuesContainer, ID>;
67
- delete(serviceId: string): FormValuesContainerMutation<FieldValue, FieldMetadata, BridgedFormValuesContainer, void>;
68
+ setValue(label: string, language: string, fv?: FieldValue, id?: string, metadata?: FieldMetadata): void;
69
+ setMetadata(meta: FieldMetadata, id?: string | undefined): void;
70
+ delete(serviceId: string): void;
68
71
  private getVersionedValuesForKey;
69
72
  compute<T, S extends {
70
73
  [key: string | symbol]: unknown;
71
74
  }>(formula: string, sandbox?: S): T | undefined;
72
75
  getChildren(): FormValuesContainer<FieldValue, FieldMetadata>[];
73
76
  getValidationErrors(): [FieldMetadata, string][];
74
- addChild(anchorId: string, templateId: string, label: string): Promise<FormValuesContainerMutation<FieldValue, FieldMetadata, BridgedFormValuesContainer, BridgedFormValuesContainer>>;
75
- removeChild(container: BridgedFormValuesContainer): Promise<FormValuesContainerMutation<FieldValue, FieldMetadata, BridgedFormValuesContainer, void>>;
77
+ addChild(anchorId: string, templateId: string, label: string): Promise<void>;
78
+ removeChild(container: BridgedFormValuesContainer): Promise<void>;
79
+ synchronise(): this;
76
80
  }
77
81
  /**
78
82
  * This class is a form values container that uses a hierarchy of forms as a data source. The actual values are extracted from the services of the contacts.
@@ -90,8 +94,13 @@ export declare class ContactFormValuesContainer implements FormValuesContainer<S
90
94
  serviceFactory: (label: string, serviceId?: string) => Service;
91
95
  formFactory: (anchorId: string, formTemplateId: string, label: string) => Promise<ICureForm>;
92
96
  changeListeners: ((newValue: ContactFormValuesContainer) => void)[];
93
- constructor(rootForm: ICureForm, currentContact: Contact, contactsHistory: Contact[], serviceFactory: (label: string, serviceId?: string) => Service, children: ContactFormValuesContainer[], formFactory: (anchorId: string, formTemplateId: string, label: string) => Promise<ICureForm>, changeListeners?: ((newValue: ContactFormValuesContainer) => void)[]);
94
- registerChildFormValuesContainer(childFVC: ContactFormValuesContainer): void;
97
+ private _id;
98
+ private _initialised;
99
+ toString(): string;
100
+ mustBeInitialised(): boolean;
101
+ constructor(rootForm: ICureForm, currentContact: Contact, contactsHistory: Contact[], serviceFactory: (label: string, serviceId?: string) => Service, children: ContactFormValuesContainer[], formFactory: (anchorId: string, formTemplateId: string, label: string) => Promise<ICureForm>, changeListeners?: ((newValue: ContactFormValuesContainer) => void)[], initialised?: boolean);
102
+ synchronise(): this;
103
+ registerChildFormValuesContainer(childFormValueContainer: ContactFormValuesContainer): void;
95
104
  static fromFormsHierarchy(rootForm: ICureForm, currentContact: Contact, contactsHistory: Contact[], serviceFactory: (label: string, serviceId?: string) => Service, formChildrenProvider: (parentId: string) => Promise<ICureForm[]>, formFactory: (anchorId: string, formTemplateId: string, label: string) => Promise<ICureForm>, changeListeners?: ((newValue: ContactFormValuesContainer) => void)[]): Promise<ContactFormValuesContainer>;
96
105
  getLabel(): string;
97
106
  getFormId(): string | undefined;
@@ -101,9 +110,9 @@ export declare class ContactFormValuesContainer implements FormValuesContainer<S
101
110
  getValidationErrors(): [FieldMetadata, string][];
102
111
  getValues(revisionsFilter: (id: string, history: Version<ServiceMetadata>[]) => (string | null)[]): VersionedData<Service>;
103
112
  getMetadata(id: string, revisions: (string | null)[]): VersionedData<ServiceMetadata>;
104
- setMetadata(meta: ServiceMetadata, id?: string): FormValuesContainerMutation<Service, ServiceMetadata, ContactFormValuesContainer, ID>;
105
- setValue(label: string, language: string, value?: Service, id?: string, metadata?: ServiceMetadata): FormValuesContainerMutation<Service, ServiceMetadata, ContactFormValuesContainer, ID>;
106
- delete(serviceId: string): FormValuesContainerMutation<Service, ServiceMetadata, ContactFormValuesContainer, void>;
113
+ setMetadata(meta: ServiceMetadata, id?: string): void;
114
+ setValue(label: string, language: string, value?: Service, id?: string, metadata?: ServiceMetadata, changeListenersOverrider?: (fvc: ContactFormValuesContainer) => void): void;
115
+ delete(serviceId: string): void;
107
116
  compute<T>(): T | undefined;
108
117
  /** returns all services in history that match a selector
109
118
  *
@@ -111,7 +120,7 @@ export declare class ContactFormValuesContainer implements FormValuesContainer<S
111
120
  * @param revisionsFilter
112
121
  */
113
122
  private getServicesInHistory;
114
- addChild(anchorId: string, templateId: string, label: string): Promise<FormValuesContainerMutation<Service, ServiceMetadata, ContactFormValuesContainer, ContactFormValuesContainer>>;
123
+ addChild(anchorId: string, templateId: string, label: string): Promise<void>;
115
124
  private getServiceInCurrentContact;
116
- removeChild(container: ContactFormValuesContainer): Promise<FormValuesContainerMutation<Service, ServiceMetadata, ContactFormValuesContainer, void>>;
125
+ removeChild(container: ContactFormValuesContainer): Promise<void>;
117
126
  }
@@ -15,6 +15,11 @@ const no_lodash_1 = require("../utils/no-lodash");
15
15
  const icure_utils_1 = require("./icure-utils");
16
16
  const primitive_1 = require("../utils/primitive");
17
17
  const dates_1 = require("../utils/dates");
18
+ const uuid_1 = require("uuid");
19
+ function notify(l, fvc) {
20
+ //console.log('Notifying', l, fvc.toString())
21
+ l(fvc);
22
+ }
18
23
  /** This class is a bridge between the ICure API and the generic FormValuesContainer interface.
19
24
  * It wraps around a ContactFormValuesContainer and provides a series of services:
20
25
  * - It computes dependent values when the form is created
@@ -35,11 +40,8 @@ const dates_1 = require("../utils/dates");
35
40
  * This class is fairly generic and can be used as an inspiration or subclassed for other bridges
36
41
  */
37
42
  class BridgedFormValuesContainer {
38
- get children() {
39
- var _a;
40
- return ((_a = this._children) !== null && _a !== void 0 ? _a : (this._children = this.contactFormValuesContainer
41
- .getChildren()
42
- .map((fvc) => new BridgedFormValuesContainer(this.responsible, fvc, this.interpreter, this.contact, this.dependentValuesProvider, this.validatorsProvider, this.language, this.changeListeners))));
43
+ toString() {
44
+ return `Bridged(${this.contactFormValuesContainer.rootForm.formTemplateId}[${this.contactFormValuesContainer.rootForm.id}]) - ${this._id}`;
43
45
  }
44
46
  /**
45
47
  * Creates an instance of BridgedFormValuesContainer.
@@ -51,17 +53,32 @@ class BridgedFormValuesContainer {
51
53
  * @param validatorsProvider A function that provides the validators for a given anchorId and templateId
52
54
  * @param language The language in which the values are displayed
53
55
  * @param changeListeners The listeners that will be notified when the values change
56
+ * @param initialValuesProvider A lambda that provides the initial values of the form
54
57
  */
55
- constructor(responsible, contactFormValuesContainer, interpreter, contact, dependentValuesProvider = () => [], validatorsProvider = () => [], language = 'en', changeListeners = []) {
58
+ constructor(responsible, contactFormValuesContainer, interpreter, contact, initialValuesProvider = () => [], dependentValuesProvider = () => [], validatorsProvider = () => [], language = 'en', changeListeners = []) {
59
+ var _a, _b, _c, _d;
56
60
  this.responsible = responsible;
57
61
  this.interpreter = interpreter;
62
+ this.initialValuesProvider = initialValuesProvider;
58
63
  this.dependentValuesProvider = dependentValuesProvider;
59
64
  this.validatorsProvider = validatorsProvider;
60
65
  this.language = language;
61
66
  this.changeListeners = changeListeners;
67
+ this._id = (0, uuid_1.v4)();
68
+ console.log(`Creating bridge FVC (${contactFormValuesContainer.rootForm.formTemplateId}) with ${contactFormValuesContainer.children.length} children [${this._id}]`);
62
69
  //Before start to broadcast changes, we need to fill in the contactFormValuesContainer with the dependent values
63
70
  this.contactFormValuesContainer = contactFormValuesContainer;
71
+ this.mutateAndNotify = (newContactFormValuesContainer) => {
72
+ newContactFormValuesContainer.unregisterChangeListener(this.mutateAndNotify);
73
+ const newBridgedFormValueContainer = new BridgedFormValuesContainer(this.responsible, newContactFormValuesContainer, this.interpreter, this.contact === this.contactFormValuesContainer.currentContact ? newContactFormValuesContainer.currentContact : this.contact, this.initialValuesProvider, this.dependentValuesProvider, this.validatorsProvider, this.language, this.changeListeners);
74
+ this.changeListeners.forEach((l) => notify(l, newBridgedFormValueContainer));
75
+ return newBridgedFormValueContainer;
76
+ };
77
+ this.contactFormValuesContainer.registerChangeListener(this.mutateAndNotify);
64
78
  this.contact = contact !== null && contact !== void 0 ? contact : contactFormValuesContainer.currentContact;
79
+ if (this.contactFormValuesContainer.mustBeInitialised()) {
80
+ this.forceValues(initialValuesProvider(this, (_b = (_a = this.contactFormValuesContainer) === null || _a === void 0 ? void 0 : _a.rootForm) === null || _b === void 0 ? void 0 : _b.descr, (_d = (_c = this.contactFormValuesContainer) === null || _c === void 0 ? void 0 : _c.rootForm) === null || _d === void 0 ? void 0 : _d.formTemplateId));
81
+ }
65
82
  this.computeDependentValues();
66
83
  }
67
84
  getLabel() {
@@ -127,10 +144,17 @@ class BridgedFormValuesContainer {
127
144
  },
128
145
  })) })), {});
129
146
  }
130
- mutateAndNotify(newContactFormValuesContainer) {
131
- const newBridgedFormValueContainer = new BridgedFormValuesContainer(this.responsible, newContactFormValuesContainer, this.interpreter, this.contact === this.contactFormValuesContainer.currentContact ? newContactFormValuesContainer.currentContact : this.contact, this.dependentValuesProvider, this.validatorsProvider, this.language, this.changeListeners);
132
- this.changeListeners.forEach((l) => l(newBridgedFormValueContainer));
133
- return newBridgedFormValueContainer;
147
+ //This method mutates the BridgedFormValuesContainer but can only be called from the constructor
148
+ forceValues(fieldValues) {
149
+ fieldValues.forEach(([value, metadata]) => {
150
+ setValueOnContactFormValuesContainer(this.contactFormValuesContainer, metadata.label, this.language, value, undefined, metadata, (fvc) => {
151
+ const currentContact = this.contactFormValuesContainer.currentContact;
152
+ this.contactFormValuesContainer = fvc;
153
+ if (this.contact === currentContact) {
154
+ this.contact = fvc.currentContact;
155
+ }
156
+ });
157
+ });
134
158
  }
135
159
  //This method mutates the BridgedFormValuesContainer but can only be called from the constructor
136
160
  computeDependentValues() {
@@ -148,11 +172,13 @@ class BridgedFormValuesContainer {
148
172
  if (newValue) {
149
173
  delete newValue.content['*'];
150
174
  }
151
- const currentContact = this.contactFormValuesContainer.currentContact;
152
- this.contactFormValuesContainer = setValueOnContactFormValuesContainer(this.contactFormValuesContainer, metadata.label, lng, newValue, Object.keys(currentValue !== null && currentValue !== void 0 ? currentValue : {})[0], metadata).formValuesContainer;
153
- if (this.contact === currentContact) {
154
- this.contact = this.contactFormValuesContainer.currentContact;
155
- }
175
+ setValueOnContactFormValuesContainer(this.contactFormValuesContainer, metadata.label, lng, newValue, Object.keys(currentValue !== null && currentValue !== void 0 ? currentValue : {})[0], metadata, (fvc) => {
176
+ const currentContact = this.contactFormValuesContainer.currentContact;
177
+ this.contactFormValuesContainer = fvc;
178
+ if (this.contact === currentContact) {
179
+ this.contact = fvc.currentContact;
180
+ }
181
+ });
156
182
  }
157
183
  }
158
184
  catch (e) {
@@ -162,21 +188,18 @@ class BridgedFormValuesContainer {
162
188
  }
163
189
  }
164
190
  setValue(label, language, fv, id, metadata) {
165
- const mutation = setValueOnContactFormValuesContainer(this.contactFormValuesContainer, label, language, fv, id, metadata);
166
- return { result: mutation.result, formValuesContainer: this.mutateAndNotify(mutation.formValuesContainer) };
191
+ setValueOnContactFormValuesContainer(this.contactFormValuesContainer, label, language, fv, id, metadata);
167
192
  }
168
193
  setMetadata(meta, id) {
169
- const mutation = this.contactFormValuesContainer.setMetadata({
194
+ this.contactFormValuesContainer.setMetadata({
170
195
  label: meta.label,
171
196
  responsible: meta.owner,
172
197
  valueDate: meta.valueDate,
173
198
  tags: meta.tags,
174
199
  }, id);
175
- return { result: mutation.result, formValuesContainer: this.mutateAndNotify(mutation.formValuesContainer) };
176
200
  }
177
201
  delete(serviceId) {
178
- const mutation = this.contactFormValuesContainer.delete(serviceId);
179
- return { result: undefined, formValuesContainer: this.mutateAndNotify(mutation.formValuesContainer) };
202
+ this.contactFormValuesContainer.delete(serviceId);
180
203
  }
181
204
  getVersionedValuesForKey(key) {
182
205
  return this.getValues((id, history) => { var _a, _b, _c; return (((_b = (_a = history === null || history === void 0 ? void 0 : history[0]) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.label) && key === history[0].value.label ? [(_c = history === null || history === void 0 ? void 0 : history[0]) === null || _c === void 0 ? void 0 : _c.revision] : []); });
@@ -229,7 +252,11 @@ class BridgedFormValuesContainer {
229
252
  return (_a = this.interpreter) === null || _a === void 0 ? void 0 : _a.call(this, formula, sandbox !== null && sandbox !== void 0 ? sandbox : proxy);
230
253
  }
231
254
  getChildren() {
232
- return this.contactFormValuesContainer.getChildren().map((fvc) => new BridgedFormValuesContainer(this.responsible, fvc, this.interpreter, this.contact));
255
+ const children = this.contactFormValuesContainer
256
+ .getChildren()
257
+ .map((fvc) => new BridgedFormValuesContainer(this.responsible, fvc, this.interpreter, this.contact, this.initialValuesProvider, this.dependentValuesProvider, this.validatorsProvider, this.language, []));
258
+ console.log(`${children.length} children found in ${this.contactFormValuesContainer.rootForm.formTemplateId} initialised with `, this.initialValuesProvider);
259
+ return children;
233
260
  }
234
261
  getValidationErrors() {
235
262
  if (this.contactFormValuesContainer.rootForm.formTemplateId) {
@@ -251,21 +278,18 @@ class BridgedFormValuesContainer {
251
278
  }
252
279
  addChild(anchorId, templateId, label) {
253
280
  return __awaiter(this, void 0, void 0, function* () {
254
- const mutation = yield this.contactFormValuesContainer.addChild(anchorId, templateId, label);
255
- const newBridgedFormValueContainer = this.mutateAndNotify(mutation.formValuesContainer);
256
- const newChild = newBridgedFormValueContainer.children.find((c) => c.contactFormValuesContainer === mutation.result);
257
- if (!newChild) {
258
- throw new Error('Illegal state, the new child must be found');
259
- }
260
- return { result: newChild, formValuesContainer: newBridgedFormValueContainer };
281
+ yield this.contactFormValuesContainer.addChild(anchorId, templateId, label);
261
282
  });
262
283
  }
263
284
  removeChild(container) {
264
285
  return __awaiter(this, void 0, void 0, function* () {
265
- const mutation = yield this.contactFormValuesContainer.removeChild(container.contactFormValuesContainer);
266
- return { result: undefined, formValuesContainer: this.mutateAndNotify(mutation.formValuesContainer) };
286
+ yield this.contactFormValuesContainer.removeChild(container.contactFormValuesContainer);
267
287
  });
268
288
  }
289
+ synchronise() {
290
+ this.contactFormValuesContainer.synchronise();
291
+ return this;
292
+ }
269
293
  }
270
294
  exports.BridgedFormValuesContainer = BridgedFormValuesContainer;
271
295
  /**
@@ -277,7 +301,16 @@ exports.BridgedFormValuesContainer = BridgedFormValuesContainer;
277
301
  * The `serviceFactory` and `formFactory` are used to create new services and add sub-forms.
278
302
  */
279
303
  class ContactFormValuesContainer {
280
- constructor(rootForm, currentContact, contactsHistory, serviceFactory, children, formFactory, changeListeners = []) {
304
+ toString() {
305
+ return `Contact(${this.rootForm.formTemplateId}[${this.rootForm.id}]) - ${this._id}`;
306
+ }
307
+ mustBeInitialised() {
308
+ return !this._initialised;
309
+ }
310
+ constructor(rootForm, currentContact, contactsHistory, serviceFactory, children, formFactory, changeListeners = [], initialised = true) {
311
+ this._id = (0, uuid_1.v4)();
312
+ this._initialised = false;
313
+ console.log(`Creating contact FVC (${rootForm.formTemplateId}) with ${children.length} children [${this._id}]`);
281
314
  if (contactsHistory.includes(currentContact)) {
282
315
  throw new Error('Illegal argument, the history must not contain the currentContact');
283
316
  }
@@ -288,12 +321,26 @@ class ContactFormValuesContainer {
288
321
  this.serviceFactory = serviceFactory;
289
322
  this.formFactory = formFactory;
290
323
  this.changeListeners = changeListeners;
324
+ this._initialised = initialised;
325
+ this.synchronise();
291
326
  }
292
- registerChildFormValuesContainer(childFVC) {
293
- childFVC.registerChangeListener((newValue) => {
294
- const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, this.children.map((c) => (c === childFVC ? newValue : c)), this.formFactory, this.changeListeners);
295
- this.changeListeners.forEach((l) => l(newContactFormValuesContainer));
327
+ synchronise() {
328
+ this.children.forEach((childFVC) => {
329
+ this.registerChildFormValuesContainer(childFVC.synchronise());
296
330
  });
331
+ return this;
332
+ }
333
+ //Make sure that when a child is changed, a new version of this is created with the updated child
334
+ registerChildFormValuesContainer(childFormValueContainer) {
335
+ childFormValueContainer.changeListeners = [
336
+ (newValue) => {
337
+ console.log(`Child ${newValue._id} ${childFormValueContainer.rootForm.formTemplateId} changed, updating parent ${this._id} ${this.rootForm.formTemplateId}`);
338
+ const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, this.children.map((c) => {
339
+ return c.rootForm.id === childFormValueContainer.rootForm.id ? newValue : c;
340
+ }), this.formFactory);
341
+ this.changeListeners.forEach((l) => notify(l, newContactFormValuesContainer));
342
+ },
343
+ ];
297
344
  }
298
345
  static fromFormsHierarchy(rootForm_1, currentContact_1, contactsHistory_1, serviceFactory_1, formChildrenProvider_1, formFactory_1) {
299
346
  return __awaiter(this, arguments, void 0, function* (rootForm, currentContact, contactsHistory, serviceFactory, formChildrenProvider, formFactory, changeListeners = []) {
@@ -301,7 +348,7 @@ class ContactFormValuesContainer {
301
348
  ? yield Promise.all((yield formChildrenProvider(rootForm.id)).map((f) => __awaiter(this, void 0, void 0, function* () {
302
349
  // eslint-disable-next-line max-len
303
350
  return yield ContactFormValuesContainer.fromFormsHierarchy(f, currentContact, contactsHistory, serviceFactory, formChildrenProvider, formFactory); })))
304
- : [], formFactory, changeListeners);
351
+ : [], formFactory, changeListeners, false);
305
352
  contactFormValuesContainer.children.forEach((childFVC) => contactFormValuesContainer.registerChildFormValuesContainer(childFVC));
306
353
  return contactFormValuesContainer;
307
354
  });
@@ -370,12 +417,10 @@ class ContactFormValuesContainer {
370
417
  meta.codes && (newService.codes = meta.codes);
371
418
  meta.tags && (newService.tags = meta.tags);
372
419
  const newFormValuesContainer = new ContactFormValuesContainer(this.rootForm, Object.assign(Object.assign({}, this.currentContact), { services: (_a = this.currentContact.services) === null || _a === void 0 ? void 0 : _a.map((s) => (s.id === service.id ? newService : s)) }), this.contactsHistory, this.serviceFactory, this.children, this.formFactory, this.changeListeners);
373
- this.changeListeners.forEach((l) => l(newFormValuesContainer));
374
- return { result: service.id, formValuesContainer: newFormValuesContainer };
420
+ this.changeListeners.forEach((l) => notify(l, newFormValuesContainer));
375
421
  }
376
- return { result: service.id, formValuesContainer: this };
377
422
  }
378
- setValue(label, language, value, id, metadata) {
423
+ setValue(label, language, value, id, metadata, changeListenersOverrider) {
379
424
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
380
425
  const service = (id && ((_b = (_a = this.getServicesInHistory((sid, history) => (sid === id ? history.map((x) => x.revision) : []))[id]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value)) || this.serviceFactory(label, id);
381
426
  if (!service.id) {
@@ -410,20 +455,16 @@ class ContactFormValuesContainer {
410
455
  : [...((_r = this.currentContact.services) !== null && _r !== void 0 ? _r : []), newService] });
411
456
  }
412
457
  const newFormValuesContainer = new ContactFormValuesContainer(this.rootForm, newCurrentContact, this.contactsHistory.map((c) => (c === this.currentContact ? newCurrentContact : c)), this.serviceFactory, this.children, this.formFactory, this.changeListeners);
413
- this.changeListeners.forEach((l) => l(newFormValuesContainer));
414
- return { result: service.id, formValuesContainer: newFormValuesContainer };
458
+ changeListenersOverrider ? changeListenersOverrider(newFormValuesContainer) : this.changeListeners.forEach((l) => notify(l, newFormValuesContainer));
415
459
  }
416
- return { result: service.id, formValuesContainer: this };
417
460
  }
418
461
  delete(serviceId) {
419
462
  var _a;
420
463
  const service = this.getServiceInCurrentContact(serviceId);
421
464
  if (service) {
422
465
  const newFormValuesContainer = new ContactFormValuesContainer(this.rootForm, Object.assign(Object.assign({}, this.currentContact), { services: (_a = this.currentContact.services) === null || _a === void 0 ? void 0 : _a.map((s) => (s.id === serviceId ? new api_1.Service(Object.assign(Object.assign({}, service), { endOfLife: Date.now() })) : s)) }), this.contactsHistory, this.serviceFactory, this.children, this.formFactory, this.changeListeners);
423
- this.changeListeners.forEach((l) => l(newFormValuesContainer));
424
- return { result: undefined, formValuesContainer: newFormValuesContainer };
466
+ this.changeListeners.forEach((l) => notify(l, newFormValuesContainer));
425
467
  }
426
- return { result: undefined, formValuesContainer: this };
427
468
  }
428
469
  compute() {
429
470
  throw new Error('Compute not supported at contact level');
@@ -463,11 +504,10 @@ class ContactFormValuesContainer {
463
504
  addChild(anchorId, templateId, label) {
464
505
  return __awaiter(this, void 0, void 0, function* () {
465
506
  const newForm = yield this.formFactory(anchorId, templateId, label);
466
- const childFVC = new ContactFormValuesContainer(newForm, this.currentContact, this.contactsHistory, this.serviceFactory, [], this.formFactory);
467
- const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, [...this.children, childFVC], this.formFactory);
507
+ const childFVC = new ContactFormValuesContainer(newForm, this.currentContact, this.contactsHistory, this.serviceFactory, [], this.formFactory, [], false);
508
+ const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, [...this.children, childFVC], this.formFactory, this.changeListeners);
468
509
  newContactFormValuesContainer.registerChildFormValuesContainer(childFVC);
469
- this.changeListeners.forEach((l) => l(newContactFormValuesContainer));
470
- return { result: childFVC, formValuesContainer: newContactFormValuesContainer };
510
+ this.changeListeners.forEach((l) => notify(l, newContactFormValuesContainer));
471
511
  });
472
512
  }
473
513
  getServiceInCurrentContact(id) {
@@ -477,17 +517,16 @@ class ContactFormValuesContainer {
477
517
  }
478
518
  removeChild(container) {
479
519
  return __awaiter(this, void 0, void 0, function* () {
480
- const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, this.children.filter((c) => c !== container), this.formFactory);
481
- this.changeListeners.forEach((l) => l(newContactFormValuesContainer));
482
- return { result: undefined, formValuesContainer: newContactFormValuesContainer };
520
+ const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, this.currentContact, this.contactsHistory, this.serviceFactory, this.children.filter((c) => c.rootForm.id !== container.rootForm.id), this.formFactory, this.changeListeners);
521
+ this.changeListeners.forEach((l) => notify(l, newContactFormValuesContainer));
483
522
  });
484
523
  }
485
524
  }
486
525
  exports.ContactFormValuesContainer = ContactFormValuesContainer;
487
- const setValueOnContactFormValuesContainer = (cfvc, label, language, fv, id, metadata) => {
526
+ const setValueOnContactFormValuesContainer = (cfvc, label, language, fv, id, metadata, changeListenersOverrider) => {
488
527
  var _a, _b;
489
528
  const value = fv === null || fv === void 0 ? void 0 : fv.content[language];
490
- const mutation = cfvc.setValue(label, language, {
529
+ cfvc.setValue(label, language, {
491
530
  id: id,
492
531
  codes: (_a = fv === null || fv === void 0 ? void 0 : fv.codes) !== null && _a !== void 0 ? _a : [],
493
532
  content: value
@@ -502,7 +541,6 @@ const setValueOnContactFormValuesContainer = (cfvc, label, language, fv, id, met
502
541
  valueDate: metadata === null || metadata === void 0 ? void 0 : metadata.valueDate,
503
542
  tags: metadata === null || metadata === void 0 ? void 0 : metadata.tags,
504
543
  }
505
- : undefined);
506
- return mutation;
544
+ : undefined, changeListenersOverrider);
507
545
  };
508
546
  //# sourceMappingURL=form-values-container.js.map