@masterteam/dashboard-builder 0.0.14 → 0.0.16
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/assets/dashboard-builder.css +1 -1
- package/assets/i18n/ar.json +53 -42
- package/assets/i18n/en.json +23 -12
- package/fesm2022/{masterteam-dashboard-builder-dashboard-dialog.component-CF1Lnyxf.mjs → masterteam-dashboard-builder-dashboard-dialog.component-CMNlOHiK.mjs} +3 -4
- package/fesm2022/masterteam-dashboard-builder-dashboard-dialog.component-CMNlOHiK.mjs.map +1 -0
- package/fesm2022/masterteam-dashboard-builder.mjs +809 -285
- package/fesm2022/masterteam-dashboard-builder.mjs.map +1 -1
- package/package.json +3 -3
- package/types/masterteam-dashboard-builder.d.ts +244 -123
- package/fesm2022/masterteam-dashboard-builder-dashboard-dialog.component-CF1Lnyxf.mjs.map +0 -1
|
@@ -8,12 +8,8 @@ import { TranslocoService, TranslocoDirective } from '@jsverse/transloco';
|
|
|
8
8
|
import * as i2$2 from 'angular-gridster2';
|
|
9
9
|
import { GridsterModule } from 'angular-gridster2';
|
|
10
10
|
import { Button } from '@masterteam/components/button';
|
|
11
|
-
import { Tabs } from '@masterteam/components/tabs';
|
|
12
|
-
import { Card } from '@masterteam/components/card';
|
|
13
|
-
import { Tooltip } from '@masterteam/components/tooltip';
|
|
14
11
|
import { ModalService } from '@masterteam/components/modal';
|
|
15
12
|
import { Page } from '@masterteam/components/page';
|
|
16
|
-
import { Menu } from '@masterteam/components/menu';
|
|
17
13
|
import * as i3$1 from 'primeng/contextmenu';
|
|
18
14
|
import { ContextMenuModule } from 'primeng/contextmenu';
|
|
19
15
|
import * as i5 from 'primeng/popover';
|
|
@@ -30,14 +26,16 @@ import { NumberField } from '@masterteam/components/number-field';
|
|
|
30
26
|
import { TextareaField } from '@masterteam/components/textarea-field';
|
|
31
27
|
import { DynamicDialogRef, DynamicDialogConfig } from 'primeng/dynamicdialog';
|
|
32
28
|
import { DynamicDrawerConfig } from '@masterteam/components/dynamic-drawer';
|
|
29
|
+
import { Tabs } from '@masterteam/components/tabs';
|
|
33
30
|
import { catchError, tap, map as map$1, filter, distinctUntilChanged, share, groupBy as groupBy$1, mergeMap, debounceTime, retry, finalize, shareReplay, takeUntil } from 'rxjs/operators';
|
|
34
31
|
import { MultiSelectField } from '@masterteam/components/multi-select-field';
|
|
35
32
|
import { ColorPickerField } from '@masterteam/components/color-picker-field';
|
|
36
33
|
import { SliderField } from '@masterteam/components/slider-field';
|
|
37
34
|
import { ToggleField } from '@masterteam/components/toggle-field';
|
|
38
35
|
import { IconField } from '@masterteam/components/icon-field';
|
|
36
|
+
import { Card } from '@masterteam/components/card';
|
|
39
37
|
import * as i2$1 from 'primeng/tooltip';
|
|
40
|
-
import { Tooltip
|
|
38
|
+
import { Tooltip, TooltipModule } from 'primeng/tooltip';
|
|
41
39
|
import { Skeleton } from 'primeng/skeleton';
|
|
42
40
|
import * as i2 from 'primeng/inputtext';
|
|
43
41
|
import { InputTextModule } from 'primeng/inputtext';
|
|
@@ -48,8 +46,10 @@ import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
|
|
|
48
46
|
import * as i6 from 'primeng/select';
|
|
49
47
|
import { SelectModule } from 'primeng/select';
|
|
50
48
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
49
|
+
import { Tooltip as Tooltip$1 } from '@masterteam/components/tooltip';
|
|
51
50
|
import * as mtIcons from '@masterteam/icons/assets/select-icons.json';
|
|
52
|
-
import {
|
|
51
|
+
import { Avatar } from '@masterteam/components/avatar';
|
|
52
|
+
import { EntitiesPreview, EntityPreview } from '@masterteam/components/entities';
|
|
53
53
|
import * as i2$3 from 'primeng/button';
|
|
54
54
|
import { ButtonModule } from 'primeng/button';
|
|
55
55
|
import { rxResource } from '@angular/core/rxjs-interop';
|
|
@@ -81,6 +81,10 @@ class DashboardBuilderService {
|
|
|
81
81
|
* Tree data cache for building selector name map
|
|
82
82
|
*/
|
|
83
83
|
treeData = signal([], ...(ngDevMode ? [{ debugName: "treeData" }] : []));
|
|
84
|
+
/**
|
|
85
|
+
* Optional services filter for the modules tree request.
|
|
86
|
+
*/
|
|
87
|
+
modulesTreeServices = signal(null, ...(ngDevMode ? [{ debugName: "modulesTreeServices" }] : []));
|
|
84
88
|
/**
|
|
85
89
|
* Fixed selections that cannot be removed or edited in SelectionConfiguration.
|
|
86
90
|
* These selections are always shown and are read-only.
|
|
@@ -146,6 +150,13 @@ class DashboardBuilderService {
|
|
|
146
150
|
clearFixedSelections() {
|
|
147
151
|
this.fixedSelections.set([]);
|
|
148
152
|
}
|
|
153
|
+
setModulesTreeServices(services) {
|
|
154
|
+
if (services?.length) {
|
|
155
|
+
this.modulesTreeServices.set([...services]);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
this.modulesTreeServices.set(null);
|
|
159
|
+
}
|
|
149
160
|
/**
|
|
150
161
|
* Add a single fixed selection
|
|
151
162
|
* @param selection Selection to add as fixed
|
|
@@ -266,7 +277,11 @@ class DashboardBuilderService {
|
|
|
266
277
|
* This returns the complete tree structure for efficient caching
|
|
267
278
|
*/
|
|
268
279
|
getModulesTree() {
|
|
269
|
-
|
|
280
|
+
const services = this.modulesTreeServices();
|
|
281
|
+
const servicesQuery = services?.length
|
|
282
|
+
? `?services=${services.map(encodeURIComponent).join(',')}`
|
|
283
|
+
: '';
|
|
284
|
+
return this.http.get(`metadata/modules/tree${servicesQuery}`, { context: this.gatewayContext });
|
|
270
285
|
}
|
|
271
286
|
/**
|
|
272
287
|
* Get modules for a specific service
|
|
@@ -1035,13 +1050,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1035
1050
|
TranslocoDirective,
|
|
1036
1051
|
Button,
|
|
1037
1052
|
Icon,
|
|
1038
|
-
Card,
|
|
1039
1053
|
SelectField,
|
|
1040
1054
|
TextField,
|
|
1041
1055
|
NumberField,
|
|
1042
1056
|
CheckboxField,
|
|
1043
1057
|
TextareaField,
|
|
1044
|
-
Tooltip,
|
|
1045
1058
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
1046
1059
|
{
|
|
1047
1060
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -1125,7 +1138,7 @@ const CHART_TYPES = [
|
|
|
1125
1138
|
componentName: 'cardsStatistic',
|
|
1126
1139
|
functionName: 'handleOverviewCard',
|
|
1127
1140
|
requestType: 'custom',
|
|
1128
|
-
category: '
|
|
1141
|
+
category: 'special',
|
|
1129
1142
|
products: ['pplus', 'splus', 'report'],
|
|
1130
1143
|
hasManageItem: true,
|
|
1131
1144
|
defaultSize: { cols: 6, rows: 2 },
|
|
@@ -1311,13 +1324,14 @@ const CHART_TYPES = [
|
|
|
1311
1324
|
requestType: 'custom',
|
|
1312
1325
|
category: 'table',
|
|
1313
1326
|
products: ['pplus', 'splus', 'report'],
|
|
1327
|
+
hideInList: true,
|
|
1314
1328
|
hasManageItem: true,
|
|
1315
1329
|
defaultSize: { cols: 18, rows: 6 },
|
|
1316
1330
|
},
|
|
1317
1331
|
{
|
|
1318
1332
|
id: 'chart-map-chart',
|
|
1319
1333
|
name: 'Map Chart',
|
|
1320
|
-
icon: '
|
|
1334
|
+
icon: 'map.globe-01',
|
|
1321
1335
|
serviceType: 'TableView',
|
|
1322
1336
|
componentName: 'map',
|
|
1323
1337
|
functionName: 'handleLeafletMap',
|
|
@@ -1330,7 +1344,7 @@ const CHART_TYPES = [
|
|
|
1330
1344
|
// ===================== SPECIAL =====================
|
|
1331
1345
|
{
|
|
1332
1346
|
id: 'entity-preview',
|
|
1333
|
-
name: '
|
|
1347
|
+
name: 'Properties View',
|
|
1334
1348
|
icon: 'file.file-05',
|
|
1335
1349
|
serviceType: 'Properties',
|
|
1336
1350
|
componentName: 'entityPreview',
|
|
@@ -1344,7 +1358,7 @@ const CHART_TYPES = [
|
|
|
1344
1358
|
{
|
|
1345
1359
|
id: 'entity-preview-with-formula',
|
|
1346
1360
|
name: 'Entity Preview with Formula',
|
|
1347
|
-
icon: '
|
|
1361
|
+
icon: 'education.calculator',
|
|
1348
1362
|
serviceType: 'BarV2Chart',
|
|
1349
1363
|
componentName: 'entityPreviewWithFormula',
|
|
1350
1364
|
functionName: 'handleEntityPreviewWithFormula',
|
|
@@ -1364,15 +1378,16 @@ const CHART_TYPES = [
|
|
|
1364
1378
|
requestType: 'levelCards',
|
|
1365
1379
|
category: 'special',
|
|
1366
1380
|
products: ['pplus'],
|
|
1381
|
+
hideInList: true,
|
|
1367
1382
|
hasManageItem: true,
|
|
1368
1383
|
defaultSize: { cols: 18, rows: 4 },
|
|
1369
1384
|
},
|
|
1370
1385
|
{
|
|
1371
1386
|
id: 'entity-preview-levelCards2',
|
|
1372
|
-
name: '
|
|
1387
|
+
name: 'Properties Card',
|
|
1373
1388
|
icon: 'layout.grid-01',
|
|
1374
1389
|
serviceType: 'TableView',
|
|
1375
|
-
componentName: '
|
|
1390
|
+
componentName: 'entitiesPreview',
|
|
1376
1391
|
functionName: 'handlelevelCardsWithFilter',
|
|
1377
1392
|
requestType: 'custom',
|
|
1378
1393
|
category: 'special',
|
|
@@ -1390,13 +1405,14 @@ const CHART_TYPES = [
|
|
|
1390
1405
|
requestType: 'custom',
|
|
1391
1406
|
category: 'special',
|
|
1392
1407
|
products: ['splus'],
|
|
1408
|
+
hideInList: true,
|
|
1393
1409
|
hasManageItem: true,
|
|
1394
1410
|
defaultSize: { cols: 18, rows: 4 },
|
|
1395
1411
|
},
|
|
1396
1412
|
{
|
|
1397
1413
|
id: 'last-history-level-card',
|
|
1398
1414
|
name: 'Progress Update',
|
|
1399
|
-
icon: 'time.
|
|
1415
|
+
icon: 'time.clock-refresh',
|
|
1400
1416
|
serviceType: 'TableView',
|
|
1401
1417
|
componentName: 'lastHistoryLevelCard',
|
|
1402
1418
|
functionName: 'handleTableView',
|
|
@@ -1416,13 +1432,14 @@ const CHART_TYPES = [
|
|
|
1416
1432
|
requestType: 'custom',
|
|
1417
1433
|
category: 'special',
|
|
1418
1434
|
products: ['pplus', 'splus'],
|
|
1435
|
+
hideInList: true,
|
|
1419
1436
|
hasManageItem: true,
|
|
1420
1437
|
defaultSize: { cols: 18, rows: 4 },
|
|
1421
1438
|
},
|
|
1422
1439
|
{
|
|
1423
1440
|
id: 'phase-gate-stepper-card',
|
|
1424
1441
|
name: 'Phase Gate Stepper',
|
|
1425
|
-
icon: '
|
|
1442
|
+
icon: 'media.sliders-02',
|
|
1426
1443
|
serviceType: 'phaseGate',
|
|
1427
1444
|
componentName: 'phaseGateStepperCard',
|
|
1428
1445
|
functionName: 'handlePhaseGateStepperCard',
|
|
@@ -1624,7 +1641,7 @@ class ManageItemService {
|
|
|
1624
1641
|
this.selectedType.set({
|
|
1625
1642
|
id: 'custom-type',
|
|
1626
1643
|
name: 'Custom Type',
|
|
1627
|
-
icon: 'general.
|
|
1644
|
+
icon: 'general.help-circle',
|
|
1628
1645
|
serviceType: config.serviceConfig.chartType,
|
|
1629
1646
|
componentName: config.clientConfig.componentName,
|
|
1630
1647
|
functionName: config.clientConfig.functionName,
|
|
@@ -1794,6 +1811,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1794
1811
|
type: Injectable
|
|
1795
1812
|
}] });
|
|
1796
1813
|
|
|
1814
|
+
function createDefaultPropsConfigItem() {
|
|
1815
|
+
return {
|
|
1816
|
+
width: '',
|
|
1817
|
+
colorAsProperty: '',
|
|
1818
|
+
hidden: false,
|
|
1819
|
+
border: [],
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1797
1822
|
/**
|
|
1798
1823
|
* Display Settings Component
|
|
1799
1824
|
*
|
|
@@ -1847,12 +1872,13 @@ class DisplaySettings {
|
|
|
1847
1872
|
// Snapshot
|
|
1848
1873
|
snapShot_chart: 'advanced,format,overrideLabels,configAd,defaultColors,centerHeader,advancedHeaderConfig,borderTop,cardStyleConfig',
|
|
1849
1874
|
// Level Cards
|
|
1850
|
-
levelCards_listOfLevelCards: 'advanced,configAd,centerHeader,advancedHeaderConfig,cardStyleConfig,cardListConfig',
|
|
1851
|
-
TableView_listOfLevelCards: 'advanced,configAd,centerHeader,advancedHeaderConfig,cardStyleConfig
|
|
1875
|
+
levelCards_listOfLevelCards: 'advanced,propsConfigAsIndex,configAd,centerHeader,advancedHeaderConfig,cardStyleConfig,cardListConfig',
|
|
1876
|
+
TableView_listOfLevelCards: 'advanced,propsConfigAsIndex,configAd,centerHeader,advancedHeaderConfig,cardStyleConfig',
|
|
1877
|
+
TableView_entitiesPreview: 'advanced,propsConfigAsIndex,configAd,centerHeader,advancedHeaderConfig,cardStyleConfig',
|
|
1852
1878
|
// Component Cards
|
|
1853
1879
|
componentCards_listComponentSplusCard: 'cardStyleConfig',
|
|
1854
1880
|
// Entity Preview
|
|
1855
|
-
Properties_entityPreview: 'advanced,propsConfigAsIndex,
|
|
1881
|
+
Properties_entityPreview: 'advanced,propsConfigAsIndex,configAd,centerHeader,advancedHeaderConfig,borderTop,cardStyleConfig',
|
|
1856
1882
|
// Level Cards with Static
|
|
1857
1883
|
TableView_levelCardsWithStatic: 'advanced,labelCenter,propertyTranslations,format,toggleAssociation,propertyColors',
|
|
1858
1884
|
// Ring Gauge
|
|
@@ -1887,6 +1913,18 @@ class DisplaySettings {
|
|
|
1887
1913
|
shouldShowField(fieldName) {
|
|
1888
1914
|
return this.fieldsToShow().split(',').includes(fieldName);
|
|
1889
1915
|
}
|
|
1916
|
+
shouldShowPropertiesViewSettings() {
|
|
1917
|
+
if (this.shouldShowField('propsConfigAsIndex')) {
|
|
1918
|
+
return true;
|
|
1919
|
+
}
|
|
1920
|
+
const chartType = this.chartType();
|
|
1921
|
+
if (!chartType) {
|
|
1922
|
+
return false;
|
|
1923
|
+
}
|
|
1924
|
+
return (chartType.componentName === 'entitiesPreview' ||
|
|
1925
|
+
chartType.componentName === 'listOfLevelCards' ||
|
|
1926
|
+
chartType.componentName === 'entityPreview');
|
|
1927
|
+
}
|
|
1890
1928
|
/** Position options */
|
|
1891
1929
|
positionOptions = [
|
|
1892
1930
|
{ label: 'Start', value: 'start' },
|
|
@@ -2105,12 +2143,17 @@ class DisplaySettings {
|
|
|
2105
2143
|
toggleAssociation = computed(() => this.configAsType()['toggleAssociation'] || false, ...(ngDevMode ? [{ debugName: "toggleAssociation" }] : []));
|
|
2106
2144
|
/** Selected properties resolved from input or config */
|
|
2107
2145
|
resolvedSelectedProperties = computed(() => {
|
|
2108
|
-
const props = this.selectedProperties()
|
|
2109
|
-
|
|
2146
|
+
const props = this.selectedProperties()
|
|
2147
|
+
.map((prop) => this.resolvePropertyKey(prop))
|
|
2148
|
+
.filter((prop) => !!prop);
|
|
2149
|
+
if (props.length)
|
|
2110
2150
|
return props;
|
|
2111
2151
|
const fromConfig = this.config()?.serviceConfig?.query?.['selectedProperties'];
|
|
2112
|
-
if (Array.isArray(fromConfig))
|
|
2113
|
-
return fromConfig
|
|
2152
|
+
if (Array.isArray(fromConfig)) {
|
|
2153
|
+
return fromConfig
|
|
2154
|
+
.map((prop) => this.resolvePropertyKey(prop))
|
|
2155
|
+
.filter((prop) => !!prop);
|
|
2156
|
+
}
|
|
2114
2157
|
return [];
|
|
2115
2158
|
}, ...(ngDevMode ? [{ debugName: "resolvedSelectedProperties" }] : []));
|
|
2116
2159
|
/** Available properties resolved from input or selected properties */
|
|
@@ -2123,21 +2166,50 @@ class DisplaySettings {
|
|
|
2123
2166
|
name: key,
|
|
2124
2167
|
}));
|
|
2125
2168
|
}, ...(ngDevMode ? [{ debugName: "resolvedAvailableProperties" }] : []));
|
|
2126
|
-
/**
|
|
2127
|
-
|
|
2169
|
+
/** Selected properties as ordered options */
|
|
2170
|
+
selectedPropertyOptions = computed(() => {
|
|
2128
2171
|
const selected = this.resolvedSelectedProperties();
|
|
2172
|
+
if (!selected.length)
|
|
2173
|
+
return [];
|
|
2129
2174
|
const allProps = this.resolvedAvailableProperties();
|
|
2175
|
+
return selected.map((key) => {
|
|
2176
|
+
const prop = allProps.find((item) => this.resolvePropertyKey(item) === key ||
|
|
2177
|
+
item.key === key ||
|
|
2178
|
+
item.value === key);
|
|
2179
|
+
return {
|
|
2180
|
+
label: prop?.name || prop?.label || key,
|
|
2181
|
+
value: key,
|
|
2182
|
+
};
|
|
2183
|
+
});
|
|
2184
|
+
}, ...(ngDevMode ? [{ debugName: "selectedPropertyOptions" }] : []));
|
|
2185
|
+
/** Available properties as options */
|
|
2186
|
+
propertyOptions = computed(() => {
|
|
2187
|
+
const selected = this.selectedPropertyOptions();
|
|
2130
2188
|
if (selected.length > 0) {
|
|
2131
|
-
return selected
|
|
2132
|
-
const prop = allProps.find((p) => p.key === key || p.value === key);
|
|
2133
|
-
return { label: prop?.name || prop?.label || key, value: key };
|
|
2134
|
-
});
|
|
2189
|
+
return selected;
|
|
2135
2190
|
}
|
|
2191
|
+
const allProps = this.resolvedAvailableProperties();
|
|
2136
2192
|
return allProps.map((prop) => ({
|
|
2137
2193
|
label: prop?.name || prop?.label || prop?.key || prop?.value || String(prop),
|
|
2138
2194
|
value: prop?.key || prop?.value || String(prop),
|
|
2139
2195
|
}));
|
|
2140
2196
|
}, ...(ngDevMode ? [{ debugName: "propertyOptions" }] : []));
|
|
2197
|
+
/** Properties view rows driven by selected properties order */
|
|
2198
|
+
propertiesViewRows = computed(() => this.selectedPropertyOptions().map((property, index) => ({
|
|
2199
|
+
key: property.value,
|
|
2200
|
+
label: property.label,
|
|
2201
|
+
index,
|
|
2202
|
+
config: this.propsConfigAsIndex()[index] || createDefaultPropsConfigItem(),
|
|
2203
|
+
})), ...(ngDevMode ? [{ debugName: "propertiesViewRows" }] : []));
|
|
2204
|
+
/** Property translations rows driven by selected properties order */
|
|
2205
|
+
propertyTranslationRows = computed(() => this.selectedPropertyOptions().map((property) => ({
|
|
2206
|
+
key: property.value,
|
|
2207
|
+
label: property.label,
|
|
2208
|
+
translation: this.propertyTranslations()[property.value] || {
|
|
2209
|
+
ar: '',
|
|
2210
|
+
en: '',
|
|
2211
|
+
},
|
|
2212
|
+
})), ...(ngDevMode ? [{ debugName: "propertyTranslationRows" }] : []));
|
|
2141
2213
|
/** Available translation options (exclude used) */
|
|
2142
2214
|
availableTranslationOptions = computed(() => {
|
|
2143
2215
|
const used = new Set(Object.keys(this.propertyTranslations()));
|
|
@@ -2690,28 +2762,12 @@ class DisplaySettings {
|
|
|
2690
2762
|
this.updateNestedConfigAsType('cardListConfig', 'hideProperties', properties);
|
|
2691
2763
|
}
|
|
2692
2764
|
// ============ Props Config As Index Methods ============
|
|
2693
|
-
/** Add props config item */
|
|
2694
|
-
addPropsConfigItem() {
|
|
2695
|
-
const items = [...this.propsConfigAsIndex()];
|
|
2696
|
-
items.push({
|
|
2697
|
-
width: '',
|
|
2698
|
-
colorAsProperty: '',
|
|
2699
|
-
hidden: false,
|
|
2700
|
-
border: [],
|
|
2701
|
-
});
|
|
2702
|
-
this.updateConfigAsType('propsConfigAsIndex', items);
|
|
2703
|
-
}
|
|
2704
|
-
/** Remove props config item */
|
|
2705
|
-
removePropsConfigItem(index) {
|
|
2706
|
-
const items = [...this.propsConfigAsIndex()];
|
|
2707
|
-
items.splice(index, 1);
|
|
2708
|
-
this.updateConfigAsType('propsConfigAsIndex', items);
|
|
2709
|
-
}
|
|
2710
2765
|
/** Update props config item */
|
|
2711
2766
|
updatePropsConfigItem(index, key, value) {
|
|
2712
2767
|
const items = [...this.propsConfigAsIndex()];
|
|
2713
|
-
|
|
2714
|
-
|
|
2768
|
+
while (items.length <= index) {
|
|
2769
|
+
items.push(createDefaultPropsConfigItem());
|
|
2770
|
+
}
|
|
2715
2771
|
items[index] = {
|
|
2716
2772
|
...items[index],
|
|
2717
2773
|
[key]: value,
|
|
@@ -2865,12 +2921,11 @@ class DisplaySettings {
|
|
|
2865
2921
|
const translations = {
|
|
2866
2922
|
...(configAsType['overrideSelectedPropertiesLabels'] || {}),
|
|
2867
2923
|
};
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
}
|
|
2924
|
+
const currentTranslation = translations[propertyKey] || { ar: '', en: '' };
|
|
2925
|
+
translations[propertyKey] = {
|
|
2926
|
+
...currentTranslation,
|
|
2927
|
+
[lang]: value,
|
|
2928
|
+
};
|
|
2874
2929
|
this.clientConfigChange.emit({
|
|
2875
2930
|
configAsType: {
|
|
2876
2931
|
...configAsType,
|
|
@@ -3050,8 +3105,29 @@ class DisplaySettings {
|
|
|
3050
3105
|
selectedPropertyForTranslation = signal('', ...(ngDevMode ? [{ debugName: "selectedPropertyForTranslation" }] : []));
|
|
3051
3106
|
/** Selected property for adding colors */
|
|
3052
3107
|
selectedPropertyForColor = signal('', ...(ngDevMode ? [{ debugName: "selectedPropertyForColor" }] : []));
|
|
3108
|
+
resolvePropertyKey(value) {
|
|
3109
|
+
if (typeof value === 'string') {
|
|
3110
|
+
return value;
|
|
3111
|
+
}
|
|
3112
|
+
if (value && typeof value === 'object') {
|
|
3113
|
+
const record = value;
|
|
3114
|
+
const key = record['key'];
|
|
3115
|
+
const normalizedKey = record['normalizedKey'];
|
|
3116
|
+
const valueKey = record['value'];
|
|
3117
|
+
if (typeof key === 'string') {
|
|
3118
|
+
return key;
|
|
3119
|
+
}
|
|
3120
|
+
if (typeof normalizedKey === 'string') {
|
|
3121
|
+
return normalizedKey;
|
|
3122
|
+
}
|
|
3123
|
+
if (typeof valueKey === 'string') {
|
|
3124
|
+
return valueKey;
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
return '';
|
|
3128
|
+
}
|
|
3053
3129
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DisplaySettings, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3054
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DisplaySettings, isStandalone: true, selector: "mt-display-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartType: { classPropertyName: "chartType", publicName: "chartType", isSignal: true, isRequired: false, transformFunction: null }, availableProperties: { classPropertyName: "availableProperties", publicName: "availableProperties", isSignal: true, isRequired: false, transformFunction: null }, selectedProperties: { classPropertyName: "selectedProperties", publicName: "selectedProperties", isSignal: true, isRequired: false, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clientConfigChange: "clientConfigChange" }, ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <!-- Header Configuration -->\r\n @if (\r\n shouldShowField(\"centerHeader\") || shouldShowField(\"advancedHeaderConfig\")\r\n ) {\r\n <mt-card [title]=\"t('headerConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n @if (shouldShowField(\"centerHeader\")) {\r\n <mt-toggle-field\r\n [label]=\"t('centerHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderCentered || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderCentered', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"advancedHeaderConfig\")) {\r\n <mt-toggle-field\r\n [label]=\"t('hideHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderHidden || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderHidden', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerColor')\"\r\n [ngModel]=\"headerCardConfig().headerColor || ''\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerColor', $event)\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('headerFontSize')\"\r\n [ngModel]=\"headerCardConfig().headerFontSize || 14\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerFontSize', $event)\"\r\n [min]=\"10\"\r\n [max]=\"48\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Colors Section (for cards) -->\r\n @if (\r\n shouldShowField(\"bgColor\") ||\r\n shouldShowField(\"textColor\") ||\r\n shouldShowField(\"icon\")\r\n ) {\r\n <mt-card [title]=\"t('cardColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n @if (shouldShowField(\"bgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"styleConfig()['background-color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('background-color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"textColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"styleConfig()['color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"icon\")) {\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"configAsType()['icon'] || ''\"\r\n (ngModelChange)=\"updateConfigAsType('icon', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"styleConfig()['iconColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconBgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconBgColor')\"\r\n [ngModel]=\"styleConfig()['iconBgColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconBgColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"positionTitle\")) {\r\n <mt-select-field\r\n [label]=\"t('positionTitle')\"\r\n [ngModel]=\"styleConfig()['justify-content'] || 'start'\"\r\n (ngModelChange)=\"updateStyleConfig('justify-content', $event)\"\r\n [options]=\"positionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Border Top Section -->\r\n @if (shouldShowField(\"borderTop\")) {\r\n <mt-card [title]=\"t('borderTop')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showBorderTop')\"\r\n [ngModel]=\"styleConfig()['border-top-show'] || false\"\r\n (ngModelChange)=\"updateBorderTopShow($event)\"\r\n />\r\n @if (styleConfig()[\"border-top-show\"]) {\r\n <mt-color-picker-field\r\n [label]=\"t('borderTopColor')\"\r\n [ngModel]=\"\r\n styleConfig()['border-top-color'] ||\r\n styleConfig()['border-color'] ||\r\n '#3b82f6'\r\n \"\r\n (ngModelChange)=\"updateBorderTopColor($event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Style Configuration -->\r\n @if (shouldShowField(\"cardStyleConfig\")) {\r\n <mt-card [title]=\"t('cardStyle')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4 mb-4\">\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"borderRadius\") }}:\r\n {{ cardStyleConfig().borderRadius || 8 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"cardStyleConfig().borderRadius || 8\"\r\n (ngModelChange)=\"updateCardStyleConfig('borderRadius', $event)\"\r\n [min]=\"0\"\r\n [max]=\"24\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <mt-color-picker-field\r\n [label]=\"t('cardBackgroundColor')\"\r\n [ngModel]=\"cardStyleConfig().backgroundColor || ''\"\r\n (ngModelChange)=\"updateCardStyleConfig('backgroundColor', $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Shadows -->\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"font-medium\">{{ t(\"shadows\") }}</span>\r\n <mt-button\r\n [label]=\"t('addShadow')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addShadow()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n shadow of cardStyleConfig().shadows || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"shadow\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeShadow(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-5 gap-2\">\r\n <mt-number-field\r\n [label]=\"t('x')\"\r\n [ngModel]=\"shadow.x\"\r\n (ngModelChange)=\"updateShadow(i, 'x', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('y')\"\r\n [ngModel]=\"shadow.y\"\r\n (ngModelChange)=\"updateShadow(i, 'y', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('blur')\"\r\n [ngModel]=\"shadow.blur\"\r\n (ngModelChange)=\"updateShadow(i, 'blur', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('spread')\"\r\n [ngModel]=\"shadow.spread\"\r\n (ngModelChange)=\"updateShadow(i, 'spread', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"shadow.color\"\r\n (ngModelChange)=\"updateShadow(i, 'color', $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Legend Settings -->\r\n @if (shouldShowField(\"legend\")) {\r\n <mt-card [title]=\"t('legendSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLegend')\"\r\n [ngModel]=\"legendConfig().show || false\"\r\n (ngModelChange)=\"updateLegend('show', $event)\"\r\n />\r\n @if (legendConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"legendConfig().position || 'bottom'\"\r\n (ngModelChange)=\"updateLegend('position', $event)\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"legendIconType\")) {\r\n <mt-select-field\r\n [label]=\"t('legendIconType')\"\r\n [ngModel]=\"legendConfig().iconType || 'circle'\"\r\n (ngModelChange)=\"updateLegend('iconType', $event)\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Settings -->\r\n @if (shouldShowField(\"label\")) {\r\n <mt-card [title]=\"t('labelSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabels')\"\r\n [ngModel]=\"labelConfig().show || false\"\r\n (ngModelChange)=\"updateLabel('show', $event)\"\r\n />\r\n @if (labelConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"labelConfig().position || 'inside'\"\r\n (ngModelChange)=\"updateLabel('position', $event)\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"showTotal\")) {\r\n <mt-toggle-field\r\n [label]=\"t('showTotalInTop')\"\r\n [ngModel]=\"labelConfig().showTotalInTop || false\"\r\n (ngModelChange)=\"updateLabel('showTotalInTop', $event)\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Center (for Pie/Donut charts) -->\r\n @if (shouldShowField(\"labelCenter\")) {\r\n <mt-card [title]=\"t('labelCenter')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideLabelCenter')\"\r\n [ngModel]=\"labelCenterConfig().hide || false\"\r\n (ngModelChange)=\"updateLabelCenterConfig('hide', $event)\"\r\n />\r\n @if (!labelCenterConfig().hide) {\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextEn')\"\r\n [ngModel]=\"labelCenterConfig().text?.en || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('en', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextAr')\"\r\n [ngModel]=\"labelCenterConfig().text?.ar || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('ar', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Override Labels -->\r\n @if (shouldShowField(\"overrideLabels\")) {\r\n <mt-card [title]=\"t('overrideLabels')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"overrideLabelsDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addLabel')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOverrideLabel()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n label of overrideLabels();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"label\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOverrideLabel(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"label.en\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'en', $event)\"\r\n [placeholder]=\"t('enterLabelEn')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"label.ar\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'ar', $event)\"\r\n [placeholder]=\"t('enterLabelAr')\"\r\n dir=\"rtl\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (overrideLabels().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOverrideLabels\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Sort Data Bars -->\r\n @if (shouldShowField(\"sortDataBars\")) {\r\n <mt-card [title]=\"t('sortDataBars')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableSorting')\"\r\n [ngModel]=\"sortDataBarsConfig().enable || false\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('enable', $event)\"\r\n />\r\n @if (sortDataBarsConfig().enable) {\r\n <mt-text-field\r\n [label]=\"t('sortBy')\"\r\n [ngModel]=\"sortDataBarsConfig().sortBy || ''\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('sortBy', $event)\"\r\n [placeholder]=\"t('propertyKey')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('order')\"\r\n [ngModel]=\"sortDataBarsConfig().order || 'asc'\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('order', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Default Colors (for charts) -->\r\n @if (shouldShowField(\"defaultColors\")) {\r\n <mt-card [title]=\"t('defaultColors')\">\r\n <div class=\"flex flex-wrap gap-2 mb-4\">\r\n @for (\r\n color of defaultColors();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"flex items-center gap-1 p-2 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-color-picker-field\r\n [ngModel]=\"color\"\r\n (ngModelChange)=\"updateDefaultColor(i, $event)\"\r\n />\r\n <mt-button\r\n icon=\"general.x-close\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeDefaultColor(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-2 items-center\">\r\n <span class=\"text-sm text-muted-color xl:mr-2\">{{ t(\"quickAdd\") }}:</span>\r\n @for (color of defaultColorPalette; track color) {\r\n <button\r\n type=\"button\"\r\n class=\"w-6 h-6 rounded cursor-pointer border border-surface-300 hover:scale-110 transition-transform\"\r\n [style.background-color]=\"color\"\r\n (click)=\"addDefaultColor(color)\"\r\n [pTooltip]=\"color\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n\r\n @if (defaultColors().length === 0) {\r\n <div class=\"text-center py-2 text-muted-color text-sm mt-2\">\r\n {{ t(\"noColorsSelected\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Info -->\r\n @if (shouldShowField(\"cardInfo\")) {\r\n <mt-card [title]=\"t('cardInfo')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showCardInfo')\"\r\n [ngModel]=\"cardInfo().show || false\"\r\n (ngModelChange)=\"updateCardInfoConfig('show', $event)\"\r\n />\r\n @if (cardInfo().show) {\r\n <mt-text-field\r\n [label]=\"t('cardInfoValue')\"\r\n [ngModel]=\"cardInfo().value || ''\"\r\n (ngModelChange)=\"updateCardInfoConfig('value', $event)\"\r\n [placeholder]=\"t('enterCardInfoValue')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Settings -->\r\n @if (shouldShowField(\"hideIndex\")) {\r\n <mt-card [title]=\"t('tableSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideIndex')\"\r\n [ngModel]=\"configAsType()['hideIndex'] || false\"\r\n (ngModelChange)=\"updateConfigAsType('hideIndex', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Map Settings -->\r\n @if (shouldShowField(\"mapChart\")) {\r\n <mt-card [title]=\"t('mapSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('mapType')\"\r\n [ngModel]=\"config()?.clientConfig?.['map'] || 'SaudiArabia'\"\r\n (ngModelChange)=\"updateMapType($event)\"\r\n [options]=\"mapOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Format Configuration -->\r\n @if (shouldShowField(\"format\")) {\r\n <mt-card [title]=\"t('formatConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatConfig().type\"\r\n (ngModelChange)=\"updateFormatConfig('type', $event)\"\r\n [options]=\"formatTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n\r\n @if (formatConfig().type === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"formatConfig().showCurrency || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrency', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showCurrencyTooltip')\"\r\n [ngModel]=\"formatConfig().showCurrencyTooltip || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrencyTooltip', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('handleLanguage')\"\r\n [ngModel]=\"formatConfig().handleLang || false\"\r\n (ngModelChange)=\"updateFormatConfig('handleLang', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hideSuffixes')\"\r\n [ngModel]=\"formatConfig().hideSuffixes || false\"\r\n (ngModelChange)=\"updateFormatConfig('hideSuffixes', $event)\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"custom\") {\r\n <mt-text-field\r\n [label]=\"t('customText')\"\r\n [ngModel]=\"formatConfig().customText || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customText', $event)\"\r\n [placeholder]=\"t('enterCustomText')\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"date\") {\r\n <mt-text-field\r\n [label]=\"t('dateFormat')\"\r\n [ngModel]=\"formatConfig().customDateFormat || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customDateFormat', $event)\"\r\n [placeholder]=\"'YYYY-MM-DD'\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Format Configuration -->\r\n @if (shouldShowField(\"tableFormat\")) {\r\n <mt-card [title]=\"t('tableFormatConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <!-- Colors -->\r\n <mt-color-picker-field\r\n [label]=\"t('headerTextColor')\"\r\n [ngModel]=\"tableFormatConfig().thTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().thBackgroundColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thBackgroundColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cellTextColor')\"\r\n [ngModel]=\"tableFormatConfig().tdTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().groupBackgroundColor || ''\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('groupBackgroundColor', $event)\r\n \"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupTextColor')\"\r\n [ngModel]=\"tableFormatConfig().groupTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('groupTextColor', $event)\"\r\n />\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n <!-- Font Settings -->\r\n <mt-toggle-field\r\n [label]=\"t('boldHeaderFont')\"\r\n [ngModel]=\"tableFormatConfig().thFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontBold', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('boldCellFont')\"\r\n [ngModel]=\"tableFormatConfig().tdFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontBold', $event)\"\r\n />\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"headerFontSize\") }}:\r\n {{ tableFormatConfig().thFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().thFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"cellFontSize\") }}:\r\n {{ tableFormatConfig().tdFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().tdFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n <!-- Options -->\r\n <mt-toggle-field\r\n [label]=\"t('hideTableSubheader')\"\r\n [ngModel]=\"tableFormatConfig().hideTableSubheader || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('hideTableSubheader', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('disableCurrencyFormat')\"\r\n [ngModel]=\"tableFormatConfig().disableCurrencyFormat || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('disableCurrencyFormat', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageAsProgressBar')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageAsProgressBar || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageAsProgressBar', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageStatus')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageStatus || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageStatus', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <!-- Sort & Hidden Columns -->\r\n <mt-select-field\r\n [label]=\"t('sortColumn')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.column || ''\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('column', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumn')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('sortDirection')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.direction || 'asc'\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('direction', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenColumns')\"\r\n [ngModel]=\"tableFormatConfig().hiddenColumns || []\"\r\n (ngModelChange)=\"updateTableFormatConfig('hiddenColumns', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumns')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <mt-button\r\n [label]=\"t('resetToDefault')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"resetTableFormat()\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Color By Condition -->\r\n @if (shouldShowField(\"colorByCondition\")) {\r\n <mt-card [title]=\"t('colorByCondition')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"colorByConditionDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('add')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addColorConditionIndex()\"\r\n />\r\n </div>\r\n\r\n @for (barIndex of getColorConditionIndexes(); track barIndex) {\r\n <div class=\"mb-4 border border-surface-200 rounded-lg\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 p-3 bg-surface-50\">\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"text-sm text-muted-color\"\r\n (click)=\"toggleColorConditionExpanded(barIndex)\"\r\n >\r\n {{ isColorConditionExpanded(barIndex) ? \"-\" : \"+\" }}\r\n </button>\r\n <span class=\"font-medium text-sm\"\r\n >{{ t(\"bar\") }} {{ barIndex }}</span\r\n >\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n addColorCondition(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n removeColorConditionIndex(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (isColorConditionExpanded(barIndex)) {\r\n <div class=\"p-3\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"conditions\") }}</span>\r\n <mt-button\r\n [label]=\"t('addCondition')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addColorCondition(barIndex)\"\r\n />\r\n </div>\r\n\r\n @for (\r\n condition of colorByCondition()[barIndex] || [];\r\n track trackByIndex($index);\r\n let condIndex = $index\r\n ) {\r\n <div class=\"p-3 border border-surface-200 rounded-lg mb-3\">\r\n <div class=\"grid grid-cols-1 2xl:grid-cols-6 gap-3 items-end\">\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"condition.color\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'color',\r\n $event\r\n )\r\n \"\r\n />\r\n <mt-select-field\r\n [label]=\"t('condition')\"\r\n [ngModel]=\"condition.type\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'type',\r\n $event\r\n )\r\n \"\r\n [options]=\"colorConditionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-number-field\r\n [label]=\"\r\n condition.type === 'between' ? t('from') : t('value')\r\n \"\r\n [ngModel]=\"condition.value1\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value1',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n @if (condition.type === \"between\") {\r\n <mt-number-field\r\n [label]=\"t('to')\"\r\n [ngModel]=\"condition.value2\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value2',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n }\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeColorCondition(barIndex, condIndex)\"\r\n />\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3 mt-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"condition.labelEn || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelEn',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"condition.labelAr || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelAr',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((colorByCondition()[barIndex] || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getColorConditionIndexes().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Timeline Header Colors -->\r\n @if (shouldShowField(\"timelineHeaderColorsConfig\")) {\r\n <mt-card [title]=\"t('timelineHeaderColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().bgColor || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('bgColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().color || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('color', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Ring Gauge Configuration -->\r\n @if (shouldShowField(\"ringGaugeConfig\")) {\r\n <mt-card [title]=\"t('ringGaugeConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('centerProperty')\"\r\n [ngModel]=\"ringGaugeConfig().centerProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('centerProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('statusProperty')\"\r\n [ngModel]=\"ringGaugeConfig().statusProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('statusProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <div class=\"mt-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenProperties')\"\r\n [ngModel]=\"ringGaugeConfig().hiddenProperties || []\"\r\n (ngModelChange)=\"updateRingGaugeConfig('hiddenProperties', $event)\"\r\n [options]=\"ringGaugeHiddenOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Order Configuration -->\r\n @if (shouldShowField(\"orderConfig\")) {\r\n <mt-card [title]=\"t('orderConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4 mb-4\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n [ngModel]=\"orderConfig().operation || 'deleteNotEqual'\"\r\n (ngModelChange)=\"updateOrderConfig('operation', $event)\"\r\n [options]=\"orderOperationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('orderBy')\"\r\n [ngModel]=\"orderConfig().orderBy || ''\"\r\n (ngModelChange)=\"updateOrderConfig('orderBy', $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n />\r\n </div>\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"orderConfigurationDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addOrderItem')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOrderItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of orderConfig().order || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 flex flex-col gap-3 rounded-lg border border-surface-200 bg-surface-50 p-4 xl:flex-row xl:items-center\"\r\n >\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n <span class=\"text-sm font-medium w-auto xl:w-8\">{{ i + 1 }}.</span>\r\n <mt-text-field\r\n [ngModel]=\"item\"\r\n (ngModelChange)=\"updateOrderItem(i, $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n size=\"small\"\r\n class=\"min-w-0 flex-1\"\r\n />\r\n </div>\r\n <div class=\"flex items-center justify-end gap-1\">\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === 0\"\r\n (onClick)=\"moveOrderItemUp(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === (orderConfig().order || []).length - 1\"\r\n (onClick)=\"moveOrderItemDown(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOrderItem(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((orderConfig().order || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOrderItems\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card List Configuration -->\r\n @if (shouldShowField(\"cardListConfig\")) {\r\n <mt-card [title]=\"t('cardListConfiguration')\">\r\n <mt-multi-select-field\r\n [label]=\"t('hideProperties')\"\r\n [ngModel]=\"cardListConfig().hideProperties || []\"\r\n (ngModelChange)=\"updateCardListHideProperties($event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertiesToHide')\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Props Config As Index -->\r\n @if (shouldShowField(\"propsConfigAsIndex\")) {\r\n <mt-card [title]=\"t('entityPreviewSettings')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"text-sm text-muted-color\">{{ t(\"properties\") }}</span>\r\n <mt-button\r\n [label]=\"t('addProperty')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addPropsConfigItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of propsConfigAsIndex();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"property\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropsConfigItem(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 2xl:grid-cols-4 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('width')\"\r\n [ngModel]=\"item.width || ''\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'width', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('colorProperty')\"\r\n [ngModel]=\"item.colorAsProperty || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(i, 'colorAsProperty', $event)\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('border')\"\r\n [ngModel]=\"item.border || []\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'border', $event)\"\r\n [options]=\"borderOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hidden')\"\r\n [ngModel]=\"item.hidden || false\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'hidden', $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Toggle Association -->\r\n @if (shouldShowField(\"toggleAssociation\")) {\r\n <mt-card [title]=\"t('toggleAssociation')\">\r\n <mt-toggle-field\r\n [label]=\"t('enableToggleAssociation')\"\r\n [ngModel]=\"toggleAssociation()\"\r\n (ngModelChange)=\"updateToggleAssociation($event)\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Translations -->\r\n @if (\r\n shouldShowField(\"propertyTranslations\") &&\r\n resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyTranslations')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyTranslations()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyTranslationsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyTranslationsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyTranslationsPasteText()\"\r\n (ngModelChange)=\"propertyTranslationsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyTranslationsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyTranslationsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyTranslationsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyTranslationsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForTranslation()\"\r\n (ngModelChange)=\"selectedPropertyForTranslation.set($event)\"\r\n [options]=\"availableTranslationOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertyToTranslate')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForTranslation()\"\r\n (onClick)=\"\r\n addPropertyTranslation(selectedPropertyForTranslation());\r\n selectedPropertyForTranslation.set('')\r\n \"\r\n [pTooltip]=\"t('addTranslation')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Translation List -->\r\n @for (propKey of getPropertyTranslationKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyTranslation(propKey)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('arabicLabel')\"\r\n [ngModel]=\"propertyTranslations()[propKey]?.ar || ''\"\r\n (ngModelChange)=\"updatePropertyTranslation(propKey, 'ar', $event)\"\r\n [placeholder]=\"t('enterArabicLabel')\"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('englishLabel')\"\r\n [ngModel]=\"propertyTranslations()[propKey]?.en || ''\"\r\n (ngModelChange)=\"updatePropertyTranslation(propKey, 'en', $event)\"\r\n [placeholder]=\"t('enterEnglishLabel')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getPropertyTranslationKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyTranslations\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Colors -->\r\n @if (\r\n shouldShowField(\"propertyColors\") && resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyColors')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyColors()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyColorsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyColorsPasteText()\"\r\n (ngModelChange)=\"propertyColorsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyColorsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyColorsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyColorsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForColor()\"\r\n (ngModelChange)=\"selectedPropertyForColor.set($event)\"\r\n [options]=\"availableColorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForColor()\"\r\n (onClick)=\"\r\n addPropertyColor(selectedPropertyForColor());\r\n selectedPropertyForColor.set('')\r\n \"\r\n [pTooltip]=\"t('addProperty')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Property Color List -->\r\n @for (propKey of getPropertyColorKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyColor(propKey)\"\r\n />\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('selectColorProperty')\"\r\n [ngModel]=\"propertyColors()[propKey]?.selectedKey || ''\"\r\n (ngModelChange)=\"updatePropertyColor(propKey, $event)\"\r\n [options]=\"allPropertyKeyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (getPropertyColorKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyColors\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Format X-Axis Configuration -->\r\n @if (shouldShowField(\"formatXAxis\")) {\r\n <mt-card [title]=\"t('formatXAxisConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatXAxisConfig().type\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('type', $event)\"\r\n [options]=\"formatXAxisTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n @if (\r\n formatXAxisConfig().type === \"dateToMonth\" ||\r\n formatXAxisConfig().type === \"month\"\r\n ) {\r\n <mt-toggle-field\r\n [label]=\"t('shortFormat')\"\r\n [ngModel]=\"formatXAxisConfig().shortFormate || false\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('shortFormate', $event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Extra Column From Lookup -->\r\n @if (shouldShowField(\"extraColumnFromLookup\")) {\r\n <mt-card [title]=\"t('extraColumnFromLookup')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableExtraColumnFromLookup')\"\r\n [ngModel]=\"tableColumnsConfig().extraCoulmnFromLookup || false\"\r\n (ngModelChange)=\"\r\n updateTableColumnsConfig('extraCoulmnFromLookup', $event)\r\n \"\r\n />\r\n\r\n @if (tableColumnsConfig().extraCoulmnFromLookup) {\r\n <mt-select-field\r\n [label]=\"t('lookup')\"\r\n [ngModel]=\"tableColumnsConfig().lookupId\"\r\n (ngModelChange)=\"updateTableColumnsConfig('lookupId', $event)\"\r\n [options]=\"lookups()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectLookup')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('groupedBy')\"\r\n [ngModel]=\"tableColumnsConfig().groupedBy\"\r\n (ngModelChange)=\"updateTableColumnsConfig('groupedBy', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"tableColumnsConfig().propKey\"\r\n (ngModelChange)=\"updateTableColumnsConfig('propKey', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: SliderField, selector: "mt-slider-field", inputs: ["field", "label", "animate", "class", "min", "max", "step", "hideNumber", "unit", "readonly", "pInputs", "required"], outputs: ["onChange", "onSlideEnd"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: IconField, selector: "mt-icon-field", inputs: ["label", "required"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip$1, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3130
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DisplaySettings, isStandalone: true, selector: "mt-display-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartType: { classPropertyName: "chartType", publicName: "chartType", isSignal: true, isRequired: false, transformFunction: null }, availableProperties: { classPropertyName: "availableProperties", publicName: "availableProperties", isSignal: true, isRequired: false, transformFunction: null }, selectedProperties: { classPropertyName: "selectedProperties", publicName: "selectedProperties", isSignal: true, isRequired: false, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clientConfigChange: "clientConfigChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Header Configuration -->\r\n @if (\r\n shouldShowField(\"centerHeader\") || shouldShowField(\"advancedHeaderConfig\")\r\n ) {\r\n <mt-card [title]=\"t('headerConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-5\">\r\n @if (shouldShowField(\"centerHeader\")) {\r\n <mt-toggle-field\r\n [label]=\"t('centerHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderCentered || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderCentered', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"advancedHeaderConfig\")) {\r\n <mt-toggle-field\r\n [label]=\"t('hideHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderHidden || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderHidden', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerColor')\"\r\n [ngModel]=\"headerCardConfig().headerColor || ''\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerColor', $event)\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('headerFontSize')\"\r\n [ngModel]=\"headerCardConfig().headerFontSize || 14\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerFontSize', $event)\"\r\n [min]=\"10\"\r\n [max]=\"48\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Colors Section (for cards) -->\r\n @if (\r\n shouldShowField(\"bgColor\") ||\r\n shouldShowField(\"textColor\") ||\r\n shouldShowField(\"icon\")\r\n ) {\r\n <mt-card [title]=\"t('cardColors')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-5\">\r\n @if (shouldShowField(\"bgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"styleConfig()['background-color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('background-color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"textColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"styleConfig()['color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"icon\")) {\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"configAsType()['icon'] || ''\"\r\n (ngModelChange)=\"updateConfigAsType('icon', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"styleConfig()['iconColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconBgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconBgColor')\"\r\n [ngModel]=\"styleConfig()['iconBgColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconBgColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"positionTitle\")) {\r\n <mt-select-field\r\n [label]=\"t('positionTitle')\"\r\n [ngModel]=\"styleConfig()['justify-content'] || 'start'\"\r\n (ngModelChange)=\"updateStyleConfig('justify-content', $event)\"\r\n [options]=\"positionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Border Top Section -->\r\n @if (shouldShowField(\"borderTop\")) {\r\n <mt-card [title]=\"t('borderTop')\">\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-5\">\r\n <mt-toggle-field\r\n [label]=\"t('showBorderTop')\"\r\n [ngModel]=\"styleConfig()['border-top-show'] || false\"\r\n (ngModelChange)=\"updateBorderTopShow($event)\"\r\n />\r\n @if (styleConfig()[\"border-top-show\"]) {\r\n <mt-color-picker-field\r\n [label]=\"t('borderTopColor')\"\r\n [ngModel]=\"\r\n styleConfig()['border-top-color'] ||\r\n styleConfig()['border-color'] ||\r\n '#3b82f6'\r\n \"\r\n (ngModelChange)=\"updateBorderTopColor($event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Style Configuration -->\r\n @if (shouldShowField(\"cardStyleConfig\")) {\r\n <mt-card [title]=\"t('cardStyle')\">\r\n <div class=\"grid grid-cols-1 gap-5 mb-6\">\r\n <mt-slider-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"cardStyleConfig().borderRadius || 8\"\r\n (ngModelChange)=\"updateCardStyleConfig('borderRadius', $event)\"\r\n [min]=\"0\"\r\n [max]=\"24\"\r\n [step]=\"1\"\r\n unit=\"px\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cardBackgroundColor')\"\r\n [ngModel]=\"cardStyleConfig().backgroundColor || ''\"\r\n (ngModelChange)=\"updateCardStyleConfig('backgroundColor', $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Shadows -->\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"font-medium\">{{ t(\"shadows\") }}</span>\r\n <mt-button\r\n [label]=\"t('addShadow')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addShadow()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n shadow of cardStyleConfig().shadows || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"shadow\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeShadow(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-number-field\r\n [label]=\"t('x')\"\r\n [ngModel]=\"shadow.x\"\r\n (ngModelChange)=\"updateShadow(i, 'x', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('y')\"\r\n [ngModel]=\"shadow.y\"\r\n (ngModelChange)=\"updateShadow(i, 'y', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('blur')\"\r\n [ngModel]=\"shadow.blur\"\r\n (ngModelChange)=\"updateShadow(i, 'blur', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('spread')\"\r\n [ngModel]=\"shadow.spread\"\r\n (ngModelChange)=\"updateShadow(i, 'spread', $event)\"\r\n size=\"small\"\r\n />\r\n <div class=\"md:col-span-2\">\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"shadow.color\"\r\n (ngModelChange)=\"updateShadow(i, 'color', $event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Legend Settings -->\r\n @if (shouldShowField(\"legend\")) {\r\n <mt-card [title]=\"t('legendSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLegend')\"\r\n [ngModel]=\"legendConfig().show || false\"\r\n (ngModelChange)=\"updateLegend('show', $event)\"\r\n />\r\n @if (legendConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"legendConfig().position || 'bottom'\"\r\n (ngModelChange)=\"updateLegend('position', $event)\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"legendIconType\")) {\r\n <mt-select-field\r\n [label]=\"t('legendIconType')\"\r\n [ngModel]=\"legendConfig().iconType || 'circle'\"\r\n (ngModelChange)=\"updateLegend('iconType', $event)\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Settings -->\r\n @if (shouldShowField(\"label\")) {\r\n <mt-card [title]=\"t('labelSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabels')\"\r\n [ngModel]=\"labelConfig().show || false\"\r\n (ngModelChange)=\"updateLabel('show', $event)\"\r\n />\r\n @if (labelConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"labelConfig().position || 'inside'\"\r\n (ngModelChange)=\"updateLabel('position', $event)\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"showTotal\")) {\r\n <mt-toggle-field\r\n [label]=\"t('showTotalInTop')\"\r\n [ngModel]=\"labelConfig().showTotalInTop || false\"\r\n (ngModelChange)=\"updateLabel('showTotalInTop', $event)\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Center (for Pie/Donut charts) -->\r\n @if (shouldShowField(\"labelCenter\")) {\r\n <mt-card [title]=\"t('labelCenter')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideLabelCenter')\"\r\n [ngModel]=\"labelCenterConfig().hide || false\"\r\n (ngModelChange)=\"updateLabelCenterConfig('hide', $event)\"\r\n />\r\n @if (!labelCenterConfig().hide) {\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextEn')\"\r\n [ngModel]=\"labelCenterConfig().text?.en || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('en', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextAr')\"\r\n [ngModel]=\"labelCenterConfig().text?.ar || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('ar', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Override Labels -->\r\n @if (shouldShowField(\"overrideLabels\")) {\r\n <mt-card [title]=\"t('overrideLabels')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"overrideLabelsDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addLabel')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOverrideLabel()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n label of overrideLabels();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"label\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOverrideLabel(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"label.en\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'en', $event)\"\r\n [placeholder]=\"t('enterLabelEn')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"label.ar\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'ar', $event)\"\r\n [placeholder]=\"t('enterLabelAr')\"\r\n dir=\"rtl\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (overrideLabels().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOverrideLabels\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Sort Data Bars -->\r\n @if (shouldShowField(\"sortDataBars\")) {\r\n <mt-card [title]=\"t('sortDataBars')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableSorting')\"\r\n [ngModel]=\"sortDataBarsConfig().enable || false\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('enable', $event)\"\r\n />\r\n @if (sortDataBarsConfig().enable) {\r\n <mt-text-field\r\n [label]=\"t('sortBy')\"\r\n [ngModel]=\"sortDataBarsConfig().sortBy || ''\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('sortBy', $event)\"\r\n [placeholder]=\"t('propertyKey')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('order')\"\r\n [ngModel]=\"sortDataBarsConfig().order || 'asc'\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('order', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Default Colors (for charts) -->\r\n @if (shouldShowField(\"defaultColors\")) {\r\n <mt-card [title]=\"t('defaultColors')\">\r\n <div class=\"flex flex-wrap gap-2 mb-4\">\r\n @for (\r\n color of defaultColors();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"flex items-center gap-1 p-2 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-color-picker-field\r\n [ngModel]=\"color\"\r\n (ngModelChange)=\"updateDefaultColor(i, $event)\"\r\n />\r\n <mt-button\r\n icon=\"general.x-close\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeDefaultColor(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-2 items-center\">\r\n <span class=\"text-sm text-muted-color xl:mr-2\"\r\n >{{ t(\"quickAdd\") }}:</span\r\n >\r\n @for (color of defaultColorPalette; track color) {\r\n <button\r\n type=\"button\"\r\n class=\"w-6 h-6 rounded cursor-pointer border border-surface-300 hover:scale-110 transition-transform\"\r\n [style.background-color]=\"color\"\r\n (click)=\"addDefaultColor(color)\"\r\n [pTooltip]=\"color\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n\r\n @if (defaultColors().length === 0) {\r\n <div class=\"text-center py-2 text-muted-color text-sm mt-2\">\r\n {{ t(\"noColorsSelected\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Info -->\r\n @if (shouldShowField(\"cardInfo\")) {\r\n <mt-card [title]=\"t('cardInfo')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showCardInfo')\"\r\n [ngModel]=\"cardInfo().show || false\"\r\n (ngModelChange)=\"updateCardInfoConfig('show', $event)\"\r\n />\r\n @if (cardInfo().show) {\r\n <mt-text-field\r\n [label]=\"t('cardInfoValue')\"\r\n [ngModel]=\"cardInfo().value || ''\"\r\n (ngModelChange)=\"updateCardInfoConfig('value', $event)\"\r\n [placeholder]=\"t('enterCardInfoValue')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Settings -->\r\n @if (shouldShowField(\"hideIndex\")) {\r\n <mt-card [title]=\"t('tableSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideIndex')\"\r\n [ngModel]=\"configAsType()['hideIndex'] || false\"\r\n (ngModelChange)=\"updateConfigAsType('hideIndex', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Map Settings -->\r\n @if (shouldShowField(\"mapChart\")) {\r\n <mt-card [title]=\"t('mapSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('mapType')\"\r\n [ngModel]=\"config()?.clientConfig?.['map'] || 'SaudiArabia'\"\r\n (ngModelChange)=\"updateMapType($event)\"\r\n [options]=\"mapOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Format Configuration -->\r\n @if (shouldShowField(\"format\")) {\r\n <mt-card [title]=\"t('formatConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatConfig().type\"\r\n (ngModelChange)=\"updateFormatConfig('type', $event)\"\r\n [options]=\"formatTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n\r\n @if (formatConfig().type === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"formatConfig().showCurrency || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrency', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showCurrencyTooltip')\"\r\n [ngModel]=\"formatConfig().showCurrencyTooltip || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrencyTooltip', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('handleLanguage')\"\r\n [ngModel]=\"formatConfig().handleLang || false\"\r\n (ngModelChange)=\"updateFormatConfig('handleLang', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hideSuffixes')\"\r\n [ngModel]=\"formatConfig().hideSuffixes || false\"\r\n (ngModelChange)=\"updateFormatConfig('hideSuffixes', $event)\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"custom\") {\r\n <mt-text-field\r\n [label]=\"t('customText')\"\r\n [ngModel]=\"formatConfig().customText || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customText', $event)\"\r\n [placeholder]=\"t('enterCustomText')\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"date\") {\r\n <mt-text-field\r\n [label]=\"t('dateFormat')\"\r\n [ngModel]=\"formatConfig().customDateFormat || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customDateFormat', $event)\"\r\n [placeholder]=\"'YYYY-MM-DD'\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Format Configuration -->\r\n @if (shouldShowField(\"tableFormat\")) {\r\n <mt-card [title]=\"t('tableFormatConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Colors -->\r\n <mt-color-picker-field\r\n [label]=\"t('headerTextColor')\"\r\n [ngModel]=\"tableFormatConfig().thTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().thBackgroundColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thBackgroundColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cellTextColor')\"\r\n [ngModel]=\"tableFormatConfig().tdTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().groupBackgroundColor || ''\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('groupBackgroundColor', $event)\r\n \"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupTextColor')\"\r\n [ngModel]=\"tableFormatConfig().groupTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('groupTextColor', $event)\"\r\n />\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Font Settings -->\r\n <mt-toggle-field\r\n [label]=\"t('boldHeaderFont')\"\r\n [ngModel]=\"tableFormatConfig().thFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontBold', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('boldCellFont')\"\r\n [ngModel]=\"tableFormatConfig().tdFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontBold', $event)\"\r\n />\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"headerFontSize\") }}:\r\n {{ tableFormatConfig().thFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().thFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"cellFontSize\") }}:\r\n {{ tableFormatConfig().tdFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().tdFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Options -->\r\n <mt-toggle-field\r\n [label]=\"t('hideTableSubheader')\"\r\n [ngModel]=\"tableFormatConfig().hideTableSubheader || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('hideTableSubheader', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('disableCurrencyFormat')\"\r\n [ngModel]=\"tableFormatConfig().disableCurrencyFormat || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('disableCurrencyFormat', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageAsProgressBar')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageAsProgressBar || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageAsProgressBar', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageStatus')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageStatus || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageStatus', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Sort & Hidden Columns -->\r\n <mt-select-field\r\n [label]=\"t('sortColumn')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.column || ''\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('column', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumn')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('sortDirection')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.direction || 'asc'\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('direction', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenColumns')\"\r\n [ngModel]=\"tableFormatConfig().hiddenColumns || []\"\r\n (ngModelChange)=\"updateTableFormatConfig('hiddenColumns', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumns')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <mt-button\r\n [label]=\"t('resetToDefault')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"resetTableFormat()\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Color By Condition -->\r\n @if (shouldShowField(\"colorByCondition\")) {\r\n <mt-card [title]=\"t('colorByCondition')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"colorByConditionDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('add')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addColorConditionIndex()\"\r\n />\r\n </div>\r\n\r\n @for (barIndex of getColorConditionIndexes(); track barIndex) {\r\n <div class=\"mb-4 border border-surface-200 rounded-lg\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-2 p-3 bg-surface-50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"text-sm text-muted-color\"\r\n (click)=\"toggleColorConditionExpanded(barIndex)\"\r\n >\r\n {{ isColorConditionExpanded(barIndex) ? \"-\" : \"+\" }}\r\n </button>\r\n <span class=\"font-medium text-sm\"\r\n >{{ t(\"bar\") }} {{ barIndex }}</span\r\n >\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n addColorCondition(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n removeColorConditionIndex(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (isColorConditionExpanded(barIndex)) {\r\n <div class=\"p-3\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-2 mb-3\"\r\n >\r\n <span class=\"text-sm font-medium\">{{ t(\"conditions\") }}</span>\r\n <mt-button\r\n [label]=\"t('addCondition')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addColorCondition(barIndex)\"\r\n />\r\n </div>\r\n\r\n @for (\r\n condition of colorByCondition()[barIndex] || [];\r\n track trackByIndex($index);\r\n let condIndex = $index\r\n ) {\r\n <div class=\"p-3 border border-surface-200 rounded-lg mb-3\">\r\n <div\r\n class=\"grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-3 items-end\"\r\n >\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"condition.color\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'color',\r\n $event\r\n )\r\n \"\r\n />\r\n <mt-select-field\r\n [label]=\"t('condition')\"\r\n [ngModel]=\"condition.type\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'type',\r\n $event\r\n )\r\n \"\r\n [options]=\"colorConditionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-number-field\r\n [label]=\"\r\n condition.type === 'between' ? t('from') : t('value')\r\n \"\r\n [ngModel]=\"condition.value1\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value1',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n @if (condition.type === \"between\") {\r\n <mt-number-field\r\n [label]=\"t('to')\"\r\n [ngModel]=\"condition.value2\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value2',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n }\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeColorCondition(barIndex, condIndex)\"\r\n />\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3 mt-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"condition.labelEn || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelEn',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"condition.labelAr || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelAr',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((colorByCondition()[barIndex] || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getColorConditionIndexes().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Timeline Header Colors -->\r\n @if (shouldShowField(\"timelineHeaderColorsConfig\")) {\r\n <mt-card [title]=\"t('timelineHeaderColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().bgColor || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('bgColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().color || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('color', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Ring Gauge Configuration -->\r\n @if (shouldShowField(\"ringGaugeConfig\")) {\r\n <mt-card [title]=\"t('ringGaugeConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('centerProperty')\"\r\n [ngModel]=\"ringGaugeConfig().centerProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('centerProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('statusProperty')\"\r\n [ngModel]=\"ringGaugeConfig().statusProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('statusProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <div class=\"mt-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenProperties')\"\r\n [ngModel]=\"ringGaugeConfig().hiddenProperties || []\"\r\n (ngModelChange)=\"updateRingGaugeConfig('hiddenProperties', $event)\"\r\n [options]=\"ringGaugeHiddenOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Order Configuration -->\r\n @if (shouldShowField(\"orderConfig\")) {\r\n <mt-card [title]=\"t('orderConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4 mb-4\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n [ngModel]=\"orderConfig().operation || 'deleteNotEqual'\"\r\n (ngModelChange)=\"updateOrderConfig('operation', $event)\"\r\n [options]=\"orderOperationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('orderBy')\"\r\n [ngModel]=\"orderConfig().orderBy || ''\"\r\n (ngModelChange)=\"updateOrderConfig('orderBy', $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n />\r\n </div>\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"orderConfigurationDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addOrderItem')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOrderItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of orderConfig().order || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 flex flex-col gap-3 rounded-lg border border-surface-200 bg-surface-50 p-4 xl:flex-row xl:items-center\"\r\n >\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n <span class=\"text-sm font-medium w-auto xl:w-8\">{{ i + 1 }}.</span>\r\n <mt-text-field\r\n [ngModel]=\"item\"\r\n (ngModelChange)=\"updateOrderItem(i, $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n size=\"small\"\r\n class=\"min-w-0 flex-1\"\r\n />\r\n </div>\r\n <div class=\"flex items-center justify-end gap-1\">\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === 0\"\r\n (onClick)=\"moveOrderItemUp(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === (orderConfig().order || []).length - 1\"\r\n (onClick)=\"moveOrderItemDown(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOrderItem(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((orderConfig().order || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOrderItems\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card List Configuration -->\r\n @if (shouldShowField(\"cardListConfig\")) {\r\n <mt-card [title]=\"t('cardListConfiguration')\">\r\n <mt-multi-select-field\r\n [label]=\"t('hideProperties')\"\r\n [ngModel]=\"cardListConfig().hideProperties || []\"\r\n (ngModelChange)=\"updateCardListHideProperties($event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertiesToHide')\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Props Config As Index -->\r\n @if (shouldShowPropertiesViewSettings()) {\r\n <mt-card [title]=\"t('entityPreviewSettings')\">\r\n @if (propertiesViewRows().length === 0) {\r\n <div class=\"py-4 text-sm text-muted-color\">\r\n {{ t(\"selectPropertiesFirst\") }}\r\n </div>\r\n } @else {\r\n <div class=\"space-y-4\">\r\n @for (property of propertiesViewRows(); track property.key) {\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-50 p-5\">\r\n <div class=\"mb-4\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ property.label }}\r\n </div>\r\n @if (property.label !== property.key) {\r\n <div class=\"mt-1 text-xs text-muted-color\">\r\n {{ property.key }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('width')\"\r\n [ngModel]=\"property.config.width || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'width', $event)\r\n \"\r\n [placeholder]=\"'100%'\"\r\n size=\"small\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('colorProperty')\"\r\n [ngModel]=\"property.config.colorAsProperty || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(\r\n property.index,\r\n 'colorAsProperty',\r\n $event\r\n )\r\n \"\r\n [options]=\"selectedPropertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColorProperty')\"\r\n [showClear]=\"true\"\r\n [filter]=\"true\"\r\n size=\"small\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('border')\"\r\n [ngModel]=\"property.config.border || []\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'border', $event)\r\n \"\r\n [options]=\"borderOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hidden')\"\r\n [ngModel]=\"property.config.hidden || false\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'hidden', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Toggle Association -->\r\n @if (shouldShowField(\"toggleAssociation\")) {\r\n <mt-card [title]=\"t('toggleAssociation')\">\r\n <mt-toggle-field\r\n [label]=\"t('enableToggleAssociation')\"\r\n [ngModel]=\"toggleAssociation()\"\r\n (ngModelChange)=\"updateToggleAssociation($event)\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Translations -->\r\n @if (\r\n shouldShowField(\"propertyTranslations\") &&\r\n resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyTranslations')\">\r\n <div class=\"space-y-4\">\r\n @for (property of propertyTranslationRows(); track property.key) {\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-50 p-5\">\r\n <div class=\"mb-4\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ property.label }}\r\n </div>\r\n @if (property.label !== property.key) {\r\n <div class=\"mt-1 text-xs text-muted-color\">\r\n {{ property.key }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('englishLabel')\"\r\n [ngModel]=\"property.translation.en\"\r\n (ngModelChange)=\"\r\n updatePropertyTranslation(property.key, 'en', $event)\r\n \"\r\n [placeholder]=\"t('enterEnglishLabel')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('arabicLabel')\"\r\n [ngModel]=\"property.translation.ar\"\r\n (ngModelChange)=\"\r\n updatePropertyTranslation(property.key, 'ar', $event)\r\n \"\r\n [placeholder]=\"t('enterArabicLabel')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (propertyTranslationRows().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyTranslations\") }}\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Colors -->\r\n @if (\r\n shouldShowField(\"propertyColors\") && resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyColors')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyColors()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyColorsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyColorsPasteText()\"\r\n (ngModelChange)=\"propertyColorsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyColorsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyColorsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyColorsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForColor()\"\r\n (ngModelChange)=\"selectedPropertyForColor.set($event)\"\r\n [options]=\"availableColorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForColor()\"\r\n (onClick)=\"\r\n addPropertyColor(selectedPropertyForColor());\r\n selectedPropertyForColor.set('')\r\n \"\r\n [pTooltip]=\"t('addProperty')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Property Color List -->\r\n @for (propKey of getPropertyColorKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyColor(propKey)\"\r\n />\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('selectColorProperty')\"\r\n [ngModel]=\"propertyColors()[propKey]?.selectedKey || ''\"\r\n (ngModelChange)=\"updatePropertyColor(propKey, $event)\"\r\n [options]=\"allPropertyKeyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (getPropertyColorKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyColors\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Format X-Axis Configuration -->\r\n @if (shouldShowField(\"formatXAxis\")) {\r\n <mt-card [title]=\"t('formatXAxisConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatXAxisConfig().type\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('type', $event)\"\r\n [options]=\"formatXAxisTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n @if (\r\n formatXAxisConfig().type === \"dateToMonth\" ||\r\n formatXAxisConfig().type === \"month\"\r\n ) {\r\n <mt-toggle-field\r\n [label]=\"t('shortFormat')\"\r\n [ngModel]=\"formatXAxisConfig().shortFormate || false\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('shortFormate', $event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Extra Column From Lookup -->\r\n @if (shouldShowField(\"extraColumnFromLookup\")) {\r\n <mt-card [title]=\"t('extraColumnFromLookup')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableExtraColumnFromLookup')\"\r\n [ngModel]=\"tableColumnsConfig().extraCoulmnFromLookup || false\"\r\n (ngModelChange)=\"\r\n updateTableColumnsConfig('extraCoulmnFromLookup', $event)\r\n \"\r\n />\r\n\r\n @if (tableColumnsConfig().extraCoulmnFromLookup) {\r\n <mt-select-field\r\n [label]=\"t('lookup')\"\r\n [ngModel]=\"tableColumnsConfig().lookupId\"\r\n (ngModelChange)=\"updateTableColumnsConfig('lookupId', $event)\"\r\n [options]=\"lookups()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectLookup')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('groupedBy')\"\r\n [ngModel]=\"tableColumnsConfig().groupedBy\"\r\n (ngModelChange)=\"updateTableColumnsConfig('groupedBy', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"tableColumnsConfig().propKey\"\r\n (ngModelChange)=\"updateTableColumnsConfig('propKey', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: SliderField, selector: "mt-slider-field", inputs: ["field", "label", "animate", "class", "min", "max", "step", "hideNumber", "unit", "readonly", "pInputs", "required"], outputs: ["onChange", "onSlideEnd"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: IconField, selector: "mt-icon-field", inputs: ["label", "required"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3055
3131
|
}
|
|
3056
3132
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DisplaySettings, decorators: [{
|
|
3057
3133
|
type: Component,
|
|
@@ -3070,11 +3146,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3070
3146
|
ToggleField,
|
|
3071
3147
|
IconField,
|
|
3072
3148
|
Card,
|
|
3073
|
-
Tooltip
|
|
3074
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <!-- Header Configuration -->\r\n @if (\r\n shouldShowField(\"centerHeader\") || shouldShowField(\"advancedHeaderConfig\")\r\n ) {\r\n <mt-card [title]=\"t('headerConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n @if (shouldShowField(\"centerHeader\")) {\r\n <mt-toggle-field\r\n [label]=\"t('centerHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderCentered || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderCentered', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"advancedHeaderConfig\")) {\r\n <mt-toggle-field\r\n [label]=\"t('hideHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderHidden || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderHidden', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerColor')\"\r\n [ngModel]=\"headerCardConfig().headerColor || ''\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerColor', $event)\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('headerFontSize')\"\r\n [ngModel]=\"headerCardConfig().headerFontSize || 14\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerFontSize', $event)\"\r\n [min]=\"10\"\r\n [max]=\"48\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Colors Section (for cards) -->\r\n @if (\r\n shouldShowField(\"bgColor\") ||\r\n shouldShowField(\"textColor\") ||\r\n shouldShowField(\"icon\")\r\n ) {\r\n <mt-card [title]=\"t('cardColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n @if (shouldShowField(\"bgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"styleConfig()['background-color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('background-color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"textColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"styleConfig()['color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"icon\")) {\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"configAsType()['icon'] || ''\"\r\n (ngModelChange)=\"updateConfigAsType('icon', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"styleConfig()['iconColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconBgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconBgColor')\"\r\n [ngModel]=\"styleConfig()['iconBgColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconBgColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"positionTitle\")) {\r\n <mt-select-field\r\n [label]=\"t('positionTitle')\"\r\n [ngModel]=\"styleConfig()['justify-content'] || 'start'\"\r\n (ngModelChange)=\"updateStyleConfig('justify-content', $event)\"\r\n [options]=\"positionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Border Top Section -->\r\n @if (shouldShowField(\"borderTop\")) {\r\n <mt-card [title]=\"t('borderTop')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showBorderTop')\"\r\n [ngModel]=\"styleConfig()['border-top-show'] || false\"\r\n (ngModelChange)=\"updateBorderTopShow($event)\"\r\n />\r\n @if (styleConfig()[\"border-top-show\"]) {\r\n <mt-color-picker-field\r\n [label]=\"t('borderTopColor')\"\r\n [ngModel]=\"\r\n styleConfig()['border-top-color'] ||\r\n styleConfig()['border-color'] ||\r\n '#3b82f6'\r\n \"\r\n (ngModelChange)=\"updateBorderTopColor($event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Style Configuration -->\r\n @if (shouldShowField(\"cardStyleConfig\")) {\r\n <mt-card [title]=\"t('cardStyle')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4 mb-4\">\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"borderRadius\") }}:\r\n {{ cardStyleConfig().borderRadius || 8 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"cardStyleConfig().borderRadius || 8\"\r\n (ngModelChange)=\"updateCardStyleConfig('borderRadius', $event)\"\r\n [min]=\"0\"\r\n [max]=\"24\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <mt-color-picker-field\r\n [label]=\"t('cardBackgroundColor')\"\r\n [ngModel]=\"cardStyleConfig().backgroundColor || ''\"\r\n (ngModelChange)=\"updateCardStyleConfig('backgroundColor', $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Shadows -->\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"font-medium\">{{ t(\"shadows\") }}</span>\r\n <mt-button\r\n [label]=\"t('addShadow')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addShadow()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n shadow of cardStyleConfig().shadows || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"shadow\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeShadow(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-5 gap-2\">\r\n <mt-number-field\r\n [label]=\"t('x')\"\r\n [ngModel]=\"shadow.x\"\r\n (ngModelChange)=\"updateShadow(i, 'x', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('y')\"\r\n [ngModel]=\"shadow.y\"\r\n (ngModelChange)=\"updateShadow(i, 'y', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('blur')\"\r\n [ngModel]=\"shadow.blur\"\r\n (ngModelChange)=\"updateShadow(i, 'blur', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('spread')\"\r\n [ngModel]=\"shadow.spread\"\r\n (ngModelChange)=\"updateShadow(i, 'spread', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"shadow.color\"\r\n (ngModelChange)=\"updateShadow(i, 'color', $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Legend Settings -->\r\n @if (shouldShowField(\"legend\")) {\r\n <mt-card [title]=\"t('legendSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLegend')\"\r\n [ngModel]=\"legendConfig().show || false\"\r\n (ngModelChange)=\"updateLegend('show', $event)\"\r\n />\r\n @if (legendConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"legendConfig().position || 'bottom'\"\r\n (ngModelChange)=\"updateLegend('position', $event)\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"legendIconType\")) {\r\n <mt-select-field\r\n [label]=\"t('legendIconType')\"\r\n [ngModel]=\"legendConfig().iconType || 'circle'\"\r\n (ngModelChange)=\"updateLegend('iconType', $event)\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Settings -->\r\n @if (shouldShowField(\"label\")) {\r\n <mt-card [title]=\"t('labelSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabels')\"\r\n [ngModel]=\"labelConfig().show || false\"\r\n (ngModelChange)=\"updateLabel('show', $event)\"\r\n />\r\n @if (labelConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"labelConfig().position || 'inside'\"\r\n (ngModelChange)=\"updateLabel('position', $event)\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"showTotal\")) {\r\n <mt-toggle-field\r\n [label]=\"t('showTotalInTop')\"\r\n [ngModel]=\"labelConfig().showTotalInTop || false\"\r\n (ngModelChange)=\"updateLabel('showTotalInTop', $event)\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Center (for Pie/Donut charts) -->\r\n @if (shouldShowField(\"labelCenter\")) {\r\n <mt-card [title]=\"t('labelCenter')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideLabelCenter')\"\r\n [ngModel]=\"labelCenterConfig().hide || false\"\r\n (ngModelChange)=\"updateLabelCenterConfig('hide', $event)\"\r\n />\r\n @if (!labelCenterConfig().hide) {\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextEn')\"\r\n [ngModel]=\"labelCenterConfig().text?.en || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('en', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextAr')\"\r\n [ngModel]=\"labelCenterConfig().text?.ar || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('ar', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Override Labels -->\r\n @if (shouldShowField(\"overrideLabels\")) {\r\n <mt-card [title]=\"t('overrideLabels')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"overrideLabelsDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addLabel')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOverrideLabel()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n label of overrideLabels();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"label\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOverrideLabel(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"label.en\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'en', $event)\"\r\n [placeholder]=\"t('enterLabelEn')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"label.ar\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'ar', $event)\"\r\n [placeholder]=\"t('enterLabelAr')\"\r\n dir=\"rtl\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (overrideLabels().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOverrideLabels\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Sort Data Bars -->\r\n @if (shouldShowField(\"sortDataBars\")) {\r\n <mt-card [title]=\"t('sortDataBars')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-3 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableSorting')\"\r\n [ngModel]=\"sortDataBarsConfig().enable || false\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('enable', $event)\"\r\n />\r\n @if (sortDataBarsConfig().enable) {\r\n <mt-text-field\r\n [label]=\"t('sortBy')\"\r\n [ngModel]=\"sortDataBarsConfig().sortBy || ''\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('sortBy', $event)\"\r\n [placeholder]=\"t('propertyKey')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('order')\"\r\n [ngModel]=\"sortDataBarsConfig().order || 'asc'\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('order', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Default Colors (for charts) -->\r\n @if (shouldShowField(\"defaultColors\")) {\r\n <mt-card [title]=\"t('defaultColors')\">\r\n <div class=\"flex flex-wrap gap-2 mb-4\">\r\n @for (\r\n color of defaultColors();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"flex items-center gap-1 p-2 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-color-picker-field\r\n [ngModel]=\"color\"\r\n (ngModelChange)=\"updateDefaultColor(i, $event)\"\r\n />\r\n <mt-button\r\n icon=\"general.x-close\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeDefaultColor(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-2 items-center\">\r\n <span class=\"text-sm text-muted-color xl:mr-2\">{{ t(\"quickAdd\") }}:</span>\r\n @for (color of defaultColorPalette; track color) {\r\n <button\r\n type=\"button\"\r\n class=\"w-6 h-6 rounded cursor-pointer border border-surface-300 hover:scale-110 transition-transform\"\r\n [style.background-color]=\"color\"\r\n (click)=\"addDefaultColor(color)\"\r\n [pTooltip]=\"color\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n\r\n @if (defaultColors().length === 0) {\r\n <div class=\"text-center py-2 text-muted-color text-sm mt-2\">\r\n {{ t(\"noColorsSelected\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Info -->\r\n @if (shouldShowField(\"cardInfo\")) {\r\n <mt-card [title]=\"t('cardInfo')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showCardInfo')\"\r\n [ngModel]=\"cardInfo().show || false\"\r\n (ngModelChange)=\"updateCardInfoConfig('show', $event)\"\r\n />\r\n @if (cardInfo().show) {\r\n <mt-text-field\r\n [label]=\"t('cardInfoValue')\"\r\n [ngModel]=\"cardInfo().value || ''\"\r\n (ngModelChange)=\"updateCardInfoConfig('value', $event)\"\r\n [placeholder]=\"t('enterCardInfoValue')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Settings -->\r\n @if (shouldShowField(\"hideIndex\")) {\r\n <mt-card [title]=\"t('tableSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideIndex')\"\r\n [ngModel]=\"configAsType()['hideIndex'] || false\"\r\n (ngModelChange)=\"updateConfigAsType('hideIndex', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Map Settings -->\r\n @if (shouldShowField(\"mapChart\")) {\r\n <mt-card [title]=\"t('mapSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('mapType')\"\r\n [ngModel]=\"config()?.clientConfig?.['map'] || 'SaudiArabia'\"\r\n (ngModelChange)=\"updateMapType($event)\"\r\n [options]=\"mapOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Format Configuration -->\r\n @if (shouldShowField(\"format\")) {\r\n <mt-card [title]=\"t('formatConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatConfig().type\"\r\n (ngModelChange)=\"updateFormatConfig('type', $event)\"\r\n [options]=\"formatTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n\r\n @if (formatConfig().type === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"formatConfig().showCurrency || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrency', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showCurrencyTooltip')\"\r\n [ngModel]=\"formatConfig().showCurrencyTooltip || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrencyTooltip', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('handleLanguage')\"\r\n [ngModel]=\"formatConfig().handleLang || false\"\r\n (ngModelChange)=\"updateFormatConfig('handleLang', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hideSuffixes')\"\r\n [ngModel]=\"formatConfig().hideSuffixes || false\"\r\n (ngModelChange)=\"updateFormatConfig('hideSuffixes', $event)\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"custom\") {\r\n <mt-text-field\r\n [label]=\"t('customText')\"\r\n [ngModel]=\"formatConfig().customText || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customText', $event)\"\r\n [placeholder]=\"t('enterCustomText')\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"date\") {\r\n <mt-text-field\r\n [label]=\"t('dateFormat')\"\r\n [ngModel]=\"formatConfig().customDateFormat || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customDateFormat', $event)\"\r\n [placeholder]=\"'YYYY-MM-DD'\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Format Configuration -->\r\n @if (shouldShowField(\"tableFormat\")) {\r\n <mt-card [title]=\"t('tableFormatConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <!-- Colors -->\r\n <mt-color-picker-field\r\n [label]=\"t('headerTextColor')\"\r\n [ngModel]=\"tableFormatConfig().thTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().thBackgroundColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thBackgroundColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cellTextColor')\"\r\n [ngModel]=\"tableFormatConfig().tdTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().groupBackgroundColor || ''\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('groupBackgroundColor', $event)\r\n \"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupTextColor')\"\r\n [ngModel]=\"tableFormatConfig().groupTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('groupTextColor', $event)\"\r\n />\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n <!-- Font Settings -->\r\n <mt-toggle-field\r\n [label]=\"t('boldHeaderFont')\"\r\n [ngModel]=\"tableFormatConfig().thFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontBold', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('boldCellFont')\"\r\n [ngModel]=\"tableFormatConfig().tdFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontBold', $event)\"\r\n />\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"headerFontSize\") }}:\r\n {{ tableFormatConfig().thFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().thFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"cellFontSize\") }}:\r\n {{ tableFormatConfig().tdFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().tdFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-4 gap-4\">\r\n <!-- Options -->\r\n <mt-toggle-field\r\n [label]=\"t('hideTableSubheader')\"\r\n [ngModel]=\"tableFormatConfig().hideTableSubheader || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('hideTableSubheader', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('disableCurrencyFormat')\"\r\n [ngModel]=\"tableFormatConfig().disableCurrencyFormat || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('disableCurrencyFormat', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageAsProgressBar')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageAsProgressBar || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageAsProgressBar', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageStatus')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageStatus || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageStatus', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 gap-4\">\r\n <!-- Sort & Hidden Columns -->\r\n <mt-select-field\r\n [label]=\"t('sortColumn')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.column || ''\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('column', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumn')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('sortDirection')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.direction || 'asc'\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('direction', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenColumns')\"\r\n [ngModel]=\"tableFormatConfig().hiddenColumns || []\"\r\n (ngModelChange)=\"updateTableFormatConfig('hiddenColumns', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumns')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <mt-button\r\n [label]=\"t('resetToDefault')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"resetTableFormat()\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Color By Condition -->\r\n @if (shouldShowField(\"colorByCondition\")) {\r\n <mt-card [title]=\"t('colorByCondition')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"colorByConditionDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('add')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addColorConditionIndex()\"\r\n />\r\n </div>\r\n\r\n @for (barIndex of getColorConditionIndexes(); track barIndex) {\r\n <div class=\"mb-4 border border-surface-200 rounded-lg\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 p-3 bg-surface-50\">\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"text-sm text-muted-color\"\r\n (click)=\"toggleColorConditionExpanded(barIndex)\"\r\n >\r\n {{ isColorConditionExpanded(barIndex) ? \"-\" : \"+\" }}\r\n </button>\r\n <span class=\"font-medium text-sm\"\r\n >{{ t(\"bar\") }} {{ barIndex }}</span\r\n >\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n addColorCondition(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n removeColorConditionIndex(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (isColorConditionExpanded(barIndex)) {\r\n <div class=\"p-3\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"conditions\") }}</span>\r\n <mt-button\r\n [label]=\"t('addCondition')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addColorCondition(barIndex)\"\r\n />\r\n </div>\r\n\r\n @for (\r\n condition of colorByCondition()[barIndex] || [];\r\n track trackByIndex($index);\r\n let condIndex = $index\r\n ) {\r\n <div class=\"p-3 border border-surface-200 rounded-lg mb-3\">\r\n <div class=\"grid grid-cols-1 2xl:grid-cols-6 gap-3 items-end\">\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"condition.color\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'color',\r\n $event\r\n )\r\n \"\r\n />\r\n <mt-select-field\r\n [label]=\"t('condition')\"\r\n [ngModel]=\"condition.type\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'type',\r\n $event\r\n )\r\n \"\r\n [options]=\"colorConditionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-number-field\r\n [label]=\"\r\n condition.type === 'between' ? t('from') : t('value')\r\n \"\r\n [ngModel]=\"condition.value1\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value1',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n @if (condition.type === \"between\") {\r\n <mt-number-field\r\n [label]=\"t('to')\"\r\n [ngModel]=\"condition.value2\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value2',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n }\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeColorCondition(barIndex, condIndex)\"\r\n />\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3 mt-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"condition.labelEn || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelEn',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"condition.labelAr || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelAr',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((colorByCondition()[barIndex] || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getColorConditionIndexes().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Timeline Header Colors -->\r\n @if (shouldShowField(\"timelineHeaderColorsConfig\")) {\r\n <mt-card [title]=\"t('timelineHeaderColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().bgColor || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('bgColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().color || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('color', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Ring Gauge Configuration -->\r\n @if (shouldShowField(\"ringGaugeConfig\")) {\r\n <mt-card [title]=\"t('ringGaugeConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('centerProperty')\"\r\n [ngModel]=\"ringGaugeConfig().centerProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('centerProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('statusProperty')\"\r\n [ngModel]=\"ringGaugeConfig().statusProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('statusProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <div class=\"mt-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenProperties')\"\r\n [ngModel]=\"ringGaugeConfig().hiddenProperties || []\"\r\n (ngModelChange)=\"updateRingGaugeConfig('hiddenProperties', $event)\"\r\n [options]=\"ringGaugeHiddenOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Order Configuration -->\r\n @if (shouldShowField(\"orderConfig\")) {\r\n <mt-card [title]=\"t('orderConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4 mb-4\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n [ngModel]=\"orderConfig().operation || 'deleteNotEqual'\"\r\n (ngModelChange)=\"updateOrderConfig('operation', $event)\"\r\n [options]=\"orderOperationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('orderBy')\"\r\n [ngModel]=\"orderConfig().orderBy || ''\"\r\n (ngModelChange)=\"updateOrderConfig('orderBy', $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n />\r\n </div>\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"orderConfigurationDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addOrderItem')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOrderItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of orderConfig().order || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 flex flex-col gap-3 rounded-lg border border-surface-200 bg-surface-50 p-4 xl:flex-row xl:items-center\"\r\n >\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n <span class=\"text-sm font-medium w-auto xl:w-8\">{{ i + 1 }}.</span>\r\n <mt-text-field\r\n [ngModel]=\"item\"\r\n (ngModelChange)=\"updateOrderItem(i, $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n size=\"small\"\r\n class=\"min-w-0 flex-1\"\r\n />\r\n </div>\r\n <div class=\"flex items-center justify-end gap-1\">\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === 0\"\r\n (onClick)=\"moveOrderItemUp(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === (orderConfig().order || []).length - 1\"\r\n (onClick)=\"moveOrderItemDown(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOrderItem(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((orderConfig().order || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOrderItems\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card List Configuration -->\r\n @if (shouldShowField(\"cardListConfig\")) {\r\n <mt-card [title]=\"t('cardListConfiguration')\">\r\n <mt-multi-select-field\r\n [label]=\"t('hideProperties')\"\r\n [ngModel]=\"cardListConfig().hideProperties || []\"\r\n (ngModelChange)=\"updateCardListHideProperties($event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertiesToHide')\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Props Config As Index -->\r\n @if (shouldShowField(\"propsConfigAsIndex\")) {\r\n <mt-card [title]=\"t('entityPreviewSettings')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"text-sm text-muted-color\">{{ t(\"properties\") }}</span>\r\n <mt-button\r\n [label]=\"t('addProperty')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addPropsConfigItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of propsConfigAsIndex();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"property\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropsConfigItem(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 2xl:grid-cols-4 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('width')\"\r\n [ngModel]=\"item.width || ''\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'width', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('colorProperty')\"\r\n [ngModel]=\"item.colorAsProperty || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(i, 'colorAsProperty', $event)\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('border')\"\r\n [ngModel]=\"item.border || []\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'border', $event)\"\r\n [options]=\"borderOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hidden')\"\r\n [ngModel]=\"item.hidden || false\"\r\n (ngModelChange)=\"updatePropsConfigItem(i, 'hidden', $event)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Toggle Association -->\r\n @if (shouldShowField(\"toggleAssociation\")) {\r\n <mt-card [title]=\"t('toggleAssociation')\">\r\n <mt-toggle-field\r\n [label]=\"t('enableToggleAssociation')\"\r\n [ngModel]=\"toggleAssociation()\"\r\n (ngModelChange)=\"updateToggleAssociation($event)\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Translations -->\r\n @if (\r\n shouldShowField(\"propertyTranslations\") &&\r\n resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyTranslations')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyTranslations()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyTranslationsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyTranslationsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyTranslationsPasteText()\"\r\n (ngModelChange)=\"propertyTranslationsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyTranslationsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyTranslationsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyTranslationsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyTranslationsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForTranslation()\"\r\n (ngModelChange)=\"selectedPropertyForTranslation.set($event)\"\r\n [options]=\"availableTranslationOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertyToTranslate')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForTranslation()\"\r\n (onClick)=\"\r\n addPropertyTranslation(selectedPropertyForTranslation());\r\n selectedPropertyForTranslation.set('')\r\n \"\r\n [pTooltip]=\"t('addTranslation')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Translation List -->\r\n @for (propKey of getPropertyTranslationKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyTranslation(propKey)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('arabicLabel')\"\r\n [ngModel]=\"propertyTranslations()[propKey]?.ar || ''\"\r\n (ngModelChange)=\"updatePropertyTranslation(propKey, 'ar', $event)\"\r\n [placeholder]=\"t('enterArabicLabel')\"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('englishLabel')\"\r\n [ngModel]=\"propertyTranslations()[propKey]?.en || ''\"\r\n (ngModelChange)=\"updatePropertyTranslation(propKey, 'en', $event)\"\r\n [placeholder]=\"t('enterEnglishLabel')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getPropertyTranslationKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyTranslations\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Colors -->\r\n @if (\r\n shouldShowField(\"propertyColors\") && resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyColors')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyColors()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyColorsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyColorsPasteText()\"\r\n (ngModelChange)=\"propertyColorsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyColorsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyColorsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyColorsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForColor()\"\r\n (ngModelChange)=\"selectedPropertyForColor.set($event)\"\r\n [options]=\"availableColorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForColor()\"\r\n (onClick)=\"\r\n addPropertyColor(selectedPropertyForColor());\r\n selectedPropertyForColor.set('')\r\n \"\r\n [pTooltip]=\"t('addProperty')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Property Color List -->\r\n @for (propKey of getPropertyColorKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyColor(propKey)\"\r\n />\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('selectColorProperty')\"\r\n [ngModel]=\"propertyColors()[propKey]?.selectedKey || ''\"\r\n (ngModelChange)=\"updatePropertyColor(propKey, $event)\"\r\n [options]=\"allPropertyKeyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (getPropertyColorKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyColors\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Format X-Axis Configuration -->\r\n @if (shouldShowField(\"formatXAxis\")) {\r\n <mt-card [title]=\"t('formatXAxisConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatXAxisConfig().type\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('type', $event)\"\r\n [options]=\"formatXAxisTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n @if (\r\n formatXAxisConfig().type === \"dateToMonth\" ||\r\n formatXAxisConfig().type === \"month\"\r\n ) {\r\n <mt-toggle-field\r\n [label]=\"t('shortFormat')\"\r\n [ngModel]=\"formatXAxisConfig().shortFormate || false\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('shortFormate', $event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Extra Column From Lookup -->\r\n @if (shouldShowField(\"extraColumnFromLookup\")) {\r\n <mt-card [title]=\"t('extraColumnFromLookup')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableExtraColumnFromLookup')\"\r\n [ngModel]=\"tableColumnsConfig().extraCoulmnFromLookup || false\"\r\n (ngModelChange)=\"\r\n updateTableColumnsConfig('extraCoulmnFromLookup', $event)\r\n \"\r\n />\r\n\r\n @if (tableColumnsConfig().extraCoulmnFromLookup) {\r\n <mt-select-field\r\n [label]=\"t('lookup')\"\r\n [ngModel]=\"tableColumnsConfig().lookupId\"\r\n (ngModelChange)=\"updateTableColumnsConfig('lookupId', $event)\"\r\n [options]=\"lookups()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectLookup')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('groupedBy')\"\r\n [ngModel]=\"tableColumnsConfig().groupedBy\"\r\n (ngModelChange)=\"updateTableColumnsConfig('groupedBy', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"tableColumnsConfig().propKey\"\r\n (ngModelChange)=\"updateTableColumnsConfig('propKey', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n</div>\r\n" }]
|
|
3149
|
+
Tooltip,
|
|
3150
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"flex flex-col gap-6\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Header Configuration -->\r\n @if (\r\n shouldShowField(\"centerHeader\") || shouldShowField(\"advancedHeaderConfig\")\r\n ) {\r\n <mt-card [title]=\"t('headerConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-5\">\r\n @if (shouldShowField(\"centerHeader\")) {\r\n <mt-toggle-field\r\n [label]=\"t('centerHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderCentered || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderCentered', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"advancedHeaderConfig\")) {\r\n <mt-toggle-field\r\n [label]=\"t('hideHeader')\"\r\n [ngModel]=\"headerCardConfig().isHeaderHidden || false\"\r\n (ngModelChange)=\"updateHeaderCardConfig('isHeaderHidden', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerColor')\"\r\n [ngModel]=\"headerCardConfig().headerColor || ''\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerColor', $event)\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('headerFontSize')\"\r\n [ngModel]=\"headerCardConfig().headerFontSize || 14\"\r\n (ngModelChange)=\"updateHeaderCardConfig('headerFontSize', $event)\"\r\n [min]=\"10\"\r\n [max]=\"48\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Colors Section (for cards) -->\r\n @if (\r\n shouldShowField(\"bgColor\") ||\r\n shouldShowField(\"textColor\") ||\r\n shouldShowField(\"icon\")\r\n ) {\r\n <mt-card [title]=\"t('cardColors')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-5\">\r\n @if (shouldShowField(\"bgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"styleConfig()['background-color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('background-color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"textColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"styleConfig()['color'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('color', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"icon\")) {\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"configAsType()['icon'] || ''\"\r\n (ngModelChange)=\"updateConfigAsType('icon', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"styleConfig()['iconColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"iconBgColor\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('iconBgColor')\"\r\n [ngModel]=\"styleConfig()['iconBgColor'] || ''\"\r\n (ngModelChange)=\"updateStyleConfig('iconBgColor', $event)\"\r\n />\r\n }\r\n @if (shouldShowField(\"positionTitle\")) {\r\n <mt-select-field\r\n [label]=\"t('positionTitle')\"\r\n [ngModel]=\"styleConfig()['justify-content'] || 'start'\"\r\n (ngModelChange)=\"updateStyleConfig('justify-content', $event)\"\r\n [options]=\"positionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Border Top Section -->\r\n @if (shouldShowField(\"borderTop\")) {\r\n <mt-card [title]=\"t('borderTop')\">\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-5\">\r\n <mt-toggle-field\r\n [label]=\"t('showBorderTop')\"\r\n [ngModel]=\"styleConfig()['border-top-show'] || false\"\r\n (ngModelChange)=\"updateBorderTopShow($event)\"\r\n />\r\n @if (styleConfig()[\"border-top-show\"]) {\r\n <mt-color-picker-field\r\n [label]=\"t('borderTopColor')\"\r\n [ngModel]=\"\r\n styleConfig()['border-top-color'] ||\r\n styleConfig()['border-color'] ||\r\n '#3b82f6'\r\n \"\r\n (ngModelChange)=\"updateBorderTopColor($event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Style Configuration -->\r\n @if (shouldShowField(\"cardStyleConfig\")) {\r\n <mt-card [title]=\"t('cardStyle')\">\r\n <div class=\"grid grid-cols-1 gap-5 mb-6\">\r\n <mt-slider-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"cardStyleConfig().borderRadius || 8\"\r\n (ngModelChange)=\"updateCardStyleConfig('borderRadius', $event)\"\r\n [min]=\"0\"\r\n [max]=\"24\"\r\n [step]=\"1\"\r\n unit=\"px\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cardBackgroundColor')\"\r\n [ngModel]=\"cardStyleConfig().backgroundColor || ''\"\r\n (ngModelChange)=\"updateCardStyleConfig('backgroundColor', $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Shadows -->\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-3\">\r\n <span class=\"font-medium\">{{ t(\"shadows\") }}</span>\r\n <mt-button\r\n [label]=\"t('addShadow')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addShadow()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n shadow of cardStyleConfig().shadows || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"shadow\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeShadow(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-number-field\r\n [label]=\"t('x')\"\r\n [ngModel]=\"shadow.x\"\r\n (ngModelChange)=\"updateShadow(i, 'x', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('y')\"\r\n [ngModel]=\"shadow.y\"\r\n (ngModelChange)=\"updateShadow(i, 'y', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('blur')\"\r\n [ngModel]=\"shadow.blur\"\r\n (ngModelChange)=\"updateShadow(i, 'blur', $event)\"\r\n size=\"small\"\r\n />\r\n <mt-number-field\r\n [label]=\"t('spread')\"\r\n [ngModel]=\"shadow.spread\"\r\n (ngModelChange)=\"updateShadow(i, 'spread', $event)\"\r\n size=\"small\"\r\n />\r\n <div class=\"md:col-span-2\">\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"shadow.color\"\r\n (ngModelChange)=\"updateShadow(i, 'color', $event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Legend Settings -->\r\n @if (shouldShowField(\"legend\")) {\r\n <mt-card [title]=\"t('legendSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLegend')\"\r\n [ngModel]=\"legendConfig().show || false\"\r\n (ngModelChange)=\"updateLegend('show', $event)\"\r\n />\r\n @if (legendConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"legendConfig().position || 'bottom'\"\r\n (ngModelChange)=\"updateLegend('position', $event)\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"legendIconType\")) {\r\n <mt-select-field\r\n [label]=\"t('legendIconType')\"\r\n [ngModel]=\"legendConfig().iconType || 'circle'\"\r\n (ngModelChange)=\"updateLegend('iconType', $event)\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Settings -->\r\n @if (shouldShowField(\"label\")) {\r\n <mt-card [title]=\"t('labelSettings')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabels')\"\r\n [ngModel]=\"labelConfig().show || false\"\r\n (ngModelChange)=\"updateLabel('show', $event)\"\r\n />\r\n @if (labelConfig().show) {\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"labelConfig().position || 'inside'\"\r\n (ngModelChange)=\"updateLabel('position', $event)\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n @if (shouldShowField(\"showTotal\")) {\r\n <mt-toggle-field\r\n [label]=\"t('showTotalInTop')\"\r\n [ngModel]=\"labelConfig().showTotalInTop || false\"\r\n (ngModelChange)=\"updateLabel('showTotalInTop', $event)\"\r\n />\r\n }\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Label Center (for Pie/Donut charts) -->\r\n @if (shouldShowField(\"labelCenter\")) {\r\n <mt-card [title]=\"t('labelCenter')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideLabelCenter')\"\r\n [ngModel]=\"labelCenterConfig().hide || false\"\r\n (ngModelChange)=\"updateLabelCenterConfig('hide', $event)\"\r\n />\r\n @if (!labelCenterConfig().hide) {\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextEn')\"\r\n [ngModel]=\"labelCenterConfig().text?.en || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('en', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelCenterTextAr')\"\r\n [ngModel]=\"labelCenterConfig().text?.ar || ''\"\r\n (ngModelChange)=\"updateLabelCenterText('ar', $event)\"\r\n [placeholder]=\"t('enterLabelCenterText')\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Override Labels -->\r\n @if (shouldShowField(\"overrideLabels\")) {\r\n <mt-card [title]=\"t('overrideLabels')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"overrideLabelsDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addLabel')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOverrideLabel()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n label of overrideLabels();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"text-sm font-medium\"\r\n >{{ t(\"label\") }} {{ i + 1 }}</span\r\n >\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOverrideLabel(i)\"\r\n />\r\n </div>\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"label.en\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'en', $event)\"\r\n [placeholder]=\"t('enterLabelEn')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"label.ar\"\r\n (ngModelChange)=\"updateOverrideLabel(i, 'ar', $event)\"\r\n [placeholder]=\"t('enterLabelAr')\"\r\n dir=\"rtl\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (overrideLabels().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOverrideLabels\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Sort Data Bars -->\r\n @if (shouldShowField(\"sortDataBars\")) {\r\n <mt-card [title]=\"t('sortDataBars')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableSorting')\"\r\n [ngModel]=\"sortDataBarsConfig().enable || false\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('enable', $event)\"\r\n />\r\n @if (sortDataBarsConfig().enable) {\r\n <mt-text-field\r\n [label]=\"t('sortBy')\"\r\n [ngModel]=\"sortDataBarsConfig().sortBy || ''\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('sortBy', $event)\"\r\n [placeholder]=\"t('propertyKey')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('order')\"\r\n [ngModel]=\"sortDataBarsConfig().order || 'asc'\"\r\n (ngModelChange)=\"updateSortDataBarsConfig('order', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Default Colors (for charts) -->\r\n @if (shouldShowField(\"defaultColors\")) {\r\n <mt-card [title]=\"t('defaultColors')\">\r\n <div class=\"flex flex-wrap gap-2 mb-4\">\r\n @for (\r\n color of defaultColors();\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"flex items-center gap-1 p-2 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-color-picker-field\r\n [ngModel]=\"color\"\r\n (ngModelChange)=\"updateDefaultColor(i, $event)\"\r\n />\r\n <mt-button\r\n icon=\"general.x-close\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeDefaultColor(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-2 items-center\">\r\n <span class=\"text-sm text-muted-color xl:mr-2\"\r\n >{{ t(\"quickAdd\") }}:</span\r\n >\r\n @for (color of defaultColorPalette; track color) {\r\n <button\r\n type=\"button\"\r\n class=\"w-6 h-6 rounded cursor-pointer border border-surface-300 hover:scale-110 transition-transform\"\r\n [style.background-color]=\"color\"\r\n (click)=\"addDefaultColor(color)\"\r\n [pTooltip]=\"color\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n\r\n @if (defaultColors().length === 0) {\r\n <div class=\"text-center py-2 text-muted-color text-sm mt-2\">\r\n {{ t(\"noColorsSelected\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card Info -->\r\n @if (shouldShowField(\"cardInfo\")) {\r\n <mt-card [title]=\"t('cardInfo')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showCardInfo')\"\r\n [ngModel]=\"cardInfo().show || false\"\r\n (ngModelChange)=\"updateCardInfoConfig('show', $event)\"\r\n />\r\n @if (cardInfo().show) {\r\n <mt-text-field\r\n [label]=\"t('cardInfoValue')\"\r\n [ngModel]=\"cardInfo().value || ''\"\r\n (ngModelChange)=\"updateCardInfoConfig('value', $event)\"\r\n [placeholder]=\"t('enterCardInfoValue')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Settings -->\r\n @if (shouldShowField(\"hideIndex\")) {\r\n <mt-card [title]=\"t('tableSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('hideIndex')\"\r\n [ngModel]=\"configAsType()['hideIndex'] || false\"\r\n (ngModelChange)=\"updateConfigAsType('hideIndex', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Map Settings -->\r\n @if (shouldShowField(\"mapChart\")) {\r\n <mt-card [title]=\"t('mapSettings')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('mapType')\"\r\n [ngModel]=\"config()?.clientConfig?.['map'] || 'SaudiArabia'\"\r\n (ngModelChange)=\"updateMapType($event)\"\r\n [options]=\"mapOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Format Configuration -->\r\n @if (shouldShowField(\"format\")) {\r\n <mt-card [title]=\"t('formatConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatConfig().type\"\r\n (ngModelChange)=\"updateFormatConfig('type', $event)\"\r\n [options]=\"formatTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n\r\n @if (formatConfig().type === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"formatConfig().showCurrency || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrency', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showCurrencyTooltip')\"\r\n [ngModel]=\"formatConfig().showCurrencyTooltip || false\"\r\n (ngModelChange)=\"updateFormatConfig('showCurrencyTooltip', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('handleLanguage')\"\r\n [ngModel]=\"formatConfig().handleLang || false\"\r\n (ngModelChange)=\"updateFormatConfig('handleLang', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hideSuffixes')\"\r\n [ngModel]=\"formatConfig().hideSuffixes || false\"\r\n (ngModelChange)=\"updateFormatConfig('hideSuffixes', $event)\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"custom\") {\r\n <mt-text-field\r\n [label]=\"t('customText')\"\r\n [ngModel]=\"formatConfig().customText || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customText', $event)\"\r\n [placeholder]=\"t('enterCustomText')\"\r\n />\r\n }\r\n\r\n @if (formatConfig().type === \"date\") {\r\n <mt-text-field\r\n [label]=\"t('dateFormat')\"\r\n [ngModel]=\"formatConfig().customDateFormat || ''\"\r\n (ngModelChange)=\"updateFormatConfig('customDateFormat', $event)\"\r\n [placeholder]=\"'YYYY-MM-DD'\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Table Format Configuration -->\r\n @if (shouldShowField(\"tableFormat\")) {\r\n <mt-card [title]=\"t('tableFormatConfiguration')\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Colors -->\r\n <mt-color-picker-field\r\n [label]=\"t('headerTextColor')\"\r\n [ngModel]=\"tableFormatConfig().thTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('headerBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().thBackgroundColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('thBackgroundColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('cellTextColor')\"\r\n [ngModel]=\"tableFormatConfig().tdTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdTextColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupBackgroundColor')\"\r\n [ngModel]=\"tableFormatConfig().groupBackgroundColor || ''\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('groupBackgroundColor', $event)\r\n \"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('groupTextColor')\"\r\n [ngModel]=\"tableFormatConfig().groupTextColor || ''\"\r\n (ngModelChange)=\"updateTableFormatConfig('groupTextColor', $event)\"\r\n />\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Font Settings -->\r\n <mt-toggle-field\r\n [label]=\"t('boldHeaderFont')\"\r\n [ngModel]=\"tableFormatConfig().thFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontBold', $event)\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('boldCellFont')\"\r\n [ngModel]=\"tableFormatConfig().tdFontBold || false\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontBold', $event)\"\r\n />\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"headerFontSize\") }}:\r\n {{ tableFormatConfig().thFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().thFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('thFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n <div>\r\n <label class=\"block text-sm font-medium mb-2\"\r\n >{{ t(\"cellFontSize\") }}:\r\n {{ tableFormatConfig().tdFontSize || 14 }}px</label\r\n >\r\n <mt-slider-field\r\n [ngModel]=\"tableFormatConfig().tdFontSize || 14\"\r\n (ngModelChange)=\"updateTableFormatConfig('tdFontSize', $event)\"\r\n [min]=\"8\"\r\n [max]=\"32\"\r\n [step]=\"1\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Options -->\r\n <mt-toggle-field\r\n [label]=\"t('hideTableSubheader')\"\r\n [ngModel]=\"tableFormatConfig().hideTableSubheader || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('hideTableSubheader', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('disableCurrencyFormat')\"\r\n [ngModel]=\"tableFormatConfig().disableCurrencyFormat || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('disableCurrencyFormat', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageAsProgressBar')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageAsProgressBar || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageAsProgressBar', $event)\r\n \"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('showPercentageStatus')\"\r\n [ngModel]=\"tableFormatConfig().showPercentageStatus || false\"\r\n (ngModelChange)=\"\r\n updateTableFormatConfig('showPercentageStatus', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <!-- Sort & Hidden Columns -->\r\n <mt-select-field\r\n [label]=\"t('sortColumn')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.column || ''\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('column', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumn')\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('sortDirection')\"\r\n [ngModel]=\"tableFormatConfig().sortConfig?.direction || 'asc'\"\r\n (ngModelChange)=\"updateTableFormatSortConfig('direction', $event)\"\r\n [options]=\"orderTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenColumns')\"\r\n [ngModel]=\"tableFormatConfig().hiddenColumns || []\"\r\n (ngModelChange)=\"updateTableFormatConfig('hiddenColumns', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColumns')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"border-t border-surface-200 pt-4 mt-4\">\r\n <mt-button\r\n [label]=\"t('resetToDefault')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"resetTableFormat()\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Color By Condition -->\r\n @if (shouldShowField(\"colorByCondition\")) {\r\n <mt-card [title]=\"t('colorByCondition')\">\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"colorByConditionDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('add')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addColorConditionIndex()\"\r\n />\r\n </div>\r\n\r\n @for (barIndex of getColorConditionIndexes(); track barIndex) {\r\n <div class=\"mb-4 border border-surface-200 rounded-lg\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-2 p-3 bg-surface-50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"text-sm text-muted-color\"\r\n (click)=\"toggleColorConditionExpanded(barIndex)\"\r\n >\r\n {{ isColorConditionExpanded(barIndex) ? \"-\" : \"+\" }}\r\n </button>\r\n <span class=\"font-medium text-sm\"\r\n >{{ t(\"bar\") }} {{ barIndex }}</span\r\n >\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n addColorCondition(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n removeColorConditionIndex(barIndex); $event.stopPropagation()\r\n \"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (isColorConditionExpanded(barIndex)) {\r\n <div class=\"p-3\">\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-2 mb-3\"\r\n >\r\n <span class=\"text-sm font-medium\">{{ t(\"conditions\") }}</span>\r\n <mt-button\r\n [label]=\"t('addCondition')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addColorCondition(barIndex)\"\r\n />\r\n </div>\r\n\r\n @for (\r\n condition of colorByCondition()[barIndex] || [];\r\n track trackByIndex($index);\r\n let condIndex = $index\r\n ) {\r\n <div class=\"p-3 border border-surface-200 rounded-lg mb-3\">\r\n <div\r\n class=\"grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-3 items-end\"\r\n >\r\n <mt-color-picker-field\r\n [label]=\"t('color')\"\r\n [ngModel]=\"condition.color\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'color',\r\n $event\r\n )\r\n \"\r\n />\r\n <mt-select-field\r\n [label]=\"t('condition')\"\r\n [ngModel]=\"condition.type\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'type',\r\n $event\r\n )\r\n \"\r\n [options]=\"colorConditionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-number-field\r\n [label]=\"\r\n condition.type === 'between' ? t('from') : t('value')\r\n \"\r\n [ngModel]=\"condition.value1\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value1',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n @if (condition.type === \"between\") {\r\n <mt-number-field\r\n [label]=\"t('to')\"\r\n [ngModel]=\"condition.value2\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'value2',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n }\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeColorCondition(barIndex, condIndex)\"\r\n />\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-3 mt-3\">\r\n <mt-text-field\r\n [label]=\"t('labelEn')\"\r\n [ngModel]=\"condition.labelEn || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelEn',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('labelAr')\"\r\n [ngModel]=\"condition.labelAr || ''\"\r\n (ngModelChange)=\"\r\n updateColorCondition(\r\n barIndex,\r\n condIndex,\r\n 'labelAr',\r\n $event\r\n )\r\n \"\r\n size=\"small\"\r\n dir=\"rtl\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((colorByCondition()[barIndex] || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (getColorConditionIndexes().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noColorConditions\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Timeline Header Colors -->\r\n @if (shouldShowField(\"timelineHeaderColorsConfig\")) {\r\n <mt-card [title]=\"t('timelineHeaderColors')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().bgColor || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('bgColor', $event)\"\r\n />\r\n <mt-color-picker-field\r\n [label]=\"t('textColor')\"\r\n [ngModel]=\"timelineHeaderColorsSingle().color || ''\"\r\n (ngModelChange)=\"updateTimelineHeaderColorSingle('color', $event)\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Ring Gauge Configuration -->\r\n @if (shouldShowField(\"ringGaugeConfig\")) {\r\n <mt-card [title]=\"t('ringGaugeConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('centerProperty')\"\r\n [ngModel]=\"ringGaugeConfig().centerProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('centerProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('statusProperty')\"\r\n [ngModel]=\"ringGaugeConfig().statusProperty || ''\"\r\n (ngModelChange)=\"updateRingGaugeConfig('statusProperty', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <div class=\"mt-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('hiddenProperties')\"\r\n [ngModel]=\"ringGaugeConfig().hiddenProperties || []\"\r\n (ngModelChange)=\"updateRingGaugeConfig('hiddenProperties', $event)\"\r\n [options]=\"ringGaugeHiddenOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Order Configuration -->\r\n @if (shouldShowField(\"orderConfig\")) {\r\n <mt-card [title]=\"t('orderConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4 mb-4\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n [ngModel]=\"orderConfig().operation || 'deleteNotEqual'\"\r\n (ngModelChange)=\"updateOrderConfig('operation', $event)\"\r\n [options]=\"orderOperationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('orderBy')\"\r\n [ngModel]=\"orderConfig().orderBy || ''\"\r\n (ngModelChange)=\"updateOrderConfig('orderBy', $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n />\r\n </div>\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-4\">\r\n <span class=\"text-sm text-muted-color\">{{\r\n t(\"orderConfigurationDescription\")\r\n }}</span>\r\n <mt-button\r\n [label]=\"t('addOrderItem')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addOrderItem()\"\r\n />\r\n </div>\r\n\r\n @for (\r\n item of orderConfig().order || [];\r\n track trackByIndex($index);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"mb-3 flex flex-col gap-3 rounded-lg border border-surface-200 bg-surface-50 p-4 xl:flex-row xl:items-center\"\r\n >\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n <span class=\"text-sm font-medium w-auto xl:w-8\">{{ i + 1 }}.</span>\r\n <mt-text-field\r\n [ngModel]=\"item\"\r\n (ngModelChange)=\"updateOrderItem(i, $event)\"\r\n [placeholder]=\"t('enterPropertyKey')\"\r\n size=\"small\"\r\n class=\"min-w-0 flex-1\"\r\n />\r\n </div>\r\n <div class=\"flex items-center justify-end gap-1\">\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === 0\"\r\n (onClick)=\"moveOrderItemUp(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"i === (orderConfig().order || []).length - 1\"\r\n (onClick)=\"moveOrderItemDown(i)\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeOrderItem(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if ((orderConfig().order || []).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noOrderItems\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Card List Configuration -->\r\n @if (shouldShowField(\"cardListConfig\")) {\r\n <mt-card [title]=\"t('cardListConfiguration')\">\r\n <mt-multi-select-field\r\n [label]=\"t('hideProperties')\"\r\n [ngModel]=\"cardListConfig().hideProperties || []\"\r\n (ngModelChange)=\"updateCardListHideProperties($event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectPropertiesToHide')\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Props Config As Index -->\r\n @if (shouldShowPropertiesViewSettings()) {\r\n <mt-card [title]=\"t('entityPreviewSettings')\">\r\n @if (propertiesViewRows().length === 0) {\r\n <div class=\"py-4 text-sm text-muted-color\">\r\n {{ t(\"selectPropertiesFirst\") }}\r\n </div>\r\n } @else {\r\n <div class=\"space-y-4\">\r\n @for (property of propertiesViewRows(); track property.key) {\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-50 p-5\">\r\n <div class=\"mb-4\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ property.label }}\r\n </div>\r\n @if (property.label !== property.key) {\r\n <div class=\"mt-1 text-xs text-muted-color\">\r\n {{ property.key }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('width')\"\r\n [ngModel]=\"property.config.width || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'width', $event)\r\n \"\r\n [placeholder]=\"'100%'\"\r\n size=\"small\"\r\n />\r\n <mt-select-field\r\n [label]=\"t('colorProperty')\"\r\n [ngModel]=\"property.config.colorAsProperty || ''\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(\r\n property.index,\r\n 'colorAsProperty',\r\n $event\r\n )\r\n \"\r\n [options]=\"selectedPropertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectColorProperty')\"\r\n [showClear]=\"true\"\r\n [filter]=\"true\"\r\n size=\"small\"\r\n />\r\n <mt-multi-select-field\r\n [label]=\"t('border')\"\r\n [ngModel]=\"property.config.border || []\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'border', $event)\r\n \"\r\n [options]=\"borderOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('hidden')\"\r\n [ngModel]=\"property.config.hidden || false\"\r\n (ngModelChange)=\"\r\n updatePropsConfigItem(property.index, 'hidden', $event)\r\n \"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Toggle Association -->\r\n @if (shouldShowField(\"toggleAssociation\")) {\r\n <mt-card [title]=\"t('toggleAssociation')\">\r\n <mt-toggle-field\r\n [label]=\"t('enableToggleAssociation')\"\r\n [ngModel]=\"toggleAssociation()\"\r\n (ngModelChange)=\"updateToggleAssociation($event)\"\r\n />\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Translations -->\r\n @if (\r\n shouldShowField(\"propertyTranslations\") &&\r\n resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyTranslations')\">\r\n <div class=\"space-y-4\">\r\n @for (property of propertyTranslationRows(); track property.key) {\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-50 p-5\">\r\n <div class=\"mb-4\">\r\n <div class=\"text-sm font-semibold text-surface-900\">\r\n {{ property.label }}\r\n </div>\r\n @if (property.label !== property.key) {\r\n <div class=\"mt-1 text-xs text-muted-color\">\r\n {{ property.key }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-text-field\r\n [label]=\"t('englishLabel')\"\r\n [ngModel]=\"property.translation.en\"\r\n (ngModelChange)=\"\r\n updatePropertyTranslation(property.key, 'en', $event)\r\n \"\r\n [placeholder]=\"t('enterEnglishLabel')\"\r\n size=\"small\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('arabicLabel')\"\r\n [ngModel]=\"property.translation.ar\"\r\n (ngModelChange)=\"\r\n updatePropertyTranslation(property.key, 'ar', $event)\r\n \"\r\n [placeholder]=\"t('enterArabicLabel')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (propertyTranslationRows().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyTranslations\") }}\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Property Colors -->\r\n @if (\r\n shouldShowField(\"propertyColors\") && resolvedSelectedProperties().length > 0\r\n ) {\r\n <mt-card [title]=\"t('propertyColors')\">\r\n <ng-template #cardEnd>\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"copyPropertyColors()\"\r\n [pTooltip]=\"t('copyConfig')\"\r\n />\r\n <mt-button\r\n icon=\"general.clipboard\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n [pTooltip]=\"t('pasteConfig')\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n @if (showPropertyColorsPaste()) {\r\n <div\r\n class=\"mb-4 p-4 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteConfiguration')\"\r\n [ngModel]=\"propertyColorsPasteText()\"\r\n (ngModelChange)=\"propertyColorsPasteText.set($event)\"\r\n [placeholder]=\"t('pasteConfigurationPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (propertyColorsPasteError()) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n propertyColorsPasteError()\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-3\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePropertyColorsPaste()\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPropertyColorsPaste()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Property Selection -->\r\n <div class=\"mb-4\">\r\n <div class=\"flex flex-wrap items-end gap-2 xl:flex-nowrap\">\r\n <div class=\"flex-1\">\r\n <mt-select-field\r\n [label]=\"t('selectProperty')\"\r\n [ngModel]=\"selectedPropertyForColor()\"\r\n (ngModelChange)=\"selectedPropertyForColor.set($event)\"\r\n [options]=\"availableColorOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"!selectedPropertyForColor()\"\r\n (onClick)=\"\r\n addPropertyColor(selectedPropertyForColor());\r\n selectedPropertyForColor.set('')\r\n \"\r\n [pTooltip]=\"t('addProperty')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Property Color List -->\r\n @for (propKey of getPropertyColorKeys(); track propKey) {\r\n <div\r\n class=\"mb-3 rounded-lg border border-surface-200 bg-surface-50 p-4\"\r\n >\r\n <div class=\"flex flex-wrap items-center justify-between gap-2 mb-2\">\r\n <span class=\"font-medium text-sm\">{{ propKey }}</span>\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removePropertyColor(propKey)\"\r\n />\r\n </div>\r\n <mt-select-field\r\n [label]=\"t('selectColorProperty')\"\r\n [ngModel]=\"propertyColors()[propKey]?.selectedKey || ''\"\r\n (ngModelChange)=\"updatePropertyColor(propKey, $event)\"\r\n [options]=\"allPropertyKeyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n size=\"small\"\r\n />\r\n </div>\r\n }\r\n\r\n @if (getPropertyColorKeys().length === 0) {\r\n <div class=\"text-center py-4 text-muted-color\">\r\n {{ t(\"noPropertyColors\") }}\r\n </div>\r\n }\r\n </mt-card>\r\n }\r\n\r\n <!-- Format X-Axis Configuration -->\r\n @if (shouldShowField(\"formatXAxis\")) {\r\n <mt-card [title]=\"t('formatXAxisConfiguration')\">\r\n <div class=\"grid grid-cols-1 xl:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('formatType')\"\r\n [ngModel]=\"formatXAxisConfig().type\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('type', $event)\"\r\n [options]=\"formatXAxisTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFormat')\"\r\n />\r\n @if (\r\n formatXAxisConfig().type === \"dateToMonth\" ||\r\n formatXAxisConfig().type === \"month\"\r\n ) {\r\n <mt-toggle-field\r\n [label]=\"t('shortFormat')\"\r\n [ngModel]=\"formatXAxisConfig().shortFormate || false\"\r\n (ngModelChange)=\"updateFormatXAxisConfig('shortFormate', $event)\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <!-- Extra Column From Lookup -->\r\n @if (shouldShowField(\"extraColumnFromLookup\")) {\r\n <mt-card [title]=\"t('extraColumnFromLookup')\">\r\n <div class=\"grid grid-cols-1 gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('enableExtraColumnFromLookup')\"\r\n [ngModel]=\"tableColumnsConfig().extraCoulmnFromLookup || false\"\r\n (ngModelChange)=\"\r\n updateTableColumnsConfig('extraCoulmnFromLookup', $event)\r\n \"\r\n />\r\n\r\n @if (tableColumnsConfig().extraCoulmnFromLookup) {\r\n <mt-select-field\r\n [label]=\"t('lookup')\"\r\n [ngModel]=\"tableColumnsConfig().lookupId\"\r\n (ngModelChange)=\"updateTableColumnsConfig('lookupId', $event)\"\r\n [options]=\"lookups()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectLookup')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('groupedBy')\"\r\n [ngModel]=\"tableColumnsConfig().groupedBy\"\r\n (ngModelChange)=\"updateTableColumnsConfig('groupedBy', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"tableColumnsConfig().propKey\"\r\n (ngModelChange)=\"updateTableColumnsConfig('propKey', $event)\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectProperty')\"\r\n />\r\n }\r\n </div>\r\n </mt-card>\r\n }\r\n</div>\r\n" }]
|
|
3075
3151
|
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartType: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartType", required: false }] }], availableProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableProperties", required: false }] }], selectedProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedProperties", required: false }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], clientConfigChange: [{ type: i0.Output, args: ["clientConfigChange"] }] } });
|
|
3076
3152
|
|
|
3077
3153
|
class DefaultControlUi {
|
|
3154
|
+
showIconSettings = input(false, ...(ngDevMode ? [{ debugName: "showIconSettings" }] : []));
|
|
3155
|
+
layoutComponent = input(null, ...(ngDevMode ? [{ debugName: "layoutComponent" }] : []));
|
|
3078
3156
|
config = signal({
|
|
3079
3157
|
title: '',
|
|
3080
3158
|
titleFontSize: 16,
|
|
@@ -3083,6 +3161,9 @@ class DefaultControlUi {
|
|
|
3083
3161
|
subtitle: '',
|
|
3084
3162
|
subtitleFontSize: 14,
|
|
3085
3163
|
subtitleColor: '#666666',
|
|
3164
|
+
icon: '',
|
|
3165
|
+
iconColor: '#4caf50',
|
|
3166
|
+
iconBackgroundColor: 'rgba(76, 175, 80, 0.1)',
|
|
3086
3167
|
backgroundColor: '#ffffff',
|
|
3087
3168
|
borderColor: '#e0e0e0',
|
|
3088
3169
|
borderRadius: 8,
|
|
@@ -3100,6 +3181,9 @@ class DefaultControlUi {
|
|
|
3100
3181
|
];
|
|
3101
3182
|
onChange = () => { };
|
|
3102
3183
|
onTouched = () => { };
|
|
3184
|
+
supportsSubtitle = computed(() => {
|
|
3185
|
+
return this.layoutComponent() === 'topbar';
|
|
3186
|
+
}, ...(ngDevMode ? [{ debugName: "supportsSubtitle" }] : []));
|
|
3103
3187
|
writeValue(value) {
|
|
3104
3188
|
if (value) {
|
|
3105
3189
|
this.config.set({ ...this.config(), ...value });
|
|
@@ -3118,13 +3202,13 @@ class DefaultControlUi {
|
|
|
3118
3202
|
this.onTouched();
|
|
3119
3203
|
}
|
|
3120
3204
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DefaultControlUi, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3121
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DefaultControlUi, isStandalone: true, selector: "mt-default-control-ui", providers: [
|
|
3205
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DefaultControlUi, isStandalone: true, selector: "mt-default-control-ui", inputs: { showIconSettings: { classPropertyName: "showIconSettings", publicName: "showIconSettings", isSignal: true, isRequired: false, transformFunction: null }, layoutComponent: { classPropertyName: "layoutComponent", publicName: "layoutComponent", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
3122
3206
|
{
|
|
3123
3207
|
provide: NG_VALUE_ACCESSOR,
|
|
3124
3208
|
useExisting: forwardRef(() => DefaultControlUi),
|
|
3125
3209
|
multi: true,
|
|
3126
3210
|
},
|
|
3127
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls'\"\r\n>\r\n <
|
|
3211
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls'\"\r\n>\r\n <mt-card [title]=\"t('chartTitle')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\r\n <mt-text-field\r\n [label]=\"t('chartTitle')\"\r\n [ngModel]=\"config().title\"\r\n (ngModelChange)=\"updateConfig({ title: $event })\"\r\n [placeholder]=\"t('chartTitlePlaceholder')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('titleFontSize')\"\r\n [ngModel]=\"config().titleFontSize\"\r\n (ngModelChange)=\"updateConfig({ titleFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFontSize')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('titleColor')\"\r\n [ngModel]=\"config().titleColor\"\r\n (ngModelChange)=\"updateConfig({ titleColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n </div>\r\n </mt-card>\r\n\r\n @if (showIconSettings()) {\r\n <mt-card [title]=\"t('icon')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-3\">\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"config().icon\"\r\n (ngModelChange)=\"updateConfig({ icon: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"config().iconColor\"\r\n (ngModelChange)=\"updateConfig({ iconColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('iconBackgroundColor')\"\r\n [ngModel]=\"config().iconBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ iconBackgroundColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n @if (supportsSubtitle()) {\r\n <mt-card [title]=\"t('subtitle')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showSubtitle')\"\r\n [ngModel]=\"config().showSubtitle\"\r\n (ngModelChange)=\"updateConfig({ showSubtitle: $event })\"\r\n toggleShape=\"card\"\r\n size=\"small\"\r\n />\r\n\r\n <div\r\n class=\"grid grid-cols-1 gap-4 rounded-xl border border-surface-200 bg-surface-50 p-4 transition-opacity xl:grid-cols-2\"\r\n [class.opacity-60]=\"!config().showSubtitle\"\r\n >\r\n <mt-text-field\r\n [label]=\"t('subtitle')\"\r\n [ngModel]=\"config().subtitle\"\r\n (ngModelChange)=\"updateConfig({ subtitle: $event })\"\r\n [placeholder]=\"t('subtitlePlaceholder')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('subtitleFontSize')\"\r\n [ngModel]=\"config().subtitleFontSize\"\r\n (ngModelChange)=\"updateConfig({ subtitleFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFontSize')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('subtitleColor')\"\r\n [ngModel]=\"config().subtitleColor\"\r\n (ngModelChange)=\"updateConfig({ subtitleColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <mt-card [title]=\"t('backgroundColor')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"config().backgroundColor\"\r\n (ngModelChange)=\"updateConfig({ backgroundColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('borderColor')\"\r\n [ngModel]=\"config().borderColor\"\r\n (ngModelChange)=\"updateConfig({ borderColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"50\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('padding')\"\r\n [ngModel]=\"config().padding\"\r\n (ngModelChange)=\"updateConfig({ padding: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </mt-card>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: IconField, selector: "mt-icon-field", inputs: ["label", "required"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3128
3212
|
}
|
|
3129
3213
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DefaultControlUi, decorators: [{
|
|
3130
3214
|
type: Component,
|
|
@@ -3137,14 +3221,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3137
3221
|
ColorPickerField,
|
|
3138
3222
|
ToggleField,
|
|
3139
3223
|
NumberField,
|
|
3140
|
-
|
|
3224
|
+
IconField,
|
|
3225
|
+
Card,
|
|
3226
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3141
3227
|
{
|
|
3142
3228
|
provide: NG_VALUE_ACCESSOR,
|
|
3143
3229
|
useExisting: forwardRef(() => DefaultControlUi),
|
|
3144
3230
|
multi: true,
|
|
3145
3231
|
},
|
|
3146
|
-
], template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls'\"\r\n>\r\n <
|
|
3147
|
-
}] });
|
|
3232
|
+
], template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls'\"\r\n>\r\n <mt-card [title]=\"t('chartTitle')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\r\n <mt-text-field\r\n [label]=\"t('chartTitle')\"\r\n [ngModel]=\"config().title\"\r\n (ngModelChange)=\"updateConfig({ title: $event })\"\r\n [placeholder]=\"t('chartTitlePlaceholder')\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('titleFontSize')\"\r\n [ngModel]=\"config().titleFontSize\"\r\n (ngModelChange)=\"updateConfig({ titleFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFontSize')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('titleColor')\"\r\n [ngModel]=\"config().titleColor\"\r\n (ngModelChange)=\"updateConfig({ titleColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n </div>\r\n </mt-card>\r\n\r\n @if (showIconSettings()) {\r\n <mt-card [title]=\"t('icon')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-3\">\r\n <mt-icon-field\r\n [label]=\"t('icon')\"\r\n [ngModel]=\"config().icon\"\r\n (ngModelChange)=\"updateConfig({ icon: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('iconColor')\"\r\n [ngModel]=\"config().iconColor\"\r\n (ngModelChange)=\"updateConfig({ iconColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('iconBackgroundColor')\"\r\n [ngModel]=\"config().iconBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ iconBackgroundColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n @if (supportsSubtitle()) {\r\n <mt-card [title]=\"t('subtitle')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showSubtitle')\"\r\n [ngModel]=\"config().showSubtitle\"\r\n (ngModelChange)=\"updateConfig({ showSubtitle: $event })\"\r\n toggleShape=\"card\"\r\n size=\"small\"\r\n />\r\n\r\n <div\r\n class=\"grid grid-cols-1 gap-4 rounded-xl border border-surface-200 bg-surface-50 p-4 transition-opacity xl:grid-cols-2\"\r\n [class.opacity-60]=\"!config().showSubtitle\"\r\n >\r\n <mt-text-field\r\n [label]=\"t('subtitle')\"\r\n [ngModel]=\"config().subtitle\"\r\n (ngModelChange)=\"updateConfig({ subtitle: $event })\"\r\n [placeholder]=\"t('subtitlePlaceholder')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('subtitleFontSize')\"\r\n [ngModel]=\"config().subtitleFontSize\"\r\n (ngModelChange)=\"updateConfig({ subtitleFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectFontSize')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('subtitleColor')\"\r\n [ngModel]=\"config().subtitleColor\"\r\n (ngModelChange)=\"updateConfig({ subtitleColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n [disabled]=\"!config().showSubtitle\"\r\n />\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n\r\n <mt-card [title]=\"t('backgroundColor')\">\r\n <div class=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\r\n <mt-color-picker-field\r\n [label]=\"t('backgroundColor')\"\r\n [ngModel]=\"config().backgroundColor\"\r\n (ngModelChange)=\"updateConfig({ backgroundColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('borderColor')\"\r\n [ngModel]=\"config().borderColor\"\r\n (ngModelChange)=\"updateConfig({ borderColor: $event })\"\r\n [placeholder]=\"t('colorPlaceholder')\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"50\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('padding')\"\r\n [ngModel]=\"config().padding\"\r\n (ngModelChange)=\"updateConfig({ padding: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </mt-card>\r\n</div>\r\n" }]
|
|
3233
|
+
}], propDecorators: { showIconSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIconSettings", required: false }] }], layoutComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "layoutComponent", required: false }] }] } });
|
|
3148
3234
|
|
|
3149
3235
|
class PieControlUi {
|
|
3150
3236
|
config = signal({
|
|
@@ -3264,7 +3350,7 @@ class PieControlUi {
|
|
|
3264
3350
|
useExisting: forwardRef(() => PieControlUi),
|
|
3265
3351
|
multi: true,
|
|
3266
3352
|
},
|
|
3267
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.pie'\"\r\n>\r\n <!-- Basic Chart Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"pieSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('radius')\"\r\n [ngModel]=\"config().radius\"\r\n (ngModelChange)=\"updateConfig({ radius: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('thickness')\"\r\n [ngModel]=\"config().thickness\"\r\n (ngModelChange)=\"updateConfig({ thickness: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('padAngle')\"\r\n [ngModel]=\"config().padAngle\"\r\n (ngModelChange)=\"updateConfig({ padAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"20\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"50\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('centerX')\"\r\n [ngModel]=\"config().centerX\"\r\n (ngModelChange)=\"updateConfig({ centerX: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('centerY')\"\r\n [ngModel]=\"config().centerY\"\r\n (ngModelChange)=\"updateConfig({ centerY: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('startAngle')\"\r\n [ngModel]=\"config().startAngle\"\r\n (ngModelChange)=\"updateConfig({ startAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('endAngle')\"\r\n [ngModel]=\"config().endAngle\"\r\n (ngModelChange)=\"updateConfig({ endAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('roseType')\"\r\n [ngModel]=\"config().roseType\"\r\n (ngModelChange)=\"updateConfig({ roseType: $event })\"\r\n [options]=\"roseTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Legend Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"legendSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('useEnhancedLegend')\"\r\n [ngModel]=\"config().useEnhancedLegend\"\r\n (ngModelChange)=\"updateConfig({ useEnhancedLegend: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"config().legendPosition\"\r\n (ngModelChange)=\"updateConfig({ legendPosition: $event })\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendVerticalAlign')\"\r\n [ngModel]=\"config().legendVerticalAlign\"\r\n (ngModelChange)=\"updateConfig({ legendVerticalAlign: $event })\"\r\n [options]=\"legendVerticalAlignOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendOrientation')\"\r\n [ngModel]=\"config().legendOrientation\"\r\n (ngModelChange)=\"updateConfig({ legendOrientation: $event })\"\r\n [options]=\"legendOrientationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendType')\"\r\n [ngModel]=\"config().legendType\"\r\n (ngModelChange)=\"updateConfig({ legendType: $event })\"\r\n [options]=\"legendTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendFontSize')\"\r\n [ngModel]=\"config().legendFontSize\"\r\n (ngModelChange)=\"updateConfig({ legendFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('legendFontColor')\"\r\n [ngModel]=\"config().legendFontColor\"\r\n (ngModelChange)=\"updateConfig({ legendFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendIcon')\"\r\n [ngModel]=\"config().legendIcon\"\r\n (ngModelChange)=\"updateConfig({ legendIcon: $event })\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"config().labelPosition\"\r\n (ngModelChange)=\"updateConfig({ labelPosition: $event })\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('totalValueFontSize')\"\r\n [ngModel]=\"config().totalValueFontSize\"\r\n (ngModelChange)=\"updateConfig({ totalValueFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFormatter')\"\r\n [ngModel]=\"config().labelFormatter\"\r\n (ngModelChange)=\"updateConfig({ labelFormatter: $event })\"\r\n [options]=\"labelFormatterOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('showLabelLine')\"\r\n [ngModel]=\"config().showLabelLine\"\r\n (ngModelChange)=\"updateConfig({ showLabelLine: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('tooltipTrigger')\"\r\n [ngModel]=\"config().tooltipTrigger\"\r\n (ngModelChange)=\"updateConfig({ tooltipTrigger: $event })\"\r\n [options]=\"tooltipTriggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Animation Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"animationSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('animation')\"\r\n [ngModel]=\"config().animation\"\r\n (ngModelChange)=\"updateConfig({ animation: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('animationDuration')\"\r\n [ngModel]=\"config().animationDuration\"\r\n (ngModelChange)=\"updateConfig({ animationDuration: $event })\"\r\n [min]=\"0\"\r\n [max]=\"5000\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('explode')\"\r\n [ngModel]=\"config().explode\"\r\n (ngModelChange)=\"updateConfig({ explode: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3353
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.pie'\"\r\n>\r\n <!-- Basic Chart Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"pieSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('radius')\"\r\n [ngModel]=\"config().radius\"\r\n (ngModelChange)=\"updateConfig({ radius: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('thickness')\"\r\n [ngModel]=\"config().thickness\"\r\n (ngModelChange)=\"updateConfig({ thickness: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('padAngle')\"\r\n [ngModel]=\"config().padAngle\"\r\n (ngModelChange)=\"updateConfig({ padAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"20\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"50\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('centerX')\"\r\n [ngModel]=\"config().centerX\"\r\n (ngModelChange)=\"updateConfig({ centerX: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('centerY')\"\r\n [ngModel]=\"config().centerY\"\r\n (ngModelChange)=\"updateConfig({ centerY: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('startAngle')\"\r\n [ngModel]=\"config().startAngle\"\r\n (ngModelChange)=\"updateConfig({ startAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('endAngle')\"\r\n [ngModel]=\"config().endAngle\"\r\n (ngModelChange)=\"updateConfig({ endAngle: $event })\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('roseType')\"\r\n [ngModel]=\"config().roseType\"\r\n (ngModelChange)=\"updateConfig({ roseType: $event })\"\r\n [options]=\"roseTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Legend Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"legendSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('useEnhancedLegend')\"\r\n [ngModel]=\"config().useEnhancedLegend\"\r\n (ngModelChange)=\"updateConfig({ useEnhancedLegend: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendPosition')\"\r\n [ngModel]=\"config().legendPosition\"\r\n (ngModelChange)=\"updateConfig({ legendPosition: $event })\"\r\n [options]=\"legendPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendVerticalAlign')\"\r\n [ngModel]=\"config().legendVerticalAlign\"\r\n (ngModelChange)=\"updateConfig({ legendVerticalAlign: $event })\"\r\n [options]=\"legendVerticalAlignOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendOrientation')\"\r\n [ngModel]=\"config().legendOrientation\"\r\n (ngModelChange)=\"updateConfig({ legendOrientation: $event })\"\r\n [options]=\"legendOrientationOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendType')\"\r\n [ngModel]=\"config().legendType\"\r\n (ngModelChange)=\"updateConfig({ legendType: $event })\"\r\n [options]=\"legendTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendFontSize')\"\r\n [ngModel]=\"config().legendFontSize\"\r\n (ngModelChange)=\"updateConfig({ legendFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('legendFontColor')\"\r\n [ngModel]=\"config().legendFontColor\"\r\n (ngModelChange)=\"updateConfig({ legendFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendIcon')\"\r\n [ngModel]=\"config().legendIcon\"\r\n (ngModelChange)=\"updateConfig({ legendIcon: $event })\"\r\n [options]=\"legendIconOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"config().labelPosition\"\r\n (ngModelChange)=\"updateConfig({ labelPosition: $event })\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('totalValueFontSize')\"\r\n [ngModel]=\"config().totalValueFontSize\"\r\n (ngModelChange)=\"updateConfig({ totalValueFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFormatter')\"\r\n [ngModel]=\"config().labelFormatter\"\r\n (ngModelChange)=\"updateConfig({ labelFormatter: $event })\"\r\n [options]=\"labelFormatterOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('showLabelLine')\"\r\n [ngModel]=\"config().showLabelLine\"\r\n (ngModelChange)=\"updateConfig({ showLabelLine: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('tooltipTrigger')\"\r\n [ngModel]=\"config().tooltipTrigger\"\r\n (ngModelChange)=\"updateConfig({ tooltipTrigger: $event })\"\r\n [options]=\"tooltipTriggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Animation Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"animationSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('animation')\"\r\n [ngModel]=\"config().animation\"\r\n (ngModelChange)=\"updateConfig({ animation: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('animationDuration')\"\r\n [ngModel]=\"config().animationDuration\"\r\n (ngModelChange)=\"updateConfig({ animationDuration: $event })\"\r\n [min]=\"0\"\r\n [max]=\"5000\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('explode')\"\r\n [ngModel]=\"config().explode\"\r\n (ngModelChange)=\"updateConfig({ explode: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3268
3354
|
}
|
|
3269
3355
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PieControlUi, decorators: [{
|
|
3270
3356
|
type: Component,
|
|
@@ -3392,7 +3478,7 @@ class BarControlUi {
|
|
|
3392
3478
|
useExisting: forwardRef(() => BarControlUi),
|
|
3393
3479
|
multi: true,
|
|
3394
3480
|
},
|
|
3395
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.bar'\"\r\n>\r\n <!-- Bar Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"barSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('barWidth')\"\r\n [ngModel]=\"config().barWidth\"\r\n (ngModelChange)=\"updateConfig({ barWidth: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n [ngModel]=\"config().barType\"\r\n (ngModelChange)=\"updateConfig({ barType: $event })\"\r\n [options]=\"barTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('isGrouped')\"\r\n [ngModel]=\"config().isGrouped\"\r\n (ngModelChange)=\"updateConfig({ isGrouped: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- X-Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"xAxisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('xAxisShow')\"\r\n [ngModel]=\"config().xAxisShow\"\r\n (ngModelChange)=\"updateConfig({ xAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('xAxisFontSize')\"\r\n [ngModel]=\"config().xAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('xAxisFontColor')\"\r\n [ngModel]=\"config().xAxisFontColor\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('xAxisLineColor')\"\r\n [ngModel]=\"config().xAxisLineColor\"\r\n (ngModelChange)=\"updateConfig({ xAxisLineColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Y-Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"yAxisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('yAxisShow')\"\r\n [ngModel]=\"config().yAxisShow\"\r\n (ngModelChange)=\"updateConfig({ yAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n @if (config().yAxisShow) {\r\n <mt-select-field\r\n [label]=\"t('yAxisFormat')\"\r\n [ngModel]=\"config().yAxisFormat\"\r\n (ngModelChange)=\"onYAxisFormatChange($event)\"\r\n [options]=\"yAxisFormatOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n @if (config().yAxisFormat === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"config().showCurrency\"\r\n (ngModelChange)=\"updateConfig({ showCurrency: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n }\r\n }\r\n\r\n <mt-select-field\r\n [label]=\"t('yAxisFontSize')\"\r\n [ngModel]=\"config().yAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ yAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('yAxisFontColor')\"\r\n [ngModel]=\"config().yAxisFontColor\"\r\n (ngModelChange)=\"updateConfig({ yAxisFontColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('yAxisLineColor')\"\r\n [ngModel]=\"config().yAxisLineColor\"\r\n (ngModelChange)=\"updateConfig({ yAxisLineColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Grid Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"gridSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('gridTop')\"\r\n [ngModel]=\"config().gridTop\"\r\n (ngModelChange)=\"updateConfig({ gridTop: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridBottom')\"\r\n [ngModel]=\"config().gridBottom\"\r\n (ngModelChange)=\"updateConfig({ gridBottom: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridLeft')\"\r\n [ngModel]=\"config().gridLeft\"\r\n (ngModelChange)=\"updateConfig({ gridLeft: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridRight')\"\r\n [ngModel]=\"config().gridRight\"\r\n (ngModelChange)=\"updateConfig({ gridRight: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('labelShow')\"\r\n [ngModel]=\"config().labelShow\"\r\n (ngModelChange)=\"updateConfig({ labelShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"config().labelPosition\"\r\n (ngModelChange)=\"updateConfig({ labelPosition: $event })\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFormatter')\"\r\n [ngModel]=\"config().labelFormatter\"\r\n (ngModelChange)=\"updateConfig({ labelFormatter: $event })\"\r\n [options]=\"labelFormatterOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('tooltipShow')\"\r\n [ngModel]=\"config().tooltipShow\"\r\n (ngModelChange)=\"updateConfig({ tooltipShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('showValueOnlyInTooltip')\"\r\n [ngModel]=\"config().showValueOnlyInTooltip\"\r\n (ngModelChange)=\"updateConfig({ showValueOnlyInTooltip: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('maxCharsPerLine')\"\r\n [ngModel]=\"config().maxCharsPerLine\"\r\n (ngModelChange)=\"updateConfig({ maxCharsPerLine: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('tooltipTrigger')\"\r\n [ngModel]=\"config().tooltipTrigger\"\r\n (ngModelChange)=\"updateConfig({ tooltipTrigger: $event })\"\r\n [options]=\"tooltipTriggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3481
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.bar'\"\r\n>\r\n <!-- Bar Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"barSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('barWidth')\"\r\n [ngModel]=\"config().barWidth\"\r\n (ngModelChange)=\"updateConfig({ barWidth: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n [ngModel]=\"config().barType\"\r\n (ngModelChange)=\"updateConfig({ barType: $event })\"\r\n [options]=\"barTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('isGrouped')\"\r\n [ngModel]=\"config().isGrouped\"\r\n (ngModelChange)=\"updateConfig({ isGrouped: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- X-Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"xAxisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('xAxisShow')\"\r\n [ngModel]=\"config().xAxisShow\"\r\n (ngModelChange)=\"updateConfig({ xAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('xAxisFontSize')\"\r\n [ngModel]=\"config().xAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('xAxisFontColor')\"\r\n [ngModel]=\"config().xAxisFontColor\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('xAxisLineColor')\"\r\n [ngModel]=\"config().xAxisLineColor\"\r\n (ngModelChange)=\"updateConfig({ xAxisLineColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Y-Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"yAxisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('yAxisShow')\"\r\n [ngModel]=\"config().yAxisShow\"\r\n (ngModelChange)=\"updateConfig({ yAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n @if (config().yAxisShow) {\r\n <mt-select-field\r\n [label]=\"t('yAxisFormat')\"\r\n [ngModel]=\"config().yAxisFormat\"\r\n (ngModelChange)=\"onYAxisFormatChange($event)\"\r\n [options]=\"yAxisFormatOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n @if (config().yAxisFormat === \"currency\") {\r\n <mt-toggle-field\r\n [label]=\"t('showCurrency')\"\r\n [ngModel]=\"config().showCurrency\"\r\n (ngModelChange)=\"updateConfig({ showCurrency: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n }\r\n }\r\n\r\n <mt-select-field\r\n [label]=\"t('yAxisFontSize')\"\r\n [ngModel]=\"config().yAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ yAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('yAxisFontColor')\"\r\n [ngModel]=\"config().yAxisFontColor\"\r\n (ngModelChange)=\"updateConfig({ yAxisFontColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('yAxisLineColor')\"\r\n [ngModel]=\"config().yAxisLineColor\"\r\n (ngModelChange)=\"updateConfig({ yAxisLineColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Grid Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"gridSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('gridTop')\"\r\n [ngModel]=\"config().gridTop\"\r\n (ngModelChange)=\"updateConfig({ gridTop: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridBottom')\"\r\n [ngModel]=\"config().gridBottom\"\r\n (ngModelChange)=\"updateConfig({ gridBottom: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridLeft')\"\r\n [ngModel]=\"config().gridLeft\"\r\n (ngModelChange)=\"updateConfig({ gridLeft: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridRight')\"\r\n [ngModel]=\"config().gridRight\"\r\n (ngModelChange)=\"updateConfig({ gridRight: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('labelShow')\"\r\n [ngModel]=\"config().labelShow\"\r\n (ngModelChange)=\"updateConfig({ labelShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelPosition')\"\r\n [ngModel]=\"config().labelPosition\"\r\n (ngModelChange)=\"updateConfig({ labelPosition: $event })\"\r\n [options]=\"labelPositionOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFormatter')\"\r\n [ngModel]=\"config().labelFormatter\"\r\n (ngModelChange)=\"updateConfig({ labelFormatter: $event })\"\r\n [options]=\"labelFormatterOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('tooltipShow')\"\r\n [ngModel]=\"config().tooltipShow\"\r\n (ngModelChange)=\"updateConfig({ tooltipShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('showValueOnlyInTooltip')\"\r\n [ngModel]=\"config().showValueOnlyInTooltip\"\r\n (ngModelChange)=\"updateConfig({ showValueOnlyInTooltip: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('maxCharsPerLine')\"\r\n [ngModel]=\"config().maxCharsPerLine\"\r\n (ngModelChange)=\"updateConfig({ maxCharsPerLine: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('tooltipTrigger')\"\r\n [ngModel]=\"config().tooltipTrigger\"\r\n (ngModelChange)=\"updateConfig({ tooltipTrigger: $event })\"\r\n [options]=\"tooltipTriggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3396
3482
|
}
|
|
3397
3483
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: BarControlUi, decorators: [{
|
|
3398
3484
|
type: Component,
|
|
@@ -3503,7 +3589,7 @@ class StackBarControlUi {
|
|
|
3503
3589
|
useExisting: forwardRef(() => StackBarControlUi),
|
|
3504
3590
|
multi: true,
|
|
3505
3591
|
},
|
|
3506
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.stackBar'\"\r\n>\r\n <!-- Bar Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"barSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('isStacked')\"\r\n [ngModel]=\"config().isStacked\"\r\n (ngModelChange)=\"updateConfig({ isStacked: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('hasLines')\"\r\n [ngModel]=\"config().hasLines\"\r\n (ngModelChange)=\"updateConfig({ hasLines: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n [ngModel]=\"config().barType\"\r\n (ngModelChange)=\"updateConfig({ barType: $event })\"\r\n [options]=\"barTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('barWidth')\"\r\n [ngModel]=\"config().barWidth\"\r\n (ngModelChange)=\"updateConfig({ barWidth: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Grid Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"gridSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('gridLeft')\"\r\n [ngModel]=\"config().gridLeft\"\r\n (ngModelChange)=\"updateConfig({ gridLeft: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridRight')\"\r\n [ngModel]=\"config().gridRight\"\r\n (ngModelChange)=\"updateConfig({ gridRight: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridTop')\"\r\n [ngModel]=\"config().gridTop\"\r\n (ngModelChange)=\"updateConfig({ gridTop: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridBottom')\"\r\n [ngModel]=\"config().gridBottom\"\r\n (ngModelChange)=\"updateConfig({ gridBottom: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"axisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('yAxisShow')\"\r\n [ngModel]=\"config().yAxisShow\"\r\n (ngModelChange)=\"updateConfig({ yAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('yAxisFormat')\"\r\n [ngModel]=\"config().yAxisFormat?.type\"\r\n (ngModelChange)=\"onYAxisFormatChange($event)\"\r\n [options]=\"yAxisFormatOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('xAxisLabelRotate')\"\r\n [ngModel]=\"config().xAxisLabelRotate\"\r\n (ngModelChange)=\"updateConfig({ xAxisLabelRotate: $event })\"\r\n [min]=\"-90\"\r\n [max]=\"90\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('xAxisFontSize')\"\r\n [ngModel]=\"config().xAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Legend Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"legendSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('legendPositionY')\"\r\n [ngModel]=\"config().legendPositionY\"\r\n (ngModelChange)=\"updateConfig({ legendPositionY: $event })\"\r\n [options]=\"legendPositionYOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendPositionX')\"\r\n [ngModel]=\"config().legendPositionX\"\r\n (ngModelChange)=\"updateConfig({ legendPositionX: $event })\"\r\n [options]=\"legendPositionXOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendFontSize')\"\r\n [ngModel]=\"config().legendFontSize\"\r\n (ngModelChange)=\"updateConfig({ legendFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('legendFontColor')\"\r\n [ngModel]=\"config().legendFontColor\"\r\n (ngModelChange)=\"updateConfig({ legendFontColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabel')\"\r\n [ngModel]=\"config().showLabel\"\r\n (ngModelChange)=\"updateConfig({ showLabel: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3592
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-5\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder.chartControls.stackBar'\"\r\n>\r\n <!-- Bar Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"barSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('isStacked')\"\r\n [ngModel]=\"config().isStacked\"\r\n (ngModelChange)=\"updateConfig({ isStacked: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-toggle-field\r\n [label]=\"t('hasLines')\"\r\n [ngModel]=\"config().hasLines\"\r\n (ngModelChange)=\"updateConfig({ hasLines: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n [ngModel]=\"config().barType\"\r\n (ngModelChange)=\"updateConfig({ barType: $event })\"\r\n [options]=\"barTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('barWidth')\"\r\n [ngModel]=\"config().barWidth\"\r\n (ngModelChange)=\"updateConfig({ barWidth: $event })\"\r\n [min]=\"10\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('borderRadius')\"\r\n [ngModel]=\"config().borderRadius\"\r\n (ngModelChange)=\"updateConfig({ borderRadius: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Grid Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"gridSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-number-field\r\n [label]=\"t('gridLeft')\"\r\n [ngModel]=\"config().gridLeft\"\r\n (ngModelChange)=\"updateConfig({ gridLeft: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridRight')\"\r\n [ngModel]=\"config().gridRight\"\r\n (ngModelChange)=\"updateConfig({ gridRight: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridTop')\"\r\n [ngModel]=\"config().gridTop\"\r\n (ngModelChange)=\"updateConfig({ gridTop: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('gridBottom')\"\r\n [ngModel]=\"config().gridBottom\"\r\n (ngModelChange)=\"updateConfig({ gridBottom: $event })\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Axis Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"axisSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('yAxisShow')\"\r\n [ngModel]=\"config().yAxisShow\"\r\n (ngModelChange)=\"updateConfig({ yAxisShow: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('yAxisFormat')\"\r\n [ngModel]=\"config().yAxisFormat?.type\"\r\n (ngModelChange)=\"onYAxisFormatChange($event)\"\r\n [options]=\"yAxisFormatOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('xAxisLabelRotate')\"\r\n [ngModel]=\"config().xAxisLabelRotate\"\r\n (ngModelChange)=\"updateConfig({ xAxisLabelRotate: $event })\"\r\n [min]=\"-90\"\r\n [max]=\"90\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('xAxisFontSize')\"\r\n [ngModel]=\"config().xAxisFontSize\"\r\n (ngModelChange)=\"updateConfig({ xAxisFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Legend Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"legendSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('legendPositionY')\"\r\n [ngModel]=\"config().legendPositionY\"\r\n (ngModelChange)=\"updateConfig({ legendPositionY: $event })\"\r\n [options]=\"legendPositionYOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendPositionX')\"\r\n [ngModel]=\"config().legendPositionX\"\r\n (ngModelChange)=\"updateConfig({ legendPositionX: $event })\"\r\n [options]=\"legendPositionXOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('legendFontSize')\"\r\n [ngModel]=\"config().legendFontSize\"\r\n (ngModelChange)=\"updateConfig({ legendFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('legendFontColor')\"\r\n [ngModel]=\"config().legendFontColor\"\r\n (ngModelChange)=\"updateConfig({ legendFontColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Label Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"labelSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-toggle-field\r\n [label]=\"t('showLabel')\"\r\n [ngModel]=\"config().showLabel\"\r\n (ngModelChange)=\"updateConfig({ showLabel: $event })\"\r\n labelPosition=\"start\"\r\n />\r\n\r\n <mt-select-field\r\n [label]=\"t('labelFontSize')\"\r\n [ngModel]=\"config().labelFontSize\"\r\n (ngModelChange)=\"updateConfig({ labelFontSize: $event })\"\r\n [options]=\"fontSizeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('labelFontColor')\"\r\n [ngModel]=\"config().labelFontColor\"\r\n (ngModelChange)=\"updateConfig({ labelFontColor: $event })\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Tooltip Settings -->\r\n <div class=\"rounded-xl border border-surface-200 bg-surface-0 p-4\">\r\n <h4 class=\"mb-4 text-sm font-semibold text-color\">\r\n {{ t(\"tooltipSettings\") }}\r\n </h4>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBackgroundColor')\"\r\n [ngModel]=\"config().tooltipBackgroundColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBackgroundColor: $event })\"\r\n />\r\n\r\n <mt-color-picker-field\r\n [label]=\"t('tooltipBorderColor')\"\r\n [ngModel]=\"config().tooltipBorderColor\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderColor: $event })\"\r\n />\r\n\r\n <mt-number-field\r\n [label]=\"t('tooltipBorderWidth')\"\r\n [ngModel]=\"config().tooltipBorderWidth\"\r\n (ngModelChange)=\"updateConfig({ tooltipBorderWidth: $event })\"\r\n [min]=\"0\"\r\n [max]=\"10\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }] });
|
|
3507
3593
|
}
|
|
3508
3594
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: StackBarControlUi, decorators: [{
|
|
3509
3595
|
type: Component,
|
|
@@ -3547,15 +3633,41 @@ class ChartSettingsDrawer {
|
|
|
3547
3633
|
if (configItem) {
|
|
3548
3634
|
// Deep clone to avoid mutating original
|
|
3549
3635
|
this.item.set(JSON.parse(JSON.stringify(configItem)));
|
|
3636
|
+
if (this.isLayoutComponent(configItem.config?.clientConfig?.componentName)) {
|
|
3637
|
+
this.activeTab.set('chartControls');
|
|
3638
|
+
}
|
|
3550
3639
|
}
|
|
3551
3640
|
}
|
|
3552
3641
|
/** Active tab: 'display' or 'chartControls' */
|
|
3553
3642
|
activeTab = signal('display', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
3554
|
-
/**
|
|
3643
|
+
/** Layout widgets use quick controls only */
|
|
3644
|
+
showDisplayTab = computed(() => {
|
|
3645
|
+
const chartType = this.resolvedChartType();
|
|
3646
|
+
if (chartType?.category === 'layout')
|
|
3647
|
+
return false;
|
|
3648
|
+
const componentName = this.item()?.config?.clientConfig?.componentName;
|
|
3649
|
+
return !this.isLayoutComponent(componentName);
|
|
3650
|
+
}, ...(ngDevMode ? [{ debugName: "showDisplayTab" }] : []));
|
|
3651
|
+
isLayoutItem = computed(() => {
|
|
3652
|
+
const chartType = this.resolvedChartType();
|
|
3653
|
+
if (chartType?.category === 'layout')
|
|
3654
|
+
return true;
|
|
3655
|
+
const componentName = this.item()?.config?.clientConfig?.componentName;
|
|
3656
|
+
return this.isLayoutComponent(componentName);
|
|
3657
|
+
}, ...(ngDevMode ? [{ debugName: "isLayoutItem" }] : []));
|
|
3658
|
+
layoutComponentName = computed(() => {
|
|
3659
|
+
const componentName = this.item()?.config?.clientConfig?.componentName;
|
|
3660
|
+
if (componentName === 'header' || componentName === 'topbar') {
|
|
3661
|
+
return componentName;
|
|
3662
|
+
}
|
|
3663
|
+
return null;
|
|
3664
|
+
}, ...(ngDevMode ? [{ debugName: "layoutComponentName" }] : []));
|
|
3665
|
+
/** Tab options - hide Display for layout widgets, show Chart Controls when a chart control UI exists */
|
|
3555
3666
|
tabOptions = computed(() => {
|
|
3556
|
-
const tabs = [
|
|
3557
|
-
|
|
3558
|
-
|
|
3667
|
+
const tabs = [];
|
|
3668
|
+
if (this.showDisplayTab()) {
|
|
3669
|
+
tabs.push({ label: 'Display', value: 'display', icon: 'design.palette' });
|
|
3670
|
+
}
|
|
3559
3671
|
if (this.manageType() !== null) {
|
|
3560
3672
|
tabs.push({
|
|
3561
3673
|
label: 'Chart Controls',
|
|
@@ -3606,10 +3718,37 @@ class ChartSettingsDrawer {
|
|
|
3606
3718
|
}
|
|
3607
3719
|
return null;
|
|
3608
3720
|
}, ...(ngDevMode ? [{ debugName: "manageType" }] : []));
|
|
3609
|
-
/** Default config
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3721
|
+
/** Default control config mapped from item config */
|
|
3722
|
+
defaultControlConfig = computed(() => {
|
|
3723
|
+
const clientConfig = this.item()?.config?.clientConfig;
|
|
3724
|
+
const componentName = clientConfig?.componentName;
|
|
3725
|
+
const styleConfig = clientConfig?.displayConfig?.StyleConfig ?? {};
|
|
3726
|
+
const configAsType = clientConfig?.configAsType ?? {};
|
|
3727
|
+
const cardStyleConfig = configAsType['cardStyleConfig'] ??
|
|
3728
|
+
{};
|
|
3729
|
+
const subtitleConfig = clientConfig?.['subtitle'];
|
|
3730
|
+
return {
|
|
3731
|
+
title: clientConfig?.title?.['en'] || clientConfig?.title?.['ar'] || '',
|
|
3732
|
+
titleFontSize: Number(styleConfig['font-size-title'] ??
|
|
3733
|
+
(componentName === 'header' ? 20 : 18)),
|
|
3734
|
+
titleColor: String(styleConfig['color'] || ''),
|
|
3735
|
+
showSubtitle: Boolean(configAsType['showSubtitle']),
|
|
3736
|
+
subtitle: typeof subtitleConfig === 'string'
|
|
3737
|
+
? subtitleConfig
|
|
3738
|
+
: subtitleConfig?.['en'] || subtitleConfig?.['ar'] || '',
|
|
3739
|
+
subtitleFontSize: Number(configAsType['subtitleFontSize'] ?? 14),
|
|
3740
|
+
subtitleColor: String(configAsType['subtitleColor'] || ''),
|
|
3741
|
+
icon: String(configAsType['icon'] || ''),
|
|
3742
|
+
iconColor: String(styleConfig['iconColor'] || ''),
|
|
3743
|
+
iconBackgroundColor: String(styleConfig['iconBgColor'] || ''),
|
|
3744
|
+
backgroundColor: String(cardStyleConfig['backgroundColor'] ||
|
|
3745
|
+
styleConfig['background-color'] ||
|
|
3746
|
+
''),
|
|
3747
|
+
borderColor: String(styleConfig['border-color'] || ''),
|
|
3748
|
+
borderRadius: Number(cardStyleConfig['borderRadius'] ?? 0),
|
|
3749
|
+
padding: Number(configAsType['padding'] ?? 16),
|
|
3750
|
+
};
|
|
3751
|
+
}, ...(ngDevMode ? [{ debugName: "defaultControlConfig" }] : []));
|
|
3613
3752
|
/** Pie chart config - note: typo "Overried" matches old implementation */
|
|
3614
3753
|
pieConfig = computed(() => {
|
|
3615
3754
|
return this.item()?.config?.clientConfig?.['pieConfigOverried'] || {};
|
|
@@ -3629,12 +3768,56 @@ class ChartSettingsDrawer {
|
|
|
3629
3768
|
/** Update default config */
|
|
3630
3769
|
onDefaultConfigChange(config) {
|
|
3631
3770
|
const currentItem = this.item();
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
}
|
|
3771
|
+
const currentConfig = currentItem?.config;
|
|
3772
|
+
if (!currentItem || !currentConfig)
|
|
3773
|
+
return;
|
|
3774
|
+
const currentClientConfig = currentConfig.clientConfig ?? {};
|
|
3775
|
+
const currentStyleConfig = currentClientConfig.displayConfig?.StyleConfig ?? {};
|
|
3776
|
+
const currentConfigAsType = currentClientConfig.configAsType ?? {};
|
|
3777
|
+
const currentCardStyleConfig = currentConfigAsType['cardStyleConfig'] ?? {};
|
|
3778
|
+
this.item.set({
|
|
3779
|
+
...currentItem,
|
|
3780
|
+
config: {
|
|
3781
|
+
...currentConfig,
|
|
3782
|
+
clientConfig: {
|
|
3783
|
+
...currentClientConfig,
|
|
3784
|
+
title: {
|
|
3785
|
+
...currentClientConfig.title,
|
|
3786
|
+
en: config.title,
|
|
3787
|
+
ar: config.title,
|
|
3788
|
+
},
|
|
3789
|
+
subtitle: {
|
|
3790
|
+
en: config.subtitle,
|
|
3791
|
+
ar: config.subtitle,
|
|
3792
|
+
},
|
|
3793
|
+
displayConfig: {
|
|
3794
|
+
...currentClientConfig.displayConfig,
|
|
3795
|
+
StyleConfig: {
|
|
3796
|
+
...currentStyleConfig,
|
|
3797
|
+
color: config.titleColor,
|
|
3798
|
+
'font-size-title': config.titleFontSize,
|
|
3799
|
+
'background-color': config.backgroundColor,
|
|
3800
|
+
'border-color': config.borderColor,
|
|
3801
|
+
iconColor: config.iconColor,
|
|
3802
|
+
iconBgColor: config.iconBackgroundColor,
|
|
3803
|
+
},
|
|
3804
|
+
},
|
|
3805
|
+
configAsType: {
|
|
3806
|
+
...currentConfigAsType,
|
|
3807
|
+
icon: config.icon,
|
|
3808
|
+
showSubtitle: config.showSubtitle,
|
|
3809
|
+
subtitleFontSize: config.subtitleFontSize,
|
|
3810
|
+
subtitleColor: config.subtitleColor,
|
|
3811
|
+
padding: config.padding,
|
|
3812
|
+
cardStyleConfig: {
|
|
3813
|
+
...currentCardStyleConfig,
|
|
3814
|
+
backgroundColor: config.backgroundColor,
|
|
3815
|
+
borderRadius: config.borderRadius,
|
|
3816
|
+
},
|
|
3817
|
+
},
|
|
3818
|
+
},
|
|
3819
|
+
},
|
|
3820
|
+
});
|
|
3638
3821
|
}
|
|
3639
3822
|
/** Update pie chart config - note: typo "Overried" matches old implementation */
|
|
3640
3823
|
onPieConfigChange(config) {
|
|
@@ -3728,8 +3911,11 @@ class ChartSettingsDrawer {
|
|
|
3728
3911
|
close() {
|
|
3729
3912
|
this.dialogRef.close(null);
|
|
3730
3913
|
}
|
|
3914
|
+
isLayoutComponent(componentName) {
|
|
3915
|
+
return componentName === 'header' || componentName === 'topbar';
|
|
3916
|
+
}
|
|
3731
3917
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartSettingsDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3732
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartSettingsDrawer, isStandalone: true, selector: "mt-chart-settings-drawer", ngImport: i0, template: "<div\r\n [class]=\"modal.contentClass + ' flex h-full min-h-0 flex-col p-0'\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div\r\n class=\"sticky top-0 z-10 border-b border-surface-200 bg-surface-0 px-4 pb-3 pt-4\"\r\n >\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto px-4 pb-4 pt-3\">\r\n <!-- Display Tab -->\r\n
|
|
3918
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartSettingsDrawer, isStandalone: true, selector: "mt-chart-settings-drawer", ngImport: i0, template: "<div\r\n [class]=\"modal.contentClass + ' flex h-full min-h-0 flex-col p-0'\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div\r\n class=\"sticky top-0 z-10 border-b border-surface-200 bg-surface-0 px-4 pb-3 pt-4\"\r\n >\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto px-4 pb-4 pt-3\">\r\n @if (showDisplayTab()) {\r\n <!-- Display Tab -->\r\n <div [hidden]=\"activeTab() !== 'display'\" class=\"flex flex-col gap-3\">\r\n <mt-display-settings\r\n [config]=\"itemConfig()\"\r\n [chartType]=\"resolvedChartType()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Chart Controls Tab -->\r\n <div [hidden]=\"activeTab() !== 'chartControls'\" class=\"flex flex-col gap-3\">\r\n @switch (manageType()) {\r\n @case (\"default\") {\r\n <mt-default-control-ui\r\n [ngModel]=\"defaultControlConfig()\"\r\n [showIconSettings]=\"isLayoutItem()\"\r\n [layoutComponent]=\"layoutComponentName()\"\r\n (ngModelChange)=\"onDefaultConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"pie\") {\r\n <mt-pie-control-ui\r\n [ngModel]=\"pieConfig()\"\r\n (ngModelChange)=\"onPieConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"bar\") {\r\n <mt-bar-control-ui\r\n [ngModel]=\"barConfig()\"\r\n (ngModelChange)=\"onBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"stackBar\") {\r\n <mt-stack-bar-control-ui\r\n [ngModel]=\"stackBarConfig()\"\r\n (ngModelChange)=\"onStackBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"snapshotBar\") {\r\n <mt-bar-control-ui\r\n [ngModel]=\"snapshotBarConfig()\"\r\n (ngModelChange)=\"onSnapshotBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @default {\r\n <div class=\"p-4 text-center text-muted-color\">\r\n {{ t(\"noSettingsAvailable\") }}\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div\r\n [class]=\"\r\n modal.footerClass + ' border-t border-surface-200 bg-surface-0 px-4 py-3'\r\n \"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <mt-button [label]=\"t('apply')\" icon=\"general.check\" (onClick)=\"apply()\" />\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: DisplaySettings, selector: "mt-display-settings", inputs: ["config", "chartType", "availableProperties", "selectedProperties", "lookups"], outputs: ["clientConfigChange"] }, { kind: "component", type: DefaultControlUi, selector: "mt-default-control-ui", inputs: ["showIconSettings", "layoutComponent"] }, { kind: "component", type: PieControlUi, selector: "mt-pie-control-ui" }, { kind: "component", type: BarControlUi, selector: "mt-bar-control-ui" }, { kind: "component", type: StackBarControlUi, selector: "mt-stack-bar-control-ui" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3733
3919
|
}
|
|
3734
3920
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartSettingsDrawer, decorators: [{
|
|
3735
3921
|
type: Component,
|
|
@@ -3744,7 +3930,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3744
3930
|
PieControlUi,
|
|
3745
3931
|
BarControlUi,
|
|
3746
3932
|
StackBarControlUi,
|
|
3747
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\r\n [class]=\"modal.contentClass + ' flex h-full min-h-0 flex-col p-0'\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div\r\n class=\"sticky top-0 z-10 border-b border-surface-200 bg-surface-0 px-4 pb-3 pt-4\"\r\n >\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto px-4 pb-4 pt-3\">\r\n <!-- Display Tab -->\r\n
|
|
3933
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\r\n [class]=\"modal.contentClass + ' flex h-full min-h-0 flex-col p-0'\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div\r\n class=\"sticky top-0 z-10 border-b border-surface-200 bg-surface-0 px-4 pb-3 pt-4\"\r\n >\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n </div>\r\n\r\n <div class=\"min-h-0 flex-1 overflow-y-auto px-4 pb-4 pt-3\">\r\n @if (showDisplayTab()) {\r\n <!-- Display Tab -->\r\n <div [hidden]=\"activeTab() !== 'display'\" class=\"flex flex-col gap-3\">\r\n <mt-display-settings\r\n [config]=\"itemConfig()\"\r\n [chartType]=\"resolvedChartType()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Chart Controls Tab -->\r\n <div [hidden]=\"activeTab() !== 'chartControls'\" class=\"flex flex-col gap-3\">\r\n @switch (manageType()) {\r\n @case (\"default\") {\r\n <mt-default-control-ui\r\n [ngModel]=\"defaultControlConfig()\"\r\n [showIconSettings]=\"isLayoutItem()\"\r\n [layoutComponent]=\"layoutComponentName()\"\r\n (ngModelChange)=\"onDefaultConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"pie\") {\r\n <mt-pie-control-ui\r\n [ngModel]=\"pieConfig()\"\r\n (ngModelChange)=\"onPieConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"bar\") {\r\n <mt-bar-control-ui\r\n [ngModel]=\"barConfig()\"\r\n (ngModelChange)=\"onBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"stackBar\") {\r\n <mt-stack-bar-control-ui\r\n [ngModel]=\"stackBarConfig()\"\r\n (ngModelChange)=\"onStackBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @case (\"snapshotBar\") {\r\n <mt-bar-control-ui\r\n [ngModel]=\"snapshotBarConfig()\"\r\n (ngModelChange)=\"onSnapshotBarConfigChange($event)\"\r\n />\r\n }\r\n\r\n @default {\r\n <div class=\"p-4 text-center text-muted-color\">\r\n {{ t(\"noSettingsAvailable\") }}\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div\r\n [class]=\"\r\n modal.footerClass + ' border-t border-surface-200 bg-surface-0 px-4 py-3'\r\n \"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <mt-button [label]=\"t('apply')\" icon=\"general.check\" (onClick)=\"apply()\" />\r\n</div>\r\n" }]
|
|
3748
3934
|
}], ctorParameters: () => [] });
|
|
3749
3935
|
|
|
3750
3936
|
/**
|
|
@@ -3882,10 +4068,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3882
4068
|
CommonModule,
|
|
3883
4069
|
FormsModule,
|
|
3884
4070
|
TranslocoDirective,
|
|
3885
|
-
Button,
|
|
3886
4071
|
TextField,
|
|
3887
|
-
SelectField,
|
|
3888
|
-
CheckboxField,
|
|
3889
4072
|
Card,
|
|
3890
4073
|
TooltipModule,
|
|
3891
4074
|
Icon,
|
|
@@ -4687,7 +4870,7 @@ class SelectionConfiguration {
|
|
|
4687
4870
|
useExisting: forwardRef(() => SelectionConfiguration),
|
|
4688
4871
|
multi: true,
|
|
4689
4872
|
},
|
|
4690
|
-
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('selections')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n (onClick)=\"addSelection()\"\r\n [disabled]=\"disabled || loadingTree()\"\r\n [pTooltip]=\"t('addSelection')\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Loading Skeleton State - Show for entire component while tree is loading -->\r\n @if (loadingTree()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Skeleton Selection Card -->\r\n <div class=\"p-4 rounded-lg border border-surface-200\">\r\n <!-- Skeleton Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton shape=\"circle\" width=\"24px\" height=\"24px\" />\r\n <p-skeleton width=\"80px\" height=\"16px\" />\r\n </div>\r\n </div>\r\n <!-- Skeleton Module Selection -->\r\n <div class=\"grid grid-cols-1 gap-4 mb-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"60px\" height=\"14px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n <!-- Skeleton Filters Section -->\r\n <div class=\"border border-surface-200 rounded-lg p-4\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <p-skeleton width=\"50px\" height=\"14px\" />\r\n <div class=\"flex gap-1\">\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n </div>\r\n </div>\r\n <div class=\"text-center py-4\">\r\n <p-skeleton width=\"150px\" height=\"14px\" styleClass=\"mx-auto\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4\" [formGroup]=\"selectionsForm\">\r\n <div formArrayName=\"selections\">\r\n @for (\r\n selection of selectionsArray.controls;\r\n track trackBySelectionId($index, selection);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all mb-4 last:mb-0\"\r\n [class.border-red-500]=\"selection.invalid\"\r\n [class.border-surface-200]=\"!selection.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Selection Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full text-sm font-semibold\"\r\n [class.bg-primary-100]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.text-primary-600]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.bg-amber-100]=\"isFixedSelection(selection.value.id)\"\r\n [class.text-amber-600]=\"\r\n isFixedSelection(selection.value.id)\r\n \"\r\n >\r\n @if (isFixedSelection(selection.value.id)) {\r\n <i class=\"mti mti-lock-01 text-xs\"></i>\r\n } @else {\r\n {{ selection.value.id }}\r\n }\r\n </span>\r\n <span class=\"text-sm font-medium text-muted-color\">\r\n @if (isFixedSelection(selection.value.id)) {\r\n {{ t(\"fixedSelection\") }}\r\n } @else {\r\n {{ t(\"selection\") }}\r\n }\r\n </span>\r\n </div>\r\n @if (\r\n selectionsArray.length > 1 &&\r\n !isFixedSelection(selection.value.id)\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeSelection(i)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Service & Module Selection -->\r\n <div\r\n class=\"grid grid-cols-1 gap-4 mb-4\"\r\n [class.md:grid-cols-2]=\"!hasSingleService()\"\r\n >\r\n <!-- Service (hidden when only one service) -->\r\n @if (!hasSingleService()) {\r\n <mt-select-field\r\n [label]=\"t('service')\"\r\n formControlName=\"service\"\r\n [options]=\"services()\"\r\n optionLabel=\"name\"\r\n optionValue=\"name\"\r\n [placeholder]=\"t('selectService')\"\r\n [loading]=\"loadingTree()\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (ngModelChange)=\"onServiceChange(i, $event)\"\r\n />\r\n }\r\n\r\n <!-- Module (grouped by module type) -->\r\n <mt-select-field\r\n [label]=\"t('module')\"\r\n formControlName=\"selector\"\r\n [options]=\"getGroupedModulesForSelection(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"selector\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectModule')\"\r\n [loading]=\"loadingTree()\"\r\n [filter]=\"true\"\r\n [showClear]=\"!isFixedSelection(selection.value.id)\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (ngModelChange)=\"onModuleChange(i, $event)\"\r\n />\r\n </div>\r\n @if (\r\n selection.get(\"selector\")?.invalid &&\r\n selection.get(\"selector\")?.touched\r\n ) {\r\n <small class=\"text-red-500 mt-1 block mb-2\">{{\r\n t(\"moduleRequired\")\r\n }}</small>\r\n }\r\n\r\n <!-- Filters Section -->\r\n <div\r\n class=\"border border-surface-200 rounded-lg p-4\"\r\n [class.border-red-500]=\"getFilters(selection).invalid\"\r\n [class.border-amber-200]=\"isFixedSelection(selection.value.id)\"\r\n [class.bg-amber-50]=\"isFixedSelection(selection.value.id)\"\r\n >\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"filters\") }}</span>\r\n @if (!isFixedSelection(selection.value.id)) {\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n [disabled]=\"\r\n disabled || getFilters(selection).length === 0\r\n \"\r\n (onClick)=\"copyFilters(i)\"\r\n [pTooltip]=\"t('copyFilters')\"\r\n />\r\n <mt-button\r\n icon=\"file.clipboard\"\r\n severity=\"help\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"togglePaste(i)\"\r\n [pTooltip]=\"t('pasteFilters')\"\r\n />\r\n <mt-button\r\n icon=\"general.plus\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addFilter(i)\"\r\n [pTooltip]=\"t('addFilter')\"\r\n />\r\n </div>\r\n } @else {\r\n <span class=\"text-xs text-amber-600 font-medium\">\r\n <i class=\"mti mti-lock-01 mr-1\"></i>\r\n {{ t(\"readOnly\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- Paste JSON Area -->\r\n @if (selection.value.showPaste) {\r\n <div\r\n class=\"mb-4 p-3 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteFiltersJson')\"\r\n formControlName=\"filterJson\"\r\n [placeholder]=\"t('pasteFiltersJsonPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (selection.value.pasteError) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n selection.value.pasteError\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-2\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePaste(i)\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPastedFilters(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Filters List -->\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"filters\">\r\n @for (\r\n filter of getFilters(selection).controls;\r\n track trackByFilterIndex(j);\r\n let j = $index\r\n ) {\r\n <div\r\n class=\"flex flex-col gap-3 p-3 rounded-lg border\"\r\n [class.bg-surface-50]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.border-surface-100]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.bg-amber-25]=\"isFixedSelection(selection.value.id)\"\r\n [class.border-amber-100]=\"\r\n isFixedSelection(selection.value.id)\r\n \"\r\n [formGroupName]=\"j\"\r\n >\r\n <!-- Row 1: Property, Operation, Logical -->\r\n <div class=\"grid grid-cols-12 gap-3\">\r\n <!-- Property Key -->\r\n <div class=\"col-span-5\">\r\n <mt-select-field\r\n [label]=\"t('property')\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"getPropertiesForSelection(i)\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (onChange)=\"onFilterPropertyChange(i, j, $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Operation -->\r\n <div class=\"col-span-3\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n formControlName=\"operation\"\r\n [options]=\"operations\"\r\n optionLabel=\"name\"\r\n optionValue=\"value\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n\r\n <!-- Logical Operator -->\r\n <div class=\"col-span-2\">\r\n <mt-select-field\r\n [label]=\"t('logical')\"\r\n formControlName=\"logical\"\r\n [options]=\"logicals\"\r\n optionLabel=\"name\"\r\n optionValue=\"value\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n\r\n <!-- Remove Filter (hidden for fixed selections) -->\r\n @if (!isFixedSelection(selection.value.id)) {\r\n <div class=\"col-span-2 flex items-end justify-end\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeFilter(i, j)\"\r\n />\r\n </div>\r\n } @else {\r\n <div class=\"col-span-2\"></div>\r\n }\r\n </div>\r\n\r\n <!-- Row 2: Value, Level -->\r\n <div class=\"grid grid-cols-12 gap-3\">\r\n <!-- Value -->\r\n <div class=\"col-span-10\">\r\n @if (shouldShowPropertyItems(i, j)) {\r\n <mt-select-field\r\n [label]=\"t('value')\"\r\n formControlName=\"propertyValue\"\r\n [options]=\"getPropertyItemsForFilter(i, j)\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n } @else {\r\n <mt-filter-value-field\r\n [label]=\"t('value')\"\r\n formControlName=\"propertyValue\"\r\n [placeholder]=\"t('enterValue')\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Operation Level -->\r\n <div class=\"col-span-2\">\r\n <mt-number-field\r\n [label]=\"t('level')\"\r\n formControlName=\"operationLevel\"\r\n [min]=\"1\"\r\n [max]=\"10\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getFilters(selection).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color text-sm\">\r\n {{ t(\"noFiltersConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (selectionsArray.length === 0 && !loadingTree()) {\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-database text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSelectionsConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSelection')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSelection()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required"] }, { kind: "component", type: FilterValueField, selector: "mt-filter-value-field", inputs: ["label", "placeholder", "extraProperties"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip$1, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
4873
|
+
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('selections')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n (onClick)=\"addSelection()\"\r\n [disabled]=\"disabled || loadingTree()\"\r\n [pTooltip]=\"t('addSelection')\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Loading Skeleton State - Show for entire component while tree is loading -->\r\n @if (loadingTree()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Skeleton Selection Card -->\r\n <div class=\"p-4 rounded-lg border border-surface-200\">\r\n <!-- Skeleton Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton shape=\"circle\" width=\"24px\" height=\"24px\" />\r\n <p-skeleton width=\"80px\" height=\"16px\" />\r\n </div>\r\n </div>\r\n <!-- Skeleton Module Selection -->\r\n <div class=\"grid grid-cols-1 gap-4 mb-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"60px\" height=\"14px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n <!-- Skeleton Filters Section -->\r\n <div class=\"border border-surface-200 rounded-lg p-4\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <p-skeleton width=\"50px\" height=\"14px\" />\r\n <div class=\"flex gap-1\">\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n <p-skeleton shape=\"circle\" width=\"28px\" height=\"28px\" />\r\n </div>\r\n </div>\r\n <div class=\"text-center py-4\">\r\n <p-skeleton width=\"150px\" height=\"14px\" styleClass=\"mx-auto\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4\" [formGroup]=\"selectionsForm\">\r\n <div formArrayName=\"selections\">\r\n @for (\r\n selection of selectionsArray.controls;\r\n track trackBySelectionId($index, selection);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all mb-4 last:mb-0\"\r\n [class.border-red-500]=\"selection.invalid\"\r\n [class.border-surface-200]=\"!selection.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Selection Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full text-sm font-semibold\"\r\n [class.bg-primary-100]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.text-primary-600]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.bg-amber-100]=\"isFixedSelection(selection.value.id)\"\r\n [class.text-amber-600]=\"\r\n isFixedSelection(selection.value.id)\r\n \"\r\n >\r\n @if (isFixedSelection(selection.value.id)) {\r\n <i class=\"mti mti-lock-01 text-xs\"></i>\r\n } @else {\r\n {{ selection.value.id }}\r\n }\r\n </span>\r\n <span class=\"text-sm font-medium text-muted-color\">\r\n @if (isFixedSelection(selection.value.id)) {\r\n {{ t(\"fixedSelection\") }}\r\n } @else {\r\n {{ t(\"selection\") }}\r\n }\r\n </span>\r\n </div>\r\n @if (\r\n selectionsArray.length > 1 &&\r\n !isFixedSelection(selection.value.id)\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeSelection(i)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Service & Module Selection -->\r\n <div\r\n class=\"grid grid-cols-1 gap-4 mb-4\"\r\n [class.md:grid-cols-2]=\"!hasSingleService()\"\r\n >\r\n <!-- Service (hidden when only one service) -->\r\n @if (!hasSingleService()) {\r\n <mt-select-field\r\n [label]=\"t('service')\"\r\n formControlName=\"service\"\r\n [options]=\"services()\"\r\n optionLabel=\"name\"\r\n optionValue=\"name\"\r\n [placeholder]=\"t('selectService')\"\r\n [loading]=\"loadingTree()\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (ngModelChange)=\"onServiceChange(i, $event)\"\r\n />\r\n }\r\n\r\n <!-- Module (grouped by module type) -->\r\n <mt-select-field\r\n [label]=\"t('module')\"\r\n formControlName=\"selector\"\r\n [options]=\"getGroupedModulesForSelection(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"selector\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectModule')\"\r\n [loading]=\"loadingTree()\"\r\n [filter]=\"true\"\r\n [showClear]=\"!isFixedSelection(selection.value.id)\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (ngModelChange)=\"onModuleChange(i, $event)\"\r\n />\r\n </div>\r\n @if (\r\n selection.get(\"selector\")?.invalid &&\r\n selection.get(\"selector\")?.touched\r\n ) {\r\n <small class=\"text-red-500 mt-1 block mb-2\">{{\r\n t(\"moduleRequired\")\r\n }}</small>\r\n }\r\n\r\n <!-- Filters Section -->\r\n <div\r\n class=\"border border-surface-200 rounded-lg p-4\"\r\n [class.border-red-500]=\"getFilters(selection).invalid\"\r\n [class.border-amber-200]=\"isFixedSelection(selection.value.id)\"\r\n [class.bg-amber-50]=\"isFixedSelection(selection.value.id)\"\r\n >\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"filters\") }}</span>\r\n @if (!isFixedSelection(selection.value.id)) {\r\n <div class=\"flex items-center gap-1\">\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n [disabled]=\"\r\n disabled || getFilters(selection).length === 0\r\n \"\r\n (onClick)=\"copyFilters(i)\"\r\n [pTooltip]=\"t('copyFilters')\"\r\n />\r\n <mt-button\r\n icon=\"file.clipboard\"\r\n severity=\"help\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"togglePaste(i)\"\r\n [pTooltip]=\"t('pasteFilters')\"\r\n />\r\n <mt-button\r\n icon=\"general.plus\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addFilter(i)\"\r\n [pTooltip]=\"t('addFilter')\"\r\n />\r\n </div>\r\n } @else {\r\n <span class=\"text-xs text-amber-600 font-medium\">\r\n <i class=\"mti mti-lock-01 mr-1\"></i>\r\n {{ t(\"readOnly\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- Paste JSON Area -->\r\n @if (selection.value.showPaste) {\r\n <div\r\n class=\"mb-4 p-3 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <mt-textarea-field\r\n [label]=\"t('pasteFiltersJson')\"\r\n formControlName=\"filterJson\"\r\n [placeholder]=\"t('pasteFiltersJsonPlaceholder')\"\r\n [rows]=\"4\"\r\n />\r\n @if (selection.value.pasteError) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n selection.value.pasteError\r\n }}</small>\r\n }\r\n <div class=\"flex justify-end gap-2 mt-2\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"togglePaste(i)\"\r\n />\r\n <mt-button\r\n [label]=\"t('apply')\"\r\n size=\"small\"\r\n (onClick)=\"applyPastedFilters(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Filters List -->\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"filters\">\r\n @for (\r\n filter of getFilters(selection).controls;\r\n track trackByFilterIndex(j);\r\n let j = $index\r\n ) {\r\n <div\r\n class=\"flex flex-col gap-3 p-3 rounded-lg border\"\r\n [class.bg-surface-50]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.border-surface-100]=\"\r\n !isFixedSelection(selection.value.id)\r\n \"\r\n [class.bg-amber-25]=\"isFixedSelection(selection.value.id)\"\r\n [class.border-amber-100]=\"\r\n isFixedSelection(selection.value.id)\r\n \"\r\n [formGroupName]=\"j\"\r\n >\r\n <!-- Row 1: Property, Operation, Logical -->\r\n <div class=\"grid grid-cols-12 gap-3\">\r\n <!-- Property Key -->\r\n <div class=\"col-span-5\">\r\n <mt-select-field\r\n [label]=\"t('property')\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"getPropertiesForSelection(i)\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n (onChange)=\"onFilterPropertyChange(i, j, $event)\"\r\n />\r\n </div>\r\n\r\n <!-- Operation -->\r\n <div class=\"col-span-3\">\r\n <mt-select-field\r\n [label]=\"t('operation')\"\r\n formControlName=\"operation\"\r\n [options]=\"operations\"\r\n optionLabel=\"name\"\r\n optionValue=\"value\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n\r\n <!-- Logical Operator -->\r\n <div class=\"col-span-2\">\r\n <mt-select-field\r\n [label]=\"t('logical')\"\r\n formControlName=\"logical\"\r\n [options]=\"logicals\"\r\n optionLabel=\"name\"\r\n optionValue=\"value\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n\r\n <!-- Remove Filter (hidden for fixed selections) -->\r\n @if (!isFixedSelection(selection.value.id)) {\r\n <div class=\"col-span-2 flex items-end justify-end\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeFilter(i, j)\"\r\n />\r\n </div>\r\n } @else {\r\n <div class=\"col-span-2\"></div>\r\n }\r\n </div>\r\n\r\n <!-- Row 2: Value, Level -->\r\n <div class=\"grid grid-cols-12 gap-3\">\r\n <!-- Value -->\r\n <div class=\"col-span-10\">\r\n @if (shouldShowPropertyItems(i, j)) {\r\n <mt-select-field\r\n [label]=\"t('value')\"\r\n formControlName=\"propertyValue\"\r\n [options]=\"getPropertyItemsForFilter(i, j)\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n } @else {\r\n <mt-filter-value-field\r\n [label]=\"t('value')\"\r\n formControlName=\"propertyValue\"\r\n [placeholder]=\"t('enterValue')\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Operation Level -->\r\n <div class=\"col-span-2\">\r\n <mt-number-field\r\n [label]=\"t('level')\"\r\n formControlName=\"operationLevel\"\r\n [min]=\"1\"\r\n [max]=\"10\"\r\n [disabled]=\"isFixedSelection(selection.value.id)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getFilters(selection).length === 0) {\r\n <div class=\"text-center py-4 text-muted-color text-sm\">\r\n {{ t(\"noFiltersConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (selectionsArray.length === 0 && !loadingTree()) {\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-database text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSelectionsConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSelection')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSelection()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: NumberField, selector: "mt-number-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "format", "useGrouping", "maxFractionDigits", "min", "max", "required"] }, { kind: "component", type: TextareaField, selector: "mt-textarea-field", inputs: ["field", "label", "placeholder", "class", "readonly", "noErrorStyle", "pInputs", "rows", "required"] }, { kind: "component", type: FilterValueField, selector: "mt-filter-value-field", inputs: ["label", "placeholder", "extraProperties"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
4691
4874
|
}
|
|
4692
4875
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SelectionConfiguration, decorators: [{
|
|
4693
4876
|
type: Component,
|
|
@@ -4698,12 +4881,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
4698
4881
|
TranslocoDirective,
|
|
4699
4882
|
Button,
|
|
4700
4883
|
SelectField,
|
|
4701
|
-
TextField,
|
|
4702
4884
|
NumberField,
|
|
4703
4885
|
TextareaField,
|
|
4704
4886
|
FilterValueField,
|
|
4705
4887
|
Card,
|
|
4706
|
-
Tooltip
|
|
4888
|
+
Tooltip,
|
|
4707
4889
|
Skeleton,
|
|
4708
4890
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
4709
4891
|
{
|
|
@@ -5010,7 +5192,7 @@ class SourceLinkConfiguration {
|
|
|
5010
5192
|
useExisting: forwardRef(() => SourceLinkConfiguration),
|
|
5011
5193
|
multi: true,
|
|
5012
5194
|
},
|
|
5013
|
-
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('sourceLinks')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addSourceLink()\"\r\n [disabled]=\"disabled\"\r\n [pTooltip]=\"t('addSourceLink')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\" [formGroup]=\"sourceLinksForm\">\r\n <div formArrayName=\"sourceLinks\">\r\n @for (\r\n link of sourceLinksArray.controls;\r\n track trackByIndex(i);\r\n let i = $index;\r\n let first = $first\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all mb-4 last:mb-0\"\r\n [class.border-red-500]=\"link.invalid\"\r\n [class.border-surface-200]=\"!link.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Link Header with Type Tabs -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-3\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full bg-primary-100 text-primary-600 text-sm font-semibold\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n\r\n <!-- Link Type Tabs (only show for non-first links) -->\r\n @if (!first) {\r\n <mt-tabs\r\n [active]=\"getLinkType(i)\"\r\n (activeChange)=\"onLinkTypeChange(i, $event)\"\r\n [options]=\"getLinkTypeOptions(i)\"\r\n size=\"small\"\r\n />\r\n } @else {\r\n <span class=\"text-sm font-medium text-muted-color\">\r\n {{ t(\"selectionToSelection\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeSourceLink(i)\"\r\n />\r\n </div>\r\n\r\n <!-- Source Selections based on link type -->\r\n @if (getLinkType(i) === \"selection\") {\r\n <!-- Selection to Selection Mode -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source 1 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source1')\"\r\n formControlName=\"source1SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n\r\n <!-- Source 2 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source2')\"\r\n formControlName=\"source2SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n </div>\r\n } @else {\r\n <!-- Chained Mode: Previous Link to Selection -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source Link (previous link) -->\r\n <mt-select-field\r\n [label]=\"t('previousLink')\"\r\n formControlName=\"sourceLinkId\"\r\n [options]=\"getAvailableSourceLinks(i)\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"index\"\r\n [placeholder]=\"t('selectPreviousLink')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n\r\n <!-- Source 2 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source2')\"\r\n formControlName=\"source2SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Link Properties -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source 1 Property -->\r\n <mt-select-field\r\n [label]=\"t('source1LinkProperty')\"\r\n formControlName=\"source1PropertyKey\"\r\n [options]=\"getSource1PropertiesGrouped(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n\r\n <!-- Source 2 Property -->\r\n <mt-select-field\r\n [label]=\"t('source2LinkProperty')\"\r\n formControlName=\"source2PropertyKey\"\r\n [options]=\"getSource2PropertiesGrouped(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Join Options -->\r\n <div class=\"flex items-center gap-6\">\r\n <mt-toggle-field\r\n [label]=\"t('isLeftJoin')\"\r\n formControlName=\"isLeftJoin\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('isFilterLinkage')\"\r\n formControlName=\"isFilterLinkage\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (sourceLinksArray.length === 0) {\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-link-01 text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSourceLinksConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSourceLink')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSourceLink()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "directive", type: Tooltip$1, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5195
|
+
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('sourceLinks')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addSourceLink()\"\r\n [disabled]=\"disabled\"\r\n [pTooltip]=\"t('addSourceLink')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\" [formGroup]=\"sourceLinksForm\">\r\n <div formArrayName=\"sourceLinks\">\r\n @for (\r\n link of sourceLinksArray.controls;\r\n track trackByIndex(i);\r\n let i = $index;\r\n let first = $first\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all mb-4 last:mb-0\"\r\n [class.border-red-500]=\"link.invalid\"\r\n [class.border-surface-200]=\"!link.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Link Header with Type Tabs -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-3\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full bg-primary-100 text-primary-600 text-sm font-semibold\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n\r\n <!-- Link Type Tabs (only show for non-first links) -->\r\n @if (!first) {\r\n <mt-tabs\r\n [active]=\"getLinkType(i)\"\r\n (activeChange)=\"onLinkTypeChange(i, $event)\"\r\n [options]=\"getLinkTypeOptions(i)\"\r\n size=\"small\"\r\n />\r\n } @else {\r\n <span class=\"text-sm font-medium text-muted-color\">\r\n {{ t(\"selectionToSelection\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeSourceLink(i)\"\r\n />\r\n </div>\r\n\r\n <!-- Source Selections based on link type -->\r\n @if (getLinkType(i) === \"selection\") {\r\n <!-- Selection to Selection Mode -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source 1 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source1')\"\r\n formControlName=\"source1SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n\r\n <!-- Source 2 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source2')\"\r\n formControlName=\"source2SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n </div>\r\n } @else {\r\n <!-- Chained Mode: Previous Link to Selection -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source Link (previous link) -->\r\n <mt-select-field\r\n [label]=\"t('previousLink')\"\r\n formControlName=\"sourceLinkId\"\r\n [options]=\"getAvailableSourceLinks(i)\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"index\"\r\n [placeholder]=\"t('selectPreviousLink')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n\r\n <!-- Source 2 Selection -->\r\n <mt-select-field\r\n [label]=\"t('source2')\"\r\n formControlName=\"source2SelectionId\"\r\n [options]=\"selectionOptions()\"\r\n optionLabel=\"displayName\"\r\n optionValue=\"selectionId\"\r\n [placeholder]=\"t('selectSource')\"\r\n (ngModelChange)=\"onSourceChange(i)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Link Properties -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\r\n <!-- Source 1 Property -->\r\n <mt-select-field\r\n [label]=\"t('source1LinkProperty')\"\r\n formControlName=\"source1PropertyKey\"\r\n [options]=\"getSource1PropertiesGrouped(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n\r\n <!-- Source 2 Property -->\r\n <mt-select-field\r\n [label]=\"t('source2LinkProperty')\"\r\n formControlName=\"source2PropertyKey\"\r\n [options]=\"getSource2PropertiesGrouped(i)\"\r\n [group]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Join Options -->\r\n <div class=\"flex items-center gap-6\">\r\n <mt-toggle-field\r\n [label]=\"t('isLeftJoin')\"\r\n formControlName=\"isLeftJoin\"\r\n />\r\n <mt-toggle-field\r\n [label]=\"t('isFilterLinkage')\"\r\n formControlName=\"isFilterLinkage\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (sourceLinksArray.length === 0) {\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-link-01 text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSourceLinksConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSourceLink')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSourceLink()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5014
5196
|
}
|
|
5015
5197
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SourceLinkConfiguration, decorators: [{
|
|
5016
5198
|
type: Component,
|
|
@@ -5024,7 +5206,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5024
5206
|
ToggleField,
|
|
5025
5207
|
Card,
|
|
5026
5208
|
Tabs,
|
|
5027
|
-
Tooltip
|
|
5209
|
+
Tooltip,
|
|
5028
5210
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5029
5211
|
{
|
|
5030
5212
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -5114,7 +5296,7 @@ class CustomApiConfiguration {
|
|
|
5114
5296
|
useExisting: forwardRef(() => CustomApiConfiguration),
|
|
5115
5297
|
multi: true,
|
|
5116
5298
|
},
|
|
5117
|
-
], ngImport: i0, template: "<mt-card
|
|
5299
|
+
], ngImport: i0, template: "<mt-card\r\n [title]=\"t('customApi')\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div class=\"flex flex-col gap-4\">\r\n <p class=\"text-sm text-muted-color\">\r\n {{ t(\"customApiDescription\") }}\r\n </p>\r\n\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <!-- HTTP Method -->\r\n <div class=\"col-span-3\">\r\n <mt-select-field\r\n [label]=\"t('httpMethod')\"\r\n [options]=\"methodOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [ngModel]=\"method()\"\r\n (ngModelChange)=\"onMethodChange($event)\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </div>\r\n\r\n <!-- Custom API URL -->\r\n <div class=\"col-span-9\">\r\n <mt-text-field\r\n [label]=\"t('customApiUrl')\"\r\n [placeholder]=\"t('customApiUrlPlaceholder')\"\r\n [ngModel]=\"customApiUrl()\"\r\n (ngModelChange)=\"onUrlChange($event)\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</mt-card>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5118
5300
|
}
|
|
5119
5301
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CustomApiConfiguration, decorators: [{
|
|
5120
5302
|
type: Component,
|
|
@@ -5131,7 +5313,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5131
5313
|
useExisting: forwardRef(() => CustomApiConfiguration),
|
|
5132
5314
|
multi: true,
|
|
5133
5315
|
},
|
|
5134
|
-
], template: "<mt-card
|
|
5316
|
+
], template: "<mt-card\r\n [title]=\"t('customApi')\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n>\r\n <div class=\"flex flex-col gap-4\">\r\n <p class=\"text-sm text-muted-color\">\r\n {{ t(\"customApiDescription\") }}\r\n </p>\r\n\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <!-- HTTP Method -->\r\n <div class=\"col-span-3\">\r\n <mt-select-field\r\n [label]=\"t('httpMethod')\"\r\n [options]=\"methodOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [ngModel]=\"method()\"\r\n (ngModelChange)=\"onMethodChange($event)\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </div>\r\n\r\n <!-- Custom API URL -->\r\n <div class=\"col-span-9\">\r\n <mt-text-field\r\n [label]=\"t('customApiUrl')\"\r\n [placeholder]=\"t('customApiUrlPlaceholder')\"\r\n [ngModel]=\"customApiUrl()\"\r\n (ngModelChange)=\"onUrlChange($event)\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</mt-card>\r\n" }]
|
|
5135
5317
|
}] });
|
|
5136
5318
|
|
|
5137
5319
|
/**
|
|
@@ -5408,7 +5590,7 @@ class GeneralQuery {
|
|
|
5408
5590
|
useExisting: forwardRef(() => GeneralQuery),
|
|
5409
5591
|
multi: true,
|
|
5410
5592
|
},
|
|
5411
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-4\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n [formGroup]=\"queryForm\"\r\n>\r\n <!-- Category Property (shown for certain chart types) -->\r\n @if (shouldShowField(\"categoryProperty\")) {\r\n <div class=\"mb-2\">\r\n <mt-select-field\r\n [label]=\"t('categoryProperty')\"\r\n formControlName=\"categoryProperty\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectCategoryProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Add Series Button -->\r\n @if (chartType() !== \"overview\" || seriesArray.length === 0) {\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSeries')\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSeries()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Series List -->\r\n <div formArrayName=\"series\" class=\"flex flex-col gap-4\">\r\n @for (\r\n series of seriesArray.controls;\r\n track trackByIndex(i);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all\"\r\n [class.border-red-500]=\"series.invalid\"\r\n [class.border-surface-200]=\"!series.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Series Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full bg-primary-100 text-primary-600 text-sm font-semibold\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n <span class=\"text-sm font-medium text-muted-color\">{{\r\n t(\"series\")\r\n }}</span>\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.settings-02\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"toggleAdvanced(i)\"\r\n [pTooltip]=\"t('advancedSettings')\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"deleteSeries(i)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n <!-- Auto Stack Toggle -->\r\n @if (shouldShowField(\"autoStack\")) {\r\n <div class=\"md:col-span-2 lg:col-span-3\">\r\n <mt-toggle-field\r\n [label]=\"t('autoStack')\"\r\n formControlName=\"autoStack\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Value Property -->\r\n @if (shouldShowField(\"valueProperty\") || series.value.autoStack) {\r\n <mt-select-field\r\n [label]=\"t('valueProperty')\"\r\n formControlName=\"valueProperty\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectValueProperty')\"\r\n [filter]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Aggregate Function -->\r\n @if (shouldShowField(\"aggregateFunction\")) {\r\n <mt-select-field\r\n [label]=\"t('aggregateFunction')\"\r\n formControlName=\"aggregateFunction\"\r\n [options]=\"aggregateFunctions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n\r\n <!-- Color Picker -->\r\n @if (shouldShowField(\"color\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('seriesColor')\"\r\n formControlName=\"color\"\r\n />\r\n }\r\n\r\n <!-- Bar Type (for stacked bar charts) -->\r\n @if (shouldShowField(\"barType\")) {\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n formControlName=\"barType\"\r\n [options]=\"barTypes\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n />\r\n }\r\n\r\n <!-- Auto Stack By Property -->\r\n @if (\r\n shouldShowField(\"autoStackByProperty\") && series.value.autoStack\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('autoStackByProperty')\"\r\n formControlName=\"autoStackByProperty\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Group By Properties -->\r\n @if (shouldShowField(\"groupByProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('groupByProperties')\"\r\n formControlName=\"groupByProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Stack Properties (for stacked charts) -->\r\n @if (shouldShowField(\"stackProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('stackProperties')\"\r\n formControlName=\"stackProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Extra Properties -->\r\n @if (shouldShowField(\"extraProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('extraProperties')\"\r\n formControlName=\"extraProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Advanced Settings (Formula) -->\r\n @if (series.value.showAdvancedSettings && shouldShowField(\"formula\")) {\r\n <div\r\n class=\"mt-4 p-3 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <div class=\"text-sm font-medium mb-2\">\r\n {{ t(\"advancedSettings\") }}\r\n </div>\r\n <mt-text-field\r\n [label]=\"t('formula')\"\r\n formControlName=\"formula\"\r\n [placeholder]=\"t('enterFormula')\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Filters Section -->\r\n @if (shouldShowField(\"filters\")) {\r\n <div class=\"mt-4 border border-surface-200 rounded-lg p-4\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"seriesFilters\") }}</span>\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addFilter(i)\"\r\n [pTooltip]=\"t('addFilter')\"\r\n />\r\n </div>\r\n\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"filters\">\r\n @for (\r\n filter of getFilters(series).controls;\r\n track trackByIndex(j);\r\n let j = $index\r\n ) {\r\n <div\r\n class=\"grid grid-cols-12 gap-2 p-3 bg-surface-50 rounded-lg border border-surface-100\"\r\n [formGroupName]=\"j\"\r\n >\r\n <!-- Property Key -->\r\n <div class=\"col-span-4\">\r\n <mt-select-field\r\n [label]=\"j === 0 ? t('property') : ''\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"\r\n useGroupedSelect()\r\n ? propertiesGrouped()\r\n : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Operator -->\r\n <div class=\"col-span-2\">\r\n <mt-select-field\r\n [label]=\"j === 0 ? t('operator') : ''\"\r\n formControlName=\"operator\"\r\n [options]=\"operators\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n\r\n <!-- Value -->\r\n <div class=\"col-span-4\">\r\n <mt-text-field\r\n [label]=\"j === 0 ? t('value') : ''\"\r\n formControlName=\"value\"\r\n [placeholder]=\"t('enterValue')\"\r\n />\r\n </div>\r\n\r\n <!-- Remove Filter -->\r\n <div class=\"col-span-2 flex items-end justify-end pb-1\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeFilter(i, j)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getFilters(series).length === 0) {\r\n <div class=\"text-center py-3 text-muted-color text-sm\">\r\n {{ t(\"noFiltersConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (seriesArray.length === 0) {\r\n <div\r\n class=\"text-center py-8 text-muted-color border border-dashed border-surface-300 rounded-lg\"\r\n >\r\n <i class=\"mti mti-chart-bar text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSeriesConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSeries')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSeries()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip$1, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5593
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-4\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n [formGroup]=\"queryForm\"\r\n>\r\n <!-- Category Property (shown for certain chart types) -->\r\n @if (shouldShowField(\"categoryProperty\")) {\r\n <div class=\"mb-2\">\r\n <mt-select-field\r\n [label]=\"t('categoryProperty')\"\r\n formControlName=\"categoryProperty\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectCategoryProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Add Series Button -->\r\n @if (chartType() !== \"overview\" || seriesArray.length === 0) {\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSeries')\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSeries()\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Series List -->\r\n <div formArrayName=\"series\" class=\"flex flex-col gap-4\">\r\n @for (\r\n series of seriesArray.controls;\r\n track trackByIndex(i);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"p-4 rounded-lg border transition-all\"\r\n [class.border-red-500]=\"series.invalid\"\r\n [class.border-surface-200]=\"!series.invalid\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Series Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"inline-flex items-center justify-center w-6 h-6 rounded-full bg-primary-100 text-primary-600 text-sm font-semibold\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n <span class=\"text-sm font-medium text-muted-color\">{{\r\n t(\"series\")\r\n }}</span>\r\n </div>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-button\r\n icon=\"general.settings-02\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"toggleAdvanced(i)\"\r\n [pTooltip]=\"t('advancedSettings')\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"deleteSeries(i)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\r\n <!-- Auto Stack Toggle -->\r\n @if (shouldShowField(\"autoStack\")) {\r\n <div class=\"md:col-span-2 lg:col-span-3\">\r\n <mt-toggle-field\r\n [label]=\"t('autoStack')\"\r\n formControlName=\"autoStack\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Value Property -->\r\n @if (shouldShowField(\"valueProperty\") || series.value.autoStack) {\r\n <mt-select-field\r\n [label]=\"t('valueProperty')\"\r\n formControlName=\"valueProperty\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectValueProperty')\"\r\n [filter]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Aggregate Function -->\r\n @if (shouldShowField(\"aggregateFunction\")) {\r\n <mt-select-field\r\n [label]=\"t('aggregateFunction')\"\r\n formControlName=\"aggregateFunction\"\r\n [options]=\"aggregateFunctions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n }\r\n\r\n <!-- Color Picker -->\r\n @if (shouldShowField(\"color\")) {\r\n <mt-color-picker-field\r\n [label]=\"t('seriesColor')\"\r\n formControlName=\"color\"\r\n />\r\n }\r\n\r\n <!-- Bar Type (for stacked bar charts) -->\r\n @if (shouldShowField(\"barType\")) {\r\n <mt-select-field\r\n [label]=\"t('barType')\"\r\n formControlName=\"barType\"\r\n [options]=\"barTypes\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n />\r\n }\r\n\r\n <!-- Auto Stack By Property -->\r\n @if (\r\n shouldShowField(\"autoStackByProperty\") && series.value.autoStack\r\n ) {\r\n <mt-select-field\r\n [label]=\"t('autoStackByProperty')\"\r\n formControlName=\"autoStackByProperty\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Group By Properties -->\r\n @if (shouldShowField(\"groupByProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('groupByProperties')\"\r\n formControlName=\"groupByProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Stack Properties (for stacked charts) -->\r\n @if (shouldShowField(\"stackProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('stackProperties')\"\r\n formControlName=\"stackProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Extra Properties -->\r\n @if (shouldShowField(\"extraProperties\")) {\r\n <div class=\"col-span-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('extraProperties')\"\r\n formControlName=\"extraProperties\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Advanced Settings (Formula) -->\r\n @if (series.value.showAdvancedSettings && shouldShowField(\"formula\")) {\r\n <div\r\n class=\"mt-4 p-3 bg-surface-50 rounded-lg border border-surface-200\"\r\n >\r\n <div class=\"text-sm font-medium mb-2\">\r\n {{ t(\"advancedSettings\") }}\r\n </div>\r\n <mt-text-field\r\n [label]=\"t('formula')\"\r\n formControlName=\"formula\"\r\n [placeholder]=\"t('enterFormula')\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Filters Section -->\r\n @if (shouldShowField(\"filters\")) {\r\n <div class=\"mt-4 border border-surface-200 rounded-lg p-4\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"seriesFilters\") }}</span>\r\n <mt-button\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addFilter(i)\"\r\n [pTooltip]=\"t('addFilter')\"\r\n />\r\n </div>\r\n\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"filters\">\r\n @for (\r\n filter of getFilters(series).controls;\r\n track trackByIndex(j);\r\n let j = $index\r\n ) {\r\n <div\r\n class=\"grid grid-cols-12 gap-2 p-3 bg-surface-50 rounded-lg border border-surface-100\"\r\n [formGroupName]=\"j\"\r\n >\r\n <!-- Property Key -->\r\n <div class=\"col-span-4\">\r\n <mt-select-field\r\n [label]=\"j === 0 ? t('property') : ''\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"\r\n useGroupedSelect()\r\n ? propertiesGrouped()\r\n : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Operator -->\r\n <div class=\"col-span-2\">\r\n <mt-select-field\r\n [label]=\"j === 0 ? t('operator') : ''\"\r\n formControlName=\"operator\"\r\n [options]=\"operators\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n\r\n <!-- Value -->\r\n <div class=\"col-span-4\">\r\n <mt-text-field\r\n [label]=\"j === 0 ? t('value') : ''\"\r\n formControlName=\"value\"\r\n [placeholder]=\"t('enterValue')\"\r\n />\r\n </div>\r\n\r\n <!-- Remove Filter -->\r\n <div class=\"col-span-2 flex items-end justify-end pb-1\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeFilter(i, j)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (getFilters(series).length === 0) {\r\n <div class=\"text-center py-3 text-muted-color text-sm\">\r\n {{ t(\"noFiltersConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (seriesArray.length === 0) {\r\n <div\r\n class=\"text-center py-8 text-muted-color border border-dashed border-surface-300 rounded-lg\"\r\n >\r\n <i class=\"mti mti-chart-bar text-3xl mb-2 block\"></i>\r\n <p class=\"mb-2\">{{ t(\"noSeriesConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addSeries')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"addSeries()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: ColorPickerField, selector: "mt-color-picker-field", inputs: ["label", "appendTo", "placeholder", "class", "variant", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5412
5594
|
}
|
|
5413
5595
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: GeneralQuery, decorators: [{
|
|
5414
5596
|
type: Component,
|
|
@@ -5423,8 +5605,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5423
5605
|
ToggleField,
|
|
5424
5606
|
ColorPickerField,
|
|
5425
5607
|
MultiSelectField,
|
|
5426
|
-
|
|
5427
|
-
Tooltip$1,
|
|
5608
|
+
Tooltip,
|
|
5428
5609
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5429
5610
|
{
|
|
5430
5611
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -5566,7 +5747,7 @@ class TableQuery {
|
|
|
5566
5747
|
useExisting: forwardRef(() => TableQuery),
|
|
5567
5748
|
multi: true,
|
|
5568
5749
|
},
|
|
5569
|
-
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-4\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n [formGroup]=\"queryForm\"\r\n>\r\n <!-- Lookup Property -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('lookupProperty')\"\r\n formControlName=\"lookupProperty\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectLookupProperty')\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Selected Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('properties')\"\r\n formControlName=\"selectedProperties\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n @if (\r\n queryForm.get(\"selectedProperties\")?.invalid &&\r\n queryForm.get(\"selectedProperties\")?.touched\r\n ) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n t(\"atLeastOnePropertyRequired\")\r\n }}</small>\r\n }\r\n </div>\r\n\r\n <!-- Pivot Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('pivotProperties')\"\r\n formControlName=\"PivotProperties\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectPivotProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Aggregation Properties -->\r\n <mt-card [title]=\"t('aggregationProperties')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addAggregation()\"\r\n [disabled]=\"disabled\"\r\n [pTooltip]=\"t('addAggregation')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"AggregationProperties\">\r\n @for (\r\n agg of aggregationArray.controls;\r\n track trackByIndex(i);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"grid grid-cols-12 gap-3 p-3 bg-surface-50 rounded-lg border border-surface-100\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Property Key -->\r\n <div class=\"col-span-5\">\r\n <mt-select-field\r\n [label]=\"i === 0 ? t('property') : ''\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Aggregate Function -->\r\n <div class=\"col-span-4\">\r\n <mt-select-field\r\n [label]=\"i === 0 ? t('aggregateFunction') : ''\"\r\n formControlName=\"aggregateFunction\"\r\n [options]=\"aggregateFunctions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n\r\n <!-- Remove -->\r\n <div class=\"col-span-3 flex items-end justify-end pb-1\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeAggregation(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (aggregationArray.length === 0) {\r\n <div class=\"text-center py-4 text-muted-color text-sm\">\r\n {{ t(\"noAggregationsConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip
|
|
5750
|
+
], ngImport: i0, template: "<div\r\n class=\"flex flex-col gap-4\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n [formGroup]=\"queryForm\"\r\n>\r\n <!-- Lookup Property -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <mt-select-field\r\n [label]=\"t('lookupProperty')\"\r\n formControlName=\"lookupProperty\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectLookupProperty')\"\r\n [filter]=\"true\"\r\n [showClear]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Selected Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('properties')\"\r\n formControlName=\"selectedProperties\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [filter]=\"true\"\r\n />\r\n @if (\r\n queryForm.get(\"selectedProperties\")?.invalid &&\r\n queryForm.get(\"selectedProperties\")?.touched\r\n ) {\r\n <small class=\"text-red-500 mt-1 block\">{{\r\n t(\"atLeastOnePropertyRequired\")\r\n }}</small>\r\n }\r\n </div>\r\n\r\n <!-- Pivot Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('pivotProperties')\"\r\n formControlName=\"PivotProperties\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectPivotProperties')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Aggregation Properties -->\r\n <mt-card [title]=\"t('aggregationProperties')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"addAggregation()\"\r\n [disabled]=\"disabled\"\r\n [pTooltip]=\"t('addAggregation')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-3\" formArrayName=\"AggregationProperties\">\r\n @for (\r\n agg of aggregationArray.controls;\r\n track trackByIndex(i);\r\n let i = $index\r\n ) {\r\n <div\r\n class=\"grid grid-cols-12 gap-3 p-3 bg-surface-50 rounded-lg border border-surface-100\"\r\n [formGroupName]=\"i\"\r\n >\r\n <!-- Property Key -->\r\n <div class=\"col-span-5\">\r\n <mt-select-field\r\n [label]=\"i === 0 ? t('property') : ''\"\r\n formControlName=\"propertyKey\"\r\n [options]=\"\r\n useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\r\n \"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectProperty')\"\r\n [filter]=\"true\"\r\n />\r\n </div>\r\n\r\n <!-- Aggregate Function -->\r\n <div class=\"col-span-4\">\r\n <mt-select-field\r\n [label]=\"i === 0 ? t('aggregateFunction') : ''\"\r\n formControlName=\"aggregateFunction\"\r\n [options]=\"aggregateFunctions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n </div>\r\n\r\n <!-- Remove -->\r\n <div class=\"col-span-3 flex items-end justify-end pb-1\">\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"disabled\"\r\n (onClick)=\"removeAggregation(i)\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (aggregationArray.length === 0) {\r\n <div class=\"text-center py-4 text-muted-color text-sm\">\r\n {{ t(\"noAggregationsConfigured\") }}\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5570
5751
|
}
|
|
5571
5752
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TableQuery, decorators: [{
|
|
5572
5753
|
type: Component,
|
|
@@ -5579,7 +5760,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5579
5760
|
SelectField,
|
|
5580
5761
|
MultiSelectField,
|
|
5581
5762
|
Card,
|
|
5582
|
-
Tooltip
|
|
5763
|
+
Tooltip,
|
|
5583
5764
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5584
5765
|
{
|
|
5585
5766
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -5667,7 +5848,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5667
5848
|
TranslocoDirective,
|
|
5668
5849
|
SelectField,
|
|
5669
5850
|
MultiSelectField,
|
|
5670
|
-
Card,
|
|
5671
5851
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5672
5852
|
{
|
|
5673
5853
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -5738,13 +5918,7 @@ class PropertiesQuery {
|
|
|
5738
5918
|
}
|
|
5739
5919
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesQuery, decorators: [{
|
|
5740
5920
|
type: Component,
|
|
5741
|
-
args: [{ selector: 'mt-properties-query', standalone: true, imports: [
|
|
5742
|
-
CommonModule,
|
|
5743
|
-
FormsModule,
|
|
5744
|
-
TranslocoDirective,
|
|
5745
|
-
MultiSelectField,
|
|
5746
|
-
Card,
|
|
5747
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5921
|
+
args: [{ selector: 'mt-properties-query', standalone: true, imports: [CommonModule, FormsModule, TranslocoDirective, MultiSelectField], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5748
5922
|
{
|
|
5749
5923
|
provide: NG_VALUE_ACCESSOR,
|
|
5750
5924
|
useExisting: forwardRef(() => PropertiesQuery),
|
|
@@ -5828,7 +6002,7 @@ class SnapshotQuery {
|
|
|
5828
6002
|
useExisting: forwardRef(() => SnapshotQuery),
|
|
5829
6003
|
multi: true,
|
|
5830
6004
|
},
|
|
5831
|
-
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <!-- Level ID -->\r\n <mt-text-field\r\n [label]=\"t('levelId')\"\r\n [placeholder]=\"t('enterLevelId')\"\r\n [ngModel]=\"query().levelId\"\r\n (ngModelChange)=\"updateField('levelId', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Time Frame -->\r\n <mt-select-field\r\n [label]=\"t('timeFrame')\"\r\n [options]=\"timeFrameOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectTimeFrame')\"\r\n [ngModel]=\"query().timeFrame\"\r\n (ngModelChange)=\"updateField('timeFrame', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Year -->\r\n <mt-select-field\r\n [label]=\"t('year')\"\r\n [options]=\"yearOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectYear')\"\r\n [ngModel]=\"query().year\"\r\n (ngModelChange)=\"updateField('year', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Get Average Per Period -->\r\n <div class=\"flex items-end pb-2\">\r\n <mt-toggle-field\r\n [label]=\"t('getAveragePerPeriod')\"\r\n [ngModel]=\"query().getAveragePerPeriod\"\r\n (ngModelChange)=\"updateField('getAveragePerPeriod', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Selected Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('selectedProperties')\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [filter]=\"true\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [ngModel]=\"query().selectedProperties\"\r\n (ngModelChange)=\"updateField('selectedProperties', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6005
|
+
], ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <!-- Level ID -->\r\n <mt-text-field\r\n [label]=\"t('levelId')\"\r\n [placeholder]=\"t('enterLevelId')\"\r\n [ngModel]=\"query().levelId\"\r\n (ngModelChange)=\"updateField('levelId', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Time Frame -->\r\n <mt-select-field\r\n [label]=\"t('timeFrame')\"\r\n [options]=\"timeFrameOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectTimeFrame')\"\r\n [ngModel]=\"query().timeFrame\"\r\n (ngModelChange)=\"updateField('timeFrame', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Year -->\r\n <mt-select-field\r\n [label]=\"t('year')\"\r\n [options]=\"yearOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [placeholder]=\"t('selectYear')\"\r\n [ngModel]=\"query().year\"\r\n (ngModelChange)=\"updateField('year', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n\r\n <!-- Get Average Per Period -->\r\n <div class=\"flex items-end pb-2\">\r\n <mt-toggle-field\r\n [label]=\"t('getAveragePerPeriod')\"\r\n [ngModel]=\"query().getAveragePerPeriod\"\r\n (ngModelChange)=\"updateField('getAveragePerPeriod', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Selected Properties -->\r\n <div class=\"w-full\">\r\n <mt-multi-select-field\r\n [label]=\"t('selectedProperties')\"\r\n [options]=\"useGroupedSelect() ? propertiesGrouped() : propertiesFlat()\"\r\n [group]=\"useGroupedSelect()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [filter]=\"true\"\r\n [placeholder]=\"t('selectProperties')\"\r\n [ngModel]=\"query().selectedProperties\"\r\n (ngModelChange)=\"updateField('selectedProperties', $event)\"\r\n [disabled]=\"disabled\"\r\n />\r\n </div>\r\n</div>\r\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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5832
6006
|
}
|
|
5833
6007
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SnapshotQuery, decorators: [{
|
|
5834
6008
|
type: Component,
|
|
@@ -5840,7 +6014,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5840
6014
|
MultiSelectField,
|
|
5841
6015
|
TextField,
|
|
5842
6016
|
ToggleField,
|
|
5843
|
-
Card,
|
|
5844
6017
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5845
6018
|
{
|
|
5846
6019
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -5924,7 +6097,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
5924
6097
|
TranslocoDirective,
|
|
5925
6098
|
SelectField,
|
|
5926
6099
|
MultiSelectField,
|
|
5927
|
-
Card,
|
|
5928
6100
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
5929
6101
|
{
|
|
5930
6102
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -6015,7 +6187,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
6015
6187
|
TranslocoDirective,
|
|
6016
6188
|
SelectField,
|
|
6017
6189
|
TextField,
|
|
6018
|
-
Card,
|
|
6019
6190
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
6020
6191
|
{
|
|
6021
6192
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -6458,7 +6629,7 @@ class DataSourceSettings {
|
|
|
6458
6629
|
return chartType.componentName || '';
|
|
6459
6630
|
}
|
|
6460
6631
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataSourceSettings, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6461
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DataSourceSettings, isStandalone: true, selector: "mt-data-source-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartType: { classPropertyName: "chartType", publicName: "chartType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { serviceConfigChange: "serviceConfigChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Data Source Type Tabs (hidden for layout, snapshot, phaseGate types) -->\r\n @if (!hideSelectionConfig()) {\r\n <mt-tabs\r\n [options]=\"tabOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"id\"\r\n [active]=\"activeTab()\"\r\n (onChange)=\"onTabChange($event)\"\r\n />\r\n }\r\n\r\n <!-- Custom API Configuration Tab -->\r\n @if (!hideSelectionConfig()) {\r\n <div [hidden]=\"activeTab() !== 'customApi'\">\r\n <mt-custom-api-configuration\r\n [ngModel]=\"customApi()\"\r\n (ngModelChange)=\"onCustomApiChange($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Selection Configuration Tab -->\r\n <div [hidden]=\"activeTab() !== 'selection'\">\r\n <!-- Selection Configuration (hidden for layout, snapshot, phaseGate types) -->\r\n @if (!hideSelectionConfig()) {\r\n <mt-selection-configuration\r\n [modulesProperties]=\"modulesProperties()\"\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [ngModel]=\"selections()\"\r\n (ngModelChange)=\"onSelectionsChange($event)\"\r\n (moduleChange)=\"onModuleChange($event)\"\r\n />\r\n\r\n <!-- Source Link Configuration (shown when multiple selections) -->\r\n @if (showSourceLinks()) {\r\n <mt-source-link-configuration\r\n [selectionModules]=\"selectionModules()\"\r\n [ngModel]=\"sourceLinks()\"\r\n (ngModelChange)=\"onSourceLinksChange($event)\"\r\n />\r\n }\r\n }\r\n\r\n <!-- Loading Skeleton for Query Configuration -->\r\n @if (loadingProperties()) {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Skeleton for field labels and inputs -->\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"120px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"100px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"grid grid-cols-2 gap-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"80px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"90px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"140px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <!-- Query Configuration based on chart type -->\r\n @switch (queryComponentType()) {\r\n @case (\"general\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"mb-4 flex items-center\">\r\n <mt-toggle-field\r\n [label]=\"t('isNormalized')\"\r\n [ngModel]=\"isNormalized()\"\r\n (ngModelChange)=\"onIsNormalizedChange($event)\"\r\n />\r\n </div>\r\n <mt-general-query\r\n [chartType]=\"getChartTypeId()\"\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"table\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <!-- Group By Multiple (for non-report table views) -->\r\n @if (showGroupByMultiple()) {\r\n <div class=\"mb-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('groupByMultiple')\"\r\n [options]=\"\r\n propertiesGrouped().length > 1\r\n ? propertiesGrouped()\r\n : propertiesFlat()\r\n \"\r\n [group]=\"propertiesGrouped().length > 1\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectGroupByProperties')\"\r\n [filter]=\"true\"\r\n [ngModel]=\"groupByMultiple()\"\r\n (ngModelChange)=\"onGroupByMultipleChange($event)\"\r\n />\r\n </div>\r\n }\r\n <mt-table-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onTableQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"timeline\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-timeline-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onTimelineQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"timelineMultiLevel\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-layers-three-01 text-3xl mb-2 block\"></i>\r\n <p>{{ t(\"timelineMultiLevelQueryPlaceholder\") }}</p>\r\n <p class=\"text-sm mt-2\">{{ t(\"comingSoon\") }}</p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"map\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-map-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onMapQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"splitter\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-splitter-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onSplitterQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"properties\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-properties-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onPropertiesQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"snapshot\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-snapshot-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onSnapshotQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"phaseGate\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-git-branch-01 text-3xl mb-2 block\"></i>\r\n <p>{{ t(\"phaseGateQueryPlaceholder\") }}</p>\r\n <p class=\"text-sm mt-2\">{{ t(\"comingSoon\") }}</p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"repeater\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('selectDashboard')\"\r\n [options]=\"availableDashboards()\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectDashboardPlaceholder')\"\r\n [ngModel]=\"repeaterDashboardId()\"\r\n (ngModelChange)=\"onRepeaterDashboardChange($event)\"\r\n />\r\n <p class=\"text-sm text-muted-color\">\r\n {{ t(\"repeaterDescription\") }}\r\n </p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"none\") {\r\n <!-- No query configuration needed for layout components -->\r\n }\r\n }\r\n }\r\n </div>\r\n</div>\r\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: ReactiveFormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: SelectionConfiguration, selector: "mt-selection-configuration", inputs: ["modulesProperties", "propertiesFlat"], outputs: ["moduleChange"] }, { kind: "component", type: SourceLinkConfiguration, selector: "mt-source-link-configuration", inputs: ["selectionModules"] }, { kind: "component", type: CustomApiConfiguration, selector: "mt-custom-api-configuration" }, { kind: "component", type: GeneralQuery, selector: "mt-general-query", inputs: ["chartType", "propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: TableQuery, selector: "mt-table-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: TimelineQuery, selector: "mt-timeline-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: PropertiesQuery, selector: "mt-properties-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: SnapshotQuery, selector: "mt-snapshot-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: MapQuery, selector: "mt-map-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: SplitterQuery, selector: "mt-splitter-query", inputs: ["propertiesFlat", "propertiesGrouped"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6632
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DataSourceSettings, isStandalone: true, selector: "mt-data-source-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartType: { classPropertyName: "chartType", publicName: "chartType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { serviceConfigChange: "serviceConfigChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Data Source Type Tabs (hidden for layout, snapshot, phaseGate types) -->\r\n @if (!hideSelectionConfig()) {\r\n <mt-tabs\r\n [options]=\"tabOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"id\"\r\n [active]=\"activeTab()\"\r\n (onChange)=\"onTabChange($event)\"\r\n />\r\n }\r\n\r\n <!-- Custom API Configuration Tab -->\r\n @if (!hideSelectionConfig()) {\r\n <div [hidden]=\"activeTab() !== 'customApi'\">\r\n <mt-custom-api-configuration\r\n [ngModel]=\"customApi()\"\r\n (ngModelChange)=\"onCustomApiChange($event)\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Selection Configuration Tab -->\r\n <div [hidden]=\"activeTab() !== 'selection'\">\r\n <!-- Selection Configuration (hidden for layout, snapshot, phaseGate types) -->\r\n @if (!hideSelectionConfig()) {\r\n <mt-selection-configuration\r\n [modulesProperties]=\"modulesProperties()\"\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [ngModel]=\"selections()\"\r\n (ngModelChange)=\"onSelectionsChange($event)\"\r\n (moduleChange)=\"onModuleChange($event)\"\r\n />\r\n\r\n <!-- Source Link Configuration (shown when multiple selections) -->\r\n @if (showSourceLinks()) {\r\n <mt-source-link-configuration\r\n [selectionModules]=\"selectionModules()\"\r\n [ngModel]=\"sourceLinks()\"\r\n (ngModelChange)=\"onSourceLinksChange($event)\"\r\n />\r\n }\r\n }\r\n\r\n <!-- Loading Skeleton for Query Configuration -->\r\n @if (loadingProperties()) {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Skeleton for field labels and inputs -->\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"120px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"100px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"grid grid-cols-2 gap-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"80px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"90px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n <div class=\"flex flex-col gap-2\">\r\n <p-skeleton width=\"140px\" height=\"16px\" />\r\n <p-skeleton width=\"100%\" height=\"40px\" borderRadius=\"8px\" />\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <!-- Query Configuration based on chart type -->\r\n @switch (queryComponentType()) {\r\n @case (\"general\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"mb-4 flex items-center\">\r\n <mt-toggle-field\r\n [label]=\"t('isNormalized')\"\r\n [ngModel]=\"isNormalized()\"\r\n (ngModelChange)=\"onIsNormalizedChange($event)\"\r\n />\r\n </div>\r\n <mt-general-query\r\n [chartType]=\"getChartTypeId()\"\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"table\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <!-- Group By Multiple (for non-report table views) -->\r\n @if (showGroupByMultiple()) {\r\n <div class=\"mb-4\">\r\n <mt-multi-select-field\r\n [label]=\"t('groupByMultiple')\"\r\n [options]=\"\r\n propertiesGrouped().length > 1\r\n ? propertiesGrouped()\r\n : propertiesFlat()\r\n \"\r\n [group]=\"propertiesGrouped().length > 1\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n optionGroupLabel=\"label\"\r\n optionGroupChildren=\"items\"\r\n [placeholder]=\"t('selectGroupByProperties')\"\r\n [filter]=\"true\"\r\n [ngModel]=\"groupByMultiple()\"\r\n (ngModelChange)=\"onGroupByMultipleChange($event)\"\r\n />\r\n </div>\r\n }\r\n <mt-table-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onTableQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"timeline\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-timeline-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onTimelineQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"timelineMultiLevel\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-layers-three-01 text-3xl mb-2 block\"></i>\r\n <p>{{ t(\"timelineMultiLevelQueryPlaceholder\") }}</p>\r\n <p class=\"text-sm mt-2\">{{ t(\"comingSoon\") }}</p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"map\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-map-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onMapQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"splitter\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-splitter-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onSplitterQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"properties\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-properties-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onPropertiesQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"snapshot\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <mt-snapshot-query\r\n [propertiesFlat]=\"propertiesFlat()\"\r\n [propertiesGrouped]=\"propertiesGrouped()\"\r\n [ngModel]=\"query()\"\r\n (ngModelChange)=\"onSnapshotQueryChange($event)\"\r\n />\r\n </mt-card>\r\n }\r\n @case (\"phaseGate\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"text-center py-8 text-muted-color\">\r\n <i class=\"mti mti-git-branch-01 text-3xl mb-2 block\"></i>\r\n <p>{{ t(\"phaseGateQueryPlaceholder\") }}</p>\r\n <p class=\"text-sm mt-2\">{{ t(\"comingSoon\") }}</p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"repeater\") {\r\n <mt-card [title]=\"t('queryConfiguration')\">\r\n <div class=\"flex flex-col gap-4\">\r\n <mt-select-field\r\n [label]=\"t('selectDashboard')\"\r\n [options]=\"availableDashboards()\"\r\n optionLabel=\"name\"\r\n optionValue=\"id\"\r\n [placeholder]=\"t('selectDashboardPlaceholder')\"\r\n [ngModel]=\"repeaterDashboardId()\"\r\n (ngModelChange)=\"onRepeaterDashboardChange($event)\"\r\n />\r\n <p class=\"text-sm text-muted-color\">\r\n {{ t(\"repeaterDescription\") }}\r\n </p>\r\n </div>\r\n </mt-card>\r\n }\r\n @case (\"none\") {\r\n <!-- No query configuration needed for layout components -->\r\n }\r\n }\r\n }\r\n </div>\r\n</div>\r\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: ReactiveFormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "inputId", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "component", type: MultiSelectField, selector: "mt-multi-select-field", inputs: ["field", "label", "placeholder", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "display", "required", "maxSelectedLabels", "group", "optionGroupLabel", "optionGroupChildren", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: SelectionConfiguration, selector: "mt-selection-configuration", inputs: ["modulesProperties", "propertiesFlat"], outputs: ["moduleChange"] }, { kind: "component", type: SourceLinkConfiguration, selector: "mt-source-link-configuration", inputs: ["selectionModules"] }, { kind: "component", type: CustomApiConfiguration, selector: "mt-custom-api-configuration" }, { kind: "component", type: GeneralQuery, selector: "mt-general-query", inputs: ["chartType", "propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: TableQuery, selector: "mt-table-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: TimelineQuery, selector: "mt-timeline-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: PropertiesQuery, selector: "mt-properties-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: SnapshotQuery, selector: "mt-snapshot-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: MapQuery, selector: "mt-map-query", inputs: ["propertiesFlat", "propertiesGrouped"] }, { kind: "component", type: SplitterQuery, selector: "mt-splitter-query", inputs: ["propertiesFlat", "propertiesGrouped"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6462
6633
|
}
|
|
6463
6634
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataSourceSettings, decorators: [{
|
|
6464
6635
|
type: Component,
|
|
@@ -6468,11 +6639,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
6468
6639
|
ReactiveFormsModule,
|
|
6469
6640
|
TranslocoDirective,
|
|
6470
6641
|
Skeleton,
|
|
6471
|
-
Button,
|
|
6472
6642
|
SelectField,
|
|
6473
6643
|
ToggleField,
|
|
6474
6644
|
MultiSelectField,
|
|
6475
|
-
TextField,
|
|
6476
6645
|
Card,
|
|
6477
6646
|
Tabs,
|
|
6478
6647
|
SelectionConfiguration,
|
|
@@ -6777,18 +6946,17 @@ class ActionsSettings {
|
|
|
6777
6946
|
return index;
|
|
6778
6947
|
}
|
|
6779
6948
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ActionsSettings, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6780
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ActionsSettings, isStandalone: true, selector: "mt-actions-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clientConfigChange: "clientConfigChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('actions')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n (onClick)=\"addAction()\"\r\n [pTooltip]=\"t('addAction')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Actions List -->\r\n @for (\r\n action of actions();\r\n track $index;\r\n let i = $index;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"p-4 bg-surface-50 rounded-lg border border-surface-200 hover:border-surface-300 transition-all\"\r\n >\r\n <!-- Action Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"w-6 h-6 flex items-center justify-center bg-primary-100 text-primary-600 rounded-full text-sm font-medium\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n <span class=\"font-medium text-sm\">\r\n {{ getActionTypeLabel(action.actionType) }}\r\n </span>\r\n <span class=\"text-xs text-muted-color\">\r\n ({{ getTriggerLabel(action.type) }})\r\n </span>\r\n </div>\r\n <div class=\"flex items-center gap-1\">\r\n <!-- Move Up -->\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"first\"\r\n (onClick)=\"moveActionUp(i)\"\r\n [pTooltip]=\"t('moveUp')\"\r\n />\r\n <!-- Move Down -->\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"last\"\r\n (onClick)=\"moveActionDown(i)\"\r\n [pTooltip]=\"t('moveDown')\"\r\n />\r\n <!-- Duplicate -->\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"duplicateAction(i)\"\r\n [pTooltip]=\"t('duplicate')\"\r\n />\r\n <!-- Remove -->\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeAction(i)\"\r\n [pTooltip]=\"t('remove')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Action Configuration -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <!-- Trigger Type -->\r\n <mt-select-field\r\n [label]=\"t('trigger')\"\r\n [ngModel]=\"action.type\"\r\n (ngModelChange)=\"updateAction(i, 'type', $event)\"\r\n [options]=\"triggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Action Type -->\r\n <mt-select-field\r\n [label]=\"t('actionType')\"\r\n [ngModel]=\"action.actionType\"\r\n (ngModelChange)=\"updateAction(i, 'actionType', $event)\"\r\n [options]=\"actionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Target ID (for dialog/navigation) -->\r\n @if (\r\n action.actionType === \"openDialog\" ||\r\n action.actionType === \"navigateToPage\"\r\n ) {\r\n <mt-text-field\r\n [label]=\"t('targetId')\"\r\n [ngModel]=\"action.id || ''\"\r\n (ngModelChange)=\"updateAction(i, 'id', $event)\"\r\n [placeholder]=\"t('enterTargetId')\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Dynamic Keys Section -->\r\n @if (\r\n action.actionType === \"navigateToPage\" ||\r\n action.actionType === \"openDialog\"\r\n ) {\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"dynamicKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addDynamicKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.dynamicKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeDynamicKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.dynamicKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noDynamicKeys\") }}</p>\r\n }\r\n </div>\r\n\r\n <!-- Static Keys Section -->\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"staticKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addStaticKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.staticKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeStaticKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.staticKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noStaticKeys\") }}</p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (actions().length === 0) {\r\n <div class=\"text-center py-12 text-muted-color\">\r\n <mt-icon icon=\"editor.cursor-click-01\" class=\"text-4xl mb-3\" />\r\n <p class=\"mb-4\">{{ t(\"noActionsConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addAction')\"\r\n severity=\"secondary\"\r\n (onClick)=\"addAction()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n <!-- Actions Help Card -->\r\n <mt-card [title]=\"t('actionsHelp')\">\r\n <div class=\"text-sm text-muted-color space-y-2\">\r\n <p>\r\n <strong>{{ t(\"openDialog\") }}:</strong> {{ t(\"openDialogDesc\") }}\r\n </p>\r\n <p>\r\n <strong>{{ t(\"navigate\") }}:</strong> {{ t(\"navigateDesc\") }}\r\n </p>\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ 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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "directive", type: Tooltip$1, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6949
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ActionsSettings, isStandalone: true, selector: "mt-actions-settings", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clientConfigChange: "clientConfigChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('actions')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n (onClick)=\"addAction()\"\r\n [pTooltip]=\"t('addAction')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Actions List -->\r\n @for (\r\n action of actions();\r\n track $index;\r\n let i = $index;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"p-4 bg-surface-50 rounded-lg border border-surface-200 hover:border-surface-300 transition-all\"\r\n >\r\n <!-- Action Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"w-6 h-6 flex items-center justify-center bg-primary-100 text-primary-600 rounded-full text-sm font-medium\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n <span class=\"font-medium text-sm\">\r\n {{ getActionTypeLabel(action.actionType) }}\r\n </span>\r\n <span class=\"text-xs text-muted-color\">\r\n ({{ getTriggerLabel(action.type) }})\r\n </span>\r\n </div>\r\n <div class=\"flex items-center gap-1\">\r\n <!-- Move Up -->\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"first\"\r\n (onClick)=\"moveActionUp(i)\"\r\n [pTooltip]=\"t('moveUp')\"\r\n />\r\n <!-- Move Down -->\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"last\"\r\n (onClick)=\"moveActionDown(i)\"\r\n [pTooltip]=\"t('moveDown')\"\r\n />\r\n <!-- Duplicate -->\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"duplicateAction(i)\"\r\n [pTooltip]=\"t('duplicate')\"\r\n />\r\n <!-- Remove -->\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeAction(i)\"\r\n [pTooltip]=\"t('remove')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Action Configuration -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <!-- Trigger Type -->\r\n <mt-select-field\r\n [label]=\"t('trigger')\"\r\n [ngModel]=\"action.type\"\r\n (ngModelChange)=\"updateAction(i, 'type', $event)\"\r\n [options]=\"triggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Action Type -->\r\n <mt-select-field\r\n [label]=\"t('actionType')\"\r\n [ngModel]=\"action.actionType\"\r\n (ngModelChange)=\"updateAction(i, 'actionType', $event)\"\r\n [options]=\"actionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Target ID (for dialog/navigation) -->\r\n @if (\r\n action.actionType === \"openDialog\" ||\r\n action.actionType === \"navigateToPage\"\r\n ) {\r\n <mt-text-field\r\n [label]=\"t('targetId')\"\r\n [ngModel]=\"action.id || ''\"\r\n (ngModelChange)=\"updateAction(i, 'id', $event)\"\r\n [placeholder]=\"t('enterTargetId')\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Dynamic Keys Section -->\r\n @if (\r\n action.actionType === \"navigateToPage\" ||\r\n action.actionType === \"openDialog\"\r\n ) {\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"dynamicKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addDynamicKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.dynamicKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeDynamicKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.dynamicKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noDynamicKeys\") }}</p>\r\n }\r\n </div>\r\n\r\n <!-- Static Keys Section -->\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"staticKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addStaticKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.staticKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeStaticKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.staticKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noStaticKeys\") }}</p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (actions().length === 0) {\r\n <div class=\"text-center py-12 text-muted-color\">\r\n <mt-icon icon=\"editor.cursor-click-01\" class=\"text-4xl mb-3\" />\r\n <p class=\"mb-4\">{{ t(\"noActionsConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addAction')\"\r\n severity=\"secondary\"\r\n (onClick)=\"addAction()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n <!-- Actions Help Card -->\r\n <mt-card [title]=\"t('actionsHelp')\">\r\n <div class=\"text-sm text-muted-color space-y-2\">\r\n <p>\r\n <strong>{{ t(\"openDialog\") }}:</strong> {{ t(\"openDialogDesc\") }}\r\n </p>\r\n <p>\r\n <strong>{{ t(\"navigate\") }}:</strong> {{ t(\"navigateDesc\") }}\r\n </p>\r\n </div>\r\n </mt-card>\r\n</div>\r\n", dependencies: [{ 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: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6781
6950
|
}
|
|
6782
6951
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ActionsSettings, decorators: [{
|
|
6783
6952
|
type: Component,
|
|
6784
6953
|
args: [{ selector: 'mt-actions-settings', standalone: true, imports: [
|
|
6785
6954
|
FormsModule,
|
|
6786
6955
|
TranslocoDirective,
|
|
6787
|
-
Tooltip
|
|
6956
|
+
Tooltip,
|
|
6788
6957
|
Button,
|
|
6789
6958
|
TextField,
|
|
6790
6959
|
SelectField,
|
|
6791
|
-
ToggleField,
|
|
6792
6960
|
Card,
|
|
6793
6961
|
Icon,
|
|
6794
6962
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"flex flex-col gap-4\" *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <mt-card [title]=\"t('actions')\">\r\n <ng-template #cardEnd>\r\n <mt-button\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n (onClick)=\"addAction()\"\r\n [pTooltip]=\"t('addAction')\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Actions List -->\r\n @for (\r\n action of actions();\r\n track $index;\r\n let i = $index;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"p-4 bg-surface-50 rounded-lg border border-surface-200 hover:border-surface-300 transition-all\"\r\n >\r\n <!-- Action Header -->\r\n <div class=\"flex items-center justify-between mb-4\">\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"w-6 h-6 flex items-center justify-center bg-primary-100 text-primary-600 rounded-full text-sm font-medium\"\r\n >\r\n {{ i + 1 }}\r\n </span>\r\n <span class=\"font-medium text-sm\">\r\n {{ getActionTypeLabel(action.actionType) }}\r\n </span>\r\n <span class=\"text-xs text-muted-color\">\r\n ({{ getTriggerLabel(action.type) }})\r\n </span>\r\n </div>\r\n <div class=\"flex items-center gap-1\">\r\n <!-- Move Up -->\r\n <mt-button\r\n icon=\"general.chevron-up\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"first\"\r\n (onClick)=\"moveActionUp(i)\"\r\n [pTooltip]=\"t('moveUp')\"\r\n />\r\n <!-- Move Down -->\r\n <mt-button\r\n icon=\"general.chevron-down\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n [disabled]=\"last\"\r\n (onClick)=\"moveActionDown(i)\"\r\n [pTooltip]=\"t('moveDown')\"\r\n />\r\n <!-- Duplicate -->\r\n <mt-button\r\n icon=\"general.copy-01\"\r\n severity=\"secondary\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"duplicateAction(i)\"\r\n [pTooltip]=\"t('duplicate')\"\r\n />\r\n <!-- Remove -->\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"removeAction(i)\"\r\n [pTooltip]=\"t('remove')\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Action Configuration -->\r\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\r\n <!-- Trigger Type -->\r\n <mt-select-field\r\n [label]=\"t('trigger')\"\r\n [ngModel]=\"action.type\"\r\n (ngModelChange)=\"updateAction(i, 'type', $event)\"\r\n [options]=\"triggerOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Action Type -->\r\n <mt-select-field\r\n [label]=\"t('actionType')\"\r\n [ngModel]=\"action.actionType\"\r\n (ngModelChange)=\"updateAction(i, 'actionType', $event)\"\r\n [options]=\"actionTypeOptions\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n />\r\n\r\n <!-- Target ID (for dialog/navigation) -->\r\n @if (\r\n action.actionType === \"openDialog\" ||\r\n action.actionType === \"navigateToPage\"\r\n ) {\r\n <mt-text-field\r\n [label]=\"t('targetId')\"\r\n [ngModel]=\"action.id || ''\"\r\n (ngModelChange)=\"updateAction(i, 'id', $event)\"\r\n [placeholder]=\"t('enterTargetId')\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Dynamic Keys Section -->\r\n @if (\r\n action.actionType === \"navigateToPage\" ||\r\n action.actionType === \"openDialog\"\r\n ) {\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"dynamicKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addDynamicKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.dynamicKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateDynamicKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeDynamicKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.dynamicKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noDynamicKeys\") }}</p>\r\n }\r\n </div>\r\n\r\n <!-- Static Keys Section -->\r\n <div class=\"mt-4 pt-4 border-t border-surface-200\">\r\n <div class=\"flex items-center justify-between mb-3\">\r\n <span class=\"text-sm font-medium\">{{ t(\"staticKeys\") }}</span>\r\n <mt-button\r\n [label]=\"t('addKey')\"\r\n icon=\"general.plus\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n (onClick)=\"addStaticKey(i)\"\r\n />\r\n </div>\r\n @for (\r\n key of action.config?.staticKeys ?? [];\r\n track $index;\r\n let keyIndex = $index\r\n ) {\r\n <div class=\"flex items-center gap-2 mb-2\">\r\n <mt-text-field\r\n [label]=\"t('propertyKey')\"\r\n [ngModel]=\"key.propertyKey\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyKey', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-text-field\r\n [label]=\"t('propertyValue')\"\r\n [ngModel]=\"key.propertyValue\"\r\n (ngModelChange)=\"\r\n updateStaticKey(i, keyIndex, 'propertyValue', $event)\r\n \"\r\n size=\"small\"\r\n class=\"flex-1\"\r\n />\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n (onClick)=\"removeStaticKey(i, keyIndex)\"\r\n />\r\n </div>\r\n }\r\n @if ((action.config?.staticKeys ?? []).length === 0) {\r\n <p class=\"text-xs text-muted-color\">{{ t(\"noStaticKeys\") }}</p>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (actions().length === 0) {\r\n <div class=\"text-center py-12 text-muted-color\">\r\n <mt-icon icon=\"editor.cursor-click-01\" class=\"text-4xl mb-3\" />\r\n <p class=\"mb-4\">{{ t(\"noActionsConfigured\") }}</p>\r\n <mt-button\r\n icon=\"general.plus\"\r\n [label]=\"t('addAction')\"\r\n severity=\"secondary\"\r\n (onClick)=\"addAction()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </mt-card>\r\n\r\n <!-- Actions Help Card -->\r\n <mt-card [title]=\"t('actionsHelp')\">\r\n <div class=\"text-sm text-muted-color space-y-2\">\r\n <p>\r\n <strong>{{ t(\"openDialog\") }}:</strong> {{ t(\"openDialogDesc\") }}\r\n </p>\r\n <p>\r\n <strong>{{ t(\"navigate\") }}:</strong> {{ t(\"navigateDesc\") }}\r\n </p>\r\n </div>\r\n </mt-card>\r\n</div>\r\n" }]
|
|
@@ -15229,9 +15397,8 @@ class ActionService {
|
|
|
15229
15397
|
*/
|
|
15230
15398
|
showDialog(action, data, config) {
|
|
15231
15399
|
const actionData = this.handleActionsConfig(action.config, data, config);
|
|
15232
|
-
debugger;
|
|
15233
15400
|
// Dynamically import DashboardDialogComponent to avoid circular dependency
|
|
15234
|
-
import('./masterteam-dashboard-builder-dashboard-dialog.component-
|
|
15401
|
+
import('./masterteam-dashboard-builder-dashboard-dialog.component-CMNlOHiK.mjs').then(({ DashboardDialogComponent }) => {
|
|
15235
15402
|
// Open dialog using ModalService
|
|
15236
15403
|
this.modalService.openModal(DashboardDialogComponent, 'dialog', {
|
|
15237
15404
|
header: config.clientConfig?.title?.['en'] || '',
|
|
@@ -15476,7 +15643,7 @@ class CardContentComponent {
|
|
|
15476
15643
|
}
|
|
15477
15644
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CardContentComponent, decorators: [{
|
|
15478
15645
|
type: Component,
|
|
15479
|
-
args: [{ selector: 'mt-card-content', standalone: true, imports: [CommonModule
|
|
15646
|
+
args: [{ selector: 'mt-card-content', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"db-card-content\"\r\n [class.in-group]=\"inGroup()\"\r\n [class.no-header]=\"!showHeaderState()\"\r\n [ngStyle]=\"cardStyles()\"\r\n [style]=\"borderRadiusStyle()\"\r\n>\r\n <!-- Header -->\r\n @if (showHeaderState()) {\r\n <div\r\n class=\"db-card-header\"\r\n [class.clickable]=\"headerClickableState()\"\r\n [class.center-title]=\"headerConfig()?.isHeaderCentered && isNoTopEnd()\"\r\n [ngStyle]=\"headerRowStyles()\"\r\n (click)=\"onHeaderClick()\"\r\n >\r\n <div\r\n class=\"db-card-title-section\"\r\n [class.center-mode]=\"headerConfig()?.isHeaderCentered\"\r\n [class.force-full-width]=\"isNoTopEnd()\"\r\n >\r\n @if (headerConfig()?.icon) {\r\n <span\r\n class=\"db-card-icon\"\r\n [style.color]=\"\r\n headerConfig()?.iconColor || styleConfig()?.iconColor || 'inherit'\r\n \"\r\n [style.background-color]=\"styleConfig()?.iconBgColor\"\r\n >\r\n <i [class]=\"headerConfig()?.icon\"></i>\r\n </span>\r\n }\r\n <h3\r\n class=\"db-card-title\"\r\n [style.color]=\"\r\n headerConfig()?.headerColor ||\r\n headerConfig()?.titleColor ||\r\n 'inherit'\r\n \"\r\n [style.font-size]=\"\r\n headerConfig()?.headerFontSize\r\n ? headerConfig()?.headerFontSize + 'px'\r\n : null\r\n \"\r\n [attr.title]=\"title()\"\r\n >\r\n {{ title() }}\r\n </h3>\r\n </div>\r\n\r\n <div class=\"db-card-top-end\">\r\n <ng-content select=\"[topEnd]\"></ng-content>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Body -->\r\n <div\r\n class=\"db-card-body\"\r\n [class.no-top-end]=\"isNoTopEnd()\"\r\n [class.is-chart]=\"isChart()\"\r\n >\r\n <ng-content select=\"[body]\"></ng-content>\r\n </div>\r\n\r\n <!-- Footer (optional) -->\r\n <div class=\"db-card-footer\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </div>\r\n</div>\r\n", styles: [".db-card-content{display:flex;flex-direction:column;height:100%;background:#fff;border-radius:.5rem;box-shadow:0 1px 3px #0000001a;overflow:hidden}.db-card-content.in-group{box-shadow:none;border-radius:0}.db-card-content.no-header .db-card-body{padding-top:1rem}.db-card-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-bottom:1px solid #f0f0f0;min-height:3rem}.db-card-header.clickable{cursor:pointer;transition:background-color .15s ease}.db-card-header.clickable:hover{background-color:#f9f9f9}.db-card-title-section{display:flex;align-items:center;gap:.5rem;flex:1;min-width:0}.db-card-title-section.center-mode{justify-content:center}.db-card-title-section.force-full-width{width:100%}.db-card-header.center-title{justify-content:center}.db-card-icon{font-size:1.25rem;flex-shrink:0}.db-card-title{margin:0;font-size:.95rem;font-weight:600;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.db-card-top-end{display:flex;align-items:center;gap:.5rem;flex-shrink:0;max-width:45%}.db-card-body{flex:1;padding:.75rem 1rem;overflow:auto;min-height:0}.db-card-body.is-chart{overflow-y:hidden}.db-card-body.no-top-end{padding-top:1rem}.db-card-footer:empty{display:none}.db-card-footer{padding:.5rem 1rem;border-top:1px solid #f0f0f0}\n"] }]
|
|
15480
15647
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], headerConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerConfig", required: false }] }], styleConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleConfig", required: false }] }], cardStyleConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardStyleConfig", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], headerClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerClickable", required: false }] }], isNoTopEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "isNoTopEnd", required: false }] }], isChart: [{ type: i0.Input, args: [{ isSignal: true, alias: "isChart", required: false }] }], headerClick: [{ type: i0.Output, args: ["headerClick"] }] } });
|
|
15481
15648
|
|
|
15482
15649
|
/**
|
|
@@ -16326,11 +16493,11 @@ class CardInfoComponent {
|
|
|
16326
16493
|
<i class="pi pi-info-circle"></i>
|
|
16327
16494
|
</span>
|
|
16328
16495
|
}
|
|
16329
|
-
`, isInline: true, styles: [".card-info-icon{display:inline-flex;align-items:center;justify-content:center;cursor:help;color:#666;font-size:1rem;transition:color .15s ease}.card-info-icon:hover{color:#333}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16496
|
+
`, isInline: true, styles: [".card-info-icon{display:inline-flex;align-items:center;justify-content:center;cursor:help;color:#666;font-size:1rem;transition:color .15s ease}.card-info-icon:hover{color:#333}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Tooltip$1, selector: "[mtTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
16330
16497
|
}
|
|
16331
16498
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CardInfoComponent, decorators: [{
|
|
16332
16499
|
type: Component,
|
|
16333
|
-
args: [{ selector: 'mt-card-info', standalone: true, imports: [CommonModule, Tooltip], template: `
|
|
16500
|
+
args: [{ selector: 'mt-card-info', standalone: true, imports: [CommonModule, Tooltip$1], template: `
|
|
16334
16501
|
@if (showInfo()) {
|
|
16335
16502
|
<span
|
|
16336
16503
|
class="card-info-icon"
|
|
@@ -17039,7 +17206,7 @@ class EntityInfoComponent {
|
|
|
17039
17206
|
}
|
|
17040
17207
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityInfoComponent, decorators: [{
|
|
17041
17208
|
type: Component,
|
|
17042
|
-
args: [{ selector: 'mt-entity-info', standalone: true, imports: [CommonModule, TranslocoDirective, DecimalPipe, DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"entity-info-wrapper w-full\" *transloco=\"let t; prefix: 'dashboard'\">\r\n @switch (viewTypeLower()) {\r\n <!-- Text Types -->\r\n @case (\"text\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"float\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"longtext\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"title\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"phasegate\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Number -->\r\n @case (\"number\") {\r\n <ng-container *ngTemplateOutlet=\"numberTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Date Types -->\r\n @case (\"date\") {\r\n <ng-container *ngTemplateOutlet=\"dateTemplate\"></ng-container>\r\n }\r\n @case (\"datetime\") {\r\n <ng-container *ngTemplateOutlet=\"dateTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Currency -->\r\n @case (\"currency\") {\r\n <ng-container *ngTemplateOutlet=\"currencyTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Time -->\r\n @case (\"time\") {\r\n <ng-container *ngTemplateOutlet=\"timeTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Lookup -->\r\n @case (\"lookup\") {\r\n <ng-container *ngTemplateOutlet=\"lookupTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Checkbox -->\r\n @case (\"checkbox\") {\r\n <ng-container *ngTemplateOutlet=\"checkboxTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Status -->\r\n @case (\"status\") {\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n }\r\n @case (\"request_status\") {\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Percentage -->\r\n @case (\"percentage\") {\r\n <ng-container *ngTemplateOutlet=\"percentageTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Slider -->\r\n @case (\"slider\") {\r\n <ng-container *ngTemplateOutlet=\"sliderTemplate\"></ng-container>\r\n }\r\n\r\n <!-- User -->\r\n @case (\"user\") {\r\n <ng-container *ngTemplateOutlet=\"userTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Multi-select lookup -->\r\n @case (\"lookupmultiselect\") {\r\n <ng-container\r\n *ngTemplateOutlet=\"lookupMultiselectTemplate\"\r\n ></ng-container>\r\n }\r\n\r\n <!-- Multi user -->\r\n @case (\"multiuser\") {\r\n <ng-container *ngTemplateOutlet=\"multiUserTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Dynamic List -->\r\n @case (\"dynamiclist\") {\r\n <ng-container *ngTemplateOutlet=\"dynamicListTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Location -->\r\n @case (\"location\") {\r\n <ng-container *ngTemplateOutlet=\"locationTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Default: treat as text -->\r\n @default {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n }\r\n</div>\r\n\r\n<!-- Text Template -->\r\n<ng-template #textTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div\r\n class=\"font-semibold\"\r\n [class.text-ellipsis]=\"limitWords()\"\r\n [class.overflow-hidden]=\"limitWords()\"\r\n [class.whitespace-nowrap]=\"limitWords()\"\r\n [style.max-width]=\"limitWords() ? '200px' : 'auto'\"\r\n [title]=\"textValue()\"\r\n >\r\n {{ textValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Number Template -->\r\n<ng-template #numberTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ numericValue() !== null ? (numericValue() | number) : \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Date Template -->\r\n<ng-template #dateTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ dateDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Currency Template -->\r\n<ng-template #currencyTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ currencyDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Time Template -->\r\n<ng-template #timeTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ timeDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Lookup Template -->\r\n<ng-template #lookupTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (lookupName()) {\r\n <span class=\"flex items-center gap-1\" [style.color]=\"lookupColor()\">\r\n @if (displayType() === \"entity\" && lookupColor()) {\r\n <span\r\n class=\"w-2 h-2 rounded-full inline-block\"\r\n [style.backgroundColor]=\"lookupColor()\"\r\n ></span>\r\n }\r\n {{ lookupName() }}\r\n </span>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Checkbox Template -->\r\n<ng-template #checkboxTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center\">\r\n <i\r\n [class]=\"\r\n checkboxValue()\r\n ? 'pi pi-check-square text-primary'\r\n : 'pi pi-stop text-muted-color'\r\n \"\r\n ></i>\r\n <span class=\"ml-2\">{{ checkboxValue() ? \"Yes\" : \"No\" }}</span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Status Template -->\r\n<ng-template #statusTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n @if (statusColor()) {\r\n <span\r\n class=\"w-2.5 h-2.5 rounded-full flex-shrink-0\"\r\n [style.backgroundColor]=\"statusColor()\"\r\n ></span>\r\n }\r\n <span [style.color]=\"statusColor()\">\r\n {{ statusName() || \"__\" }}\r\n </span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Percentage Template -->\r\n<ng-template #percentageTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n @if (\r\n displayType() !== \"inTable\" ||\r\n extraInfoData()?.showPercentageAsProgressBar\r\n ) {\r\n <div\r\n class=\"flex-1 h-2 bg-surface-200 rounded-full overflow-hidden max-w-24\"\r\n >\r\n <div\r\n class=\"h-full rounded-full transition-all\"\r\n [style.width.%]=\"percentageValue() || 0\"\r\n [style.backgroundColor]=\"percentageColor() || 'var(--primary-color)'\"\r\n ></div>\r\n </div>\r\n }\r\n @if (\r\n extraInfoData()?.showPercentageStatus &&\r\n !extraInfoData()?.showPercentageAsProgressBar\r\n ) {\r\n <span\r\n class=\"w-2.5 h-2.5 rounded-full\"\r\n [style.backgroundColor]=\"percentageColor() || '#000'\"\r\n ></span>\r\n }\r\n <span [style.color]=\"percentageColor()\">\r\n {{\r\n percentageValue() !== null\r\n ? (percentageValue() | number: \"1.0-0\") + \"%\"\r\n : \"__\"\r\n }}\r\n </span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Slider Template -->\r\n<ng-template #sliderTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n <div\r\n class=\"flex-1 h-2 bg-surface-200 rounded-full overflow-hidden max-w-32\"\r\n >\r\n <div\r\n class=\"h-full bg-primary rounded-full transition-all\"\r\n [style.width.%]=\"sliderValue() || 0\"\r\n ></div>\r\n </div>\r\n <span class=\"text-sm\">{{ sliderValue() || 0 }}%</span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- User Template -->\r\n<ng-template #userTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (userData()) {\r\n <div class=\"flex items-center gap-2\">\r\n @if (userData()?.avatar || userData()?.image) {\r\n <img\r\n [src]=\"userData()?.avatar || userData()?.image\"\r\n alt=\"User avatar\"\r\n class=\"w-8 h-8 rounded-full object-cover\"\r\n />\r\n } @else {\r\n <div\r\n class=\"w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center text-primary font-semibold text-sm\"\r\n >\r\n {{ userInitials() }}\r\n </div>\r\n }\r\n <span class=\"font-medium\">{{ userName() }}</span>\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Lookup Multiselect Template -->\r\n<ng-template #lookupMultiselectTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (multiselectValues()?.length) {\r\n <div class=\"flex flex-wrap gap-1\">\r\n @for (item of multiselectValues(); track item.key || $index) {\r\n <span\r\n class=\"px-2 py-0.5 rounded-full text-xs font-medium\"\r\n [style.backgroundColor]=\"(item.details?.color || '#6b7280') + '20'\"\r\n [style.color]=\"item.details?.color || '#6b7280'\"\r\n >\r\n {{ item.name || item.display || item }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Multi User Template -->\r\n<ng-template #multiUserTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (multiUserValues()?.length) {\r\n <div class=\"flex items-center -space-x-2\">\r\n @for (user of multiUserValues().slice(0, 5); track user.id || $index) {\r\n @if (user.avatar || user.image) {\r\n <img\r\n [src]=\"user.avatar || user.image\"\r\n [alt]=\"user.name || user.displayName\"\r\n class=\"w-7 h-7 rounded-full border-2 border-white object-cover\"\r\n />\r\n } @else {\r\n <div\r\n class=\"w-7 h-7 rounded-full border-2 border-white bg-primary/20 flex items-center justify-center text-primary font-semibold text-xs\"\r\n >\r\n {{ getInitials(user.name || user.displayName) }}\r\n </div>\r\n }\r\n }\r\n @if (multiUserValues().length > 5) {\r\n <div\r\n class=\"w-7 h-7 rounded-full border-2 border-white bg-surface-300 flex items-center justify-center text-xs font-medium\"\r\n >\r\n +{{ multiUserValues().length - 5 }}\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Dynamic List Template -->\r\n<ng-template #dynamicListTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (dynamicListValues()?.length) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (item of dynamicListValues(); track $index) {\r\n <div class=\"text-sm\">\r\n {{ item?.label || item?.name || item }}\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Location Template -->\r\n<ng-template #locationTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ locationDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block}.text-ellipsis{text-overflow:ellipsis}\n"] }]
|
|
17209
|
+
args: [{ selector: 'mt-entity-info', standalone: true, imports: [CommonModule, TranslocoDirective, DecimalPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"entity-info-wrapper w-full\" *transloco=\"let t; prefix: 'dashboard'\">\r\n @switch (viewTypeLower()) {\r\n <!-- Text Types -->\r\n @case (\"text\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"float\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"longtext\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"title\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n @case (\"phasegate\") {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Number -->\r\n @case (\"number\") {\r\n <ng-container *ngTemplateOutlet=\"numberTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Date Types -->\r\n @case (\"date\") {\r\n <ng-container *ngTemplateOutlet=\"dateTemplate\"></ng-container>\r\n }\r\n @case (\"datetime\") {\r\n <ng-container *ngTemplateOutlet=\"dateTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Currency -->\r\n @case (\"currency\") {\r\n <ng-container *ngTemplateOutlet=\"currencyTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Time -->\r\n @case (\"time\") {\r\n <ng-container *ngTemplateOutlet=\"timeTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Lookup -->\r\n @case (\"lookup\") {\r\n <ng-container *ngTemplateOutlet=\"lookupTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Checkbox -->\r\n @case (\"checkbox\") {\r\n <ng-container *ngTemplateOutlet=\"checkboxTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Status -->\r\n @case (\"status\") {\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n }\r\n @case (\"request_status\") {\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Percentage -->\r\n @case (\"percentage\") {\r\n <ng-container *ngTemplateOutlet=\"percentageTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Slider -->\r\n @case (\"slider\") {\r\n <ng-container *ngTemplateOutlet=\"sliderTemplate\"></ng-container>\r\n }\r\n\r\n <!-- User -->\r\n @case (\"user\") {\r\n <ng-container *ngTemplateOutlet=\"userTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Multi-select lookup -->\r\n @case (\"lookupmultiselect\") {\r\n <ng-container\r\n *ngTemplateOutlet=\"lookupMultiselectTemplate\"\r\n ></ng-container>\r\n }\r\n\r\n <!-- Multi user -->\r\n @case (\"multiuser\") {\r\n <ng-container *ngTemplateOutlet=\"multiUserTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Dynamic List -->\r\n @case (\"dynamiclist\") {\r\n <ng-container *ngTemplateOutlet=\"dynamicListTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Location -->\r\n @case (\"location\") {\r\n <ng-container *ngTemplateOutlet=\"locationTemplate\"></ng-container>\r\n }\r\n\r\n <!-- Default: treat as text -->\r\n @default {\r\n <ng-container *ngTemplateOutlet=\"textTemplate\"></ng-container>\r\n }\r\n }\r\n</div>\r\n\r\n<!-- Text Template -->\r\n<ng-template #textTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div\r\n class=\"font-semibold\"\r\n [class.text-ellipsis]=\"limitWords()\"\r\n [class.overflow-hidden]=\"limitWords()\"\r\n [class.whitespace-nowrap]=\"limitWords()\"\r\n [style.max-width]=\"limitWords() ? '200px' : 'auto'\"\r\n [title]=\"textValue()\"\r\n >\r\n {{ textValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Number Template -->\r\n<ng-template #numberTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ numericValue() !== null ? (numericValue() | number) : \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Date Template -->\r\n<ng-template #dateTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ dateDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Currency Template -->\r\n<ng-template #currencyTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ currencyDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Time Template -->\r\n<ng-template #timeTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ timeDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Lookup Template -->\r\n<ng-template #lookupTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (lookupName()) {\r\n <span class=\"flex items-center gap-1\" [style.color]=\"lookupColor()\">\r\n @if (displayType() === \"entity\" && lookupColor()) {\r\n <span\r\n class=\"w-2 h-2 rounded-full inline-block\"\r\n [style.backgroundColor]=\"lookupColor()\"\r\n ></span>\r\n }\r\n {{ lookupName() }}\r\n </span>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Checkbox Template -->\r\n<ng-template #checkboxTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center\">\r\n <i\r\n [class]=\"\r\n checkboxValue()\r\n ? 'pi pi-check-square text-primary'\r\n : 'pi pi-stop text-muted-color'\r\n \"\r\n ></i>\r\n <span class=\"ml-2\">{{ checkboxValue() ? \"Yes\" : \"No\" }}</span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Status Template -->\r\n<ng-template #statusTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n @if (statusColor()) {\r\n <span\r\n class=\"w-2.5 h-2.5 rounded-full flex-shrink-0\"\r\n [style.backgroundColor]=\"statusColor()\"\r\n ></span>\r\n }\r\n <span [style.color]=\"statusColor()\">\r\n {{ statusName() || \"__\" }}\r\n </span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Percentage Template -->\r\n<ng-template #percentageTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n @if (\r\n displayType() !== \"inTable\" ||\r\n extraInfoData()?.showPercentageAsProgressBar\r\n ) {\r\n <div\r\n class=\"flex-1 h-2 bg-surface-200 rounded-full overflow-hidden max-w-24\"\r\n >\r\n <div\r\n class=\"h-full rounded-full transition-all\"\r\n [style.width.%]=\"percentageValue() || 0\"\r\n [style.backgroundColor]=\"percentageColor() || 'var(--primary-color)'\"\r\n ></div>\r\n </div>\r\n }\r\n @if (\r\n extraInfoData()?.showPercentageStatus &&\r\n !extraInfoData()?.showPercentageAsProgressBar\r\n ) {\r\n <span\r\n class=\"w-2.5 h-2.5 rounded-full\"\r\n [style.backgroundColor]=\"percentageColor() || '#000'\"\r\n ></span>\r\n }\r\n <span [style.color]=\"percentageColor()\">\r\n {{\r\n percentageValue() !== null\r\n ? (percentageValue() | number: \"1.0-0\") + \"%\"\r\n : \"__\"\r\n }}\r\n </span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Slider Template -->\r\n<ng-template #sliderTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"flex items-center gap-2\">\r\n <div\r\n class=\"flex-1 h-2 bg-surface-200 rounded-full overflow-hidden max-w-32\"\r\n >\r\n <div\r\n class=\"h-full bg-primary rounded-full transition-all\"\r\n [style.width.%]=\"sliderValue() || 0\"\r\n ></div>\r\n </div>\r\n <span class=\"text-sm\">{{ sliderValue() || 0 }}%</span>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- User Template -->\r\n<ng-template #userTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (userData()) {\r\n <div class=\"flex items-center gap-2\">\r\n @if (userData()?.avatar || userData()?.image) {\r\n <img\r\n [src]=\"userData()?.avatar || userData()?.image\"\r\n alt=\"User avatar\"\r\n class=\"w-8 h-8 rounded-full object-cover\"\r\n />\r\n } @else {\r\n <div\r\n class=\"w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center text-primary font-semibold text-sm\"\r\n >\r\n {{ userInitials() }}\r\n </div>\r\n }\r\n <span class=\"font-medium\">{{ userName() }}</span>\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Lookup Multiselect Template -->\r\n<ng-template #lookupMultiselectTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (multiselectValues()?.length) {\r\n <div class=\"flex flex-wrap gap-1\">\r\n @for (item of multiselectValues(); track item.key || $index) {\r\n <span\r\n class=\"px-2 py-0.5 rounded-full text-xs font-medium\"\r\n [style.backgroundColor]=\"(item.details?.color || '#6b7280') + '20'\"\r\n [style.color]=\"item.details?.color || '#6b7280'\"\r\n >\r\n {{ item.name || item.display || item }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Multi User Template -->\r\n<ng-template #multiUserTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (multiUserValues()?.length) {\r\n <div class=\"flex items-center -space-x-2\">\r\n @for (user of multiUserValues().slice(0, 5); track user.id || $index) {\r\n @if (user.avatar || user.image) {\r\n <img\r\n [src]=\"user.avatar || user.image\"\r\n [alt]=\"user.name || user.displayName\"\r\n class=\"w-7 h-7 rounded-full border-2 border-white object-cover\"\r\n />\r\n } @else {\r\n <div\r\n class=\"w-7 h-7 rounded-full border-2 border-white bg-primary/20 flex items-center justify-center text-primary font-semibold text-xs\"\r\n >\r\n {{ getInitials(user.name || user.displayName) }}\r\n </div>\r\n }\r\n }\r\n @if (multiUserValues().length > 5) {\r\n <div\r\n class=\"w-7 h-7 rounded-full border-2 border-white bg-surface-300 flex items-center justify-center text-xs font-medium\"\r\n >\r\n +{{ multiUserValues().length - 5 }}\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Dynamic List Template -->\r\n<ng-template #dynamicListTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n @if (dynamicListValues()?.length) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (item of dynamicListValues(); track $index) {\r\n <div class=\"text-sm\">\r\n {{ item?.label || item?.name || item }}\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"font-semibold\">__</span>\r\n }\r\n</ng-template>\r\n\r\n<!-- Location Template -->\r\n<ng-template #locationTemplate>\r\n @if (displayType() === \"entity\") {\r\n <div class=\"text-muted-color text-sm font-semibold mb-1\">\r\n {{ data()?.label }}\r\n </div>\r\n }\r\n <div class=\"font-semibold\">\r\n {{ locationDisplayValue() || \"__\" }}\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block}.text-ellipsis{text-overflow:ellipsis}\n"] }]
|
|
17043
17210
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], displayType: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayType", required: false }] }], extraInfoData: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraInfoData", required: false }] }], limitWords: [{ type: i0.Input, args: [{ isSignal: true, alias: "limitWords", required: false }] }], customClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "customClass", required: false }] }] } });
|
|
17044
17211
|
|
|
17045
17212
|
/**
|
|
@@ -17714,6 +17881,10 @@ class HeaderCardComponent {
|
|
|
17714
17881
|
cardStyleConfig = computed(() => {
|
|
17715
17882
|
return (this.configurationItem()?.clientConfig?.configAsType?.['cardStyleConfig'] || {});
|
|
17716
17883
|
}, ...(ngDevMode ? [{ debugName: "cardStyleConfig" }] : []));
|
|
17884
|
+
/** Config as type */
|
|
17885
|
+
configAsType = computed(() => {
|
|
17886
|
+
return this.configurationItem()?.clientConfig?.configAsType || {};
|
|
17887
|
+
}, ...(ngDevMode ? [{ debugName: "configAsType" }] : []));
|
|
17717
17888
|
/** Cols from dimensions */
|
|
17718
17889
|
cols = computed(() => {
|
|
17719
17890
|
return (this.configurationItem()?.clientConfig?.displayConfig?.['dimensions']?.['cols'] || 36);
|
|
@@ -17756,6 +17927,22 @@ class HeaderCardComponent {
|
|
|
17756
17927
|
iconBgColor = computed(() => {
|
|
17757
17928
|
return this.styleConfig()?.['iconBgColor'] || 'rgba(76, 175, 80, 0.1)';
|
|
17758
17929
|
}, ...(ngDevMode ? [{ debugName: "iconBgColor" }] : []));
|
|
17930
|
+
/** Inner card padding */
|
|
17931
|
+
padding = computed(() => {
|
|
17932
|
+
return Number(this.configAsType()['padding'] ?? 16);
|
|
17933
|
+
}, ...(ngDevMode ? [{ debugName: "padding" }] : []));
|
|
17934
|
+
/** Quick border color */
|
|
17935
|
+
borderColor = computed(() => {
|
|
17936
|
+
return String(this.styleConfig()?.['border-color'] || '');
|
|
17937
|
+
}, ...(ngDevMode ? [{ debugName: "borderColor" }] : []));
|
|
17938
|
+
/** Whether explicit side borders are configured */
|
|
17939
|
+
hasExplicitSideBorders = computed(() => {
|
|
17940
|
+
const style = this.styleConfig();
|
|
17941
|
+
return Boolean(style?.['border-top-show'] ||
|
|
17942
|
+
style?.['border-right-show'] ||
|
|
17943
|
+
style?.['border-bottom-show'] ||
|
|
17944
|
+
style?.['border-left-show']);
|
|
17945
|
+
}, ...(ngDevMode ? [{ debugName: "hasExplicitSideBorders" }] : []));
|
|
17759
17946
|
/** Font size for title */
|
|
17760
17947
|
fontSizeTitle = computed(() => {
|
|
17761
17948
|
const size = this.styleConfig()?.['font-size-title'];
|
|
@@ -17806,8 +17993,14 @@ class HeaderCardComponent {
|
|
|
17806
17993
|
if (config?.shadows) {
|
|
17807
17994
|
styles['box-shadow'] = config.shadows;
|
|
17808
17995
|
}
|
|
17809
|
-
if (config?.borderRadius) {
|
|
17810
|
-
styles['border-radius'] = config.borderRadius
|
|
17996
|
+
if (config?.borderRadius !== undefined && config?.borderRadius !== null) {
|
|
17997
|
+
styles['border-radius'] = `${config.borderRadius}px`;
|
|
17998
|
+
}
|
|
17999
|
+
if (this.padding() >= 0) {
|
|
18000
|
+
styles['padding'] = `${this.padding()}px`;
|
|
18001
|
+
}
|
|
18002
|
+
if (this.borderColor() && !this.hasExplicitSideBorders()) {
|
|
18003
|
+
styles['border'] = `1px solid ${this.borderColor()}`;
|
|
17811
18004
|
}
|
|
17812
18005
|
return styles;
|
|
17813
18006
|
}, ...(ngDevMode ? [{ debugName: "cardStyles" }] : []));
|
|
@@ -17888,11 +18081,11 @@ class HeaderCardComponent {
|
|
|
17888
18081
|
this.onAction.emit({ type: 'click', data: {} });
|
|
17889
18082
|
}
|
|
17890
18083
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HeaderCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17891
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: HeaderCardComponent, isStandalone: true, selector: "mt-header-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<div class=\"header-container\" [ngStyle]=\"containerStyles()\">\r\n <div\r\n class=\"header-card\"\r\n [class.clickable]=\"isClickable()\"\r\n [ngStyle]=\"cardStyles()\"\r\n >\r\n <!-- Logo or Icon Display -->\r\n @if (logoUrl() || icon()) {\r\n <div class=\"header-icon-wrapper\">\r\n @if (logoUrl()) {\r\n <img [src]=\"logoUrl()\" alt=\"Logo\" class=\"header-logo\" />\r\n } @else if (icon()) {\r\n <
|
|
18084
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: HeaderCardComponent, isStandalone: true, selector: "mt-header-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<div class=\"header-container\" [ngStyle]=\"containerStyles()\">\r\n <div\r\n class=\"header-card\"\r\n [class.clickable]=\"isClickable()\"\r\n [ngStyle]=\"cardStyles()\"\r\n [style.box-sizing]=\"'border-box'\"\r\n >\r\n <!-- Logo or Icon Display -->\r\n @if (logoUrl() || icon()) {\r\n <div class=\"header-icon-wrapper\">\r\n @if (logoUrl()) {\r\n <img [src]=\"logoUrl()\" alt=\"Logo\" class=\"header-logo\" />\r\n } @else if (icon()) {\r\n <mt-avatar\r\n class=\"header-icon\"\r\n [icon]=\"icon()\"\r\n size=\"large\"\r\n shape=\"square\"\r\n [style.--p-avatar-background]=\"iconBgColor()\"\r\n [style.--p-avatar-color]=\"iconColor()\"\r\n />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"header-content\" [class.label-title]=\"!isFullWidth()\">\r\n <span\r\n class=\"header-title\"\r\n [ngStyle]=\"{ 'font-size': fontSizeTitle() }\"\r\n (click)=\"onTitleClick()\"\r\n >\r\n {{ title() }}\r\n </span>\r\n\r\n <!-- Status Indicators -->\r\n @if (statuses().length > 0) {\r\n <div class=\"status-list\">\r\n @for (status of statuses(); track status.label) {\r\n <div class=\"status-item\">\r\n @if (status.iconClass) {\r\n <span\r\n [class]=\"status.iconClass\"\r\n class=\"status-icon\"\r\n [style.color]=\"status.color\"\r\n [style.font-size.px]=\"status.iconSize || 14\"\r\n ></span>\r\n } @else {\r\n <span\r\n class=\"status-dot\"\r\n [class.circle]=\"status.shape === 'circle' || !status.shape\"\r\n [class.square]=\"\r\n status.shape === 'square' || status.shape === 'rect'\r\n \"\r\n [class.rectangul]=\"status.shape === 'rectangul'\"\r\n [class.rhombic]=\"status.shape === 'rhombic'\"\r\n [ngStyle]=\"{\r\n 'background-color': status.color,\r\n 'border-color': status.borderColor,\r\n 'border-bottom-color': status.borderBottomColor,\r\n }\"\r\n ></span>\r\n }\r\n <span class=\"status-label\">{{ status.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (showArrow()) {\r\n <div class=\"header-arrow\" (click)=\"onArrowClick()\">\r\n <i class=\"pi pi-angle-right\"></i>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".header-container{height:100%}.header-card{display:flex;align-items:center;gap:.5rem;height:100%}.header-card.clickable{cursor:pointer}.header-icon-wrapper{display:flex;align-items:center}.header-logo{width:50px;height:50px;object-fit:contain;margin:0 .5rem}.header-icon{margin:0 .5rem}.header-content{display:flex;justify-content:space-between;align-items:center;flex:1}.header-content.label-title{flex-direction:column;align-items:flex-start}.header-title{margin:0;font-weight:600;line-height:1.2}.status-list{display:flex;gap:1rem;flex-wrap:wrap}.status-item{display:flex;align-items:center;gap:.25rem}.status-dot{width:.5rem;height:.5rem;border-radius:50%}.status-dot.circle{border-radius:50%}.status-dot.square,.status-dot.rect{border-radius:2px}.status-dot.rectangul{border-radius:2px;width:.75rem;height:.375rem}.status-dot.rhombic{transform:rotate(45deg);border-radius:2px}.status-icon{display:inline-flex;align-items:center;justify-content:center}.status-label{font-size:.75rem;color:#666}.header-arrow{font-size:1.5rem;color:#999;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
17892
18085
|
}
|
|
17893
18086
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HeaderCardComponent, decorators: [{
|
|
17894
18087
|
type: Component,
|
|
17895
|
-
args: [{ selector: 'mt-header-card', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"header-container\" [ngStyle]=\"containerStyles()\">\r\n <div\r\n class=\"header-card\"\r\n [class.clickable]=\"isClickable()\"\r\n [ngStyle]=\"cardStyles()\"\r\n >\r\n <!-- Logo or Icon Display -->\r\n @if (logoUrl() || icon()) {\r\n <div class=\"header-icon-wrapper\">\r\n @if (logoUrl()) {\r\n <img [src]=\"logoUrl()\" alt=\"Logo\" class=\"header-logo\" />\r\n } @else if (icon()) {\r\n <
|
|
18088
|
+
args: [{ selector: 'mt-header-card', standalone: true, imports: [CommonModule, Avatar], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"header-container\" [ngStyle]=\"containerStyles()\">\r\n <div\r\n class=\"header-card\"\r\n [class.clickable]=\"isClickable()\"\r\n [ngStyle]=\"cardStyles()\"\r\n [style.box-sizing]=\"'border-box'\"\r\n >\r\n <!-- Logo or Icon Display -->\r\n @if (logoUrl() || icon()) {\r\n <div class=\"header-icon-wrapper\">\r\n @if (logoUrl()) {\r\n <img [src]=\"logoUrl()\" alt=\"Logo\" class=\"header-logo\" />\r\n } @else if (icon()) {\r\n <mt-avatar\r\n class=\"header-icon\"\r\n [icon]=\"icon()\"\r\n size=\"large\"\r\n shape=\"square\"\r\n [style.--p-avatar-background]=\"iconBgColor()\"\r\n [style.--p-avatar-color]=\"iconColor()\"\r\n />\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"header-content\" [class.label-title]=\"!isFullWidth()\">\r\n <span\r\n class=\"header-title\"\r\n [ngStyle]=\"{ 'font-size': fontSizeTitle() }\"\r\n (click)=\"onTitleClick()\"\r\n >\r\n {{ title() }}\r\n </span>\r\n\r\n <!-- Status Indicators -->\r\n @if (statuses().length > 0) {\r\n <div class=\"status-list\">\r\n @for (status of statuses(); track status.label) {\r\n <div class=\"status-item\">\r\n @if (status.iconClass) {\r\n <span\r\n [class]=\"status.iconClass\"\r\n class=\"status-icon\"\r\n [style.color]=\"status.color\"\r\n [style.font-size.px]=\"status.iconSize || 14\"\r\n ></span>\r\n } @else {\r\n <span\r\n class=\"status-dot\"\r\n [class.circle]=\"status.shape === 'circle' || !status.shape\"\r\n [class.square]=\"\r\n status.shape === 'square' || status.shape === 'rect'\r\n \"\r\n [class.rectangul]=\"status.shape === 'rectangul'\"\r\n [class.rhombic]=\"status.shape === 'rhombic'\"\r\n [ngStyle]=\"{\r\n 'background-color': status.color,\r\n 'border-color': status.borderColor,\r\n 'border-bottom-color': status.borderBottomColor,\r\n }\"\r\n ></span>\r\n }\r\n <span class=\"status-label\">{{ status.label }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (showArrow()) {\r\n <div class=\"header-arrow\" (click)=\"onArrowClick()\">\r\n <i class=\"pi pi-angle-right\"></i>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".header-container{height:100%}.header-card{display:flex;align-items:center;gap:.5rem;height:100%}.header-card.clickable{cursor:pointer}.header-icon-wrapper{display:flex;align-items:center}.header-logo{width:50px;height:50px;object-fit:contain;margin:0 .5rem}.header-icon{margin:0 .5rem}.header-content{display:flex;justify-content:space-between;align-items:center;flex:1}.header-content.label-title{flex-direction:column;align-items:flex-start}.header-title{margin:0;font-weight:600;line-height:1.2}.status-list{display:flex;gap:1rem;flex-wrap:wrap}.status-item{display:flex;align-items:center;gap:.25rem}.status-dot{width:.5rem;height:.5rem;border-radius:50%}.status-dot.circle{border-radius:50%}.status-dot.square,.status-dot.rect{border-radius:2px}.status-dot.rectangul{border-radius:2px;width:.75rem;height:.375rem}.status-dot.rhombic{transform:rotate(45deg);border-radius:2px}.status-icon{display:inline-flex;align-items:center;justify-content:center}.status-label{font-size:.75rem;color:#666}.header-arrow{font-size:1.5rem;color:#999;cursor:pointer}\n"] }]
|
|
17896
18089
|
}], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }], onAction: [{ type: i0.Output, args: ["onAction"] }] } });
|
|
17897
18090
|
|
|
17898
18091
|
/**
|
|
@@ -17989,8 +18182,297 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
17989
18182
|
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".skeleton-container{display:flex;flex-wrap:wrap;gap:1rem;width:100%;padding:1rem}.skeleton-item{background:#f5f5f5;border-radius:.5rem;overflow:hidden;position:relative}.skeleton-animation{position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent);animation:shimmer 1.5s infinite}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}\n"] }]
|
|
17990
18183
|
}], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }] } });
|
|
17991
18184
|
|
|
18185
|
+
class PropertiesCardComponent {
|
|
18186
|
+
storeService = inject(DashboardItemStoreService);
|
|
18187
|
+
transloco = inject(TranslocoService);
|
|
18188
|
+
subscription = new Subscription();
|
|
18189
|
+
dashboardId = input.required(...(ngDevMode ? [{ debugName: "dashboardId" }] : []));
|
|
18190
|
+
inGroup = input(false, ...(ngDevMode ? [{ debugName: "inGroup" }] : []));
|
|
18191
|
+
onAction = output();
|
|
18192
|
+
configurationItem = signal(null, ...(ngDevMode ? [{ debugName: "configurationItem" }] : []));
|
|
18193
|
+
cardData = signal([], ...(ngDevMode ? [{ debugName: "cardData" }] : []));
|
|
18194
|
+
tabSelected = signal(0, ...(ngDevMode ? [{ debugName: "tabSelected" }] : []));
|
|
18195
|
+
langCode = computed(() => this.transloco.getActiveLang() || 'en', ...(ngDevMode ? [{ debugName: "langCode" }] : []));
|
|
18196
|
+
isPropertiesCard = computed(() => this.configurationItem()?.clientConfig?.functionName ===
|
|
18197
|
+
'handlelevelCardsWithFilter', ...(ngDevMode ? [{ debugName: "isPropertiesCard" }] : []));
|
|
18198
|
+
galleryMode = computed(() => !!this.configurationItem()?.clientConfig?.configAsType?.['galleryMode'], ...(ngDevMode ? [{ debugName: "galleryMode" }] : []));
|
|
18199
|
+
currentTabItems = computed(() => {
|
|
18200
|
+
const data = this.cardData();
|
|
18201
|
+
return data[this.tabSelected()] ?? data[0] ?? [];
|
|
18202
|
+
}, ...(ngDevMode ? [{ debugName: "currentTabItems" }] : []));
|
|
18203
|
+
selectedProperties = computed(() => {
|
|
18204
|
+
const selected = this.configurationItem()?.serviceConfig?.query?.['selectedProperties'];
|
|
18205
|
+
if (!Array.isArray(selected))
|
|
18206
|
+
return [];
|
|
18207
|
+
return selected
|
|
18208
|
+
.map((item) => typeof item === 'string'
|
|
18209
|
+
? item
|
|
18210
|
+
: typeof item?.key === 'string'
|
|
18211
|
+
? item.key
|
|
18212
|
+
: '')
|
|
18213
|
+
.filter((item) => !!item);
|
|
18214
|
+
}, ...(ngDevMode ? [{ debugName: "selectedProperties" }] : []));
|
|
18215
|
+
propsConfigAsIndex = computed(() => {
|
|
18216
|
+
const config = this.configurationItem()?.clientConfig?.configAsType?.['propsConfigAsIndex'];
|
|
18217
|
+
return Array.isArray(config) ? config : [];
|
|
18218
|
+
}, ...(ngDevMode ? [{ debugName: "propsConfigAsIndex" }] : []));
|
|
18219
|
+
tabOptions = computed(() => this.cardData().map((tabItems, index) => ({
|
|
18220
|
+
label: this.resolveTabLabel(tabItems, index),
|
|
18221
|
+
value: index,
|
|
18222
|
+
})), ...(ngDevMode ? [{ debugName: "tabOptions" }] : []));
|
|
18223
|
+
showTabs = computed(() => !this.inGroup() && this.tabOptions().length > 1, ...(ngDevMode ? [{ debugName: "showTabs" }] : []));
|
|
18224
|
+
currentTabCards = computed(() => {
|
|
18225
|
+
const cards = this.extractCards(this.currentTabItems());
|
|
18226
|
+
const selectedProperties = this.selectedProperties();
|
|
18227
|
+
const propsConfigAsIndex = this.propsConfigAsIndex();
|
|
18228
|
+
const propertiesMode = this.isPropertiesCard();
|
|
18229
|
+
return cards.map((card, index) => ({
|
|
18230
|
+
trackId: card.id ?? index,
|
|
18231
|
+
card,
|
|
18232
|
+
entities: propertiesMode
|
|
18233
|
+
? this.buildPropertiesCardEntities(card, selectedProperties, propsConfigAsIndex)
|
|
18234
|
+
: [],
|
|
18235
|
+
bodyProps: propertiesMode ? [] : this.buildLegacyBodyProps(card),
|
|
18236
|
+
attachments: propertiesMode ? [] : this.getAttachments(card),
|
|
18237
|
+
hasCounters: propertiesMode ? false : this.hasCounters(card),
|
|
18238
|
+
}));
|
|
18239
|
+
}, ...(ngDevMode ? [{ debugName: "currentTabCards" }] : []));
|
|
18240
|
+
constructor() {
|
|
18241
|
+
effect(() => {
|
|
18242
|
+
const tabs = this.tabOptions();
|
|
18243
|
+
const selectedTab = this.tabSelected();
|
|
18244
|
+
if (!tabs.length) {
|
|
18245
|
+
if (selectedTab !== 0) {
|
|
18246
|
+
this.tabSelected.set(0);
|
|
18247
|
+
}
|
|
18248
|
+
return;
|
|
18249
|
+
}
|
|
18250
|
+
if (selectedTab < 0 || selectedTab >= tabs.length) {
|
|
18251
|
+
this.tabSelected.set(0);
|
|
18252
|
+
}
|
|
18253
|
+
});
|
|
18254
|
+
}
|
|
18255
|
+
ngOnInit() {
|
|
18256
|
+
const id = this.dashboardId();
|
|
18257
|
+
this.subscription.add(this.storeService
|
|
18258
|
+
.selectItemProperty$(id, 'ConfigurationItem')
|
|
18259
|
+
.subscribe((config) => {
|
|
18260
|
+
this.configurationItem.set(config || null);
|
|
18261
|
+
}));
|
|
18262
|
+
this.subscription.add(this.storeService
|
|
18263
|
+
.selectItemProperty$(id, 'DataHandled')
|
|
18264
|
+
.subscribe((data) => {
|
|
18265
|
+
if (Array.isArray(data)) {
|
|
18266
|
+
this.cardData.set(data);
|
|
18267
|
+
}
|
|
18268
|
+
else {
|
|
18269
|
+
this.cardData.set([]);
|
|
18270
|
+
}
|
|
18271
|
+
}));
|
|
18272
|
+
}
|
|
18273
|
+
ngOnDestroy() {
|
|
18274
|
+
this.subscription.unsubscribe();
|
|
18275
|
+
}
|
|
18276
|
+
onCardClick(card) {
|
|
18277
|
+
this.onAction.emit({ type: 'click', data: card });
|
|
18278
|
+
}
|
|
18279
|
+
normalizePropertyKey(value) {
|
|
18280
|
+
return value?.toLowerCase().trim() || '';
|
|
18281
|
+
}
|
|
18282
|
+
clampEntitySize(value) {
|
|
18283
|
+
return Math.max(1, Math.min(24, Math.round(value)));
|
|
18284
|
+
}
|
|
18285
|
+
resolveEntitySize(width, fallback) {
|
|
18286
|
+
const fallbackSize = this.clampEntitySize(fallback ?? 24);
|
|
18287
|
+
if (!width)
|
|
18288
|
+
return fallbackSize;
|
|
18289
|
+
const normalizedWidth = width.trim();
|
|
18290
|
+
if (!normalizedWidth)
|
|
18291
|
+
return fallbackSize;
|
|
18292
|
+
if (normalizedWidth.endsWith('%')) {
|
|
18293
|
+
const percentage = Number.parseFloat(normalizedWidth.slice(0, -1));
|
|
18294
|
+
if (!Number.isNaN(percentage) && percentage > 0) {
|
|
18295
|
+
return this.clampEntitySize((percentage / 100) * 24);
|
|
18296
|
+
}
|
|
18297
|
+
return fallbackSize;
|
|
18298
|
+
}
|
|
18299
|
+
const numericWidth = Number.parseFloat(normalizedWidth);
|
|
18300
|
+
if (Number.isNaN(numericWidth) || numericWidth <= 0) {
|
|
18301
|
+
return fallbackSize;
|
|
18302
|
+
}
|
|
18303
|
+
if (numericWidth <= 24) {
|
|
18304
|
+
return this.clampEntitySize(numericWidth);
|
|
18305
|
+
}
|
|
18306
|
+
if (numericWidth <= 100) {
|
|
18307
|
+
return this.clampEntitySize((numericWidth / 100) * 24);
|
|
18308
|
+
}
|
|
18309
|
+
return fallbackSize;
|
|
18310
|
+
}
|
|
18311
|
+
isCardGroup(item) {
|
|
18312
|
+
return Array.isArray(item?.data);
|
|
18313
|
+
}
|
|
18314
|
+
extractCards(items) {
|
|
18315
|
+
const cards = [];
|
|
18316
|
+
items.forEach((item) => {
|
|
18317
|
+
if (this.isCardGroup(item)) {
|
|
18318
|
+
cards.push(...(Array.isArray(item.data) ? item.data : []));
|
|
18319
|
+
return;
|
|
18320
|
+
}
|
|
18321
|
+
cards.push(item);
|
|
18322
|
+
});
|
|
18323
|
+
return cards;
|
|
18324
|
+
}
|
|
18325
|
+
getCardProps(card) {
|
|
18326
|
+
if (Array.isArray(card.props))
|
|
18327
|
+
return card.props;
|
|
18328
|
+
if (Array.isArray(card.properties))
|
|
18329
|
+
return card.properties;
|
|
18330
|
+
return [];
|
|
18331
|
+
}
|
|
18332
|
+
orderProperties(props, selectedProperties) {
|
|
18333
|
+
if (!selectedProperties.length)
|
|
18334
|
+
return props;
|
|
18335
|
+
const propsByKey = new Map();
|
|
18336
|
+
props.forEach((prop) => {
|
|
18337
|
+
[prop.normalizedKey, prop.key].forEach((key) => {
|
|
18338
|
+
const normalized = this.normalizePropertyKey(key);
|
|
18339
|
+
if (normalized && !propsByKey.has(normalized)) {
|
|
18340
|
+
propsByKey.set(normalized, prop);
|
|
18341
|
+
}
|
|
18342
|
+
});
|
|
18343
|
+
});
|
|
18344
|
+
const ordered = selectedProperties
|
|
18345
|
+
.map((key) => propsByKey.get(this.normalizePropertyKey(key)))
|
|
18346
|
+
.filter((prop) => !!prop);
|
|
18347
|
+
if (!ordered.length)
|
|
18348
|
+
return props;
|
|
18349
|
+
const orderedSet = new Set(ordered);
|
|
18350
|
+
return [...ordered, ...props.filter((prop) => !orderedSet.has(prop))];
|
|
18351
|
+
}
|
|
18352
|
+
buildPropertiesCardEntities(card, selectedProperties, propsConfigAsIndex) {
|
|
18353
|
+
const props = this.getCardProps(card);
|
|
18354
|
+
const orderedProps = this.orderProperties(props, selectedProperties);
|
|
18355
|
+
return orderedProps
|
|
18356
|
+
.map((prop, index) => {
|
|
18357
|
+
const uiConfig = propsConfigAsIndex[index] || {};
|
|
18358
|
+
if (uiConfig.hidden)
|
|
18359
|
+
return null;
|
|
18360
|
+
const baseConfiguration = prop.configuration && typeof prop.configuration === 'object'
|
|
18361
|
+
? prop.configuration
|
|
18362
|
+
: {};
|
|
18363
|
+
const normalizedProp = this.normalizeEntityProperty(prop);
|
|
18364
|
+
return {
|
|
18365
|
+
...normalizedProp,
|
|
18366
|
+
order: index,
|
|
18367
|
+
configuration: {
|
|
18368
|
+
...baseConfiguration,
|
|
18369
|
+
size: this.resolveEntitySize(uiConfig.width, typeof baseConfiguration.size === 'number'
|
|
18370
|
+
? baseConfiguration.size
|
|
18371
|
+
: undefined),
|
|
18372
|
+
},
|
|
18373
|
+
};
|
|
18374
|
+
})
|
|
18375
|
+
.filter((prop) => !!prop);
|
|
18376
|
+
}
|
|
18377
|
+
buildLegacyBodyProps(card) {
|
|
18378
|
+
return this.getCardProps(card)
|
|
18379
|
+
.filter((prop) => {
|
|
18380
|
+
if (prop.viewType === 'Attachment')
|
|
18381
|
+
return false;
|
|
18382
|
+
const normalized = this.normalizePropertyKey(prop.normalizedKey || prop.key);
|
|
18383
|
+
if (normalized === 'name' || normalized === 'status')
|
|
18384
|
+
return false;
|
|
18385
|
+
const displayAreas = prop.displayAreas || prop.displayArea || [];
|
|
18386
|
+
return displayAreas.some((area) => area?.key === 'levelCard_body');
|
|
18387
|
+
})
|
|
18388
|
+
.sort((a, b) => {
|
|
18389
|
+
const aArea = (a.displayAreas || a.displayArea || []).find((area) => area?.key === 'levelCard_body');
|
|
18390
|
+
const bArea = (b.displayAreas || b.displayArea || []).find((area) => area?.key === 'levelCard_body');
|
|
18391
|
+
return (aArea?.order || 0) - (bArea?.order || 0);
|
|
18392
|
+
});
|
|
18393
|
+
}
|
|
18394
|
+
getAttachments(card) {
|
|
18395
|
+
const attachmentProp = this.getCardProps(card).find((prop) => prop.viewType === 'Attachment');
|
|
18396
|
+
return Array.isArray(attachmentProp?.value) ? attachmentProp.value : [];
|
|
18397
|
+
}
|
|
18398
|
+
hasCounters(card) {
|
|
18399
|
+
return !!(card.issuesCounts || card.risksCounts || card.milestonesCounts);
|
|
18400
|
+
}
|
|
18401
|
+
resolveTabLabel(tabItems, index) {
|
|
18402
|
+
const firstItem = tabItems[0];
|
|
18403
|
+
if (firstItem && this.isCardGroup(firstItem)) {
|
|
18404
|
+
const firstCard = Array.isArray(firstItem.data)
|
|
18405
|
+
? firstItem.data[0]
|
|
18406
|
+
: null;
|
|
18407
|
+
return (this.readLocalizedText(firstItem.label) ||
|
|
18408
|
+
this.readLocalizedText(firstItem.name) ||
|
|
18409
|
+
this.readString(firstItem.title) ||
|
|
18410
|
+
this.readLocalizedText(firstCard?.name) ||
|
|
18411
|
+
this.readLocalizedText(firstCard?.label) ||
|
|
18412
|
+
`${index + 1}`);
|
|
18413
|
+
}
|
|
18414
|
+
const firstCard = firstItem;
|
|
18415
|
+
return (this.readLocalizedText(firstCard?.name) ||
|
|
18416
|
+
this.readLocalizedText(firstCard?.label) ||
|
|
18417
|
+
`${index + 1}`);
|
|
18418
|
+
}
|
|
18419
|
+
readString(value) {
|
|
18420
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
18421
|
+
}
|
|
18422
|
+
normalizeEntityProperty(prop) {
|
|
18423
|
+
const resolvedName = this.resolveEntityName(prop);
|
|
18424
|
+
if (!resolvedName) {
|
|
18425
|
+
return prop;
|
|
18426
|
+
}
|
|
18427
|
+
return {
|
|
18428
|
+
...prop,
|
|
18429
|
+
name: resolvedName,
|
|
18430
|
+
};
|
|
18431
|
+
}
|
|
18432
|
+
resolveEntityName(prop) {
|
|
18433
|
+
const currentName = this.readLocalizedText(prop.name);
|
|
18434
|
+
if (currentName) {
|
|
18435
|
+
return currentName;
|
|
18436
|
+
}
|
|
18437
|
+
const fallbackLabel = this.readLocalizedText(prop.label);
|
|
18438
|
+
if (fallbackLabel) {
|
|
18439
|
+
return fallbackLabel;
|
|
18440
|
+
}
|
|
18441
|
+
return (this.readLocalizedText(prop.key) ||
|
|
18442
|
+
this.readLocalizedText(prop.normalizedKey) ||
|
|
18443
|
+
'');
|
|
18444
|
+
}
|
|
18445
|
+
readLocalizedText(value) {
|
|
18446
|
+
if (typeof value === 'string') {
|
|
18447
|
+
return value.trim();
|
|
18448
|
+
}
|
|
18449
|
+
if (value && typeof value === 'object') {
|
|
18450
|
+
const localized = value;
|
|
18451
|
+
const langCode = this.langCode();
|
|
18452
|
+
const candidate = localized[langCode] ?? localized['en'] ?? localized['ar'];
|
|
18453
|
+
if (typeof candidate === 'string') {
|
|
18454
|
+
return candidate.trim();
|
|
18455
|
+
}
|
|
18456
|
+
}
|
|
18457
|
+
return '';
|
|
18458
|
+
}
|
|
18459
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18460
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertiesCardComponent, isStandalone: true, selector: "mt-properties-card, mt-entities-preview-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\n @if (showTabs()) {\n <div class=\"mb-3\">\n <mt-tabs [(active)]=\"tabSelected\" [options]=\"tabOptions()\" size=\"small\" />\n </div>\n }\n\n <div\n class=\"overflow-y-auto overflow-x-hidden\"\n [style.max-height]=\"inGroup() ? '500px' : '90%'\"\n >\n @if (currentTabCards().length === 0) {\n <div class=\"py-6 text-center text-sm text-gray-400\">\n {{ t(\"noData\") }}\n </div>\n } @else {\n <div class=\"flex flex-wrap\">\n @for (cardView of currentTabCards(); track cardView.trackId) {\n <div\n class=\"mb-2 p-2\"\n [class.card-col]=\"!galleryMode()\"\n [class.gallery-card-col]=\"galleryMode()\"\n [class.w-full]=\"!galleryMode()\"\n [class.md:w-1/2]=\"!galleryMode()\"\n [class.lg:w-1/3]=\"!galleryMode()\"\n >\n @if (isPropertiesCard()) {\n <div\n class=\"h-full cursor-pointer rounded-lg bg-white p-3 shadow-sm transition-all hover:shadow-md\"\n (click)=\"onCardClick(cardView.card)\"\n >\n @if (cardView.entities.length > 0) {\n <mt-entities-preview [entities]=\"cardView.entities\" />\n } @else {\n <div class=\"py-6 text-center text-sm text-gray-400\">\n {{ t(\"noData\") }}\n </div>\n }\n </div>\n } @else {\n <div\n class=\"h-full cursor-pointer rounded-lg bg-white shadow-sm transition-all hover:shadow-md\"\n (click)=\"onCardClick(cardView.card)\"\n >\n <div\n class=\"flex items-center justify-between border-b p-3\"\n [style.border-left-color]=\"\n cardView.card.status?.value?.details?.color || '#64b735'\n \"\n [style.border-left-width]=\"'4px'\"\n >\n <div class=\"min-w-0 flex-1\">\n <h6 class=\"truncate text-sm font-semibold text-gray-800\">\n {{ cardView.card.name }}\n </h6>\n </div>\n <div class=\"ml-2 flex items-center gap-2\">\n @if (cardView.card.status?.value?.name) {\n <span\n class=\"whitespace-nowrap rounded-full px-2 py-0.5 text-xs font-medium text-white\"\n [style.background-color]=\"\n cardView.card.status?.value?.details?.color ||\n '#64b735'\n \"\n [pTooltip]=\"\n cardView.card.status?.value?.details?.description\n \"\n >\n {{ cardView.card.status?.value?.name }}\n </span>\n }\n @if (cardView.card.currentPhase) {\n <span\n class=\"rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-600\"\n >\n {{ cardView.card.currentPhase }}\n </span>\n }\n </div>\n </div>\n\n <div class=\"p-3\">\n @for (prop of cardView.bodyProps; track prop.key) {\n <div class=\"mb-2 flex items-start text-sm\">\n <span class=\"mr-2 font-medium text-gray-500\">\n {{ prop.key }}:\n </span>\n <span class=\"flex-1 text-gray-700\">\n <mt-entity-info\n [viewType]=\"prop.viewType\"\n [value]=\"prop.value\"\n [langCode]=\"langCode()\"\n />\n </span>\n </div>\n }\n </div>\n\n @if (galleryMode() && cardView.attachments.length > 0) {\n <div class=\"flex gap-2 overflow-x-auto p-3 pt-0\">\n @for (attachment of cardView.attachments; track $index) {\n <img\n [src]=\"'api/Uploader/' + attachment['path']\"\n alt=\"Attachment\"\n class=\"h-16 w-16 flex-shrink-0 rounded object-cover\"\n />\n }\n </div>\n }\n\n @if (cardView.hasCounters) {\n <div class=\"flex justify-around border-t p-2 text-xs\">\n @if (cardView.card.issuesCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-red-500\">\n {{ cardView.card.issuesCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"issues\") }}</div>\n </div>\n }\n @if (cardView.card.risksCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-orange-500\">\n {{ cardView.card.risksCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"risks\") }}</div>\n </div>\n }\n @if (cardView.card.milestonesCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-blue-500\">\n {{ cardView.card.milestonesCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"milestones\") }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-container>\n", styles: [":host{display:block;height:100%}.card-col{flex:0 0 100%}@media(min-width:768px){.card-col{flex:0 0 50%}}@media(min-width:1024px){.card-col{flex:0 0 33.333%}}.gallery-card-col{flex:0 0 100%}@media(min-width:640px){.gallery-card-col{flex:0 0 50%}}@media(min-width:1024px){.gallery-card-col{flex:0 0 25%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape"] }, { kind: "component", type: EntityInfoComponent, selector: "mt-entity-info", inputs: ["data", "displayType", "extraInfoData", "limitWords", "customClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18461
|
+
}
|
|
18462
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesCardComponent, decorators: [{
|
|
18463
|
+
type: Component,
|
|
18464
|
+
args: [{ selector: 'mt-properties-card, mt-entities-preview-card', standalone: true, imports: [
|
|
18465
|
+
CommonModule,
|
|
18466
|
+
TooltipModule,
|
|
18467
|
+
TranslocoDirective,
|
|
18468
|
+
Tabs,
|
|
18469
|
+
EntitiesPreview,
|
|
18470
|
+
EntityInfoComponent,
|
|
18471
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\n @if (showTabs()) {\n <div class=\"mb-3\">\n <mt-tabs [(active)]=\"tabSelected\" [options]=\"tabOptions()\" size=\"small\" />\n </div>\n }\n\n <div\n class=\"overflow-y-auto overflow-x-hidden\"\n [style.max-height]=\"inGroup() ? '500px' : '90%'\"\n >\n @if (currentTabCards().length === 0) {\n <div class=\"py-6 text-center text-sm text-gray-400\">\n {{ t(\"noData\") }}\n </div>\n } @else {\n <div class=\"flex flex-wrap\">\n @for (cardView of currentTabCards(); track cardView.trackId) {\n <div\n class=\"mb-2 p-2\"\n [class.card-col]=\"!galleryMode()\"\n [class.gallery-card-col]=\"galleryMode()\"\n [class.w-full]=\"!galleryMode()\"\n [class.md:w-1/2]=\"!galleryMode()\"\n [class.lg:w-1/3]=\"!galleryMode()\"\n >\n @if (isPropertiesCard()) {\n <div\n class=\"h-full cursor-pointer rounded-lg bg-white p-3 shadow-sm transition-all hover:shadow-md\"\n (click)=\"onCardClick(cardView.card)\"\n >\n @if (cardView.entities.length > 0) {\n <mt-entities-preview [entities]=\"cardView.entities\" />\n } @else {\n <div class=\"py-6 text-center text-sm text-gray-400\">\n {{ t(\"noData\") }}\n </div>\n }\n </div>\n } @else {\n <div\n class=\"h-full cursor-pointer rounded-lg bg-white shadow-sm transition-all hover:shadow-md\"\n (click)=\"onCardClick(cardView.card)\"\n >\n <div\n class=\"flex items-center justify-between border-b p-3\"\n [style.border-left-color]=\"\n cardView.card.status?.value?.details?.color || '#64b735'\n \"\n [style.border-left-width]=\"'4px'\"\n >\n <div class=\"min-w-0 flex-1\">\n <h6 class=\"truncate text-sm font-semibold text-gray-800\">\n {{ cardView.card.name }}\n </h6>\n </div>\n <div class=\"ml-2 flex items-center gap-2\">\n @if (cardView.card.status?.value?.name) {\n <span\n class=\"whitespace-nowrap rounded-full px-2 py-0.5 text-xs font-medium text-white\"\n [style.background-color]=\"\n cardView.card.status?.value?.details?.color ||\n '#64b735'\n \"\n [pTooltip]=\"\n cardView.card.status?.value?.details?.description\n \"\n >\n {{ cardView.card.status?.value?.name }}\n </span>\n }\n @if (cardView.card.currentPhase) {\n <span\n class=\"rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-600\"\n >\n {{ cardView.card.currentPhase }}\n </span>\n }\n </div>\n </div>\n\n <div class=\"p-3\">\n @for (prop of cardView.bodyProps; track prop.key) {\n <div class=\"mb-2 flex items-start text-sm\">\n <span class=\"mr-2 font-medium text-gray-500\">\n {{ prop.key }}:\n </span>\n <span class=\"flex-1 text-gray-700\">\n <mt-entity-info\n [viewType]=\"prop.viewType\"\n [value]=\"prop.value\"\n [langCode]=\"langCode()\"\n />\n </span>\n </div>\n }\n </div>\n\n @if (galleryMode() && cardView.attachments.length > 0) {\n <div class=\"flex gap-2 overflow-x-auto p-3 pt-0\">\n @for (attachment of cardView.attachments; track $index) {\n <img\n [src]=\"'api/Uploader/' + attachment['path']\"\n alt=\"Attachment\"\n class=\"h-16 w-16 flex-shrink-0 rounded object-cover\"\n />\n }\n </div>\n }\n\n @if (cardView.hasCounters) {\n <div class=\"flex justify-around border-t p-2 text-xs\">\n @if (cardView.card.issuesCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-red-500\">\n {{ cardView.card.issuesCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"issues\") }}</div>\n </div>\n }\n @if (cardView.card.risksCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-orange-500\">\n {{ cardView.card.risksCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"risks\") }}</div>\n </div>\n }\n @if (cardView.card.milestonesCounts) {\n <div class=\"text-center\">\n <div class=\"font-medium text-blue-500\">\n {{ cardView.card.milestonesCounts.value }}\n </div>\n <div class=\"text-gray-400\">{{ t(\"milestones\") }}</div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-container>\n", styles: [":host{display:block;height:100%}.card-col{flex:0 0 100%}@media(min-width:768px){.card-col{flex:0 0 50%}}@media(min-width:1024px){.card-col{flex:0 0 33.333%}}.gallery-card-col{flex:0 0 100%}@media(min-width:640px){.gallery-card-col{flex:0 0 50%}}@media(min-width:1024px){.gallery-card-col{flex:0 0 25%}}\n"] }]
|
|
18472
|
+
}], ctorParameters: () => [], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], onAction: [{ type: i0.Output, args: ["onAction"] }] } });
|
|
18473
|
+
|
|
17992
18474
|
/**
|
|
17993
|
-
*
|
|
18475
|
+
* Properties View Card Component
|
|
17994
18476
|
*
|
|
17995
18477
|
* Displays entity properties in a card layout.
|
|
17996
18478
|
* Used by the entityPreview componentName.
|
|
@@ -18089,6 +18571,7 @@ class EntityPreviewCardComponent {
|
|
|
18089
18571
|
const propConfig = {
|
|
18090
18572
|
...(propsConfigAsIndex[index] || {}),
|
|
18091
18573
|
};
|
|
18574
|
+
const propInfo = this.normalizeEntityProperty(prop);
|
|
18092
18575
|
// Mobile adjustments
|
|
18093
18576
|
if (isMobilePlatform()) {
|
|
18094
18577
|
if (!propConfig.width || parseInt(propConfig.width, 10) < 50) {
|
|
@@ -18096,7 +18579,7 @@ class EntityPreviewCardComponent {
|
|
|
18096
18579
|
}
|
|
18097
18580
|
}
|
|
18098
18581
|
return {
|
|
18099
|
-
propInfo
|
|
18582
|
+
propInfo,
|
|
18100
18583
|
config: propConfig,
|
|
18101
18584
|
};
|
|
18102
18585
|
});
|
|
@@ -18109,8 +18592,45 @@ class EntityPreviewCardComponent {
|
|
|
18109
18592
|
getLanguageCode() {
|
|
18110
18593
|
return (this.transloco.getActiveLang() || localStorage.getItem('langCode') || 'en');
|
|
18111
18594
|
}
|
|
18595
|
+
normalizeEntityProperty(prop) {
|
|
18596
|
+
const resolvedName = this.resolveEntityName(prop);
|
|
18597
|
+
if (!resolvedName) {
|
|
18598
|
+
return prop;
|
|
18599
|
+
}
|
|
18600
|
+
return {
|
|
18601
|
+
...prop,
|
|
18602
|
+
name: resolvedName,
|
|
18603
|
+
};
|
|
18604
|
+
}
|
|
18605
|
+
resolveEntityName(prop) {
|
|
18606
|
+
const currentName = this.readLocalizedText(prop.name);
|
|
18607
|
+
if (currentName) {
|
|
18608
|
+
return currentName;
|
|
18609
|
+
}
|
|
18610
|
+
const fallbackLabel = this.readLocalizedText(prop.label);
|
|
18611
|
+
if (fallbackLabel) {
|
|
18612
|
+
return fallbackLabel;
|
|
18613
|
+
}
|
|
18614
|
+
return (this.readLocalizedText(prop.key) ||
|
|
18615
|
+
this.readLocalizedText(prop.normalizedKey) ||
|
|
18616
|
+
'');
|
|
18617
|
+
}
|
|
18618
|
+
readLocalizedText(value) {
|
|
18619
|
+
if (typeof value === 'string') {
|
|
18620
|
+
return value.trim();
|
|
18621
|
+
}
|
|
18622
|
+
if (value && typeof value === 'object') {
|
|
18623
|
+
const localized = value;
|
|
18624
|
+
const languageCode = this.getLanguageCode();
|
|
18625
|
+
const candidate = localized[languageCode] ?? localized['en'] ?? localized['ar'];
|
|
18626
|
+
if (typeof candidate === 'string') {
|
|
18627
|
+
return candidate.trim();
|
|
18628
|
+
}
|
|
18629
|
+
}
|
|
18630
|
+
return '';
|
|
18631
|
+
}
|
|
18112
18632
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreviewCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18113
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPreviewCardComponent, isStandalone: true, selector: "mt-entity-preview-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<mt-card-content\r\n [inGroup]=\"false\"\r\n [headerConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['headerCardConfig']\r\n \"\r\n [styleConfig]=\"\r\n configurationItem()?.clientConfig?.displayConfig?.['StyleConfig']\r\n \"\r\n [cardStyleConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['cardStyleConfig']\r\n \"\r\n [title]=\"title()\"\r\n>\r\n <ng-container body>\r\n <div\r\n class=\"flex flex-wrap flex-1 p-4 pb-5\"\r\n *transloco=\"let t; prefix: 'dashboard'\"\r\n >\r\n @for (item of props(); track item.propInfo.key) {\n @if (!item.config?.hidden) {\n <div\n [style.width]=\"item.config?.width || '100%'\"\n style=\"min-width: 180px\"\n [class.border]=\"item.config?.border?.includes('all')\"\r\n [class.border-t]=\"item.config?.border?.includes('top')\"\r\n [class.border-l]=\"item.config?.border?.includes('left')\"\r\n [class.border-b]=\"item.config?.border?.includes('bottom')\"\n [class.border-r]=\"item.config?.border?.includes('right')\"\n class=\"flex items-center p-2\"\n >\n <mt-entity-preview [data]=\"item.propInfo\" class=\"w-full\">\n </mt-entity-preview>\n </div>\n }\n }\n\r\n @if (props().length === 0) {\r\n <div\r\n class=\"no-data-container w-full flex items-center justify-center py-8 text-muted-color\"\r\n >\r\n <i class=\"pi pi-info-circle mr-2\"></i>\r\n <span>{{ t(\"noData\") }}</span>\r\n </div>\r\n }\r\n </div>\r\n </ng-container>\r\n</mt-card-content>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: CardContentComponent, selector: "mt-card-content", inputs: ["title", "inGroup", "headerConfig", "styleConfig", "cardStyleConfig", "showHeader", "headerClickable", "isNoTopEnd", "isChart"], outputs: ["headerClick"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18633
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPreviewCardComponent, isStandalone: true, selector: "mt-entity-preview-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<mt-card-content\r\n [inGroup]=\"false\"\r\n [headerConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['headerCardConfig']\r\n \"\r\n [styleConfig]=\"\r\n configurationItem()?.clientConfig?.displayConfig?.['StyleConfig']\r\n \"\r\n [cardStyleConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['cardStyleConfig']\r\n \"\r\n [title]=\"title()\"\r\n>\r\n <ng-container body>\r\n <div\r\n class=\"flex flex-wrap flex-1 p-4 pb-5\"\r\n *transloco=\"let t; prefix: 'dashboard'\"\r\n >\r\n @for (item of props(); track item.propInfo.key) {\r\n @if (!item.config?.hidden) {\r\n <div\r\n [style.width]=\"item.config?.width || '100%'\"\r\n style=\"min-width: 180px\"\r\n [class.border]=\"item.config?.border?.includes('all')\"\r\n [class.border-t]=\"item.config?.border?.includes('top')\"\r\n [class.border-l]=\"item.config?.border?.includes('left')\"\r\n [class.border-b]=\"item.config?.border?.includes('bottom')\"\r\n [class.border-r]=\"item.config?.border?.includes('right')\"\r\n class=\"flex items-center p-2\"\r\n >\r\n <mt-entity-preview [data]=\"item.propInfo\" class=\"w-full\">\r\n </mt-entity-preview>\r\n </div>\r\n }\r\n }\r\n\r\n @if (props().length === 0) {\r\n <div\r\n class=\"no-data-container w-full flex items-center justify-center py-8 text-muted-color\"\r\n >\r\n <i class=\"pi pi-info-circle mr-2\"></i>\r\n <span>{{ t(\"noData\") }}</span>\r\n </div>\r\n }\r\n </div>\r\n </ng-container>\r\n</mt-card-content>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: CardContentComponent, selector: "mt-card-content", inputs: ["title", "inGroup", "headerConfig", "styleConfig", "cardStyleConfig", "showHeader", "headerClickable", "isNoTopEnd", "isChart"], outputs: ["headerClick"] }, { kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18114
18634
|
}
|
|
18115
18635
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreviewCardComponent, decorators: [{
|
|
18116
18636
|
type: Component,
|
|
@@ -18119,132 +18639,118 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
18119
18639
|
TranslocoDirective,
|
|
18120
18640
|
CardContentComponent,
|
|
18121
18641
|
EntityPreview,
|
|
18122
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mt-card-content\r\n [inGroup]=\"false\"\r\n [headerConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['headerCardConfig']\r\n \"\r\n [styleConfig]=\"\r\n configurationItem()?.clientConfig?.displayConfig?.['StyleConfig']\r\n \"\r\n [cardStyleConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['cardStyleConfig']\r\n \"\r\n [title]=\"title()\"\r\n>\r\n <ng-container body>\r\n <div\r\n class=\"flex flex-wrap flex-1 p-4 pb-5\"\r\n *transloco=\"let t; prefix: 'dashboard'\"\r\n >\r\n @for (item of props(); track item.propInfo.key) {\n @if (!item.config?.hidden) {\n <div\n [style.width]=\"item.config?.width || '100%'\"\n style=\"min-width: 180px\"\n [class.border]=\"item.config?.border?.includes('all')\"\r\n [class.border-t]=\"item.config?.border?.includes('top')\"\r\n [class.border-l]=\"item.config?.border?.includes('left')\"\r\n [class.border-b]=\"item.config?.border?.includes('bottom')\"\n [class.border-r]=\"item.config?.border?.includes('right')\"\n class=\"flex items-center p-2\"\n >\n <mt-entity-preview [data]=\"item.propInfo\" class=\"w-full\">\n </mt-entity-preview>\n </div>\n }\n }\n\r\n @if (props().length === 0) {\r\n <div\r\n class=\"no-data-container w-full flex items-center justify-center py-8 text-muted-color\"\r\n >\r\n <i class=\"pi pi-info-circle mr-2\"></i>\r\n <span>{{ t(\"noData\") }}</span>\r\n </div>\r\n }\r\n </div>\r\n </ng-container>\r\n</mt-card-content>\r\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
18642
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mt-card-content\r\n [inGroup]=\"false\"\r\n [headerConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['headerCardConfig']\r\n \"\r\n [styleConfig]=\"\r\n configurationItem()?.clientConfig?.displayConfig?.['StyleConfig']\r\n \"\r\n [cardStyleConfig]=\"\r\n configurationItem()?.clientConfig?.configAsType?.['cardStyleConfig']\r\n \"\r\n [title]=\"title()\"\r\n>\r\n <ng-container body>\r\n <div\r\n class=\"flex flex-wrap flex-1 p-4 pb-5\"\r\n *transloco=\"let t; prefix: 'dashboard'\"\r\n >\r\n @for (item of props(); track item.propInfo.key) {\r\n @if (!item.config?.hidden) {\r\n <div\r\n [style.width]=\"item.config?.width || '100%'\"\r\n style=\"min-width: 180px\"\r\n [class.border]=\"item.config?.border?.includes('all')\"\r\n [class.border-t]=\"item.config?.border?.includes('top')\"\r\n [class.border-l]=\"item.config?.border?.includes('left')\"\r\n [class.border-b]=\"item.config?.border?.includes('bottom')\"\r\n [class.border-r]=\"item.config?.border?.includes('right')\"\r\n class=\"flex items-center p-2\"\r\n >\r\n <mt-entity-preview [data]=\"item.propInfo\" class=\"w-full\">\r\n </mt-entity-preview>\r\n </div>\r\n }\r\n }\r\n\r\n @if (props().length === 0) {\r\n <div\r\n class=\"no-data-container w-full flex items-center justify-center py-8 text-muted-color\"\r\n >\r\n <i class=\"pi pi-info-circle mr-2\"></i>\r\n <span>{{ t(\"noData\") }}</span>\r\n </div>\r\n }\r\n </div>\r\n </ng-container>\r\n</mt-card-content>\r\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
18123
18643
|
}], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }] } });
|
|
18124
18644
|
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
* Displays a list of level cards with properties.
|
|
18129
|
-
* Matches old app-build-level-card behavior.
|
|
18130
|
-
*/
|
|
18131
|
-
class LevelCardListComponent {
|
|
18132
|
-
storeService = inject(DashboardItemStoreService);
|
|
18133
|
-
transloco = inject(TranslocoService);
|
|
18645
|
+
class TopbarCardComponent {
|
|
18646
|
+
storeService = inject(DashboardStoreService);
|
|
18647
|
+
itemStoreService = inject(DashboardItemStoreService);
|
|
18134
18648
|
subscription = new Subscription();
|
|
18135
|
-
/** Dashboard ID */
|
|
18136
18649
|
dashboardId = input.required(...(ngDevMode ? [{ debugName: "dashboardId" }] : []));
|
|
18137
|
-
|
|
18138
|
-
inGroup = input(false, ...(ngDevMode ? [{ debugName: "inGroup" }] : []));
|
|
18139
|
-
/** Properties to hide */
|
|
18140
|
-
hideProperties = input([], ...(ngDevMode ? [{ debugName: "hideProperties" }] : []));
|
|
18141
|
-
/** Action event output */
|
|
18142
|
-
onAction = output();
|
|
18143
|
-
/** Configuration item */
|
|
18650
|
+
defaultBreadcrumbLabel = input('', ...(ngDevMode ? [{ debugName: "defaultBreadcrumbLabel" }] : []));
|
|
18144
18651
|
configurationItem = signal(null, ...(ngDevMode ? [{ debugName: "configurationItem" }] : []));
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18652
|
+
languageCode = computed(() => this.storeService.languageCode(), ...(ngDevMode ? [{ debugName: "languageCode" }] : []));
|
|
18653
|
+
queryParams = computed(() => this.storeService.queryParams(), ...(ngDevMode ? [{ debugName: "queryParams" }] : []));
|
|
18654
|
+
styleConfig = computed(() => {
|
|
18655
|
+
return (this.configurationItem()?.clientConfig?.displayConfig?.['StyleConfig'] ||
|
|
18656
|
+
{});
|
|
18657
|
+
}, ...(ngDevMode ? [{ debugName: "styleConfig" }] : []));
|
|
18658
|
+
configAsType = computed(() => {
|
|
18659
|
+
return this.configurationItem()?.clientConfig?.configAsType || {};
|
|
18660
|
+
}, ...(ngDevMode ? [{ debugName: "configAsType" }] : []));
|
|
18661
|
+
cardStyleConfig = computed(() => {
|
|
18662
|
+
return this.configAsType()['cardStyleConfig'] || {};
|
|
18663
|
+
}, ...(ngDevMode ? [{ debugName: "cardStyleConfig" }] : []));
|
|
18664
|
+
title = computed(() => {
|
|
18665
|
+
const config = this.configurationItem()?.clientConfig;
|
|
18666
|
+
const lang = this.languageCode();
|
|
18667
|
+
const title = config?.title?.[lang] || config?.title?.['en'] || '';
|
|
18668
|
+
return dynamicTextReplace(title, this.queryParams());
|
|
18669
|
+
}, ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
18670
|
+
subtitleText = computed(() => {
|
|
18671
|
+
const subtitle = this.configurationItem()?.clientConfig?.['subtitle'];
|
|
18672
|
+
const lang = this.languageCode();
|
|
18673
|
+
const value = typeof subtitle === 'string'
|
|
18674
|
+
? subtitle
|
|
18675
|
+
: subtitle?.[lang] || subtitle?.['en'] || subtitle?.['ar'] || '';
|
|
18676
|
+
return dynamicTextReplace(value, this.queryParams());
|
|
18677
|
+
}, ...(ngDevMode ? [{ debugName: "subtitleText" }] : []));
|
|
18678
|
+
showSubtitle = computed(() => {
|
|
18679
|
+
return (Boolean(this.configAsType()['showSubtitle']) && !!this.subtitleText());
|
|
18680
|
+
}, ...(ngDevMode ? [{ debugName: "showSubtitle" }] : []));
|
|
18681
|
+
icon = computed(() => {
|
|
18682
|
+
return this.configAsType()['icon'] || '';
|
|
18683
|
+
}, ...(ngDevMode ? [{ debugName: "icon" }] : []));
|
|
18684
|
+
iconColor = computed(() => {
|
|
18685
|
+
return this.styleConfig()['iconColor'] || '#4caf50';
|
|
18686
|
+
}, ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
|
|
18687
|
+
iconBackgroundColor = computed(() => {
|
|
18688
|
+
return this.styleConfig()['iconBgColor'] || 'rgba(76, 175, 80, 0.1)';
|
|
18689
|
+
}, ...(ngDevMode ? [{ debugName: "iconBackgroundColor" }] : []));
|
|
18690
|
+
borderColor = computed(() => {
|
|
18691
|
+
return this.styleConfig()['border-color'] || '';
|
|
18692
|
+
}, ...(ngDevMode ? [{ debugName: "borderColor" }] : []));
|
|
18693
|
+
borderWidth = computed(() => {
|
|
18694
|
+
return this.borderColor() ? 1 : 0;
|
|
18695
|
+
}, ...(ngDevMode ? [{ debugName: "borderWidth" }] : []));
|
|
18696
|
+
padding = computed(() => {
|
|
18697
|
+
return Number(this.configAsType()['padding'] ?? 16);
|
|
18698
|
+
}, ...(ngDevMode ? [{ debugName: "padding" }] : []));
|
|
18699
|
+
titleFontSize = computed(() => {
|
|
18700
|
+
return Number(this.styleConfig()['font-size-title'] ?? 18);
|
|
18701
|
+
}, ...(ngDevMode ? [{ debugName: "titleFontSize" }] : []));
|
|
18702
|
+
subtitleFontSize = computed(() => {
|
|
18703
|
+
return Number(this.configAsType()['subtitleFontSize'] ?? 14);
|
|
18704
|
+
}, ...(ngDevMode ? [{ debugName: "subtitleFontSize" }] : []));
|
|
18705
|
+
subtitleColor = computed(() => {
|
|
18706
|
+
return this.configAsType()['subtitleColor'] || '#666666';
|
|
18707
|
+
}, ...(ngDevMode ? [{ debugName: "subtitleColor" }] : []));
|
|
18708
|
+
breadcrumbs = computed(() => {
|
|
18709
|
+
const lang = this.languageCode();
|
|
18710
|
+
const params = this.queryParams();
|
|
18711
|
+
const raw = this.configAsType()['breadcrumb'];
|
|
18712
|
+
const fallbackLabel = dynamicTextReplace(this.defaultBreadcrumbLabel(), params) || this.title();
|
|
18713
|
+
if (!Array.isArray(raw))
|
|
18159
18714
|
return [];
|
|
18160
|
-
return
|
|
18161
|
-
{
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18715
|
+
return raw
|
|
18716
|
+
.map((item) => {
|
|
18717
|
+
const rawLabel = typeof item?.label === 'string'
|
|
18718
|
+
? item.label
|
|
18719
|
+
: item?.label?.[lang] ||
|
|
18720
|
+
item?.label?.['en'] ||
|
|
18721
|
+
item?.label?.['ar'] ||
|
|
18722
|
+
'';
|
|
18723
|
+
const rawLink = typeof item?.link === 'string' ? item.link : '';
|
|
18724
|
+
return {
|
|
18725
|
+
label: dynamicTextReplace(rawLabel, params) || fallbackLabel,
|
|
18726
|
+
link: dynamicTextReplace(rawLink, params),
|
|
18727
|
+
};
|
|
18728
|
+
})
|
|
18729
|
+
.filter((item) => item.label);
|
|
18730
|
+
}, ...(ngDevMode ? [{ debugName: "breadcrumbs" }] : []));
|
|
18173
18731
|
ngOnInit() {
|
|
18174
18732
|
const id = this.dashboardId();
|
|
18175
|
-
|
|
18176
|
-
this.subscription.add(this.storeService
|
|
18733
|
+
this.subscription.add(this.itemStoreService
|
|
18177
18734
|
.selectItemProperty$(id, 'ConfigurationItem')
|
|
18178
18735
|
.subscribe((config) => {
|
|
18179
18736
|
if (config) {
|
|
18180
18737
|
this.configurationItem.set(config);
|
|
18181
18738
|
}
|
|
18182
18739
|
}));
|
|
18183
|
-
// Subscribe to data
|
|
18184
|
-
this.subscription.add(this.storeService
|
|
18185
|
-
.selectItemProperty$(id, 'DataHandled')
|
|
18186
|
-
.subscribe((data) => {
|
|
18187
|
-
if (data && Array.isArray(data)) {
|
|
18188
|
-
this.cardData.set(data);
|
|
18189
|
-
}
|
|
18190
|
-
}));
|
|
18191
18740
|
}
|
|
18192
18741
|
ngOnDestroy() {
|
|
18193
18742
|
this.subscription.unsubscribe();
|
|
18194
18743
|
}
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
*/
|
|
18198
|
-
getBodyProps(card) {
|
|
18199
|
-
const hideProps = this.hideProperties();
|
|
18200
|
-
return (card.props || [])
|
|
18201
|
-
.filter((prop) => {
|
|
18202
|
-
// Skip attachments - shown separately in gallery mode
|
|
18203
|
-
if (prop.viewType === 'Attachment')
|
|
18204
|
-
return false;
|
|
18205
|
-
// Skip hidden properties
|
|
18206
|
-
if (hideProps.includes(prop.key))
|
|
18207
|
-
return false;
|
|
18208
|
-
// Skip name and status - shown in header
|
|
18209
|
-
const normalized = prop.normalizedKey?.toLowerCase();
|
|
18210
|
-
if (normalized === 'name' || normalized === 'status')
|
|
18211
|
-
return false;
|
|
18212
|
-
// Check if should display in levelCard_body
|
|
18213
|
-
const displayAreas = prop.displayAreas || prop.displayArea || [];
|
|
18214
|
-
return displayAreas.some((area) => area?.key === 'levelCard_body');
|
|
18215
|
-
})
|
|
18216
|
-
.sort((a, b) => {
|
|
18217
|
-
const aArea = (a.displayAreas || a.displayArea || []).find((area) => area?.key === 'levelCard_body');
|
|
18218
|
-
const bArea = (b.displayAreas || b.displayArea || []).find((area) => area?.key === 'levelCard_body');
|
|
18219
|
-
return (aArea?.order || 0) - (bArea?.order || 0);
|
|
18220
|
-
});
|
|
18744
|
+
isExternalLink(link) {
|
|
18745
|
+
return /^https?:\/\//i.test(link);
|
|
18221
18746
|
}
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
*/
|
|
18225
|
-
getAttachments(card) {
|
|
18226
|
-
const attachmentProp = (card.props || []).find((p) => p.viewType === 'Attachment');
|
|
18227
|
-
return attachmentProp?.value || [];
|
|
18228
|
-
}
|
|
18229
|
-
/**
|
|
18230
|
-
* Check if card has any counters
|
|
18231
|
-
*/
|
|
18232
|
-
hasCounters(card) {
|
|
18233
|
-
return !!(card.issuesCounts || card.risksCounts || card.milestonesCounts);
|
|
18234
|
-
}
|
|
18235
|
-
/**
|
|
18236
|
-
* Handle card click
|
|
18237
|
-
*/
|
|
18238
|
-
onCardClick(card) {
|
|
18239
|
-
this.onAction.emit({ type: 'click', data: card });
|
|
18240
|
-
}
|
|
18241
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LevelCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: LevelCardListComponent, isStandalone: true, selector: "mt-level-card-list", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null }, hideProperties: { classPropertyName: "hideProperties", publicName: "hideProperties", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<!-- Tabs (only shown if not in group) -->\r\n@if (tabs().length > 0 && !inGroup()) {\r\n <ul class=\"flex border-b\">\r\n @for (tab of tabs(); track $index; let i = $index) {\r\n <li\r\n class=\"cursor-pointer px-4 py-2 transition-colors\"\r\n [class.border-b-2]=\"i === tabSelected()\"\r\n [class.border-primary]=\"i === tabSelected()\"\r\n [class.text-primary]=\"i === tabSelected()\"\r\n [class.text-gray-600]=\"i !== tabSelected()\"\r\n (click)=\"tabSelected.set(i)\"\r\n >\r\n {{ tab[langCode()] }}\r\n </li>\r\n }\r\n </ul>\r\n}\r\n\r\n<!-- Cards Container -->\r\n<div\r\n class=\"overflow-y-auto overflow-x-hidden\"\r\n [style.max-height]=\"inGroup() ? '500px' : '90%'\"\r\n>\r\n @for (group of currentTabData(); track $index) {\r\n <div class=\"flex flex-wrap\">\r\n @for (card of group?.data; track card.id) {\r\n <div\r\n class=\"mb-2\"\r\n [class.card-col]=\"!galleryMode()\"\r\n [class.gallery-card-col]=\"galleryMode()\"\r\n [class.w-full]=\"!galleryMode()\"\r\n [class.md:w-1/2]=\"!galleryMode()\"\r\n [class.lg:w-1/3]=\"!galleryMode()\"\r\n [class.p-2]=\"true\"\r\n >\r\n <div\r\n class=\"h-full cursor-pointer rounded-lg bg-white shadow-sm transition-all hover:shadow-md\"\r\n (click)=\"onCardClick(card)\"\r\n >\r\n <!-- Card Header -->\r\n <div\r\n class=\"flex items-center justify-between border-b p-3\"\r\n [style.border-left-color]=\"\r\n card.status?.value?.details?.color || '#64b735'\r\n \"\r\n [style.border-left-width]=\"'4px'\"\r\n >\r\n <div class=\"min-w-0 flex-1\">\r\n <h6 class=\"truncate text-sm font-semibold text-gray-800\">\r\n {{ card.name }}\r\n </h6>\r\n </div>\r\n <div class=\"ml-2 flex items-center gap-2\">\r\n @if (card.status?.value?.name) {\r\n <span\r\n class=\"whitespace-nowrap rounded-full px-2 py-0.5 text-xs font-medium text-white\"\r\n [style.background-color]=\"\r\n card.status?.value?.details?.color || '#64b735'\r\n \"\r\n [pTooltip]=\"card.status?.value?.details?.description\"\r\n >\r\n {{ card.status?.value?.name }}\r\n </span>\r\n }\r\n @if (card.currentPhase) {\r\n <span\r\n class=\"rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-600\"\r\n >\r\n {{ card.currentPhase }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body - Properties -->\r\n <div class=\"p-3\">\r\n @for (prop of getBodyProps(card); track prop.key) {\r\n <div class=\"mb-2 flex items-start text-sm\">\r\n <span class=\"mr-2 font-medium text-gray-500\">\r\n {{ prop.key }}:\r\n </span>\r\n <span class=\"flex-1 text-gray-700\">\r\n <mt-entity-info\r\n [viewType]=\"prop.viewType\"\r\n [value]=\"prop.value\"\r\n [langCode]=\"langCode()\"\r\n />\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Gallery Mode Images -->\r\n @if (galleryMode() && getAttachments(card).length > 0) {\r\n <div class=\"flex gap-2 overflow-x-auto p-3 pt-0\">\r\n @for (img of getAttachments(card); track $index) {\r\n <img\r\n [src]=\"'api/Uploader/' + img.path\"\r\n alt=\"Attachment\"\r\n class=\"h-16 w-16 flex-shrink-0 rounded object-cover\"\r\n />\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Counts Row (issues, risks, milestones) -->\r\n @if (hasCounters(card)) {\r\n <div class=\"flex justify-around border-t p-2 text-xs\">\r\n @if (card.issuesCounts) {\r\n <div class=\"text-center\">\r\n <div class=\"font-medium text-red-500\">\r\n {{ card.issuesCounts.value }}\r\n </div>\r\n <div class=\"text-gray-400\">Issues</div>\r\n </div>\r\n }\r\n @if (card.risksCounts) {\r\n <div class=\"text-center\">\r\n <div class=\"font-medium text-orange-500\">\r\n {{ card.risksCounts.value }}\r\n </div>\r\n <div class=\"text-gray-400\">Risks</div>\r\n </div>\r\n }\r\n @if (card.milestonesCounts) {\r\n <div class=\"text-center\">\r\n <div class=\"font-medium text-blue-500\">\r\n {{ card.milestonesCounts.value }}\r\n </div>\r\n <div class=\"text-gray-400\">Milestones</div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".card-col{flex:0 0 100%}@media(min-width:768px){.card-col{flex:0 0 50%}}@media(min-width:1024px){.card-col{flex:0 0 33.333%}}.gallery-card-col{flex:0 0 100%}@media(min-width:640px){.gallery-card-col{flex:0 0 50%}}@media(min-width:1024px){.gallery-card-col{flex:0 0 25%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: EntityInfoComponent, selector: "mt-entity-info", inputs: ["data", "displayType", "extraInfoData", "limitWords", "customClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18747
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TopbarCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18748
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TopbarCardComponent, isStandalone: true, selector: "mt-topbar-card", inputs: { dashboardId: { classPropertyName: "dashboardId", publicName: "dashboardId", isSignal: true, isRequired: true, transformFunction: null }, defaultBreadcrumbLabel: { classPropertyName: "defaultBreadcrumbLabel", publicName: "defaultBreadcrumbLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"flex h-full flex-col gap-3 md:flex-row md:items-center md:justify-between\"\n [style.background-color]=\"\n cardStyleConfig()['backgroundColor'] || styleConfig()['background-color']\n \"\n [style.border-radius.px]=\"cardStyleConfig()['borderRadius']\"\n [style.border-color]=\"borderColor()\"\n [style.border-style]=\"borderWidth() ? 'solid' : null\"\n [style.border-width.px]=\"borderWidth()\"\n [style.color]=\"styleConfig()['color'] || 'inherit'\"\n [style.padding.px]=\"padding()\"\n>\n <div class=\"flex min-w-0 flex-1 items-center gap-3\">\n @if (icon()) {\n <mt-avatar\n [icon]=\"icon()\"\n size=\"normal\"\n shape=\"square\"\n [style.--p-avatar-background]=\"iconBackgroundColor()\"\n [style.--p-avatar-color]=\"iconColor()\"\n />\n }\n\n <div class=\"min-w-0\">\n @if (title()) {\n <h3\n class=\"m-0 truncate font-semibold leading-tight\"\n [style.font-size.px]=\"titleFontSize()\"\n >\n {{ title() }}\n </h3>\n }\n\n @if (showSubtitle()) {\n <p\n class=\"m-0 truncate leading-tight\"\n [style.font-size.px]=\"subtitleFontSize()\"\n [style.color]=\"subtitleColor()\"\n >\n {{ subtitleText() }}\n </p>\n }\n </div>\n </div>\n\n @if (breadcrumbs().length > 0) {\n <nav class=\"min-w-0 md:max-w-[60%]\">\n <ol class=\"flex flex-wrap items-center gap-2 text-sm\">\n @for (\n breadcrumb of breadcrumbs();\n track breadcrumb.label + $index;\n let last = $last\n ) {\n <li class=\"flex min-w-0 items-center gap-2\">\n @if (breadcrumb.link) {\n <a\n class=\"max-w-[12rem] truncate text-muted-color transition-colors hover:text-primary\"\n [href]=\"breadcrumb.link\"\n [target]=\"isExternalLink(breadcrumb.link) ? '_blank' : null\"\n [rel]=\"isExternalLink(breadcrumb.link) ? 'noreferrer' : null\"\n >\n {{ breadcrumb.label }}\n </a>\n } @else {\n <span class=\"max-w-[12rem] truncate text-muted-color\">\n {{ breadcrumb.label }}\n </span>\n }\n\n @if (!last) {\n <i class=\"mti mti-chevron-right text-xs text-muted-color\"></i>\n }\n </li>\n }\n </ol>\n </nav>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18243
18749
|
}
|
|
18244
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type:
|
|
18750
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TopbarCardComponent, decorators: [{
|
|
18245
18751
|
type: Component,
|
|
18246
|
-
args: [{ selector: 'mt-
|
|
18247
|
-
}], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }],
|
|
18752
|
+
args: [{ selector: 'mt-topbar-card', standalone: true, imports: [CommonModule, Avatar], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"flex h-full flex-col gap-3 md:flex-row md:items-center md:justify-between\"\n [style.background-color]=\"\n cardStyleConfig()['backgroundColor'] || styleConfig()['background-color']\n \"\n [style.border-radius.px]=\"cardStyleConfig()['borderRadius']\"\n [style.border-color]=\"borderColor()\"\n [style.border-style]=\"borderWidth() ? 'solid' : null\"\n [style.border-width.px]=\"borderWidth()\"\n [style.color]=\"styleConfig()['color'] || 'inherit'\"\n [style.padding.px]=\"padding()\"\n>\n <div class=\"flex min-w-0 flex-1 items-center gap-3\">\n @if (icon()) {\n <mt-avatar\n [icon]=\"icon()\"\n size=\"normal\"\n shape=\"square\"\n [style.--p-avatar-background]=\"iconBackgroundColor()\"\n [style.--p-avatar-color]=\"iconColor()\"\n />\n }\n\n <div class=\"min-w-0\">\n @if (title()) {\n <h3\n class=\"m-0 truncate font-semibold leading-tight\"\n [style.font-size.px]=\"titleFontSize()\"\n >\n {{ title() }}\n </h3>\n }\n\n @if (showSubtitle()) {\n <p\n class=\"m-0 truncate leading-tight\"\n [style.font-size.px]=\"subtitleFontSize()\"\n [style.color]=\"subtitleColor()\"\n >\n {{ subtitleText() }}\n </p>\n }\n </div>\n </div>\n\n @if (breadcrumbs().length > 0) {\n <nav class=\"min-w-0 md:max-w-[60%]\">\n <ol class=\"flex flex-wrap items-center gap-2 text-sm\">\n @for (\n breadcrumb of breadcrumbs();\n track breadcrumb.label + $index;\n let last = $last\n ) {\n <li class=\"flex min-w-0 items-center gap-2\">\n @if (breadcrumb.link) {\n <a\n class=\"max-w-[12rem] truncate text-muted-color transition-colors hover:text-primary\"\n [href]=\"breadcrumb.link\"\n [target]=\"isExternalLink(breadcrumb.link) ? '_blank' : null\"\n [rel]=\"isExternalLink(breadcrumb.link) ? 'noreferrer' : null\"\n >\n {{ breadcrumb.label }}\n </a>\n } @else {\n <span class=\"max-w-[12rem] truncate text-muted-color\">\n {{ breadcrumb.label }}\n </span>\n }\n\n @if (!last) {\n <i class=\"mti mti-chevron-right text-xs text-muted-color\"></i>\n }\n </li>\n }\n </ol>\n </nav>\n }\n</div>\n" }]
|
|
18753
|
+
}], propDecorators: { dashboardId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardId", required: true }] }], defaultBreadcrumbLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultBreadcrumbLabel", required: false }] }] } });
|
|
18248
18754
|
|
|
18249
18755
|
class DashboardItem {
|
|
18250
18756
|
storeService = inject(DashboardStoreService);
|
|
@@ -18263,6 +18769,8 @@ class DashboardItem {
|
|
|
18263
18769
|
chartTypeId = input(undefined, ...(ngDevMode ? [{ debugName: "chartTypeId" }] : []));
|
|
18264
18770
|
/** Read-only mode */
|
|
18265
18771
|
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
18772
|
+
/** Parent page/dashboard name for topbar breadcrumb fallbacks */
|
|
18773
|
+
pageName = input('', ...(ngDevMode ? [{ debugName: "pageName" }] : []));
|
|
18266
18774
|
/** Whether this item is inside a group */
|
|
18267
18775
|
inGroup = input(false, ...(ngDevMode ? [{ debugName: "inGroup" }] : []));
|
|
18268
18776
|
/** Whether this item is rendered inside a dialog */
|
|
@@ -18553,25 +19061,24 @@ class DashboardItem {
|
|
|
18553
19061
|
return merged;
|
|
18554
19062
|
}
|
|
18555
19063
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18556
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardItem, isStandalone: true, selector: "mt-dashboard-item", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null }, isDialog: { classPropertyName: "isDialog", publicName: "isDialog", isSignal: true, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryFilter: { classPropertyName: "ignoreQueryFilter", publicName: "ignoreQueryFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered" }, ngImport: i0, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div class=\"flex flex-col items-center justify-center h-full p-4 text-center\">\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || \"Error loading data\" }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"'Retry'\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-level-card-list\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-level-card-list>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <!-- Topbar handled at viewer level -->\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: ChartCardComponent, selector: "mt-chart-card", inputs: ["dashboardId", "inGroup", "isConfigMode"], outputs: ["onAction"] }, { kind: "component", type: TableCardComponent, selector: "mt-table-card", inputs: ["dashboardId", "inGroup"], outputs: ["onAction"] }, { kind: "component", type: ListStatisticCardComponent, selector: "mt-list-statistic-card", inputs: ["dashboardId"] }, { kind: "component", type: HeaderCardComponent, selector: "mt-header-card", inputs: ["dashboardId"], outputs: ["onAction"] }, { kind: "component", type: SkeletonCardComponent, selector: "mt-skeleton-card", inputs: ["dashboardId"] }, { kind: "component", type: EntityPreviewCardComponent, selector: "mt-entity-preview-card", inputs: ["dashboardId"] }, { kind: "component", type: LevelCardListComponent, selector: "mt-level-card-list", inputs: ["dashboardId", "inGroup", "hideProperties"], outputs: ["onAction"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19064
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardItem, isStandalone: true, selector: "mt-dashboard-item", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, pageName: { classPropertyName: "pageName", publicName: "pageName", isSignal: true, isRequired: false, transformFunction: null }, inGroup: { classPropertyName: "inGroup", publicName: "inGroup", isSignal: true, isRequired: false, transformFunction: null }, isDialog: { classPropertyName: "isDialog", publicName: "isDialog", isSignal: true, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryFilter: { classPropertyName: "ignoreQueryFilter", publicName: "ignoreQueryFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered" }, ngImport: i0, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full p-4 text-center\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n >\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || t(\"error-loading-data\") }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"t('retry')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-properties-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-properties-card>\r\n }\r\n\r\n @case (\"entitiesPreview\") {\r\n <mt-properties-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-properties-card>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <mt-topbar-card\r\n [dashboardId]=\"dashboardId()\"\r\n [defaultBreadcrumbLabel]=\"pageName()\"\r\n ></mt-topbar-card>\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Entity Preview With Formula -->\r\n @case (\"entityPreviewWithFormula\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: ChartCardComponent, selector: "mt-chart-card", inputs: ["dashboardId", "inGroup", "isConfigMode"], outputs: ["onAction"] }, { kind: "component", type: TableCardComponent, selector: "mt-table-card", inputs: ["dashboardId", "inGroup"], outputs: ["onAction"] }, { kind: "component", type: ListStatisticCardComponent, selector: "mt-list-statistic-card", inputs: ["dashboardId"] }, { kind: "component", type: HeaderCardComponent, selector: "mt-header-card", inputs: ["dashboardId"], outputs: ["onAction"] }, { kind: "component", type: TopbarCardComponent, selector: "mt-topbar-card", inputs: ["dashboardId", "defaultBreadcrumbLabel"] }, { kind: "component", type: SkeletonCardComponent, selector: "mt-skeleton-card", inputs: ["dashboardId"] }, { kind: "component", type: PropertiesCardComponent, selector: "mt-properties-card, mt-entities-preview-card", inputs: ["dashboardId", "inGroup"], outputs: ["onAction"] }, { kind: "component", type: EntityPreviewCardComponent, selector: "mt-entity-preview-card", inputs: ["dashboardId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18557
19065
|
}
|
|
18558
19066
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardItem, decorators: [{
|
|
18559
19067
|
type: Component,
|
|
18560
19068
|
args: [{ selector: 'mt-dashboard-item', standalone: true, imports: [
|
|
18561
19069
|
CommonModule,
|
|
18562
|
-
TranslocoDirective,
|
|
18563
19070
|
Button,
|
|
18564
19071
|
Icon,
|
|
18565
19072
|
ChartCardComponent,
|
|
18566
19073
|
TableCardComponent,
|
|
18567
19074
|
ListStatisticCardComponent,
|
|
18568
|
-
StatisticCardComponent,
|
|
18569
19075
|
HeaderCardComponent,
|
|
19076
|
+
TopbarCardComponent,
|
|
18570
19077
|
SkeletonCardComponent,
|
|
19078
|
+
PropertiesCardComponent,
|
|
18571
19079
|
EntityPreviewCardComponent,
|
|
18572
|
-
|
|
18573
|
-
|
|
18574
|
-
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartTypeId", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], isDialog: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDialog", required: false }] }], queryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryParams", required: false }] }], extraFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraFilters", required: false }] }], ignoreQueryFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryFilter", required: false }] }], actionTriggered: [{ type: i0.Output, args: ["actionTriggered"] }] } });
|
|
19080
|
+
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isLoading()) {\r\n <mt-skeleton-card [dashboardId]=\"dashboardId()\"></mt-skeleton-card>\r\n} @else if (hasError()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full p-4 text-center\"\r\n *transloco=\"let t; prefix: 'dashboardBuilder'\"\r\n >\r\n <mt-icon\r\n icon=\"general.alert-circle\"\r\n class=\"text-4xl text-red-500 mb-2\"\r\n ></mt-icon>\r\n <p class=\"text-red-500 font-medium\">\r\n {{ errorMessage() || t(\"error-loading-data\") }}\r\n </p>\r\n <mt-button\r\n class=\"mt-2\"\r\n [label]=\"t('retry')\"\r\n severity=\"secondary\"\r\n size=\"small\"\r\n icon=\"arrow.refresh-cw-01\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n} @else {\r\n @switch (componentName()) {\r\n <!-- Chart Types -->\r\n @case (\"chart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Map Chart -->\r\n @case (\"map\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Background Text -->\r\n @case (\"BackgroundTextChart\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Chart Custom With Card Info -->\r\n @case (\"chartCustomWithCardInfo\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Charts -->\r\n @case (\"listOfcharts\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List of Cards Statistic -->\r\n @case (\"listOfCardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Cards Statistic (single) -->\r\n @case (\"cardsStatistic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Header -->\r\n @case (\"header\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Footer (same as header) -->\r\n @case (\"footer\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Label (same as header) -->\r\n @case (\"label\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- List of Level Cards -->\r\n @case (\"listOfLevelCards\") {\r\n <mt-properties-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-properties-card>\r\n }\r\n\r\n @case (\"entitiesPreview\") {\r\n <mt-properties-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-properties-card>\r\n }\r\n\r\n <!-- Table -->\r\n @case (\"table\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Phase Gate Table -->\r\n @case (\"phaseGateTable\") {\r\n <mt-table-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-table-card>\r\n }\r\n\r\n <!-- Topbar -->\r\n @case (\"topbar\") {\r\n <mt-topbar-card\r\n [dashboardId]=\"dashboardId()\"\r\n [defaultBreadcrumbLabel]=\"pageName()\"\r\n ></mt-topbar-card>\r\n }\r\n\r\n <!-- Timeline -->\r\n @case (\"timeline\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Timeline Project Dependencies -->\r\n @case (\"timelineProjectDependencies\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Last History Level Card -->\r\n @case (\"lastHistoryLevelCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Entity Preview -->\r\n @case (\"entityPreview\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Entity Preview With Formula -->\r\n @case (\"entityPreviewWithFormula\") {\r\n <mt-entity-preview-card [dashboardId]=\"dashboardId()\">\r\n </mt-entity-preview-card>\r\n }\r\n\r\n <!-- Cluster Stacked Chart -->\r\n @case (\"clusterStackedChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- List Component S+ Card -->\r\n @case (\"listComponentSplusCard\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Splitter Chart -->\r\n @case (\"splitterChart\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Repeater (same as header) -->\r\n @case (\"repeater\") {\r\n <mt-header-card [dashboardId]=\"dashboardId()\"> </mt-header-card>\r\n }\r\n\r\n <!-- Level Cards With Static -->\r\n @case (\"levelCardsWithStatic\") {\r\n <mt-list-statistic-card [dashboardId]=\"dashboardId()\">\r\n </mt-list-statistic-card>\r\n }\r\n\r\n <!-- Phase Gate Stepper Card -->\r\n @case (\"phaseGateStepperCard\") {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n\r\n <!-- Dialog -->\r\n @case (\"dialog\") {\r\n <!-- Dialog handled separately via ModalService -->\r\n }\r\n\r\n <!-- Default: try chart -->\r\n @default {\r\n <mt-chart-card\r\n [dashboardId]=\"dashboardId()\"\r\n [inGroup]=\"inGroup()\"\r\n (onAction)=\"doActions($event.data, $event.type)\"\r\n >\r\n </mt-chart-card>\r\n }\r\n }\r\n}\r\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
|
19081
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartTypeId", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], pageName: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageName", required: false }] }], inGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "inGroup", required: false }] }], isDialog: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDialog", required: false }] }], queryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryParams", required: false }] }], extraFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraFilters", required: false }] }], ignoreQueryFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryFilter", required: false }] }], actionTriggered: [{ type: i0.Output, args: ["actionTriggered"] }] } });
|
|
18575
19082
|
|
|
18576
19083
|
/**
|
|
18577
19084
|
* Chart Viewer Component
|
|
@@ -18594,11 +19101,11 @@ class ChartViewer {
|
|
|
18594
19101
|
}, 500);
|
|
18595
19102
|
}
|
|
18596
19103
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartViewer, isStandalone: true, selector: "mt-chart-viewer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19104
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ChartViewer, isStandalone: true, selector: "mt-chart-viewer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, chartTypeId: { classPropertyName: "chartTypeId", publicName: "chartTypeId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n [pageName]=\"\r\n config()?.clientConfig?.title?.['en'] ||\r\n config()?.clientConfig?.title?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "pageName", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18598
19105
|
}
|
|
18599
19106
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ChartViewer, decorators: [{
|
|
18600
19107
|
type: Component,
|
|
18601
|
-
args: [{ selector: 'mt-chart-viewer', standalone: true, imports: [CommonModule, TranslocoDirective, Button, Icon, DashboardItem], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
19108
|
+
args: [{ selector: 'mt-chart-viewer', standalone: true, imports: [CommonModule, TranslocoDirective, Button, Icon, DashboardItem], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"h-full flex flex-col bg-surface-50 border-l border-surface-200\">\r\n <!-- Header -->\r\n <div\r\n class=\"flex items-center justify-between px-4 py-3 bg-surface-0 border-b border-surface-200\"\r\n >\r\n <span class=\"text-sm font-medium text-surface-700\">{{\r\n t(\"preview\")\r\n }}</span>\r\n <mt-button\r\n icon=\"arrow.refresh-cw-01\"\r\n [rounded]=\"true\"\r\n size=\"small\"\r\n severity=\"help\"\r\n [tooltip]=\"t('refresh')\"\r\n (onClick)=\"refresh()\"\r\n />\r\n </div>\r\n\r\n <!-- Preview Content -->\r\n <div class=\"flex-1 p-4 overflow-auto\">\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <mt-icon\r\n icon=\"general.loading-02\"\r\n class=\"text-3xl text-primary animate-spin\"\r\n />\r\n </div>\r\n } @else if (config() && chartTypeId()) {\r\n <div\r\n class=\"h-full bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden\"\r\n >\r\n <mt-dashboard-item\r\n [config]=\"config()\"\r\n [chartTypeId]=\"chartTypeId()\"\r\n [readonly]=\"true\"\r\n [pageName]=\"\r\n config()?.clientConfig?.title?.['en'] ||\r\n config()?.clientConfig?.title?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-full text-muted-color\"\r\n >\r\n <mt-icon icon=\"chart.bar-chart-10\" class=\"text-4xl mb-3 opacity-50\" />\r\n <p class=\"text-sm\">{{ t(\"noPreviewAvailable\") }}</p>\r\n <p class=\"text-xs opacity-70\">{{ t(\"configureChartToPreview\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
18602
19109
|
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], chartTypeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartTypeId", required: false }] }] } });
|
|
18603
19110
|
|
|
18604
19111
|
/**
|
|
@@ -18676,6 +19183,8 @@ class ManageItem {
|
|
|
18676
19183
|
// Check for dialog config data (when opened via DynamicDialog)
|
|
18677
19184
|
const dialogData = this._dialogConfig?.data;
|
|
18678
19185
|
const inputData = this.data();
|
|
19186
|
+
const services = inputData?.services ?? dialogData?.services ?? null;
|
|
19187
|
+
this._dashboardService.setModulesTreeServices(services);
|
|
18679
19188
|
// Get pre-selected chart type if available
|
|
18680
19189
|
const preselectedType = inputData?.chartType ?? dialogData?.chartType;
|
|
18681
19190
|
if (dialogData?.chart) {
|
|
@@ -18724,6 +19233,9 @@ class ManageItem {
|
|
|
18724
19233
|
this._manageItemService.updateClientConfig(partialConfig.clientConfig);
|
|
18725
19234
|
}
|
|
18726
19235
|
}
|
|
19236
|
+
onChartTypeChange(type) {
|
|
19237
|
+
this._manageItemService.selectType(type);
|
|
19238
|
+
}
|
|
18727
19239
|
/** Update service config */
|
|
18728
19240
|
onServiceConfigUpdate(partialConfig) {
|
|
18729
19241
|
this._manageItemService.updateServiceConfig(partialConfig);
|
|
@@ -18733,7 +19245,7 @@ class ManageItem {
|
|
|
18733
19245
|
this._manageItemService.updateClientConfig(partialConfig);
|
|
18734
19246
|
}
|
|
18735
19247
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ManageItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18736
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ManageItem, isStandalone: true, selector: "mt-manage-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ManageItemService], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"flex flex-col h-full\" [class]=\"modal.contentClass\">\r\n <!-- Main Layout: 60% Config | 40% Preview -->\r\n <div class=\"flex flex-1\">\r\n <!-- Left Side: Configuration (60%) -->\r\n <div class=\"w-[60%] flex flex-col border-r border-surface-200\">\r\n <!-- Content -->\r\n <div class=\"flex-1 flex flex-col gap-4 p-4 overflow-auto\">\r\n <!-- Chart Type Badge -->\r\n @if (selectedChartType()) {\r\n <div class=\"flex items-center gap-2 p-3 bg-surface-50 rounded-lg\">\r\n <span\r\n class=\"w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600\"\r\n >\r\n <mt-icon\r\n [icon]=\"selectedChartType()?.icon\"\r\n class=\"text-xl\"\r\n ></mt-icon>\r\n </span>\r\n <div class=\"flex-1\">\r\n <h3 class=\"text-sm font-semibold text-surface-700\">\r\n {{ isNew() ? t(\"newItem\") : t(\"editItem\") }}\r\n </h3>\r\n <p class=\"text-xs text-muted-color\">\r\n {{ selectedChartType()?.name }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Tabs -->\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n\r\n <!-- Tab Content - All tabs rendered but hidden, prevents re-initialization -->\r\n <div [hidden]=\"activeTab() !== 'general'\">\r\n <mt-general-settings\r\n [config]=\"config()\"\r\n [isDialog]=\"isDialog()\"\r\n [hasPreselectedType]=\"hasPreselectedType()\"\r\n (configChange)=\"onConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'dataSource'\">\r\n <mt-data-source-settings\r\n [config]=\"config()\"\r\n [chartType]=\"selectedChartType()\"\r\n (serviceConfigChange)=\"onServiceConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'actions'\">\r\n <mt-actions-settings\r\n [config]=\"config()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Chart Preview (40%) -->\r\n <div class=\"w-[40%] min-w-[350px] h-[500px]\">\r\n <mt-chart-viewer [config]=\"config()\" [chartTypeId]=\"chartTypeId()\" />\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <!-- Validation Status -->\r\n <div class=\"flex items-center gap-2 text-sm flex-1\">\r\n @if (isValid()) {\r\n <span class=\"flex items-center gap-1 text-green-600\">\r\n <mt-icon icon=\"general.check-circle\" class=\"text-base\" />\r\n {{ t(\"ready\") }}\r\n </span>\r\n } @else {\r\n <span class=\"flex items-center gap-1 text-amber-600\">\r\n <mt-icon icon=\"general.alert-circle\" class=\"text-base\" />\r\n {{ t(\"incomplete\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n [text]=\"true\"\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"!isValid()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: GeneralSettings, selector: "mt-general-settings", inputs: ["config", "isDialog", "hasPreselectedType"], outputs: ["configChange", "chartTypeChange"] }, { kind: "component", type: DataSourceSettings, selector: "mt-data-source-settings", inputs: ["config", "chartType"], outputs: ["serviceConfigChange"] }, { kind: "component", type: ActionsSettings, selector: "mt-actions-settings", inputs: ["config"], outputs: ["clientConfigChange"] }, { kind: "component", type: ChartViewer, selector: "mt-chart-viewer", inputs: ["config", "chartTypeId"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19248
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ManageItem, isStandalone: true, selector: "mt-manage-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ManageItemService], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"flex flex-col h-full\" [class]=\"modal.contentClass\">\r\n <!-- Main Layout: 60% Config | 40% Preview -->\r\n <div class=\"flex flex-1\">\r\n <!-- Left Side: Configuration (60%) -->\r\n <div class=\"w-[60%] flex flex-col border-r border-surface-200\">\r\n <!-- Content -->\r\n <div class=\"flex-1 flex flex-col gap-4 p-4 overflow-auto\">\r\n <!-- Chart Type Badge -->\r\n @if (selectedChartType()) {\r\n <div class=\"flex items-center gap-2 p-3 bg-surface-50 rounded-lg\">\r\n <span\r\n class=\"w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600\"\r\n >\r\n <mt-icon\r\n [icon]=\"selectedChartType()?.icon\"\r\n class=\"text-xl\"\r\n ></mt-icon>\r\n </span>\r\n <div class=\"flex-1\">\r\n <h3 class=\"text-sm font-semibold text-surface-700\">\r\n {{ isNew() ? t(\"newItem\") : t(\"editItem\") }}\r\n </h3>\r\n <p class=\"text-xs text-muted-color\">\r\n {{ selectedChartType()?.name }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Tabs -->\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n\r\n <!-- Tab Content - All tabs rendered but hidden, prevents re-initialization -->\r\n <div [hidden]=\"activeTab() !== 'general'\">\r\n <mt-general-settings\r\n [config]=\"config()\"\r\n [isDialog]=\"isDialog()\"\r\n [hasPreselectedType]=\"hasPreselectedType()\"\r\n (configChange)=\"onConfigUpdate($event)\"\r\n (chartTypeChange)=\"onChartTypeChange($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'dataSource'\">\r\n <mt-data-source-settings\r\n [config]=\"config()\"\r\n [chartType]=\"selectedChartType()\"\r\n (serviceConfigChange)=\"onServiceConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'actions'\">\r\n <mt-actions-settings\r\n [config]=\"config()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Chart Preview (40%) -->\r\n <div class=\"w-[40%] min-w-[350px] h-[500px]\">\r\n <mt-chart-viewer [config]=\"config()\" [chartTypeId]=\"chartTypeId()\" />\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <!-- Validation Status -->\r\n <div class=\"flex items-center gap-2 text-sm flex-1\">\r\n @if (isValid()) {\r\n <span class=\"flex items-center gap-1 text-green-600\">\r\n <mt-icon icon=\"general.check-circle\" class=\"text-base\" />\r\n {{ t(\"ready\") }}\r\n </span>\r\n } @else {\r\n <span class=\"flex items-center gap-1 text-amber-600\">\r\n <mt-icon icon=\"general.alert-circle\" class=\"text-base\" />\r\n {{ t(\"incomplete\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n [text]=\"true\"\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"!isValid()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: GeneralSettings, selector: "mt-general-settings", inputs: ["config", "isDialog", "hasPreselectedType"], outputs: ["configChange", "chartTypeChange"] }, { kind: "component", type: DataSourceSettings, selector: "mt-data-source-settings", inputs: ["config", "chartType"], outputs: ["serviceConfigChange"] }, { kind: "component", type: ActionsSettings, selector: "mt-actions-settings", inputs: ["config"], outputs: ["clientConfigChange"] }, { kind: "component", type: ChartViewer, selector: "mt-chart-viewer", inputs: ["config", "chartTypeId"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18737
19249
|
}
|
|
18738
19250
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ManageItem, decorators: [{
|
|
18739
19251
|
type: Component,
|
|
@@ -18743,16 +19255,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
18743
19255
|
TranslocoDirective,
|
|
18744
19256
|
Button,
|
|
18745
19257
|
Tabs,
|
|
18746
|
-
Card,
|
|
18747
|
-
TextField,
|
|
18748
|
-
SelectField,
|
|
18749
|
-
CheckboxField,
|
|
18750
19258
|
GeneralSettings,
|
|
18751
19259
|
DataSourceSettings,
|
|
18752
19260
|
ActionsSettings,
|
|
18753
19261
|
ChartViewer,
|
|
18754
19262
|
Icon,
|
|
18755
|
-
], providers: [ManageItemService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"flex flex-col h-full\" [class]=\"modal.contentClass\">\r\n <!-- Main Layout: 60% Config | 40% Preview -->\r\n <div class=\"flex flex-1\">\r\n <!-- Left Side: Configuration (60%) -->\r\n <div class=\"w-[60%] flex flex-col border-r border-surface-200\">\r\n <!-- Content -->\r\n <div class=\"flex-1 flex flex-col gap-4 p-4 overflow-auto\">\r\n <!-- Chart Type Badge -->\r\n @if (selectedChartType()) {\r\n <div class=\"flex items-center gap-2 p-3 bg-surface-50 rounded-lg\">\r\n <span\r\n class=\"w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600\"\r\n >\r\n <mt-icon\r\n [icon]=\"selectedChartType()?.icon\"\r\n class=\"text-xl\"\r\n ></mt-icon>\r\n </span>\r\n <div class=\"flex-1\">\r\n <h3 class=\"text-sm font-semibold text-surface-700\">\r\n {{ isNew() ? t(\"newItem\") : t(\"editItem\") }}\r\n </h3>\r\n <p class=\"text-xs text-muted-color\">\r\n {{ selectedChartType()?.name }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Tabs -->\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n\r\n <!-- Tab Content - All tabs rendered but hidden, prevents re-initialization -->\r\n <div [hidden]=\"activeTab() !== 'general'\">\r\n <mt-general-settings\r\n [config]=\"config()\"\r\n [isDialog]=\"isDialog()\"\r\n [hasPreselectedType]=\"hasPreselectedType()\"\r\n (configChange)=\"onConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'dataSource'\">\r\n <mt-data-source-settings\r\n [config]=\"config()\"\r\n [chartType]=\"selectedChartType()\"\r\n (serviceConfigChange)=\"onServiceConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'actions'\">\r\n <mt-actions-settings\r\n [config]=\"config()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Chart Preview (40%) -->\r\n <div class=\"w-[40%] min-w-[350px] h-[500px]\">\r\n <mt-chart-viewer [config]=\"config()\" [chartTypeId]=\"chartTypeId()\" />\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <!-- Validation Status -->\r\n <div class=\"flex items-center gap-2 text-sm flex-1\">\r\n @if (isValid()) {\r\n <span class=\"flex items-center gap-1 text-green-600\">\r\n <mt-icon icon=\"general.check-circle\" class=\"text-base\" />\r\n {{ t(\"ready\") }}\r\n </span>\r\n } @else {\r\n <span class=\"flex items-center gap-1 text-amber-600\">\r\n <mt-icon icon=\"general.alert-circle\" class=\"text-base\" />\r\n {{ t(\"incomplete\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n [text]=\"true\"\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"!isValid()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
|
|
19263
|
+
], providers: [ManageItemService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <div class=\"flex flex-col h-full\" [class]=\"modal.contentClass\">\r\n <!-- Main Layout: 60% Config | 40% Preview -->\r\n <div class=\"flex flex-1\">\r\n <!-- Left Side: Configuration (60%) -->\r\n <div class=\"w-[60%] flex flex-col border-r border-surface-200\">\r\n <!-- Content -->\r\n <div class=\"flex-1 flex flex-col gap-4 p-4 overflow-auto\">\r\n <!-- Chart Type Badge -->\r\n @if (selectedChartType()) {\r\n <div class=\"flex items-center gap-2 p-3 bg-surface-50 rounded-lg\">\r\n <span\r\n class=\"w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600\"\r\n >\r\n <mt-icon\r\n [icon]=\"selectedChartType()?.icon\"\r\n class=\"text-xl\"\r\n ></mt-icon>\r\n </span>\r\n <div class=\"flex-1\">\r\n <h3 class=\"text-sm font-semibold text-surface-700\">\r\n {{ isNew() ? t(\"newItem\") : t(\"editItem\") }}\r\n </h3>\r\n <p class=\"text-xs text-muted-color\">\r\n {{ selectedChartType()?.name }}\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Tabs -->\r\n <mt-tabs\r\n [options]=\"tabOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(active)]=\"activeTab\"\r\n />\r\n\r\n <!-- Tab Content - All tabs rendered but hidden, prevents re-initialization -->\r\n <div [hidden]=\"activeTab() !== 'general'\">\r\n <mt-general-settings\r\n [config]=\"config()\"\r\n [isDialog]=\"isDialog()\"\r\n [hasPreselectedType]=\"hasPreselectedType()\"\r\n (configChange)=\"onConfigUpdate($event)\"\r\n (chartTypeChange)=\"onChartTypeChange($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'dataSource'\">\r\n <mt-data-source-settings\r\n [config]=\"config()\"\r\n [chartType]=\"selectedChartType()\"\r\n (serviceConfigChange)=\"onServiceConfigUpdate($event)\"\r\n />\r\n </div>\r\n\r\n <div [hidden]=\"activeTab() !== 'actions'\">\r\n <mt-actions-settings\r\n [config]=\"config()\"\r\n (clientConfigChange)=\"onClientConfigUpdate($event)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Chart Preview (40%) -->\r\n <div class=\"w-[40%] min-w-[350px] h-[500px]\">\r\n <mt-chart-viewer [config]=\"config()\" [chartTypeId]=\"chartTypeId()\" />\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <!-- Validation Status -->\r\n <div class=\"flex items-center gap-2 text-sm flex-1\">\r\n @if (isValid()) {\r\n <span class=\"flex items-center gap-1 text-green-600\">\r\n <mt-icon icon=\"general.check-circle\" class=\"text-base\" />\r\n {{ t(\"ready\") }}\r\n </span>\r\n } @else {\r\n <span class=\"flex items-center gap-1 text-amber-600\">\r\n <mt-icon icon=\"general.alert-circle\" class=\"text-base\" />\r\n {{ t(\"incomplete\") }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <mt-button\r\n [text]=\"true\"\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n (onClick)=\"cancel()\"\r\n />\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"!isValid()\"\r\n (onClick)=\"save()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
|
|
18756
19264
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
18757
19265
|
|
|
18758
19266
|
/**
|
|
@@ -18795,20 +19303,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
18795
19303
|
class WidgetPaletteComponent {
|
|
18796
19304
|
modal = inject(ModalService);
|
|
18797
19305
|
ref = inject(ModalRef, { optional: true });
|
|
19306
|
+
translocoService = inject(TranslocoService);
|
|
18798
19307
|
/** Product filter - filters chart types by product (pplus, splus, report) */
|
|
18799
19308
|
product = input(null, ...(ngDevMode ? [{ debugName: "product" }] : []));
|
|
18800
19309
|
/** Search filter */
|
|
18801
19310
|
searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
18802
19311
|
/** Active tab (category) */
|
|
18803
|
-
activeTab = signal('
|
|
19312
|
+
activeTab = signal('layout', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
|
18804
19313
|
/** Tab options for categories */
|
|
18805
|
-
tabOptions = [
|
|
18806
|
-
{
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
{
|
|
18811
|
-
|
|
19314
|
+
tabOptions = computed(() => [
|
|
19315
|
+
{
|
|
19316
|
+
label: this.translocoService.translate('dashboardBuilder.categoryLayout'),
|
|
19317
|
+
value: 'layout',
|
|
19318
|
+
},
|
|
19319
|
+
{
|
|
19320
|
+
label: this.translocoService.translate('dashboardBuilder.categoryCommon'),
|
|
19321
|
+
value: 'special',
|
|
19322
|
+
},
|
|
19323
|
+
{
|
|
19324
|
+
label: this.translocoService.translate('dashboardBuilder.categoryCharts'),
|
|
19325
|
+
value: 'chart',
|
|
19326
|
+
},
|
|
19327
|
+
{
|
|
19328
|
+
label: this.translocoService.translate('dashboardBuilder.categoryTables'),
|
|
19329
|
+
value: 'table',
|
|
19330
|
+
},
|
|
19331
|
+
], ...(ngDevMode ? [{ debugName: "tabOptions" }] : []));
|
|
18812
19332
|
/** All chart types filtered by product */
|
|
18813
19333
|
filteredChartTypes = computed(() => {
|
|
18814
19334
|
const prod = this.product();
|
|
@@ -18838,7 +19358,6 @@ class WidgetPaletteComponent {
|
|
|
18838
19358
|
const types = this.filteredChartTypes().filter((t) => !t.hideInList);
|
|
18839
19359
|
return {
|
|
18840
19360
|
chart: types.filter((t) => t.category === 'chart').length,
|
|
18841
|
-
card: types.filter((t) => t.category === 'card').length,
|
|
18842
19361
|
table: types.filter((t) => t.category === 'table').length,
|
|
18843
19362
|
special: types.filter((t) => t.category === 'special').length,
|
|
18844
19363
|
layout: types.filter((t) => t.category === 'layout').length,
|
|
@@ -18870,11 +19389,11 @@ class WidgetPaletteComponent {
|
|
|
18870
19389
|
this.ref?.close(null);
|
|
18871
19390
|
}
|
|
18872
19391
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WidgetPaletteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18873
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WidgetPaletteComponent, isStandalone: true, selector: "mt-widget-palette", inputs: { product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Content -->\r\n <div class=\"flex flex-col gap-4 p-4\" [class]=\"modal.contentClass\">\r\n <!-- Search -->\r\n <mt-text-field\r\n [placeholder]=\"t('widgetPalette.searchPlaceholder')\"\r\n [icon]=\"'general.search-lg'\"\r\n [(value)]=\"searchTerm\"\r\n />\r\n\r\n <!-- Category Tabs -->\r\n <mt-tabs
|
|
19392
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WidgetPaletteComponent, isStandalone: true, selector: "mt-widget-palette", inputs: { product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Content -->\r\n <div class=\"flex flex-col gap-4 p-4\" [class]=\"modal.contentClass\">\r\n <!-- Search -->\r\n <mt-text-field\r\n [placeholder]=\"t('widgetPalette.searchPlaceholder')\"\r\n [icon]=\"'general.search-lg'\"\r\n [(value)]=\"searchTerm\"\r\n />\r\n\r\n <!-- Category Tabs -->\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n size=\"small\"\r\n fluid\r\n />\r\n\r\n <!-- Widgets Grid -->\r\n <div class=\"flex-1 overflow-y-auto\">\r\n <div class=\"grid grid-cols-3 gap-3\">\r\n @for (widget of widgets(); track widget.id) {\r\n <div\r\n class=\"flex flex-col items-center justify-center gap-2 p-4 rounded-lg cursor-pointer border border-surface-200 bg-white select-none transition-all hover:border-primary-400 hover:shadow-md hover:bg-primary-50\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (click)=\"onWidgetClick(widget)\"\r\n [title]=\"widget.name\"\r\n >\r\n <div\r\n class=\"w-10 h-10 flex items-center justify-center text-primary-500\"\r\n >\r\n <mt-icon [icon]=\"widget.icon\" class=\"text-2xl\" />\r\n </div>\r\n <span\r\n class=\"text-xs font-medium text-color text-center leading-tight\"\r\n >{{ widget.name }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (widgets().length === 0) {\r\n <div class=\"p-8 text-center text-muted-color\">\r\n <mt-icon icon=\"general.search-lg\" class=\"text-3xl mb-2\" />\r\n <p>{{ t(\"widgetPalette.noResults\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hint -->\r\n <div\r\n class=\"text-xs text-muted-color text-center py-2 border-t border-surface-200\"\r\n >\r\n {{ t(\"widgetPalette.dragHint\") }}\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n (onClick)=\"close()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18874
19393
|
}
|
|
18875
19394
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WidgetPaletteComponent, decorators: [{
|
|
18876
19395
|
type: Component,
|
|
18877
|
-
args: [{ selector: 'mt-widget-palette', standalone: true, imports: [TranslocoDirective, Button, TextField, Tabs, Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Content -->\r\n <div class=\"flex flex-col gap-4 p-4\" [class]=\"modal.contentClass\">\r\n <!-- Search -->\r\n <mt-text-field\r\n [placeholder]=\"t('widgetPalette.searchPlaceholder')\"\r\n [icon]=\"'general.search-lg'\"\r\n [(value)]=\"searchTerm\"\r\n />\r\n\r\n <!-- Category Tabs -->\r\n <mt-tabs
|
|
19396
|
+
args: [{ selector: 'mt-widget-palette', standalone: true, imports: [TranslocoDirective, Button, TextField, Tabs, Icon], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Content -->\r\n <div class=\"flex flex-col gap-4 p-4\" [class]=\"modal.contentClass\">\r\n <!-- Search -->\r\n <mt-text-field\r\n [placeholder]=\"t('widgetPalette.searchPlaceholder')\"\r\n [icon]=\"'general.search-lg'\"\r\n [(value)]=\"searchTerm\"\r\n />\r\n\r\n <!-- Category Tabs -->\r\n <mt-tabs\r\n [(active)]=\"activeTab\"\r\n [options]=\"tabOptions()\"\r\n size=\"small\"\r\n fluid\r\n />\r\n\r\n <!-- Widgets Grid -->\r\n <div class=\"flex-1 overflow-y-auto\">\r\n <div class=\"grid grid-cols-3 gap-3\">\r\n @for (widget of widgets(); track widget.id) {\r\n <div\r\n class=\"flex flex-col items-center justify-center gap-2 p-4 rounded-lg cursor-pointer border border-surface-200 bg-white select-none transition-all hover:border-primary-400 hover:shadow-md hover:bg-primary-50\"\r\n draggable=\"true\"\r\n (dragstart)=\"onDragStart($event, widget)\"\r\n (click)=\"onWidgetClick(widget)\"\r\n [title]=\"widget.name\"\r\n >\r\n <div\r\n class=\"w-10 h-10 flex items-center justify-center text-primary-500\"\r\n >\r\n <mt-icon [icon]=\"widget.icon\" class=\"text-2xl\" />\r\n </div>\r\n <span\r\n class=\"text-xs font-medium text-color text-center leading-tight\"\r\n >{{ widget.name }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (widgets().length === 0) {\r\n <div class=\"p-8 text-center text-muted-color\">\r\n <mt-icon icon=\"general.search-lg\" class=\"text-3xl mb-2\" />\r\n <p>{{ t(\"widgetPalette.noResults\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hint -->\r\n <div\r\n class=\"text-xs text-muted-color text-center py-2 border-t border-surface-200\"\r\n >\r\n {{ t(\"widgetPalette.dragHint\") }}\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div [class]=\"modal.footerClass\">\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n (onClick)=\"close()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
|
|
18878
19397
|
}], propDecorators: { product: [{ type: i0.Input, args: [{ isSignal: true, alias: "product", required: false }] }] } });
|
|
18879
19398
|
|
|
18880
19399
|
/**
|
|
@@ -18907,6 +19426,8 @@ class DashboardBuilder {
|
|
|
18907
19426
|
pageId = input(null, ...(ngDevMode ? [{ debugName: "pageId" }] : []));
|
|
18908
19427
|
/** Standalone mode (when true, builder runs without API calls) */
|
|
18909
19428
|
standalone = input(false, ...(ngDevMode ? [{ debugName: "standalone" }] : []));
|
|
19429
|
+
/** Optional services filter used by manage-item metadata tree loading */
|
|
19430
|
+
services = input(null, ...(ngDevMode ? [{ debugName: "services" }] : []));
|
|
18910
19431
|
/** Standalone dashboard data model */
|
|
18911
19432
|
dashboardData = model(null, ...(ngDevMode ? [{ debugName: "dashboardData" }] : []));
|
|
18912
19433
|
/** Read-only mode */
|
|
@@ -19027,6 +19548,9 @@ class DashboardBuilder {
|
|
|
19027
19548
|
dragStartY = 0;
|
|
19028
19549
|
applyingDashboardData = false;
|
|
19029
19550
|
emittingDashboardData = false;
|
|
19551
|
+
boundHandleDragOver = (event) => this.handleDragOver(event);
|
|
19552
|
+
boundHandleDrop = (event) => this.handleDrop(event);
|
|
19553
|
+
boundHandleDragEnd = (event) => this.handleDragEnd(event);
|
|
19030
19554
|
// ============================================
|
|
19031
19555
|
// Context Menu Items
|
|
19032
19556
|
// ============================================
|
|
@@ -19076,14 +19600,14 @@ class DashboardBuilder {
|
|
|
19076
19600
|
this.storeService.updateStopActions(false);
|
|
19077
19601
|
}
|
|
19078
19602
|
setupEventListeners() {
|
|
19079
|
-
window.addEventListener('dragover', this.
|
|
19080
|
-
window.addEventListener('drop', this.
|
|
19081
|
-
window.addEventListener('dragend', this.
|
|
19603
|
+
window.addEventListener('dragover', this.boundHandleDragOver);
|
|
19604
|
+
window.addEventListener('drop', this.boundHandleDrop);
|
|
19605
|
+
window.addEventListener('dragend', this.boundHandleDragEnd);
|
|
19082
19606
|
}
|
|
19083
19607
|
removeEventListeners() {
|
|
19084
|
-
window.removeEventListener('dragover', this.
|
|
19085
|
-
window.removeEventListener('drop', this.
|
|
19086
|
-
window.removeEventListener('dragend', this.
|
|
19608
|
+
window.removeEventListener('dragover', this.boundHandleDragOver);
|
|
19609
|
+
window.removeEventListener('drop', this.boundHandleDrop);
|
|
19610
|
+
window.removeEventListener('dragend', this.boundHandleDragEnd);
|
|
19087
19611
|
}
|
|
19088
19612
|
loadPageIfNeeded() {
|
|
19089
19613
|
if (this.standalone()) {
|
|
@@ -19392,7 +19916,10 @@ class DashboardBuilder {
|
|
|
19392
19916
|
position: 'end',
|
|
19393
19917
|
dismissible: true,
|
|
19394
19918
|
inputValues: {
|
|
19395
|
-
data: {
|
|
19919
|
+
data: {
|
|
19920
|
+
isNew: true,
|
|
19921
|
+
services: this.services(),
|
|
19922
|
+
},
|
|
19396
19923
|
},
|
|
19397
19924
|
});
|
|
19398
19925
|
ref.onClose.subscribe((result) => {
|
|
@@ -19411,7 +19938,12 @@ class DashboardBuilder {
|
|
|
19411
19938
|
dismissible: true,
|
|
19412
19939
|
position: 'end',
|
|
19413
19940
|
inputValues: {
|
|
19414
|
-
data: {
|
|
19941
|
+
data: {
|
|
19942
|
+
chart,
|
|
19943
|
+
isDialog: false,
|
|
19944
|
+
isNew: false,
|
|
19945
|
+
services: this.services(),
|
|
19946
|
+
},
|
|
19415
19947
|
},
|
|
19416
19948
|
});
|
|
19417
19949
|
ref.onClose.subscribe((result) => {
|
|
@@ -19609,7 +20141,7 @@ class DashboardBuilder {
|
|
|
19609
20141
|
header: this.transloco.translate('dashboardBuilder.widgetPalette.title'),
|
|
19610
20142
|
styleClass: '!w-1/3 !absolute',
|
|
19611
20143
|
dismissible: true,
|
|
19612
|
-
modal:
|
|
20144
|
+
modal: true,
|
|
19613
20145
|
appendTo: '#page-content',
|
|
19614
20146
|
});
|
|
19615
20147
|
this.widgetPaletteRef.onClose.subscribe((result) => {
|
|
@@ -19674,6 +20206,7 @@ class DashboardBuilder {
|
|
|
19674
20206
|
isNew: true,
|
|
19675
20207
|
chartType: widgetType, // Pass the pre-selected type
|
|
19676
20208
|
defaultSize: widgetType.defaultSize,
|
|
20209
|
+
services: this.services(),
|
|
19677
20210
|
},
|
|
19678
20211
|
},
|
|
19679
20212
|
});
|
|
@@ -19820,6 +20353,7 @@ class DashboardBuilder {
|
|
|
19820
20353
|
},
|
|
19821
20354
|
isDialog: true,
|
|
19822
20355
|
isNew: false,
|
|
20356
|
+
services: this.services(),
|
|
19823
20357
|
},
|
|
19824
20358
|
},
|
|
19825
20359
|
});
|
|
@@ -20042,7 +20576,7 @@ class DashboardBuilder {
|
|
|
20042
20576
|
this.emittingDashboardData = false;
|
|
20043
20577
|
}
|
|
20044
20578
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20045
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardBuilder, isStandalone: true, selector: "mt-dashboard-builder", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, backButton: { classPropertyName: "backButton", publicName: "backButton", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null }, standalone: { classPropertyName: "standalone", publicName: "standalone", isSignal: true, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardData: "dashboardDataChange", pageChange: "pageChange", chartsChange: "chartsChange", onSave: "onSave", onBack: "onBack", onAddChart: "onAddChart", onEditChart: "onEditChart" }, host: { listeners: { "window:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["contextMenu"], descendants: true, isSignal: true }, { propertyName: "gridsterContainer", first: true, predicate: ["gridsterContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Shared Actions Template -->\r\n <ng-template #actionsTemplate let-inPage=\"inPage\">\r\n <mt-button\r\n [label]=\"t('addWidget')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"toggleWidgetPalette()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"saving()\"\r\n (onClick)=\"saveDash()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <span [class]=\"'w-px h-5 bg-surface-300'\"></span>\r\n\r\n <mt-button\r\n [icon]=\"stopActionsOnCards() ? 'media.play' : 'media.stop'\"\r\n [tooltip]=\"stopActionsOnCards() ? t('activateActions') : t('stopActions')\"\r\n (onClick)=\"stopAndActiveActions()\"\r\n [severity]=\"'warn'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('pageSettings')\"\r\n (onClick)=\"addOrEditPage(pageConfig()!)\"\r\n [severity]=\"'help'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.filter-lines\"\r\n [tooltip]=\"t('manageFilter')\"\r\n (onClick)=\"openManageFilter()\"\r\n [severity]=\"'info'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('builder')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n <div class=\"flex items-center gap-2\">\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: true }\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n }\r\n\r\n <!-- Reusable builder content template -->\r\n <ng-template #builderContent>\r\n <div class=\"relative h-full min-h-[600px]\">\r\n <!-- Loading State -->\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-64\">\r\n <i class=\"mti mti-spinner-third mti-spin text-4xl text-primary\"></i>\r\n </div>\r\n }\r\n\r\n <!-- Main Content -->\r\n @if (!loading() && pageConfig()) {\r\n <!-- Fixed Actions Bar (only when NOT page mode) -->\r\n @if (!isPage()) {\r\n <div\r\n class=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 bg-surface-0 rounded-full shadow-lg px-4 py-2 border border-surface-200\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: false }\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Gridster Container -->\r\n <gridster\r\n #gridsterContainer\r\n [options]=\"options\"\r\n class=\"h-full min-h-[500px] bg-surface-50!\"\r\n [class.is-page]=\"isPage()\"\r\n [class.pointer-events-none]=\"readonly()\"\r\n (dragover)=\"onGridDragOver($event)\"\r\n (drop)=\"onGridDrop($event)\"\r\n >\r\n @for (chart of charts() | filterByGroup: undefined; track $index) {\r\n <gridster-item\r\n [item]=\"chart\"\r\n class=\"bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden transition-all duration-200 hover:shadow-md hover:border-surface-300\"\r\n [class.ring-2]=\"isSelected(chart)\"\r\n [class.ring-primary]=\"isSelected(chart)\"\r\n [class.ring-offset-2]=\"isSelected(chart)\"\r\n (click)=\"onSelect(chart, $event)\"\r\n >\r\n <!-- Chart Content -->\r\n <div class=\"h-full w-full relative group\">\r\n <!-- Drag Handle -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"drag-handler absolute top-0 left-0 right-0 h-6 cursor-move bg-gradient-to-b from-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center z-10\"\r\n >\r\n <i\r\n class=\"mti mti-grip-horizontal text-white/70 text-sm\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Action Buttons -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"absolute top-1 right-1 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20\"\r\n >\r\n <!-- Quick Manage Button -->\r\n @if (showQuickManageButton(chart)) {\r\n <mt-button\r\n icon=\"editor.palette\"\r\n [tooltip]=\"t('quickManage')\"\r\n (onClick)=\"openQuickManage($event, chart)\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Breadcrumb Button (for topbar) -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"topbar\"\r\n ) {\r\n <mt-button\r\n icon=\"general.slash-divider\"\r\n [tooltip]=\"t('manageBreadcrumb')\"\r\n (onClick)=\"openBreadcrumb(chart)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName !== \"header\" &&\r\n chart.config?.clientConfig?.componentName !== \"topbar\" &&\r\n chart.config?.clientConfig?.componentName !== \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('edit')\"\r\n (onClick)=\"editItem(chart)\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('removeGroup')\"\r\n (onClick)=\"removeGroup(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n } @else {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('delete')\"\r\n (onClick)=\"deleteItem(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Advanced/Dialog Actions Button (pipe handles all conditions) -->\r\n @let dialogActions =\r\n chart | getChartActions: chartActionsContext;\r\n @if (dialogActions.length > 0) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n [tooltip]=\"t('advanced')\"\r\n (onClick)=\"advancedPopover.toggle($event)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n <p-popover #advancedPopover appendTo=\"body\">\r\n <div class=\"flex flex-col gap-1 min-w-[160px]\">\r\n @for (action of dialogActions; track action.label) {\r\n <mt-button\r\n [label]=\"action.label\"\r\n [icon]=\"action.icon\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n action.command?.({\r\n originalEvent: $event,\r\n item: action,\r\n });\r\n advancedPopover.hide()\r\n \"\r\n />\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Chart Rendering -->\r\n @if (!chart.loading) {\r\n <mt-dashboard-item\r\n [config]=\"chart.config\"\r\n [chartTypeId]=\"chart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n />\r\n } @else {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <i\r\n class=\"mti mti-spinner-third mti-spin text-2xl text-primary\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Group Children -->\r\n @if (chart.config?.clientConfig?.componentName === \"Group\") {\r\n <div class=\"h-full flex flex-col p-2\">\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n @if (idx === chart.selectedGroupIndex) {\r\n <div class=\"flex-1 min-h-0\">\r\n <mt-dashboard-item\r\n [config]=\"childChart.config\"\r\n [chartTypeId]=\"childChart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Group Tabs -->\r\n <div\r\n class=\"absolute bottom-0 left-0 right-0 flex gap-1 p-1 bg-surface-100 rounded-b-lg overflow-x-auto\"\r\n >\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n <mt-button\r\n [label]=\"\r\n childChart.config?.clientConfig?.title?.[\r\n languageCode()\r\n ] ||\r\n childChart.config?.clientConfig?.title?.['en'] ||\r\n 'Chart ' + (idx + 1)\r\n \"\r\n [severity]=\"\r\n idx === chart.selectedGroupIndex\r\n ? 'primary'\r\n : 'secondary'\r\n \"\r\n [text]=\"idx !== chart.selectedGroupIndex\"\r\n size=\"small\"\r\n (onClick)=\"chart.selectedGroupIndex = idx\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </gridster-item>\r\n }\r\n </gridster>\r\n\r\n <!-- Context Menu -->\r\n <p-contextMenu #contextMenu [model]=\"menuItems()\" appendTo=\"body\" />\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (!loading() && !pageConfig()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}gridster{min-height:calc(100vh - 120px);height:100%}gridster .gridster-column{border-left:1px solid var(--p-primary-100)!important;border-right:1px solid var(--p-primary-100)!important}gridster .gridster-row{border-top:1px solid var(--p-primary-100)!important;border-bottom:1px solid var(--p-primary-100)!important}gridster.is-page{min-height:calc(100vh - 200px)}.mti-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gridster-drop-indicator{position:absolute;background:var(--p-primary-100);border:2px dashed var(--p-primary-400);border-radius:8px;pointer-events:none;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: GridsterModule }, { kind: "component", type: i2$2.GridsterComponent, selector: "gridster", inputs: ["options"] }, { kind: "component", type: i2$2.GridsterItemComponent, selector: "gridster-item", inputs: ["item"], outputs: ["itemInit", "itemChange", "itemResize"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i3$1.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "pipe", type: FilterByGroupPipe, name: "filterByGroup" }, { kind: "pipe", type: GetChartActionsPipe, name: "getChartActions" }], encapsulation: i0.ViewEncapsulation.None });
|
|
20579
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardBuilder, isStandalone: true, selector: "mt-dashboard-builder", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, backButton: { classPropertyName: "backButton", publicName: "backButton", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null }, standalone: { classPropertyName: "standalone", publicName: "standalone", isSignal: true, isRequired: false, transformFunction: null }, services: { classPropertyName: "services", publicName: "services", isSignal: true, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardData: "dashboardDataChange", pageChange: "pageChange", chartsChange: "chartsChange", onSave: "onSave", onBack: "onBack", onAddChart: "onAddChart", onEditChart: "onEditChart" }, host: { listeners: { "window:keydown": "onKeyDown($event)" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["contextMenu"], descendants: true, isSignal: true }, { propertyName: "gridsterContainer", first: true, predicate: ["gridsterContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Shared Actions Template -->\r\n <ng-template #actionsTemplate let-inPage=\"inPage\">\r\n <mt-button\r\n [label]=\"t('addWidget')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"toggleWidgetPalette()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"saving()\"\r\n (onClick)=\"saveDash()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <span [class]=\"'w-px h-5 bg-surface-300'\"></span>\r\n\r\n <mt-button\r\n [icon]=\"stopActionsOnCards() ? 'media.play' : 'media.stop'\"\r\n [tooltip]=\"stopActionsOnCards() ? t('activateActions') : t('stopActions')\"\r\n (onClick)=\"stopAndActiveActions()\"\r\n [severity]=\"'warn'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('pageSettings')\"\r\n (onClick)=\"addOrEditPage(pageConfig()!)\"\r\n [severity]=\"'help'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.filter-lines\"\r\n [tooltip]=\"t('manageFilter')\"\r\n (onClick)=\"openManageFilter()\"\r\n [severity]=\"'info'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('builder')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n <div class=\"flex items-center gap-2\">\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: true }\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n }\r\n\r\n <!-- Reusable builder content template -->\r\n <ng-template #builderContent>\r\n <div class=\"relative h-full min-h-[600px]\">\r\n <!-- Loading State -->\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-64\">\r\n <i class=\"mti mti-spinner-third mti-spin text-4xl text-primary\"></i>\r\n </div>\r\n }\r\n\r\n <!-- Main Content -->\r\n @if (!loading() && pageConfig()) {\r\n <!-- Fixed Actions Bar (only when NOT page mode) -->\r\n @if (!isPage()) {\r\n <div\r\n class=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 bg-surface-0 rounded-full shadow-lg px-4 py-2 border border-surface-200\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: false }\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Gridster Container -->\r\n <gridster\r\n #gridsterContainer\r\n [options]=\"options\"\r\n class=\"h-full min-h-[500px] bg-surface-50!\"\r\n [class.is-page]=\"isPage()\"\r\n [class.pointer-events-none]=\"readonly()\"\r\n (dragover)=\"onGridDragOver($event)\"\r\n (drop)=\"onGridDrop($event)\"\r\n >\r\n @for (chart of charts() | filterByGroup: undefined; track $index) {\r\n <gridster-item\r\n [item]=\"chart\"\r\n class=\"bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden transition-all duration-200 hover:shadow-md hover:border-surface-300\"\r\n [class.ring-2]=\"isSelected(chart)\"\r\n [class.ring-primary]=\"isSelected(chart)\"\r\n [class.ring-offset-2]=\"isSelected(chart)\"\r\n (click)=\"onSelect(chart, $event)\"\r\n >\r\n <!-- Chart Content -->\r\n <div class=\"h-full w-full relative group\">\r\n <!-- Drag Handle -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"drag-handler absolute top-0 left-0 right-0 h-6 cursor-move bg-gradient-to-b from-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center z-10\"\r\n >\r\n <i\r\n class=\"mti mti-grip-horizontal text-white/70 text-sm\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Action Buttons -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"absolute top-1 right-1 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20\"\r\n >\r\n <!-- Quick Manage Button -->\r\n @if (showQuickManageButton(chart)) {\r\n <mt-button\r\n icon=\"editor.palette\"\r\n [tooltip]=\"t('quickManage')\"\r\n (onClick)=\"openQuickManage($event, chart)\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Breadcrumb Button (for topbar) -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"topbar\"\r\n ) {\r\n <mt-button\r\n icon=\"general.slash-divider\"\r\n [tooltip]=\"t('manageBreadcrumb')\"\r\n (onClick)=\"openBreadcrumb(chart)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName !== \"header\" &&\r\n chart.config?.clientConfig?.componentName !== \"topbar\" &&\r\n chart.config?.clientConfig?.componentName !== \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('edit')\"\r\n (onClick)=\"editItem(chart)\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('removeGroup')\"\r\n (onClick)=\"removeGroup(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n } @else {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('delete')\"\r\n (onClick)=\"deleteItem(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Advanced/Dialog Actions Button (pipe handles all conditions) -->\r\n @let dialogActions =\r\n chart | getChartActions: chartActionsContext;\r\n @if (dialogActions.length > 0) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n [tooltip]=\"t('advanced')\"\r\n (onClick)=\"advancedPopover.toggle($event)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n <p-popover #advancedPopover appendTo=\"body\">\r\n <div class=\"flex flex-col gap-1 min-w-[160px]\">\r\n @for (action of dialogActions; track action.label) {\r\n <mt-button\r\n [label]=\"action.label\"\r\n [icon]=\"action.icon\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n action.command?.({\r\n originalEvent: $event,\r\n item: action,\r\n });\r\n advancedPopover.hide()\r\n \"\r\n />\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Chart Rendering -->\r\n @if (!chart.loading) {\r\n <mt-dashboard-item\r\n [config]=\"chart.config\"\r\n [chartTypeId]=\"chart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n } @else {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <i\r\n class=\"mti mti-spinner-third mti-spin text-2xl text-primary\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Group Children -->\r\n @if (chart.config?.clientConfig?.componentName === \"Group\") {\r\n <div class=\"h-full flex flex-col p-2\">\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n @if (idx === chart.selectedGroupIndex) {\r\n <div class=\"flex-1 min-h-0\">\r\n <mt-dashboard-item\r\n [config]=\"childChart.config\"\r\n [chartTypeId]=\"childChart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Group Tabs -->\r\n <div\r\n class=\"absolute bottom-0 left-0 right-0 flex gap-1 p-1 bg-surface-100 rounded-b-lg overflow-x-auto\"\r\n >\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n <mt-button\r\n [label]=\"\r\n childChart.config?.clientConfig?.title?.[\r\n languageCode()\r\n ] ||\r\n childChart.config?.clientConfig?.title?.['en'] ||\r\n 'Chart ' + (idx + 1)\r\n \"\r\n [severity]=\"\r\n idx === chart.selectedGroupIndex\r\n ? 'primary'\r\n : 'secondary'\r\n \"\r\n [text]=\"idx !== chart.selectedGroupIndex\"\r\n size=\"small\"\r\n (onClick)=\"chart.selectedGroupIndex = idx\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </gridster-item>\r\n }\r\n </gridster>\r\n\r\n <!-- Context Menu -->\r\n <p-contextMenu #contextMenu [model]=\"menuItems()\" appendTo=\"body\" />\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (!loading() && !pageConfig()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}gridster{min-height:calc(100vh - 120px);height:100%}gridster .gridster-column{border-left:1px solid var(--p-primary-100)!important;border-right:1px solid var(--p-primary-100)!important}gridster .gridster-row{border-top:1px solid var(--p-primary-100)!important;border-bottom:1px solid var(--p-primary-100)!important}gridster.is-page{min-height:calc(100vh - 200px)}.mti-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gridster-drop-indicator{position:absolute;background:var(--p-primary-100);border:2px dashed var(--p-primary-400);border-radius:8px;pointer-events:none;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: GridsterModule }, { kind: "component", type: i2$2.GridsterComponent, selector: "gridster", inputs: ["options"] }, { kind: "component", type: i2$2.GridsterItemComponent, selector: "gridster-item", inputs: ["item"], outputs: ["itemInit", "itemChange", "itemResize"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i3$1.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "pageName", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "pipe", type: FilterByGroupPipe, name: "filterByGroup" }, { kind: "pipe", type: GetChartActionsPipe, name: "getChartActions" }], encapsulation: i0.ViewEncapsulation.None });
|
|
20046
20580
|
}
|
|
20047
20581
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardBuilder, decorators: [{
|
|
20048
20582
|
type: Component,
|
|
@@ -20052,18 +20586,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
20052
20586
|
TranslocoDirective,
|
|
20053
20587
|
GridsterModule,
|
|
20054
20588
|
Button,
|
|
20055
|
-
Tabs,
|
|
20056
|
-
Card,
|
|
20057
|
-
Tooltip,
|
|
20058
20589
|
Page,
|
|
20059
|
-
Menu,
|
|
20060
20590
|
Popover,
|
|
20061
20591
|
ContextMenuModule,
|
|
20062
20592
|
FilterByGroupPipe,
|
|
20063
20593
|
GetChartActionsPipe,
|
|
20064
20594
|
DashboardItem,
|
|
20065
|
-
], encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Shared Actions Template -->\r\n <ng-template #actionsTemplate let-inPage=\"inPage\">\r\n <mt-button\r\n [label]=\"t('addWidget')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"toggleWidgetPalette()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"saving()\"\r\n (onClick)=\"saveDash()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <span [class]=\"'w-px h-5 bg-surface-300'\"></span>\r\n\r\n <mt-button\r\n [icon]=\"stopActionsOnCards() ? 'media.play' : 'media.stop'\"\r\n [tooltip]=\"stopActionsOnCards() ? t('activateActions') : t('stopActions')\"\r\n (onClick)=\"stopAndActiveActions()\"\r\n [severity]=\"'warn'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('pageSettings')\"\r\n (onClick)=\"addOrEditPage(pageConfig()!)\"\r\n [severity]=\"'help'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.filter-lines\"\r\n [tooltip]=\"t('manageFilter')\"\r\n (onClick)=\"openManageFilter()\"\r\n [severity]=\"'info'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('builder')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n <div class=\"flex items-center gap-2\">\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: true }\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n }\r\n\r\n <!-- Reusable builder content template -->\r\n <ng-template #builderContent>\r\n <div class=\"relative h-full min-h-[600px]\">\r\n <!-- Loading State -->\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-64\">\r\n <i class=\"mti mti-spinner-third mti-spin text-4xl text-primary\"></i>\r\n </div>\r\n }\r\n\r\n <!-- Main Content -->\r\n @if (!loading() && pageConfig()) {\r\n <!-- Fixed Actions Bar (only when NOT page mode) -->\r\n @if (!isPage()) {\r\n <div\r\n class=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 bg-surface-0 rounded-full shadow-lg px-4 py-2 border border-surface-200\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: false }\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Gridster Container -->\r\n <gridster\r\n #gridsterContainer\r\n [options]=\"options\"\r\n class=\"h-full min-h-[500px] bg-surface-50!\"\r\n [class.is-page]=\"isPage()\"\r\n [class.pointer-events-none]=\"readonly()\"\r\n (dragover)=\"onGridDragOver($event)\"\r\n (drop)=\"onGridDrop($event)\"\r\n >\r\n @for (chart of charts() | filterByGroup: undefined; track $index) {\r\n <gridster-item\r\n [item]=\"chart\"\r\n class=\"bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden transition-all duration-200 hover:shadow-md hover:border-surface-300\"\r\n [class.ring-2]=\"isSelected(chart)\"\r\n [class.ring-primary]=\"isSelected(chart)\"\r\n [class.ring-offset-2]=\"isSelected(chart)\"\r\n (click)=\"onSelect(chart, $event)\"\r\n >\r\n <!-- Chart Content -->\r\n <div class=\"h-full w-full relative group\">\r\n <!-- Drag Handle -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"drag-handler absolute top-0 left-0 right-0 h-6 cursor-move bg-gradient-to-b from-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center z-10\"\r\n >\r\n <i\r\n class=\"mti mti-grip-horizontal text-white/70 text-sm\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Action Buttons -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"absolute top-1 right-1 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20\"\r\n >\r\n <!-- Quick Manage Button -->\r\n @if (showQuickManageButton(chart)) {\r\n <mt-button\r\n icon=\"editor.palette\"\r\n [tooltip]=\"t('quickManage')\"\r\n (onClick)=\"openQuickManage($event, chart)\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Breadcrumb Button (for topbar) -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"topbar\"\r\n ) {\r\n <mt-button\r\n icon=\"general.slash-divider\"\r\n [tooltip]=\"t('manageBreadcrumb')\"\r\n (onClick)=\"openBreadcrumb(chart)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName !== \"header\" &&\r\n chart.config?.clientConfig?.componentName !== \"topbar\" &&\r\n chart.config?.clientConfig?.componentName !== \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('edit')\"\r\n (onClick)=\"editItem(chart)\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('removeGroup')\"\r\n (onClick)=\"removeGroup(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n } @else {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('delete')\"\r\n (onClick)=\"deleteItem(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Advanced/Dialog Actions Button (pipe handles all conditions) -->\r\n @let dialogActions =\r\n chart | getChartActions: chartActionsContext;\r\n @if (dialogActions.length > 0) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n [tooltip]=\"t('advanced')\"\r\n (onClick)=\"advancedPopover.toggle($event)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n <p-popover #advancedPopover appendTo=\"body\">\r\n <div class=\"flex flex-col gap-1 min-w-[160px]\">\r\n @for (action of dialogActions; track action.label) {\r\n <mt-button\r\n [label]=\"action.label\"\r\n [icon]=\"action.icon\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n action.command?.({\r\n originalEvent: $event,\r\n item: action,\r\n });\r\n advancedPopover.hide()\r\n \"\r\n />\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Chart Rendering -->\r\n @if (!chart.loading) {\r\n <mt-dashboard-item\r\n [config]=\"chart.config\"\r\n [chartTypeId]=\"chart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n />\r\n } @else {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <i\r\n class=\"mti mti-spinner-third mti-spin text-2xl text-primary\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Group Children -->\r\n @if (chart.config?.clientConfig?.componentName === \"Group\") {\r\n <div class=\"h-full flex flex-col p-2\">\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n @if (idx === chart.selectedGroupIndex) {\r\n <div class=\"flex-1 min-h-0\">\r\n <mt-dashboard-item\r\n [config]=\"childChart.config\"\r\n [chartTypeId]=\"childChart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Group Tabs -->\r\n <div\r\n class=\"absolute bottom-0 left-0 right-0 flex gap-1 p-1 bg-surface-100 rounded-b-lg overflow-x-auto\"\r\n >\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n <mt-button\r\n [label]=\"\r\n childChart.config?.clientConfig?.title?.[\r\n languageCode()\r\n ] ||\r\n childChart.config?.clientConfig?.title?.['en'] ||\r\n 'Chart ' + (idx + 1)\r\n \"\r\n [severity]=\"\r\n idx === chart.selectedGroupIndex\r\n ? 'primary'\r\n : 'secondary'\r\n \"\r\n [text]=\"idx !== chart.selectedGroupIndex\"\r\n size=\"small\"\r\n (onClick)=\"chart.selectedGroupIndex = idx\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </gridster-item>\r\n }\r\n </gridster>\r\n\r\n <!-- Context Menu -->\r\n <p-contextMenu #contextMenu [model]=\"menuItems()\" appendTo=\"body\" />\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (!loading() && !pageConfig()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}gridster{min-height:calc(100vh - 120px);height:100%}gridster .gridster-column{border-left:1px solid var(--p-primary-100)!important;border-right:1px solid var(--p-primary-100)!important}gridster .gridster-row{border-top:1px solid var(--p-primary-100)!important;border-bottom:1px solid var(--p-primary-100)!important}gridster.is-page{min-height:calc(100vh - 200px)}.mti-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gridster-drop-indicator{position:absolute;background:var(--p-primary-100);border:2px dashed var(--p-primary-400);border-radius:8px;pointer-events:none;z-index:100}\n"] }]
|
|
20066
|
-
}], ctorParameters: () => [], propDecorators: { isPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPage", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], backButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "backButton", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }], standalone: [{ type: i0.Input, args: [{ isSignal: true, alias: "standalone", required: false }] }], dashboardData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardData", required: false }] }, { type: i0.Output, args: ["dashboardDataChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], chartsChange: [{ type: i0.Output, args: ["chartsChange"] }], onSave: [{ type: i0.Output, args: ["onSave"] }], onBack: [{ type: i0.Output, args: ["onBack"] }], onAddChart: [{ type: i0.Output, args: ["onAddChart"] }], onEditChart: [{ type: i0.Output, args: ["onEditChart"] }], contextMenu: [{ type: i0.ViewChild, args: ['contextMenu', { isSignal: true }] }], gridsterContainer: [{ type: i0.ViewChild, args: ['gridsterContainer', { isSignal: true }] }], onKeyDown: [{
|
|
20595
|
+
], encapsulation: ViewEncapsulation.None, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Shared Actions Template -->\r\n <ng-template #actionsTemplate let-inPage=\"inPage\">\r\n <mt-button\r\n [label]=\"t('addWidget')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"toggleWidgetPalette()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n [label]=\"t('save')\"\r\n icon=\"general.save-02\"\r\n [loading]=\"saving()\"\r\n [disabled]=\"saving()\"\r\n (onClick)=\"saveDash()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <span [class]=\"'w-px h-5 bg-surface-300'\"></span>\r\n\r\n <mt-button\r\n [icon]=\"stopActionsOnCards() ? 'media.play' : 'media.stop'\"\r\n [tooltip]=\"stopActionsOnCards() ? t('activateActions') : t('stopActions')\"\r\n (onClick)=\"stopAndActiveActions()\"\r\n [severity]=\"'warn'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('pageSettings')\"\r\n (onClick)=\"addOrEditPage(pageConfig()!)\"\r\n [severity]=\"'help'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n\r\n <mt-button\r\n icon=\"general.filter-lines\"\r\n [tooltip]=\"t('manageFilter')\"\r\n (onClick)=\"openManageFilter()\"\r\n [severity]=\"'info'\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [rounded]=\"!inPage\"\r\n />\r\n </ng-template>\r\n\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('builder')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n <div class=\"flex items-center gap-2\">\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: true }\"\r\n />\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"builderContent\" />\r\n }\r\n\r\n <!-- Reusable builder content template -->\r\n <ng-template #builderContent>\r\n <div class=\"relative h-full min-h-[600px]\">\r\n <!-- Loading State -->\r\n @if (loading()) {\r\n <div class=\"flex items-center justify-center h-64\">\r\n <i class=\"mti mti-spinner-third mti-spin text-4xl text-primary\"></i>\r\n </div>\r\n }\r\n\r\n <!-- Main Content -->\r\n @if (!loading() && pageConfig()) {\r\n <!-- Fixed Actions Bar (only when NOT page mode) -->\r\n @if (!isPage()) {\r\n <div\r\n class=\"fixed bottom-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 bg-surface-0 rounded-full shadow-lg px-4 py-2 border border-surface-200\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"actionsTemplate; context: { inPage: false }\"\r\n />\r\n </div>\r\n }\r\n\r\n <!-- Gridster Container -->\r\n <gridster\r\n #gridsterContainer\r\n [options]=\"options\"\r\n class=\"h-full min-h-[500px] bg-surface-50!\"\r\n [class.is-page]=\"isPage()\"\r\n [class.pointer-events-none]=\"readonly()\"\r\n (dragover)=\"onGridDragOver($event)\"\r\n (drop)=\"onGridDrop($event)\"\r\n >\r\n @for (chart of charts() | filterByGroup: undefined; track $index) {\r\n <gridster-item\r\n [item]=\"chart\"\r\n class=\"bg-surface-0 rounded-lg shadow-sm border border-surface-200 overflow-hidden transition-all duration-200 hover:shadow-md hover:border-surface-300\"\r\n [class.ring-2]=\"isSelected(chart)\"\r\n [class.ring-primary]=\"isSelected(chart)\"\r\n [class.ring-offset-2]=\"isSelected(chart)\"\r\n (click)=\"onSelect(chart, $event)\"\r\n >\r\n <!-- Chart Content -->\r\n <div class=\"h-full w-full relative group\">\r\n <!-- Drag Handle -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"drag-handler absolute top-0 left-0 right-0 h-6 cursor-move bg-gradient-to-b from-black/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center z-10\"\r\n >\r\n <i\r\n class=\"mti mti-grip-horizontal text-white/70 text-sm\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Action Buttons -->\r\n @if (!readonly()) {\r\n <div\r\n class=\"absolute top-1 right-1 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20\"\r\n >\r\n <!-- Quick Manage Button -->\r\n @if (showQuickManageButton(chart)) {\r\n <mt-button\r\n icon=\"editor.palette\"\r\n [tooltip]=\"t('quickManage')\"\r\n (onClick)=\"openQuickManage($event, chart)\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Breadcrumb Button (for topbar) -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"topbar\"\r\n ) {\r\n <mt-button\r\n icon=\"general.slash-divider\"\r\n [tooltip]=\"t('manageBreadcrumb')\"\r\n (onClick)=\"openBreadcrumb(chart)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Edit Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName !== \"header\" &&\r\n chart.config?.clientConfig?.componentName !== \"topbar\" &&\r\n chart.config?.clientConfig?.componentName !== \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.edit-05\"\r\n [tooltip]=\"t('edit')\"\r\n (onClick)=\"editItem(chart)\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Delete Button -->\r\n @if (\r\n chart.config?.clientConfig?.componentName === \"Group\"\r\n ) {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('removeGroup')\"\r\n (onClick)=\"removeGroup(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n } @else {\r\n <mt-button\r\n icon=\"general.trash-01\"\r\n [tooltip]=\"t('delete')\"\r\n (onClick)=\"deleteItem(chart)\"\r\n severity=\"danger\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n }\r\n\r\n <!-- Advanced/Dialog Actions Button (pipe handles all conditions) -->\r\n @let dialogActions =\r\n chart | getChartActions: chartActionsContext;\r\n @if (dialogActions.length > 0) {\r\n <mt-button\r\n icon=\"general.dots-vertical\"\r\n [tooltip]=\"t('advanced')\"\r\n (onClick)=\"advancedPopover.toggle($event)\"\r\n severity=\"info\"\r\n size=\"small\"\r\n [rounded]=\"true\"\r\n />\r\n <p-popover #advancedPopover appendTo=\"body\">\r\n <div class=\"flex flex-col gap-1 min-w-[160px]\">\r\n @for (action of dialogActions; track action.label) {\r\n <mt-button\r\n [label]=\"action.label\"\r\n [icon]=\"action.icon\"\r\n severity=\"secondary\"\r\n [text]=\"true\"\r\n size=\"small\"\r\n (onClick)=\"\r\n action.command?.({\r\n originalEvent: $event,\r\n item: action,\r\n });\r\n advancedPopover.hide()\r\n \"\r\n />\r\n }\r\n </div>\r\n </p-popover>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Chart Rendering -->\r\n @if (!chart.loading) {\r\n <mt-dashboard-item\r\n [config]=\"chart.config\"\r\n [chartTypeId]=\"chart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n } @else {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <i\r\n class=\"mti mti-spinner-third mti-spin text-2xl text-primary\"\r\n ></i>\r\n </div>\r\n }\r\n\r\n <!-- Group Children -->\r\n @if (chart.config?.clientConfig?.componentName === \"Group\") {\r\n <div class=\"h-full flex flex-col p-2\">\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n @if (idx === chart.selectedGroupIndex) {\r\n <div class=\"flex-1 min-h-0\">\r\n <mt-dashboard-item\r\n [config]=\"childChart.config\"\r\n [chartTypeId]=\"childChart.chartTypeId\"\r\n [readonly]=\"readonly()\"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n />\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Group Tabs -->\r\n <div\r\n class=\"absolute bottom-0 left-0 right-0 flex gap-1 p-1 bg-surface-100 rounded-b-lg overflow-x-auto\"\r\n >\r\n @for (\r\n childChart of charts()\r\n | filterByGroup\r\n : chart.config?.serviceConfig?.dashboardId;\r\n track childChart.config?.serviceConfig?.dashboardId;\r\n let idx = $index\r\n ) {\r\n <mt-button\r\n [label]=\"\r\n childChart.config?.clientConfig?.title?.[\r\n languageCode()\r\n ] ||\r\n childChart.config?.clientConfig?.title?.['en'] ||\r\n 'Chart ' + (idx + 1)\r\n \"\r\n [severity]=\"\r\n idx === chart.selectedGroupIndex\r\n ? 'primary'\r\n : 'secondary'\r\n \"\r\n [text]=\"idx !== chart.selectedGroupIndex\"\r\n size=\"small\"\r\n (onClick)=\"chart.selectedGroupIndex = idx\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </gridster-item>\r\n }\r\n </gridster>\r\n\r\n <!-- Context Menu -->\r\n <p-contextMenu #contextMenu [model]=\"menuItems()\" appendTo=\"body\" />\r\n }\r\n\r\n <!-- Empty State -->\r\n @if (!loading() && !pageConfig()) {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [":host{display:block;height:100%}gridster{min-height:calc(100vh - 120px);height:100%}gridster .gridster-column{border-left:1px solid var(--p-primary-100)!important;border-right:1px solid var(--p-primary-100)!important}gridster .gridster-row{border-top:1px solid var(--p-primary-100)!important;border-bottom:1px solid var(--p-primary-100)!important}gridster.is-page{min-height:calc(100vh - 200px)}.mti-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gridster-drop-indicator{position:absolute;background:var(--p-primary-100);border:2px dashed var(--p-primary-400);border-radius:8px;pointer-events:none;z-index:100}\n"] }]
|
|
20596
|
+
}], ctorParameters: () => [], propDecorators: { isPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPage", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], backButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "backButton", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }], standalone: [{ type: i0.Input, args: [{ isSignal: true, alias: "standalone", required: false }] }], services: [{ type: i0.Input, args: [{ isSignal: true, alias: "services", required: false }] }], dashboardData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardData", required: false }] }, { type: i0.Output, args: ["dashboardDataChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], chartsChange: [{ type: i0.Output, args: ["chartsChange"] }], onSave: [{ type: i0.Output, args: ["onSave"] }], onBack: [{ type: i0.Output, args: ["onBack"] }], onAddChart: [{ type: i0.Output, args: ["onAddChart"] }], onEditChart: [{ type: i0.Output, args: ["onEditChart"] }], contextMenu: [{ type: i0.ViewChild, args: ['contextMenu', { isSignal: true }] }], gridsterContainer: [{ type: i0.ViewChild, args: ['gridsterContainer', { isSignal: true }] }], onKeyDown: [{
|
|
20067
20597
|
type: HostListener,
|
|
20068
20598
|
args: ['window:keydown', ['$event']]
|
|
20069
20599
|
}] } });
|
|
@@ -20405,12 +20935,6 @@ class DashboardViewer {
|
|
|
20405
20935
|
getItemIcon(item) {
|
|
20406
20936
|
return item.config?.clientConfig?.configAsType?.icon || null;
|
|
20407
20937
|
}
|
|
20408
|
-
/**
|
|
20409
|
-
* Get breadcrumb items for topbar
|
|
20410
|
-
*/
|
|
20411
|
-
getBreadcrumb(item) {
|
|
20412
|
-
return item.config?.clientConfig?.configAsType?.breadcrumb || [];
|
|
20413
|
-
}
|
|
20414
20938
|
/**
|
|
20415
20939
|
* Get chart type
|
|
20416
20940
|
*/
|
|
@@ -20454,7 +20978,7 @@ class DashboardViewer {
|
|
|
20454
20978
|
});
|
|
20455
20979
|
}
|
|
20456
20980
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20457
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardViewer, isStandalone: true, selector: "mt-dashboard-viewer", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, backButton: { classPropertyName: "backButton", publicName: "backButton", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, chartsData: { classPropertyName: "chartsData", publicName: "chartsData", isSignal: true, isRequired: false, transformFunction: null }, dialogsData: { classPropertyName: "dialogsData", publicName: "dialogsData", isSignal: true, isRequired: false, transformFunction: null }, filtersData: { classPropertyName: "filtersData", publicName: "filtersData", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, showFilters: { classPropertyName: "showFilters", publicName: "showFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageLoaded: "pageLoaded", onBack: "onBack", chartClick: "chartClick" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig\r\n ?.ignoreQueryFilter ?? false\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20981
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardViewer, isStandalone: true, selector: "mt-dashboard-viewer", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, backButton: { classPropertyName: "backButton", publicName: "backButton", isSignal: true, isRequired: false, transformFunction: null }, pageId: { classPropertyName: "pageId", publicName: "pageId", isSignal: true, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: false, transformFunction: null }, chartsData: { classPropertyName: "chartsData", publicName: "chartsData", isSignal: true, isRequired: false, transformFunction: null }, dialogsData: { classPropertyName: "dialogsData", publicName: "dialogsData", isSignal: true, isRequired: false, transformFunction: null }, filtersData: { classPropertyName: "filtersData", publicName: "filtersData", isSignal: true, isRequired: false, transformFunction: null }, extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: true, isRequired: false, transformFunction: null }, showFilters: { classPropertyName: "showFilters", publicName: "showFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageLoaded: "pageLoaded", onBack: "onBack", chartClick: "chartClick" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig\r\n ?.ignoreQueryFilter ?? false\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: DashboardItem, selector: "mt-dashboard-item", inputs: ["config", "chartTypeId", "readonly", "pageName", "inGroup", "isDialog", "queryParams", "extraFilters", "ignoreQueryFilter"], outputs: ["actionTriggered"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20458
20982
|
}
|
|
20459
20983
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardViewer, decorators: [{
|
|
20460
20984
|
type: Component,
|
|
@@ -20464,7 +20988,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
20464
20988
|
ButtonModule,
|
|
20465
20989
|
DashboardItem,
|
|
20466
20990
|
Page,
|
|
20467
|
-
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig\r\n ?.ignoreQueryFilter ?? false\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"header-item flex items-center h-full px-4 border-b-2 border-primary\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'transparent'\r\n \"\r\n [style.color]=\"getStyleConfig(item)['color'] || 'inherit'\"\r\n >\r\n <h3 class=\"font-semibold text-lg m-0\">\r\n {{ getItemTitle(item) }}\r\n </h3>\r\n </div>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"topbar-item flex items-center h-full px-4 bg-surface-50\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-50)'\r\n \"\r\n >\r\n <nav class=\"flex items-center gap-2 text-sm\">\r\n @for (\r\n crumb of getBreadcrumb(item);\r\n track $index;\r\n let last = $last\r\n ) {\r\n <span\r\n class=\"text-muted-color hover:text-primary cursor-pointer transition-colors\"\r\n >\r\n {{\r\n crumb.label?.[languageCode()] ||\r\n crumb.label?.[\"en\"] ||\r\n crumb.label\r\n }}\r\n </span>\r\n @if (!last) {\r\n <i\r\n class=\"mti mti-chevron-right text-xs text-muted-color\"\r\n ></i>\r\n }\r\n }\r\n @if (getBreadcrumb(item).length === 0) {\r\n <span class=\"text-muted-color italic\">{{\r\n t(\"noBreadcrumb\")\r\n }}</span>\r\n }\r\n </nav>\r\n </div>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"] }]
|
|
20991
|
+
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page\r\n [title]=\"\r\n pageTitle() ||\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n t('dashboard')\r\n \"\r\n [backButton]=\"backButton()\"\r\n (backButtonClick)=\"onBack.emit()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <ng-container *ngTemplateOutlet=\"viewerContent\" />\r\n }\r\n\r\n <!-- Reusable viewer content template -->\r\n <ng-template #viewerContent>\r\n <div class=\"relative h-full min-h-[600px] mt-dashboard-viewer\">\r\n @if (!loading() && hasRenderableContent()) {\r\n <div class=\"dashboard-viewer-layout-wrapper\">\r\n <div\r\n class=\"dashboard-viewer-layout\"\r\n [style.min-height]=\"layoutHeight()\"\r\n >\r\n @for (\r\n item of visibleItems();\r\n track trackByDashboardId($index, item)\r\n ) {\r\n <div\r\n class=\"dashboard-viewer-item\"\r\n [class.dashboard-viewer-item--group]=\"isGroup(item)\"\r\n [class.dashboard-viewer-item--header]=\"isHeader(item)\"\r\n [class.dashboard-viewer-item--topbar]=\"isTopbar(item)\"\r\n [style.grid-column]=\"getGridColumn(item)\"\r\n [style.grid-row]=\"getGridRow(item)\"\r\n >\r\n <!-- Group Container -->\r\n @if (isGroup(item)) {\r\n @if (!item.loading) {\r\n <div\r\n class=\"group-container h-full flex flex-col rounded-lg border border-surface-200 overflow-hidden\"\r\n [style.background-color]=\"\r\n getStyleConfig(item)['background-color'] ||\r\n 'var(--surface-card)'\r\n \"\r\n >\r\n <!-- Group Header with Tabs -->\r\n <div\r\n class=\"group-header flex items-center justify-between px-4 py-2 bg-surface-50 border-b border-surface-200\"\r\n >\r\n <span class=\"font-medium text-sm\">{{\r\n getGroupTitle(item)\r\n }}</span>\r\n <div class=\"group-tabs flex items-center gap-1\">\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let gIndex = $index\r\n ) {\r\n @if (getItemIcon(child); as icon) {\r\n <button\r\n type=\"button\"\r\n class=\"w-8 h-8 flex items-center justify-center rounded transition-colors\"\r\n [class.bg-primary-100]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-primary-600]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.text-muted-color]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [class.hover:bg-surface-100]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n >\r\n <i class=\"mti mti-{{ icon }}\"></i>\r\n </button>\r\n } @else {\r\n <button\r\n pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-sm\"\r\n [class.p-button-primary]=\"\r\n item.selectedGroupIndex === gIndex\r\n \"\r\n [class.p-button-secondary]=\"\r\n item.selectedGroupIndex !== gIndex\r\n \"\r\n [label]=\"getItemTitle(child)\"\r\n (click)=\"selectGroupChild(item, gIndex)\"\r\n ></button>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Group Body - Selected Child Content -->\r\n <div class=\"group-body flex-1 min-h-0\">\r\n @if (\r\n item.selectedGroupIndex !== null &&\r\n item.selectedGroupIndex !== undefined\r\n ) {\r\n @for (\r\n child of getGroupChildren(item);\r\n track child.config?.serviceConfig?.dashboardId;\r\n let cIndex = $index\r\n ) {\r\n @if (\r\n cIndex === item.selectedGroupIndex &&\r\n !child.loading\r\n ) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"child.config\"\r\n [chartTypeId]=\"\r\n child.config?.serviceConfig?.dashboardId ||\r\n child.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig\r\n ?.ignoreQueryFilter ?? false\r\n \"\r\n [inGroup]=\"true\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n <!-- Header Item -->\r\n @else if (isHeader(item)) {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n <!-- Topbar Item -->\r\n @else if (isTopbar(item)) {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n <!-- Regular Chart Item -->\r\n @else {\r\n @if (!item.loading) {\r\n <mt-dashboard-item\r\n class=\"dashboard-viewer-content-item\"\r\n [config]=\"item.config\"\r\n [chartTypeId]=\"\r\n item.config?.serviceConfig?.dashboardId || item.id\r\n \"\r\n [pageName]=\"\r\n pageConfig()?.name?.[languageCode()] ||\r\n pageConfig()?.name?.['en'] ||\r\n pageConfig()?.name?.['ar'] ||\r\n ''\r\n \"\r\n [extraFilters]=\"extraFilters()\"\r\n [ignoreQueryFilter]=\"\r\n pageConfig()?.dashboardConfig?.ignoreQueryFilter ??\r\n false\r\n \"\r\n [inGroup]=\"false\"\r\n >\r\n </mt-dashboard-item>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden Dialogs (for modal rendering) -->\r\n @if (dialogs().length > 0) {\r\n <div class=\"hidden\">\r\n @for (\r\n dialog of dialogs();\r\n track dialog.config?.serviceConfig?.dashboardId\r\n ) {\r\n <!-- Dialog placeholder - will be rendered in modal when triggered -->\r\n <div\r\n [attr.data-dialog-id]=\"\r\n dialog.config?.serviceConfig?.dashboardId\r\n \"\r\n ></div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Filters Sidebar Placeholder -->\r\n @if (showFilters() && filters().length > 0) {\r\n <div\r\n class=\"filters-sidebar fixed end-0 top-0 bottom-0 w-64 bg-surface-card border-s border-surface-200 p-4 shadow-lg z-50 hidden\"\r\n >\r\n <!-- Filter sidebar content - integrate with actual filter component -->\r\n <h4 class=\"font-semibold mb-4\">{{ t(\"filters\") }}</h4>\r\n @for (filter of filters(); track $index) {\r\n <div class=\"filter-item mb-3 p-2 bg-surface-50 rounded\">\r\n <span class=\"text-sm\">{{\r\n filter.label || filter.propertyKey\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else if (loading()) {\r\n <!-- Loading State -->\r\n <div class=\"flex items-center justify-center h-64\">\r\n <div class=\"text-center\">\r\n <i\r\n class=\"mti mti-loader-2 text-4xl text-primary animate-spin mb-2\"\r\n ></i>\r\n <p class=\"text-muted-color\">{{ t(\"loading\") }}</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div\r\n class=\"flex flex-col items-center justify-center h-64 text-muted-color\"\r\n >\r\n <i class=\"mti mti-layout text-6xl mb-4\"></i>\r\n <p class=\"text-lg\">{{ t(\"noPageSelected\") }}</p>\r\n <p class=\"text-sm\">{{ t(\"selectPageToStart\") }}</p>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n</ng-container>\r\n", styles: [".mt-dashboard-viewer{width:100%;height:100%}.dashboard-viewer-layout-wrapper{width:100%}.dashboard-viewer-layout{display:grid;grid-template-columns:repeat(36,minmax(0,1fr));grid-auto-rows:60px;gap:10px;width:100%;align-items:stretch}.dashboard-viewer-item{display:flex;min-width:0;min-height:0}.dashboard-viewer-item>*{width:100%;height:100%}.dashboard-viewer-content-item{display:block;flex:1 1 auto;min-width:0;min-height:0;width:100%;height:100%}.dashboard-viewer-item--header{z-index:1}.dashboard-viewer-item--topbar{z-index:2}.group-container{background-color:var(--surface-card)}.group-header{flex-shrink:0}.group-tabs{flex-wrap:wrap}.group-body{background-color:var(--surface-0)}.header-item{background-color:transparent}.topbar-item{background-color:var(--surface-50)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.filters-sidebar{transform:translate(100%);transition:transform .3s ease-in-out}.filters-sidebar.open{transform:translate(0)}[dir=rtl] .filters-sidebar{transform:translate(-100%)}[dir=rtl] .filters-sidebar.open{transform:translate(0)}.table-responsive{max-height:75vh;overflow-y:auto;overflow-x:auto}.modal-content{border:0!important}.custom-donut-chart{display:flex;justify-content:center;height:auto!important}.custom-donut-chart canvas{margin-top:-1.5rem!important}@media(max-width:768px){.dashboard-viewer-layout{display:flex;flex-direction:column;min-height:0!important}.dashboard-viewer-item{min-height:220px}.dashboard-viewer-item--header,.dashboard-viewer-item--topbar{min-height:72px}.dashboard-viewer-item--group{min-height:280px}}\n"] }]
|
|
20468
20992
|
}], propDecorators: { isPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPage", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], backButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "backButton", required: false }] }], pageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageId", required: false }] }], dashboardData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dashboardData", required: false }] }], chartsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartsData", required: false }] }], dialogsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogsData", required: false }] }], filtersData: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersData", required: false }] }], extraFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "extraFilters", required: false }] }], showFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilters", required: false }] }], pageLoaded: [{ type: i0.Output, args: ["pageLoaded"] }], onBack: [{ type: i0.Output, args: ["onBack"] }], chartClick: [{ type: i0.Output, args: ["chartClick"] }] } });
|
|
20469
20993
|
|
|
20470
20994
|
/**
|
|
@@ -20671,7 +21195,7 @@ class DashboardList {
|
|
|
20671
21195
|
this.dashboards.reload();
|
|
20672
21196
|
}
|
|
20673
21197
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardList, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20674
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardList, isStandalone: true, selector: "mt-dashboard-list", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, baseRoute: { classPropertyName: "baseRoute", publicName: "baseRoute", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, showViewButton: { classPropertyName: "showViewButton", publicName: "showViewButton", isSignal: true, isRequired: false, transformFunction: null }, showEditButton: { classPropertyName: "showEditButton", publicName: "showEditButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardAction: "dashboardAction", dashboardCreated: "dashboardCreated" }, viewQueries: [{ propertyName: "nameTpl", first: true, predicate: ["nameTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder.dashboard'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page [title]=\"pageTitle() || t('dashboards')\">\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <div class=\"dashboard-list space-y-3\">\r\n <!-- Header -->\r\n <div class=\"flex justify-between items-center gap-4\">\r\n <h2 class=\"text-2xl font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ t(\"dashboards\") }}\r\n </h2>\r\n\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </div>\r\n }\r\n\r\n <!-- Reusable table content template -->\r\n <ng-template #tableContent>\r\n <!-- Custom cell templates -->\r\n <ng-template #nameTpl let-row>\r\n <span class=\"font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ getDashboardName(row) }}\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Dashboard Table -->\r\n <mt-table\r\n [data]=\"dashboardList()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"isLoading()\"\r\n [showFilters]=\"true\"\r\n [generalSearch]=\"true\"\r\n dataKey=\"id\"\r\n />\r\n </ng-template>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "actionShape", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
21198
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: DashboardList, isStandalone: true, selector: "mt-dashboard-list", inputs: { isPage: { classPropertyName: "isPage", publicName: "isPage", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, baseRoute: { classPropertyName: "baseRoute", publicName: "baseRoute", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, showViewButton: { classPropertyName: "showViewButton", publicName: "showViewButton", isSignal: true, isRequired: false, transformFunction: null }, showEditButton: { classPropertyName: "showEditButton", publicName: "showEditButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dashboardAction: "dashboardAction", dashboardCreated: "dashboardCreated" }, viewQueries: [{ propertyName: "nameTpl", first: true, predicate: ["nameTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'dashboardBuilder.dashboard'\">\r\n <!-- Page mode -->\r\n @if (isPage()) {\r\n <mt-page [title]=\"pageTitle() || t('dashboards')\">\r\n <!-- Header actions -->\r\n <ng-template #headerEnd>\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n size=\"small\"\r\n />\r\n }\r\n </ng-template>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </mt-page>\r\n } @else {\r\n <!-- Non-page mode -->\r\n <div class=\"dashboard-list space-y-3\">\r\n <!-- Header -->\r\n <div class=\"flex justify-between items-center gap-4\">\r\n <h2 class=\"text-2xl font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ t(\"dashboards\") }}\r\n </h2>\r\n\r\n @if (showCreateButton()) {\r\n <mt-button\r\n [label]=\"t('createDashboard')\"\r\n icon=\"general.plus\"\r\n (onClick)=\"openCreateModal()\"\r\n severity=\"primary\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <ng-container *ngTemplateOutlet=\"tableContent\" />\r\n </div>\r\n }\r\n\r\n <!-- Reusable table content template -->\r\n <ng-template #tableContent>\r\n <!-- Custom cell templates -->\r\n <ng-template #nameTpl let-row>\r\n <span class=\"font-semibold text-surface-900 dark:text-surface-0\">\r\n {{ getDashboardName(row) }}\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Dashboard Table -->\r\n <mt-table\r\n [data]=\"dashboardList()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [loading]=\"isLoading()\"\r\n [showFilters]=\"true\"\r\n [generalSearch]=\"true\"\r\n dataKey=\"id\"\r\n />\r\n </ng-template>\r\n</ng-container>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "lazyLocalSearch", "showFilters", "loading", "updating", "lazy", "lazyLocalSort", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "storageKey", "storageMode", "exportable", "exportFilename", "actionShape", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "rowsPerPageOptions", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
20675
21199
|
}
|
|
20676
21200
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DashboardList, decorators: [{
|
|
20677
21201
|
type: Component,
|
|
@@ -20700,5 +21224,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
20700
21224
|
* Generated bundle index. Do not edit.
|
|
20701
21225
|
*/
|
|
20702
21226
|
|
|
20703
|
-
export { ActionsSettings, BarChartHandler, BarControlUi, CHART_TYPES, CardContentComponent, CardFilterComponent, CardInfoComponent, ChartCardComponent, ChartDataService, ChartSettingsDrawer, ChartViewer, ComparisonChartHandler, DashboardBuilder, DashboardBuilderService, DashboardItem, DashboardItemStoreService, DashboardList, DashboardStoreService, DashboardViewer, DataSourceSettings, DefaultControlUi, DisplaySettings, DynamicFiltersComponent, DynamicFiltersConfig, EChartComponent, EntityInfoComponent, EntityPreviewCardComponent, FilterByGroupPipe, GaugeChartHandler, GeneralSettings, GetChartActionsPipe, HTTPMethod, HeaderCardComponent, LevelCardHandler,
|
|
21227
|
+
export { ActionsSettings, BarChartHandler, BarControlUi, CHART_TYPES, CardContentComponent, CardFilterComponent, CardInfoComponent, ChartCardComponent, ChartDataService, ChartSettingsDrawer, ChartViewer, ComparisonChartHandler, DashboardBuilder, DashboardBuilderService, DashboardItem, DashboardItemStoreService, DashboardList, DashboardStoreService, DashboardViewer, DataSourceSettings, DefaultControlUi, DisplaySettings, DynamicFiltersComponent, DynamicFiltersConfig, EChartComponent, PropertiesCardComponent as EntitiesPreviewCardComponent, EntityInfoComponent, EntityPreviewCardComponent, FilterByGroupPipe, GaugeChartHandler, GeneralSettings, GetChartActionsPipe, HTTPMethod, HeaderCardComponent, LevelCardHandler, LineChartHandler, ListStatisticCardComponent, ManageBreadcrumb, ManageFilterOnPage, ManageItem, ManageItemService, ManagePages, MapChartHandler, OverviewCardHandler, PhaseGateStepperHandler, PieChartHandler, PieControlUi, PropertiesCardComponent, RingGaugeChartHandler, SPlusChartHandler, SkeletonCardComponent, SnapshotHandler, SplitterChartHandler, StackBarChartHandler, StackBarControlUi, StaticFiltersComponent, StatisticCardComponent, TableCardComponent, TableViewHandler, TimelineHandler, TopbarCardComponent, addCommasToNumber, axisFormatters, cloneDeep$1 as cloneDeep, createAxisFormatter, createTooltipFormatter, dynamicReorder, dynamicTextReplace, formatCurrency, formatDate, formatNumber, formatPercentage, formatValue, formatWordsUnderBar, formatXAxis, generalConfiguration, getColorFromConditions, getLanguageCode, getLocalizedTitle, getNestedData, groupDatesByYearAndMonth, handleFilterForCard, handleFilterForSnapshot, handleFiltersForCustom, isMobilePlatform$1 as isMobilePlatform, sortChartData, sortDataTableView, switchAllKeysSmall$1 as switchAllKeysSmall, switchAllKeysToLower };
|
|
20704
21228
|
//# sourceMappingURL=masterteam-dashboard-builder.mjs.map
|