wuic-framework-lib 1.5.0 → 1.7.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 (27) hide show
  1. package/fesm2022/{wuic-framework-lib-chart-list.component-0J1ghIrS.mjs → wuic-framework-lib-chart-list.component-Dq9IEKsY.mjs} +50 -38
  2. package/fesm2022/{wuic-framework-lib-code-editor.component-C21mvjyr.mjs → wuic-framework-lib-code-editor.component-B6IpTSo8.mjs} +174 -274
  3. package/fesm2022/{wuic-framework-lib-designer.component-x10ZzUEy.mjs → wuic-framework-lib-designer.component-D6cbqNFg.mjs} +499 -581
  4. package/fesm2022/wuic-framework-lib-first-run-wizard.component-D1ZQUl-q.mjs +1630 -0
  5. package/fesm2022/{wuic-framework-lib-framework-docs.component-xTGLbEnp.mjs → wuic-framework-lib-framework-docs.component-C_o5r7pg.mjs} +4320 -1255
  6. package/fesm2022/{wuic-framework-lib-pivot-builder.component-BkFFjPm4.mjs → wuic-framework-lib-pivot-builder.component-DkWGzJpr.mjs} +580 -68
  7. package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-Bi-TrJB6.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-D29go5yA.mjs} +2 -2
  8. package/fesm2022/wuic-framework-lib-report-designer.component-DcpCWghx.mjs +380 -0
  9. package/fesm2022/wuic-framework-lib-report-scaffold-dialog.component-CgUjG7Bi.mjs +431 -0
  10. package/fesm2022/{wuic-framework-lib-report-viewer.component-BR-BfI2r.mjs → wuic-framework-lib-report-viewer.component-C4Opgl_M.mjs} +8 -13
  11. package/fesm2022/{wuic-framework-lib-scene3d-designer.component-BQzFxSXP.mjs → wuic-framework-lib-scene3d-designer.component-8l3vsyEb.mjs} +323 -88
  12. package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-0LjqhSNn.mjs → wuic-framework-lib-scene3d-light-baker-gpu-C1w-8Aai.mjs} +2 -2
  13. package/fesm2022/{wuic-framework-lib-scene3d-shader-effect-CQLWkuh1.mjs → wuic-framework-lib-scene3d-shader-effect-DjHyCAFK.mjs} +612 -32
  14. package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-imoV3HOs.mjs → wuic-framework-lib-scene3d-viewer.component-nMSl5jbe.mjs} +149 -18
  15. package/fesm2022/{wuic-framework-lib-scheduler-list.component-xzlTEkoq.mjs → wuic-framework-lib-scheduler-list.component-Cvk3Zg0Q.mjs} +169 -53
  16. package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-CrS6fOGj.mjs → wuic-framework-lib-spreadsheet-list-sf.component-C1U7JPiq.mjs} +149 -108
  17. package/fesm2022/{wuic-framework-lib-stimulsoft-license.service-BIyxB4pO.mjs → wuic-framework-lib-stimulsoft-license.service-CsNNSFYs.mjs} +3 -3
  18. package/fesm2022/wuic-framework-lib-timeline-list.component-cZbPgNh1.mjs +805 -0
  19. package/fesm2022/{wuic-framework-lib-workflow-designer.component-5xtQ7-6z.mjs → wuic-framework-lib-workflow-designer.component-C_4RQGa0.mjs} +180 -150
  20. package/fesm2022/{wuic-framework-lib-wuic-framework-lib-3TZ-j-yL.mjs → wuic-framework-lib-wuic-framework-lib-BZZwta8b.mjs} +6785 -2347
  21. package/fesm2022/wuic-framework-lib.mjs +1 -1
  22. package/package.json +21 -2
  23. package/styles/_wuic-tokens.scss +82 -0
  24. package/styles/styles.scss +160 -0
  25. package/types/wuic-framework-lib.d.ts +4269 -2691
  26. package/fesm2022/wuic-framework-lib-first-run-wizard.component-BuSxs_CM.mjs +0 -1316
  27. package/fesm2022/wuic-framework-lib-report-designer.component-ZvB46-LV.mjs +0 -194
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Output, Input, Component, inject, ElementRef, SecurityContext, ViewChild, HostBinding } from '@angular/core';
2
+ import { EventEmitter, Output, Input, Component, inject, ElementRef, NgZone, ChangeDetectorRef, SecurityContext, ViewChild, HostBinding } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormsModule } from '@angular/forms';
5
5
  import * as i1$1 from '@materia-ui/ngx-monaco-editor';
6
6
  import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
7
7
  import { filter, take } from 'rxjs/operators';
8
8
  import { Emitter } from 'monaco-editor/esm/vs/base/common/event';
9
- import { W as WtoolboxService, M as MetadataProviderService, e as MetadatiColonna, m as MetaInfo, U as UserInfoService, f as DataProviderService } from './wuic-framework-lib-wuic-framework-lib-3TZ-j-yL.mjs';
9
+ import { W as WtoolboxService, M as MetadataProviderService, g as MetadatiColonna, o as MetaInfo, U as UserInfoService, h as DataProviderService } from './wuic-framework-lib-wuic-framework-lib-BZZwta8b.mjs';
10
10
  import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common';
11
- import * as i10 from 'primeng/contextmenu';
11
+ import * as i14 from 'primeng/contextmenu';
12
12
  import { ContextMenuModule } from 'primeng/contextmenu';
13
13
  import * as i4 from 'primeng/tree';
14
14
  import { TreeModule } from 'primeng/tree';
@@ -92,9 +92,6 @@ class Statement {
92
92
  }
93
93
  }
94
94
 
95
- // import { editor } from 'monaco-editor';
96
- // import { LinkedList } from 'monaco-editor/esm/vs/base/common/linkedList';
97
- // import { MenuId, MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions';
98
95
  class SqlProvider {
99
96
  http;
100
97
  currents;
@@ -124,8 +121,6 @@ class SqlProvider {
124
121
  this.editor = editor;
125
122
  this.editor['_onDropIntoEditor'] = this.editor['_register'](new DragDropInteractionEmitter$1(this.editor['_contributions'], this.editor['_deliveryQueue'], this.editor, this));
126
123
  this.editor['onDropIntoEditor'] = this.editor['_onDropIntoEditor'].event;
127
- // this._onContextMenu = this._register(new InteractionEmitter(this._contributions, this._deliveryQueue));
128
- // this.onContextMenu = this._onContextMenu.event;
129
124
  this.editor['_onContextMenu'] = this.editor['_register'](new ContextMenuInteractionEmitter$1(this.editor['_contributions'], this.editor['_deliveryQueue'], this.editor, this));
130
125
  this.editor['onContextMenu'] = this.editor['_onContextMenu'].event;
131
126
  }
@@ -196,10 +191,8 @@ class SqlProvider {
196
191
  }
197
192
  });
198
193
  this.editorOptions.onNodeClick = (event, dataItem) => {
199
- // debugger;
200
194
  };
201
195
  this.editorOptions.onInit = (editor) => {
202
- // debugger;
203
196
  this.editor = editor;
204
197
  };
205
198
  this.editorOptions.onNodeDragStart = (event, dataItem) => {
@@ -208,50 +201,11 @@ class SqlProvider {
208
201
  event.dataTransfer.setData("text/plain", JSON.stringify(dataItem));
209
202
  };
210
203
  this.editorOptions.onNodeDragEnd = (event, dataItem) => {
211
- // debugger;
212
204
  };
213
205
  // monaco.languages.registerSignatureHelpProvider('sql', {
214
206
  // signatureHelpTriggerCharacters: ['(', ','],
215
207
  // provideSignatureHelp: (model: monaco.editor.ITextModel, position: monaco.Position, token: any, context: any) => {
216
- // var lastWord = model.getWordUntilPosition(position); //getWordUntilPosition //getWordAtPosition
217
- // var originalText = model.getValueInRange(model.getFullModelRange());
218
- // var fullText = this.sanitize(originalText);
219
- // var range: IRange = {
220
- // startLineNumber: position.lineNumber,
221
- // endLineNumber: position.lineNumber,
222
- // startColumn: lastWord.startColumn,
223
- // endColumn: lastWord.endColumn,
224
- // };
225
- // var contextInfo = this.getContextInfo(originalText, position);
226
- // this.parseStatements();
227
- // var currentStatement = this.currents.statements.find(x => x.index == contextInfo.currentStmntIndex);
228
- // if (currentStatement && currentStatement.words.length > 0
229
- // && currentStatement.words[0].toUpperCase() == 'INSERT INTO') {
230
208
  // } else {
231
- // return {
232
- // dispose: () => { },
233
- // value: {
234
- // activeParameter: 0,
235
- // activeSignature: 0,
236
- // signatures: [{
237
- // label: 'string substr(string $string, int $start [, int $length])',
238
- // parameters: [
239
- // {
240
- // label: 'string $string',
241
- // documentation: 'The input string. Must be one character or longer.'
242
- // },
243
- // {
244
- // label: 'int $start',
245
- // documentation: "If "
246
- // },
247
- // {
248
- // label: 'int $length',
249
- // documentation: 'If '
250
- // }
251
- // ]
252
- // }]
253
- // }
254
- // };
255
209
  // }
256
210
  // }
257
211
  // });
@@ -387,7 +341,7 @@ class SqlProvider {
387
341
  * @returns SQL sanificato in singola linea.
388
342
  */
389
343
  sanitize(str) {
390
- return str.replace(/(\r\n|\n|\r|\t)/gm, " ").replace(/ +(?= )/g, '');
344
+ return str.replaceAll(/(\r\n|\n|\r|\t)/gm, " ").replaceAll(/ +(?= )/g, '');
391
345
  }
392
346
  normalizeStatement(previousWords) {
393
347
  let skipNext = false;
@@ -567,8 +521,8 @@ class SqlProvider {
567
521
  if (!levelBlock && position.column == 1 && position.lineNumber > 1) {
568
522
  let levelLineBlock = parsedText.filter(y => y.find(z => z.lineNumber == position.lineNumber - 1));
569
523
  if (levelLineBlock.length > 0) {
570
- levelBlock = levelLineBlock[levelLineBlock.length - 1];
571
- charToken = levelBlock[levelBlock.length - 1];
524
+ levelBlock = levelLineBlock.at(-1);
525
+ charToken = levelBlock.at(-1);
572
526
  }
573
527
  }
574
528
  else {
@@ -576,7 +530,7 @@ class SqlProvider {
576
530
  }
577
531
  if (!levelBlock) {
578
532
  // Fallback: pick last parsed row block so autocomplete can continue safely.
579
- levelBlock = parsedText[parsedText.length - 1];
533
+ levelBlock = parsedText.at(-1);
580
534
  }
581
535
  if (!charToken) {
582
536
  charToken = levelBlock?.[levelBlock.length - 1];
@@ -634,7 +588,8 @@ class SqlProvider {
634
588
  let statementIndex = 1;
635
589
  let txtLines = originalText.split('\r\n');
636
590
  let nestedStatements = this.getNestedStatements(originalText);
637
- let parsedInput = this.processText(originalText, position);
591
+ let parsedInput;
592
+ this.processText(originalText, position);
638
593
  let adjacentChars = '';
639
594
  let x = txtLines[position.lineNumber - 1];
640
595
  if (x.length >= position.column - 1) {
@@ -661,7 +616,7 @@ class SqlProvider {
661
616
  absolutePosition = endPosition;
662
617
  previousWords = previousWords.concat(line.split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x, statementIndx: statementIndex }; }));
663
618
  if (cleanString != line) {
664
- previousNonNestedWords = previousNonNestedWords.concat(cleanString.substring(0, Math.min(position.column, line.length)).split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x.replace(/§/g, ''), statementIndx: statementIndex }; }));
619
+ previousNonNestedWords = previousNonNestedWords.concat(cleanString.substring(0, Math.min(position.column, line.length)).split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x.replaceAll('§', ''), statementIndx: statementIndex }; }));
665
620
  }
666
621
  else {
667
622
  previousNonNestedWords = previousNonNestedWords.concat(previousWords);
@@ -679,7 +634,7 @@ class SqlProvider {
679
634
  absolutePosition = endPosition;
680
635
  previousWords = previousWords.concat(line.substring(0, Math.min(position.column, line.length)).split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x, statementIndx: statementIndex }; }));
681
636
  if (cleanString != line) {
682
- previousNonNestedWords = previousNonNestedWords.concat(cleanString.substring(0, Math.min(position.column, line.length)).split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x.replace(/§/g, ''), statementIndx: statementIndex }; }));
637
+ previousNonNestedWords = previousNonNestedWords.concat(cleanString.substring(0, Math.min(position.column, line.length)).split(' ').filter(x => x.length > 0).map(x => x.trim().toUpperCase()).map(x => { return { word: x.replaceAll('§', ''), statementIndx: statementIndex }; }));
683
638
  }
