@masterteam/formula-builder 0.0.7 → 0.0.8

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.
@@ -77,6 +77,7 @@ class FormulaValidatorService {
77
77
  this.validateSubject
78
78
  .pipe(debounceTime(this.DEBOUNCE_MS), distinctUntilChanged((a, b) => a.formula === b.formula &&
79
79
  a.levelSchemaId === b.levelSchemaId &&
80
+ a.moduleId === b.moduleId &&
80
81
  a.templateId === b.templateId &&
81
82
  a.apiMode === b.apiMode &&
82
83
  JSON.stringify(a.knownProperties) ===
@@ -87,7 +88,7 @@ class FormulaValidatorService {
87
88
  });
88
89
  }
89
90
  /** Validate formula (debounced) */
90
- validate(formula, knownProperties, levelSchemaId, templateId, apiMode = 'default') {
91
+ validate(formula, knownProperties, levelSchemaId, moduleId, templateId, apiMode = 'default') {
91
92
  // Handle empty formula
92
93
  if (!formula || formula.trim() === '') {
93
94
  this._validation.set(EMPTY_VALIDATION);
@@ -98,12 +99,13 @@ class FormulaValidatorService {
98
99
  formula,
99
100
  knownProperties,
100
101
  levelSchemaId,
102
+ moduleId,
101
103
  templateId,
102
104
  apiMode,
103
105
  });
104
106
  }
105
107
  /** Validate formula immediately (no debounce) */
106
- validateImmediate(formula, knownProperties, levelSchemaId, templateId, apiMode = 'default') {
108
+ validateImmediate(formula, knownProperties, levelSchemaId, moduleId, templateId, apiMode = 'default') {
107
109
  if (!formula || formula.trim() === '') {
108
110
  return of(EMPTY_VALIDATION);
109
111
  }
@@ -112,6 +114,7 @@ class FormulaValidatorService {
112
114
  formula,
113
115
  knownProperties,
114
116
  levelSchemaId,
117
+ moduleId,
115
118
  templateId,
116
119
  apiMode,
117
120
  }).pipe(tap((result) => {
@@ -195,17 +198,23 @@ class FormulaContextService {
195
198
  contextCache = new Map();
196
199
  propertiesCache = new Map();
197
200
  nextTokensCache = new Map();
198
- loadContext(schemaId, contextEntityTypeKey, mode = 'default') {
201
+ loadContext(schemaId, moduleId, contextEntityTypeKey, mode = 'default') {
199
202
  if (!schemaId)
200
203
  return of(null);
201
- const cacheKey = `${mode}:${schemaId}:${contextEntityTypeKey ?? ''}`;
204
+ const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${contextEntityTypeKey ?? ''}`;
202
205
  const cached = this.contextCache.get(cacheKey);
203
206
  if (cached) {
204
207
  return of(cached);
205
208
  }
206
- const query = mode === 'default' && contextEntityTypeKey
207
- ? `?contextEntityTypeKey=${encodeURIComponent(contextEntityTypeKey)}`
208
- : '';
209
+ const params = new URLSearchParams();
210
+ if (mode === 'default' && contextEntityTypeKey) {
211
+ params.set('contextEntityTypeKey', contextEntityTypeKey);
212
+ }
213
+ if (moduleId !== undefined) {
214
+ params.set('moduleId', moduleId.toString());
215
+ }
216
+ const queryString = params.toString();
217
+ const query = queryString ? `?${queryString}` : '';
209
218
  return this.http
210
219
  .get(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)
211
220
  .pipe(map((response) => this.unwrapResponse(response)), tap((context) => {
@@ -217,12 +226,12 @@ class FormulaContextService {
217
226
  return of(null);
218
227
  }));
219
228
  }
220
- getScopeProperties(schemaId, component, tablePath, mode = 'default') {
229
+ getScopeProperties(schemaId, component, tablePath, moduleId, mode = 'default') {
221
230
  if (!schemaId || !component || !tablePath)
222
231
  return of([]);
223
232
  if (mode === 'current-only')
224
233
  return of([]);
225
- const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;
234
+ const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;
226
235
  const cached = this.propertiesCache.get(cacheKey);
227
236
  if (cached) {
228
237
  return of(cached);
@@ -232,6 +241,9 @@ class FormulaContextService {
232
241
  component,
233
242
  tablePath,
234
243
  });
244
+ if (moduleId !== undefined) {
245
+ params.set('moduleId', moduleId.toString());
246
+ }
235
247
  return this.http
236
248
  .get(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)
237
249
  .pipe(map((response) => this.unwrapResponse(response) ?? []), tap((response) => {
@@ -241,12 +253,12 @@ class FormulaContextService {
241
253
  return of([]);
242
254
  }));
243
255
  }
244
- getNextTokens(schemaId, component, tablePath, mode = 'default') {
256
+ getNextTokens(schemaId, component, tablePath, moduleId, mode = 'default') {
245
257
  if (!schemaId || !component || !tablePath)
246
258
  return of(null);
247
259
  if (mode === 'current-only')
248
260
  return of(null);
249
- const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;
261
+ const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;
250
262
  const cached = this.nextTokensCache.get(cacheKey);
251
263
  if (cached) {
252
264
  return of(cached);
@@ -256,6 +268,9 @@ class FormulaContextService {
256
268
  component,
257
269
  tablePath,
258
270
  });
271
+ if (moduleId !== undefined) {
272
+ params.set('moduleId', moduleId.toString());
273
+ }
259
274
  return this.http
260
275
  .get(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)
261
276
  .pipe(map((response) => this.unwrapResponse(response)), tap((payload) => {
@@ -410,8 +425,17 @@ const DEFAULT_TOOLBAR_TABS = [
410
425
  'properties',
411
426
  'operators',
412
427
  ];
428
+ const PROPERTY_SCOPE_ORDER = [
429
+ 'Current',
430
+ 'Host',
431
+ 'Parent',
432
+ // 'Children',
433
+ // 'Descendants',
434
+ // 'Modules',
435
+ ];
413
436
  const SCOPE_ICON_MAP = {
414
437
  Current: 'map.marker-pin-01',
438
+ Host: 'map.marker-pin-01',
415
439
  Level: 'map.marker-pin-01',
416
440
  Parent: 'arrow.arrow-up',
417
441
  Children: 'user.users-01',
@@ -430,6 +454,8 @@ class FormulaBuilder {
430
454
  propertiesByPath = input({}, ...(ngDevMode ? [{ debugName: "propertiesByPath" }] : []));
431
455
  /** Level schema ID for validation context */
432
456
  levelSchemaId = input(...(ngDevMode ? [undefined, { debugName: "levelSchemaId" }] : []));
457
+ /** Optional module ID when the formula is scoped inside a level-linked module */
458
+ moduleId = input(...(ngDevMode ? [undefined, { debugName: "moduleId" }] : []));
433
459
  /** Optional current context entity key, e.g. LevelData or Risk */
434
460
  contextEntityTypeKey = input(...(ngDevMode ? [undefined, { debugName: "contextEntityTypeKey" }] : []));
435
461
  /** Template ID for validation context */
@@ -468,10 +494,20 @@ class FormulaBuilder {
468
494
  const normalized = value.trim();
469
495
  return normalized.length > 0 ? normalized : undefined;
470
496
  }, ...(ngDevMode ? [{ debugName: "resolvedContextEntityTypeKey" }] : []));
497
+ isModuleContext = computed(() => {
498
+ const contextType = this.resolvedContextEntityTypeKey() ??
499
+ this.builderContext()?.contextEntityTypeKey;
500
+ if (typeof contextType !== 'string') {
501
+ return false;
502
+ }
503
+ const normalized = contextType.trim().toLowerCase();
504
+ return normalized.length > 0 && normalized !== 'leveldata';
505
+ }, ...(ngDevMode ? [{ debugName: "isModuleContext" }] : []));
471
506
  autocompleteProvider = (request) => {
472
507
  return this.autocompleteService.getSuggestions({
473
508
  ...request,
474
509
  levelSchemaId: this.levelSchemaId(),
510
+ moduleId: this.moduleId(),
475
511
  contextEntityTypeKey: this.resolvedContextEntityTypeKey() ??
476
512
  this.builderContext()?.contextEntityTypeKey,
477
513
  }, this.isProcessBuilder() ? 'current-only' : 'default');
@@ -514,9 +550,10 @@ class FormulaBuilder {
514
550
  // Validate when formula changes
515
551
  effect(() => {
516
552
  const formula = this.expressionValue();
553
+ const moduleId = this.moduleId();
517
554
  const apiMode = this.formulaApiMode();
518
555
  if (formula && formula.trim().length > 0) {
519
- this.validatorService.validate(formula, undefined, this.levelSchemaId(), this.templateId(), apiMode);
556
+ this.validatorService.validate(formula, undefined, this.levelSchemaId(), moduleId, this.templateId(), apiMode);
520
557
  }
521
558
  });
522
559
  // Emit validation changes
@@ -527,6 +564,7 @@ class FormulaBuilder {
527
564
  // Load builder context when schema changes
528
565
  effect(() => {
529
566
  const schemaId = this.levelSchemaId();
567
+ const moduleId = this.moduleId();
530
568
  const apiMode = this.formulaApiMode();
531
569
  const contextEntityTypeKey = this.resolvedContextEntityTypeKey();
532
570
  if (!schemaId) {
@@ -541,7 +579,7 @@ class FormulaBuilder {
541
579
  this.propertiesByPathApi.set({});
542
580
  this.nextTokenRulesByPath.set({});
543
581
  this.contextService
544
- .loadContext(schemaId, contextEntityTypeKey, apiMode)
582
+ .loadContext(schemaId, moduleId, contextEntityTypeKey, apiMode)
545
583
  .subscribe((context) => {
546
584
  if (requestId !== this.contextRequestId) {
547
585
  return;
@@ -579,6 +617,7 @@ class FormulaBuilder {
579
617
  // Fetch properties for the selected table path
580
618
  effect(() => {
581
619
  const schemaId = this.levelSchemaId();
620
+ const moduleId = this.moduleId();
582
621
  const isProcessBuilder = this.isProcessBuilder();
583
622
  const tablePath = this.resolvedTablePath();
584
623
  const component = this.propertiesComponent();
@@ -598,7 +637,7 @@ class FormulaBuilder {
598
637
  }
599
638
  this.propertyLoadingPath.set(tablePath);
600
639
  this.contextService
601
- .getScopeProperties(schemaId, component, tablePath)
640
+ .getScopeProperties(schemaId, component, tablePath, moduleId)
602
641
  .subscribe((props) => {
603
642
  this.propertiesByPathApi.update((current) => ({
604
643
  ...current,
@@ -612,6 +651,7 @@ class FormulaBuilder {
612
651
  // Fetch next-token rules for the current table path
613
652
  effect(() => {
614
653
  const schemaId = this.levelSchemaId();
654
+ const moduleId = this.moduleId();
615
655
  const isProcessBuilder = this.isProcessBuilder();
616
656
  const tablePath = this.resolvedTablePath();
617
657
  const component = this.propertiesComponent();
@@ -620,7 +660,7 @@ class FormulaBuilder {
620
660
  if (this.nextTokenRulesByPath()[tablePath])
621
661
  return;
622
662
  this.contextService
623
- .getNextTokens(schemaId, component, tablePath)
663
+ .getNextTokens(schemaId, component, tablePath, moduleId)
624
664
  .subscribe((response) => {
625
665
  if (!response)
626
666
  return;
@@ -898,7 +938,10 @@ class FormulaBuilder {
898
938
  const operators = this.contextOperators();
899
939
  if (operators.length === 0)
900
940
  return [];
901
- return operators.map((operator) => ({
941
+ const operatorsByToken = new Map(operators.map((operator) => [operator.token, operator]));
942
+ return PROPERTY_SCOPE_ORDER.map((token) => operatorsByToken.get(token))
943
+ .filter((operator) => Boolean(operator))
944
+ .map((operator) => ({
902
945
  key: operator.token,
903
946
  label: `@${operator.token}`,
904
947
  requiresParam: operator.requiresParameter ?? false,
@@ -908,7 +951,7 @@ class FormulaBuilder {
908
951
  /** Radio card options for scope selection */
909
952
  scopeOptions = computed(() => this.availableScopes().map((scope) => ({
910
953
  id: scope.key,
911
- name: scope.key,
954
+ name: this.getOperatorDisplayName(scope.key),
912
955
  icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,
913
956
  })), ...(ngDevMode ? [{ debugName: "scopeOptions" }] : []));
914
957
  /** Handle scope selection from radio cards */
@@ -1062,14 +1105,20 @@ class FormulaBuilder {
1062
1105
  const block = createPropertyBlock(`@${tablePath}::${prop.key}`, 'current', display);
1063
1106
  insertBlock(block);
1064
1107
  }
1108
+ getOperatorDisplayName(token) {
1109
+ if (token === 'Host' && this.isModuleContext()) {
1110
+ return 'Level';
1111
+ }
1112
+ return token;
1113
+ }
1065
1114
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FormulaBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
1066
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FormulaBuilder, isStandalone: true, selector: "mt-formula-builder", inputs: { propertiesByPath: { classPropertyName: "propertiesByPath", publicName: "propertiesByPath", isSignal: true, isRequired: false, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null }, contextEntityTypeKey: { classPropertyName: "contextEntityTypeKey", publicName: "contextEntityTypeKey", isSignal: true, isRequired: false, transformFunction: null }, templateId: { classPropertyName: "templateId", publicName: "templateId", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hideToolbar: { classPropertyName: "hideToolbar", publicName: "hideToolbar", isSignal: true, isRequired: false, transformFunction: null }, hideStatusBar: { classPropertyName: "hideStatusBar", publicName: "hideStatusBar", isSignal: true, isRequired: false, transformFunction: null }, toolbarTabs: { classPropertyName: "toolbarTabs", publicName: "toolbarTabs", isSignal: true, isRequired: false, transformFunction: null }, codeOnly: { classPropertyName: "codeOnly", publicName: "codeOnly", isSignal: true, isRequired: false, transformFunction: null }, isProcessBuilder: { classPropertyName: "isProcessBuilder", publicName: "isProcessBuilder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validationChange: "validationChange", tokensChange: "tokensChange" }, host: { classAttribute: "block" }, providers: [
1115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FormulaBuilder, isStandalone: true, selector: "mt-formula-builder", inputs: { propertiesByPath: { classPropertyName: "propertiesByPath", publicName: "propertiesByPath", isSignal: true, isRequired: false, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null }, moduleId: { classPropertyName: "moduleId", publicName: "moduleId", isSignal: true, isRequired: false, transformFunction: null }, contextEntityTypeKey: { classPropertyName: "contextEntityTypeKey", publicName: "contextEntityTypeKey", isSignal: true, isRequired: false, transformFunction: null }, templateId: { classPropertyName: "templateId", publicName: "templateId", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hideToolbar: { classPropertyName: "hideToolbar", publicName: "hideToolbar", isSignal: true, isRequired: false, transformFunction: null }, hideStatusBar: { classPropertyName: "hideStatusBar", publicName: "hideStatusBar", isSignal: true, isRequired: false, transformFunction: null }, toolbarTabs: { classPropertyName: "toolbarTabs", publicName: "toolbarTabs", isSignal: true, isRequired: false, transformFunction: null }, codeOnly: { classPropertyName: "codeOnly", publicName: "codeOnly", isSignal: true, isRequired: false, transformFunction: null }, isProcessBuilder: { classPropertyName: "isProcessBuilder", publicName: "isProcessBuilder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validationChange: "validationChange", tokensChange: "tokensChange" }, host: { classAttribute: "block" }, providers: [
1067
1116
  {
1068
1117
  provide: NG_VALUE_ACCESSOR,
1069
1118
  useExisting: forwardRef(() => FormulaBuilder),
1070
1119
  multi: true,
1071
1120
  },
1072
- ], viewQueries: [{ propertyName: "editor", first: true, predicate: ["formulaEditor"], descendants: true, isSignal: true }, { propertyName: "codeEditor", first: true, predicate: ["formulaEditorCode"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: RadioCards, selector: "mt-radio-cards", inputs: ["circle", "color", "size", "columns", "options", "activeId", "itemTemplate"], outputs: ["optionsChange", "activeIdChange", "selectionChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: FormulaToolbar, selector: "mt-formula-toolbar", inputs: ["knownProperties", "propertiesTemplate", "functionCategories", "operators", "initialTab", "visibleTabs", "searchPlaceholder", "labels"], outputs: ["onBlockInsert", "onTabChange"] }, { kind: "component", type: FormulaStatusBar, selector: "mt-formula-status-bar", inputs: ["validation", "labels"] }, { kind: "component", type: FormulaEditor, selector: "mt-formula-editor", inputs: ["placeholder", "initialTokens", "disabled", "borderless"], outputs: ["formulaChange", "tokensChange", "onBlur", "onFocus"] }, { kind: "component", type: FormulaEditorCode, selector: "mt-formula-editor-code", inputs: ["placeholder", "initialFormula", "disabled", "language", "theme", "borderless", "autocompleteProvider", "autocompleteDebounceMs"], outputs: ["formulaChange", "onBlur", "onFocus"] }] });
1121
+ ], viewQueries: [{ propertyName: "editor", first: true, predicate: ["formulaEditor"], descendants: true, isSignal: true }, { propertyName: "codeEditor", first: true, predicate: ["formulaEditorCode"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { 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: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: RadioCards, selector: "mt-radio-cards", inputs: ["circle", "color", "size", "columns", "options", "activeId", "itemTemplate"], outputs: ["optionsChange", "activeIdChange", "selectionChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: FormulaToolbar, selector: "mt-formula-toolbar", inputs: ["knownProperties", "propertiesTemplate", "functionCategories", "operators", "initialTab", "visibleTabs", "searchPlaceholder", "labels"], outputs: ["onBlockInsert", "onTabChange"] }, { kind: "component", type: FormulaStatusBar, selector: "mt-formula-status-bar", inputs: ["validation", "labels"] }, { kind: "component", type: FormulaEditor, selector: "mt-formula-editor", inputs: ["placeholder", "initialTokens", "disabled", "borderless"], outputs: ["formulaChange", "tokensChange", "onBlur", "onFocus"] }, { kind: "component", type: FormulaEditorCode, selector: "mt-formula-editor-code", inputs: ["placeholder", "initialFormula", "disabled", "language", "theme", "borderless", "autocompleteProvider", "autocompleteDebounceMs"], outputs: ["formulaChange", "onBlur", "onFocus"] }] });
1073
1122
  }
1074
1123
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FormulaBuilder, decorators: [{
1075
1124
  type: Component,
@@ -1097,8 +1146,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1097
1146
  useExisting: forwardRef(() => FormulaBuilder),
1098
1147
  multi: true,
1099
1148
  },
1100
- ], template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n" }]
1101
- }], ctorParameters: () => [], propDecorators: { editor: [{ type: i0.ViewChild, args: ['formulaEditor', { isSignal: true }] }], codeEditor: [{ type: i0.ViewChild, args: ['formulaEditorCode', { isSignal: true }] }], propertiesByPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertiesByPath", required: false }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }], contextEntityTypeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextEntityTypeKey", required: false }] }], templateId: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateId", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hideToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideToolbar", required: false }] }], hideStatusBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideStatusBar", required: false }] }], toolbarTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarTabs", required: false }] }], codeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "codeOnly", required: false }] }], isProcessBuilder: [{ type: i0.Input, args: [{ isSignal: true, alias: "isProcessBuilder", required: false }] }], validationChange: [{ type: i0.Output, args: ["validationChange"] }], tokensChange: [{ type: i0.Output, args: ["tokensChange"] }] } });
1149
+ ], template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n" }]
1150
+ }], ctorParameters: () => [], propDecorators: { editor: [{ type: i0.ViewChild, args: ['formulaEditor', { isSignal: true }] }], codeEditor: [{ type: i0.ViewChild, args: ['formulaEditorCode', { isSignal: true }] }], propertiesByPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertiesByPath", required: false }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }], moduleId: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleId", required: false }] }], contextEntityTypeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextEntityTypeKey", required: false }] }], templateId: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateId", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hideToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideToolbar", required: false }] }], hideStatusBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideStatusBar", required: false }] }], toolbarTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarTabs", required: false }] }], codeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "codeOnly", required: false }] }], isProcessBuilder: [{ type: i0.Input, args: [{ isSignal: true, alias: "isProcessBuilder", required: false }] }], validationChange: [{ type: i0.Output, args: ["validationChange"] }], tokensChange: [{ type: i0.Output, args: ["tokensChange"] }] } });
1102
1151
 
1103
1152
  /**
1104
1153
  * Services barrel export
@@ -1 +1 @@
1
- {"version":3,"file":"masterteam-formula-builder.mjs","sources":["../../../../packages/masterteam/formula-builder/src/lib/services/formula-validator.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-context.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-autocomplete.service.ts","../../../../packages/masterteam/formula-builder/src/lib/utils/formula-path-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.html","../../../../packages/masterteam/formula-builder/src/lib/services/index.ts","../../../../packages/masterteam/formula-builder/src/public-api.ts","../../../../packages/masterteam/formula-builder/src/masterteam-formula-builder.ts"],"sourcesContent":["/**\r\n * Formula Validator Service\r\n * Handles real-time validation via API\r\n */\r\n\r\nimport { Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\r\nimport {\r\n Observable,\r\n Subject,\r\n of,\r\n catchError,\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n tap,\r\n} from 'rxjs';\r\nimport {\r\n ValidationResult,\r\n ValidationRequest,\r\n ApiErrorResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\ntype ValidationJob = ValidationRequest & { apiMode: FormulaApiMode };\r\n\r\n/** Default validation result for empty formulas */\r\nconst EMPTY_VALIDATION: ValidationResult = {\r\n isValid: true,\r\n errors: [],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n/** Error validation result */\r\nconst ERROR_VALIDATION: ValidationResult = {\r\n isValid: false,\r\n errors: [\r\n { message: 'Validation failed', line: 1, column: 1, severity: 'Error' },\r\n ],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaValidatorService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n /** Debounce time in ms */\r\n private readonly DEBOUNCE_MS = 300;\r\n\r\n /** Current validation result */\r\n private readonly _validation = signal<ValidationResult>(EMPTY_VALIDATION);\r\n\r\n /** Loading state */\r\n private readonly _isValidating = signal(false);\r\n\r\n /** Validation subject for debouncing */\r\n private readonly validateSubject = new Subject<ValidationJob>();\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n /** Public signals */\r\n readonly validation = this._validation.asReadonly();\r\n readonly isValidating = this._isValidating.asReadonly();\r\n\r\n constructor() {\r\n this.setupValidationStream();\r\n }\r\n\r\n /** Setup debounced validation stream */\r\n private setupValidationStream(): void {\r\n this.validateSubject\r\n .pipe(\r\n debounceTime(this.DEBOUNCE_MS),\r\n distinctUntilChanged(\r\n (a, b) =>\r\n a.formula === b.formula &&\r\n a.levelSchemaId === b.levelSchemaId &&\r\n a.templateId === b.templateId &&\r\n a.apiMode === b.apiMode &&\r\n JSON.stringify(a.knownProperties) ===\r\n JSON.stringify(b.knownProperties),\r\n ),\r\n tap(() => this._isValidating.set(true)),\r\n switchMap((request) => this.callValidateApi(request)),\r\n )\r\n .subscribe((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n });\r\n }\r\n\r\n /** Validate formula (debounced) */\r\n validate(\r\n formula: string,\r\n knownProperties?: string[],\r\n levelSchemaId?: number,\r\n templateId?: number,\r\n apiMode: FormulaApiMode = 'default',\r\n ): void {\r\n // Handle empty formula\r\n if (!formula || formula.trim() === '') {\r\n this._validation.set(EMPTY_VALIDATION);\r\n return;\r\n }\r\n\r\n // Push to debounced stream\r\n this.validateSubject.next({\r\n formula,\r\n knownProperties,\r\n levelSchemaId,\r\n templateId,\r\n apiMode,\r\n });\r\n }\r\n\r\n /** Validate formula immediately (no debounce) */\r\n validateImmediate(\r\n formula: string,\r\n knownProperties?: string[],\r\n levelSchemaId?: number,\r\n templateId?: number,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<ValidationResult> {\r\n if (!formula || formula.trim() === '') {\r\n return of(EMPTY_VALIDATION);\r\n }\r\n\r\n this._isValidating.set(true);\r\n\r\n return this.callValidateApi({\r\n formula,\r\n knownProperties,\r\n levelSchemaId,\r\n templateId,\r\n apiMode,\r\n }).pipe(\r\n tap((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n }),\r\n );\r\n }\r\n\r\n /** Call validation API */\r\n private callValidateApi(\r\n request: ValidationJob,\r\n ): Observable<ValidationResult> {\r\n const { apiMode, ...payload } = request;\r\n return this.http\r\n .post<\r\n ValidationResult | { data: ValidationResult }\r\n >(`${this.getBaseUrl(apiMode)}/validate`, payload)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? ERROR_VALIDATION),\r\n catchError((error: HttpErrorResponse) => {\r\n console.error('Validation API error:', error);\r\n\r\n // Try to extract error message\r\n const apiError = error.error as ApiErrorResponse;\r\n const message =\r\n apiError?.message ?? apiError?.error ?? 'Validation failed';\r\n\r\n return of({\r\n ...ERROR_VALIDATION,\r\n errors: [\r\n { message, line: 1, column: 1, severity: 'Error' as const },\r\n ],\r\n });\r\n }),\r\n );\r\n }\r\n\r\n /** Reset validation state */\r\n reset(): void {\r\n this._validation.set(EMPTY_VALIDATION);\r\n this._isValidating.set(false);\r\n }\r\n\r\n /** Get current validation result */\r\n getCurrentValidation(): ValidationResult {\r\n return this._validation();\r\n }\r\n\r\n /** Check if formula is valid */\r\n isValid(): boolean {\r\n return this._validation().isValid;\r\n }\r\n\r\n /** Get validation errors */\r\n getErrors() {\r\n return this._validation().errors;\r\n }\r\n\r\n /** Get validation warnings */\r\n getWarnings() {\r\n return this._validation().warnings;\r\n }\r\n\r\n /** Get formula dependencies */\r\n getDependencies() {\r\n return this._validation().dependencies;\r\n }\r\n\r\n /** Get formula complexity */\r\n getComplexity() {\r\n return this._validation().complexity;\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, tap, map } from 'rxjs';\r\n\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaBuilderNextTokensResponse,\r\n FormulaPropertyDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaContextService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n private readonly contextCache = new Map<\r\n string,\r\n FormulaBuilderContextResponse\r\n >();\r\n private readonly propertiesCache = new Map<\r\n string,\r\n FormulaPropertyDescriptor[]\r\n >();\r\n private readonly nextTokensCache = new Map<\r\n string,\r\n FormulaBuilderNextTokensResponse\r\n >();\r\n\r\n loadContext(\r\n schemaId: number,\r\n contextEntityTypeKey?: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaBuilderContextResponse | null> {\r\n if (!schemaId) return of(null);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${contextEntityTypeKey ?? ''}`;\r\n const cached = this.contextCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const query =\r\n mode === 'default' && contextEntityTypeKey\r\n ? `?contextEntityTypeKey=${encodeURIComponent(contextEntityTypeKey)}`\r\n : '';\r\n\r\n return this.http\r\n .get<\r\n FormulaBuilderContextResponse | { data: FormulaBuilderContextResponse }\r\n >(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((context) => {\r\n if (context) {\r\n this.contextCache.set(cacheKey, context);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula builder context:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n\r\n getScopeProperties(\r\n schemaId: number,\r\n component: string,\r\n tablePath: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaPropertyDescriptor[]> {\r\n if (!schemaId || !component || !tablePath) return of([]);\r\n if (mode === 'current-only') return of([]);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;\r\n const cached = this.propertiesCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const params = new URLSearchParams({\r\n schemaId: schemaId.toString(),\r\n component,\r\n tablePath,\r\n });\r\n\r\n return this.http\r\n .get<\r\n FormulaPropertyDescriptor[] | { data: FormulaPropertyDescriptor[] }\r\n >(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? []),\r\n tap((response) => {\r\n this.propertiesCache.set(cacheKey, response);\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula properties:', error);\r\n return of([]);\r\n }),\r\n );\r\n }\r\n\r\n getNextTokens(\r\n schemaId: number,\r\n component: string,\r\n tablePath: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaBuilderNextTokensResponse | null> {\r\n if (!schemaId || !component || !tablePath) return of(null);\r\n if (mode === 'current-only') return of(null);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;\r\n const cached = this.nextTokensCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const params = new URLSearchParams({\r\n schemaId: schemaId.toString(),\r\n component,\r\n tablePath,\r\n });\r\n\r\n return this.http\r\n .get<\r\n | FormulaBuilderNextTokensResponse\r\n | { data: FormulaBuilderNextTokensResponse }\r\n >(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((payload) => {\r\n if (payload) {\r\n this.nextTokensCache.set(cacheKey, payload);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula next tokens:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, map } from 'rxjs';\r\nimport type {\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaAutocompleteService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n getSuggestions(\r\n request: AutocompleteRequest,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<AutocompleteResponse | null> {\r\n if (!request) {\r\n return of(null);\r\n }\r\n\r\n const normalized: AutocompleteRequest = {\r\n ...request,\r\n formula: request.formula ?? '',\r\n };\r\n\r\n return this.http\r\n .post<\r\n AutocompleteResponse | { data: AutocompleteResponse }\r\n >(`${this.getBaseUrl(apiMode)}/autocomplete`, normalized)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n catchError((error) => {\r\n console.warn('Autocomplete API error:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import type {\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\nexport type PathSegment = {\r\n operatorToken: string;\r\n value: string;\r\n};\r\n\r\nexport type SegmentMeta = PathSegment & {\r\n parameterKind?: string | null;\r\n requiresParameter: boolean;\r\n allowedValues: string[];\r\n optional: boolean;\r\n canRemove: boolean;\r\n};\r\n\r\nexport type ResolveSegmentsParams = {\r\n scope: string;\r\n segments: PathSegment[];\r\n operators: OperatorDescriptor[];\r\n baseRule?: NextTokenRule;\r\n rulesByPath: Record<string, Record<string, NextTokenRule>>;\r\n};\r\n\r\nexport function resolveSegmentsMeta({\r\n scope,\r\n segments,\r\n operators,\r\n baseRule,\r\n rulesByPath,\r\n}: ResolveSegmentsParams): SegmentMeta[] {\r\n if (!scope || segments.length === 0) {\r\n return [];\r\n }\r\n\r\n let pathBefore = scope;\r\n let blocked = false;\r\n\r\n return segments.map((segment, index) => {\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n const operator = operators.find((op) => op.token === segment.operatorToken);\r\n const rule = blocked\r\n ? undefined\r\n : isBase\r\n ? baseRule\r\n : rulesByPath[pathBefore]?.[segment.operatorToken];\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n const normalizedValue = segment.value;\r\n const isComplete = !requiresParameter || Boolean(normalizedValue);\r\n\r\n if (!blocked && isComplete) {\r\n pathBefore = appendToPath(\r\n pathBefore,\r\n segment.operatorToken,\r\n normalizedValue,\r\n isBase,\r\n );\r\n } else {\r\n blocked = true;\r\n }\r\n\r\n return {\r\n operatorToken: segment.operatorToken,\r\n value: normalizedValue,\r\n parameterKind,\r\n requiresParameter,\r\n allowedValues,\r\n optional: !requiresParameter,\r\n canRemove: !isBase,\r\n };\r\n });\r\n}\r\n\r\nexport function buildInitialSegments(\r\n scope: string,\r\n operator: OperatorDescriptor | undefined,\r\n rule: NextTokenRule | undefined,\r\n): PathSegment[] {\r\n if (!operator || !scope) return [];\r\n const parameterKind = operator.parameterKind ?? rule?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator.requiresParameter ?? Boolean(parameterKind);\r\n const shouldHaveSegment = Boolean(parameterKind) || requiresParameter;\r\n if (!shouldHaveSegment) return [];\r\n\r\n return [{ operatorToken: scope, value: '' }];\r\n}\r\n\r\nexport function buildTablePath(\r\n scope: string,\r\n segments: SegmentMeta[],\r\n baseOperator: OperatorDescriptor | undefined,\r\n stopOnIncomplete: boolean,\r\n): string {\r\n if (!scope) return '';\r\n\r\n if (\r\n stopOnIncomplete &&\r\n segments.length === 0 &&\r\n (baseOperator?.requiresParameter || baseOperator?.parameterKind)\r\n ) {\r\n return '';\r\n }\r\n\r\n let path = scope;\r\n for (let index = 0; index < segments.length; index += 1) {\r\n const segment = segments[index];\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n if (!isBase) {\r\n path += `.${segment.operatorToken}`;\r\n }\r\n if (segment.value) {\r\n path += `.${segment.value}`;\r\n } else if (segment.requiresParameter && stopOnIncomplete) {\r\n return '';\r\n }\r\n }\r\n\r\n return path;\r\n}\r\n\r\nexport function getAllowedValues(rule: NextTokenRule | undefined): string[] {\r\n return rule?.allowedValues ?? [];\r\n}\r\n\r\nfunction appendToPath(\r\n basePath: string,\r\n operatorToken: string,\r\n value: string,\r\n isBase: boolean,\r\n): string {\r\n if (isBase) {\r\n if (!value) return basePath;\r\n if (!basePath) return value;\r\n return `${basePath}.${value}`;\r\n }\r\n if (!basePath) {\r\n return value ? `${operatorToken}.${value}` : operatorToken;\r\n }\r\n const withOperator = `${basePath}.${operatorToken}`;\r\n return value ? `${withOperator}.${value}` : withOperator;\r\n}\r\n","import {\r\n Component,\r\n forwardRef,\r\n input,\r\n output,\r\n signal,\r\n computed,\r\n inject,\r\n effect,\r\n OnDestroy,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { TranslocoDirective } from '@jsverse/transloco';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NG_VALUE_ACCESSOR,\r\n} from '@angular/forms';\r\nimport { Card } from '@masterteam/components/card';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport { Tooltip } from '@masterteam/components/tooltip';\r\nimport { RadioCards, type RadioItem } from '@masterteam/components/radio-cards';\r\nimport { ToggleField } from '@masterteam/components/toggle-field';\r\nimport type { MTIcon } from '@masterteam/icons';\r\nimport { PopoverModule } from 'primeng/popover';\r\nimport { Skeleton } from 'primeng/skeleton';\r\nimport { Observable } from 'rxjs';\r\n\r\n// Import pure UI components from @masterteam/components/formula\r\nimport {\r\n FormulaToolbar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n FormulaStatusBar,\r\n type SmartBlock,\r\n type FormulaToken,\r\n type ToolbarTab,\r\n createPropertyBlock,\r\n serializeTokens,\r\n} from '@masterteam/components/formula';\r\n\r\n// Services are kept in formula-builder (backend logic)\r\nimport { FormulaValidatorService } from './services/formula-validator.service';\r\nimport { FormulaContextService } from './services/formula-context.service';\r\nimport { FormulaAutocompleteService } from './services/formula-autocomplete.service';\r\nimport type {\r\n ValidationResult,\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from './models/validation-result.model';\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from './models/formula-context.model';\r\nimport type { FormulaBuilderValue } from './models/formula-builder-value.model';\r\nimport {\r\n buildInitialSegments,\r\n buildTablePath,\r\n getAllowedValues,\r\n resolveSegmentsMeta,\r\n type PathSegment,\r\n type SegmentMeta,\r\n} from './utils/formula-path-builder';\r\n\r\nconst DEFAULT_SCOPE_ICON: MTIcon = 'general.placeholder';\r\nconst DEFAULT_TOOLBAR_TABS: readonly ToolbarTab[] = [\r\n 'functions',\r\n 'properties',\r\n 'operators',\r\n];\r\n\r\nexport interface FormulaBuilderUiConfig {\r\n toolbarTabs?: readonly ToolbarTab[];\r\n codeOnly?: boolean;\r\n hideToolbar?: boolean;\r\n hideStatusBar?: boolean;\r\n isProcessBuilder?: boolean;\r\n contextEntityTypeKey?: string;\r\n}\r\n\r\nconst SCOPE_ICON_MAP: Record<string, MTIcon> = {\r\n Current: 'map.marker-pin-01',\r\n Level: 'map.marker-pin-01',\r\n Parent: 'arrow.arrow-up',\r\n Children: 'user.users-01',\r\n Descendants: 'custom.hierarchy-structure',\r\n Modules: 'file.folder-closed',\r\n};\r\n\r\n@Component({\r\n selector: 'mt-formula-builder',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n TranslocoDirective,\r\n FormsModule,\r\n Card,\r\n Button,\r\n SelectField,\r\n Tooltip,\r\n RadioCards,\r\n ToggleField,\r\n PopoverModule,\r\n Skeleton,\r\n FormulaToolbar,\r\n FormulaStatusBar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n ],\r\n templateUrl: './formula-builder.html',\r\n host: {\r\n class: 'block',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => FormulaBuilder),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FormulaBuilder implements ControlValueAccessor, OnDestroy {\r\n private readonly validatorService = inject(FormulaValidatorService);\r\n private readonly contextService = inject(FormulaContextService);\r\n private readonly autocompleteService = inject(FormulaAutocompleteService);\r\n\r\n /** Reference to the formula editor */\r\n private readonly editor = viewChild<FormulaEditor>('formulaEditor');\r\n private readonly codeEditor =\r\n viewChild<FormulaEditorCode>('formulaEditorCode');\r\n\r\n // ===== INPUTS =====\r\n\r\n /** Properties per table path (e.g., \"Current\", \"Children.Project\") */\r\n readonly propertiesByPath = input<\r\n Record<string, { key: string; name?: string }[]>\r\n >({});\r\n\r\n /** Level schema ID for validation context */\r\n readonly levelSchemaId = input<number>();\r\n\r\n /** Optional current context entity key, e.g. LevelData or Risk */\r\n readonly contextEntityTypeKey = input<string>();\r\n\r\n /** Template ID for validation context */\r\n readonly templateId = input<number>();\r\n\r\n /** Placeholder text */\r\n readonly placeholder = input('');\r\n\r\n /** Hide the top toolbar */\r\n readonly hideToolbar = input(false);\r\n\r\n /** Hide the status bar */\r\n readonly hideStatusBar = input(false);\r\n\r\n /** Visible toolbar tabs */\r\n readonly toolbarTabs = input<readonly ToolbarTab[]>(DEFAULT_TOOLBAR_TABS);\r\n\r\n /** Force code editor mode and hide the mode toggle */\r\n readonly codeOnly = input(false);\r\n\r\n /** Use Process Builder current-only Formula Engine endpoints */\r\n readonly isProcessBuilder = input(false);\r\n\r\n // ===== OUTPUTS =====\r\n\r\n /** Emits validation result on change */\r\n readonly validationChange = output<ValidationResult>();\r\n\r\n /** Emits when tokens change */\r\n readonly tokensChange = output<FormulaToken[]>();\r\n\r\n // ===== STATE =====\r\n\r\n /** Editor focus state */\r\n readonly hasFocus = signal(false);\r\n\r\n /** Form control value */\r\n private readonly expressionValue = signal('');\r\n private readonly builderValue = signal<FormulaToken[]>([]);\r\n\r\n /** Tokens for the editor */\r\n readonly tokens = signal<FormulaToken[]>([]);\r\n readonly expression = computed(() => this.expressionValue());\r\n readonly resolvedContextEntityTypeKey = computed(() => {\r\n const value = this.contextEntityTypeKey();\r\n if (typeof value !== 'string') {\r\n return undefined;\r\n }\r\n\r\n const normalized = value.trim();\r\n return normalized.length > 0 ? normalized : undefined;\r\n });\r\n\r\n readonly autocompleteProvider = (\r\n request: AutocompleteRequest,\r\n ): Observable<AutocompleteResponse | null> => {\r\n return this.autocompleteService.getSuggestions(\r\n {\r\n ...request,\r\n levelSchemaId: this.levelSchemaId(),\r\n contextEntityTypeKey:\r\n this.resolvedContextEntityTypeKey() ??\r\n this.builderContext()?.contextEntityTypeKey,\r\n },\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n };\r\n\r\n /** Track last synced builder JSON to avoid loops */\r\n private lastBuilderJson = '';\r\n\r\n /** Editor mode */\r\n readonly editorMode = signal<'builder' | 'code'>('builder');\r\n readonly isCodeMode = computed(() => this.editorMode() === 'code');\r\n readonly isCodeModeLocked = signal(false);\r\n readonly showModeToggle = computed(() => !this.codeOnly());\r\n readonly formulaApiMode = computed<'default' | 'current-only'>(() =>\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n readonly resolvedToolbarTabs = computed(() => {\r\n const tabs = this.toolbarTabs();\r\n return tabs.length > 0 ? tabs : DEFAULT_TOOLBAR_TABS;\r\n });\r\n private codeModeSnapshotTokens: FormulaToken[] = [];\r\n private codeModeSnapshotExpression = '';\r\n\r\n /** ControlValueAccessor callbacks */\r\n private onChange: (value: FormulaBuilderValue) => void = () => {};\r\n private onTouched: () => void = () => {};\r\n\r\n /** Disabled state */\r\n private readonly isDisabled = signal(false);\r\n\r\n /** Validation result from service */\r\n readonly validation = this.validatorService.validation;\r\n\r\n /** Is validation in progress */\r\n readonly isValidating = this.validatorService.isValidating;\r\n\r\n /** Builder context from API */\r\n readonly builderContext = signal<FormulaBuilderContextResponse | null>(null);\r\n\r\n /** Function categories from context */\r\n readonly functionCategories = computed(\r\n () => this.builderContext()?.functions?.categories ?? [],\r\n );\r\n\r\n /** Is builder context loading */\r\n readonly isContextLoading = signal(false);\r\n\r\n private contextRequestId = 0;\r\n\r\n /** Properties loaded from API */\r\n private readonly propertiesByPathApi = signal<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >({});\r\n\r\n /** Current property list loading path */\r\n private readonly propertyLoadingPath = signal<string | null>(null);\r\n\r\n constructor() {\r\n // Validate when formula changes\r\n effect(() => {\r\n const formula = this.expressionValue();\r\n const apiMode = this.formulaApiMode();\r\n if (formula && formula.trim().length > 0) {\r\n this.validatorService.validate(\r\n formula,\r\n undefined,\r\n this.levelSchemaId(),\r\n this.templateId(),\r\n apiMode,\r\n );\r\n }\r\n });\r\n\r\n // Emit validation changes\r\n effect(() => {\r\n const validation = this.validation();\r\n this.validationChange.emit(validation);\r\n });\r\n\r\n // Load builder context when schema changes\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\r\n const apiMode = this.formulaApiMode();\r\n const contextEntityTypeKey = this.resolvedContextEntityTypeKey();\r\n\r\n if (!schemaId) {\r\n this.builderContext.set(null);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.isContextLoading.set(false);\r\n return;\r\n }\r\n\r\n const requestId = ++this.contextRequestId;\r\n this.isContextLoading.set(true);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.contextService\r\n .loadContext(schemaId, contextEntityTypeKey, apiMode)\r\n .subscribe((context) => {\r\n if (requestId !== this.contextRequestId) {\r\n return;\r\n }\r\n\r\n this.builderContext.set(context);\r\n this.isContextLoading.set(false);\r\n\r\n if (!context) {\r\n return;\r\n }\r\n\r\n if (context.currentProperties?.length) {\r\n const scalarOperators =\r\n context.schemaDescriptor?.operators?.filter(\r\n (operator) =>\r\n operator.cardinality === 'scalar' &&\r\n !operator.requiresParameter &&\r\n !operator.parameterKind,\r\n ) ?? [];\r\n const scopedProperties = scalarOperators.reduce(\r\n (acc, operator) => ({\r\n ...acc,\r\n [operator.token]: context.currentProperties,\r\n }),\r\n {} as Record<string, FormulaPropertyDescriptor[]>,\r\n );\r\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n ...scopedProperties,\r\n }));\r\n }\r\n });\r\n });\r\n\r\n // Ensure selected scope exists in available options\r\n effect(() => {\r\n const scopes = this.availableScopes();\r\n if (scopes.length === 0) return;\r\n const current = this.propertyScope();\r\n if (!scopes.some((scope) => scope.key === current)) {\r\n this.setPropertyScope(scopes[0].key);\r\n }\r\n });\r\n\r\n // Fetch properties for the selected table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\r\n const isProcessBuilder = this.isProcessBuilder();\r\n const tablePath = this.resolvedTablePath();\r\n const component = this.propertiesComponent();\r\n const context = this.builderContext();\r\n\r\n if (\r\n isProcessBuilder ||\r\n !schemaId ||\r\n !tablePath ||\r\n !component ||\r\n !context\r\n ) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n const existing = this.propertiesByPathApi()[tablePath];\r\n if (existing !== undefined) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n this.propertyLoadingPath.set(tablePath);\r\n this.contextService\r\n .getScopeProperties(schemaId, component, tablePath)\r\n .subscribe((props) => {\r\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n [tablePath]: props ?? [],\r\n }));\r\n if (this.propertyLoadingPath() === tablePath) {\r\n this.propertyLoadingPath.set(null);\r\n }\r\n });\r\n });\r\n\r\n // Fetch next-token rules for the current table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\r\n const isProcessBuilder = this.isProcessBuilder();\r\n const tablePath = this.resolvedTablePath();\r\n const component = this.propertiesComponent();\r\n\r\n if (isProcessBuilder || !schemaId || !tablePath || !component) return;\r\n\r\n if (this.nextTokenRulesByPath()[tablePath]) return;\r\n\r\n this.contextService\r\n .getNextTokens(schemaId, component, tablePath)\r\n .subscribe((response) => {\r\n if (!response) return;\r\n this.nextTokenRulesByPath.update((current) => ({\r\n ...current,\r\n [tablePath]: response.nextTokenRules ?? {},\r\n }));\r\n });\r\n });\r\n\r\n // Keep base segment in sync with scope metadata\r\n effect(() => {\r\n const scope = this.propertyScope();\r\n const operator = this.baseOperator();\r\n const shouldHaveSegment =\r\n Boolean(operator?.parameterKind) ||\r\n Boolean(operator?.requiresParameter);\r\n const segments = this.propertyPathSegments();\r\n const hasBase = segments[0]?.operatorToken === scope;\r\n\r\n if (shouldHaveSegment && !hasBase) {\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(scope, operator, this.baseRule()),\r\n );\r\n return;\r\n }\r\n\r\n if (!shouldHaveSegment && hasBase) {\r\n this.propertyPathSegments.set(segments.slice(1));\r\n }\r\n });\r\n\r\n // Normalize segment values when allowed values change\r\n effect(() => {\r\n const meta = this.pathSegments();\r\n const segments = this.propertyPathSegments();\r\n if (meta.length !== segments.length) return;\r\n\r\n let changed = false;\r\n const next = segments.map((segment, index) => {\r\n const normalized = meta[index]?.value ?? segment.value;\r\n if (segment.value !== normalized) {\r\n changed = true;\r\n return { ...segment, value: normalized };\r\n }\r\n return segment;\r\n });\r\n\r\n if (changed) {\r\n this.propertyPathSegments.set(next);\r\n }\r\n });\r\n\r\n // Ensure selected field exists in current options\r\n effect(() => {\r\n const options = this.propertyOptions();\r\n const current = this.propertyFieldKey();\r\n\r\n if (options.length === 0) {\r\n if (current) this.propertyFieldKey.set('');\r\n return;\r\n }\r\n\r\n if (current && !options.some((prop) => prop.key === current)) {\r\n this.propertyFieldKey.set('');\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.validatorService.reset();\r\n }\r\n\r\n // ===== ControlValueAccessor =====\r\n\r\n writeValue(value: FormulaBuilderValue | null): void {\r\n if (!value) {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n return;\r\n }\r\n\r\n const builder = Array.isArray(value.builder) ? value.builder : [];\r\n const expression = this.codeOnly()\r\n ? this.resolveExpressionValue(value.expression ?? '', builder)\r\n : (value.expression ?? '');\r\n this.expressionValue.set(expression);\r\n\r\n if (this.codeOnly()) {\r\n this.applyFormulaValue(builder, expression, true);\r\n return;\r\n }\r\n\r\n if (builder.length === 0) {\r\n this.applyFormulaValue(\r\n [],\r\n expression,\r\n expression.trim().length > 0,\r\n true,\r\n );\r\n return;\r\n }\r\n\r\n this.applyFormulaValue(builder, expression, false);\r\n }\r\n\r\n registerOnChange(fn: (value: FormulaBuilderValue) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.isDisabled.set(isDisabled);\r\n }\r\n\r\n /** Handle formula change from editor */\r\n onFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle formula change from code editor */\r\n onCodeFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n if (!newFormula.trim()) {\r\n this.clearBuilderTokens();\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.emitValueChange();\r\n return;\r\n }\r\n\r\n if (\r\n !this.isCodeModeLocked() &&\r\n newFormula !== this.codeModeSnapshotExpression\r\n ) {\r\n this.isCodeModeLocked.set(true);\r\n this.clearBuilderTokens();\r\n }\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle block insert from toolbar */\r\n onBlockInsert(block: SmartBlock): void {\r\n if (this.isCodeMode()) {\r\n const editor = this.codeEditor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n return;\r\n }\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n }\r\n\r\n /** Handle tokens change */\r\n onTokensChange(newTokens: FormulaToken[]): void {\r\n this.tokens.set(newTokens);\r\n const json = JSON.stringify(newTokens);\r\n this.lastBuilderJson = json;\r\n this.builderValue.set(newTokens);\r\n this.tokensChange.emit(newTokens);\r\n this.emitValueChange();\r\n }\r\n\r\n onEditorFocus(): void {\r\n this.hasFocus.set(true);\r\n }\r\n\r\n onEditorBlur(): void {\r\n this.hasFocus.set(false);\r\n this.onTouched();\r\n }\r\n\r\n private emitValueChange(): void {\r\n this.onChange({\r\n expression: this.expressionValue(),\r\n builder: this.builderValue(),\r\n });\r\n }\r\n\r\n onModeToggle(value: boolean): void {\r\n if (this.codeOnly()) {\r\n return;\r\n }\r\n const nextMode: 'builder' | 'code' = value ? 'code' : 'builder';\r\n this.setEditorMode(nextMode);\r\n }\r\n\r\n private setEditorMode(mode: 'builder' | 'code'): void {\r\n if (this.editorMode() === mode) return;\r\n\r\n if (mode === 'code') {\r\n this.enterCodeMode();\r\n return;\r\n }\r\n\r\n if (this.isCodeModeLocked()) {\r\n return;\r\n }\r\n\r\n this.exitCodeMode();\r\n }\r\n\r\n private enterCodeMode(): void {\r\n this.codeModeSnapshotTokens = this.tokens().slice();\r\n this.codeModeSnapshotExpression = this.expressionValue();\r\n const editor = this.editor();\r\n if (editor) {\r\n const formula = editor.serialize();\r\n this.codeModeSnapshotExpression = formula;\r\n this.expressionValue.set(formula);\r\n this.emitValueChange();\r\n }\r\n this.isCodeModeLocked.set(false);\r\n this.editorMode.set('code');\r\n }\r\n\r\n private exitCodeMode(): void {\r\n this.editorMode.set('builder');\r\n if (!this.expressionValue().trim()) {\r\n this.clearBuilderTokens();\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue([]);\r\n }\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.isCodeModeLocked.set(false);\r\n return;\r\n }\r\n\r\n if (this.codeModeSnapshotTokens.length > 0) {\r\n const restored = this.codeModeSnapshotTokens.slice();\r\n this.tokens.set(restored);\r\n this.builderValue.set(restored);\r\n this.lastBuilderJson = JSON.stringify(restored);\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(restored);\r\n }\r\n }\r\n if (this.codeModeSnapshotExpression) {\r\n this.expressionValue.set(this.codeModeSnapshotExpression);\r\n }\r\n this.isCodeModeLocked.set(false);\r\n }\r\n\r\n private clearBuilderTokens(): void {\r\n if (this.tokens().length === 0 && this.builderValue().length === 0) {\r\n return;\r\n }\r\n this.tokens.set([]);\r\n this.builderValue.set([]);\r\n this.lastBuilderJson = '';\r\n this.tokensChange.emit([]);\r\n }\r\n\r\n // ===== PUBLIC METHODS =====\r\n\r\n /** Clear the formula */\r\n clear(): void {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n this.emitValueChange();\r\n }\r\n\r\n private resolveExpressionValue(\r\n expression: string,\r\n builder: FormulaToken[],\r\n ): string {\r\n if (expression.trim().length > 0) {\r\n return expression;\r\n }\r\n return builder.length > 0 ? serializeTokens(builder) : '';\r\n }\r\n\r\n private applyFormulaValue(\r\n builder: FormulaToken[],\r\n expression: string,\r\n useCodeMode: boolean,\r\n lockCodeMode: boolean = false,\r\n ): void {\r\n const serialized = JSON.stringify(builder);\r\n this.builderValue.set(builder);\r\n this.tokens.set(builder);\r\n this.lastBuilderJson = builder.length > 0 ? serialized : '';\r\n\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(builder);\r\n }\r\n\r\n const codeEditor = this.codeEditor();\r\n if (codeEditor) {\r\n codeEditor.writeValue(expression);\r\n }\r\n\r\n if (useCodeMode) {\r\n this.editorMode.set('code');\r\n this.isCodeModeLocked.set(lockCodeMode);\r\n this.codeModeSnapshotTokens = builder.slice();\r\n this.codeModeSnapshotExpression = expression;\r\n return;\r\n }\r\n\r\n this.editorMode.set('builder');\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n }\r\n\r\n // ===== PROPERTY COMPOSER =====\r\n\r\n readonly propertyScope = signal<string>('');\r\n\r\n readonly propertyPathSegments = signal<PathSegment[]>([]);\r\n\r\n readonly propertyFieldKey = signal('');\r\n\r\n private readonly nextTokenRulesByPath = signal<\r\n Record<string, Record<string, NextTokenRule>>\r\n >({});\r\n\r\n readonly contextOperators = computed<OperatorDescriptor[]>(() => {\r\n return this.builderContext()?.schemaDescriptor?.operators ?? [];\r\n });\r\n\r\n readonly baseOperator = computed(() =>\r\n this.contextOperators().find((op) => op.token === this.propertyScope()),\r\n );\r\n\r\n readonly baseRule = computed(() => {\r\n const scope = this.propertyScope();\r\n return this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope];\r\n });\r\n\r\n readonly availableScopes = computed(() => {\r\n const operators = this.contextOperators();\r\n if (operators.length === 0) return [];\r\n return operators.map((operator) => ({\r\n key: operator.token,\r\n label: `@${operator.token}`,\r\n requiresParam: operator.requiresParameter ?? false,\r\n optional: !operator.requiresParameter,\r\n }));\r\n });\r\n\r\n /** Radio card options for scope selection */\r\n readonly scopeOptions = computed<RadioItem[]>(() =>\r\n this.availableScopes().map((scope) => ({\r\n id: scope.key,\r\n name: scope.key,\r\n icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,\r\n })),\r\n );\r\n\r\n /** Handle scope selection from radio cards */\r\n onScopeChange(item: RadioItem): void {\r\n this.setPropertyScope(String(item.id));\r\n }\r\n\r\n readonly pathSegments = computed<SegmentMeta[]>(() => {\r\n const scope = this.propertyScope();\r\n return resolveSegmentsMeta({\r\n scope,\r\n segments: this.propertyPathSegments(),\r\n operators: this.contextOperators(),\r\n baseRule: this.baseRule(),\r\n rulesByPath: this.nextTokenRulesByPath(),\r\n });\r\n });\r\n\r\n readonly isDirectAccess = computed(() => {\r\n const operator = this.baseOperator();\r\n const needsParameter =\r\n Boolean(operator?.parameterKind) || Boolean(operator?.requiresParameter);\r\n return !needsParameter && this.pathSegments().length === 0;\r\n });\r\n\r\n readonly propertyTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n false,\r\n ),\r\n );\r\n\r\n readonly resolvedTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n true,\r\n ),\r\n );\r\n\r\n readonly currentNextTokenRules = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return {};\r\n return this.nextTokenRulesByPath()[path] ?? {};\r\n });\r\n\r\n readonly nextOperatorOptions = computed(() => {\r\n const rules = this.currentNextTokenRules();\r\n const operators = this.contextOperators();\r\n return Object.keys(rules)\r\n .map((token) => {\r\n const rule = rules[token];\r\n const operator = operators.find((item) => item.token === token);\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n return {\r\n token,\r\n rule,\r\n requiresParameter,\r\n allowedValues,\r\n };\r\n })\r\n .filter(\r\n (option) =>\r\n option.allowedValues.length > 0 || !option.requiresParameter,\r\n );\r\n });\r\n\r\n readonly canAddNextSegment = computed(() => {\r\n if (this.nextOperatorOptions().length === 0) return false;\r\n const segments = this.pathSegments();\r\n if (segments.length === 0 || !segments[0].value) {\r\n return false;\r\n }\r\n return segments.every(\r\n (segment) => !segment.requiresParameter || Boolean(segment.value),\r\n );\r\n });\r\n\r\n readonly propertiesComponent = computed(() => {\r\n if (this.isProcessBuilder()) {\r\n return undefined;\r\n }\r\n const contextKey = this.builderContext()?.contextEntityTypeKey;\r\n return contextKey;\r\n });\r\n\r\n readonly mergedPropertiesByPath = computed<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >(() => {\r\n const merged: Record<string, FormulaPropertyDescriptor[]> = {\r\n ...this.propertiesByPath(),\r\n };\r\n const apiProps = this.propertiesByPathApi();\r\n Object.entries(apiProps).forEach(([path, props]) => {\r\n if (props && props.length > 0) {\r\n merged[path] = props;\r\n }\r\n });\r\n return merged;\r\n });\r\n\r\n readonly isPropertyLoading = computed(() => {\r\n const path = this.resolvedTablePath();\r\n return Boolean(path) && this.propertyLoadingPath() === path;\r\n });\r\n\r\n readonly propertyOptions = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return [];\r\n const byPath = this.mergedPropertiesByPath()[path];\r\n const list = byPath && byPath.length > 0 ? byPath : [];\r\n return list.map((prop) => ({\r\n key: prop.key,\r\n name: prop.name ?? prop.key,\r\n }));\r\n });\r\n\r\n readonly selectedProperty = computed(() => {\r\n const key = this.propertyFieldKey();\r\n return this.propertyOptions().find((prop) => prop.key === key) ?? null;\r\n });\r\n\r\n readonly canInsertProperty = computed(() => {\r\n if (!this.selectedProperty()) return false;\r\n return Boolean(this.resolvedTablePath());\r\n });\r\n\r\n setPropertyScope(scope: string): void {\r\n if (this.propertyScope() === scope) {\r\n return;\r\n }\r\n this.propertyScope.set(scope);\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(\r\n scope,\r\n this.contextOperators().find((op) => op.token === scope),\r\n this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope],\r\n ),\r\n );\r\n this.propertyFieldKey.set('');\r\n }\r\n\r\n setPathSegmentValue(index: number, value: string | null): void {\r\n this.propertyPathSegments.update((segments) => {\r\n // Update the segment at the given index and remove all segments after it\r\n // because subsequent segments depend on previous values\r\n const updated = segments.slice(0, index + 1);\r\n updated[index] = { ...updated[index], value: value ?? '' };\r\n return updated;\r\n });\r\n }\r\n\r\n addNextSegment(operatorToken: string): void {\r\n const value = '';\r\n\r\n this.propertyPathSegments.update((segments) => [\r\n ...segments,\r\n { operatorToken, value },\r\n ]);\r\n }\r\n\r\n onAddSegmentSelection(\r\n operatorToken: string,\r\n popover: { hide: () => void },\r\n ): void {\r\n popover.hide();\r\n this.addNextSegment(operatorToken);\r\n }\r\n\r\n removePathSegment(index: number): void {\r\n this.propertyPathSegments.update((segments) =>\r\n segments.filter((_, i) => i !== index),\r\n );\r\n }\r\n\r\n segmentOptions(index: number): { key: string; name: string }[] {\r\n const segment = this.pathSegments()[index];\r\n if (!segment) return [];\r\n return segment.allowedValues.map((value) => ({\r\n key: value,\r\n name: value,\r\n }));\r\n }\r\n\r\n insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void {\r\n const prop = this.selectedProperty();\r\n if (!prop) return;\r\n\r\n if (!this.canInsertProperty()) return;\r\n\r\n const tablePath = this.resolvedTablePath();\r\n if (!tablePath) return;\r\n const display = prop.name ?? prop.key;\r\n const block = createPropertyBlock(\r\n `@${tablePath}::${prop.key}`,\r\n 'current',\r\n display,\r\n );\r\n insertBlock(block);\r\n }\r\n}\r\n","<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n ✓ {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >›</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n","/**\r\n * Services barrel export\r\n */\r\n\r\nexport * from './formula-context.service';\r\nexport * from './formula-validator.service';\r\n","/**\r\n * Public API Surface of @masterteam/formula-builder\r\n *\r\n * This package provides the FormulaBuilder component which wraps\r\n * pure UI components from @masterteam/components/formula with\r\n * backend services for validation and context loading.\r\n *\r\n * Architecture:\r\n * - UI Components: imported from @masterteam/components/formula (pure, no services)\r\n * - Services: FormulaContextService, FormulaValidatorService (backend logic)\r\n * - FormulaBuilder: Main wrapper that connects UI with services\r\n */\r\n\r\n// Main component\r\nexport * from './lib/formula-builder';\r\n\r\n// Services (backend logic only)\r\nexport * from './lib/services/index';\r\n\r\n// Re-export models from base package for convenience\r\nexport {\r\n type SmartBlock,\r\n type BlockType,\r\n type ArgumentSlot,\r\n type FormulaToken,\r\n type TokenType,\r\n type DragBehavior,\r\n type ValidationResult,\r\n type ValidationError,\r\n type FunctionDefinition,\r\n type FunctionCategoryGroup,\r\n type OperatorDefinition,\r\n createFunctionBlock,\r\n createPropertyBlock,\r\n createOperatorBlock,\r\n createLiteralBlock,\r\n} from '@masterteam/components/formula';\r\n\r\n// Export validation-specific models\r\nexport type {\r\n ValidationRequest,\r\n FunctionCatalogResponse,\r\n ApiErrorResponse,\r\n} from './lib/models/validation-result.model';\r\n\r\n// Export value model for ControlValueAccessor usage\r\nexport type { FormulaBuilderValue } from './lib/models/formula-builder-value.model';\r\n\r\n// Export builder context models\r\nexport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n FormulaEngineSchemaDescriptor,\r\n OperatorDescriptor,\r\n NextTokenRule,\r\n} from './lib/models/formula-context.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"masterteam-formula-builder.mjs","sources":["../../../../packages/masterteam/formula-builder/src/lib/services/formula-validator.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-context.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-autocomplete.service.ts","../../../../packages/masterteam/formula-builder/src/lib/utils/formula-path-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.html","../../../../packages/masterteam/formula-builder/src/lib/services/index.ts","../../../../packages/masterteam/formula-builder/src/public-api.ts","../../../../packages/masterteam/formula-builder/src/masterteam-formula-builder.ts"],"sourcesContent":["/**\r\n * Formula Validator Service\r\n * Handles real-time validation via API\r\n */\r\n\r\nimport { Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\r\nimport {\r\n Observable,\r\n Subject,\r\n of,\r\n catchError,\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n tap,\r\n} from 'rxjs';\r\nimport {\r\n ValidationResult,\r\n ValidationRequest,\r\n ApiErrorResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\ntype ValidationJob = ValidationRequest & { apiMode: FormulaApiMode };\r\n\r\n/** Default validation result for empty formulas */\r\nconst EMPTY_VALIDATION: ValidationResult = {\r\n isValid: true,\r\n errors: [],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n/** Error validation result */\r\nconst ERROR_VALIDATION: ValidationResult = {\r\n isValid: false,\r\n errors: [\r\n { message: 'Validation failed', line: 1, column: 1, severity: 'Error' },\r\n ],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaValidatorService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n /** Debounce time in ms */\r\n private readonly DEBOUNCE_MS = 300;\r\n\r\n /** Current validation result */\r\n private readonly _validation = signal<ValidationResult>(EMPTY_VALIDATION);\r\n\r\n /** Loading state */\r\n private readonly _isValidating = signal(false);\r\n\r\n /** Validation subject for debouncing */\r\n private readonly validateSubject = new Subject<ValidationJob>();\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n /** Public signals */\r\n readonly validation = this._validation.asReadonly();\r\n readonly isValidating = this._isValidating.asReadonly();\r\n\r\n constructor() {\r\n this.setupValidationStream();\r\n }\r\n\r\n /** Setup debounced validation stream */\r\n private setupValidationStream(): void {\r\n this.validateSubject\r\n .pipe(\r\n debounceTime(this.DEBOUNCE_MS),\r\n distinctUntilChanged(\n (a, b) =>\n a.formula === b.formula &&\n a.levelSchemaId === b.levelSchemaId &&\n a.moduleId === b.moduleId &&\n a.templateId === b.templateId &&\n a.apiMode === b.apiMode &&\n JSON.stringify(a.knownProperties) ===\n JSON.stringify(b.knownProperties),\n ),\n tap(() => this._isValidating.set(true)),\r\n switchMap((request) => this.callValidateApi(request)),\r\n )\r\n .subscribe((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n });\r\n }\r\n\r\n /** Validate formula (debounced) */\r\n validate(\n formula: string,\n knownProperties?: string[],\n levelSchemaId?: number,\n moduleId?: number,\n templateId?: number,\n apiMode: FormulaApiMode = 'default',\n ): void {\n // Handle empty formula\r\n if (!formula || formula.trim() === '') {\r\n this._validation.set(EMPTY_VALIDATION);\r\n return;\r\n }\r\n\r\n // Push to debounced stream\r\n this.validateSubject.next({\n formula,\n knownProperties,\n levelSchemaId,\n moduleId,\n templateId,\n apiMode,\n });\n }\n\r\n /** Validate formula immediately (no debounce) */\r\n validateImmediate(\n formula: string,\n knownProperties?: string[],\n levelSchemaId?: number,\n moduleId?: number,\n templateId?: number,\n apiMode: FormulaApiMode = 'default',\n ): Observable<ValidationResult> {\n if (!formula || formula.trim() === '') {\r\n return of(EMPTY_VALIDATION);\r\n }\r\n\r\n this._isValidating.set(true);\r\n\r\n return this.callValidateApi({\n formula,\n knownProperties,\n levelSchemaId,\n moduleId,\n templateId,\n apiMode,\n }).pipe(\n tap((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n }),\r\n );\r\n }\r\n\r\n /** Call validation API */\r\n private callValidateApi(\r\n request: ValidationJob,\r\n ): Observable<ValidationResult> {\r\n const { apiMode, ...payload } = request;\r\n return this.http\r\n .post<\r\n ValidationResult | { data: ValidationResult }\r\n >(`${this.getBaseUrl(apiMode)}/validate`, payload)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? ERROR_VALIDATION),\r\n catchError((error: HttpErrorResponse) => {\r\n console.error('Validation API error:', error);\r\n\r\n // Try to extract error message\r\n const apiError = error.error as ApiErrorResponse;\r\n const message =\r\n apiError?.message ?? apiError?.error ?? 'Validation failed';\r\n\r\n return of({\r\n ...ERROR_VALIDATION,\r\n errors: [\r\n { message, line: 1, column: 1, severity: 'Error' as const },\r\n ],\r\n });\r\n }),\r\n );\r\n }\r\n\r\n /** Reset validation state */\r\n reset(): void {\r\n this._validation.set(EMPTY_VALIDATION);\r\n this._isValidating.set(false);\r\n }\r\n\r\n /** Get current validation result */\r\n getCurrentValidation(): ValidationResult {\r\n return this._validation();\r\n }\r\n\r\n /** Check if formula is valid */\r\n isValid(): boolean {\r\n return this._validation().isValid;\r\n }\r\n\r\n /** Get validation errors */\r\n getErrors() {\r\n return this._validation().errors;\r\n }\r\n\r\n /** Get validation warnings */\r\n getWarnings() {\r\n return this._validation().warnings;\r\n }\r\n\r\n /** Get formula dependencies */\r\n getDependencies() {\r\n return this._validation().dependencies;\r\n }\r\n\r\n /** Get formula complexity */\r\n getComplexity() {\r\n return this._validation().complexity;\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, tap, map } from 'rxjs';\r\n\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaBuilderNextTokensResponse,\r\n FormulaPropertyDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaContextService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n private readonly contextCache = new Map<\r\n string,\r\n FormulaBuilderContextResponse\r\n >();\r\n private readonly propertiesCache = new Map<\r\n string,\r\n FormulaPropertyDescriptor[]\r\n >();\r\n private readonly nextTokensCache = new Map<\r\n string,\r\n FormulaBuilderNextTokensResponse\r\n >();\r\n\r\n loadContext(\n schemaId: number,\n moduleId?: number,\n contextEntityTypeKey?: string,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaBuilderContextResponse | null> {\n if (!schemaId) return of(null);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${contextEntityTypeKey ?? ''}`;\n const cached = this.contextCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\n const params = new URLSearchParams();\n if (mode === 'default' && contextEntityTypeKey) {\n params.set('contextEntityTypeKey', contextEntityTypeKey);\n }\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n const queryString = params.toString();\n const query = queryString ? `?${queryString}` : '';\n\n return this.http\n .get<\n FormulaBuilderContextResponse | { data: FormulaBuilderContextResponse }\n >(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((context) => {\r\n if (context) {\r\n this.contextCache.set(cacheKey, context);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula builder context:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n\r\n getScopeProperties(\n schemaId: number,\n component: string,\n tablePath: string,\n moduleId?: number,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaPropertyDescriptor[]> {\n if (!schemaId || !component || !tablePath) return of([]);\n if (mode === 'current-only') return of([]);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;\n const cached = this.propertiesCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\r\n const params = new URLSearchParams({\n schemaId: schemaId.toString(),\n component,\n tablePath,\n });\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n\n return this.http\n .get<\n FormulaPropertyDescriptor[] | { data: FormulaPropertyDescriptor[] }\n >(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? []),\r\n tap((response) => {\r\n this.propertiesCache.set(cacheKey, response);\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula properties:', error);\r\n return of([]);\r\n }),\r\n );\r\n }\r\n\r\n getNextTokens(\n schemaId: number,\n component: string,\n tablePath: string,\n moduleId?: number,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaBuilderNextTokensResponse | null> {\n if (!schemaId || !component || !tablePath) return of(null);\n if (mode === 'current-only') return of(null);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;\n const cached = this.nextTokensCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\r\n const params = new URLSearchParams({\n schemaId: schemaId.toString(),\n component,\n tablePath,\n });\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n\n return this.http\n .get<\n | FormulaBuilderNextTokensResponse\n | { data: FormulaBuilderNextTokensResponse }\n >(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((payload) => {\r\n if (payload) {\r\n this.nextTokensCache.set(cacheKey, payload);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula next tokens:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, map } from 'rxjs';\r\nimport type {\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaAutocompleteService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n getSuggestions(\r\n request: AutocompleteRequest,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<AutocompleteResponse | null> {\r\n if (!request) {\r\n return of(null);\r\n }\r\n\r\n const normalized: AutocompleteRequest = {\r\n ...request,\r\n formula: request.formula ?? '',\r\n };\r\n\r\n return this.http\r\n .post<\r\n AutocompleteResponse | { data: AutocompleteResponse }\r\n >(`${this.getBaseUrl(apiMode)}/autocomplete`, normalized)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n catchError((error) => {\r\n console.warn('Autocomplete API error:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import type {\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\nexport type PathSegment = {\r\n operatorToken: string;\r\n value: string;\r\n};\r\n\r\nexport type SegmentMeta = PathSegment & {\r\n parameterKind?: string | null;\r\n requiresParameter: boolean;\r\n allowedValues: string[];\r\n optional: boolean;\r\n canRemove: boolean;\r\n};\r\n\r\nexport type ResolveSegmentsParams = {\r\n scope: string;\r\n segments: PathSegment[];\r\n operators: OperatorDescriptor[];\r\n baseRule?: NextTokenRule;\r\n rulesByPath: Record<string, Record<string, NextTokenRule>>;\r\n};\r\n\r\nexport function resolveSegmentsMeta({\r\n scope,\r\n segments,\r\n operators,\r\n baseRule,\r\n rulesByPath,\r\n}: ResolveSegmentsParams): SegmentMeta[] {\r\n if (!scope || segments.length === 0) {\r\n return [];\r\n }\r\n\r\n let pathBefore = scope;\r\n let blocked = false;\r\n\r\n return segments.map((segment, index) => {\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n const operator = operators.find((op) => op.token === segment.operatorToken);\r\n const rule = blocked\r\n ? undefined\r\n : isBase\r\n ? baseRule\r\n : rulesByPath[pathBefore]?.[segment.operatorToken];\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n const normalizedValue = segment.value;\r\n const isComplete = !requiresParameter || Boolean(normalizedValue);\r\n\r\n if (!blocked && isComplete) {\r\n pathBefore = appendToPath(\r\n pathBefore,\r\n segment.operatorToken,\r\n normalizedValue,\r\n isBase,\r\n );\r\n } else {\r\n blocked = true;\r\n }\r\n\r\n return {\r\n operatorToken: segment.operatorToken,\r\n value: normalizedValue,\r\n parameterKind,\r\n requiresParameter,\r\n allowedValues,\r\n optional: !requiresParameter,\r\n canRemove: !isBase,\r\n };\r\n });\r\n}\r\n\r\nexport function buildInitialSegments(\r\n scope: string,\r\n operator: OperatorDescriptor | undefined,\r\n rule: NextTokenRule | undefined,\r\n): PathSegment[] {\r\n if (!operator || !scope) return [];\r\n const parameterKind = operator.parameterKind ?? rule?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator.requiresParameter ?? Boolean(parameterKind);\r\n const shouldHaveSegment = Boolean(parameterKind) || requiresParameter;\r\n if (!shouldHaveSegment) return [];\r\n\r\n return [{ operatorToken: scope, value: '' }];\r\n}\r\n\r\nexport function buildTablePath(\r\n scope: string,\r\n segments: SegmentMeta[],\r\n baseOperator: OperatorDescriptor | undefined,\r\n stopOnIncomplete: boolean,\r\n): string {\r\n if (!scope) return '';\r\n\r\n if (\r\n stopOnIncomplete &&\r\n segments.length === 0 &&\r\n (baseOperator?.requiresParameter || baseOperator?.parameterKind)\r\n ) {\r\n return '';\r\n }\r\n\r\n let path = scope;\r\n for (let index = 0; index < segments.length; index += 1) {\r\n const segment = segments[index];\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n if (!isBase) {\r\n path += `.${segment.operatorToken}`;\r\n }\r\n if (segment.value) {\r\n path += `.${segment.value}`;\r\n } else if (segment.requiresParameter && stopOnIncomplete) {\r\n return '';\r\n }\r\n }\r\n\r\n return path;\r\n}\r\n\r\nexport function getAllowedValues(rule: NextTokenRule | undefined): string[] {\r\n return rule?.allowedValues ?? [];\r\n}\r\n\r\nfunction appendToPath(\r\n basePath: string,\r\n operatorToken: string,\r\n value: string,\r\n isBase: boolean,\r\n): string {\r\n if (isBase) {\r\n if (!value) return basePath;\r\n if (!basePath) return value;\r\n return `${basePath}.${value}`;\r\n }\r\n if (!basePath) {\r\n return value ? `${operatorToken}.${value}` : operatorToken;\r\n }\r\n const withOperator = `${basePath}.${operatorToken}`;\r\n return value ? `${withOperator}.${value}` : withOperator;\r\n}\r\n","import {\r\n Component,\r\n forwardRef,\r\n input,\r\n output,\r\n signal,\r\n computed,\r\n inject,\r\n effect,\r\n OnDestroy,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { TranslocoDirective } from '@jsverse/transloco';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NG_VALUE_ACCESSOR,\r\n} from '@angular/forms';\r\nimport { Card } from '@masterteam/components/card';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport { Tooltip } from '@masterteam/components/tooltip';\r\nimport { RadioCards, type RadioItem } from '@masterteam/components/radio-cards';\r\nimport { ToggleField } from '@masterteam/components/toggle-field';\r\nimport type { MTIcon } from '@masterteam/icons';\r\nimport { PopoverModule } from 'primeng/popover';\r\nimport { Skeleton } from 'primeng/skeleton';\r\nimport { Observable } from 'rxjs';\r\n\r\n// Import pure UI components from @masterteam/components/formula\r\nimport {\r\n FormulaToolbar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n FormulaStatusBar,\r\n type SmartBlock,\r\n type FormulaToken,\r\n type ToolbarTab,\r\n createPropertyBlock,\r\n serializeTokens,\r\n} from '@masterteam/components/formula';\r\n\r\n// Services are kept in formula-builder (backend logic)\r\nimport { FormulaValidatorService } from './services/formula-validator.service';\r\nimport { FormulaContextService } from './services/formula-context.service';\r\nimport { FormulaAutocompleteService } from './services/formula-autocomplete.service';\r\nimport type {\r\n ValidationResult,\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from './models/validation-result.model';\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from './models/formula-context.model';\r\nimport type { FormulaBuilderValue } from './models/formula-builder-value.model';\r\nimport {\r\n buildInitialSegments,\r\n buildTablePath,\r\n getAllowedValues,\r\n resolveSegmentsMeta,\r\n type PathSegment,\r\n type SegmentMeta,\r\n} from './utils/formula-path-builder';\r\n\r\nconst DEFAULT_SCOPE_ICON: MTIcon = 'general.placeholder';\nconst DEFAULT_TOOLBAR_TABS: readonly ToolbarTab[] = [\n 'functions',\n 'properties',\n 'operators',\n];\nconst PROPERTY_SCOPE_ORDER = [\n 'Current',\n 'Host',\n 'Parent',\n // 'Children',\n // 'Descendants',\n // 'Modules',\n] as const;\n\r\nexport interface FormulaBuilderUiConfig {\r\n toolbarTabs?: readonly ToolbarTab[];\r\n codeOnly?: boolean;\r\n hideToolbar?: boolean;\r\n hideStatusBar?: boolean;\r\n isProcessBuilder?: boolean;\r\n contextEntityTypeKey?: string;\r\n}\r\n\r\nconst SCOPE_ICON_MAP: Record<string, MTIcon> = {\n Current: 'map.marker-pin-01',\n Host: 'map.marker-pin-01',\n Level: 'map.marker-pin-01',\n Parent: 'arrow.arrow-up',\n Children: 'user.users-01',\n Descendants: 'custom.hierarchy-structure',\n Modules: 'file.folder-closed',\n};\r\n\r\n@Component({\r\n selector: 'mt-formula-builder',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n TranslocoDirective,\r\n FormsModule,\r\n Card,\r\n Button,\r\n SelectField,\r\n Tooltip,\r\n RadioCards,\r\n ToggleField,\r\n PopoverModule,\r\n Skeleton,\r\n FormulaToolbar,\r\n FormulaStatusBar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n ],\r\n templateUrl: './formula-builder.html',\r\n host: {\r\n class: 'block',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => FormulaBuilder),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FormulaBuilder implements ControlValueAccessor, OnDestroy {\r\n private readonly validatorService = inject(FormulaValidatorService);\r\n private readonly contextService = inject(FormulaContextService);\r\n private readonly autocompleteService = inject(FormulaAutocompleteService);\r\n\r\n /** Reference to the formula editor */\r\n private readonly editor = viewChild<FormulaEditor>('formulaEditor');\r\n private readonly codeEditor =\r\n viewChild<FormulaEditorCode>('formulaEditorCode');\r\n\r\n // ===== INPUTS =====\r\n\r\n /** Properties per table path (e.g., \"Current\", \"Children.Project\") */\r\n readonly propertiesByPath = input<\r\n Record<string, { key: string; name?: string }[]>\r\n >({});\r\n\r\n /** Level schema ID for validation context */\n readonly levelSchemaId = input<number>();\n\n /** Optional module ID when the formula is scoped inside a level-linked module */\n readonly moduleId = input<number>();\n\n /** Optional current context entity key, e.g. LevelData or Risk */\n readonly contextEntityTypeKey = input<string>();\n\r\n /** Template ID for validation context */\r\n readonly templateId = input<number>();\r\n\r\n /** Placeholder text */\r\n readonly placeholder = input('');\r\n\r\n /** Hide the top toolbar */\r\n readonly hideToolbar = input(false);\r\n\r\n /** Hide the status bar */\r\n readonly hideStatusBar = input(false);\r\n\r\n /** Visible toolbar tabs */\r\n readonly toolbarTabs = input<readonly ToolbarTab[]>(DEFAULT_TOOLBAR_TABS);\r\n\r\n /** Force code editor mode and hide the mode toggle */\r\n readonly codeOnly = input(false);\r\n\r\n /** Use Process Builder current-only Formula Engine endpoints */\r\n readonly isProcessBuilder = input(false);\r\n\r\n // ===== OUTPUTS =====\r\n\r\n /** Emits validation result on change */\r\n readonly validationChange = output<ValidationResult>();\r\n\r\n /** Emits when tokens change */\r\n readonly tokensChange = output<FormulaToken[]>();\r\n\r\n // ===== STATE =====\r\n\r\n /** Editor focus state */\r\n readonly hasFocus = signal(false);\r\n\r\n /** Form control value */\r\n private readonly expressionValue = signal('');\r\n private readonly builderValue = signal<FormulaToken[]>([]);\r\n\r\n /** Tokens for the editor */\r\n readonly tokens = signal<FormulaToken[]>([]);\r\n readonly expression = computed(() => this.expressionValue());\r\n readonly resolvedContextEntityTypeKey = computed(() => {\n const value = this.contextEntityTypeKey();\n if (typeof value !== 'string') {\r\n return undefined;\r\n }\r\n\r\n const normalized = value.trim();\r\n return normalized.length > 0 ? normalized : undefined;\n });\n readonly isModuleContext = computed(() => {\n const contextType =\n this.resolvedContextEntityTypeKey() ??\n this.builderContext()?.contextEntityTypeKey;\n\n if (typeof contextType !== 'string') {\n return false;\n }\n\n const normalized = contextType.trim().toLowerCase();\n return normalized.length > 0 && normalized !== 'leveldata';\n });\n\r\n readonly autocompleteProvider = (\r\n request: AutocompleteRequest,\r\n ): Observable<AutocompleteResponse | null> => {\r\n return this.autocompleteService.getSuggestions(\n {\n ...request,\n levelSchemaId: this.levelSchemaId(),\n moduleId: this.moduleId(),\n contextEntityTypeKey:\n this.resolvedContextEntityTypeKey() ??\n this.builderContext()?.contextEntityTypeKey,\n },\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n };\r\n\r\n /** Track last synced builder JSON to avoid loops */\r\n private lastBuilderJson = '';\r\n\r\n /** Editor mode */\r\n readonly editorMode = signal<'builder' | 'code'>('builder');\r\n readonly isCodeMode = computed(() => this.editorMode() === 'code');\r\n readonly isCodeModeLocked = signal(false);\r\n readonly showModeToggle = computed(() => !this.codeOnly());\r\n readonly formulaApiMode = computed<'default' | 'current-only'>(() =>\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n readonly resolvedToolbarTabs = computed(() => {\r\n const tabs = this.toolbarTabs();\r\n return tabs.length > 0 ? tabs : DEFAULT_TOOLBAR_TABS;\r\n });\r\n private codeModeSnapshotTokens: FormulaToken[] = [];\r\n private codeModeSnapshotExpression = '';\r\n\r\n /** ControlValueAccessor callbacks */\r\n private onChange: (value: FormulaBuilderValue) => void = () => {};\r\n private onTouched: () => void = () => {};\r\n\r\n /** Disabled state */\r\n private readonly isDisabled = signal(false);\r\n\r\n /** Validation result from service */\r\n readonly validation = this.validatorService.validation;\r\n\r\n /** Is validation in progress */\r\n readonly isValidating = this.validatorService.isValidating;\r\n\r\n /** Builder context from API */\r\n readonly builderContext = signal<FormulaBuilderContextResponse | null>(null);\r\n\r\n /** Function categories from context */\r\n readonly functionCategories = computed(\r\n () => this.builderContext()?.functions?.categories ?? [],\r\n );\r\n\r\n /** Is builder context loading */\r\n readonly isContextLoading = signal(false);\r\n\r\n private contextRequestId = 0;\r\n\r\n /** Properties loaded from API */\r\n private readonly propertiesByPathApi = signal<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >({});\r\n\r\n /** Current property list loading path */\r\n private readonly propertyLoadingPath = signal<string | null>(null);\r\n\r\n constructor() {\r\n // Validate when formula changes\r\n effect(() => {\r\n const formula = this.expressionValue();\n const moduleId = this.moduleId();\n const apiMode = this.formulaApiMode();\n if (formula && formula.trim().length > 0) {\n this.validatorService.validate(\n formula,\n undefined,\n this.levelSchemaId(),\n moduleId,\n this.templateId(),\n apiMode,\n );\n }\n });\r\n\r\n // Emit validation changes\r\n effect(() => {\r\n const validation = this.validation();\r\n this.validationChange.emit(validation);\r\n });\r\n\r\n // Load builder context when schema changes\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const apiMode = this.formulaApiMode();\n const contextEntityTypeKey = this.resolvedContextEntityTypeKey();\n\r\n if (!schemaId) {\r\n this.builderContext.set(null);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.isContextLoading.set(false);\r\n return;\r\n }\r\n\r\n const requestId = ++this.contextRequestId;\r\n this.isContextLoading.set(true);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.contextService\n .loadContext(schemaId, moduleId, contextEntityTypeKey, apiMode)\n .subscribe((context) => {\n if (requestId !== this.contextRequestId) {\r\n return;\r\n }\r\n\r\n this.builderContext.set(context);\r\n this.isContextLoading.set(false);\r\n\r\n if (!context) {\r\n return;\r\n }\r\n\r\n if (context.currentProperties?.length) {\r\n const scalarOperators =\r\n context.schemaDescriptor?.operators?.filter(\r\n (operator) =>\r\n operator.cardinality === 'scalar' &&\r\n !operator.requiresParameter &&\r\n !operator.parameterKind,\r\n ) ?? [];\r\n const scopedProperties = scalarOperators.reduce(\r\n (acc, operator) => ({\r\n ...acc,\r\n [operator.token]: context.currentProperties,\r\n }),\r\n {} as Record<string, FormulaPropertyDescriptor[]>,\r\n );\r\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n ...scopedProperties,\r\n }));\r\n }\r\n });\r\n });\r\n\r\n // Ensure selected scope exists in available options\r\n effect(() => {\r\n const scopes = this.availableScopes();\r\n if (scopes.length === 0) return;\r\n const current = this.propertyScope();\r\n if (!scopes.some((scope) => scope.key === current)) {\r\n this.setPropertyScope(scopes[0].key);\r\n }\r\n });\r\n\r\n // Fetch properties for the selected table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n const context = this.builderContext();\r\n\r\n if (\r\n isProcessBuilder ||\r\n !schemaId ||\r\n !tablePath ||\r\n !component ||\r\n !context\r\n ) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n const existing = this.propertiesByPathApi()[tablePath];\r\n if (existing !== undefined) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n this.propertyLoadingPath.set(tablePath);\n this.contextService\n .getScopeProperties(schemaId, component, tablePath, moduleId)\n .subscribe((props) => {\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n [tablePath]: props ?? [],\r\n }));\r\n if (this.propertyLoadingPath() === tablePath) {\r\n this.propertyLoadingPath.set(null);\r\n }\r\n });\r\n });\r\n\r\n // Fetch next-token rules for the current table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n\r\n if (isProcessBuilder || !schemaId || !tablePath || !component) return;\r\n\r\n if (this.nextTokenRulesByPath()[tablePath]) return;\r\n\r\n this.contextService\n .getNextTokens(schemaId, component, tablePath, moduleId)\n .subscribe((response) => {\n if (!response) return;\r\n this.nextTokenRulesByPath.update((current) => ({\r\n ...current,\r\n [tablePath]: response.nextTokenRules ?? {},\r\n }));\r\n });\r\n });\r\n\r\n // Keep base segment in sync with scope metadata\r\n effect(() => {\r\n const scope = this.propertyScope();\r\n const operator = this.baseOperator();\r\n const shouldHaveSegment =\r\n Boolean(operator?.parameterKind) ||\r\n Boolean(operator?.requiresParameter);\r\n const segments = this.propertyPathSegments();\r\n const hasBase = segments[0]?.operatorToken === scope;\r\n\r\n if (shouldHaveSegment && !hasBase) {\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(scope, operator, this.baseRule()),\r\n );\r\n return;\r\n }\r\n\r\n if (!shouldHaveSegment && hasBase) {\r\n this.propertyPathSegments.set(segments.slice(1));\r\n }\r\n });\r\n\r\n // Normalize segment values when allowed values change\r\n effect(() => {\r\n const meta = this.pathSegments();\r\n const segments = this.propertyPathSegments();\r\n if (meta.length !== segments.length) return;\r\n\r\n let changed = false;\r\n const next = segments.map((segment, index) => {\r\n const normalized = meta[index]?.value ?? segment.value;\r\n if (segment.value !== normalized) {\r\n changed = true;\r\n return { ...segment, value: normalized };\r\n }\r\n return segment;\r\n });\r\n\r\n if (changed) {\r\n this.propertyPathSegments.set(next);\r\n }\r\n });\r\n\r\n // Ensure selected field exists in current options\r\n effect(() => {\r\n const options = this.propertyOptions();\r\n const current = this.propertyFieldKey();\r\n\r\n if (options.length === 0) {\r\n if (current) this.propertyFieldKey.set('');\r\n return;\r\n }\r\n\r\n if (current && !options.some((prop) => prop.key === current)) {\r\n this.propertyFieldKey.set('');\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.validatorService.reset();\r\n }\r\n\r\n // ===== ControlValueAccessor =====\r\n\r\n writeValue(value: FormulaBuilderValue | null): void {\r\n if (!value) {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n return;\r\n }\r\n\r\n const builder = Array.isArray(value.builder) ? value.builder : [];\r\n const expression = this.codeOnly()\r\n ? this.resolveExpressionValue(value.expression ?? '', builder)\r\n : (value.expression ?? '');\r\n this.expressionValue.set(expression);\r\n\r\n if (this.codeOnly()) {\r\n this.applyFormulaValue(builder, expression, true);\r\n return;\r\n }\r\n\r\n if (builder.length === 0) {\r\n this.applyFormulaValue(\r\n [],\r\n expression,\r\n expression.trim().length > 0,\r\n true,\r\n );\r\n return;\r\n }\r\n\r\n this.applyFormulaValue(builder, expression, false);\r\n }\r\n\r\n registerOnChange(fn: (value: FormulaBuilderValue) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.isDisabled.set(isDisabled);\r\n }\r\n\r\n /** Handle formula change from editor */\r\n onFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle formula change from code editor */\r\n onCodeFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n if (!newFormula.trim()) {\r\n this.clearBuilderTokens();\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.emitValueChange();\r\n return;\r\n }\r\n\r\n if (\r\n !this.isCodeModeLocked() &&\r\n newFormula !== this.codeModeSnapshotExpression\r\n ) {\r\n this.isCodeModeLocked.set(true);\r\n this.clearBuilderTokens();\r\n }\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle block insert from toolbar */\r\n onBlockInsert(block: SmartBlock): void {\r\n if (this.isCodeMode()) {\r\n const editor = this.codeEditor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n return;\r\n }\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n }\r\n\r\n /** Handle tokens change */\r\n onTokensChange(newTokens: FormulaToken[]): void {\r\n this.tokens.set(newTokens);\r\n const json = JSON.stringify(newTokens);\r\n this.lastBuilderJson = json;\r\n this.builderValue.set(newTokens);\r\n this.tokensChange.emit(newTokens);\r\n this.emitValueChange();\r\n }\r\n\r\n onEditorFocus(): void {\r\n this.hasFocus.set(true);\r\n }\r\n\r\n onEditorBlur(): void {\r\n this.hasFocus.set(false);\r\n this.onTouched();\r\n }\r\n\r\n private emitValueChange(): void {\r\n this.onChange({\r\n expression: this.expressionValue(),\r\n builder: this.builderValue(),\r\n });\r\n }\r\n\r\n onModeToggle(value: boolean): void {\r\n if (this.codeOnly()) {\r\n return;\r\n }\r\n const nextMode: 'builder' | 'code' = value ? 'code' : 'builder';\r\n this.setEditorMode(nextMode);\r\n }\r\n\r\n private setEditorMode(mode: 'builder' | 'code'): void {\r\n if (this.editorMode() === mode) return;\r\n\r\n if (mode === 'code') {\r\n this.enterCodeMode();\r\n return;\r\n }\r\n\r\n if (this.isCodeModeLocked()) {\r\n return;\r\n }\r\n\r\n this.exitCodeMode();\r\n }\r\n\r\n private enterCodeMode(): void {\r\n this.codeModeSnapshotTokens = this.tokens().slice();\r\n this.codeModeSnapshotExpression = this.expressionValue();\r\n const editor = this.editor();\r\n if (editor) {\r\n const formula = editor.serialize();\r\n this.codeModeSnapshotExpression = formula;\r\n this.expressionValue.set(formula);\r\n this.emitValueChange();\r\n }\r\n this.isCodeModeLocked.set(false);\r\n this.editorMode.set('code');\r\n }\r\n\r\n private exitCodeMode(): void {\r\n this.editorMode.set('builder');\r\n if (!this.expressionValue().trim()) {\r\n this.clearBuilderTokens();\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue([]);\r\n }\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.isCodeModeLocked.set(false);\r\n return;\r\n }\r\n\r\n if (this.codeModeSnapshotTokens.length > 0) {\r\n const restored = this.codeModeSnapshotTokens.slice();\r\n this.tokens.set(restored);\r\n this.builderValue.set(restored);\r\n this.lastBuilderJson = JSON.stringify(restored);\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(restored);\r\n }\r\n }\r\n if (this.codeModeSnapshotExpression) {\r\n this.expressionValue.set(this.codeModeSnapshotExpression);\r\n }\r\n this.isCodeModeLocked.set(false);\r\n }\r\n\r\n private clearBuilderTokens(): void {\r\n if (this.tokens().length === 0 && this.builderValue().length === 0) {\r\n return;\r\n }\r\n this.tokens.set([]);\r\n this.builderValue.set([]);\r\n this.lastBuilderJson = '';\r\n this.tokensChange.emit([]);\r\n }\r\n\r\n // ===== PUBLIC METHODS =====\r\n\r\n /** Clear the formula */\r\n clear(): void {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n this.emitValueChange();\r\n }\r\n\r\n private resolveExpressionValue(\r\n expression: string,\r\n builder: FormulaToken[],\r\n ): string {\r\n if (expression.trim().length > 0) {\r\n return expression;\r\n }\r\n return builder.length > 0 ? serializeTokens(builder) : '';\r\n }\r\n\r\n private applyFormulaValue(\r\n builder: FormulaToken[],\r\n expression: string,\r\n useCodeMode: boolean,\r\n lockCodeMode: boolean = false,\r\n ): void {\r\n const serialized = JSON.stringify(builder);\r\n this.builderValue.set(builder);\r\n this.tokens.set(builder);\r\n this.lastBuilderJson = builder.length > 0 ? serialized : '';\r\n\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(builder);\r\n }\r\n\r\n const codeEditor = this.codeEditor();\r\n if (codeEditor) {\r\n codeEditor.writeValue(expression);\r\n }\r\n\r\n if (useCodeMode) {\r\n this.editorMode.set('code');\r\n this.isCodeModeLocked.set(lockCodeMode);\r\n this.codeModeSnapshotTokens = builder.slice();\r\n this.codeModeSnapshotExpression = expression;\r\n return;\r\n }\r\n\r\n this.editorMode.set('builder');\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n }\r\n\r\n // ===== PROPERTY COMPOSER =====\r\n\r\n readonly propertyScope = signal<string>('');\r\n\r\n readonly propertyPathSegments = signal<PathSegment[]>([]);\r\n\r\n readonly propertyFieldKey = signal('');\r\n\r\n private readonly nextTokenRulesByPath = signal<\r\n Record<string, Record<string, NextTokenRule>>\r\n >({});\r\n\r\n readonly contextOperators = computed<OperatorDescriptor[]>(() => {\r\n return this.builderContext()?.schemaDescriptor?.operators ?? [];\r\n });\r\n\r\n readonly baseOperator = computed(() =>\r\n this.contextOperators().find((op) => op.token === this.propertyScope()),\r\n );\r\n\r\n readonly baseRule = computed(() => {\r\n const scope = this.propertyScope();\r\n return this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope];\r\n });\r\n\r\n readonly availableScopes = computed(() => {\n const operators = this.contextOperators();\n if (operators.length === 0) return [];\n const operatorsByToken = new Map(\n operators.map((operator) => [operator.token, operator]),\n );\n\n return PROPERTY_SCOPE_ORDER.map((token) => operatorsByToken.get(token))\n .filter((operator): operator is OperatorDescriptor => Boolean(operator))\n .map((operator) => ({\n key: operator.token,\n label: `@${operator.token}`,\n requiresParam: operator.requiresParameter ?? false,\n optional: !operator.requiresParameter,\n }));\n });\n\r\n /** Radio card options for scope selection */\r\n readonly scopeOptions = computed<RadioItem[]>(() =>\n this.availableScopes().map((scope) => ({\n id: scope.key,\n name: this.getOperatorDisplayName(scope.key),\n icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,\n })),\n );\n\r\n /** Handle scope selection from radio cards */\r\n onScopeChange(item: RadioItem): void {\r\n this.setPropertyScope(String(item.id));\r\n }\r\n\r\n readonly pathSegments = computed<SegmentMeta[]>(() => {\r\n const scope = this.propertyScope();\r\n return resolveSegmentsMeta({\r\n scope,\r\n segments: this.propertyPathSegments(),\r\n operators: this.contextOperators(),\r\n baseRule: this.baseRule(),\r\n rulesByPath: this.nextTokenRulesByPath(),\r\n });\r\n });\r\n\r\n readonly isDirectAccess = computed(() => {\r\n const operator = this.baseOperator();\r\n const needsParameter =\r\n Boolean(operator?.parameterKind) || Boolean(operator?.requiresParameter);\r\n return !needsParameter && this.pathSegments().length === 0;\r\n });\r\n\r\n readonly propertyTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n false,\r\n ),\r\n );\r\n\r\n readonly resolvedTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n true,\r\n ),\r\n );\r\n\r\n readonly currentNextTokenRules = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return {};\r\n return this.nextTokenRulesByPath()[path] ?? {};\r\n });\r\n\r\n readonly nextOperatorOptions = computed(() => {\r\n const rules = this.currentNextTokenRules();\r\n const operators = this.contextOperators();\r\n return Object.keys(rules)\r\n .map((token) => {\r\n const rule = rules[token];\r\n const operator = operators.find((item) => item.token === token);\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n return {\r\n token,\r\n rule,\r\n requiresParameter,\r\n allowedValues,\r\n };\r\n })\r\n .filter(\r\n (option) =>\r\n option.allowedValues.length > 0 || !option.requiresParameter,\r\n );\r\n });\r\n\r\n readonly canAddNextSegment = computed(() => {\r\n if (this.nextOperatorOptions().length === 0) return false;\r\n const segments = this.pathSegments();\r\n if (segments.length === 0 || !segments[0].value) {\r\n return false;\r\n }\r\n return segments.every(\r\n (segment) => !segment.requiresParameter || Boolean(segment.value),\r\n );\r\n });\r\n\r\n readonly propertiesComponent = computed(() => {\r\n if (this.isProcessBuilder()) {\r\n return undefined;\r\n }\r\n const contextKey = this.builderContext()?.contextEntityTypeKey;\r\n return contextKey;\r\n });\r\n\r\n readonly mergedPropertiesByPath = computed<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >(() => {\r\n const merged: Record<string, FormulaPropertyDescriptor[]> = {\r\n ...this.propertiesByPath(),\r\n };\r\n const apiProps = this.propertiesByPathApi();\r\n Object.entries(apiProps).forEach(([path, props]) => {\r\n if (props && props.length > 0) {\r\n merged[path] = props;\r\n }\r\n });\r\n return merged;\r\n });\r\n\r\n readonly isPropertyLoading = computed(() => {\r\n const path = this.resolvedTablePath();\r\n return Boolean(path) && this.propertyLoadingPath() === path;\r\n });\r\n\r\n readonly propertyOptions = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return [];\r\n const byPath = this.mergedPropertiesByPath()[path];\r\n const list = byPath && byPath.length > 0 ? byPath : [];\r\n return list.map((prop) => ({\r\n key: prop.key,\r\n name: prop.name ?? prop.key,\r\n }));\r\n });\r\n\r\n readonly selectedProperty = computed(() => {\r\n const key = this.propertyFieldKey();\r\n return this.propertyOptions().find((prop) => prop.key === key) ?? null;\r\n });\r\n\r\n readonly canInsertProperty = computed(() => {\r\n if (!this.selectedProperty()) return false;\r\n return Boolean(this.resolvedTablePath());\r\n });\r\n\r\n setPropertyScope(scope: string): void {\r\n if (this.propertyScope() === scope) {\r\n return;\r\n }\r\n this.propertyScope.set(scope);\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(\r\n scope,\r\n this.contextOperators().find((op) => op.token === scope),\r\n this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope],\r\n ),\r\n );\r\n this.propertyFieldKey.set('');\r\n }\r\n\r\n setPathSegmentValue(index: number, value: string | null): void {\r\n this.propertyPathSegments.update((segments) => {\r\n // Update the segment at the given index and remove all segments after it\r\n // because subsequent segments depend on previous values\r\n const updated = segments.slice(0, index + 1);\r\n updated[index] = { ...updated[index], value: value ?? '' };\r\n return updated;\r\n });\r\n }\r\n\r\n addNextSegment(operatorToken: string): void {\r\n const value = '';\r\n\r\n this.propertyPathSegments.update((segments) => [\r\n ...segments,\r\n { operatorToken, value },\r\n ]);\r\n }\r\n\r\n onAddSegmentSelection(\r\n operatorToken: string,\r\n popover: { hide: () => void },\r\n ): void {\r\n popover.hide();\r\n this.addNextSegment(operatorToken);\r\n }\r\n\r\n removePathSegment(index: number): void {\r\n this.propertyPathSegments.update((segments) =>\r\n segments.filter((_, i) => i !== index),\r\n );\r\n }\r\n\r\n segmentOptions(index: number): { key: string; name: string }[] {\n const segment = this.pathSegments()[index];\r\n if (!segment) return [];\r\n return segment.allowedValues.map((value) => ({\r\n key: value,\r\n name: value,\r\n }));\r\n }\r\n\r\n insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void {\n const prop = this.selectedProperty();\r\n if (!prop) return;\r\n\r\n if (!this.canInsertProperty()) return;\r\n\r\n const tablePath = this.resolvedTablePath();\r\n if (!tablePath) return;\r\n const display = prop.name ?? prop.key;\r\n const block = createPropertyBlock(\n `@${tablePath}::${prop.key}`,\n 'current',\n display,\n );\n insertBlock(block);\n }\n\n getOperatorDisplayName(token: string): string {\n if (token === 'Host' && this.isModuleContext()) {\n return 'Level';\n }\n\n return token;\n }\n}\n","<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n ✓ {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >›</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n","/**\r\n * Services barrel export\r\n */\r\n\r\nexport * from './formula-context.service';\r\nexport * from './formula-validator.service';\r\n","/**\r\n * Public API Surface of @masterteam/formula-builder\r\n *\r\n * This package provides the FormulaBuilder component which wraps\r\n * pure UI components from @masterteam/components/formula with\r\n * backend services for validation and context loading.\r\n *\r\n * Architecture:\r\n * - UI Components: imported from @masterteam/components/formula (pure, no services)\r\n * - Services: FormulaContextService, FormulaValidatorService (backend logic)\r\n * - FormulaBuilder: Main wrapper that connects UI with services\r\n */\r\n\r\n// Main component\r\nexport * from './lib/formula-builder';\r\n\r\n// Services (backend logic only)\r\nexport * from './lib/services/index';\r\n\r\n// Re-export models from base package for convenience\r\nexport {\r\n type SmartBlock,\r\n type BlockType,\r\n type ArgumentSlot,\r\n type FormulaToken,\r\n type TokenType,\r\n type DragBehavior,\r\n type ValidationResult,\r\n type ValidationError,\r\n type FunctionDefinition,\r\n type FunctionCategoryGroup,\r\n type OperatorDefinition,\r\n createFunctionBlock,\r\n createPropertyBlock,\r\n createOperatorBlock,\r\n createLiteralBlock,\r\n} from '@masterteam/components/formula';\r\n\r\n// Export validation-specific models\r\nexport type {\r\n ValidationRequest,\r\n FunctionCatalogResponse,\r\n ApiErrorResponse,\r\n} from './lib/models/validation-result.model';\r\n\r\n// Export value model for ControlValueAccessor usage\r\nexport type { FormulaBuilderValue } from './lib/models/formula-builder-value.model';\r\n\r\n// Export builder context models\r\nexport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n FormulaEngineSchemaDescriptor,\r\n OperatorDescriptor,\r\n NextTokenRule,\r\n} from './lib/models/formula-context.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masterteam/formula-builder",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "publishConfig": {
5
5
  "directory": "../../../dist/masterteam/formula-builder",
6
6
  "linkDirectory": true,
@@ -19,7 +19,7 @@
19
19
  "rxjs": "^7.8.2",
20
20
  "tailwindcss": "^4.1.17",
21
21
  "tailwindcss-primeui": "^0.6.1",
22
- "@masterteam/components": "^0.0.130",
22
+ "@masterteam/components": "^0.0.131",
23
23
  "@masterteam/icons": "^0.0.14"
24
24
  },
25
25
  "sideEffects": false,
@@ -4,14 +4,20 @@ import { OnDestroy } from '@angular/core';
4
4
  import { ControlValueAccessor } from '@angular/forms';
5
5
  import { RadioItem } from '@masterteam/components/radio-cards';
6
6
  import { Observable } from 'rxjs';
7
- import { FunctionCategoryGroup, FormulaToken, ToolbarTab, ValidationResult, AutocompleteRequest, AutocompleteResponse, SmartBlock } from '@masterteam/components/formula';
7
+ import { FunctionCategoryGroup, AutocompleteRequest as AutocompleteRequest$1, AutocompleteResponse as AutocompleteResponse$1, ValidationResult as ValidationResult$1, FormulaToken, ToolbarTab, SmartBlock } from '@masterteam/components/formula';
8
8
  export { ArgumentSlot, BlockType, DragBehavior, FormulaToken, FunctionCategoryGroup, FunctionDefinition, OperatorDefinition, SmartBlock, TokenType, ValidationError, ValidationResult, createFunctionBlock, createLiteralBlock, createOperatorBlock, createPropertyBlock } from '@masterteam/components/formula';
9
9
 
10
+ type ValidationResult = ValidationResult$1;
11
+ type AutocompleteResponse = AutocompleteResponse$1;
12
+ interface AutocompleteRequest extends AutocompleteRequest$1 {
13
+ moduleId?: number;
14
+ }
10
15
  /** Validation request payload (for API calls) */
11
16
  interface ValidationRequest {
12
17
  formula: string;
13
18
  knownProperties?: string[];
14
19
  levelSchemaId?: number;
20
+ moduleId?: number;
15
21
  templateId?: number;
16
22
  }
17
23
  /** Function catalog response from API */
@@ -108,6 +114,8 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
108
114
  }[]>>;
109
115
  /** Level schema ID for validation context */
110
116
  readonly levelSchemaId: _angular_core.InputSignal<number | undefined>;
117
+ /** Optional module ID when the formula is scoped inside a level-linked module */
118
+ readonly moduleId: _angular_core.InputSignal<number | undefined>;
111
119
  /** Optional current context entity key, e.g. LevelData or Risk */
112
120
  readonly contextEntityTypeKey: _angular_core.InputSignal<string | undefined>;
113
121
  /** Template ID for validation context */
@@ -125,7 +133,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
125
133
  /** Use Process Builder current-only Formula Engine endpoints */
126
134
  readonly isProcessBuilder: _angular_core.InputSignal<boolean>;
127
135
  /** Emits validation result on change */
128
- readonly validationChange: _angular_core.OutputEmitterRef<ValidationResult>;
136
+ readonly validationChange: _angular_core.OutputEmitterRef<_masterteam_formula_builder.ValidationResult>;
129
137
  /** Emits when tokens change */
130
138
  readonly tokensChange: _angular_core.OutputEmitterRef<FormulaToken[]>;
131
139
  /** Editor focus state */
@@ -137,6 +145,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
137
145
  readonly tokens: _angular_core.WritableSignal<FormulaToken[]>;
138
146
  readonly expression: _angular_core.Signal<string>;
139
147
  readonly resolvedContextEntityTypeKey: _angular_core.Signal<string | undefined>;
148
+ readonly isModuleContext: _angular_core.Signal<boolean>;
140
149
  readonly autocompleteProvider: (request: AutocompleteRequest) => Observable<AutocompleteResponse | null>;
141
150
  /** Track last synced builder JSON to avoid loops */
142
151
  private lastBuilderJson;
@@ -155,7 +164,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
155
164
  /** Disabled state */
156
165
  private readonly isDisabled;
157
166
  /** Validation result from service */
158
- readonly validation: _angular_core.Signal<ValidationResult>;
167
+ readonly validation: _angular_core.Signal<_masterteam_formula_builder.ValidationResult>;
159
168
  /** Is validation in progress */
160
169
  readonly isValidating: _angular_core.Signal<boolean>;
161
170
  /** Builder context from API */
@@ -248,8 +257,9 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
248
257
  name: string;
249
258
  }[];
250
259
  insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void;
260
+ getOperatorDisplayName(token: string): string;
251
261
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormulaBuilder, never>;
252
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormulaBuilder, "mt-formula-builder", never, { "propertiesByPath": { "alias": "propertiesByPath"; "required": false; "isSignal": true; }; "levelSchemaId": { "alias": "levelSchemaId"; "required": false; "isSignal": true; }; "contextEntityTypeKey": { "alias": "contextEntityTypeKey"; "required": false; "isSignal": true; }; "templateId": { "alias": "templateId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideToolbar": { "alias": "hideToolbar"; "required": false; "isSignal": true; }; "hideStatusBar": { "alias": "hideStatusBar"; "required": false; "isSignal": true; }; "toolbarTabs": { "alias": "toolbarTabs"; "required": false; "isSignal": true; }; "codeOnly": { "alias": "codeOnly"; "required": false; "isSignal": true; }; "isProcessBuilder": { "alias": "isProcessBuilder"; "required": false; "isSignal": true; }; }, { "validationChange": "validationChange"; "tokensChange": "tokensChange"; }, never, never, true, never>;
262
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormulaBuilder, "mt-formula-builder", never, { "propertiesByPath": { "alias": "propertiesByPath"; "required": false; "isSignal": true; }; "levelSchemaId": { "alias": "levelSchemaId"; "required": false; "isSignal": true; }; "moduleId": { "alias": "moduleId"; "required": false; "isSignal": true; }; "contextEntityTypeKey": { "alias": "contextEntityTypeKey"; "required": false; "isSignal": true; }; "templateId": { "alias": "templateId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideToolbar": { "alias": "hideToolbar"; "required": false; "isSignal": true; }; "hideStatusBar": { "alias": "hideStatusBar"; "required": false; "isSignal": true; }; "toolbarTabs": { "alias": "toolbarTabs"; "required": false; "isSignal": true; }; "codeOnly": { "alias": "codeOnly"; "required": false; "isSignal": true; }; "isProcessBuilder": { "alias": "isProcessBuilder"; "required": false; "isSignal": true; }; }, { "validationChange": "validationChange"; "tokensChange": "tokensChange"; }, never, never, true, never>;
253
263
  }
254
264
 
255
265
  type FormulaApiMode$1 = 'default' | 'current-only';
@@ -261,9 +271,9 @@ declare class FormulaContextService {
261
271
  private readonly contextCache;
262
272
  private readonly propertiesCache;
263
273
  private readonly nextTokensCache;
264
- loadContext(schemaId: number, contextEntityTypeKey?: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderContextResponse | null>;
265
- getScopeProperties(schemaId: number, component: string, tablePath: string, mode?: FormulaApiMode$1): Observable<FormulaPropertyDescriptor[]>;
266
- getNextTokens(schemaId: number, component: string, tablePath: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderNextTokensResponse | null>;
274
+ loadContext(schemaId: number, moduleId?: number, contextEntityTypeKey?: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderContextResponse | null>;
275
+ getScopeProperties(schemaId: number, component: string, tablePath: string, moduleId?: number, mode?: FormulaApiMode$1): Observable<FormulaPropertyDescriptor[]>;
276
+ getNextTokens(schemaId: number, component: string, tablePath: string, moduleId?: number, mode?: FormulaApiMode$1): Observable<FormulaBuilderNextTokensResponse | null>;
267
277
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormulaContextService, never>;
268
278
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<FormulaContextService>;
269
279
  }
@@ -283,15 +293,15 @@ declare class FormulaValidatorService {
283
293
  private readonly validateSubject;
284
294
  private unwrapResponse;
285
295
  /** Public signals */
286
- readonly validation: _angular_core.Signal<ValidationResult>;
296
+ readonly validation: _angular_core.Signal<_masterteam_formula_builder.ValidationResult>;
287
297
  readonly isValidating: _angular_core.Signal<boolean>;
288
298
  constructor();
289
299
  /** Setup debounced validation stream */
290
300
  private setupValidationStream;
291
301
  /** Validate formula (debounced) */
292
- validate(formula: string, knownProperties?: string[], levelSchemaId?: number, templateId?: number, apiMode?: FormulaApiMode): void;
302
+ validate(formula: string, knownProperties?: string[], levelSchemaId?: number, moduleId?: number, templateId?: number, apiMode?: FormulaApiMode): void;
293
303
  /** Validate formula immediately (no debounce) */
294
- validateImmediate(formula: string, knownProperties?: string[], levelSchemaId?: number, templateId?: number, apiMode?: FormulaApiMode): Observable<ValidationResult>;
304
+ validateImmediate(formula: string, knownProperties?: string[], levelSchemaId?: number, moduleId?: number, templateId?: number, apiMode?: FormulaApiMode): Observable<ValidationResult>;
295
305
  /** Call validation API */
296
306
  private callValidateApi;
297
307
  /** Reset validation state */