@eqproject/eqp-dynamic-module 2.10.84 → 2.10.86

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.
@@ -1189,10 +1189,22 @@ class UtilityHelperService {
1189
1189
  * In nuovo FormControl avrà il nome del campo passato e verranno impostati i Validators in base al tipo del campo stesso.
1190
1190
  * @param field BaseField per cui creare il FormControl da inserire nel FormGroup dela form.
1191
1191
  */
1192
+ /**
1193
+ * Validator "required" che legge dal record invece che da control.value.
1194
+ * Serve per far funzionare la validazione quando il valore viene impostato via formula/ActionButton
1195
+ * (che aggiornano record[fieldName] direttamente senza passare dal FormControl).
1196
+ */
1197
+ createRecordRequiredValidator(record, fieldName) {
1198
+ return () => {
1199
+ const v = record[fieldName];
1200
+ const isEmpty = v == null || ((typeof v === 'string' || Array.isArray(v)) && v.length === 0);
1201
+ return isEmpty ? { required: true } : null;
1202
+ };
1203
+ }
1192
1204
  createFieldFormControl(field, record) {
1193
1205
  const validators = [];
1194
1206
  if (field.Required)
1195
- validators.push(Validators.required);
1207
+ validators.push(this.createRecordRequiredValidator(record, field.Name));
1196
1208
  switch (field.FieldType) {
1197
1209
  case FieldTypeEnum["Campo di testo"]:
1198
1210
  if (field.MaxLenght) {
@@ -5043,6 +5055,7 @@ class ListValueFieldTemplateComponent {
5043
5055
  this.record[this.field.Label] = initialvalue;
5044
5056
  }
5045
5057
  updateField() {
5058
+ var _a;
5046
5059
  if (this.field.ReadonlyIf) {
5047
5060
  this.field.Readonly = UtilityHelperService.EvaluateFieldFormula(this.field.ReadonlyIf, this.record, this.formulaObject);
5048
5061
  this.checkReadonly();
@@ -5050,12 +5063,24 @@ class ListValueFieldTemplateComponent {
5050
5063
  GlobalService.debugLog("list-value-field updateField", this.field);
5051
5064
  if (this.field.Formula) {
5052
5065
  GlobalService.debugLog("list-value-field - updateField - Formula", "formula");
5053
- const tempValuePairs = this.field.ValuePairs;
5054
- this.field.ValuePairs = {};
5055
- const temp = UtilityHelperService.EvaluateFieldFormula(this.field.Formula, this.record, this.formulaObject);
5056
- this.field.ValuePairs = GlobalService.stringToValuePairs(temp);
5057
- if (!(JSON.stringify(tempValuePairs) === JSON.stringify(this.field.ValuePairs))) {
5058
- this.resetArrayData();
5066
+ if (((_a = this.field.DataGetter) === null || _a === void 0 ? void 0 : _a.DataGetterType) === DataGetterTypeEnum.Formula) {
5067
+ // La formula calcola il VALORE SELEZIONATO (non le opzioni): comportamento analogo al campo numerico.
5068
+ // Le opzioni vengono da ValueString/ValuePairs. Non si chiama resetArrayData() per evitare loop.
5069
+ const newValue = UtilityHelperService.EvaluateFieldFormula(this.field.Formula, this.record, this.formulaObject);
5070
+ if (this.record[this.field.Name] !== newValue) {
5071
+ this.record[this.field.Name] = newValue;
5072
+ this.setFormControlValue();
5073
+ }
5074
+ }
5075
+ else {
5076
+ // La formula calcola le OPZIONI (ValuePairs) — caso d'uso originale
5077
+ const tempValuePairs = this.field.ValuePairs;
5078
+ this.field.ValuePairs = {};
5079
+ const temp = UtilityHelperService.EvaluateFieldFormula(this.field.Formula, this.record, this.formulaObject);
5080
+ this.field.ValuePairs = GlobalService.stringToValuePairs(temp);
5081
+ if (!(JSON.stringify(tempValuePairs) === JSON.stringify(this.field.ValuePairs))) {
5082
+ this.resetArrayData();
5083
+ }
5059
5084
  }
5060
5085
  }
5061
5086
  else if (this.field.ValuePairs != null && this.field.ValuePairs.lenght > 0) {
@@ -5089,7 +5114,13 @@ class ListValueFieldTemplateComponent {
5089
5114
  this.onRecordValueChange();
5090
5115
  }
5091
5116
  updateSelected(emitChange = true) {
5092
- this.record[this.field.Name] = this.arrayData.filter(data => data.Selected).map(data => data.Value);
5117
+ const selectedValues = this.arrayData.filter(data => data.Selected).map(data => data.Value);
5118
+ // Single-choice: usa null (non []) quando nessun valore è selezionato.
5119
+ // [] !== [] in JS (confronto per referenza): mat-select._assignValue vede sempre un "cambio"
5120
+ // su ogni cycle di CD e scatena _onChange → ngModelChange → loop infinito.
5121
+ this.record[this.field.Name] = this.field.IsMultiChoiche
5122
+ ? selectedValues
5123
+ : (selectedValues.length > 0 ? selectedValues[0] : null);
5093
5124
  this.setFormControlValue();
5094
5125
  if (emitChange) {
5095
5126
  this.onRecordValueChange();
@@ -5100,7 +5131,7 @@ class ListValueFieldTemplateComponent {
5100
5131
  }
5101
5132
  resetArrayData() {
5102
5133
  this.arrayData = [];
5103
- this.updateSelected(true);
5134
+ this.updateSelected(false);
5104
5135
  this.setArrayData();
5105
5136
  }
5106
5137
  reloadArrayData() {
@@ -5138,7 +5169,10 @@ class ListValueFieldTemplateComponent {
5138
5169
  this.arrayData.push({ Key: key, Value: value, Selected: isOptionSelected, ImgUrl: imgUrl });
5139
5170
  }
5140
5171
  setFormControlValue() {
5141
- this.field.FormFormGroup.controls[this.field.Name].setValue(this.record[this.field.Name]);
5172
+ // emitModelToViewChange:false impedisce che FormControl.setValue() notifichi i callback
5173
+ // _onChange registrati da NgModel (via [formControlName] sul mat-checkbox), evitando che
5174
+ // NgModel emetta ngModelChange → updateSelected() → setFormControlValue() ricorsivamente.
5175
+ this.field.FormFormGroup.controls[this.field.Name].setValue(this.record[this.field.Name], { emitEvent: false, emitModelToViewChange: false });
5142
5176
  }
5143
5177
  }
5144
5178
  ListValueFieldTemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ListValueFieldTemplateComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
@@ -6091,10 +6125,10 @@ class ImageFieldTemplateComponent {
6091
6125
  }
6092
6126
  }
6093
6127
  ImageFieldTemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImageFieldTemplateComponent, deps: [{ token: i1$3.MatDialog }, { token: UtilityHelperService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
6094
- ImageFieldTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImageFieldTemplateComponent, selector: "image-field-template", inputs: { endPointConfiguration: "endPointConfiguration", record: "record", formulaObject: "formulaObject", field: "field", inConfig: "inConfig", styleVersion: "styleVersion", forceState: "forceState" }, outputs: { recordChange: "recordChange", imageDraw: "imageDraw" }, viewQueries: [{ propertyName: "dialogImageDrawing", first: true, predicate: ["dialogImageDrawing"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\">\r\n </div>\r\n <div *ngIf=\"field.EnableDrawing\" class=\"col-12 drawButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openDraw()\">Disegna</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonKey != null && field.DynAttachment.ButtonKey != ''\"\r\n class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div>\r\n <div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonValue != null && field.DynAttachment.ButtonValue != ''\"\r\n class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER DISEGNARE SUL NUOVO ALLEGATO CARICATO -->\r\n<ng-template #dialogImageDrawing>\r\n <div class=\"padder\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12\">\r\n <tmw-image-drawer *ngIf=\"drawingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\" [showCancelButton]=\"false\" [enableLoadAnotherImage]=\"false\"\r\n [enableRemoveImage]=\"false\" [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\" [i18n]=\"i18n\" [showCancelButton]=\"true\"\r\n (save)=\"saveDraw($event)\" (loadOriginal)=\"loadOriginal()\"\r\n (closeDialog)=\"closeImageDrowingDialog()\">\r\n </tmw-image-drawer>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TmwImageDrawerComponent, selector: "tmw-image-drawer", inputs: ["src", "width", "height", "forceSizeCanvas", "forceSizeExport", "enableRemoveImage", "enableLoadAnotherImage", "enableTooltip", "showCancelButton", "inConfig", "i18n", "locale", "loadingTemplate", "errorTemplate", "outputMimeType", "outputQuality", "borderCss", "drawingSizes", "colors"], outputs: ["closeDialog", "save", "loadOriginal"] }] });
6128
+ ImageFieldTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImageFieldTemplateComponent, selector: "image-field-template", inputs: { endPointConfiguration: "endPointConfiguration", record: "record", formulaObject: "formulaObject", field: "field", inConfig: "inConfig", styleVersion: "styleVersion", forceState: "forceState" }, outputs: { recordChange: "recordChange", imageDraw: "imageDraw" }, viewQueries: [{ propertyName: "dialogImageDrawing", first: true, predicate: ["dialogImageDrawing"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\">\r\n </div>\r\n <div *ngIf=\"field.EnableDrawing\" class=\"col-12 drawButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openDraw()\">Disegna</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonKey != null && field.DynAttachment?.ButtonKey != ''\"\r\n class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div>\r\n <div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonValue != null && field.DynAttachment?.ButtonValue != ''\"\r\n class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER DISEGNARE SUL NUOVO ALLEGATO CARICATO -->\r\n<ng-template #dialogImageDrawing>\r\n <div class=\"padder\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12\">\r\n <tmw-image-drawer *ngIf=\"drawingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\" [showCancelButton]=\"false\" [enableLoadAnotherImage]=\"false\"\r\n [enableRemoveImage]=\"false\" [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\" [i18n]=\"i18n\" [showCancelButton]=\"true\"\r\n (save)=\"saveDraw($event)\" (loadOriginal)=\"loadOriginal()\"\r\n (closeDialog)=\"closeImageDrowingDialog()\">\r\n </tmw-image-drawer>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TmwImageDrawerComponent, selector: "tmw-image-drawer", inputs: ["src", "width", "height", "forceSizeCanvas", "forceSizeExport", "enableRemoveImage", "enableLoadAnotherImage", "enableTooltip", "showCancelButton", "inConfig", "i18n", "locale", "loadingTemplate", "errorTemplate", "outputMimeType", "outputQuality", "borderCss", "drawingSizes", "colors"], outputs: ["closeDialog", "save", "loadOriginal"] }] });
6095
6129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImageFieldTemplateComponent, decorators: [{
6096
6130
  type: Component,
6097
- args: [{ selector: 'image-field-template', template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\">\r\n </div>\r\n <div *ngIf=\"field.EnableDrawing\" class=\"col-12 drawButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openDraw()\">Disegna</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonKey != null && field.DynAttachment.ButtonKey != ''\"\r\n class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div>\r\n <div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonValue != null && field.DynAttachment.ButtonValue != ''\"\r\n class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER DISEGNARE SUL NUOVO ALLEGATO CARICATO -->\r\n<ng-template #dialogImageDrawing>\r\n <div class=\"padder\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12\">\r\n <tmw-image-drawer *ngIf=\"drawingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\" [showCancelButton]=\"false\" [enableLoadAnotherImage]=\"false\"\r\n [enableRemoveImage]=\"false\" [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\" [i18n]=\"i18n\" [showCancelButton]=\"true\"\r\n (save)=\"saveDraw($event)\" (loadOriginal)=\"loadOriginal()\"\r\n (closeDialog)=\"closeImageDrowingDialog()\">\r\n </tmw-image-drawer>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"] }]
6131
+ args: [{ selector: 'image-field-template', template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\">\r\n </div>\r\n <div *ngIf=\"field.EnableDrawing\" class=\"col-12 drawButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openDraw()\">Disegna</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonKey != null && field.DynAttachment?.ButtonKey != ''\"\r\n class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div>\r\n <div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonValue != null && field.DynAttachment?.ButtonValue != ''\"\r\n class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER DISEGNARE SUL NUOVO ALLEGATO CARICATO -->\r\n<ng-template #dialogImageDrawing>\r\n <div class=\"padder\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12\">\r\n <tmw-image-drawer *ngIf=\"drawingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\" [showCancelButton]=\"false\" [enableLoadAnotherImage]=\"false\"\r\n [enableRemoveImage]=\"false\" [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\" [i18n]=\"i18n\" [showCancelButton]=\"true\"\r\n (save)=\"saveDraw($event)\" (loadOriginal)=\"loadOriginal()\"\r\n (closeDialog)=\"closeImageDrowingDialog()\">\r\n </tmw-image-drawer>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"] }]
6098
6132
  }], ctorParameters: function () { return [{ type: i1$3.MatDialog }, { type: UtilityHelperService }, { type: i0.Renderer2 }]; }, propDecorators: { endPointConfiguration: [{
6099
6133
  type: Input
6100
6134
  }], record: [{
@@ -7113,10 +7147,10 @@ class ImageWithMarkersFieldTemplateComponent {
7113
7147
  }
7114
7148
  }
7115
7149
  ImageWithMarkersFieldTemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImageWithMarkersFieldTemplateComponent, deps: [{ token: i1$3.MatDialog }, { token: UtilityHelperService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
7116
- ImageWithMarkersFieldTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImageWithMarkersFieldTemplateComponent, selector: "image-with-markers-field-template", inputs: { endPointConfiguration: "endPointConfiguration", record: "record", formulaObject: "formulaObject", field: "field", inConfig: "inConfig", styleVersion: "styleVersion", forceState: "forceState" }, outputs: { recordChange: "recordChange", imageMark: "imageMark" }, viewQueries: [{ propertyName: "dialogImageMarking", first: true, predicate: ["dialogImageMarking"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\"\r\n >\r\n </div>\r\n <div class=\"col-12 markButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openMark()\">Marca</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonKey != null && field.DynAttachment.ButtonKey != ''\" class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div><div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonValue != null && field.DynAttachment.ButtonValue != ''\" class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER MARCATURA -->\r\n<ng-template #dialogImageMarking>\r\n <tmw-image-marker *ngIf=\"MarkingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\"\r\n [savedMarkers]=\"extraJSON\"\r\n (save)=\"saveMark($event)\"\r\n (closeDialog)=\"closeDialog()\"\r\n [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\"\r\n >\r\n </tmw-image-marker>\r\n</ng-template>\r\n", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TmwImageMarkerComponent, selector: "tmw-image-marker", inputs: ["src", "width", "height", "inConfig", "savedMarkers", "outputMimeType", "outputQuality", "forceSizeCanvas"], outputs: ["closeDialog", "save"] }] });
7150
+ ImageWithMarkersFieldTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ImageWithMarkersFieldTemplateComponent, selector: "image-with-markers-field-template", inputs: { endPointConfiguration: "endPointConfiguration", record: "record", formulaObject: "formulaObject", field: "field", inConfig: "inConfig", styleVersion: "styleVersion", forceState: "forceState" }, outputs: { recordChange: "recordChange", imageMark: "imageMark" }, viewQueries: [{ propertyName: "dialogImageMarking", first: true, predicate: ["dialogImageMarking"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\"\r\n >\r\n </div>\r\n <div class=\"col-12 markButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openMark()\">Marca</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonKey != null && field.DynAttachment?.ButtonKey != ''\" class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div><div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonValue != null && field.DynAttachment?.ButtonValue != ''\" class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER MARCATURA -->\r\n<ng-template #dialogImageMarking>\r\n <tmw-image-marker *ngIf=\"MarkingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\"\r\n [savedMarkers]=\"extraJSON\"\r\n (save)=\"saveMark($event)\"\r\n (closeDialog)=\"closeDialog()\"\r\n [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\"\r\n >\r\n </tmw-image-marker>\r\n</ng-template>\r\n", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TmwImageMarkerComponent, selector: "tmw-image-marker", inputs: ["src", "width", "height", "inConfig", "savedMarkers", "outputMimeType", "outputQuality", "forceSizeCanvas"], outputs: ["closeDialog", "save"] }] });
7117
7151
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ImageWithMarkersFieldTemplateComponent, decorators: [{
7118
7152
  type: Component,
7119
- args: [{ selector: 'image-with-markers-field-template', template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\"\r\n >\r\n </div>\r\n <div class=\"col-12 markButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openMark()\">Marca</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonKey != null && field.DynAttachment.ButtonKey != ''\" class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div><div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment.ButtonValue != null && field.DynAttachment.ButtonValue != ''\" class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER MARCATURA -->\r\n<ng-template #dialogImageMarking>\r\n <tmw-image-marker *ngIf=\"MarkingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\"\r\n [savedMarkers]=\"extraJSON\"\r\n (save)=\"saveMark($event)\"\r\n (closeDialog)=\"closeDialog()\"\r\n [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\"\r\n >\r\n </tmw-image-marker>\r\n</ng-template>\r\n", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"] }]
7153
+ args: [{ selector: 'image-with-markers-field-template', template: "<div id=\"{{fieldUid}}\">\r\n <div class=\"row imageContainer\">\r\n <div class=\"row\">\r\n <div class=\"col-12 image-label\">{{field.Description}}</div>\r\n <div class=\"col-12\">\r\n <img *ngIf=\"field.DynAttachment\"\r\n src=\"data:{{field.DynAttachment.FileContentType}};base64,{{FileDataBase64}}\"\r\n [height]=\"field.DynAttachment.ResizedImageHeightPx != null ? field.DynAttachment.ResizedImageHeightPx : 128\"\r\n class=\"singleImage\"\r\n >\r\n </div>\r\n <div class=\"col-12 markButton\">\r\n <button class=\"btn btn-primary btn-w100\" (click)=\"openMark()\">Marca</button>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonKey != null && field.DynAttachment?.ButtonKey != ''\" class=\"col-12 flex justify-content-around buttonkey\">\r\n <div>Etichetta</div><div>{{field.DynAttachment.ButtonKey}}</div>\r\n </div>\r\n <div *ngIf=\"field.DynAttachment?.ButtonValue != null && field.DynAttachment?.ButtonValue != ''\" class=\"col-12 flex justify-content-around buttonvalue\">\r\n <div>Valore</div>\r\n <div>{{field.DynAttachment.ButtonValue}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- DIALOG PER MARCATURA -->\r\n<ng-template #dialogImageMarking>\r\n <tmw-image-marker *ngIf=\"MarkingLoaded\"\r\n [src]=\"'data:'+ field.DynAttachment.FileContentType + ';base64,'+ FileBase64\"\r\n [inConfig]=\"inConfig\"\r\n [savedMarkers]=\"extraJSON\"\r\n (save)=\"saveMark($event)\"\r\n (closeDialog)=\"closeDialog()\"\r\n [width]=\"field.DynAttachment.ImageWidthPx\"\r\n [height]=\"field.DynAttachment.ImageHeightPx\"\r\n >\r\n </tmw-image-marker>\r\n</ng-template>\r\n", styles: ["::ng-deep image-drawing>button{background-color:var(--primary)!important;color:#fff!important}.imageContainer .singleImage{margin-top:5px;display:block}.drawButton{margin:5px 0}.buttonkey{border-top:1px solid black;padding-top:10px}\n"] }]
7120
7154
  }], ctorParameters: function () { return [{ type: i1$3.MatDialog }, { type: UtilityHelperService }, { type: i0.Renderer2 }]; }, propDecorators: { endPointConfiguration: [{
7121
7155
  type: Input
7122
7156
  }], record: [{
@@ -8302,16 +8336,11 @@ class AddFormRecordComponent {
8302
8336
  this.loader = false;
8303
8337
  this.isSaving = false;
8304
8338
  this.formloaded = false;
8339
+ this._recordChanging = false;
8305
8340
  this.fieldGroups = {};
8306
8341
  this.FormScalarTypeEnum = FormScalarTypeEnum;
8307
8342
  this.FieldTypeEnum = FieldTypeEnum;
8308
8343
  this.visibleActionButtons = new Array();
8309
- //#region onRecordChange
8310
- /**
8311
- * Metodo invocato al cambio del valore di ogni proprietà dell'oggetto record.
8312
- * Serve ad aggiornare il valore di tutti i campi che hanno una formula.
8313
- */
8314
- this._isInRecordChange = false;
8315
8344
  }
8316
8345
  ngOnInit() {
8317
8346
  injectGoogleFontsFromForm(this.form);
@@ -8357,14 +8386,18 @@ class AddFormRecordComponent {
8357
8386
  GlobalService.speechDirective.SpeechToTextToggler();
8358
8387
  }
8359
8388
  }
8389
+ //#region onRecordChange
8390
+ /**
8391
+ * Metodo invocato al cambio del valore di ogni proprietà dell'oggetto record.
8392
+ * Serve ad aggiornare il valore di tutti i campi che hanno una formula.
8393
+ * Il guard _recordChanging previene la rientranza: i campi formula aggiornano
8394
+ * record[name] e ciò riemette recordChange; senza guard si genera un loop infinito.
8395
+ */
8360
8396
  onRecordChange() {
8361
8397
  var _a;
8362
- // Guardia di rientranza: setValue sui FormControl può triggerare writeValue sui ControlValueAccessor
8363
- // (es. mat-datepicker), che emettono (dateChange)/(ngModelChange) → recordChange → loop infinito.
8364
- if (this._isInRecordChange) {
8398
+ if (this._recordChanging)
8365
8399
  return;
8366
- }
8367
- this._isInRecordChange = true;
8400
+ this._recordChanging = true;
8368
8401
  try {
8369
8402
  if (this.fieldTemplate && this.fieldTemplate.length > 0) {
8370
8403
  this.fieldTemplate.forEach((f) => {
@@ -8373,21 +8406,18 @@ class AddFormRecordComponent {
8373
8406
  }
8374
8407
  });
8375
8408
  }
8376
- // Le formule aggiornano record[fieldName] direttamente, senza passare dal FormControl.
8377
- // Qui risincronizziamo i FormControl il cui valore è cambiato rispetto al record,
8378
- // altrimenti la validazione required fallisce sui campi valorizzati via formula/ActionButton.
8409
+ // I validator required leggono da record[field.Name] (closure su record), quindi basta
8410
+ // chiamare updateValueAndValidity per far rileggere il valore aggiornato dalla formula/ActionButton.
8411
+ // Non si usa setValue per evitare che writeValue sui ControlValueAccessor scateni eventi → loop.
8379
8412
  if ((_a = this.form) === null || _a === void 0 ? void 0 : _a.Fields) {
8380
8413
  this.form.Fields.forEach(field => {
8381
- var _a;
8382
- const ctrl = (_a = field.FormFormGroup) === null || _a === void 0 ? void 0 : _a.get(field.Name);
8383
- if (ctrl != null && ctrl.value !== this.record[field.Name]) {
8384
- ctrl.setValue(this.record[field.Name], { emitEvent: false });
8385
- }
8414
+ var _a, _b;
8415
+ (_b = (_a = field.FormFormGroup) === null || _a === void 0 ? void 0 : _a.get(field.Name)) === null || _b === void 0 ? void 0 : _b.updateValueAndValidity({ emitEvent: false });
8386
8416
  });
8387
8417
  }
8388
8418
  }
8389
8419
  finally {
8390
- this._isInRecordChange = false;
8420
+ this._recordChanging = false;
8391
8421
  }
8392
8422
  }
8393
8423
  //#endregion onRecordChange
@@ -15899,7 +15929,9 @@ class AddFormFieldComponent {
15899
15929
  disableClose: true,
15900
15930
  hasBackdrop: true,
15901
15931
  panelClass: 'query-editor-modal',
15902
- width: '90%'
15932
+ width: '90%',
15933
+ maxHeight: '90vh',
15934
+ position: { top: '20px' },
15903
15935
  });
15904
15936
  }
15905
15937
  else {