684
639
  else {
685
640
  previousNonNestedWords = previousNonNestedWords.concat(previousWords);
@@ -734,8 +689,8 @@ class SqlProvider {
734
689
  let normalized = this.normalizeStatement(contextWords.map((x, indx) => { return { token: x.word, tokenIndx: indx }; }));
735
690
  currentStatementWords = normalized.map(x => x.token.replace("(", ""));
736
691
  let keywordIndx = -1;
737
- let matchingKeyWords = currentStatementWords.filter(x => sqlKeywords.indexOf(x.toUpperCase()) >= 0);
738
- let matchingKeyWord = matchingKeyWords.length > 0 ? matchingKeyWords[matchingKeyWords.length - 1] : '';
692
+ let matchingKeyWords = currentStatementWords.filter(x => sqlKeywords.includes(x.toUpperCase()));
693
+ let matchingKeyWord = matchingKeyWords.length > 0 ? matchingKeyWords.at(-1) : '';
739
694
  if (matchingKeyWord) {
740
695
  keywordIndx = sqlKeywords.indexOf(matchingKeyWord.toUpperCase());
741
696
  }
@@ -765,7 +720,7 @@ class SqlProvider {
765
720
  let currentSubStmntWords = subStmnt.statement.words;
766
721
  switch (subStmnt.key) {
767
722
  case 'DECLARE':
768
- if (currentSubStmntWords[currentSubStmntWords.length - 1].token.indexOf('@') < 0) {
723
+ if (!currentSubStmntWords[currentSubStmntWords.length - 1].token.includes('@')) {
769
724
  return autocompleteContext.declaration;
770
725
  }
771
726
  else {
@@ -786,37 +741,38 @@ class SqlProvider {
786
741
  console.log('table!!!');
787
742
  return autocompleteContext.table;
788
743
  });
789
- case 'SELECT':
744
+ case 'SELECT': {
790
745
  let previousWord;
791
746
  let nextWord;
792
747
  let previousWords = currentSubStmntWords.filter(x => x.tokenIndx < contextInfo.position.column - 1);
793
748
  if (previousWords.length > 0) {
794
- previousWord = previousWords[previousWords.length - 1];
749
+ previousWord = previousWords.at(-1);
795
750
  }
796
751
  let nextWords = currentSubStmntWords.filter(x => x.tokenIndx >= contextInfo.position.column - 1);
797
752
  if (nextWords.length > 0) {
798
753
  nextWord = nextWords[0];
799
754
  }
800
- let selectLastToken = (currentSubStmntWords[currentSubStmntWords.length - 1]?.token || '').trim();
801
- if (selectLastToken.indexOf('.') >= 0) {
755
+ let selectLastToken = (currentSubStmntWords.at(-1)?.token || '').trim();
756
+ if (selectLastToken.includes('.')) {
802
757
  // Alias-qualified column completion (e.g. AppCit. or AppCit.Sta)
803
758
  return autocompleteContext.columnWhereRestricted;
804
759
  }
805
760
  if (contextInfo.adjacentChars == '()' || (previousWord && nextWord && previousWord.token[previousWord.token.length - 1] == '(' && nextWord.token[0] == ')')) {
806
761
  return autocompleteContext.columnSelect;
807
762
  }
808
- else if (currentSubStmntWords[currentSubStmntWords.length - 1].token.indexOf(',') >= 0 || currentSubStmntWords[currentSubStmntWords.length - 1].token.toUpperCase() == 'SELECT') {
763
+ else if (currentSubStmntWords.at(-1).token.includes(',') || currentSubStmntWords.at(-1).token.toUpperCase() == 'SELECT') {
809
764
  return autocompleteContext.columnSelect;
810
765
  }
811
766
  else {
812
767
  return autocompleteContext.statementFrom;
813
768
  }
769
+ }
814
770
  case 'FROM':
815
771
  // After at least one table in FROM, allow partial clause prefixes
816
772
  // (e.g. "I" => "INNER JOIN") while keeping schema suggestions otherwise.
817
773
  return this.evaluateAutocompleteContext(contextInfo, subStmnt.statement, false, subStmnt.statement.sqlTables.length > 0 ? autocompleteContext.statementWhereJoin : null);
818
774
  case 'AS':
819
- if (matchingKeyWords.length > 1 && matchingKeyWords[matchingKeyWords.length - 2] == 'WITH') {
775
+ if (matchingKeyWords.length > 1 && matchingKeyWords.at(-2) == 'WITH') {
820
776
  return autocompleteContext.statementSelect;
821
777
  }
822
778
  else {
@@ -832,16 +788,18 @@ class SqlProvider {
832
788
  if (schemaTableAliasToken) {
833
789
  let schemaAndTableOrAlias = schemaTableAliasToken.token.split('.').filter(x => x.length > 0);
834
790
  if (schemaAndTableOrAlias.length > 0) {
791
+ // intentionally empty: schema part already typed, fall through to next token checks
835
792
  }
836
793
  else {
837
794
  return autocompleteContext.schema;
838
795
  }
839
796
  if (schemaAndTableOrAlias.length >= 1) {
797
+ // intentionally empty: table part already typed, fall through to join context checks
840
798
  }
841
799
  else {
842
800
  return autocompleteContext.table;
843
801
  }
844
- if (currentSubStmntWords[currentSubStmntWords.length - 1].token.toUpperCase() == subStmnt.key.toUpperCase()) {
802
+ if (currentSubStmntWords.at(-1).token.toUpperCase() == subStmnt.key.toUpperCase()) {
845
803
  return autocompleteContext.schemaJoin;
846
804
  }
847
805
  else {
@@ -862,28 +820,24 @@ class SqlProvider {
862
820
  case 'GROUP BY':
863
821
  return autocompleteContext.columnGroupBy;
864
822
  case 'SET':
865
- if (currentSubStmntWords[currentSubStmntWords.length - 1].token.trim().toUpperCase() == 'SET') {
823
+ if (currentSubStmntWords.at(-1).token.trim().toUpperCase() == 'SET') {
866
824
  let updtStmnt = currentStmnt.subStatements.find(x => x.key == 'UPDATE');
867
825
  if (updtStmnt && updtStmnt.statement.words.length > 1) {
868
- // this.currents.table = updtStmnt.statement.sqlTables[updtStmnt.statement.sqlTables.length - 1];
869
826
  return autocompleteContext.columnWhere;
870
827
  }
871
828
  else {
872
829
  return autocompleteContext.variable;
873
830
  }
874
831
  }
832
+ else if (currentSubStmntWords.at(-1).token.trim().endsWith(',')) {
833
+ return autocompleteContext.columnWhere;
834
+ }
835
+ else if (currentSubStmntWords.at(-1).token.trim() == '=') {
836
+ return autocompleteContext.columnWhereAndVariables;
837
+ }
875
838
  else {
876
- if (currentSubStmntWords[currentSubStmntWords.length - 1].token.trim().endsWith(',')) {
877
- return autocompleteContext.columnWhere;
878
- }
879
- else if (currentSubStmntWords[currentSubStmntWords.length - 1].token.trim() == '=') {
880
- return autocompleteContext.columnWhereAndVariables;
881
- }
882
- else {
883
- return autocompleteContext.assignmentOperator;
884
- }
839
+ return autocompleteContext.assignmentOperator;
885
840
  }
886
- break;
887
841
  }
888
842
  }
889
843
  }
@@ -892,7 +846,7 @@ class SqlProvider {
892
846
  }
893
847
  evaluateAutocompleteContext(contextInfo, statement, skipAs = false, defaultAutoCtx = null, contextDelegate = null) {
894
848
  const lastToken = statement?.words?.length
895
- ? (statement.words[statement.words.length - 1].token || '').trim()
849
+ ? (statement.words.at(-1).token || '').trim()
896
850
  : '';
897
851
  const lastDotIndex = lastToken.lastIndexOf('.');
898
852
  if (lastDotIndex >= 0) {
@@ -907,18 +861,14 @@ class SqlProvider {
907
861
  return defaultAutoCtx;
908
862
  }
909
863
  }
864
+ else if (statement.sqlTables.length > 0) {
865
+ return autocompleteContext.columnWhereRestricted;
866
+ }
867
+ else if (!skipAs) {
868
+ return autocompleteContext.table;
869
+ }
910
870
  else {
911
- if (statement.sqlTables.length > 0) {
912
- return autocompleteContext.columnWhereRestricted;
913
- }
914
- else {
915
- if (!skipAs) {
916
- return autocompleteContext.table;
917
- }
918
- else {
919
- return autocompleteContext.tableNoAs;
920
- }
921
- }
871
+ return autocompleteContext.tableNoAs;
922
872
  }
923
873
  }
924
874
  else {
@@ -957,7 +907,7 @@ class SqlProvider {
957
907
  * @returns Context specifico WHERE.
958
908
  */
959
909
  evaluateAutocompleteWhereContext(currents, currentStatementWords, whereSubStatemnt) {
960
- let lastToken = currentStatementWords[currentStatementWords.length - 1].trim().toUpperCase();
910
+ let lastToken = currentStatementWords.at(-1).trim().toUpperCase();
961
911
  if (lastToken == 'AND' || lastToken == 'WHERE') {
962
912
  return autocompleteContext.columnWhere;
963
913
  }
@@ -1003,7 +953,6 @@ class SqlProvider {
1003
953
  }
1004
954
  let subStatement;
1005
955
  let nestedStatements = this.getNestedStatements(statement);
1006
- let z = nestedStatements[0];
1007
956
  statementObj.statement = this.removeNestedStatements(statement, nestedStatements);
1008
957
  let previousWords = statement.split(' ').filter(x => x.length > 0).map((x, splitIndx) => {
1009
958
  return {
@@ -1023,8 +972,7 @@ class SqlProvider {
1023
972
  const elementObj = sanitizedPreviousWords[indx];
1024
973
  let element = elementObj.token;
1025
974
  let indxOffset = 0;
1026
- for (let nestedIndex = 0; nestedIndex < nestedStatements.length; nestedIndex++) {
1027
- nested = nestedStatements[nestedIndex];
975
+ for (nested of nestedStatements) {
1028
976
  if (nested.length > 1 && elementObj.tokenIndx >= nested.index && elementObj.tokenIndx <= nested.index + nested[1].length) {
1029
977
  this.parseStatementRecursive(nested[1], indx, subStatement);
1030
978
  let firstWordOutsideNested = sanitizedPreviousWords.find(x => x.tokenIndx > nested.index + nested[1].length);
@@ -1035,7 +983,7 @@ class SqlProvider {
1035
983
  indx = indxOffset;
1036
984
  continue;
1037
985
  }
1038
- if (sqlKeywords.indexOf(element.toUpperCase()) >= 0) {
986
+ if (sqlKeywords.includes(element.toUpperCase())) {
1039
987
  currentStatementTag = element;
1040
988
  subStatement = new Statement(element, Object.keys(statementObj.subStatements).length + 1);
1041
989
  subStatement.words.push(elementObj);
@@ -1102,7 +1050,7 @@ class SqlProvider {
1102
1050
  }
1103
1051
  return col;
1104
1052
  });
1105
- if (!this.currents.globalTables.find(x => x.table.toUpperCase() == table.table.toUpperCase())) {
1053
+ if (!this.currents.globalTables.some(x => x.table.toUpperCase() == table.table.toUpperCase())) {
1106
1054
  this.currents.globalTables.push(table);
1107
1055
  }
1108
1056
  return true;
@@ -1116,12 +1064,12 @@ class SqlProvider {
1116
1064
  * @returns `true` se e stata aggiunta una dichiarazione.
1117
1065
  */
1118
1066
  populateDeclarations(statement, found) {
1119
- if (statement.indexOf('@') >= 0) {
1067
+ if (statement.includes('@')) {
1120
1068
  let decStr = statement.trim().toUpperCase().split(' ');
1121
1069
  if (decStr.length >= 3) {
1122
1070
  let dec = { paramName: decStr[1], paramtype: decStr[2], usertype: null };
1123
1071
  let type;
1124
- if (decStr[2].indexOf('.') >= 0) {
1072
+ if (decStr[2].includes('.')) {
1125
1073
  type = this.userDefTypes.find(x => x.table.toUpperCase() == decStr[2].split('.')[1] && x.schema.toUpperCase() == decStr[2].split('.')[0]);
1126
1074
  }
1127
1075
  else {
@@ -1130,7 +1078,7 @@ class SqlProvider {
1130
1078
  if (type) {
1131
1079
  dec.usertype = type;
1132
1080
  }
1133
- if (!this.currents.declarations.find(x => x.paramName.toUpperCase() == dec.paramName.toUpperCase())) {
1081
+ if (!this.currents.declarations.some(x => x.paramName.toUpperCase() == dec.paramName.toUpperCase())) {
1134
1082
  this.currents.declarations.push(dec);
1135
1083
  }
1136
1084
  found = true;
@@ -1148,12 +1096,12 @@ class SqlProvider {
1148
1096
  populateCurrentColumns(element, stmntIndx, statementObj, subStatement) {
1149
1097
  let selStmnt = statementObj.subStatements.find(x => x.key == 'SELECT');
1150
1098
  if (selStmnt) {
1151
- let columns = selStmnt.statement.statement.replace('SELECT', '').trim().toUpperCase().split(',').filter(x => x).map(x => {
1099
+ let columns = selStmnt.statement.statement.replace('SELECT', '').trim().toUpperCase().split(',').filter(Boolean).map(x => {
1152
1100
  let col = null;
1153
1101
  x = x.trim();
1154
1102
  let ownerTbl;
1155
1103
  let isAlias = false;
1156
- if (x.indexOf('.') >= 0) {
1104
+ if (x.includes('.')) {
1157
1105
  let schema = x.split('.')[0].replace('[', '').replace(']', '').replace('(', '').replace(')', '').toUpperCase();
1158
1106
  let ownerSchema = this.schemas.find(s => s.schema.toUpperCase() === schema);
1159
1107
  if (!ownerSchema) {
@@ -1205,19 +1153,19 @@ class SqlProvider {
1205
1153
  }
1206
1154
  }
1207
1155
  return col;
1208
- }).filter(x => x);
1156
+ }).filter(Boolean);
1209
1157
  columns.forEach(x => {
1210
1158
  let normalizedColumn = x?.column?.column?.toUpperCase();
1211
1159
  if (!normalizedColumn) {
1212
1160
  return;
1213
1161
  }
1214
1162
  if (statementObj) {
1215
- if (!statementObj.sqlColumns.find(c => c?.column?.column?.toUpperCase() == normalizedColumn)) {
1163
+ if (!statementObj.sqlColumns.some(c => c?.column?.column?.toUpperCase() == normalizedColumn)) {
1216
1164
  statementObj.sqlColumns.push(x);
1217
1165
  }
1218
1166
  }
1219
1167
  if (subStatement) {
1220
- if (!subStatement.sqlColumns.find(c => c?.column?.column?.toUpperCase() == normalizedColumn)) {
1168
+ if (!subStatement.sqlColumns.some(c => c?.column?.column?.toUpperCase() == normalizedColumn)) {
1221
1169
  subStatement.sqlColumns.push(x);
1222
1170
  }
1223
1171
  }
@@ -1279,7 +1227,7 @@ class SqlProvider {
1279
1227
  populateCurrentSchemaTables(element, stmntIndx, found, statementObj, subStatement) {
1280
1228
  let tblStr = element.trim().toUpperCase().split(' ');
1281
1229
  if (tblStr.length > 0 && tblStr[0].split('.').length > 1) {
1282
- let identifierParts = tblStr[0].replace('[', '').replace(']', '').split('.').filter(x => x);
1230
+ let identifierParts = tblStr[0].replace('[', '').replace(']', '').split('.').filter(Boolean);
1283
1231
  let schemaName = '';
1284
1232
  let tableName = '';
1285
1233
  let dbName = '';
@@ -1331,11 +1279,11 @@ class SqlProvider {
1331
1279
  let aliasCandidate = identifierParts[0] || '';
1332
1280
  let matchTbl = statementObj.sqlTables.find(x => x.usedAlias.toUpperCase() === aliasCandidate.toUpperCase());
1333
1281
  if (matchTbl) {
1334
- if (!subStatement.sqlTables.find(x => x.table.table.toUpperCase() == matchTbl.table.table.toUpperCase() && x.table.schema.toUpperCase() == matchTbl.table.schema.toUpperCase())) {
1282
+ if (!subStatement.sqlTables.some(x => x.table.table.toUpperCase() == matchTbl.table.table.toUpperCase() && x.table.schema.toUpperCase() == matchTbl.table.schema.toUpperCase())) {
1335
1283
  subStatement.sqlTables.push({ table: matchTbl.table, usedAlias: matchTbl.usedAlias });
1336
1284
  }
1337
1285
  let matchSchema = statementObj.sqlModels.find(x => matchTbl.table.schema.toUpperCase() === x.schema.toUpperCase());
1338
- if (matchSchema && !subStatement.sqlModels.find(x => matchTbl.table.schema.toUpperCase() === x.schema.toUpperCase())) {
1286
+ if (matchSchema && !subStatement.sqlModels.some(x => matchTbl.table.schema.toUpperCase() === x.schema.toUpperCase())) {
1339
1287
  subStatement.sqlModels.push(matchSchema);
1340
1288
  }
1341
1289
  }
@@ -1465,7 +1413,7 @@ class SqlProvider {
1465
1413
  }
1466
1414
  ].filter(x => {
1467
1415
  if (currentStatement) {
1468
- if (currentStatement.subStatements.find(s => x.label.indexOf('JOIN') < 0 && x.label == s.key.toUpperCase())) {
1416
+ if (currentStatement.subStatements.some(s => !x.label.includes('JOIN') && x.label == s.key.toUpperCase())) {
1469
1417
  return false;
1470
1418
  }
1471
1419
  }
@@ -1502,7 +1450,7 @@ class SqlProvider {
1502
1450
  });
1503
1451
  }
1504
1452
  ci = ci.concat(selectFields.filter(x => {
1505
- if (context == autocompleteContext.columnSelect && currentStatement.sqlColumns.find(c => c?.column?.column?.toUpperCase() == x.column.toUpperCase())) {
1453
+ if (context == autocompleteContext.columnSelect && currentStatement.sqlColumns.some(c => c?.column?.column?.toUpperCase() == x.column.toUpperCase())) {
1506
1454
  return false;
1507
1455
  }
1508
1456
  return true;
@@ -1515,7 +1463,7 @@ class SqlProvider {
1515
1463
  .replace('(', '')
1516
1464
  .replace(')', '')
1517
1465
  .split('.')
1518
- .filter(y => y)
1466
+ .filter(Boolean)
1519
1467
  .map(y => y.trim().toUpperCase());
1520
1468
  if (!scaffoldedOnly && restrictedParts.length >= 3) {
1521
1469
  let dbFilter = restrictedParts[0];
@@ -1526,7 +1474,7 @@ class SqlProvider {
1526
1474
  && x.table.toUpperCase() === tableFilter
1527
1475
  && (!dbFilter || colDb === dbFilter);
1528
1476
  }
1529
- if (restrictedParts.length >= 1 && restrictedToken.indexOf('.') >= 0) {
1477
+ if (restrictedParts.length >= 1 && restrictedToken.includes('.')) {
1530
1478
  let aliasFilter = restrictedParts[0];
1531
1479
  return (x.tableAlias || '').toUpperCase() === aliasFilter;
1532
1480
  }
@@ -1538,8 +1486,8 @@ class SqlProvider {
1538
1486
  return true;
1539
1487
  }).map(x => {
1540
1488
  let restrictedToken = (currentSubStatement?.words?.[currentSubStatement.words.length - 1]?.token || '').trim();
1541
- let isAliasQualifiedCompletion = context == autocompleteContext.columnWhereRestricted && restrictedToken.indexOf('.') >= 0;
1542
- let aliasStmnts = currentStatement.subStatements.filter(s => s.key == 'FROM' || s.key.indexOf('JOIN') >= 0 || s.key == 'ON');
1489
+ let isAliasQualifiedCompletion = context == autocompleteContext.columnWhereRestricted && restrictedToken.includes('.');
1490
+ let aliasStmnts = currentStatement.subStatements.filter(s => s.key == 'FROM' || s.key.includes('JOIN') || s.key == 'ON');
1543
1491
  let aliasStmnt = aliasStmnts.find(y => y.statement.sqlTables.length > 0 &&
1544
1492
  y.statement.sqlTables[0].table.schema.toUpperCase() == x.schema.toUpperCase() &&
1545
1493
  y.statement.sqlTables[0].table.table.toUpperCase() == x.table.toUpperCase());
@@ -1554,11 +1502,13 @@ class SqlProvider {
1554
1502
  else if (aliasStmnt) {
1555
1503
  str = `${aliasStmnt.statement.sqlTables[0].usedAlias}.${x.column}`;
1556
1504
  }
1557
- let longDescr = `${x.column} (${x.type}, ${x.isNullable ? 'null' : 'not null'})${x.columnDescription ? ` - ${x.columnDescription}` : ''}`;
1505
+ const columnDescriptionSuffix = x.columnDescription ? ` - ${x.columnDescription}` : '';
1506
+ let longDescr = `${x.column} (${x.type}, ${x.isNullable ? 'null' : 'not null'})${columnDescriptionSuffix}`;
1507
+ let nonPkeyKind = (x.parentRelation) ? monaco.languages.CompletionItemKind.Reference : monaco.languages.CompletionItemKind.Field;
1558
1508
  return {
1559
1509
  documentation: longDescr,
1560
1510
  insertText: str,
1561
- kind: x.isPkey ? monaco.languages.CompletionItemKind.Keyword : (x.parentRelation) ? monaco.languages.CompletionItemKind.Reference : monaco.languages.CompletionItemKind.Field,
1511
+ kind: x.isPkey ? monaco.languages.CompletionItemKind.Keyword : nonPkeyKind,
1562
1512
  label: longDescr,
1563
1513
  range: range
1564
1514
  };
@@ -1587,21 +1537,6 @@ class SqlProvider {
1587
1537
  break;
1588
1538
  case autocompleteContext.comparisonOperator:
1589
1539
  ci = comparisonOperators.filter(x => {
1590
- // if (this.currents.column && this.currents.column.type) {
1591
- // var sqlType = sqlTypes.find(x => x.name.toUpperCase() == this.currents.column.type.toUpperCase());
1592
- // if (sqlType) {
1593
- // switch (true) {
1594
- // case sqlType.isString:
1595
- // return ['=', '<>', '!=', '!', 'NOT', 'LIKE', 'IN', 'IS', 'IS NOT NULL'].indexOf(x) >= 0;
1596
- // case sqlType.isNumber:
1597
- // return ['=', '<>', '<', '<=', '>', '>=', '!=', '!', 'NOT', 'BETWEEN', 'IN', 'IS', 'IS NOT NULL'].indexOf(x) >= 0;
1598
- // case sqlType.isBool:
1599
- // return ['=', '<>', '!=', '!', 'NOT', 'IS', 'IS NOT NULL'].indexOf(x) >= 0;
1600
- // default:
1601
- // return true;
1602
- // }
1603
- // }
1604
- // }
1605
1540
  return true;
1606
1541
  }).map(x => {
1607
1542
  return {
@@ -1659,17 +1594,17 @@ class SqlProvider {
1659
1594
  break;
1660
1595
  case autocompleteContext.table:
1661
1596
  case autocompleteContext.tableNoAs:
1662
- case autocompleteContext.tableJoin:
1597
+ case autocompleteContext.tableJoin: {
1663
1598
  let rawScopedToken = (currentSubStatement?.words?.[currentSubStatement.words.length - 1]?.token || '').trim();
1664
- let currentSchema = currentStatement.sqlModels[currentStatement.sqlModels.length - 1]?.schema;
1599
+ let currentSchema = currentStatement.sqlModels.at(-1)?.schema;
1665
1600
  let scopedParts = rawScopedToken
1666
1601
  .replace('[', '')
1667
1602
  .replace(']', '')
1668
1603
  .replace('(', '')
1669
1604
  .replace(')', '')
1670
1605
  .split('.')
1671
- .filter(x => x);
1672
- let isDbScopedSchema = !scaffoldedOnly && rawScopedToken.indexOf('.') >= 0;
1606
+ .filter(Boolean);
1607
+ let isDbScopedSchema = !scaffoldedOnly && rawScopedToken.includes('.');
1673
1608
  if (context == autocompleteContext.tableJoin) {
1674
1609
  currentStatement.sqlTables.forEach(tbl => {
1675
1610
  this.parseTblRelations(currentStatement, tbl, ci, range, currentSchema);
@@ -1739,13 +1674,10 @@ class SqlProvider {
1739
1674
  let txtLine = originalText.split('\n')[range.startLineNumber - 1];
1740
1675
  let qualifiedSchema = scopedModel ? this.getModelSchemaName(scopedModel) : x.schema;
1741
1676
  let startCol = txtLine.toUpperCase().indexOf(`${qualifiedSchema.toUpperCase()}.`);
1742
- let tokenHasQualifier = rawScopedToken.indexOf('.') >= 0;
1743
- let insertTxt = (!x.alias || context == autocompleteContext.tableNoAs) ?
1744
- (tokenHasQualifier
1745
- ? x.table
1746
- : `${context != autocompleteContext.tableNoAs ? `${qualifiedSchema}.` : ''}${x.table}`)
1747
- :
1748
- ``;
1677
+ let tokenHasQualifier = rawScopedToken.includes('.');
1678
+ let schemaPrefix = context != autocompleteContext.tableNoAs ? `${qualifiedSchema}.` : '';
1679
+ let qualifiedInsert = tokenHasQualifier ? x.table : `${schemaPrefix}${x.table}`;
1680
+ let insertTxt = (!x.alias || context == autocompleteContext.tableNoAs) ? qualifiedInsert : ``;
1749
1681
  return {
1750
1682
  documentation: x.table,
1751
1683
  insertText: insertTxt,
@@ -1764,16 +1696,19 @@ class SqlProvider {
1764
1696
  };
1765
1697
  }
1766
1698
  catch (error) {
1699
+ // Malformed table suggestion entry — skip this completion item
1700
+ // (return null) instead of breaking the whole autocomplete list.
1767
1701
  debugger;
1768
1702
  return null;
1769
1703
  }
1770
1704
  });
1771
1705
  }
1772
1706
  break;
1773
- case autocompleteContext.declaration:
1707
+ }
1708
+ case autocompleteContext.declaration: {
1774
1709
  let paramName = '@Param';
1775
1710
  let paramIndx = 1;
1776
- while (this.currents.declarations.find(x => x.paramName.toUpperCase() === `${paramName}${paramIndx.toString()}`.toUpperCase())) {
1711
+ while (this.currents.declarations.some(x => x.paramName.toUpperCase() === `${paramName}${paramIndx.toString()}`.toUpperCase())) {
1777
1712
  paramIndx++;
1778
1713
  }
1779
1714
  paramName = `@Param${paramIndx}`;
@@ -1787,13 +1722,19 @@ class SqlProvider {
1787
1722
  }
1788
1723
  ];
1789
1724
  break;
1725
+ }
1790
1726
  case autocompleteContext.sqlType:
1791
1727
  ci = sqlTypes.map(x => {
1728
+ let sizeHint = '';
1729
+ if (x.isString && x.name.toUpperCase().includes("VAR")) {
1730
+ sizeHint = '(100)';
1731
+ }
1732
+ else if (x.isNumber && x.name.toUpperCase() == "DECIMAL") {
1733
+ sizeHint = '(18, 2)';
1734
+ }
1792
1735
  return {
1793
1736
  documentation: x.name,
1794
- insertText: `${x.name} ${x.isString && x.name.toUpperCase().indexOf("VAR") >= 0 ? '(100)' :
1795
- x.isNumber && x.name.toUpperCase() == "DECIMAL" ? '(18, 2)' :
1796
- ''}= null;\n`,
1737
+ insertText: `${x.name} ${sizeHint}= null;\n`,
1797
1738
  kind: monaco.languages.CompletionItemKind.TypeParameter,
1798
1739
  label: x.name,
1799
1740
  range: range
@@ -1843,7 +1784,7 @@ class SqlProvider {
1843
1784
  return modelAny.database;
1844
1785
  }
1845
1786
  let schema = model.schema || '';
1846
- if (schema.indexOf('.') >= 0) {
1787
+ if (schema.includes('.')) {
1847
1788
  return schema.split('.')[0];
1848
1789
  }
1849
1790
  return null;
@@ -1858,7 +1799,7 @@ class SqlProvider {
1858
1799
  return '';
1859
1800
  }
1860
1801
  let schema = model.schema || '';
1861
- if (schema.indexOf('.') >= 0) {
1802
+ if (schema.includes('.')) {
1862
1803
  return schema.split('.').slice(1).join('.');
1863
1804
  }
1864
1805
  return schema;
@@ -1907,7 +1848,7 @@ class SqlProvider {
1907
1848
  if (rel) {
1908
1849
  relations.push(rel);
1909
1850
  }
1910
- if (col.parentRelation && col.parentRelation.tableFK.toUpperCase() == tbl.table.table.toUpperCase() && col.parentRelation.schemaFK.toUpperCase() == tbl.table.schema.toUpperCase() && (!schemaFilter || col.parentRelation.schemaPK.toUpperCase() == schemaFilter.toUpperCase())) {
1851
+ if (col.parentRelation?.tableFK.toUpperCase() == tbl.table.table.toUpperCase() && col.parentRelation.schemaFK.toUpperCase() == tbl.table.schema.toUpperCase() && (!schemaFilter || col.parentRelation.schemaPK.toUpperCase() == schemaFilter.toUpperCase())) {
1911
1852
  relations.push(col.parentRelation);
1912
1853
  }
1913
1854
  });
@@ -1919,19 +1860,21 @@ class SqlProvider {
1919
1860
  let aliasTblFK;
1920
1861
  if (rel.schemaFK == tbl.table.schema && rel.tableFK == tbl.table.table) {
1921
1862
  aliasTblPK = tblPK.alias ? tblPK.alias : `${tblPK.schema}.${tblPK.table}`;
1922
- aliasTblFK = tbl.usedAlias ? tbl.usedAlias : (tblFK.alias ? tblFK.alias : `${tblFK.schema}.${tblFK.table}`);
1863
+ const fkFallbackAlias = tblFK.alias ? tblFK.alias : `${tblFK.schema}.${tblFK.table}`;
1864
+ aliasTblFK = tbl.usedAlias ? tbl.usedAlias : fkFallbackAlias;
1923
1865
  joinSuggestion = `\t${rel.schemaPK}.${rel.tablePK} AS ${aliasTblPK} ON \n\t${aliasTblFK}.${rel.columnFK} = \n\t${aliasTblPK}.${rel.columnPK}`;
1924
1866
  }
1925
1867
  else {
1926
- aliasTblPK = tbl.usedAlias ? tbl.usedAlias : (tblPK.alias ? tblPK.alias : `${tblPK.schema}.${tblPK.table}`);
1868
+ const pkFallbackAlias = tblPK.alias ? tblPK.alias : `${tblPK.schema}.${tblPK.table}`;
1869
+ aliasTblPK = tbl.usedAlias ? tbl.usedAlias : pkFallbackAlias;
1927
1870
  aliasTblFK = tblFK.alias ? tblFK.alias : `${tblFK.schema}.${tblFK.table}`;
1928
1871
  joinSuggestion = `\t${rel.schemaFK}.${rel.tableFK} AS ${aliasTblFK} ON \n\t${aliasTblPK}.${rel.columnPK} = \n\t${aliasTblFK}.${rel.columnFK}`;
1929
1872
  }
1930
1873
  ci.push({
1931
- documentation: joinSuggestion.replace(/(\r\n|\n|\r|\t)/gm, ' '),
1874
+ documentation: joinSuggestion.replaceAll(/(\r\n|\n|\r|\t)/gm, ' '),
1932
1875
  insertText: `\n${joinSuggestion}`,
1933
1876
  kind: monaco.languages.CompletionItemKind.Reference,
1934
- label: joinSuggestion.replace(/(\r\n|\n|\r|\t)/gm, ' '),
1877
+ label: joinSuggestion.replaceAll(/(\r\n|\n|\r|\t)/gm, ' '),
1935
1878
  range: range
1936
1879
  });
1937
1880
  });
@@ -1946,10 +1889,9 @@ class SqlProvider {
1946
1889
  let tbl;
1947
1890
  this.schemas.forEach(schema => {
1948
1891
  schema.tables.forEach(table => {
1949
- if (table.alias && table.alias.toUpperCase() === alias.toUpperCase()) {
1892
+ if (table.alias?.toUpperCase() === alias.toUpperCase()) {
1950
1893
  tbl = table;
1951
1894
  tbl.schemaObj = schema;
1952
- return;
1953
1895
  }
1954
1896
  });
1955
1897
  if (tbl) {
@@ -1991,12 +1933,12 @@ let DragDropInteractionEmitter$1 = class DragDropInteractionEmitter extends Emit
1991
1933
  let getDbPrefixFor = (schemaName, tableName, preferredDbName) => {
1992
1934
  let owner = providerSchemas.find(m => {
1993
1935
  if (preferredDbName) {
1994
- let mDb = (m.database || ((m.schema || '').indexOf('.') >= 0 ? (m.schema || '').split('.')[0] : '') || '').toUpperCase();
1936
+ let mDb = (m.database || ((m.schema || '').includes('.') ? (m.schema || '').split('.')[0] : '') || '').toUpperCase();
1995
1937
  if (mDb !== preferredDbName.toUpperCase()) {
1996
1938
  return false;
1997
1939
  }
1998
1940
  }
1999
- let mSchema = (m.schema || '').indexOf('.') >= 0 ? (m.schema || '').split('.').slice(1).join('.') : (m.schema || '');
1941
+ let mSchema = (m.schema || '').includes('.') ? (m.schema || '').split('.').slice(1).join('.') : (m.schema || '');
2000
1942
  let schemaMatch = mSchema.toUpperCase() === (schemaName || '').toUpperCase();
2001
1943
  if (!schemaMatch) {
2002
1944
  return false;
@@ -2009,13 +1951,13 @@ let DragDropInteractionEmitter$1 = class DragDropInteractionEmitter extends Emit
2009
1951
  if (!owner) {
2010
1952
  return '';
2011
1953
  }
2012
- let db = owner.database || ((owner.schema || '').indexOf('.') >= 0 ? (owner.schema || '').split('.')[0] : '');
1954
+ let db = owner.database || ((owner.schema || '').includes('.') ? (owner.schema || '').split('.')[0] : '');
2013
1955
  return db ? `${db}.` : '';
2014
1956
  };
2015
1957
  if (dataItem.sqlModel) {
2016
1958
  let modelAny = dataItem.sqlModel;
2017
- let modelDb = modelAny.database || ((dataItem.sqlModel.schema || '').indexOf('.') >= 0 ? (dataItem.sqlModel.schema || '').split('.')[0] : '');
2018
- let modelSchema = (dataItem.sqlModel.schema || '').indexOf('.') >= 0
1959
+ let modelDb = modelAny.database || ((dataItem.sqlModel.schema || '').includes('.') ? (dataItem.sqlModel.schema || '').split('.')[0] : '');
1960
+ let modelSchema = (dataItem.sqlModel.schema || '').includes('.')
2019
1961
  ? (dataItem.sqlModel.schema || '').split('.').slice(1).join('.')
2020
1962
  : (dataItem.sqlModel.schema || '');
2021
1963
  callback(modelDb ? `${modelDb}.${modelSchema}.` : `${modelSchema}.`);
@@ -2037,7 +1979,7 @@ let DragDropInteractionEmitter$1 = class DragDropInteractionEmitter extends Emit
2037
1979
  }
2038
1980
  else if (dataItem.sqlColumn) {
2039
1981
  let suggestions = self.sqlProvider.getAutocompleteSuggestions(self.editor.getValue(), self.position);
2040
- let colSugg = suggestions.suggestions.find(x => x.insertText.indexOf(dataItem.sqlColumn.column) >= 0);
1982
+ let colSugg = suggestions.suggestions.find(x => x.insertText.includes(dataItem.sqlColumn.column));
2041
1983
  if (colSugg) {
2042
1984
  callback(colSugg.insertText);
2043
1985
  }
@@ -2049,8 +1991,8 @@ let DragDropInteractionEmitter$1 = class DragDropInteractionEmitter extends Emit
2049
1991
  }
2050
1992
  else if (dataItem.sqlRelation) {
2051
1993
  let suggestions = self.sqlProvider.getAutocompleteSuggestions(self.editor.getValue(), self.position);
2052
- if (suggestions && suggestions.suggestions) {
2053
- let relSugg = suggestions.suggestions.find(x => x.insertText.indexOf(`${dataItem.sqlRelation.schemaPK}.${dataItem.sqlRelation.tablePK}`) >= 0);
1994
+ if (suggestions?.suggestions) {
1995
+ let relSugg = suggestions.suggestions.find(x => x.insertText.includes(`${dataItem.sqlRelation.schemaPK}.${dataItem.sqlRelation.tablePK}`));
2054
1996
  if (relSugg) {
2055
1997
  callback(relSugg.insertText);
2056
1998
  }
@@ -2070,10 +2012,6 @@ let DragDropInteractionEmitter$1 = class DragDropInteractionEmitter extends Emit
2070
2012
  },
2071
2013
  position: event.position
2072
2014
  };
2073
- // IMMUTABLE !!!!
2074
- // event.event.dataTransfer.clearData();
2075
- // event.event.dataTransfer.items.clear();
2076
- // event.event.dataTransfer.setData('text/plain', 'pippo');
2077
2015
  this.editor._contributions.onBeforeInteractionEvent();
2078
2016
  super.fire(de);
2079
2017
  }
@@ -2090,9 +2028,6 @@ let ContextMenuInteractionEmitter$1 = class ContextMenuInteractionEmitter extend
2090
2028
  fire(event) {
2091
2029
  event.event.preventDefault();
2092
2030
  debugger;
2093
- // event.event.stopPropagation();
2094
- // this.editor._contributions.onBeforeInteractionEvent();
2095
- // super.fire(event);
2096
2031
  }
2097
2032
  };
2098
2033
  class ContextInfo {
@@ -2253,9 +2188,6 @@ class EditorOptions {
2253
2188
  }
2254
2189
  }
2255
2190
 
2256
- // import { editor } from 'monaco-editor';
2257
- // import { LinkedList } from 'monaco-editor/esm/vs/base/common/linkedList';
2258
- // import { MenuId, MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions';
2259
2191
  /**
2260
2192
  * Stub ambient delle classi rxjs core iniettato in Monaco come extra-lib.
2261
2193
  *
@@ -2335,8 +2267,6 @@ class TSProvider {
2335
2267
  this.editor = editor;
2336
2268
  this.editor['_onDropIntoEditor'] = this.editor['_register'](new DragDropInteractionEmitter(this.editor['_contributions'], this.editor['_deliveryQueue'], this.editor, this));
2337
2269
  this.editor['onDropIntoEditor'] = this.editor['_onDropIntoEditor'].event;
2338
- // this._onContextMenu = this._register(new InteractionEmitter(this._contributions, this._deliveryQueue));
2339
- // this.onContextMenu = this._onContextMenu.event;
2340
2270
  this.editor['_onContextMenu'] = this.editor['_register'](new ContextMenuInteractionEmitter(this.editor['_contributions'], this.editor['_deliveryQueue'], this.editor, this));
2341
2271
  this.editor['onContextMenu'] = this.editor['_onContextMenu'].event;
2342
2272
  }
@@ -2379,10 +2309,8 @@ class TSProvider {
2379
2309
  });
2380
2310
  this.editorOptions.contextMenuItems = contextMenuItems;
2381
2311
  this.editorOptions.onNodeClick = (event, dataItem) => {
2382
- // debugger;
2383
2312
  };
2384
2313
  this.editorOptions.onInit = (editor) => {
2385
- // debugger;
2386
2314
  this.editor = editor;
2387
2315
  };
2388
2316
  this.editorOptions.onNodeDragStart = (event, dataItem) => {
@@ -2391,7 +2319,6 @@ class TSProvider {
2391
2319
  event.dataTransfer.setData("text/plain", JSON.stringify(dataItem));
2392
2320
  };
2393
2321
  this.editorOptions.onNodeDragEnd = (event, dataItem) => {
2394
- // debugger;
2395
2322
  };
2396
2323
  let compilerOptions = {
2397
2324
  target: monaco.languages.typescript.ScriptTarget.ES2016,
@@ -2423,16 +2350,6 @@ class TSProvider {
2423
2350
  noSyntaxValidation: false,
2424
2351
  diagnosticCodesToIgnore: [1108, 1375, 1378],
2425
2352
  });
2426
- // //esportare i tipi usando angular.json (riduci i file esportati alle cartelle ...)
2427
- // // "assets": [
2428
- // // ....
2429
- // // {
2430
- // // "glob": "**/*",
2431
- // // "input": "node_modules/@skylab/easygrid/lib",
2432
- // // "output": "assets/"
2433
- // // },
2434
- // // ....
2435
- // libs.push(this.http.get("assets/models/easygrid.server.d.ts", { responseType: 'text' }));
2436
2353
  let headers = new HttpHeaders({
2437
2354
  'Cache-Control': 'no-cache, no-store, must-revalidate, post-check=0, pre- check=0',
2438
2355
  'Pragma': 'no-cache',
@@ -2441,7 +2358,7 @@ class TSProvider {
2441
2358
  libs = MetadataProviderService.baseLibs.map(lib => {
2442
2359
  return this.http.get(lib, { headers: headers, responseType: 'text' });
2443
2360
  });
2444
- if (formFieldOptions.extraLibs && formFieldOptions.extraLibs.length) {
2361
+ if (formFieldOptions.extraLibs?.length) {
2445
2362
  libs.concat(formFieldOptions.extraLibs.map(lib => {
2446
2363
  return this.http.get(lib, { headers: headers, responseType: 'text' });
2447
2364
  }));
@@ -2450,15 +2367,15 @@ class TSProvider {
2450
2367
  if (codeContext) {
2451
2368
  let routeIdContextField = field.extras.customEditorConfig?.routeContextField;
2452
2369
  let columnContextField = field.extras.customEditorConfig?.columnContextField;
2453
- if (codeContext.indexOf('record: ') >= 0 && routeIdContextField) {
2454
- let routeId = record[routeIdContextField]?.value; // this.metaInfo.tableMetadata.md_route_name.replaceAll(' ', '_');
2370
+ if (codeContext.includes('record: ') && routeIdContextField) {
2371
+ let routeId = record[routeIdContextField]?.value;
2455
2372
  if (routeId) {
2456
2373
  let metas = await metaSrv.getMetadatiById(routeId);
2457
2374
  let currentColumnMeta = null;
2458
2375
  if (columnContextField) {
2459
2376
  currentColumnMeta = metas.find(m => m.mc_id == record[columnContextField].value);
2460
2377
  }
2461
- if (metas && metas.length) {
2378
+ if (metas?.length) {
2462
2379
  let routeName = metas[0]._Metadati_Tabelle.md_route_name.replaceAll(' ', '_');
2463
2380
  let classProperties = '';
2464
2381
  let classPropsArray = [];
@@ -2473,7 +2390,7 @@ class TSProvider {
2473
2390
  let lookupMetas = await metaSrv.getMetadati(lookupRoute);
2474
2391
  let nestedClassProperties = '';
2475
2392
  let nestedClassPropsArray = [];
2476
- if (lookupMetas && lookupMetas.length) {
2393
+ if (lookupMetas?.length) {
2477
2394
  lookupRoute = lookupRoute.replaceAll(' ', '_');
2478
2395
  for (let cLookup of lookupMetas) {
2479
2396
  nestedClassPropsArray.push(`${cLookup.mc_nome_colonna}: ${MetadataProviderService.getTSTypeFromMetaColumn(cLookup)};`);
@@ -2490,7 +2407,7 @@ class TSProvider {
2490
2407
  }
2491
2408
  // recursive function to get the type of the nested lookup objects
2492
2409
  // ...
2493
- if (codeContext.indexOf('record: any') >= 0) {
2410
+ if (codeContext.includes('record: any')) {
2494
2411
  classPropsArray.push(`${c.mc_nome_colonna}: ${MetadataProviderService.getTSTypeFromMetaColumn(c)};`);
2495
2412
  }
2496
2413
  else {
@@ -2507,13 +2424,13 @@ class TSProvider {
2507
2424
  };
2508
2425
  constructor();`);
2509
2426
  })));
2510
- if (codeContext.indexOf('record: any') >= 0) {
2427
+ if (codeContext.includes('record: any')) {
2511
2428
  codeContext = codeContext.replace('record: any', `record: ${routeName}`);
2512
2429
  }
2513
2430
  else {
2514
2431
  codeContext = codeContext.replace('record: {[key: string]: BehaviorSubject<any>}', `record: {${compositeTypeDef}}`);
2515
2432
  }
2516
- if (currentColumnMeta && currentColumnMeta.mc_ui_column_type == 'lookupByID' && codeContext.indexOf('let newValue: any;') >= 0) {
2433
+ if (currentColumnMeta?.mc_ui_column_type == 'lookupByID' && codeContext.includes('let newValue: any;')) {
2517
2434
  codeContext = codeContext.replace('let newValue: any;', `let newValue: ${currentColumnMeta.mc_ui_lookup_entity_name};`);
2518
2435
  }
2519
2436
  }
@@ -2528,7 +2445,7 @@ class TSProvider {
2528
2445
  let lines = data.split('\n');
2529
2446
  // da migliorare con regex !!!
2530
2447
  let parsedLines = lines.filter(x => {
2531
- return x.indexOf('import ') < 0; // && x.indexOf('export interface ') < 0
2448
+ return !x.includes('import '); // && x.indexOf('export interface ') < 0
2532
2449
  }).map((line) => {
2533
2450
  return line.replace('export declare', 'declare').replace('export interface', 'declare interface').replace('export class', 'declare class');
2534
2451
  });
@@ -2577,33 +2494,13 @@ class DragDropInteractionEmitter extends Emitter {
2577
2494
  callback(`${dataItem.sqlTable.schema}.${dataItem.sqlTable.table}`);
2578
2495
  }
2579
2496
  if (dataItem.parentTable) {
2580
- // let suggestions = self.sqlProvider.getAutocompleteSuggestions(self.editor.getValue(), self.position);
2581
- // let colSugg = suggestions.suggestions.find(x => x.label == '<All columns>');
2582
- // if (colSugg) {
2583
- // callback(colSugg.insertText);
2584
- // } else {
2585
- // callback(dataItem.parentTable.columns.map(x => x.column).join(','));
2586
- // }
2497
+ // intentionally empty: parentTable drops have no plain-text representation
2587
2498
  }
2588
2499
  if (dataItem.sqlColumn) {
2589
- // let suggestions = self.sqlProvider.getAutocompleteSuggestions(self.editor.getValue(), self.position);
2590
- // let colSugg = suggestions.suggestions.find(x => x.insertText.indexOf(dataItem.sqlColumn.column) >= 0);
2591
- // if (colSugg) {
2592
- // callback(colSugg.insertText);
2593
- // } else {
2594
- // callback(`${dataItem.sqlColumn.schema}.${dataItem.sqlColumn.table}.${dataItem.sqlColumn.column}`);
2595
- // }
2500
+ // intentionally empty: sqlColumn drops have no plain-text representation
2596
2501
  }
2597
2502
  if (dataItem.sqlRelation) {
2598
- // let suggestions = self.sqlProvider.getAutocompleteSuggestions(self.editor.getValue(), self.position);
2599
- // if (suggestions && suggestions.suggestions) {
2600
- // let relSugg = suggestions.suggestions.find(x => x.insertText.indexOf(`${dataItem.sqlRelation.schemaPK}.${dataItem.sqlRelation.tablePK}`) >= 0);
2601
- // if (relSugg) {
2602
- // callback(relSugg.insertText);
2603
- // } else {
2604
- // callback(`${dataItem.sqlRelation.schemaPK}.${dataItem.sqlRelation.tablePK} ON ${dataItem.sqlRelation.schemaFK}.${dataItem.sqlRelation.tableFK}.${dataItem.sqlRelation.columnFK} = ${dataItem.sqlRelation.schemaPK}.${dataItem.sqlRelation.tablePK}.${dataItem.sqlRelation.columnPK}`);
2605
- // }
2606
- // }
2503
+ // intentionally empty: sqlRelation drops have no plain-text representation
2607
2504
  }
2608
2505
  }
2609
2506
  }
@@ -2613,10 +2510,6 @@ class DragDropInteractionEmitter extends Emitter {
2613
2510
  },
2614
2511
  position: event.position
2615
2512
  };
2616
- // IMMUTABLE !!!!
2617
- // event.event.dataTransfer.clearData();
2618
- // event.event.dataTransfer.items.clear();
2619
- // event.event.dataTransfer.setData('text/plain', 'pippo');
2620
2513
  this.editor._contributions.onBeforeInteractionEvent();
2621
2514
  super.fire(de);
2622
2515
  }
@@ -2633,9 +2526,6 @@ class ContextMenuInteractionEmitter extends Emitter {
2633
2526
  fire(event) {
2634
2527
  event.event.preventDefault();
2635
2528
  this.tsProvider.contextMenuEvent = event;
2636
- // event.event.stopPropagation();
2637
- // this.editor._contributions.onBeforeInteractionEvent();
2638
- // super.fire(event);
2639
2529
  }
2640
2530
  }
2641
2531
 
@@ -2684,7 +2574,7 @@ class JsonSchemaTreeEditorComponent {
2684
2574
  const props = schema?.properties || {};
2685
2575
  const required = Array.isArray(schema?.required) ? schema.required : [];
2686
2576
  return Object.keys(props)
2687
- .filter((key) => obj != null && Object.prototype.hasOwnProperty.call(obj, key))
2577
+ .filter((key) => obj != null && Object.hasOwn(obj, key))
2688
2578
  .map((key) => ({
2689
2579
  key,
2690
2580
  schema: props[key],
@@ -2695,7 +2585,7 @@ class JsonSchemaTreeEditorComponent {
2695
2585
  /** Proprieta' dello schema NON ancora presenti nel valore (per il dropdown "aggiungi"). */
2696
2586
  addable(schema, obj) {
2697
2587
  const props = schema?.properties || {};
2698
- return Object.keys(props).filter((key) => !(obj != null && Object.prototype.hasOwnProperty.call(obj, key)));
2588
+ return Object.keys(props).filter((key) => !(obj != null && Object.hasOwn(obj, key)));
2699
2589
  }
2700
2590
  /** Classifica il tipo di editor per una property schema. */
2701
2591
  kindOf(propSchema) {
@@ -2909,11 +2799,11 @@ class HtmlProvider {
2909
2799
  { label: 'div', snippet: '<div>$0</div>', documentation: 'Container element' },
2910
2800
  { label: 'section', snippet: '<section>$0</section>', documentation: 'Sectioning content' },
2911
2801
  { label: 'article', snippet: '<article>$0</article>', documentation: 'Independent content block' },
2912
- { label: 'a', snippet: '<a href=\"$1\">$0</a>', documentation: 'Anchor link' },
2913
- { label: 'img', snippet: '<img src=\"$1\" alt=\"$2\" />', documentation: 'Image with alt text' },
2802
+ { label: 'a', snippet: '<a href="$1">$0</a>', documentation: 'Anchor link' },
2803
+ { label: 'img', snippet: '<img src="$1" alt="$2" />', documentation: 'Image with alt text' },
2914
2804
  { label: 'table', snippet: '<table>\\n <thead>\\n <tr><th>$1</th></tr>\\n </thead>\\n <tbody>\\n <tr><td>$0</td></tr>\\n </tbody>\\n</table>', documentation: 'Basic table template' },
2915
2805
  { label: 'ul', snippet: '<ul>\\n <li>$0</li>\\n</ul>', documentation: 'Unordered list' },
2916
- { label: 'form', snippet: '<form>\\n <label for=\"$1\">$2</label>\\n <input id=\"$1\" name=\"$1\" />\\n</form>', documentation: 'Simple form template' }
2806
+ { label: 'form', snippet: '<form>\\n <label for="$1">$2</label>\\n <input id="$1" name="$1" />\\n</form>', documentation: 'Simple form template' }
2917
2807
  ];
2918
2808
  constructor(editorOptions, componentSelectors = [], componentBindings = {}) {
2919
2809
  this.editorOptions = editorOptions;
@@ -3027,7 +2917,7 @@ class HtmlProvider {
3027
2917
  message: `Possible malformed tag '${firstToken}': missing '<' at start.`
3028
2918
  });
3029
2919
  }
3030
- const inlineEventMatch = line.match(/\son[a-z]+\s*=/i);
2920
+ const inlineEventMatch = /\son[a-z]+\s*=/i.exec(line);
3031
2921
  if (inlineEventMatch?.index != null) {
3032
2922
  const startColumn = inlineEventMatch.index + 2;
3033
2923
  markers.push({
@@ -3039,7 +2929,7 @@ class HtmlProvider {
3039
2929
  message: 'Inline on* event handler detected.'
3040
2930
  });
3041
2931
  }
3042
- const jsUrlMatch = line.match(/\b(?:href|src)\s*=\s*["']?\s*javascript:/i);
2932
+ const jsUrlMatch = /\b(?:href|src)\s*=\s*["']?\s*javascript:/i.exec(line);
3043
2933
  if (jsUrlMatch?.index != null) {
3044
2934
  const startColumn = jsUrlMatch.index + 1;
3045
2935
  markers.push({
@@ -3073,7 +2963,6 @@ class HtmlProvider {
3073
2963
  while ((match = tagRegex.exec(content)) !== null) {
3074
2964
  const full = match[0];
3075
2965
  const tag = (match[1] || '').toLowerCase();
3076
- const attrs = match[2] || '';
3077
2966
  const isClosing = full.startsWith('</');
3078
2967
  const isSelfClosing = /\/\s*>$/.test(full) || voidTags.has(tag);
3079
2968
  if (!isClosing && !isSelfClosing) {
@@ -3081,8 +2970,8 @@ class HtmlProvider {
3081
2970
  continue;
3082
2971
  }
3083
2972
  if (isClosing) {
3084
- const last = stack[stack.length - 1];
3085
- if (last && last.tag === tag) {
2973
+ const last = stack.at(-1);
2974
+ if (last?.tag === tag) {
3086
2975
  stack.pop();
3087
2976
  }
3088
2977
  else {
@@ -3173,12 +3062,12 @@ class HtmlProvider {
3173
3062
  pushMarker(tagOffset + 1 + bad.index, bad[0].length, monaco.MarkerSeverity.Error, 'Malformed Angular property binding. Use [prop]="...".');
3174
3063
  }
3175
3064
  // Broken event binding: (event=...
3176
- const malformedEvent = /\([^\)\s=><"'`]*\s*=/g;
3065
+ const malformedEvent = /\([^)\s=><"'`]*\s*=/g;
3177
3066
  while ((bad = malformedEvent.exec(attrs)) !== null) {
3178
3067
  pushMarker(tagOffset + 1 + bad.index, bad[0].length, monaco.MarkerSeverity.Error, 'Malformed Angular event binding. Use (event)="...".');
3179
3068
  }
3180
3069
  // Broken two-way binding: [(model=...
3181
- const malformedTwoWay = /\[\([^\)\]]+\s*=/g;
3070
+ const malformedTwoWay = /\[\([^)\]]+\s*=/g;
3182
3071
  while ((bad = malformedTwoWay.exec(attrs)) !== null) {
3183
3072
  pushMarker(tagOffset + 1 + bad.index, bad[0].length, monaco.MarkerSeverity.Error, 'Malformed Angular two-way binding. Use [(prop)]="...".');
3184
3073
  }
@@ -3256,7 +3145,7 @@ class HtmlProvider {
3256
3145
  }));
3257
3146
  suggestions.unshift(...wuicSuggestions);
3258
3147
  }
3259
- if (openTagContext && openTagContext.tagName.startsWith('wuic-')) {
3148
+ if (openTagContext?.tagName.startsWith('wuic-')) {
3260
3149
  const bindingSuggestions = this.buildAngularBindingSuggestions(openTagContext.tagName, range);
3261
3150
  suggestions.unshift(...bindingSuggestions);
3262
3151
  }
@@ -3265,7 +3154,7 @@ class HtmlProvider {
3265
3154
  });
3266
3155
  }
3267
3156
  getOpenTagContext(linePrefix) {
3268
- const match = linePrefix.match(/<([\w-]+)\b([^<>]*)$/);
3157
+ const match = /<([\w-]+)\b([^<>]*)$/.exec(linePrefix);
3269
3158
  if (!match) {
3270
3159
  return null;
3271
3160
  }
@@ -3356,13 +3245,13 @@ class HtmlProvider {
3356
3245
  return '';
3357
3246
  }
3358
3247
  const normalized = input
3359
- .replace(/>\s+</g, '><')
3360
- .replace(/\r\n/g, '\n')
3248
+ .replaceAll(/>\s+</g, '><')
3249
+ .replaceAll('\r\n', '\n')
3361
3250
  .trim();
3362
3251
  const withLineBreaks = normalized
3363
- .replace(/></g, '>\n<')
3364
- .replace(/(<\/(div|section|article|main|aside|header|footer|nav|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|form|fieldset|p|h[1-6]|pre|blockquote)>)/gi, '$1\n')
3365
- .replace(/(<(div|section|article|main|aside|header|footer|nav|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|form|fieldset|p|h[1-6]|pre|blockquote)(\s[^>]*)?>)/gi, '\n$1')
3252
+ .replaceAll('><', '>\n<')
3253
+ .replaceAll(/(<\/(div|section|article|main|aside|header|footer|nav|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|form|fieldset|p|h[1-6]|pre|blockquote)>)/gi, '$1\n')
3254
+ .replaceAll(/(<(div|section|article|main|aside|header|footer|nav|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|form|fieldset|p|h[1-6]|pre|blockquote)(\s[^>]*)?>)/gi, '\n$1')
3366
3255
  .split('\n')
3367
3256
  .map((line) => line.trim())
3368
3257
  .filter((line) => line.length > 0);
@@ -3374,12 +3263,12 @@ class HtmlProvider {
3374
3263
  const voidTags = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
3375
3264
  for (const rawLine of withLineBreaks) {
3376
3265
  const line = rawLine.trim();
3377
- const closeMatch = line.match(closingTag);
3266
+ const closeMatch = closingTag.exec(line);
3378
3267
  if (closeMatch) {
3379
3268
  indentLevel = Math.max(0, indentLevel - 1);
3380
3269
  }
3381
3270
  lines.push(`${' '.repeat(indentLevel)}${line}`);
3382
- const openMatch = line.match(openingTag);
3271
+ const openMatch = openingTag.exec(line);
3383
3272
  const isSelf = selfClosing.test(line);
3384
3273
  if (openMatch && !isSelf && !voidTags.has(openMatch[1].toLowerCase()) && !line.includes(`</${openMatch[1]}>`)) {
3385
3274
  indentLevel += 1;
@@ -3442,7 +3331,6 @@ const WUIC_COMPONENT_SELECTORS = [
3442
3331
  'wuic-workflow-runner'
3443
3332
  ];
3444
3333
 
3445
- // import { TreeItemDragStartEvent, TreeItemDragEvent, TreeItemDropEvent, DropPosition, TreeItemAddRemoveArgs, TreeItem, NodeClickEvent } from '@progress/kendo-angular-treeview';
3446
3334
  class CodeEditorComponent {
3447
3335
  monacoLoaderService;
3448
3336
  http;
@@ -3512,7 +3400,6 @@ class CodeEditorComponent {
3512
3400
  * Proprieta di stato del componente per sample code, usata dalla logica interna e dal template.
3513
3401
  */
3514
3402
  sampleCode = '';
3515
- // originalCode = 'function x() { // TODO }';
3516
3403
  /**
3517
3404
  * Flag di stato che governa il comportamento UI/logico relativo a fullscreen.
3518
3405
  */
@@ -3625,6 +3512,16 @@ class CodeEditorComponent {
3625
3512
  * (che e' tree-shaken nei build prod).
3626
3513
  */
3627
3514
  hostElementRef = inject(ElementRef, { optional: true });
3515
+ /**
3516
+ * NgZone + ChangeDetectorRef via `inject()` (stesso idioma di hostElementRef,
3517
+ * per non toccare il costruttore a 7 argomenti posizionali). Servono al
3518
+ * subscribe di `isMonacoLoaded$`: il loader ngx-monaco emette dal callback di
3519
+ * script-load (FUORI da NgZone) e la continuation async del subscribe resta
3520
+ * fuori zona → `this.render = true` non triggera change detection e il
3521
+ * template `<ngx-monaco-editor>` non monta mai (editor mai creato).
3522
+ */
3523
+ ngZone = inject(NgZone);
3524
+ cdRef = inject(ChangeDetectorRef);
3628
3525
  t(resource, fallback) {
3629
3526
  const translated = WtoolboxService.translationService?.instant?.(resource);
3630
3527
  return translated && translated !== resource ? translated : fallback;
@@ -3701,8 +3598,6 @@ class CodeEditorComponent {
3701
3598
  async suggest($event, ctx) {
3702
3599
  $event.stopPropagation();
3703
3600
  $event.preventDefault();
3704
- // var resp = await WtoolboxService.promptDialog('Suggest', [{ name: 'prompt', caption: 'prompt', type: 'text' }]);
3705
- // debugger;
3706
3601
  const nextValue = String(this.field.mc_suggest_value_callback__fn(this.record, this.field, this.metaInfo, WtoolboxService) ?? '');
3707
3602
  this.editorModelValue = nextValue;
3708
3603
  this.record[this.field.mc_nome_colonna].next(nextValue);
@@ -3729,11 +3624,13 @@ class CodeEditorComponent {
3729
3624
  // component instance on host element for tests that need direct access
3730
3625
  // (toggle-monaco contract check, etc.).
3731
3626
  try {
3732
- (this.hostElementRef?.nativeElement).__wuicCmp = this;
3627
+ if (this.hostElementRef?.nativeElement) {
3628
+ this.hostElementRef.nativeElement.__wuicCmp = this;
3629
+ }
3733
3630
  }
3734
3631
  catch { /* defensive */ }
3735
3632
  let formFieldOptions = {};
3736
- if (this.field && this.field.extras.customEditorConfig) {
3633
+ if (this.field?.extras.customEditorConfig) {
3737
3634
  try {
3738
3635
  formFieldOptions = this.field.extras.customEditorConfig;
3739
3636
  }
@@ -3741,7 +3638,7 @@ class CodeEditorComponent {
3741
3638
  console.error(`customEditorConfig for field ${this.field.mc_nome_colonna} error: ${e}`);
3742
3639
  }
3743
3640
  }
3744
- this.editorOptions = { ...this.editorOptions, ...(formFieldOptions.editorOptions || {}) };
3641
+ this.editorOptions = { ...this.editorOptions, ...(formFieldOptions.editorOptions) };
3745
3642
  const configuredLanguage = String(formFieldOptions.editorOptions?.language || '').trim().toLowerCase();
3746
3643
  if (configuredLanguage === 'json' || configuredLanguage === 'typescript' || configuredLanguage === 'sql' || configuredLanguage === 'csharp' || configuredLanguage === 'html') {
3747
3644
  this.editorOptions.language = configuredLanguage;
@@ -3752,7 +3649,7 @@ class CodeEditorComponent {
3752
3649
  this.editorOptions.wordWrap = this.editorOptions.wordWrap || 'on';
3753
3650
  this.editorOptions.wrappingIndent = this.editorOptions.wrappingIndent || 'same';
3754
3651
  this.editorOptions.suggest = {
3755
- ...(this.editorOptions.suggest || {}),
3652
+ ...(this.editorOptions.suggest),
3756
3653
  showStatusBar: false,
3757
3654
  preview: false,
3758
3655
  previewMode: 'subwordSmart',
@@ -3764,14 +3661,6 @@ class CodeEditorComponent {
3764
3661
  }
3765
3662
  this.bindRecordValue();
3766
3663
  this.refreshHtmlPreview();
3767
- // if (this.editorOptions.language === 'sql') {
3768
- // this.sampleCode = '';
3769
- // } else if (this.editorOptions.language === 'typescript') {
3770
- // this.sampleCode = 'function x() {\nconsole.log("Hello world!");\n}';
3771
- // } else if (this.editorOptions.language === 'json') {
3772
- // this.sampleCode = '{\n\n}';
3773
- // }
3774
- // this.sampleCode = formFieldOptions.sampleCode || this.sampleCode;
3775
3664
  this.monacoLoaderService.isMonacoLoaded$.pipe(filter(isLoaded => isLoaded), take(1)).subscribe(async () => {
3776
3665
  if (this.editorOptions.language === 'sql') {
3777
3666
  this.sqlProvider = new SqlProvider(this.http, this.editorOptions);
@@ -3786,7 +3675,7 @@ class CodeEditorComponent {
3786
3675
  // Vista "Struttura" (property-editor treeview da schema): abilitabile
3787
3676
  // via @Input jsonTreeToggle o `customEditorConfig.jsonTreeToggle`.
3788
3677
  this.jsonTreeToggle = this.jsonTreeToggle || formFieldOptions.jsonTreeToggle === true;
3789
- this.jsonTreeSchema = formFieldOptions.schemas?.[0]?.schema || null;
3678
+ this.jsonTreeSchema = (formFieldOptions.schemas?.[0])?.schema || null;
3790
3679
  // https://json-schema.org/learn/getting-started-step-by-step
3791
3680
  // string.
3792
3681
  // number.
@@ -3821,7 +3710,16 @@ class CodeEditorComponent {
3821
3710
  this.htmlProvider = new HtmlProvider(this.editorOptions, WUIC_COMPONENT_SELECTORS, WUIC_COMPONENT_BINDINGS);
3822
3711
  this.htmlProvider.registerHtmlProvider();
3823
3712
  }
3824
- this.render = true;
3713
+ // FIX (2026-07-22): rientra in NgZone e forza CD. La emit di
3714
+ // isMonacoLoaded$ arriva dal callback script-load di ngx-monaco (fuori
3715
+ // zona) e gli `await` sopra mantengono la continuation fuori zona:
3716
+ // senza run()+detectChanges il flag non rirenderizza il template e
3717
+ // Monaco non viene mai istanziato (test toggle-monaco: render=false /
3718
+ // ngxCount=0 deterministico).
3719
+ this.ngZone.run(() => {
3720
+ this.render = true;
3721
+ this.cdRef.detectChanges();
3722
+ });
3825
3723
  });
3826
3724
  }
3827
3725
  /**
@@ -3840,7 +3738,7 @@ class CodeEditorComponent {
3840
3738
  wordWrap: this.editorOptions.wordWrap || 'on',
3841
3739
  wrappingIndent: this.editorOptions.wrappingIndent || 'same',
3842
3740
  suggest: {
3843
- ...(this.editorOptions.suggest || {}),
3741
+ ...(this.editorOptions.suggest),
3844
3742
  showStatusBar: false,
3845
3743
  preview: false,
3846
3744
  previewMode: 'subwordSmart',
@@ -3869,7 +3767,9 @@ class CodeEditorComponent {
3869
3767
  */
3870
3768
  ngOnDestroy() {
3871
3769
  try {
3872
- delete (this.hostElementRef?.nativeElement).__wuicCmp;
3770
+ if (this.hostElementRef?.nativeElement) {
3771
+ delete this.hostElementRef.nativeElement.__wuicCmp;
3772
+ }
3873
3773
  }
3874
3774
  catch { /* defensive */ }
3875
3775
  if (this.layoutRaf !== null) {
@@ -3910,7 +3810,7 @@ class CodeEditorComponent {
3910
3810
  const hosts = [];
3911
3811
  let current = start?.parentElement || null;
3912
3812
  while (current) {
3913
- const style = window.getComputedStyle(current);
3813
+ const style = globalThis.getComputedStyle(current);
3914
3814
  const overflowY = style.overflowY || '';
3915
3815
  const isScrollableY = (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay')
3916
3816
  && current.scrollHeight > current.clientHeight;
@@ -4135,7 +4035,7 @@ class CodeEditorComponent {
4135
4035
  const replacement = doc.createElement('div');
4136
4036
  const ngIfAttr = node.getAttribute('*ngif') || node.getAttribute('*ngIf') || '';
4137
4037
  const captionMatch = /getMetaColumn\(\s*['"]([^'"]+)['"]\s*\)/i.exec(ngIfAttr);
4138
- if (captionMatch && captionMatch[1]) {
4038
+ if (captionMatch?.[1]) {
4139
4039
  replacement.setAttribute('data-wuic-caption', captionMatch[1]);
4140
4040
  }
4141
4041
  Array.from(node.attributes).forEach((attr) => replacement.setAttribute(attr.name, attr.value));
@@ -4209,7 +4109,7 @@ class CodeEditorComponent {
4209
4109
  }
4210
4110
  const ngIfAttr = current.getAttribute('*ngif') || current.getAttribute('*ngIf') || '';
4211
4111
  const match = /getMetaColumn\(\s*['"]([^'"]+)['"]\s*\)/i.exec(ngIfAttr);
4212
- if (match && match[1]) {
4112
+ if (match?.[1]) {
4213
4113
  return match[1];
4214
4114
  }
4215
4115
  current = current.parentElement;
@@ -4232,11 +4132,11 @@ class CodeEditorComponent {
4232
4132
  }));
4233
4133
  }
4234
4134
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CodeEditorComponent, deps: [{ token: i1$1.MonacoEditorLoaderService }, { token: i1$2.HttpClient }, { token: MetadataProviderService }, { token: UserInfoService }, { token: DataProviderService }, { token: WtoolboxService }, { token: i1$3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
4235
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CodeEditorComponent, isStandalone: true, selector: "wuic-code-editor", inputs: { field: "field", record: "record", metaInfo: "metaInfo", jsonTreeToggle: "jsonTreeToggle" }, host: { properties: { "style": "this.style" } }, viewQueries: [{ propertyName: "contextMenuAnchor", first: true, predicate: ["contextMenuAnchor"], descendants: true }, { propertyName: "editorRef", first: true, predicate: ["editorRef"], descendants: true }, { propertyName: "ctxs", first: true, predicate: ["ctxs"], descendants: true }], ngImport: i0, template: "@if (render) {\n<div [ngClass]=\"{'fullscreen': fullscreen, 'no-full-screen': !fullscreen }\">\n <div\n [ngStyle]=\"{width: sqlObjView ? '22%' : null, display: sqlObjView ? null : 'none', position: fullscreen ? 'absolute' : null, 'left': fullscreen ? '0px' : null, 'top': fullscreen ? '0px' : null }\"\n style=\"float: left; height: 100%; overflow: auto; background-color: #1e1e1e; z-index: 2000;\">\n <p-tree [value]=\"primeTreeNodes\">\n <ng-template let-node pTemplate=\"default\">\n <span style=\"-webkit-user-select: none; -ms-user-select: none; user-select: none;\" draggable=\"true\"\n (dragstart)=\"onTreeNodeDragStart($event, node.data)\" (click)=\"editorOptions.onNodeClick($event, node.data)\"\n (dragend)=\"onTreeNodeDragEnd($event, node.data)\">\n <span>\n {{ node.label }}\n </span>\n </span>\n </ng-template>\n </p-tree>\n </div>\n <div [ngStyle]=\"{width: sqlObjView ? '78%' : '100%', 'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null }\"\n style=\"height: 100%; float: left;\">\n <ul class=\"editor-btn\">\n <li>\n <div (click)=\"setFullScreen($event, this)\">\n <i\n [ngClass]=\"{'pi': true, 'pi-window-maximize': fullscreen == false, 'pi-window-minimize': fullscreen == true}\"></i>\n </div>\n </li>\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"toggleSqlObjView($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-server': true}\"></i>\n </div>\n </li>\n }\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"testSql($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-verified': true}\"></i>\n </div>\n </li>\n }\n @if (field.mc_suggest_value_callback) {\n <li>\n <div (click)=\"suggest($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-question': true}\"></i>\n </div>\n </li>\n }\n @if (isHtmlEditor) {\n <li>\n <div (click)=\"formatHtmlNow($event)\" title=\"Format HTML\">\n <i [ngClass]=\"{'pi': true, 'pi-align-left': true}\"></i>\n </div>\n </li>\n <li>\n <div (click)=\"toggleHtmlPreview($event)\" title=\"Toggle HTML preview\">\n <i [ngClass]=\"{'pi': true, 'pi-eye': showHtmlPreview, 'pi-eye-slash': !showHtmlPreview}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor) {\n <li>\n <div (click)=\"formatJsonNow($event)\" title=\"Format JSON\">\n <i [ngClass]=\"{'pi': true, 'pi-code': true}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor && jsonTreeToggle) {\n <li>\n <div (click)=\"toggleJsonTree($event)\" [title]=\"treeViewActive ? 'Codice' : 'Struttura'\">\n <i [ngClass]=\"{'pi': true, 'pi-sitemap': !treeViewActive, 'pi-pencil': treeViewActive}\"></i>\n </div>\n </li>\n }\n </ul>\n <div class=\"editor-shell\">\n <!-- Monaco resta VIVO anche in vista struttura (solo nascosto): il model\n e il record vengono riscritti a ogni modifica della struttura. -->\n <div class=\"editor-pane\" [ngClass]=\"{'editor-pane--with-preview': isHtmlEditor && showHtmlPreview}\"\n [style.display]=\"treeViewActive ? 'none' : null\">\n <ngx-monaco-editor #editorRef [options]=\"editorOptions\" [ngModel]=\"editorModelValue\"\n (ngModelChange)=\"onEditorModelChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n [ngStyle]=\"{'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null, width: '100%' }\"\n style=\"width: 100%; height: 100%;\"\n (onDropIntoEditor)=\"editorOptions.onDropIntoEditor($event)\"></ngx-monaco-editor>\n </div>\n @if (treeViewActive) {\n <div class=\"editor-pane\">\n <wuic-json-schema-tree-editor\n [schema]=\"jsonTreeSchema\"\n [value]=\"treeValue\"\n (valueChange)=\"onTreeValueChange($event)\" />\n </div>\n }\n @if (isHtmlEditor && showHtmlPreview) {\n <div class=\"html-preview-pane\">\n <div class=\"html-preview-pane__header\">HTML Pseudo-Preview (sanitized)</div>\n <div class=\"html-preview-pane__body\" [innerHTML]=\"sanitizedHtmlPreview\"></div>\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n <!-- Monaco viene inizializzato in modo asincrono (loader + registrazione\n language provider) DOPO che il @defer del code-area-editor ha gia'\n terminato il fetch del chunk: senza questo placeholder la sezione\n collasserebbe a nulla in quel gap. Riserva l'altezza dell'editor\n (200px, come .no-full-screen) per evitare il salto di layout. -->\n <div class=\"code-editor-monaco-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i> Inizializzazione editor\u2026\n </div>\n}\n\n@if (editorRef?.editorContent?.nativeElement) {\n<p-contextMenu [target]=\"editorRef?.editorContent?.nativeElement\" [model]=\"editorOptions.contextMenuItems\"\n appendTo=\"body\" />\n}\n", styles: [".editor-btn{color:#fff;list-style-type:none;z-index:2001;visibility:visible;position:absolute;right:10px;top:10px;display:flex;gap:8px;margin:0;padding:0}.editor-btn li{list-style:none}.editor-btn li div{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border:1px solid #334155;border-radius:4px;background:#0f172ad9;cursor:pointer}.fullscreen{position:fixed;inset:16px;z-index:3000;background:#1e1e1e;width:auto;height:auto}.fullscreen .editor-shell{position:absolute;inset:44px 0 0;height:auto}.fullscreen .editor-pane ngx-monaco-editor{position:relative;height:auto!important}.no-full-screen{width:100%;height:200px;position:relative}.editor-container{overflow:visible!important}.editor-shell{display:flex;width:100%;height:100%;min-height:0}.editor-pane{flex:1 1 auto;min-width:0;height:100%}.editor-pane--with-preview{flex:0 0 62%}.code-editor-monaco-loading{display:flex;align-items:center;justify-content:center;gap:8px;height:200px;color:#64748b;font-size:.9rem;background:#f1f5f9;border:1px dashed #cbd5e1;border-radius:6px}.code-editor-monaco-loading .pi-spinner{font-size:1rem}.html-preview-pane{flex:0 0 38%;min-width:260px;border-left:1px solid #404040;background:#111827;color:#e5e7eb;display:flex;flex-direction:column}.html-preview-pane__header{font-size:12px;letter-spacing:.04em;text-transform:uppercase;padding:10px 12px;border-bottom:1px solid #374151;color:#9ca3af}.html-preview-pane__body{flex:1 1 auto;overflow:auto;padding:12px;background:#fff;color:#111827}:host ::ng-deep .html-preview-pane__body .wuic-preview-component{border:1px solid #cbd5e1;border-left:4px solid #2563eb;border-radius:6px;padding:8px 10px;margin-bottom:10px;background:#f8fafc}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__title{font-weight:600;color:#0f172a;margin-bottom:4px}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__content{margin-top:8px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__label{display:block;font-size:13px;font-weight:600;color:#0f172a;margin-bottom:6px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__input{display:block;width:100%;border:1px solid #3b82f6;border-radius:4px;min-height:36px;box-sizing:border-box;background:#fff}:host ::ng-deep .monaco-editor .suggest-widget,:host ::ng-deep .monaco-editor .parameter-hints-widget,:host ::ng-deep .monaco-editor .monaco-hover{z-index:4000!important}:host ::ng-deep .monaco-editor .suggest-widget{height:220px!important;margin-top:-30px!important}:host ::ng-deep .monaco-editor .suggest-widget .tree,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows,:host ::ng-deep .monaco-editor .suggest-widget .monaco-scrollable-element{height:186px!important;max-height:186px!important}:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows{box-sizing:border-box;padding-bottom:20px!important}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{box-shadow:inset 0 0 5px gray;border-radius:10px}::-webkit-scrollbar-thumb{background:#ffffff80;border-radius:10px;visibility:hidden}::-webkit-scrollbar-thumb:hover{visibility:visible}::-webkit-scrollbar-thumb:hover{background:#fffc}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MonacoEditorModule }, { kind: "component", type: i1$1.MonacoEditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "uri"], outputs: ["init"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i10.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TreeModule }, { kind: "component", type: i4.Tree, selector: "p-tree", inputs: ["value", "selectionMode", "loadingMode", "selection", "styleClass", "contextMenu", "contextMenuSelectionMode", "contextMenuSelection", "draggableScope", "droppableScope", "draggableNodes", "droppableNodes", "metaKeySelection", "propagateSelectionUp", "propagateSelectionDown", "loading", "loadingIcon", "emptyMessage", "ariaLabel", "togglerAriaLabel", "ariaLabelledBy", "validateDrop", "filter", "filterInputAutoFocus", "filterBy", "filterMode", "filterOptions", "filterPlaceholder", "filteredNodes", "filterLocale", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "indentation", "_templateMap", "trackBy", "highlightOnSelect"], outputs: ["selectionChange", "contextMenuSelectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse", "onNodeContextMenuSelect", "onNodeDoubleClick", "onNodeDrop", "onLazyLoad", "onScroll", "onScrollIndexChange", "onFilter"] }, { kind: "component", type: JsonSchemaTreeEditorComponent, selector: "wuic-json-schema-tree-editor", inputs: ["schema", "value"], outputs: ["valueChange"] }] });
4135
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: CodeEditorComponent, isStandalone: true, selector: "wuic-code-editor", inputs: { field: "field", record: "record", metaInfo: "metaInfo", jsonTreeToggle: "jsonTreeToggle" }, host: { properties: { "style": "this.style" } }, viewQueries: [{ propertyName: "contextMenuAnchor", first: true, predicate: ["contextMenuAnchor"], descendants: true }, { propertyName: "editorRef", first: true, predicate: ["editorRef"], descendants: true }, { propertyName: "ctxs", first: true, predicate: ["ctxs"], descendants: true }], ngImport: i0, template: "@if (render) {\n<div [ngClass]=\"{'fullscreen': fullscreen, 'no-full-screen': !fullscreen }\">\n <div\n [ngStyle]=\"{width: sqlObjView ? '22%' : null, display: sqlObjView ? null : 'none', position: fullscreen ? 'absolute' : null, 'left': fullscreen ? '0px' : null, 'top': fullscreen ? '0px' : null }\"\n style=\"float: left; height: 100%; overflow: auto; background-color: #1e1e1e; z-index: 2000;\">\n <p-tree [value]=\"primeTreeNodes\">\n <ng-template let-node pTemplate=\"default\">\n <span style=\"-webkit-user-select: none; -ms-user-select: none; user-select: none;\" draggable=\"true\"\n (dragstart)=\"onTreeNodeDragStart($event, node.data)\" (click)=\"editorOptions.onNodeClick($event, node.data)\"\n (dragend)=\"onTreeNodeDragEnd($event, node.data)\">\n <span>\n {{ node.label }}\n </span>\n </span>\n </ng-template>\n </p-tree>\n </div>\n <div [ngStyle]=\"{width: sqlObjView ? '78%' : '100%', 'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null }\"\n style=\"height: 100%; float: left;\">\n <ul class=\"editor-btn\">\n <li>\n <div (click)=\"setFullScreen($event, this)\">\n <i\n [ngClass]=\"{'pi': true, 'pi-window-maximize': fullscreen == false, 'pi-window-minimize': fullscreen == true}\"></i>\n </div>\n </li>\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"toggleSqlObjView($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-server': true}\"></i>\n </div>\n </li>\n }\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"testSql($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-verified': true}\"></i>\n </div>\n </li>\n }\n @if (field.mc_suggest_value_callback) {\n <li>\n <div (click)=\"suggest($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-question': true}\"></i>\n </div>\n </li>\n }\n @if (isHtmlEditor) {\n <li>\n <div (click)=\"formatHtmlNow($event)\" title=\"Format HTML\">\n <i [ngClass]=\"{'pi': true, 'pi-align-left': true}\"></i>\n </div>\n </li>\n <li>\n <div (click)=\"toggleHtmlPreview($event)\" title=\"Toggle HTML preview\">\n <i [ngClass]=\"{'pi': true, 'pi-eye': showHtmlPreview, 'pi-eye-slash': !showHtmlPreview}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor) {\n <li>\n <div (click)=\"formatJsonNow($event)\" title=\"Format JSON\">\n <i [ngClass]=\"{'pi': true, 'pi-code': true}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor && jsonTreeToggle) {\n <li>\n <div (click)=\"toggleJsonTree($event)\" [title]=\"treeViewActive ? 'Codice' : 'Struttura'\">\n <i [ngClass]=\"{'pi': true, 'pi-sitemap': !treeViewActive, 'pi-pencil': treeViewActive}\"></i>\n </div>\n </li>\n }\n </ul>\n <div class=\"editor-shell\">\n <!-- Monaco resta VIVO anche in vista struttura (solo nascosto): il model\n e il record vengono riscritti a ogni modifica della struttura. -->\n <div class=\"editor-pane\" [ngClass]=\"{'editor-pane--with-preview': isHtmlEditor && showHtmlPreview}\"\n [style.display]=\"treeViewActive ? 'none' : null\">\n <ngx-monaco-editor #editorRef [options]=\"editorOptions\" [ngModel]=\"editorModelValue\"\n (ngModelChange)=\"onEditorModelChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n [ngStyle]=\"{'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null, width: '100%' }\"\n style=\"width: 100%; height: 100%;\"\n (onDropIntoEditor)=\"editorOptions.onDropIntoEditor($event)\"></ngx-monaco-editor>\n </div>\n @if (treeViewActive) {\n <div class=\"editor-pane\">\n <wuic-json-schema-tree-editor\n [schema]=\"jsonTreeSchema\"\n [value]=\"treeValue\"\n (valueChange)=\"onTreeValueChange($event)\" />\n </div>\n }\n @if (isHtmlEditor && showHtmlPreview) {\n <div class=\"html-preview-pane\">\n <div class=\"html-preview-pane__header\">HTML Pseudo-Preview (sanitized)</div>\n <div class=\"html-preview-pane__body\" [innerHTML]=\"sanitizedHtmlPreview\"></div>\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n <!-- Monaco viene inizializzato in modo asincrono (loader + registrazione\n language provider) DOPO che il @defer del code-area-editor ha gia'\n terminato il fetch del chunk: senza questo placeholder la sezione\n collasserebbe a nulla in quel gap. Riserva l'altezza dell'editor\n (200px, come .no-full-screen) per evitare il salto di layout. -->\n <div class=\"code-editor-monaco-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i> Inizializzazione editor\u2026\n </div>\n}\n\n@if (editorRef?.editorContent?.nativeElement) {\n<p-contextMenu [target]=\"editorRef?.editorContent?.nativeElement\" [model]=\"editorOptions.contextMenuItems\"\n appendTo=\"body\" />\n}\n", styles: [".editor-btn{color:#fff;list-style-type:none;z-index:2001;visibility:visible;position:absolute;right:10px;top:10px;display:flex;gap:8px;margin:0;padding:0}.editor-btn li{list-style:none}.editor-btn li div{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border:1px solid #334155;border-radius:4px;background:#0f172ad9;cursor:pointer}.fullscreen{position:fixed;inset:16px;z-index:3000;background:#1e1e1e;width:auto;height:auto}.fullscreen .editor-shell{position:absolute;inset:44px 0 0;height:auto}.fullscreen .editor-pane ngx-monaco-editor{position:relative;height:auto!important}.no-full-screen{width:100%;height:200px;position:relative}.editor-container{overflow:visible!important}.editor-shell{display:flex;width:100%;height:100%;min-height:0}.editor-pane{flex:1 1 auto;min-width:0;height:100%}.editor-pane--with-preview{flex:0 0 62%}.code-editor-monaco-loading{display:flex;align-items:center;justify-content:center;gap:8px;height:200px;color:#64748b;font-size:.9rem;background:#f1f5f9;border:1px dashed #cbd5e1;border-radius:6px}.code-editor-monaco-loading .pi-spinner{font-size:1rem}.html-preview-pane{flex:0 0 38%;min-width:260px;border-left:1px solid #404040;background:#111827;color:#e5e7eb;display:flex;flex-direction:column}.html-preview-pane__header{font-size:12px;letter-spacing:.04em;text-transform:uppercase;padding:10px 12px;border-bottom:1px solid #374151;color:#9ca3af}.html-preview-pane__body{flex:1 1 auto;overflow:auto;padding:12px;background:#fff;color:#111827}:host ::ng-deep .html-preview-pane__body .wuic-preview-component{border:1px solid #cbd5e1;border-left:4px solid #2563eb;border-radius:6px;padding:8px 10px;margin-bottom:10px;background:#f8fafc}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__title{font-weight:600;color:#0f172a;margin-bottom:4px}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__content{margin-top:8px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__label{display:block;font-size:13px;font-weight:600;color:#0f172a;margin-bottom:6px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__input{display:block;width:100%;border:1px solid #3b82f6;border-radius:4px;min-height:36px;box-sizing:border-box;background:#fff}:host ::ng-deep .monaco-editor .suggest-widget,:host ::ng-deep .monaco-editor .parameter-hints-widget,:host ::ng-deep .monaco-editor .monaco-hover{z-index:4000!important}:host ::ng-deep .monaco-editor .suggest-widget{height:220px!important;margin-top:-30px!important}:host ::ng-deep .monaco-editor .suggest-widget .tree,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows,:host ::ng-deep .monaco-editor .suggest-widget .monaco-scrollable-element{height:186px!important;max-height:186px!important}:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows{box-sizing:border-box;padding-bottom:20px!important}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{box-shadow:inset 0 0 5px gray;border-radius:10px}::-webkit-scrollbar-thumb{background:#ffffff80;border-radius:10px;visibility:hidden}::-webkit-scrollbar-thumb:hover{visibility:visible;background:#fffc}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MonacoEditorModule }, { kind: "component", type: i1$1.MonacoEditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "uri"], outputs: ["init"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i14.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TreeModule }, { kind: "component", type: i4.Tree, selector: "p-tree", inputs: ["value", "selectionMode", "loadingMode", "selection", "styleClass", "contextMenu", "contextMenuSelectionMode", "contextMenuSelection", "draggableScope", "droppableScope", "draggableNodes", "droppableNodes", "metaKeySelection", "propagateSelectionUp", "propagateSelectionDown", "loading", "loadingIcon", "emptyMessage", "ariaLabel", "togglerAriaLabel", "ariaLabelledBy", "validateDrop", "filter", "filterInputAutoFocus", "filterBy", "filterMode", "filterOptions", "filterPlaceholder", "filteredNodes", "filterLocale", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "indentation", "_templateMap", "trackBy", "highlightOnSelect"], outputs: ["selectionChange", "contextMenuSelectionChange", "onNodeSelect", "onNodeUnselect", "onNodeExpand", "onNodeCollapse", "onNodeContextMenuSelect", "onNodeDoubleClick", "onNodeDrop", "onLazyLoad", "onScroll", "onScrollIndexChange", "onFilter"] }, { kind: "component", type: JsonSchemaTreeEditorComponent, selector: "wuic-json-schema-tree-editor", inputs: ["schema", "value"], outputs: ["valueChange"] }] });
4236
4136
  }
4237
4137
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CodeEditorComponent, decorators: [{
4238
4138
  type: Component,
4239
- args: [{ selector: 'wuic-code-editor', imports: [NgClass, NgStyle, FormsModule, MonacoEditorModule, ContextMenuModule, TreeModule, JsonSchemaTreeEditorComponent], template: "@if (render) {\n<div [ngClass]=\"{'fullscreen': fullscreen, 'no-full-screen': !fullscreen }\">\n <div\n [ngStyle]=\"{width: sqlObjView ? '22%' : null, display: sqlObjView ? null : 'none', position: fullscreen ? 'absolute' : null, 'left': fullscreen ? '0px' : null, 'top': fullscreen ? '0px' : null }\"\n style=\"float: left; height: 100%; overflow: auto; background-color: #1e1e1e; z-index: 2000;\">\n <p-tree [value]=\"primeTreeNodes\">\n <ng-template let-node pTemplate=\"default\">\n <span style=\"-webkit-user-select: none; -ms-user-select: none; user-select: none;\" draggable=\"true\"\n (dragstart)=\"onTreeNodeDragStart($event, node.data)\" (click)=\"editorOptions.onNodeClick($event, node.data)\"\n (dragend)=\"onTreeNodeDragEnd($event, node.data)\">\n <span>\n {{ node.label }}\n </span>\n </span>\n </ng-template>\n </p-tree>\n </div>\n <div [ngStyle]=\"{width: sqlObjView ? '78%' : '100%', 'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null }\"\n style=\"height: 100%; float: left;\">\n <ul class=\"editor-btn\">\n <li>\n <div (click)=\"setFullScreen($event, this)\">\n <i\n [ngClass]=\"{'pi': true, 'pi-window-maximize': fullscreen == false, 'pi-window-minimize': fullscreen == true}\"></i>\n </div>\n </li>\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"toggleSqlObjView($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-server': true}\"></i>\n </div>\n </li>\n }\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"testSql($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-verified': true}\"></i>\n </div>\n </li>\n }\n @if (field.mc_suggest_value_callback) {\n <li>\n <div (click)=\"suggest($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-question': true}\"></i>\n </div>\n </li>\n }\n @if (isHtmlEditor) {\n <li>\n <div (click)=\"formatHtmlNow($event)\" title=\"Format HTML\">\n <i [ngClass]=\"{'pi': true, 'pi-align-left': true}\"></i>\n </div>\n </li>\n <li>\n <div (click)=\"toggleHtmlPreview($event)\" title=\"Toggle HTML preview\">\n <i [ngClass]=\"{'pi': true, 'pi-eye': showHtmlPreview, 'pi-eye-slash': !showHtmlPreview}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor) {\n <li>\n <div (click)=\"formatJsonNow($event)\" title=\"Format JSON\">\n <i [ngClass]=\"{'pi': true, 'pi-code': true}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor && jsonTreeToggle) {\n <li>\n <div (click)=\"toggleJsonTree($event)\" [title]=\"treeViewActive ? 'Codice' : 'Struttura'\">\n <i [ngClass]=\"{'pi': true, 'pi-sitemap': !treeViewActive, 'pi-pencil': treeViewActive}\"></i>\n </div>\n </li>\n }\n </ul>\n <div class=\"editor-shell\">\n <!-- Monaco resta VIVO anche in vista struttura (solo nascosto): il model\n e il record vengono riscritti a ogni modifica della struttura. -->\n <div class=\"editor-pane\" [ngClass]=\"{'editor-pane--with-preview': isHtmlEditor && showHtmlPreview}\"\n [style.display]=\"treeViewActive ? 'none' : null\">\n <ngx-monaco-editor #editorRef [options]=\"editorOptions\" [ngModel]=\"editorModelValue\"\n (ngModelChange)=\"onEditorModelChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n [ngStyle]=\"{'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null, width: '100%' }\"\n style=\"width: 100%; height: 100%;\"\n (onDropIntoEditor)=\"editorOptions.onDropIntoEditor($event)\"></ngx-monaco-editor>\n </div>\n @if (treeViewActive) {\n <div class=\"editor-pane\">\n <wuic-json-schema-tree-editor\n [schema]=\"jsonTreeSchema\"\n [value]=\"treeValue\"\n (valueChange)=\"onTreeValueChange($event)\" />\n </div>\n }\n @if (isHtmlEditor && showHtmlPreview) {\n <div class=\"html-preview-pane\">\n <div class=\"html-preview-pane__header\">HTML Pseudo-Preview (sanitized)</div>\n <div class=\"html-preview-pane__body\" [innerHTML]=\"sanitizedHtmlPreview\"></div>\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n <!-- Monaco viene inizializzato in modo asincrono (loader + registrazione\n language provider) DOPO che il @defer del code-area-editor ha gia'\n terminato il fetch del chunk: senza questo placeholder la sezione\n collasserebbe a nulla in quel gap. Riserva l'altezza dell'editor\n (200px, come .no-full-screen) per evitare il salto di layout. -->\n <div class=\"code-editor-monaco-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i> Inizializzazione editor\u2026\n </div>\n}\n\n@if (editorRef?.editorContent?.nativeElement) {\n<p-contextMenu [target]=\"editorRef?.editorContent?.nativeElement\" [model]=\"editorOptions.contextMenuItems\"\n appendTo=\"body\" />\n}\n", styles: [".editor-btn{color:#fff;list-style-type:none;z-index:2001;visibility:visible;position:absolute;right:10px;top:10px;display:flex;gap:8px;margin:0;padding:0}.editor-btn li{list-style:none}.editor-btn li div{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border:1px solid #334155;border-radius:4px;background:#0f172ad9;cursor:pointer}.fullscreen{position:fixed;inset:16px;z-index:3000;background:#1e1e1e;width:auto;height:auto}.fullscreen .editor-shell{position:absolute;inset:44px 0 0;height:auto}.fullscreen .editor-pane ngx-monaco-editor{position:relative;height:auto!important}.no-full-screen{width:100%;height:200px;position:relative}.editor-container{overflow:visible!important}.editor-shell{display:flex;width:100%;height:100%;min-height:0}.editor-pane{flex:1 1 auto;min-width:0;height:100%}.editor-pane--with-preview{flex:0 0 62%}.code-editor-monaco-loading{display:flex;align-items:center;justify-content:center;gap:8px;height:200px;color:#64748b;font-size:.9rem;background:#f1f5f9;border:1px dashed #cbd5e1;border-radius:6px}.code-editor-monaco-loading .pi-spinner{font-size:1rem}.html-preview-pane{flex:0 0 38%;min-width:260px;border-left:1px solid #404040;background:#111827;color:#e5e7eb;display:flex;flex-direction:column}.html-preview-pane__header{font-size:12px;letter-spacing:.04em;text-transform:uppercase;padding:10px 12px;border-bottom:1px solid #374151;color:#9ca3af}.html-preview-pane__body{flex:1 1 auto;overflow:auto;padding:12px;background:#fff;color:#111827}:host ::ng-deep .html-preview-pane__body .wuic-preview-component{border:1px solid #cbd5e1;border-left:4px solid #2563eb;border-radius:6px;padding:8px 10px;margin-bottom:10px;background:#f8fafc}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__title{font-weight:600;color:#0f172a;margin-bottom:4px}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__content{margin-top:8px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__label{display:block;font-size:13px;font-weight:600;color:#0f172a;margin-bottom:6px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__input{display:block;width:100%;border:1px solid #3b82f6;border-radius:4px;min-height:36px;box-sizing:border-box;background:#fff}:host ::ng-deep .monaco-editor .suggest-widget,:host ::ng-deep .monaco-editor .parameter-hints-widget,:host ::ng-deep .monaco-editor .monaco-hover{z-index:4000!important}:host ::ng-deep .monaco-editor .suggest-widget{height:220px!important;margin-top:-30px!important}:host ::ng-deep .monaco-editor .suggest-widget .tree,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows,:host ::ng-deep .monaco-editor .suggest-widget .monaco-scrollable-element{height:186px!important;max-height:186px!important}:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows{box-sizing:border-box;padding-bottom:20px!important}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{box-shadow:inset 0 0 5px gray;border-radius:10px}::-webkit-scrollbar-thumb{background:#ffffff80;border-radius:10px;visibility:hidden}::-webkit-scrollbar-thumb:hover{visibility:visible}::-webkit-scrollbar-thumb:hover{background:#fffc}\n"] }]
4139
+ args: [{ selector: 'wuic-code-editor', imports: [NgClass, NgStyle, FormsModule, MonacoEditorModule, ContextMenuModule, TreeModule, JsonSchemaTreeEditorComponent], template: "@if (render) {\n<div [ngClass]=\"{'fullscreen': fullscreen, 'no-full-screen': !fullscreen }\">\n <div\n [ngStyle]=\"{width: sqlObjView ? '22%' : null, display: sqlObjView ? null : 'none', position: fullscreen ? 'absolute' : null, 'left': fullscreen ? '0px' : null, 'top': fullscreen ? '0px' : null }\"\n style=\"float: left; height: 100%; overflow: auto; background-color: #1e1e1e; z-index: 2000;\">\n <p-tree [value]=\"primeTreeNodes\">\n <ng-template let-node pTemplate=\"default\">\n <span style=\"-webkit-user-select: none; -ms-user-select: none; user-select: none;\" draggable=\"true\"\n (dragstart)=\"onTreeNodeDragStart($event, node.data)\" (click)=\"editorOptions.onNodeClick($event, node.data)\"\n (dragend)=\"onTreeNodeDragEnd($event, node.data)\">\n <span>\n {{ node.label }}\n </span>\n </span>\n </ng-template>\n </p-tree>\n </div>\n <div [ngStyle]=\"{width: sqlObjView ? '78%' : '100%', 'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null }\"\n style=\"height: 100%; float: left;\">\n <ul class=\"editor-btn\">\n <li>\n <div (click)=\"setFullScreen($event, this)\">\n <i\n [ngClass]=\"{'pi': true, 'pi-window-maximize': fullscreen == false, 'pi-window-minimize': fullscreen == true}\"></i>\n </div>\n </li>\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"toggleSqlObjView($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-server': true}\"></i>\n </div>\n </li>\n }\n @if (editorOptions.language == 'sql') {\n <li>\n <div (click)=\"testSql($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-verified': true}\"></i>\n </div>\n </li>\n }\n @if (field.mc_suggest_value_callback) {\n <li>\n <div (click)=\"suggest($event, this)\">\n <i [ngClass]=\"{'pi': true, 'pi-question': true}\"></i>\n </div>\n </li>\n }\n @if (isHtmlEditor) {\n <li>\n <div (click)=\"formatHtmlNow($event)\" title=\"Format HTML\">\n <i [ngClass]=\"{'pi': true, 'pi-align-left': true}\"></i>\n </div>\n </li>\n <li>\n <div (click)=\"toggleHtmlPreview($event)\" title=\"Toggle HTML preview\">\n <i [ngClass]=\"{'pi': true, 'pi-eye': showHtmlPreview, 'pi-eye-slash': !showHtmlPreview}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor) {\n <li>\n <div (click)=\"formatJsonNow($event)\" title=\"Format JSON\">\n <i [ngClass]=\"{'pi': true, 'pi-code': true}\"></i>\n </div>\n </li>\n }\n @if (isJsonEditor && jsonTreeToggle) {\n <li>\n <div (click)=\"toggleJsonTree($event)\" [title]=\"treeViewActive ? 'Codice' : 'Struttura'\">\n <i [ngClass]=\"{'pi': true, 'pi-sitemap': !treeViewActive, 'pi-pencil': treeViewActive}\"></i>\n </div>\n </li>\n }\n </ul>\n <div class=\"editor-shell\">\n <!-- Monaco resta VIVO anche in vista struttura (solo nascosto): il model\n e il record vengono riscritti a ogni modifica della struttura. -->\n <div class=\"editor-pane\" [ngClass]=\"{'editor-pane--with-preview': isHtmlEditor && showHtmlPreview}\"\n [style.display]=\"treeViewActive ? 'none' : null\">\n <ngx-monaco-editor #editorRef [options]=\"editorOptions\" [ngModel]=\"editorModelValue\"\n (ngModelChange)=\"onEditorModelChange($event)\"\n [ngModelOptions]=\"{standalone: true}\"\n [ngStyle]=\"{'left': fullscreen ? (!sqlObjView ? '0px' : '22%') : null, width: '100%' }\"\n style=\"width: 100%; height: 100%;\"\n (onDropIntoEditor)=\"editorOptions.onDropIntoEditor($event)\"></ngx-monaco-editor>\n </div>\n @if (treeViewActive) {\n <div class=\"editor-pane\">\n <wuic-json-schema-tree-editor\n [schema]=\"jsonTreeSchema\"\n [value]=\"treeValue\"\n (valueChange)=\"onTreeValueChange($event)\" />\n </div>\n }\n @if (isHtmlEditor && showHtmlPreview) {\n <div class=\"html-preview-pane\">\n <div class=\"html-preview-pane__header\">HTML Pseudo-Preview (sanitized)</div>\n <div class=\"html-preview-pane__body\" [innerHTML]=\"sanitizedHtmlPreview\"></div>\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n <!-- Monaco viene inizializzato in modo asincrono (loader + registrazione\n language provider) DOPO che il @defer del code-area-editor ha gia'\n terminato il fetch del chunk: senza questo placeholder la sezione\n collasserebbe a nulla in quel gap. Riserva l'altezza dell'editor\n (200px, come .no-full-screen) per evitare il salto di layout. -->\n <div class=\"code-editor-monaco-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i> Inizializzazione editor\u2026\n </div>\n}\n\n@if (editorRef?.editorContent?.nativeElement) {\n<p-contextMenu [target]=\"editorRef?.editorContent?.nativeElement\" [model]=\"editorOptions.contextMenuItems\"\n appendTo=\"body\" />\n}\n", styles: [".editor-btn{color:#fff;list-style-type:none;z-index:2001;visibility:visible;position:absolute;right:10px;top:10px;display:flex;gap:8px;margin:0;padding:0}.editor-btn li{list-style:none}.editor-btn li div{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border:1px solid #334155;border-radius:4px;background:#0f172ad9;cursor:pointer}.fullscreen{position:fixed;inset:16px;z-index:3000;background:#1e1e1e;width:auto;height:auto}.fullscreen .editor-shell{position:absolute;inset:44px 0 0;height:auto}.fullscreen .editor-pane ngx-monaco-editor{position:relative;height:auto!important}.no-full-screen{width:100%;height:200px;position:relative}.editor-container{overflow:visible!important}.editor-shell{display:flex;width:100%;height:100%;min-height:0}.editor-pane{flex:1 1 auto;min-width:0;height:100%}.editor-pane--with-preview{flex:0 0 62%}.code-editor-monaco-loading{display:flex;align-items:center;justify-content:center;gap:8px;height:200px;color:#64748b;font-size:.9rem;background:#f1f5f9;border:1px dashed #cbd5e1;border-radius:6px}.code-editor-monaco-loading .pi-spinner{font-size:1rem}.html-preview-pane{flex:0 0 38%;min-width:260px;border-left:1px solid #404040;background:#111827;color:#e5e7eb;display:flex;flex-direction:column}.html-preview-pane__header{font-size:12px;letter-spacing:.04em;text-transform:uppercase;padding:10px 12px;border-bottom:1px solid #374151;color:#9ca3af}.html-preview-pane__body{flex:1 1 auto;overflow:auto;padding:12px;background:#fff;color:#111827}:host ::ng-deep .html-preview-pane__body .wuic-preview-component{border:1px solid #cbd5e1;border-left:4px solid #2563eb;border-radius:6px;padding:8px 10px;margin-bottom:10px;background:#f8fafc}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__title{font-weight:600;color:#0f172a;margin-bottom:4px}:host ::ng-deep .html-preview-pane__body .wuic-preview-component__content{margin-top:8px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__label{display:block;font-size:13px;font-weight:600;color:#0f172a;margin-bottom:6px}:host ::ng-deep .html-preview-pane__body .wuic-preview-field__input{display:block;width:100%;border:1px solid #3b82f6;border-radius:4px;min-height:36px;box-sizing:border-box;background:#fff}:host ::ng-deep .monaco-editor .suggest-widget,:host ::ng-deep .monaco-editor .parameter-hints-widget,:host ::ng-deep .monaco-editor .monaco-hover{z-index:4000!important}:host ::ng-deep .monaco-editor .suggest-widget{height:220px!important;margin-top:-30px!important}:host ::ng-deep .monaco-editor .suggest-widget .tree,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list,:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows,:host ::ng-deep .monaco-editor .suggest-widget .monaco-scrollable-element{height:186px!important;max-height:186px!important}:host ::ng-deep .monaco-editor .suggest-widget .monaco-list-rows{box-sizing:border-box;padding-bottom:20px!important}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{box-shadow:inset 0 0 5px gray;border-radius:10px}::-webkit-scrollbar-thumb{background:#ffffff80;border-radius:10px;visibility:hidden}::-webkit-scrollbar-thumb:hover{visibility:visible;background:#fffc}\n"] }]
4240
4140
  }], ctorParameters: () => [{ type: i1$1.MonacoEditorLoaderService }, { type: i1$2.HttpClient }, { type: MetadataProviderService }, { type: UserInfoService }, { type: DataProviderService }, { type: WtoolboxService }, { type: i1$3.DomSanitizer }], propDecorators: { style: [{
4241
4141
  type: HostBinding,
4242
4142
  args: ['style']
@@ -4260,4 +4160,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
4260
4160
  }] } });
4261
4161
 
4262
4162
  export { CodeEditorComponent };
4263
- //# sourceMappingURL=wuic-framework-lib-code-editor.component-C21mvjyr.mjs.map
4163
+ //# sourceMappingURL=wuic-framework-lib-code-editor.component-B6IpTSo8.mjs.map