@icure/form 2.1.4 → 2.1.7

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.
@@ -1,11 +1,11 @@
1
1
  import { TemplateResult } from 'lit';
2
- import { FormValuesContainer, Suggestion } from '../../../generic';
3
- import { FieldMetadata, FieldValue, Form } from '../../model';
2
+ import { FormValuesContainer, Suggestion, Version } from '../../../generic';
3
+ import { Field, FieldMetadata, FieldValue, Form } from '../../model';
4
4
  export interface RendererProps {
5
5
  language?: string;
6
6
  labelPosition?: 'top' | 'left' | 'right' | 'bottom' | 'float';
7
7
  defaultOwner?: string;
8
8
  }
9
- export type Renderer = (form: Form, props: RendererProps, formsValueContainer?: FormValuesContainer<FieldValue, FieldMetadata>, translationProvider?: (language: string, text: string) => string, ownersProvider?: (terms: string[], ids?: string[], specialties?: string[]) => Promise<Suggestion[]>, optionsProvider?: (language: string, codifications: string[], terms?: string[]) => Promise<Suggestion[]>, actionListener?: (event: string, payload: unknown) => void, languages?: {
9
+ export type Renderer = (form: Form, props: RendererProps, formsValueContainer?: FormValuesContainer<FieldValue, FieldMetadata>, translationProvider?: (language: string, text: string) => string, revisionsFilter?: (field: Field, id: string, history: Version<FieldMetadata>[]) => string[], ownersProvider?: (terms: string[], ids?: string[], specialties?: string[]) => Promise<Suggestion[]>, optionsProvider?: (language: string, codifications: string[], terms?: string[]) => Promise<Suggestion[]>, actionListener?: (event: string, payload: unknown) => void, languages?: {
10
10
  [iso: string]: string;
11
11
  }, readonly?: boolean, displayMetadata?: boolean, sectionWrapper?: (index: number, section: () => TemplateResult) => TemplateResult) => Promise<TemplateResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../tmp/components/icure-form/renderer/index.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit'\nimport { FormValuesContainer, Suggestion } from '../../../generic'\nimport { FieldMetadata, FieldValue, Form } from '../../model'\n\nexport interface RendererProps {\n\tlanguage?: string\n\tlabelPosition?: 'top' | 'left' | 'right' | 'bottom' | 'float'\n\tdefaultOwner?: string\n}\n\nexport type Renderer = (\n\tform: Form,\n\tprops: RendererProps,\n\tformsValueContainer?: FormValuesContainer<FieldValue, FieldMetadata>,\n\ttranslationProvider?: (language: string, text: string) => string,\n\townersProvider?: (terms: string[], ids?: string[], specialties?: string[]) => Promise<Suggestion[]>,\n\toptionsProvider?: (language: string, codifications: string[], terms?: string[]) => Promise<Suggestion[]>,\n\tactionListener?: (event: string, payload: unknown) => void,\n\tlanguages?: { [iso: string]: string },\n\treadonly?: boolean,\n\tdisplayMetadata?: boolean,\n\tsectionWrapper?: (index: number, section: () => TemplateResult) => TemplateResult,\n) => Promise<TemplateResult>\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../tmp/components/icure-form/renderer/index.ts"],"names":[],"mappings":"","sourcesContent":["import { TemplateResult } from 'lit'\nimport { FormValuesContainer, Suggestion, Version } from '../../../generic'\nimport { Field, FieldMetadata, FieldValue, Form } from '../../model'\n\nexport interface RendererProps {\n\tlanguage?: string\n\tlabelPosition?: 'top' | 'left' | 'right' | 'bottom' | 'float'\n\tdefaultOwner?: string\n}\n\nexport type Renderer = (\n\tform: Form,\n\tprops: RendererProps,\n\tformsValueContainer?: FormValuesContainer<FieldValue, FieldMetadata>,\n\ttranslationProvider?: (language: string, text: string) => string,\n\trevisionsFilter?: (field: Field, id: string, history: Version<FieldMetadata>[]) => string[],\n\townersProvider?: (terms: string[], ids?: string[], specialties?: string[]) => Promise<Suggestion[]>,\n\toptionsProvider?: (language: string, codifications: string[], terms?: string[]) => Promise<Suggestion[]>,\n\tactionListener?: (event: string, payload: unknown) => void,\n\tlanguages?: { [iso: string]: string },\n\treadonly?: boolean,\n\tdisplayMetadata?: boolean,\n\tsectionWrapper?: (index: number, section: () => TemplateResult) => TemplateResult,\n) => Promise<TemplateResult>\n"]}
@@ -155,6 +155,7 @@ export declare class ContactFormValuesContainer implements FormValuesContainer<S
155
155
  private getServicesInHistory;
156
156
  addChild(anchorId: string, templateId: string, label: string): Promise<void>;
157
157
  private getServiceInCurrentContact;
158
+ private static collectFormIds;
158
159
  removeChild(container: ContactFormValuesContainer): Promise<void>;
159
160
  }
160
161
  export {};
@@ -489,12 +489,19 @@ class ContactFormValuesContainer {
489
489
  * Returns a contact that combines the content of the contact in this form with the content of all contents stored in the children
490
490
  */
491
491
  coordinatedContact() {
492
- var _a, _b, _c;
492
+ var _a, _b, _c, _d, _e;
493
493
  const childrenContacts = this.children.map((c) => c.coordinatedContact());
494
- const thisKeptServiceIds = ((_a = this.currentContact.subContacts) !== null && _a !== void 0 ? _a : []).filter((sc) => sc.formId === this.rootForm.id).flatMap((sc) => { var _a; return ((_a = sc.services) !== null && _a !== void 0 ? _a : []).map((s) => s.serviceId); });
495
- return Object.assign(Object.assign({}, this.currentContact), { services: childrenContacts.reduce((acc, c) => { var _a; return acc.concat((_a = c.services) !== null && _a !== void 0 ? _a : []); }, []).concat(((_b = this.currentContact.services) !== null && _b !== void 0 ? _b : []).filter((s) => thisKeptServiceIds.includes(s.id))), subContacts: childrenContacts
494
+ const thisKeptServiceIds = new Set(((_a = this.currentContact.subContacts) !== null && _a !== void 0 ? _a : []).filter((sc) => sc.formId === this.rootForm.id).flatMap((sc) => { var _a; return ((_a = sc.services) !== null && _a !== void 0 ? _a : []).map((s) => s.serviceId); }));
495
+ const thisFormServices = ((_b = this.currentContact.services) !== null && _b !== void 0 ? _b : []).filter((s) => thisKeptServiceIds.has(s.id));
496
+ // Include endOfLife services not linked to any subcontact (from deleted subforms)
497
+ const allSubContactServiceIds = new Set(((_c = this.currentContact.subContacts) !== null && _c !== void 0 ? _c : []).flatMap((sc) => { var _a; return ((_a = sc.services) !== null && _a !== void 0 ? _a : []).map((s) => s.serviceId); }));
498
+ const endOfLifeServices = ((_d = this.currentContact.services) !== null && _d !== void 0 ? _d : []).filter((s) => s.endOfLife && s.id && !allSubContactServiceIds.has(s.id));
499
+ return Object.assign(Object.assign({}, this.currentContact), { services: childrenContacts
500
+ .reduce((acc, c) => { var _a; return acc.concat((_a = c.services) !== null && _a !== void 0 ? _a : []); }, [])
501
+ .concat(thisFormServices)
502
+ .concat(endOfLifeServices), subContacts: childrenContacts
496
503
  .reduce((acc, c) => { var _a; return acc.concat((_a = c.subContacts) !== null && _a !== void 0 ? _a : []); }, [])
497
- .concat(((_c = this.currentContact.subContacts) !== null && _c !== void 0 ? _c : []).filter((s) => s.formId === this.rootForm.id)) });
504
+ .concat(((_e = this.currentContact.subContacts) !== null && _e !== void 0 ? _e : []).filter((s) => s.formId === this.rootForm.id)) });
498
505
  }
499
506
  /**
500
507
  * Returns a contact that combines the content of the contact in this form with the content of all contents stored in the children
@@ -503,7 +510,7 @@ class ContactFormValuesContainer {
503
510
  return [this.rootForm].concat(this.children.flatMap((c) => c.allForms()));
504
511
  }
505
512
  constructor(rootForm, currentContact, contactsHistory, serviceFactory, children, formFactory, formRecycler, changeListeners = [], anchorId, initialised = true) {
506
- var _a;
513
+ var _a, _b;
507
514
  this._id = '';
508
515
  this._initialised = false;
509
516
  this.rootForm = rootForm;
@@ -521,9 +528,16 @@ class ContactFormValuesContainer {
521
528
  this.formRecycler = formRecycler;
522
529
  this.changeListeners = changeListeners;
523
530
  this._initialised = initialised;
531
+ // Collect IDs of services that have been marked with endOfLife in the most recent contact
532
+ const endOfLifeServiceIds = new Set();
533
+ const mostRecentContact = this.currentContact;
534
+ for (const s of (_b = mostRecentContact.services) !== null && _b !== void 0 ? _b : []) {
535
+ if (s.id && s.endOfLife)
536
+ endOfLifeServiceIds.add(s.id);
537
+ }
524
538
  this.indexedServices = [this.currentContact].concat(this.contactsHistory).reduce((acc, ctc) => {
525
539
  var _a, _b, _c;
526
- return ((_c = (_b = (_a = ctc.services) === null || _a === void 0 ? void 0 : _a.filter((s) => { var _a; return (_a = ctc.subContacts) === null || _a === void 0 ? void 0 : _a.some((sc) => { var _a; return sc.formId === this.rootForm.id && ((_a = sc.services) === null || _a === void 0 ? void 0 : _a.some((sss) => sss.serviceId === s.id)); }); })) === null || _b === void 0 ? void 0 : _b.reduce((acc, s) => {
540
+ return ((_c = (_b = (_a = ctc.services) === null || _a === void 0 ? void 0 : _a.filter((s) => { var _a; return !endOfLifeServiceIds.has(s.id) && ((_a = ctc.subContacts) === null || _a === void 0 ? void 0 : _a.some((sc) => { var _a; return sc.formId === this.rootForm.id && ((_a = sc.services) === null || _a === void 0 ? void 0 : _a.some((sss) => sss.serviceId === s.id)); })); })) === null || _b === void 0 ? void 0 : _b.reduce((acc, s) => {
527
541
  var _a, _b;
528
542
  return s.id
529
543
  ? Object.assign(Object.assign({}, acc), { [s.id]: ((_a = acc[s.id]) !== null && _a !== void 0 ? _a : (acc[s.id] = [])).concat({
@@ -785,9 +799,77 @@ class ContactFormValuesContainer {
785
799
  const service = (_a = (this.currentContact.services || [])) === null || _a === void 0 ? void 0 : _a.find((s) => s.id === id);
786
800
  return service !== null && service !== void 0 ? service : undefined;
787
801
  }
802
+ static collectFormIds(container) {
803
+ const ids = new Set();
804
+ if (container.rootForm.id)
805
+ ids.add(container.rootForm.id);
806
+ for (const child of container.children) {
807
+ for (const id of ContactFormValuesContainer.collectFormIds(child)) {
808
+ ids.add(id);
809
+ }
810
+ }
811
+ return ids;
812
+ }
788
813
  removeChild(container) {
789
814
  return __awaiter(this, void 0, void 0, function* () {
790
- 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.formRecycler, this.changeListeners, this.anchorId, true);
815
+ var _a, _b, _c, _d, _e, _f, _g, _h;
816
+ // Collect all form IDs in the subtree being removed (child + its descendants)
817
+ const removedFormIds = ContactFormValuesContainer.collectFormIds(container);
818
+ // Collect service IDs linked to any removed form across current contact and history
819
+ const allContacts = [this.currentContact, ...this.contactsHistory];
820
+ const childServiceIds = new Set();
821
+ for (const ctc of allContacts) {
822
+ for (const sc of (_a = ctc.subContacts) !== null && _a !== void 0 ? _a : []) {
823
+ if (sc.formId && removedFormIds.has(sc.formId)) {
824
+ for (const sRef of (_b = sc.services) !== null && _b !== void 0 ? _b : []) {
825
+ if (sRef.serviceId)
826
+ childServiceIds.add(sRef.serviceId);
827
+ }
828
+ }
829
+ }
830
+ }
831
+ // Build the updated current contact:
832
+ // - Services that exist in history must be marked with endOfLife (not removed)
833
+ // - Services that only exist in the current contact can be simply removed
834
+ // - Remove subContact entries for all removed forms
835
+ const now = Date.now();
836
+ // Determine which child services exist in history
837
+ const childServiceIdsInHistory = new Set();
838
+ for (const ctc of this.contactsHistory) {
839
+ for (const sc of (_c = ctc.subContacts) !== null && _c !== void 0 ? _c : []) {
840
+ if (sc.formId && removedFormIds.has(sc.formId)) {
841
+ for (const sRef of (_d = sc.services) !== null && _d !== void 0 ? _d : []) {
842
+ if (sRef.serviceId && childServiceIds.has(sRef.serviceId))
843
+ childServiceIdsInHistory.add(sRef.serviceId);
844
+ }
845
+ }
846
+ }
847
+ }
848
+ const existingServiceIds = new Set(((_e = this.currentContact.services) !== null && _e !== void 0 ? _e : []).map((s) => s.id));
849
+ // Services in current contact: mark with endOfLife if in history, remove otherwise
850
+ const updatedServices = ((_f = this.currentContact.services) !== null && _f !== void 0 ? _f : [])
851
+ .filter((s) => !(s.id && childServiceIds.has(s.id) && !childServiceIdsInHistory.has(s.id)))
852
+ .map((s) => (s.id && childServiceIdsInHistory.has(s.id) ? new api_1.Service({ id: s.id, created: s.created, modified: now, endOfLife: now }) : s));
853
+ // Services only in history (not in current contact): add with endOfLife
854
+ for (const serviceId of childServiceIdsInHistory) {
855
+ if (!existingServiceIds.has(serviceId)) {
856
+ for (const ctc of this.contactsHistory) {
857
+ const historyService = (_g = ctc.services) === null || _g === void 0 ? void 0 : _g.find((s) => s.id === serviceId);
858
+ if (historyService) {
859
+ updatedServices.push(new api_1.Service({ id: historyService.id, created: historyService.created, modified: now, endOfLife: now }));
860
+ break;
861
+ }
862
+ }
863
+ }
864
+ }
865
+ // Remove subContact entries for all removed forms
866
+ const updatedSubContacts = ((_h = this.currentContact.subContacts) !== null && _h !== void 0 ? _h : []).filter((sc) => !sc.formId || !removedFormIds.has(sc.formId));
867
+ const updatedContact = Object.assign(Object.assign({}, this.currentContact), { services: updatedServices, subContacts: updatedSubContacts });
868
+ // Recycle all removed forms
869
+ for (const formId of removedFormIds) {
870
+ yield this.formRecycler(formId);
871
+ }
872
+ const newContactFormValuesContainer = new ContactFormValuesContainer(this.rootForm, updatedContact, this.contactsHistory, this.serviceFactory, this.children.filter((c) => c.rootForm.id !== container.rootForm.id), this.formFactory, this.formRecycler, this.changeListeners, this.anchorId, true);
791
873
  this.changeListeners.forEach((l) => { var _a; return notify(l, newContactFormValuesContainer, [`subForms_${(_a = container.anchorId) !== null && _a !== void 0 ? _a : 'all'}`]); });
792
874
  });
793
875
  }