@acorex-platform/module-data-management-client 0.0.38 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-data-source.mjs +15 -0
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-data-source.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-meta-data-definition.mjs +15 -0
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-meta-data-definition.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-tag.mjs +12 -0
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entities-tag.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-data-management-client-contracts-entity-catalog-acorex-platform-module-data-management-client-contracts-entity-catalog-BIY8VQ23.mjs → acorex-platform-module-data-management-client-contracts-entity-catalog-acorex-platform-module-data-management-client-contracts-entity-catalog-C-ZCoPUP.mjs} +4 -4
- package/fesm2022/{acorex-platform-module-data-management-client-contracts-entity-catalog-acorex-platform-module-data-management-client-contracts-entity-catalog-BIY8VQ23.mjs.map → acorex-platform-module-data-management-client-contracts-entity-catalog-acorex-platform-module-data-management-client-contracts-entity-catalog-C-ZCoPUP.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-data-management-client-contracts-entity-catalog-data-source.entity-CJ7ky5Gc.mjs → acorex-platform-module-data-management-client-contracts-entity-catalog-data-source.entity-BrbhJ5lR.mjs} +17 -2
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-data-source.entity-BrbhJ5lR.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-data-management-client-contracts-entity-catalog-meta-data-definition.entity-Dj3FPJ3n.mjs → acorex-platform-module-data-management-client-contracts-entity-catalog-meta-data-definition.entity-MChqGKJz.mjs} +17 -2
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-meta-data-definition.entity-MChqGKJz.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-data-management-client-contracts-entity-catalog-tag.entity-CFKCEoHu.mjs → acorex-platform-module-data-management-client-contracts-entity-catalog-tag.entity-CxCnhVte.mjs} +14 -2
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-tag.entity-CxCnhVte.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog.mjs +1 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts.mjs +21 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-data-management-client.mjs +115 -76
- package/fesm2022/acorex-platform-module-data-management-client.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-module-data-management-client-contracts.d.ts +8 -2
- package/types/acorex-platform-module-data-management-client.d.ts +28 -10
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-data-source.entity-CJ7ky5Gc.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-meta-data-definition.entity-Dj3FPJ3n.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-data-management-client-contracts-entity-catalog-tag.entity-CFKCEoHu.mjs.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { computed, effect, HostBinding, ChangeDetectionStrategy, Component, EventEmitter, signal, Output, Input, inject, ElementRef, DestroyRef, PLATFORM_ID, input, output, untracked, afterNextRender, InjectionToken, Injectable, viewChild, NgModule, model, ViewEncapsulation } from '@angular/core';
|
|
3
|
-
import { AXPContextStore, AXPDataGenerator, AXPTagProvider, AXP_TAG_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
|
|
3
|
+
import { AXPContextStore, AXPDataGenerator, AXPTagProvider, AXP_TAG_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER, provideLazyProvider } from '@acorex-platform/framework-client/core';
|
|
4
4
|
import { AXPStateMessageComponent, AXPStandardSectionItemsBuilderComponent, AXPWidgetPropertyViewerService, AXPItemConfiguratorComponent, AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';
|
|
5
5
|
import { AXPEntityDefinitionRegistryService, AXPEntityService, AXPEntityDataSelectorService, resolveEntityPluginDetailPageOrder, actionExists, AXP_ENTITY_ACTION_PLUGIN, ensureListActions, cloneLayoutArrays, ensureLayoutSection, ensureLayoutPropertyView, AXP_ENTITY_STORAGE_MIDDLEWARE } from '@acorex-platform/framework-client/layout/entity';
|
|
6
|
-
import { RootConfig, AXMDataManagementFeatureKeys, AXPInsightsReportingPermissionKeys, AXPDataManagementMenuKeys, convertValueToState } from '@acorex-platform/module-data-management-client/contracts';
|
|
7
6
|
import * as i3 from '@acorex-platform/framework-client/layout/widget-core';
|
|
8
7
|
import { AXP_WIDGETS_EDITOR_CATEGORY, AXPValueWidgetComponent, AXPWidgetCoreModule, AXPWidgetRegistryService, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/layout/widget-core';
|
|
9
8
|
import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY, AXP_LABEL_PROPERTY, AXP_READONLY_PROPERTY } from '@acorex-platform/framework-client/layout/widgets';
|
|
@@ -40,6 +39,7 @@ import { AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-c
|
|
|
40
39
|
import { AXPQueryService, provideCommandSetups, provideQuerySetups } from '@acorex-platform/framework-client/runtime';
|
|
41
40
|
import { runtimeQueryPayloadData, runtimeQueryCollectionData, AXPWidgetsCatalog, compareMultiLanguageStrings, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, AXPWidgetsList } from '@acorex-platform/framework-shared/core';
|
|
42
41
|
import { get, cloneDeep, unset } from 'lodash';
|
|
42
|
+
import { AXMDataManagementFeatureKeys, AXPInsightsReportingPermissionKeys, RootConfig, AXPDataManagementMenuKeys, convertValueToState } from '@acorex-platform/module-data-management-client/contracts';
|
|
43
43
|
import { AXPCommonPermissionGroupKeys, AXPCommonMenuKeys } from '@acorex-platform/module-common-client/contracts';
|
|
44
44
|
import { AXPLayoutBuilderService, AXPLayoutRendererComponent } from '@acorex-platform/framework-client/layout/builder';
|
|
45
45
|
import { AXToastService } from '@acorex/components/toast';
|
|
@@ -48,26 +48,6 @@ import { AXDialogService } from '@acorex/components/dialog';
|
|
|
48
48
|
import { AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';
|
|
49
49
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
50
50
|
|
|
51
|
-
//#region ---- Imports ----
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region ---- Manifest Definition ----
|
|
54
|
-
/**
|
|
55
|
-
* Data Management Module Manifest.
|
|
56
|
-
* Defines module metadata, features, and provider references.
|
|
57
|
-
*/
|
|
58
|
-
const DataManagementManifest = {
|
|
59
|
-
name: RootConfig.module.name,
|
|
60
|
-
version: '1.0.0',
|
|
61
|
-
title: RootConfig.module.title,
|
|
62
|
-
icon: RootConfig.module.icon,
|
|
63
|
-
i18n: RootConfig.config.i18n,
|
|
64
|
-
type: 'platform',
|
|
65
|
-
domain: 'data',
|
|
66
|
-
required: true,
|
|
67
|
-
// Module dependencies (optional)
|
|
68
|
-
};
|
|
69
|
-
//#endregion
|
|
70
|
-
|
|
71
51
|
const AXMColumnFilterSelectorWidget = {
|
|
72
52
|
name: 'column-filter-selector-editor',
|
|
73
53
|
title: 'Column Filter Selector',
|
|
@@ -2219,6 +2199,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2219
2199
|
}]
|
|
2220
2200
|
}] });
|
|
2221
2201
|
|
|
2202
|
+
//#region ----- Constants -----
|
|
2203
|
+
const NUMERIC_ONLY_AGGREGATE_FUNCTIONS = new Set(['sum', 'avg', 'average', 'stddev', 'variance']);
|
|
2204
|
+
function functionRequiresNumericField(name) {
|
|
2205
|
+
return NUMERIC_ONLY_AGGREGATE_FUNCTIONS.has(String(name ?? '').trim().toLowerCase());
|
|
2206
|
+
}
|
|
2207
|
+
function isNumericQueryBuilderColumn(column) {
|
|
2208
|
+
return String(column.datatype ?? '').toLowerCase() === 'number';
|
|
2209
|
+
}
|
|
2210
|
+
//#endregion
|
|
2222
2211
|
/**
|
|
2223
2212
|
* Aggregate Builder Component
|
|
2224
2213
|
*
|
|
@@ -2342,27 +2331,11 @@ class AXPAggregateBuilderComponent {
|
|
|
2342
2331
|
}, /* @ts-ignore */
|
|
2343
2332
|
...(ngDevMode ? [{ debugName: "categoriesDataSource" }] : /* istanbul ignore next */ []));
|
|
2344
2333
|
/**
|
|
2345
|
-
* Columns data source for field selection
|
|
2334
|
+
* Columns data source for field selection.
|
|
2335
|
+
* SUM / AVG (and similar) only list numeric columns (`datatype: 'number'`).
|
|
2346
2336
|
*/
|
|
2347
2337
|
this.columnsDataSource = computed(() => {
|
|
2348
|
-
|
|
2349
|
-
return new AXDataSource({
|
|
2350
|
-
load: () => {
|
|
2351
|
-
return Promise.resolve({
|
|
2352
|
-
items: cols.map(col => ({
|
|
2353
|
-
value: col.name,
|
|
2354
|
-
text: col.title || col.name,
|
|
2355
|
-
})),
|
|
2356
|
-
total: cols.length,
|
|
2357
|
-
});
|
|
2358
|
-
},
|
|
2359
|
-
byKey: (key) => {
|
|
2360
|
-
const col = cols.find(c => c.name === key);
|
|
2361
|
-
return Promise.resolve(col ? { value: col.name, text: col.title || col.name } : null);
|
|
2362
|
-
},
|
|
2363
|
-
pageSize: 1000,
|
|
2364
|
-
key: 'value',
|
|
2365
|
-
});
|
|
2338
|
+
return this.columnsDataSourceFor(this.newAggregate().function);
|
|
2366
2339
|
}, /* @ts-ignore */
|
|
2367
2340
|
...(ngDevMode ? [{ debugName: "columnsDataSource" }] : /* istanbul ignore next */ []));
|
|
2368
2341
|
/**
|
|
@@ -2406,6 +2379,33 @@ class AXPAggregateBuilderComponent {
|
|
|
2406
2379
|
const depth = this.aggregateFunctionService.getMaxNestingDepth();
|
|
2407
2380
|
this.maxNestingDepth.set(depth);
|
|
2408
2381
|
}
|
|
2382
|
+
columnsDataSourceFor(functionName) {
|
|
2383
|
+
const cols = this.fieldColumnsForFunction(functionName);
|
|
2384
|
+
return new AXDataSource({
|
|
2385
|
+
load: () => {
|
|
2386
|
+
return Promise.resolve({
|
|
2387
|
+
items: cols.map(col => ({
|
|
2388
|
+
value: col.name,
|
|
2389
|
+
text: col.title || col.name,
|
|
2390
|
+
})),
|
|
2391
|
+
total: cols.length,
|
|
2392
|
+
});
|
|
2393
|
+
},
|
|
2394
|
+
byKey: (key) => {
|
|
2395
|
+
const col = cols.find(c => c.name === key);
|
|
2396
|
+
return Promise.resolve(col ? { value: col.name, text: col.title || col.name } : null);
|
|
2397
|
+
},
|
|
2398
|
+
pageSize: 1000,
|
|
2399
|
+
key: 'value',
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2402
|
+
fieldColumnsForFunction(functionName) {
|
|
2403
|
+
const cols = this.columns();
|
|
2404
|
+
if (!functionRequiresNumericField(functionName)) {
|
|
2405
|
+
return cols;
|
|
2406
|
+
}
|
|
2407
|
+
return cols.filter(isNumericQueryBuilderColumn);
|
|
2408
|
+
}
|
|
2409
2409
|
//#endregion
|
|
2410
2410
|
//#region ---- Public Methods ----
|
|
2411
2411
|
/**
|
|
@@ -2543,12 +2543,15 @@ class AXPAggregateBuilderComponent {
|
|
|
2543
2543
|
onFunctionChange(functionName) {
|
|
2544
2544
|
const funcDef = this.availableFunctionsList().find(f => f.name === functionName);
|
|
2545
2545
|
if (funcDef && !funcDef.requiresField) {
|
|
2546
|
-
// For functions like COUNT(*), clear the field
|
|
2547
2546
|
this.newAggregate.update(agg => ({ ...agg, function: functionName, field: '' }));
|
|
2547
|
+
return;
|
|
2548
2548
|
}
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2549
|
+
const allowed = new Set(this.fieldColumnsForFunction(functionName).map((column) => column.name));
|
|
2550
|
+
this.newAggregate.update((agg) => ({
|
|
2551
|
+
...agg,
|
|
2552
|
+
function: functionName,
|
|
2553
|
+
field: agg.field && allowed.has(agg.field) ? agg.field : '',
|
|
2554
|
+
}));
|
|
2552
2555
|
}
|
|
2553
2556
|
/**
|
|
2554
2557
|
* Handle field selection change
|
|
@@ -2714,7 +2717,7 @@ class AXPAggregateBuilderComponent {
|
|
|
2714
2717
|
});
|
|
2715
2718
|
}
|
|
2716
2719
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAggregateBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2717
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPAggregateBuilderComponent, isStandalone: true, selector: "axp-aggregate-builder", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, databaseType: { classPropertyName: "databaseType", publicName: "databaseType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"axp-aggregate-builder\">\n <div class=\"__section-header\">\n <ax-label class=\"__section-title\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.title' | translate | async) || 'Aggregate Functions' }}\n </ax-label>\n <div class=\"__section-actions\">\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"(showAddForm() ? ('@data-management:metadata-definitions.components.query-builder.actions.cancel.title' | translate | async) : ('@data-management:metadata-definitions.components.query-builder.actions.add-aggregate.title' | translate | async)) || (showAddForm() ? 'Cancel' : 'Add Aggregate')\"\n (onClick)=\"toggleAddForm()\">\n <ax-prefix>\n <ax-icon [icon]=\"showAddForm() ? 'fa-light fa-times' : 'fa-light fa-plus'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <!-- Filters -->\n <div class=\"__filters\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__category-filter\"\n [dataSource]=\"categoriesDataSource()\"\n [ngModel]=\"selectedCategory()\"\n (ngModelChange)=\"selectedCategory.set($event)\"\n textField=\"text\"\n valueField=\"value\"\n [searchable]=\"false\"\n [look]=\"'outline'\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.category-placeholder' | translate | async) || 'Filter by category'\">\n </ax-lookup>\n <ax-search-box\n class=\"__search-filter\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.search-placeholder' | translate | async) || 'Search functions...'\"\n [value]=\"searchText()\"\n (valueChange)=\"searchText.set($event)\">\n </ax-search-box>\n </div>\n\n <!-- Add Form -->\n @if (showAddForm()) {\n <div class=\"__add-form\">\n <div class=\"__form-row\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"newAggregate().function\"\n (ngModelChange)=\"onFunctionChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (newAggregate().function && functionRequiresField(newAggregate().function!)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"newAggregate().field\"\n (ngModelChange)=\"onFieldChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n <ax-text-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().alias\"\n (ngModelChange)=\"onAliasChange($event)\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.alias-placeholder' | translate | async) || 'Alias (optional)'\"\n [type]=\"'text'\">\n </ax-text-box>\n @if (newAggregate().function && functionSupportsDistinct(newAggregate().function!)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().distinct\"\n (ngModelChange)=\"onDistinctChange($event)\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!)) {\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested'\"\n (onClick)=\"addNestedToNewAggregate()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add.title' | translate | async) || 'Add'\"\n (onClick)=\"addAggregate()\">\n </ax-button>\n </div>\n \n <!-- Nested Aggregates for New Aggregate -->\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!) && newAggregate().nestedAggregates && newAggregate().nestedAggregates!.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of newAggregate().nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedFromNewAggregate(ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Aggregate Operations List -->\n <div class=\"__section-body\">\n @if (value().length === 0) {\n <div class=\"__empty-state\">\n <ax-label class=\"__empty-state-text\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.empty-state' | translate | async) || 'No aggregate functions defined. Click \\'Add Aggregate\\' to add aggregation.' }}\n </ax-label>\n </div>\n } @else {\n <div class=\"__aggregate-operations\">\n @for (agg of value(); track $index; let i = $index) {\n <div class=\"__aggregate-operation\">\n <div class=\"__operation-info\">\n <ax-label class=\"__function-name\">\n {{ getFunctionDefinition(agg.function)?.title || agg.function }}(\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n {{ getFunctionDefinition(nested.function)?.title || nested.function }}({{ nested.distinct ? 'DISTINCT ' : '' }}{{ nested.field || '*' }})\n @if (ni < agg.nestedAggregates!.length - 1) {\n <span>, </span>\n }\n }\n } @else {\n {{ agg.distinct ? 'DISTINCT ' : '' }}{{ agg.field || '*' }}\n }\n )\n </ax-label>\n @if (agg.alias) {\n <ax-label class=\"__alias\">AS {{ agg.alias }}</ax-label>\n }\n </div>\n <div class=\"__operation-actions\">\n @if (functionSupportsNested(agg.function) && canAddNestedAggregate(i, getNestingDepth(agg))) {\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'primary'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested Aggregate'\"\n (onClick)=\"addNestedAggregate(i)\">\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeAggregate(i)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n \n <!-- Nested Aggregates Editor -->\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedAggregate(i, ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n", styles: ["@layer properties;.axp-aggregate-builder{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-header{display:flex;align-items:center;justify-content:space-between}.axp-aggregate-builder .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-aggregate-builder .__section-header .__section-actions,.axp-aggregate-builder .__filters{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__filters .__category-filter,.axp-aggregate-builder .__filters .__search-filter{flex:1;min-width:200px}.axp-aggregate-builder .__add-form{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__add-form .__form-row{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__add-form .__form-row .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__empty-state{padding-block:calc(var(--spacing, .25rem) * 8);text-align:center}.axp-aggregate-builder .__section-body .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation{display:flex;align-items:center;justify-content:space-between;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__function-name{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-neutral-900, oklch(20.5% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__alias{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none));font-style:italic}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates{margin-top:calc(var(--spacing, .25rem) * 2);margin-left:calc(var(--spacing, .25rem) * 6);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-neutral-300, oklch(87% 0 none));padding-left:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXLookupComponent, selector: "ax-lookup", inputs: ["name", "mode", "dataSource", "treeDataSource", "valueField", "textField", "disabledField", "columns", "treeParentField", "hasChildrenField", "searchable", "adaptivityEnabled", "caption", "alternate", "searchPlaceholder", "placeholder", "disabled", "readonly", "look", "itemHeight", "maxVisibleItems", "treeSelectionBehavior", "highlightSearch", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "value", "valueItems"], outputs: ["lookChange", "valueChange", "onValueChanged", "onSelectionChanged", "onFocus", "onBlur", "onItemClick", "onItemSelected", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i3$2.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i2.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2720
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPAggregateBuilderComponent, isStandalone: true, selector: "axp-aggregate-builder", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, databaseType: { classPropertyName: "databaseType", publicName: "databaseType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"axp-aggregate-builder\">\n <div class=\"__section-header\">\n <ax-label class=\"__section-title\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.title' | translate | async) || 'Aggregate Functions' }}\n </ax-label>\n <div class=\"__section-actions\">\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"(showAddForm() ? ('@data-management:metadata-definitions.components.query-builder.actions.cancel.title' | translate | async) : ('@data-management:metadata-definitions.components.query-builder.actions.add-aggregate.title' | translate | async)) || (showAddForm() ? 'Cancel' : 'Add Aggregate')\"\n (onClick)=\"toggleAddForm()\">\n <ax-prefix>\n <ax-icon [icon]=\"showAddForm() ? 'fa-light fa-times' : 'fa-light fa-plus'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <!-- Filters -->\n <div class=\"__filters\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__category-filter\"\n [dataSource]=\"categoriesDataSource()\"\n [ngModel]=\"selectedCategory()\"\n (ngModelChange)=\"selectedCategory.set($event)\"\n textField=\"text\"\n valueField=\"value\"\n [searchable]=\"false\"\n [look]=\"'outline'\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.category-placeholder' | translate | async) || 'Filter by category'\">\n </ax-lookup>\n <ax-search-box\n class=\"__search-filter\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.search-placeholder' | translate | async) || 'Search functions...'\"\n [value]=\"searchText()\"\n (valueChange)=\"searchText.set($event)\">\n </ax-search-box>\n </div>\n\n <!-- Add Form -->\n @if (showAddForm()) {\n <div class=\"__add-form\">\n <div class=\"__form-row\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"newAggregate().function\"\n (ngModelChange)=\"onFunctionChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (newAggregate().function && functionRequiresField(newAggregate().function!)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"newAggregate().field\"\n (ngModelChange)=\"onFieldChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n <ax-text-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().alias\"\n (ngModelChange)=\"onAliasChange($event)\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.alias-placeholder' | translate | async) || 'Alias (optional)'\"\n [type]=\"'text'\">\n </ax-text-box>\n @if (newAggregate().function && functionSupportsDistinct(newAggregate().function!)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().distinct\"\n (ngModelChange)=\"onDistinctChange($event)\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!)) {\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested'\"\n (onClick)=\"addNestedToNewAggregate()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add.title' | translate | async) || 'Add'\"\n (onClick)=\"addAggregate()\">\n </ax-button>\n </div>\n \n <!-- Nested Aggregates for New Aggregate -->\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!) && newAggregate().nestedAggregates && newAggregate().nestedAggregates!.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of newAggregate().nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSourceFor(nested.function)\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedFromNewAggregate(ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Aggregate Operations List -->\n <div class=\"__section-body\">\n @if (value().length === 0) {\n <div class=\"__empty-state\">\n <ax-label class=\"__empty-state-text\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.empty-state' | translate | async) || 'No aggregate functions defined. Click \\'Add Aggregate\\' to add aggregation.' }}\n </ax-label>\n </div>\n } @else {\n <div class=\"__aggregate-operations\">\n @for (agg of value(); track $index; let i = $index) {\n <div class=\"__aggregate-operation\">\n <div class=\"__operation-info\">\n <ax-label class=\"__function-name\">\n {{ getFunctionDefinition(agg.function)?.title || agg.function }}(\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n {{ getFunctionDefinition(nested.function)?.title || nested.function }}({{ nested.distinct ? 'DISTINCT ' : '' }}{{ nested.field || '*' }})\n @if (ni < agg.nestedAggregates!.length - 1) {\n <span>, </span>\n }\n }\n } @else {\n {{ agg.distinct ? 'DISTINCT ' : '' }}{{ agg.field || '*' }}\n }\n )\n </ax-label>\n @if (agg.alias) {\n <ax-label class=\"__alias\">AS {{ agg.alias }}</ax-label>\n }\n </div>\n <div class=\"__operation-actions\">\n @if (functionSupportsNested(agg.function) && canAddNestedAggregate(i, getNestingDepth(agg))) {\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'primary'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested Aggregate'\"\n (onClick)=\"addNestedAggregate(i)\">\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeAggregate(i)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n \n <!-- Nested Aggregates Editor -->\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSourceFor(nested.function)\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedAggregate(i, ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n", styles: ["@layer properties;.axp-aggregate-builder{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-header{display:flex;align-items:center;justify-content:space-between}.axp-aggregate-builder .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-aggregate-builder .__section-header .__section-actions,.axp-aggregate-builder .__filters{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__filters .__category-filter,.axp-aggregate-builder .__filters .__search-filter{flex:1;min-width:200px}.axp-aggregate-builder .__add-form{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__add-form .__form-row{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__add-form .__form-row .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__empty-state{padding-block:calc(var(--spacing, .25rem) * 8);text-align:center}.axp-aggregate-builder .__section-body .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation{display:flex;align-items:center;justify-content:space-between;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__function-name{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-neutral-900, oklch(20.5% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__alias{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none));font-style:italic}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates{margin-top:calc(var(--spacing, .25rem) * 2);margin-left:calc(var(--spacing, .25rem) * 6);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-neutral-300, oklch(87% 0 none));padding-left:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXLookupComponent, selector: "ax-lookup", inputs: ["name", "mode", "dataSource", "treeDataSource", "valueField", "textField", "disabledField", "columns", "treeParentField", "hasChildrenField", "searchable", "adaptivityEnabled", "caption", "alternate", "searchPlaceholder", "placeholder", "disabled", "readonly", "look", "itemHeight", "maxVisibleItems", "treeSelectionBehavior", "highlightSearch", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "value", "valueItems"], outputs: ["lookChange", "valueChange", "onValueChanged", "onSelectionChanged", "onFocus", "onBlur", "onItemClick", "onItemSelected", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i3$2.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i2.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2718
2721
|
}
|
|
2719
2722
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAggregateBuilderComponent, decorators: [{
|
|
2720
2723
|
type: Component,
|
|
@@ -2729,7 +2732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2729
2732
|
AXDecoratorModule,
|
|
2730
2733
|
AXCheckBoxModule,
|
|
2731
2734
|
AXTranslationModule,
|
|
2732
|
-
], template: "<div class=\"axp-aggregate-builder\">\n <div class=\"__section-header\">\n <ax-label class=\"__section-title\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.title' | translate | async) || 'Aggregate Functions' }}\n </ax-label>\n <div class=\"__section-actions\">\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"(showAddForm() ? ('@data-management:metadata-definitions.components.query-builder.actions.cancel.title' | translate | async) : ('@data-management:metadata-definitions.components.query-builder.actions.add-aggregate.title' | translate | async)) || (showAddForm() ? 'Cancel' : 'Add Aggregate')\"\n (onClick)=\"toggleAddForm()\">\n <ax-prefix>\n <ax-icon [icon]=\"showAddForm() ? 'fa-light fa-times' : 'fa-light fa-plus'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <!-- Filters -->\n <div class=\"__filters\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__category-filter\"\n [dataSource]=\"categoriesDataSource()\"\n [ngModel]=\"selectedCategory()\"\n (ngModelChange)=\"selectedCategory.set($event)\"\n textField=\"text\"\n valueField=\"value\"\n [searchable]=\"false\"\n [look]=\"'outline'\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.category-placeholder' | translate | async) || 'Filter by category'\">\n </ax-lookup>\n <ax-search-box\n class=\"__search-filter\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.search-placeholder' | translate | async) || 'Search functions...'\"\n [value]=\"searchText()\"\n (valueChange)=\"searchText.set($event)\">\n </ax-search-box>\n </div>\n\n <!-- Add Form -->\n @if (showAddForm()) {\n <div class=\"__add-form\">\n <div class=\"__form-row\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"newAggregate().function\"\n (ngModelChange)=\"onFunctionChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (newAggregate().function && functionRequiresField(newAggregate().function!)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"newAggregate().field\"\n (ngModelChange)=\"onFieldChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n <ax-text-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().alias\"\n (ngModelChange)=\"onAliasChange($event)\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.alias-placeholder' | translate | async) || 'Alias (optional)'\"\n [type]=\"'text'\">\n </ax-text-box>\n @if (newAggregate().function && functionSupportsDistinct(newAggregate().function!)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().distinct\"\n (ngModelChange)=\"onDistinctChange($event)\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!)) {\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested'\"\n (onClick)=\"addNestedToNewAggregate()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add.title' | translate | async) || 'Add'\"\n (onClick)=\"addAggregate()\">\n </ax-button>\n </div>\n \n <!-- Nested Aggregates for New Aggregate -->\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!) && newAggregate().nestedAggregates && newAggregate().nestedAggregates!.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of newAggregate().nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedFromNewAggregate(ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Aggregate Operations List -->\n <div class=\"__section-body\">\n @if (value().length === 0) {\n <div class=\"__empty-state\">\n <ax-label class=\"__empty-state-text\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.empty-state' | translate | async) || 'No aggregate functions defined. Click \\'Add Aggregate\\' to add aggregation.' }}\n </ax-label>\n </div>\n } @else {\n <div class=\"__aggregate-operations\">\n @for (agg of value(); track $index; let i = $index) {\n <div class=\"__aggregate-operation\">\n <div class=\"__operation-info\">\n <ax-label class=\"__function-name\">\n {{ getFunctionDefinition(agg.function)?.title || agg.function }}(\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n {{ getFunctionDefinition(nested.function)?.title || nested.function }}({{ nested.distinct ? 'DISTINCT ' : '' }}{{ nested.field || '*' }})\n @if (ni < agg.nestedAggregates!.length - 1) {\n <span>, </span>\n }\n }\n } @else {\n {{ agg.distinct ? 'DISTINCT ' : '' }}{{ agg.field || '*' }}\n }\n )\n </ax-label>\n @if (agg.alias) {\n <ax-label class=\"__alias\">AS {{ agg.alias }}</ax-label>\n }\n </div>\n <div class=\"__operation-actions\">\n @if (functionSupportsNested(agg.function) && canAddNestedAggregate(i, getNestingDepth(agg))) {\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'primary'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested Aggregate'\"\n (onClick)=\"addNestedAggregate(i)\">\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeAggregate(i)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n \n <!-- Nested Aggregates Editor -->\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedAggregate(i, ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n", styles: ["@layer properties;.axp-aggregate-builder{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-header{display:flex;align-items:center;justify-content:space-between}.axp-aggregate-builder .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-aggregate-builder .__section-header .__section-actions,.axp-aggregate-builder .__filters{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__filters .__category-filter,.axp-aggregate-builder .__filters .__search-filter{flex:1;min-width:200px}.axp-aggregate-builder .__add-form{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__add-form .__form-row{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__add-form .__form-row .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__empty-state{padding-block:calc(var(--spacing, .25rem) * 8);text-align:center}.axp-aggregate-builder .__section-body .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation{display:flex;align-items:center;justify-content:space-between;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__function-name{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-neutral-900, oklch(20.5% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__alias{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none));font-style:italic}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates{margin-top:calc(var(--spacing, .25rem) * 2);margin-left:calc(var(--spacing, .25rem) * 6);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-neutral-300, oklch(87% 0 none));padding-left:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2735
|
+
], template: "<div class=\"axp-aggregate-builder\">\n <div class=\"__section-header\">\n <ax-label class=\"__section-title\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.title' | translate | async) || 'Aggregate Functions' }}\n </ax-label>\n <div class=\"__section-actions\">\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"(showAddForm() ? ('@data-management:metadata-definitions.components.query-builder.actions.cancel.title' | translate | async) : ('@data-management:metadata-definitions.components.query-builder.actions.add-aggregate.title' | translate | async)) || (showAddForm() ? 'Cancel' : 'Add Aggregate')\"\n (onClick)=\"toggleAddForm()\">\n <ax-prefix>\n <ax-icon [icon]=\"showAddForm() ? 'fa-light fa-times' : 'fa-light fa-plus'\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <!-- Filters -->\n <div class=\"__filters\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__category-filter\"\n [dataSource]=\"categoriesDataSource()\"\n [ngModel]=\"selectedCategory()\"\n (ngModelChange)=\"selectedCategory.set($event)\"\n textField=\"text\"\n valueField=\"value\"\n [searchable]=\"false\"\n [look]=\"'outline'\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.category-placeholder' | translate | async) || 'Filter by category'\">\n </ax-lookup>\n <ax-search-box\n class=\"__search-filter\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.search-placeholder' | translate | async) || 'Search functions...'\"\n [value]=\"searchText()\"\n (valueChange)=\"searchText.set($event)\">\n </ax-search-box>\n </div>\n\n <!-- Add Form -->\n @if (showAddForm()) {\n <div class=\"__add-form\">\n <div class=\"__form-row\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"newAggregate().function\"\n (ngModelChange)=\"onFunctionChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (newAggregate().function && functionRequiresField(newAggregate().function!)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSource()\"\n [ngModel]=\"newAggregate().field\"\n (ngModelChange)=\"onFieldChange($event)\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n <ax-text-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().alias\"\n (ngModelChange)=\"onAliasChange($event)\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.alias-placeholder' | translate | async) || 'Alias (optional)'\"\n [type]=\"'text'\">\n </ax-text-box>\n @if (newAggregate().function && functionSupportsDistinct(newAggregate().function!)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"newAggregate().distinct\"\n (ngModelChange)=\"onDistinctChange($event)\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!)) {\n <ax-button\n class=\"ax-sm\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested'\"\n (onClick)=\"addNestedToNewAggregate()\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n [text]=\"('@data-management:metadata-definitions.components.query-builder.actions.add.title' | translate | async) || 'Add'\"\n (onClick)=\"addAggregate()\">\n </ax-button>\n </div>\n \n <!-- Nested Aggregates for New Aggregate -->\n @if (newAggregate().function && functionSupportsNested(newAggregate().function!) && newAggregate().nestedAggregates && newAggregate().nestedAggregates!.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of newAggregate().nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSourceFor(nested.function)\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedInNewAggregate(ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedFromNewAggregate(ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Aggregate Operations List -->\n <div class=\"__section-body\">\n @if (value().length === 0) {\n <div class=\"__empty-state\">\n <ax-label class=\"__empty-state-text\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.empty-state' | translate | async) || 'No aggregate functions defined. Click \\'Add Aggregate\\' to add aggregation.' }}\n </ax-label>\n </div>\n } @else {\n <div class=\"__aggregate-operations\">\n @for (agg of value(); track $index; let i = $index) {\n <div class=\"__aggregate-operation\">\n <div class=\"__operation-info\">\n <ax-label class=\"__function-name\">\n {{ getFunctionDefinition(agg.function)?.title || agg.function }}(\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n {{ getFunctionDefinition(nested.function)?.title || nested.function }}({{ nested.distinct ? 'DISTINCT ' : '' }}{{ nested.field || '*' }})\n @if (ni < agg.nestedAggregates!.length - 1) {\n <span>, </span>\n }\n }\n } @else {\n {{ agg.distinct ? 'DISTINCT ' : '' }}{{ agg.field || '*' }}\n }\n )\n </ax-label>\n @if (agg.alias) {\n <ax-label class=\"__alias\">AS {{ agg.alias }}</ax-label>\n }\n </div>\n <div class=\"__operation-actions\">\n @if (functionSupportsNested(agg.function) && canAddNestedAggregate(i, getNestingDepth(agg))) {\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'primary'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.add-nested.title' | translate | async) || 'Add Nested Aggregate'\"\n (onClick)=\"addNestedAggregate(i)\">\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeAggregate(i)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n \n <!-- Nested Aggregates Editor -->\n @if (agg.nestedAggregates && agg.nestedAggregates.length > 0) {\n <div class=\"__nested-aggregates\">\n @for (nested of agg.nestedAggregates; track $index; let ni = $index) {\n <div class=\"__nested-aggregate\">\n <div class=\"__nested-form\">\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"functionsDataSource()\"\n [ngModel]=\"nested.function\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { function: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.function-placeholder' | translate | async) || 'Select function'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n @if (nested.function && functionRequiresField(nested.function)) {\n <ax-lookup\n mode=\"drop-down-list\"\n class=\"__form-field\"\n [dataSource]=\"columnsDataSourceFor(nested.function)\"\n [ngModel]=\"nested.field\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { field: $event })\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.aggregate.field-placeholder' | translate | async) || 'Select field'\"\n textField=\"text\"\n valueField=\"value\"\n [look]=\"'outline'\">\n </ax-lookup>\n }\n @if (nested.function && functionSupportsDistinct(nested.function)) {\n <ax-check-box\n class=\"__form-field\"\n [ngModel]=\"nested.distinct\"\n (ngModelChange)=\"updateNestedAggregate(i, ni, { distinct: $event })\">\n <ax-label>\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.aggregate.distinct-label' | translate | async) || 'DISTINCT' }}\n </ax-label>\n </ax-check-box>\n }\n <ax-button\n class=\"ax-sm __icon-btn\"\n [look]=\"'blank'\"\n [color]=\"'danger'\"\n [title]=\"('@data-management:metadata-definitions.components.query-builder.actions.remove.title' | translate | async) || 'Remove'\"\n (onClick)=\"removeNestedAggregate(i, ni)\">\n <ax-icon icon=\"fa-light fa-trash-can\"></ax-icon>\n </ax-button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n", styles: ["@layer properties;.axp-aggregate-builder{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-header{display:flex;align-items:center;justify-content:space-between}.axp-aggregate-builder .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-aggregate-builder .__section-header .__section-actions,.axp-aggregate-builder .__filters{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__filters .__category-filter,.axp-aggregate-builder .__filters .__search-filter{flex:1;min-width:200px}.axp-aggregate-builder .__add-form{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__add-form .__form-row{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__add-form .__form-row .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__empty-state{padding-block:calc(var(--spacing, .25rem) * 8);text-align:center}.axp-aggregate-builder .__section-body .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation{display:flex;align-items:center;justify-content:space-between;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-50, oklch(98.5% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info{display:flex;flex:1;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__function-name{font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-neutral-900, oklch(20.5% 0 none))}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-info .__alias{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none));font-style:italic}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}.axp-aggregate-builder .__section-body .__aggregate-operations .__aggregate-operation .__operation-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates{margin-top:calc(var(--spacing, .25rem) * 2);margin-left:calc(var(--spacing, .25rem) * 6);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-left-style:var(--tw-border-style);border-left-width:2px;border-color:var(--color-neutral-300, oklch(87% 0 none));padding-left:calc(var(--spacing, .25rem) * 4)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-neutral-200, oklch(92.2% 0 none));background-color:var(--color-neutral-100, oklch(97% 0 none));padding:calc(var(--spacing, .25rem) * 3)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form{display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__form-field{flex:1;min-width:150px}.axp-aggregate-builder .__section-body .__aggregate-operations .__nested-aggregates .__nested-aggregate .__nested-form .__icon-btn{flex-shrink:0;width:2rem;height:2rem;padding:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2733
2736
|
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], databaseType: [{ type: i0.Input, args: [{ isSignal: true, alias: "databaseType", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
2734
2737
|
|
|
2735
2738
|
/**
|
|
@@ -3685,6 +3688,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
3685
3688
|
], template: "<div class=\"axp-output-builder\">\n <div class=\"__section\">\n <ax-label class=\"__section-title\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.output.title' | translate | async) || 'Output Type' }}\n </ax-label>\n <ax-label class=\"__section-description\">\n {{ ('@data-management:metadata-definitions.components.query-builder.sections.output.description' | translate | async) || 'Select the expected structure of the query result' }}\n </ax-label>\n </div>\n\n <div class=\"__content\">\n <ax-combo-box\n [ngModel]=\"internalValue()\"\n (ngModelChange)=\"onOutputTypeChange($event)\"\n [items]=\"outputTypeItems\"\n [searchable]=\"false\"\n [placeholder]=\"('@data-management:metadata-definitions.components.query-builder.sections.output.placeholder' | translate | async) || 'Select output type'\">\n </ax-combo-box>\n </div>\n</div>\n", styles: ["@layer properties;.axp-output-builder{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.axp-output-builder .__section{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.axp-output-builder .__section .__section-title{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-output-builder .__section .__section-description{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--ax-color-text-secondary)}.axp-output-builder .__content{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3686
3689
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
3687
3690
|
|
|
3691
|
+
//#region ----- Imports -----
|
|
3692
|
+
//#endregion
|
|
3693
|
+
//#region ----- Visible tabs -----
|
|
3694
|
+
const AXP_QUERY_BUILDER_TABS = [
|
|
3695
|
+
'columns',
|
|
3696
|
+
'where',
|
|
3697
|
+
'sort',
|
|
3698
|
+
'group-by',
|
|
3699
|
+
'aggregate',
|
|
3700
|
+
'output',
|
|
3701
|
+
'raw',
|
|
3702
|
+
];
|
|
3703
|
+
//#endregion
|
|
3704
|
+
|
|
3688
3705
|
//#region ---- Types ----
|
|
3689
3706
|
//#endregion
|
|
3690
3707
|
/**
|
|
@@ -3737,6 +3754,11 @@ class AXPQueryBuilderComponent {
|
|
|
3737
3754
|
*/
|
|
3738
3755
|
this.dataSourceDefinition = input(undefined, /* @ts-ignore */
|
|
3739
3756
|
...(ngDevMode ? [{ debugName: "dataSourceDefinition" }] : /* istanbul ignore next */ []));
|
|
3757
|
+
/**
|
|
3758
|
+
* Tabs to show. Omit or empty → all tabs (full builder).
|
|
3759
|
+
*/
|
|
3760
|
+
this.visibleTabs = input(undefined, /* @ts-ignore */
|
|
3761
|
+
...(ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []));
|
|
3740
3762
|
/**
|
|
3741
3763
|
* Emitted when query structure changes
|
|
3742
3764
|
*/
|
|
@@ -3768,7 +3790,7 @@ class AXPQueryBuilderComponent {
|
|
|
3768
3790
|
queryLanguage: 'mysql',
|
|
3769
3791
|
}, /* @ts-ignore */
|
|
3770
3792
|
...(ngDevMode ? [{ debugName: "queryData" }] : /* istanbul ignore next */ []));
|
|
3771
|
-
this.activeTab = signal(
|
|
3793
|
+
this.activeTab = signal('columns', /* @ts-ignore */
|
|
3772
3794
|
...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
3773
3795
|
this.isRawMode = signal(false, /* @ts-ignore */
|
|
3774
3796
|
...(ngDevMode ? [{ debugName: "isRawMode" }] : /* istanbul ignore next */ []));
|
|
@@ -3790,6 +3812,16 @@ class AXPQueryBuilderComponent {
|
|
|
3790
3812
|
return def?.filters || [];
|
|
3791
3813
|
}, /* @ts-ignore */
|
|
3792
3814
|
...(ngDevMode ? [{ debugName: "filterDefinitions" }] : /* istanbul ignore next */ []));
|
|
3815
|
+
this.resolvedTabs = computed(() => {
|
|
3816
|
+
const requested = this.visibleTabs();
|
|
3817
|
+
if (!requested?.length) {
|
|
3818
|
+
return [...AXP_QUERY_BUILDER_TABS];
|
|
3819
|
+
}
|
|
3820
|
+
const allowed = new Set(requested);
|
|
3821
|
+
const tabs = AXP_QUERY_BUILDER_TABS.filter((tab) => allowed.has(tab));
|
|
3822
|
+
return tabs.length ? tabs : [...AXP_QUERY_BUILDER_TABS];
|
|
3823
|
+
}, /* @ts-ignore */
|
|
3824
|
+
...(ngDevMode ? [{ debugName: "resolvedTabs" }] : /* istanbul ignore next */ []));
|
|
3793
3825
|
/**
|
|
3794
3826
|
* Validation warnings/errors for query builder
|
|
3795
3827
|
*/
|
|
@@ -3799,16 +3831,16 @@ class AXPQueryBuilderComponent {
|
|
|
3799
3831
|
// Check aggregate functions usage
|
|
3800
3832
|
const hasAggregates = data.aggregates && data.aggregates.length > 0;
|
|
3801
3833
|
const hasGroupBy = data.groupBy && data.groupBy.length > 0;
|
|
3802
|
-
|
|
3803
|
-
|
|
3834
|
+
const tabs = this.resolvedTabs();
|
|
3835
|
+
const showsGroupBy = tabs.includes('group-by');
|
|
3836
|
+
const showsColumns = tabs.includes('columns');
|
|
3837
|
+
if (showsGroupBy && hasAggregates && !hasGroupBy) {
|
|
3804
3838
|
warnings.push('@data-management:metadata-definitions.components.query-builder.validation.aggregate-without-group-by');
|
|
3805
3839
|
}
|
|
3806
|
-
|
|
3807
|
-
if (hasGroupBy && !hasAggregates) {
|
|
3840
|
+
if (showsGroupBy && hasGroupBy && !hasAggregates) {
|
|
3808
3841
|
warnings.push('@data-management:metadata-definitions.components.query-builder.validation.group-by-without-aggregate');
|
|
3809
3842
|
}
|
|
3810
|
-
|
|
3811
|
-
if (hasAggregates && data.columns.length > 0 && !hasGroupBy) {
|
|
3843
|
+
if (showsGroupBy && showsColumns && hasAggregates && data.columns.length > 0 && !hasGroupBy) {
|
|
3812
3844
|
warnings.push('@data-management:metadata-definitions.components.query-builder.validation.aggregate-columns-warning');
|
|
3813
3845
|
}
|
|
3814
3846
|
return warnings;
|
|
@@ -3837,11 +3869,17 @@ class AXPQueryBuilderComponent {
|
|
|
3837
3869
|
});
|
|
3838
3870
|
// Track last generated SQL to prevent infinite loops
|
|
3839
3871
|
let lastGeneratedSql = '';
|
|
3872
|
+
effect(() => {
|
|
3873
|
+
const first = this.resolvedTabs()[0];
|
|
3874
|
+
if (first && !this.resolvedTabs().includes(untracked(() => this.activeTab()))) {
|
|
3875
|
+
untracked(() => this.activeTab.set(first));
|
|
3876
|
+
}
|
|
3877
|
+
});
|
|
3840
3878
|
// Watch for tab changes to sync raw query
|
|
3841
3879
|
effect(() => {
|
|
3842
3880
|
const tab = this.activeTab();
|
|
3843
3881
|
// When switching to RAW tab, generate SQL from structured query
|
|
3844
|
-
if (tab ===
|
|
3882
|
+
if (tab === 'raw') {
|
|
3845
3883
|
const data = untracked(() => this.queryData());
|
|
3846
3884
|
const isRaw = untracked(() => this.isRawMode());
|
|
3847
3885
|
// Always regenerate SQL when switching to RAW tab (unless in raw mode)
|
|
@@ -3857,7 +3895,7 @@ class AXPQueryBuilderComponent {
|
|
|
3857
3895
|
}
|
|
3858
3896
|
}
|
|
3859
3897
|
// When switching away from RAW tab, reset raw mode flag
|
|
3860
|
-
if (tab !==
|
|
3898
|
+
if (tab !== 'raw') {
|
|
3861
3899
|
const isRaw = untracked(() => this.isRawMode());
|
|
3862
3900
|
if (isRaw) {
|
|
3863
3901
|
untracked(() => {
|
|
@@ -3904,6 +3942,15 @@ class AXPQueryBuilderComponent {
|
|
|
3904
3942
|
}
|
|
3905
3943
|
//#endregion
|
|
3906
3944
|
//#region ---- Public Methods ----
|
|
3945
|
+
onActiveTabChanged(index) {
|
|
3946
|
+
const tab = this.resolvedTabs()[index];
|
|
3947
|
+
if (tab) {
|
|
3948
|
+
this.activeTab.set(tab);
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
tabTitleKey(tab) {
|
|
3952
|
+
return `@data-management:metadata-definitions.components.query-builder.tabs.${tab === 'group-by' ? 'group-by' : tab}.title`;
|
|
3953
|
+
}
|
|
3907
3954
|
/**
|
|
3908
3955
|
* Update columns selection
|
|
3909
3956
|
*/
|
|
@@ -4006,7 +4053,7 @@ class AXPQueryBuilderComponent {
|
|
|
4006
4053
|
this.valueChange.emit(currentData);
|
|
4007
4054
|
}
|
|
4008
4055
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQueryBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4009
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQueryBuilderComponent, isStandalone: true, selector: "axp-query-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, dataSourceDefinition: { classPropertyName: "dataSourceDefinition", publicName: "dataSourceDefinition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"axp-query-builder\">\n <ax-tabs [look]=\"'with-line'\" (onActiveTabChanged)=\"
|
|
4056
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPQueryBuilderComponent, isStandalone: true, selector: "axp-query-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, dataSourceDefinition: { classPropertyName: "dataSourceDefinition", publicName: "dataSourceDefinition", isSignal: true, isRequired: false, transformFunction: null }, visibleTabs: { classPropertyName: "visibleTabs", publicName: "visibleTabs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"axp-query-builder\">\n <ax-tabs [look]=\"'with-line'\" (onActiveTabChanged)=\"onActiveTabChanged($event.index)\">\n @for (tab of resolvedTabs(); track tab) {\n <ax-tab-item [text]=\"(tabTitleKey(tab) | translate | async) || tab\">\n </ax-tab-item>\n }\n </ax-tabs>\n\n <!-- ----- Validation warnings for incompatible tab combinations ----- -->\n @if (validationWarnings().length > 0) {\n <div class=\"__validation-warnings\">\n @for (warning of validationWarnings(); track $index) {\n <div class=\"__warning-item\">\n <ax-label class=\"__warning-text\">\n <ax-icon icon=\"fa-light fa-circle-exclamation\" class=\"text-warning-500\"></ax-icon>\n {{ (warning | translate | async) || warning }}\n </ax-label>\n </div>\n }\n </div>\n }\n\n <div class=\"__content\">\n <!-- ----- Selected result columns ----- -->\n @if (activeTab() === 'columns') {\n <axp-columns-builder\n [columns]=\"columns()\"\n [value]=\"queryData().columns\"\n (valueChange)=\"onColumnsChange($event)\">\n </axp-columns-builder>\n }\n\n <!-- ----- Frozen or parametric WHERE clauses ----- -->\n @if (activeTab() === 'where') {\n <axp-where-builder\n [value]=\"queryData().where\"\n [filterDefinitions]=\"filterDefinitions()\"\n (valueChange)=\"onWhereChange($event)\">\n </axp-where-builder>\n }\n\n <!-- ----- Sort rules ----- -->\n @if (activeTab() === 'sort') {\n <axp-sort-builder\n [columns]=\"columns()\"\n [value]=\"queryData().sort\"\n (valueChange)=\"onSortChange($event)\">\n </axp-sort-builder>\n }\n\n <!-- ----- Group-by columns ----- -->\n @if (activeTab() === 'group-by') {\n <axp-group-by-builder\n [columns]=\"columns()\"\n [value]=\"queryData().groupBy\"\n (valueChange)=\"onGroupByChange($event)\">\n </axp-group-by-builder>\n }\n\n <!-- ----- Aggregate measures ----- -->\n @if (activeTab() === 'aggregate') {\n <axp-aggregate-builder\n [columns]=\"columns()\"\n [value]=\"queryData().aggregates\"\n (valueChange)=\"onAggregatesChange($event)\">\n </axp-aggregate-builder>\n }\n\n <!-- ----- Output type ----- -->\n @if (activeTab() === 'output') {\n <axp-output-builder\n [value]=\"queryData().outputType\"\n (valueChange)=\"onOutputTypeChange($event)\">\n </axp-output-builder>\n }\n\n <!-- ----- Raw SQL / dialect ----- -->\n @if (activeTab() === 'raw') {\n <axp-raw-query-builder\n [value]=\"queryData().rawQuery || ''\"\n [queryLanguage]=\"queryData().queryLanguage || 'mysql'\"\n (valueChange)=\"onRawQueryChange($event)\"\n (queryLanguageChange)=\"onQueryLanguageChange($event)\">\n </axp-raw-query-builder>\n }\n </div>\n</div>\n", styles: ["@layer properties;.axp-query-builder{display:flex;height:100%;width:100%;flex-direction:column}.axp-query-builder .__content{flex:1;overflow:auto;padding:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section .__section-header{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-query-builder .__section .__section-header .__section-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-query-builder .__section .__section-body,.axp-query-builder .__sort-rules{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}.axp-query-builder .__sort-rules .__sort-rule{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.axp-query-builder .__sort-rules .__sort-rule .__sort-field{flex:1}.axp-query-builder .__sort-rules .__sort-rule .__sort-direction{width:calc(var(--spacing, .25rem) * 32)}.axp-query-builder .__sort-rules .__sort-rule .__icon-btn{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;flex-shrink:0}.axp-query-builder .__validation-warnings{margin:calc(var(--spacing, .25rem) * 4);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-warning-200));background-color:rgba(var(--ax-sys-color-warning-50));padding:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__validation-warnings .__warning-item{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-query-builder .__validation-warnings .__warning-item .__warning-text{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-warning-700))}.axp-query-builder .__empty-state{display:flex;align-items:center;justify-content:center;padding-block:calc(var(--spacing, .25rem) * 8)}.axp-query-builder .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i1$1.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i1$1.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXPWhereBuilderComponent, selector: "axp-where-builder", inputs: ["value", "filterDefinitions"], outputs: ["valueChange"] }, { kind: "component", type: AXPColumnsBuilderComponent, selector: "axp-columns-builder", inputs: ["columns", "value"], outputs: ["valueChange"] }, { kind: "component", type: AXPSortBuilderComponent, selector: "axp-sort-builder", inputs: ["columns", "value"], outputs: ["valueChange"] }, { kind: "component", type: AXPGroupByBuilderComponent, selector: "axp-group-by-builder", inputs: ["columns", "value"], outputs: ["valueChange"] }, { kind: "component", type: AXPAggregateBuilderComponent, selector: "axp-aggregate-builder", inputs: ["columns", "value", "databaseType"], outputs: ["valueChange"] }, { kind: "component", type: AXPRawQueryBuilderComponent, selector: "axp-raw-query-builder", inputs: ["value", "queryLanguage"], outputs: ["valueChange", "queryLanguageChange"] }, { kind: "component", type: AXPOutputBuilderComponent, selector: "axp-output-builder", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4010
4057
|
}
|
|
4011
4058
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQueryBuilderComponent, decorators: [{
|
|
4012
4059
|
type: Component,
|
|
@@ -4023,8 +4070,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
4023
4070
|
AXPRawQueryBuilderComponent,
|
|
4024
4071
|
AXPOutputBuilderComponent,
|
|
4025
4072
|
AXTranslationModule,
|
|
4026
|
-
], template: "<div class=\"axp-query-builder\">\n <ax-tabs [look]=\"'with-line'\" (onActiveTabChanged)=\"
|
|
4027
|
-
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], dataSourceDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSourceDefinition", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
4073
|
+
], template: "<div class=\"axp-query-builder\">\n <ax-tabs [look]=\"'with-line'\" (onActiveTabChanged)=\"onActiveTabChanged($event.index)\">\n @for (tab of resolvedTabs(); track tab) {\n <ax-tab-item [text]=\"(tabTitleKey(tab) | translate | async) || tab\">\n </ax-tab-item>\n }\n </ax-tabs>\n\n <!-- ----- Validation warnings for incompatible tab combinations ----- -->\n @if (validationWarnings().length > 0) {\n <div class=\"__validation-warnings\">\n @for (warning of validationWarnings(); track $index) {\n <div class=\"__warning-item\">\n <ax-label class=\"__warning-text\">\n <ax-icon icon=\"fa-light fa-circle-exclamation\" class=\"text-warning-500\"></ax-icon>\n {{ (warning | translate | async) || warning }}\n </ax-label>\n </div>\n }\n </div>\n }\n\n <div class=\"__content\">\n <!-- ----- Selected result columns ----- -->\n @if (activeTab() === 'columns') {\n <axp-columns-builder\n [columns]=\"columns()\"\n [value]=\"queryData().columns\"\n (valueChange)=\"onColumnsChange($event)\">\n </axp-columns-builder>\n }\n\n <!-- ----- Frozen or parametric WHERE clauses ----- -->\n @if (activeTab() === 'where') {\n <axp-where-builder\n [value]=\"queryData().where\"\n [filterDefinitions]=\"filterDefinitions()\"\n (valueChange)=\"onWhereChange($event)\">\n </axp-where-builder>\n }\n\n <!-- ----- Sort rules ----- -->\n @if (activeTab() === 'sort') {\n <axp-sort-builder\n [columns]=\"columns()\"\n [value]=\"queryData().sort\"\n (valueChange)=\"onSortChange($event)\">\n </axp-sort-builder>\n }\n\n <!-- ----- Group-by columns ----- -->\n @if (activeTab() === 'group-by') {\n <axp-group-by-builder\n [columns]=\"columns()\"\n [value]=\"queryData().groupBy\"\n (valueChange)=\"onGroupByChange($event)\">\n </axp-group-by-builder>\n }\n\n <!-- ----- Aggregate measures ----- -->\n @if (activeTab() === 'aggregate') {\n <axp-aggregate-builder\n [columns]=\"columns()\"\n [value]=\"queryData().aggregates\"\n (valueChange)=\"onAggregatesChange($event)\">\n </axp-aggregate-builder>\n }\n\n <!-- ----- Output type ----- -->\n @if (activeTab() === 'output') {\n <axp-output-builder\n [value]=\"queryData().outputType\"\n (valueChange)=\"onOutputTypeChange($event)\">\n </axp-output-builder>\n }\n\n <!-- ----- Raw SQL / dialect ----- -->\n @if (activeTab() === 'raw') {\n <axp-raw-query-builder\n [value]=\"queryData().rawQuery || ''\"\n [queryLanguage]=\"queryData().queryLanguage || 'mysql'\"\n (valueChange)=\"onRawQueryChange($event)\"\n (queryLanguageChange)=\"onQueryLanguageChange($event)\">\n </axp-raw-query-builder>\n }\n </div>\n</div>\n", styles: ["@layer properties;.axp-query-builder{display:flex;height:100%;width:100%;flex-direction:column}.axp-query-builder .__content{flex:1;overflow:auto;padding:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section .__section-header{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__section .__section-header .__section-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.axp-query-builder .__section .__section-header .__section-actions{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-query-builder .__section .__section-body,.axp-query-builder .__sort-rules{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}.axp-query-builder .__sort-rules .__sort-rule{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.axp-query-builder .__sort-rules .__sort-rule .__sort-field{flex:1}.axp-query-builder .__sort-rules .__sort-rule .__sort-direction{width:calc(var(--spacing, .25rem) * 32)}.axp-query-builder .__sort-rules .__sort-rule .__icon-btn{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;flex-shrink:0}.axp-query-builder .__validation-warnings{margin:calc(var(--spacing, .25rem) * 4);display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:rgba(var(--ax-sys-color-warning-200));background-color:rgba(var(--ax-sys-color-warning-50));padding:calc(var(--spacing, .25rem) * 4)}.axp-query-builder .__validation-warnings .__warning-item{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.axp-query-builder .__validation-warnings .__warning-item .__warning-text{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-warning-700))}.axp-query-builder .__empty-state{display:flex;align-items:center;justify-content:center;padding-block:calc(var(--spacing, .25rem) * 8)}.axp-query-builder .__empty-state .__empty-state-text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-neutral-600, oklch(43.9% 0 none))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
4074
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], dataSourceDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSourceDefinition", required: false }] }], visibleTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleTabs", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
4028
4075
|
|
|
4029
4076
|
//#region ---- Types ----
|
|
4030
4077
|
// Uses AXPQueryBuilderData as root query data type
|
|
@@ -4064,6 +4111,11 @@ class AXPQueryBuilderWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
4064
4111
|
* Get datasource definition from options (passed from entity context)
|
|
4065
4112
|
* The entity passes the selected datasource definition via context
|
|
4066
4113
|
*/
|
|
4114
|
+
this.visibleTabs = computed(() => {
|
|
4115
|
+
const tabs = this.options()['visibleTabs'];
|
|
4116
|
+
return Array.isArray(tabs) ? tabs : undefined;
|
|
4117
|
+
}, /* @ts-ignore */
|
|
4118
|
+
...(ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []));
|
|
4067
4119
|
this.dataSourceDefinition = computed(() => {
|
|
4068
4120
|
const options = this.options();
|
|
4069
4121
|
// Try to get datasource definition from options
|
|
@@ -4092,9 +4144,10 @@ class AXPQueryBuilderWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
4092
4144
|
<axp-query-builder
|
|
4093
4145
|
[value]="getValue() || defaultQueryData"
|
|
4094
4146
|
[dataSourceDefinition]="dataSourceDefinition()"
|
|
4147
|
+
[visibleTabs]="visibleTabs()"
|
|
4095
4148
|
(valueChange)="onValueChange($event)">
|
|
4096
4149
|
</axp-query-builder>
|
|
4097
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AXPQueryBuilderComponent, selector: "axp-query-builder", inputs: ["value", "dataSourceDefinition"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4150
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AXPQueryBuilderComponent, selector: "axp-query-builder", inputs: ["value", "dataSourceDefinition", "visibleTabs"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4098
4151
|
}
|
|
4099
4152
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPQueryBuilderWidgetEditComponent, decorators: [{
|
|
4100
4153
|
type: Component,
|
|
@@ -4104,6 +4157,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
4104
4157
|
<axp-query-builder
|
|
4105
4158
|
[value]="getValue() || defaultQueryData"
|
|
4106
4159
|
[dataSourceDefinition]="dataSourceDefinition()"
|
|
4160
|
+
[visibleTabs]="visibleTabs()"
|
|
4107
4161
|
(valueChange)="onValueChange($event)">
|
|
4108
4162
|
</axp-query-builder>
|
|
4109
4163
|
`,
|
|
@@ -4409,9 +4463,6 @@ var queryBuilderWidgetDesigner_component = /*#__PURE__*/Object.freeze({
|
|
|
4409
4463
|
AXPQueryBuilderWidgetDesignerComponent: AXPQueryBuilderWidgetDesignerComponent
|
|
4410
4464
|
});
|
|
4411
4465
|
|
|
4412
|
-
//#region ----- Imports -----
|
|
4413
|
-
//#endregion
|
|
4414
|
-
|
|
4415
4466
|
/**
|
|
4416
4467
|
* Default Database Type Provider
|
|
4417
4468
|
*
|
|
@@ -8226,12 +8277,6 @@ class AXMDataManagementModule {
|
|
|
8226
8277
|
loader: () => import('./acorex-platform-module-data-management-client-list-availability-options.query-CdaHTgij.mjs').then((c) => c.AXMListAvailabilityOptionsQuery),
|
|
8227
8278
|
},
|
|
8228
8279
|
]),
|
|
8229
|
-
// Module Manifest Provider
|
|
8230
|
-
{
|
|
8231
|
-
provide: AXP_MODULE_MANIFEST_PROVIDER,
|
|
8232
|
-
useValue: DataManagementManifest,
|
|
8233
|
-
multi: true,
|
|
8234
|
-
},
|
|
8235
8280
|
// Provider references (now using tokens)
|
|
8236
8281
|
{
|
|
8237
8282
|
provide: AXP_FEATURE_DEFINITION_PROVIDER,
|
|
@@ -8360,12 +8405,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
8360
8405
|
loader: () => import('./acorex-platform-module-data-management-client-list-availability-options.query-CdaHTgij.mjs').then((c) => c.AXMListAvailabilityOptionsQuery),
|
|
8361
8406
|
},
|
|
8362
8407
|
]),
|
|
8363
|
-
// Module Manifest Provider
|
|
8364
|
-
{
|
|
8365
|
-
provide: AXP_MODULE_MANIFEST_PROVIDER,
|
|
8366
|
-
useValue: DataManagementManifest,
|
|
8367
|
-
multi: true,
|
|
8368
|
-
},
|
|
8369
8408
|
// Provider references (now using tokens)
|
|
8370
8409
|
{
|
|
8371
8410
|
provide: AXP_FEATURE_DEFINITION_PROVIDER,
|
|
@@ -8396,5 +8435,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
8396
8435
|
* Generated bundle index. Do not edit.
|
|
8397
8436
|
*/
|
|
8398
8437
|
|
|
8399
|
-
export { AXMDataManagementModule, AXMDefaultAggregateCategoryProvider, AXMDefaultAggregateFunctionProvider, AXMDefaultDatabaseTypeProvider, AXMDefaultMetaDataBuilderRecordService, AXMMenuProvider, AXMMetaDataBuilderRecordService, AXMMetaDataFeatureModule, AXMMetadataEvaluatorScopeProvider, AXMQueryService, AXMTagsFeatureModule, AXMetaDataConfiguratorComponent, AXPAggregateBuilderComponent, AXPAggregateFunctionService, AXPAggregateFunctionsRegistry, AXPColumnsBuilderComponent, AXPDatabaseTypeService, AXPGroupByBuilderComponent, AXPMetaDataBuilderGroupsComponent, AXPMetaDataBuilderWidget, AXPMetaDataBuilderWidgetEditComponent, AXPMetaDataBuilderWidgetViewComponent, AXPMetaDataFormWidget, AXPMetaDataFormWidgetEditComponent, AXPQueryBuilderComponent, AXPQueryBuilderWidget, AXPQueryBuilderWidgetColumnComponent, AXPQueryBuilderWidgetDesignerComponent, AXPQueryBuilderWidgetEditComponent, AXPQueryBuilderWidgetViewComponent, AXPRawQueryBuilderComponent, AXPSortBuilderComponent, AXPSystemTagProvider, AXPWhereBuilderComponent, AXP_AGGREGATE_CATEGORY_PROVIDER, AXP_AGGREGATE_FUNCTION_PROVIDER, AXP_DATABASE_TYPE_PROVIDER, AXP_DEFAULT_AGGREGATE_CATEGORY_PROVIDER, AXP_DEFAULT_AGGREGATE_FUNCTION_PROVIDER, AXP_DEFAULT_DATABASE_TYPE_PROVIDER, ExecuteQueryCommand, META_DATA_BUILDER_PAGE_COMPONENT_KEY, META_DATA_FORM_FIELD, META_DATA_SELECTOR_FIELD, ShowMetaDataBuilderPopupCommand, ShowMetaDataFormPopupCommand, builderValueToMetaDataValue, metaDataBuilderPlugin, metaDataValueToBuilderValue, tagsPlugin };
|
|
8438
|
+
export { AXMDataManagementModule, AXMDefaultAggregateCategoryProvider, AXMDefaultAggregateFunctionProvider, AXMDefaultDatabaseTypeProvider, AXMDefaultMetaDataBuilderRecordService, AXMMenuProvider, AXMMetaDataBuilderRecordService, AXMMetaDataFeatureModule, AXMMetadataEvaluatorScopeProvider, AXMQueryService, AXMTagsFeatureModule, AXMetaDataConfiguratorComponent, AXPAggregateBuilderComponent, AXPAggregateFunctionService, AXPAggregateFunctionsRegistry, AXPColumnsBuilderComponent, AXPDatabaseTypeService, AXPGroupByBuilderComponent, AXPMetaDataBuilderGroupsComponent, AXPMetaDataBuilderWidget, AXPMetaDataBuilderWidgetEditComponent, AXPMetaDataBuilderWidgetViewComponent, AXPMetaDataFormWidget, AXPMetaDataFormWidgetEditComponent, AXPQueryBuilderComponent, AXPQueryBuilderWidget, AXPQueryBuilderWidgetColumnComponent, AXPQueryBuilderWidgetDesignerComponent, AXPQueryBuilderWidgetEditComponent, AXPQueryBuilderWidgetViewComponent, AXPRawQueryBuilderComponent, AXPSortBuilderComponent, AXPSystemTagProvider, AXPWhereBuilderComponent, AXP_AGGREGATE_CATEGORY_PROVIDER, AXP_AGGREGATE_FUNCTION_PROVIDER, AXP_DATABASE_TYPE_PROVIDER, AXP_DEFAULT_AGGREGATE_CATEGORY_PROVIDER, AXP_DEFAULT_AGGREGATE_FUNCTION_PROVIDER, AXP_DEFAULT_DATABASE_TYPE_PROVIDER, AXP_QUERY_BUILDER_TABS, ExecuteQueryCommand, META_DATA_BUILDER_PAGE_COMPONENT_KEY, META_DATA_FORM_FIELD, META_DATA_SELECTOR_FIELD, ShowMetaDataBuilderPopupCommand, ShowMetaDataFormPopupCommand, builderValueToMetaDataValue, metaDataBuilderPlugin, metaDataValueToBuilderValue, tagsPlugin };
|
|
8400
8439
|
//# sourceMappingURL=acorex-platform-module-data-management-client.mjs.map
|