wuic-framework-lib 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{wuic-framework-lib-chart-list.component-0J1ghIrS.mjs → wuic-framework-lib-chart-list.component-Bl424n7x.mjs} +50 -38
- package/fesm2022/{wuic-framework-lib-code-editor.component-C21mvjyr.mjs → wuic-framework-lib-code-editor.component-N6HMl2mf.mjs} +174 -274
- package/fesm2022/{wuic-framework-lib-designer.component-x10ZzUEy.mjs → wuic-framework-lib-designer.component-Bd2fwl6H.mjs} +499 -581
- package/fesm2022/{wuic-framework-lib-first-run-wizard.component-BuSxs_CM.mjs → wuic-framework-lib-first-run-wizard.component-NN6cWVHL.mjs} +22 -24
- package/fesm2022/{wuic-framework-lib-framework-docs.component-xTGLbEnp.mjs → wuic-framework-lib-framework-docs.component-B867JAYe.mjs} +2912 -294
- package/fesm2022/{wuic-framework-lib-pivot-builder.component-BkFFjPm4.mjs → wuic-framework-lib-pivot-builder.component-DWukH0L-.mjs} +580 -68
- package/fesm2022/{wuic-framework-lib-prompt-dialog-fallback-host.component-Bi-TrJB6.mjs → wuic-framework-lib-prompt-dialog-fallback-host.component-DWO1Rcgv.mjs} +2 -2
- package/fesm2022/wuic-framework-lib-report-designer.component-QcrU81m6.mjs +380 -0
- package/fesm2022/wuic-framework-lib-report-scaffold-dialog.component-U-zdOoRV.mjs +431 -0
- package/fesm2022/{wuic-framework-lib-report-viewer.component-BR-BfI2r.mjs → wuic-framework-lib-report-viewer.component-B4LhA3SL.mjs} +8 -13
- package/fesm2022/{wuic-framework-lib-scene3d-designer.component-BQzFxSXP.mjs → wuic-framework-lib-scene3d-designer.component-DjOfzKLo.mjs} +323 -88
- package/fesm2022/{wuic-framework-lib-scene3d-light-baker-gpu-0LjqhSNn.mjs → wuic-framework-lib-scene3d-light-baker-gpu-C96T9uIW.mjs} +2 -2
- package/fesm2022/{wuic-framework-lib-scene3d-shader-effect-CQLWkuh1.mjs → wuic-framework-lib-scene3d-shader-effect-DjHyCAFK.mjs} +612 -32
- package/fesm2022/{wuic-framework-lib-scene3d-viewer.component-imoV3HOs.mjs → wuic-framework-lib-scene3d-viewer.component-Dboz1fjl.mjs} +149 -18
- package/fesm2022/{wuic-framework-lib-scheduler-list.component-xzlTEkoq.mjs → wuic-framework-lib-scheduler-list.component--wY21R3o.mjs} +169 -53
- package/fesm2022/{wuic-framework-lib-spreadsheet-list-sf.component-CrS6fOGj.mjs → wuic-framework-lib-spreadsheet-list-sf.component-Ek30J8v-.mjs} +149 -108
- package/fesm2022/{wuic-framework-lib-stimulsoft-license.service-BIyxB4pO.mjs → wuic-framework-lib-stimulsoft-license.service-CsNNSFYs.mjs} +3 -3
- package/fesm2022/wuic-framework-lib-timeline-list.component-aqCH4P0G.mjs +805 -0
- package/fesm2022/{wuic-framework-lib-workflow-designer.component-5xtQ7-6z.mjs → wuic-framework-lib-workflow-designer.component-DMM8BeXm.mjs} +180 -150
- package/fesm2022/{wuic-framework-lib-wuic-framework-lib-3TZ-j-yL.mjs → wuic-framework-lib-wuic-framework-lib-dfLTqam5.mjs} +6761 -2347
- package/fesm2022/wuic-framework-lib.mjs +1 -1
- package/package.json +4 -2
- package/styles/_wuic-tokens.scss +82 -0
- package/styles/styles.scss +160 -0
- package/types/wuic-framework-lib.d.ts +4264 -2691
- 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,
|
|
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-dfLTqam5.mjs';
|
|
10
10
|
import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common';
|
|
11
|
-
import * as
|
|
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.
|
|
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
|
|
571
|
-
charToken = levelBlock
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
738
|
-
let matchingKeyWord = matchingKeyWords.length > 0 ? matchingKeyWords
|
|
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.
|
|
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
|
|
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
|
|
801
|
-
if (selectLastToken.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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.
|
|
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.
|
|
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.
|
|
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].
|
|
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.
|
|
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(
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
1542
|
-
let aliasStmnts = currentStatement.subStatements.filter(s => s.key == 'FROM' || s.key.
|
|
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
|
-
|
|
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 :
|
|
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
|
|
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(
|
|
1672
|
-
let isDbScopedSchema = !scaffoldedOnly && rawScopedToken.
|
|
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.
|
|
1743
|
-
let
|
|
1744
|
-
|
|
1745
|
-
|
|
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
|
-
|
|
1707
|
+
}
|
|
1708
|
+
case autocompleteContext.declaration: {
|
|
1774
1709
|
let paramName = '@Param';
|
|
1775
1710
|
let paramIndx = 1;
|
|
1776
|
-
while (this.currents.declarations.
|
|
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} ${
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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 || '').
|
|
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 || '').
|
|
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 || '').
|
|
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 || '').
|
|
2018
|
-
let modelSchema = (dataItem.sqlModel.schema || '').
|
|
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.
|
|
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
|
|
2053
|
-
let relSugg = suggestions.suggestions.find(x => x.insertText.
|
|
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
|
|
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.
|
|
2454
|
-
let routeId = record[routeIdContextField]?.value;
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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.
|
|
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.
|
|
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
|
|
2913
|
-
{ label: 'img', snippet: '<img src
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
3085
|
-
if (last
|
|
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 = /\([
|
|
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 = /\[\([
|
|
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
|
|
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 =
|
|
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
|
-
.
|
|
3360
|
-
.
|
|
3248
|
+
.replaceAll(/>\s+</g, '><')
|
|
3249
|
+
.replaceAll('\r\n', '\n')
|
|
3361
3250
|
.trim();
|
|
3362
3251
|
const withLineBreaks = normalized
|
|
3363
|
-
.
|
|
3364
|
-
.
|
|
3365
|
-
.
|
|
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 =
|
|
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 =
|
|
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)
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
4163
|
+
//# sourceMappingURL=wuic-framework-lib-code-editor.component-N6HMl2mf.mjs.map
|