@meshmakers/octo-ui 3.3.850 → 3.3.870
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/meshmakers-octo-ui.mjs +1484 -64
- package/fesm2022/meshmakers-octo-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/meshmakers-octo-ui.d.ts +241 -6
- package/styles/_drawer.scss +0 -125
|
@@ -18,11 +18,11 @@ import { GridModule } from '@progress/kendo-angular-grid';
|
|
|
18
18
|
import * as i5$1 from '@progress/kendo-angular-icons';
|
|
19
19
|
import { IconsModule, SVGIconModule, SVGIconComponent } from '@progress/kendo-angular-icons';
|
|
20
20
|
import * as i5 from '@progress/kendo-angular-inputs';
|
|
21
|
-
import { InputsModule, TextBoxModule, KENDO_INPUTS } from '@progress/kendo-angular-inputs';
|
|
22
|
-
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, filterClearIcon,
|
|
21
|
+
import { InputsModule, TextBoxModule, KENDO_INPUTS, SwitchModule } from '@progress/kendo-angular-inputs';
|
|
22
|
+
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, filterClearIcon, fileIcon, folderIcon, calendarIcon, checkboxCheckedIcon, listUnorderedIcon, chevronRightIcon, chevronDownIcon, downloadIcon, windowIcon, arrowRightIcon, arrowLeftIcon, chevronDoubleRightIcon, chevronDoubleLeftIcon, arrowUpIcon, arrowDownIcon, pencilIcon, trashIcon, copyIcon, folderMoreIcon, folderOpenIcon, gearIcon, plusIcon, minusIcon, dollarIcon, hyperlinkOpenIcon, infoCircleIcon, eyeIcon, arrowRotateCcwIcon, locationsIcon, arrowRotateCwIcon, xIcon, checkCircleIcon, exclamationCircleIcon, xCircleIcon } from '@progress/kendo-svg-icons';
|
|
23
23
|
import { Subject, firstValueFrom, Subscription, of, forkJoin, takeUntil as takeUntil$1, catchError as catchError$1, map as map$1, defer, from, finalize, switchMap as switchMap$1, startWith } from 'rxjs';
|
|
24
24
|
import { debounceTime, distinctUntilChanged, map, switchMap, tap, catchError, takeUntil } from 'rxjs/operators';
|
|
25
|
-
import { LoaderModule } from '@progress/kendo-angular-indicators';
|
|
25
|
+
import { LoaderModule, BadgeModule } from '@progress/kendo-angular-indicators';
|
|
26
26
|
import { isCompositeFilterDescriptor } from '@progress/kendo-data-query';
|
|
27
27
|
import { TreeItemDataTyped } from '@meshmakers/shared-services';
|
|
28
28
|
import * as i1$3 from 'apollo-angular';
|
|
@@ -1476,6 +1476,492 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1476
1476
|
}]
|
|
1477
1477
|
}] });
|
|
1478
1478
|
|
|
1479
|
+
/**
|
|
1480
|
+
* Content component for displaying Record and RecordArray attribute values.
|
|
1481
|
+
* Designed to be hosted inside a Kendo Window opened via `WindowService.open()`
|
|
1482
|
+
* — this guarantees the window is mounted at the application root (escaping
|
|
1483
|
+
* any tile/widget stacking context) and is fully resizable, draggable,
|
|
1484
|
+
* minimizable and maximizable like the other dialogs in the studio.
|
|
1485
|
+
*
|
|
1486
|
+
* Inputs are set on the component instance after the window is created:
|
|
1487
|
+
* const ref = windowService.open({ content: RecordDetailDialogComponent, ... });
|
|
1488
|
+
* const c = ref.content.instance as RecordDetailDialogComponent;
|
|
1489
|
+
* c.attributeName = ...; c.value = ...; c.type = ...;
|
|
1490
|
+
*/
|
|
1491
|
+
class RecordDetailDialogComponent {
|
|
1492
|
+
attributeName = 'Record';
|
|
1493
|
+
value;
|
|
1494
|
+
type = AttributeValueTypeDto.RecordDto;
|
|
1495
|
+
/**
|
|
1496
|
+
* Emitted when the user-visible state changes in a way the host might want
|
|
1497
|
+
* to react to. Currently unused for closing — the host listens to
|
|
1498
|
+
* `WindowRef.result` for that.
|
|
1499
|
+
*/
|
|
1500
|
+
closed = new EventEmitter();
|
|
1501
|
+
singleRecordProperties = [];
|
|
1502
|
+
recordItems = [];
|
|
1503
|
+
searchTerm = '';
|
|
1504
|
+
// Icons
|
|
1505
|
+
fileIcon = fileIcon;
|
|
1506
|
+
folderIcon = folderIcon;
|
|
1507
|
+
calendarIcon = calendarIcon;
|
|
1508
|
+
checkboxCheckedIcon = checkboxCheckedIcon;
|
|
1509
|
+
listUnorderedIcon = listUnorderedIcon;
|
|
1510
|
+
chevronRightIcon = chevronRightIcon;
|
|
1511
|
+
chevronDownIcon = chevronDownIcon;
|
|
1512
|
+
get isRecordArray() {
|
|
1513
|
+
return this.type === AttributeValueTypeDto.RecordArrayDto;
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Compute the title text for the host window. The host reads this via
|
|
1517
|
+
* the component instance after construction.
|
|
1518
|
+
*/
|
|
1519
|
+
get dialogTitle() {
|
|
1520
|
+
const name = this.formatAttributeName(this.attributeName);
|
|
1521
|
+
if (this.isRecordArray && Array.isArray(this.value)) {
|
|
1522
|
+
return `${name} (${this.value.length} record${this.value.length !== 1 ? 's' : ''})`;
|
|
1523
|
+
}
|
|
1524
|
+
return name;
|
|
1525
|
+
}
|
|
1526
|
+
ngOnInit() {
|
|
1527
|
+
this.recompute();
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* Recompute derived state. Public so the host can call it after late
|
|
1531
|
+
* input assignment (WindowService.open() instantiates the component
|
|
1532
|
+
* before inputs can be set on its instance).
|
|
1533
|
+
*/
|
|
1534
|
+
recompute() {
|
|
1535
|
+
if (this.isRecordArray && Array.isArray(this.value)) {
|
|
1536
|
+
this.recordItems = this.value.map((item, originalIndex) => ({
|
|
1537
|
+
originalIndex,
|
|
1538
|
+
label: this.getRecordLabel(item),
|
|
1539
|
+
properties: this.toRecordProperties(item),
|
|
1540
|
+
expanded: true
|
|
1541
|
+
}));
|
|
1542
|
+
this.singleRecordProperties = [];
|
|
1543
|
+
}
|
|
1544
|
+
else {
|
|
1545
|
+
this.singleRecordProperties = this.toRecordProperties(this.value);
|
|
1546
|
+
this.recordItems = [];
|
|
1547
|
+
}
|
|
1548
|
+
this.searchTerm = '';
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Records visible after applying the search filter. With no search term
|
|
1552
|
+
* this is just the full list. The matcher checks the record's label and
|
|
1553
|
+
* every property's key + formatted value (case-insensitive substring).
|
|
1554
|
+
*/
|
|
1555
|
+
get visibleRecords() {
|
|
1556
|
+
const q = this.searchTerm.trim().toLowerCase();
|
|
1557
|
+
if (!q)
|
|
1558
|
+
return this.recordItems;
|
|
1559
|
+
return this.recordItems.filter(r => this.recordMatches(r, q));
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* When search is active, force matching records open so their content is
|
|
1563
|
+
* visible without an extra click. Outside search mode the user's manual
|
|
1564
|
+
* expanded state wins.
|
|
1565
|
+
*/
|
|
1566
|
+
isRecordExpanded(record) {
|
|
1567
|
+
if (this.searchTerm.trim())
|
|
1568
|
+
return true;
|
|
1569
|
+
return record.expanded;
|
|
1570
|
+
}
|
|
1571
|
+
onSearchInput(event) {
|
|
1572
|
+
this.searchTerm = event.target.value;
|
|
1573
|
+
}
|
|
1574
|
+
clearSearch() {
|
|
1575
|
+
this.searchTerm = '';
|
|
1576
|
+
}
|
|
1577
|
+
recordMatches(record, q) {
|
|
1578
|
+
if (record.label && record.label.toLowerCase().includes(q))
|
|
1579
|
+
return true;
|
|
1580
|
+
for (const p of record.properties) {
|
|
1581
|
+
if (p.key.toLowerCase().includes(q))
|
|
1582
|
+
return true;
|
|
1583
|
+
if (p.formattedValue.toLowerCase().includes(q))
|
|
1584
|
+
return true;
|
|
1585
|
+
}
|
|
1586
|
+
return false;
|
|
1587
|
+
}
|
|
1588
|
+
toggleRecord(index) {
|
|
1589
|
+
const item = this.recordItems[index];
|
|
1590
|
+
if (item) {
|
|
1591
|
+
item.expanded = !item.expanded;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
expandAll() {
|
|
1595
|
+
for (const item of this.recordItems) {
|
|
1596
|
+
item.expanded = true;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
collapseAll() {
|
|
1600
|
+
for (const item of this.recordItems) {
|
|
1601
|
+
item.expanded = false;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
getTypeIcon(type) {
|
|
1605
|
+
switch (type) {
|
|
1606
|
+
case AttributeValueTypeDto.BooleanDto:
|
|
1607
|
+
return checkboxCheckedIcon;
|
|
1608
|
+
case AttributeValueTypeDto.DateTimeDto:
|
|
1609
|
+
case AttributeValueTypeDto.DateTimeOffsetDto:
|
|
1610
|
+
return calendarIcon;
|
|
1611
|
+
case AttributeValueTypeDto.RecordDto:
|
|
1612
|
+
case AttributeValueTypeDto.RecordArrayDto:
|
|
1613
|
+
return folderIcon;
|
|
1614
|
+
case AttributeValueTypeDto.StringArrayDto:
|
|
1615
|
+
case AttributeValueTypeDto.IntegerArrayDto:
|
|
1616
|
+
case AttributeValueTypeDto.IntArrayDto:
|
|
1617
|
+
return listUnorderedIcon;
|
|
1618
|
+
default:
|
|
1619
|
+
return fileIcon;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
formatTypeName(type) {
|
|
1623
|
+
return type.replace('_DTO', '').replace('DTO', '').replace('_', ' ');
|
|
1624
|
+
}
|
|
1625
|
+
toRecordProperties(obj) {
|
|
1626
|
+
const props = this.getObjectProperties(obj);
|
|
1627
|
+
return props.map(prop => {
|
|
1628
|
+
const type = this.inferType(prop.value);
|
|
1629
|
+
return {
|
|
1630
|
+
key: prop.key,
|
|
1631
|
+
value: prop.value,
|
|
1632
|
+
formattedValue: this.formatValue(prop.value, type),
|
|
1633
|
+
type
|
|
1634
|
+
};
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
formatValue(value, type) {
|
|
1638
|
+
if (value === null)
|
|
1639
|
+
return '<null>';
|
|
1640
|
+
if (value === undefined)
|
|
1641
|
+
return '<undefined>';
|
|
1642
|
+
if (value === '')
|
|
1643
|
+
return '<empty>';
|
|
1644
|
+
switch (type) {
|
|
1645
|
+
case AttributeValueTypeDto.BooleanDto:
|
|
1646
|
+
return value ? 'True' : 'False';
|
|
1647
|
+
case AttributeValueTypeDto.DateTimeDto:
|
|
1648
|
+
case AttributeValueTypeDto.DateTimeOffsetDto:
|
|
1649
|
+
try {
|
|
1650
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
1651
|
+
return isNaN(date.getTime()) ? String(value) : date.toLocaleString();
|
|
1652
|
+
}
|
|
1653
|
+
catch {
|
|
1654
|
+
return String(value);
|
|
1655
|
+
}
|
|
1656
|
+
case AttributeValueTypeDto.RecordDto:
|
|
1657
|
+
case AttributeValueTypeDto.RecordArrayDto:
|
|
1658
|
+
return JSON.stringify(value, null, 2);
|
|
1659
|
+
case AttributeValueTypeDto.DoubleDto: {
|
|
1660
|
+
const num = Number(value);
|
|
1661
|
+
return isNaN(num) ? String(value) : num.toFixed(2);
|
|
1662
|
+
}
|
|
1663
|
+
default:
|
|
1664
|
+
if (Array.isArray(value)) {
|
|
1665
|
+
return value.length <= 5 ? `[${value.join(', ')}]` : `[${value.slice(0, 5).join(', ')}, ... +${value.length - 5} more]`;
|
|
1666
|
+
}
|
|
1667
|
+
return String(value);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
getRecordLabel(obj) {
|
|
1671
|
+
if (typeof obj !== 'object' || obj === null)
|
|
1672
|
+
return null;
|
|
1673
|
+
const record = obj;
|
|
1674
|
+
// OctoMesh RtRecord format
|
|
1675
|
+
if ('ckRecordId' in record) {
|
|
1676
|
+
return String(record['ckRecordId']);
|
|
1677
|
+
}
|
|
1678
|
+
// Try common name fields
|
|
1679
|
+
for (const key of ['name', 'Name', 'label', 'Label', 'id', 'Id']) {
|
|
1680
|
+
if (key in record && record[key] != null) {
|
|
1681
|
+
return String(record[key]);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
return null;
|
|
1685
|
+
}
|
|
1686
|
+
getObjectProperties(obj) {
|
|
1687
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
1688
|
+
return [];
|
|
1689
|
+
}
|
|
1690
|
+
// OctoMesh RtRecord format: { ckRecordId, attributes: [{ attributeName, value }] }
|
|
1691
|
+
const maybeRecord = obj;
|
|
1692
|
+
if ('ckRecordId' in maybeRecord && 'attributes' in maybeRecord && Array.isArray(maybeRecord['attributes'])) {
|
|
1693
|
+
return maybeRecord['attributes'].map(attr => ({
|
|
1694
|
+
key: attr.attributeName || 'unknown',
|
|
1695
|
+
value: attr.value
|
|
1696
|
+
}));
|
|
1697
|
+
}
|
|
1698
|
+
return Object.keys(maybeRecord).map(key => ({
|
|
1699
|
+
key,
|
|
1700
|
+
value: maybeRecord[key]
|
|
1701
|
+
}));
|
|
1702
|
+
}
|
|
1703
|
+
inferType(value) {
|
|
1704
|
+
if (value === null || value === undefined)
|
|
1705
|
+
return AttributeValueTypeDto.StringDto;
|
|
1706
|
+
if (typeof value === 'boolean')
|
|
1707
|
+
return AttributeValueTypeDto.BooleanDto;
|
|
1708
|
+
if (typeof value === 'number') {
|
|
1709
|
+
return Number.isInteger(value) ? AttributeValueTypeDto.IntegerDto : AttributeValueTypeDto.DoubleDto;
|
|
1710
|
+
}
|
|
1711
|
+
if (typeof value === 'string') {
|
|
1712
|
+
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value))
|
|
1713
|
+
return AttributeValueTypeDto.DateTimeDto;
|
|
1714
|
+
return AttributeValueTypeDto.StringDto;
|
|
1715
|
+
}
|
|
1716
|
+
if (Array.isArray(value)) {
|
|
1717
|
+
if (value.length > 0 && typeof value[0] === 'object')
|
|
1718
|
+
return AttributeValueTypeDto.RecordArrayDto;
|
|
1719
|
+
if (value.length > 0 && typeof value[0] === 'string')
|
|
1720
|
+
return AttributeValueTypeDto.StringArrayDto;
|
|
1721
|
+
if (value.length > 0 && typeof value[0] === 'number')
|
|
1722
|
+
return AttributeValueTypeDto.IntegerArrayDto;
|
|
1723
|
+
return AttributeValueTypeDto.StringArrayDto;
|
|
1724
|
+
}
|
|
1725
|
+
if (typeof value === 'object')
|
|
1726
|
+
return AttributeValueTypeDto.RecordDto;
|
|
1727
|
+
return AttributeValueTypeDto.StringDto;
|
|
1728
|
+
}
|
|
1729
|
+
formatAttributeName(name) {
|
|
1730
|
+
return name
|
|
1731
|
+
.replace(/([A-Z])/g, ' $1')
|
|
1732
|
+
.replace(/^./, str => str.toUpperCase())
|
|
1733
|
+
.trim();
|
|
1734
|
+
}
|
|
1735
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RecordDetailDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1736
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RecordDetailDialogComponent, isStandalone: true, selector: "mm-record-detail-dialog", inputs: { attributeName: "attributeName", value: "value", type: "type" }, outputs: { closed: "closed" }, ngImport: i0, template: `
|
|
1737
|
+
<div class="record-detail-content">
|
|
1738
|
+
@if (isRecordArray && recordItems.length > 1) {
|
|
1739
|
+
<div class="record-toolbar">
|
|
1740
|
+
<input
|
|
1741
|
+
type="text"
|
|
1742
|
+
class="search-input"
|
|
1743
|
+
[value]="searchTerm"
|
|
1744
|
+
(input)="onSearchInput($event)"
|
|
1745
|
+
placeholder="Search records, keys, values…"
|
|
1746
|
+
aria-label="Search" />
|
|
1747
|
+
@if (searchTerm) {
|
|
1748
|
+
<button
|
|
1749
|
+
type="button"
|
|
1750
|
+
class="search-clear"
|
|
1751
|
+
(click)="clearSearch()"
|
|
1752
|
+
aria-label="Clear search"
|
|
1753
|
+
title="Clear search">×</button>
|
|
1754
|
+
<span class="match-count">
|
|
1755
|
+
{{ visibleRecords.length }} of {{ recordItems.length }}
|
|
1756
|
+
</span>
|
|
1757
|
+
}
|
|
1758
|
+
<span class="toolbar-spacer"></span>
|
|
1759
|
+
<button
|
|
1760
|
+
kendoButton
|
|
1761
|
+
fillMode="flat"
|
|
1762
|
+
[svgIcon]="chevronDownIcon"
|
|
1763
|
+
(click)="expandAll()">
|
|
1764
|
+
Expand All
|
|
1765
|
+
</button>
|
|
1766
|
+
<button
|
|
1767
|
+
kendoButton
|
|
1768
|
+
fillMode="flat"
|
|
1769
|
+
[svgIcon]="chevronRightIcon"
|
|
1770
|
+
(click)="collapseAll()">
|
|
1771
|
+
Collapse All
|
|
1772
|
+
</button>
|
|
1773
|
+
</div>
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
@if (isRecordArray && searchTerm && visibleRecords.length === 0) {
|
|
1777
|
+
<div class="no-matches">No records match "{{ searchTerm }}".</div>
|
|
1778
|
+
} @else if (isRecordArray && visibleRecords.length > 0) {
|
|
1779
|
+
<div class="record-array-list">
|
|
1780
|
+
@for (record of visibleRecords; track record.originalIndex) {
|
|
1781
|
+
<div class="record-array-item">
|
|
1782
|
+
<div class="array-item-header" (click)="toggleRecord(record.originalIndex)">
|
|
1783
|
+
<kendo-svgicon
|
|
1784
|
+
[icon]="isRecordExpanded(record) ? chevronDownIcon : chevronRightIcon"
|
|
1785
|
+
class="record-chevron">
|
|
1786
|
+
</kendo-svgicon>
|
|
1787
|
+
<span class="array-item-index">[{{ record.originalIndex }}]</span>
|
|
1788
|
+
@if (record.label) {
|
|
1789
|
+
<span class="array-item-label">{{ record.label }}</span>
|
|
1790
|
+
}
|
|
1791
|
+
<span class="array-item-summary">
|
|
1792
|
+
{{ record.properties.length }} propert{{ record.properties.length === 1 ? 'y' : 'ies' }}
|
|
1793
|
+
</span>
|
|
1794
|
+
</div>
|
|
1795
|
+
@if (isRecordExpanded(record)) {
|
|
1796
|
+
<kendo-grid [data]="record.properties" [resizable]="true" scrollable="none" class="detail-grid">
|
|
1797
|
+
<kendo-grid-column field="key" title="Property" [width]="180">
|
|
1798
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1799
|
+
<div class="property-name-cell">
|
|
1800
|
+
<kendo-svgicon [icon]="getTypeIcon(dataItem.type)" class="type-icon"></kendo-svgicon>
|
|
1801
|
+
<span class="property-name">{{ dataItem.key }}</span>
|
|
1802
|
+
</div>
|
|
1803
|
+
</ng-template>
|
|
1804
|
+
</kendo-grid-column>
|
|
1805
|
+
<kendo-grid-column field="formattedValue" title="Value">
|
|
1806
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1807
|
+
<span class="property-value" [title]="dataItem.formattedValue">{{ dataItem.formattedValue }}</span>
|
|
1808
|
+
</ng-template>
|
|
1809
|
+
</kendo-grid-column>
|
|
1810
|
+
<kendo-grid-column field="type" title="Type" [width]="120">
|
|
1811
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1812
|
+
<span class="type-badge">{{ formatTypeName(dataItem.type) }}</span>
|
|
1813
|
+
</ng-template>
|
|
1814
|
+
</kendo-grid-column>
|
|
1815
|
+
</kendo-grid>
|
|
1816
|
+
}
|
|
1817
|
+
</div>
|
|
1818
|
+
}
|
|
1819
|
+
</div>
|
|
1820
|
+
} @else {
|
|
1821
|
+
<kendo-grid [data]="singleRecordProperties" [resizable]="true" class="detail-grid">
|
|
1822
|
+
<kendo-grid-column field="key" title="Property" [width]="180">
|
|
1823
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1824
|
+
<div class="property-name-cell">
|
|
1825
|
+
<kendo-svgicon [icon]="getTypeIcon(dataItem.type)" class="type-icon"></kendo-svgicon>
|
|
1826
|
+
<span class="property-name">{{ dataItem.key }}</span>
|
|
1827
|
+
</div>
|
|
1828
|
+
</ng-template>
|
|
1829
|
+
</kendo-grid-column>
|
|
1830
|
+
<kendo-grid-column field="formattedValue" title="Value">
|
|
1831
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1832
|
+
<span class="property-value" [title]="dataItem.formattedValue">{{ dataItem.formattedValue }}</span>
|
|
1833
|
+
</ng-template>
|
|
1834
|
+
</kendo-grid-column>
|
|
1835
|
+
<kendo-grid-column field="type" title="Type" [width]="120">
|
|
1836
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1837
|
+
<span class="type-badge">{{ formatTypeName(dataItem.type) }}</span>
|
|
1838
|
+
</ng-template>
|
|
1839
|
+
</kendo-grid-column>
|
|
1840
|
+
</kendo-grid>
|
|
1841
|
+
}
|
|
1842
|
+
</div>
|
|
1843
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;width:100%}.record-detail-content{display:flex;flex-direction:column;height:100%;gap:8px;padding:12px 16px;box-sizing:border-box;overflow:hidden}.record-toolbar{display:flex;align-items:center;gap:8px;flex-shrink:0;padding-bottom:4px;border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.toolbar-spacer{flex:1}.search-input{flex:0 1 220px;min-width:0;padding:4px 8px;font:inherit;color:var(--kendo-color-on-app-surface, #1d1b20);background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:3px;outline:none}.search-input::placeholder{color:var(--kendo-color-subtle, #6c757d)}.search-input:focus{border-color:var(--kendo-color-primary, #0d6efd)}.search-clear{flex-shrink:0;width:22px;height:22px;padding:0;background:transparent;border:none;cursor:pointer;font-size:1.1em;line-height:1;color:var(--kendo-color-subtle, #6c757d);border-radius:3px}.search-clear:hover{color:var(--kendo-color-on-app-surface, #1d1b20);background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 8%,transparent)}.match-count{flex-shrink:0;font-size:.8em;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.no-matches{padding:16px;text-align:center;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.record-array-list{display:flex;flex-direction:column;gap:8px;overflow-y:auto;flex:1;min-height:0}.record-array-item{display:block;flex-shrink:0;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden}.array-item-header{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--kendo-color-surface-alt, #f8f9fa);transition:background-color .15s ease}.array-item-header:hover{background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent)}.record-chevron{width:14px;height:14px;color:var(--kendo-color-subtle);flex-shrink:0}.array-item-index{font-family:Roboto Mono,monospace;font-size:.8em;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.array-item-label{font-size:.85em;color:var(--kendo-color-on-app-surface, #1d1b20);font-weight:500}.array-item-summary{margin-left:auto;font-size:.75em;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.detail-grid{display:block!important;height:auto!important;border:none;border-top:1px solid var(--kendo-color-border, #dee2e6)}:host ::ng-deep .detail-grid .k-grid-aria-root{height:auto}.property-name-cell{display:flex;align-items:center;gap:8px}.type-icon{width:16px;height:16px;opacity:.7}.property-name{font-weight:500}.property-value{word-break:break-word;white-space:pre-wrap}.type-badge{font-size:.75em;padding:2px 6px;border-radius:3px;text-transform:uppercase;font-weight:500;background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 12%,transparent);color:var(--kendo-color-on-app-surface, #1d1b20)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }] });
|
|
1844
|
+
}
|
|
1845
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RecordDetailDialogComponent, decorators: [{
|
|
1846
|
+
type: Component,
|
|
1847
|
+
args: [{ selector: 'mm-record-detail-dialog', standalone: true, imports: [CommonModule, ButtonModule, GridModule, SVGIconModule], template: `
|
|
1848
|
+
<div class="record-detail-content">
|
|
1849
|
+
@if (isRecordArray && recordItems.length > 1) {
|
|
1850
|
+
<div class="record-toolbar">
|
|
1851
|
+
<input
|
|
1852
|
+
type="text"
|
|
1853
|
+
class="search-input"
|
|
1854
|
+
[value]="searchTerm"
|
|
1855
|
+
(input)="onSearchInput($event)"
|
|
1856
|
+
placeholder="Search records, keys, values…"
|
|
1857
|
+
aria-label="Search" />
|
|
1858
|
+
@if (searchTerm) {
|
|
1859
|
+
<button
|
|
1860
|
+
type="button"
|
|
1861
|
+
class="search-clear"
|
|
1862
|
+
(click)="clearSearch()"
|
|
1863
|
+
aria-label="Clear search"
|
|
1864
|
+
title="Clear search">×</button>
|
|
1865
|
+
<span class="match-count">
|
|
1866
|
+
{{ visibleRecords.length }} of {{ recordItems.length }}
|
|
1867
|
+
</span>
|
|
1868
|
+
}
|
|
1869
|
+
<span class="toolbar-spacer"></span>
|
|
1870
|
+
<button
|
|
1871
|
+
kendoButton
|
|
1872
|
+
fillMode="flat"
|
|
1873
|
+
[svgIcon]="chevronDownIcon"
|
|
1874
|
+
(click)="expandAll()">
|
|
1875
|
+
Expand All
|
|
1876
|
+
</button>
|
|
1877
|
+
<button
|
|
1878
|
+
kendoButton
|
|
1879
|
+
fillMode="flat"
|
|
1880
|
+
[svgIcon]="chevronRightIcon"
|
|
1881
|
+
(click)="collapseAll()">
|
|
1882
|
+
Collapse All
|
|
1883
|
+
</button>
|
|
1884
|
+
</div>
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
@if (isRecordArray && searchTerm && visibleRecords.length === 0) {
|
|
1888
|
+
<div class="no-matches">No records match "{{ searchTerm }}".</div>
|
|
1889
|
+
} @else if (isRecordArray && visibleRecords.length > 0) {
|
|
1890
|
+
<div class="record-array-list">
|
|
1891
|
+
@for (record of visibleRecords; track record.originalIndex) {
|
|
1892
|
+
<div class="record-array-item">
|
|
1893
|
+
<div class="array-item-header" (click)="toggleRecord(record.originalIndex)">
|
|
1894
|
+
<kendo-svgicon
|
|
1895
|
+
[icon]="isRecordExpanded(record) ? chevronDownIcon : chevronRightIcon"
|
|
1896
|
+
class="record-chevron">
|
|
1897
|
+
</kendo-svgicon>
|
|
1898
|
+
<span class="array-item-index">[{{ record.originalIndex }}]</span>
|
|
1899
|
+
@if (record.label) {
|
|
1900
|
+
<span class="array-item-label">{{ record.label }}</span>
|
|
1901
|
+
}
|
|
1902
|
+
<span class="array-item-summary">
|
|
1903
|
+
{{ record.properties.length }} propert{{ record.properties.length === 1 ? 'y' : 'ies' }}
|
|
1904
|
+
</span>
|
|
1905
|
+
</div>
|
|
1906
|
+
@if (isRecordExpanded(record)) {
|
|
1907
|
+
<kendo-grid [data]="record.properties" [resizable]="true" scrollable="none" class="detail-grid">
|
|
1908
|
+
<kendo-grid-column field="key" title="Property" [width]="180">
|
|
1909
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1910
|
+
<div class="property-name-cell">
|
|
1911
|
+
<kendo-svgicon [icon]="getTypeIcon(dataItem.type)" class="type-icon"></kendo-svgicon>
|
|
1912
|
+
<span class="property-name">{{ dataItem.key }}</span>
|
|
1913
|
+
</div>
|
|
1914
|
+
</ng-template>
|
|
1915
|
+
</kendo-grid-column>
|
|
1916
|
+
<kendo-grid-column field="formattedValue" title="Value">
|
|
1917
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1918
|
+
<span class="property-value" [title]="dataItem.formattedValue">{{ dataItem.formattedValue }}</span>
|
|
1919
|
+
</ng-template>
|
|
1920
|
+
</kendo-grid-column>
|
|
1921
|
+
<kendo-grid-column field="type" title="Type" [width]="120">
|
|
1922
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1923
|
+
<span class="type-badge">{{ formatTypeName(dataItem.type) }}</span>
|
|
1924
|
+
</ng-template>
|
|
1925
|
+
</kendo-grid-column>
|
|
1926
|
+
</kendo-grid>
|
|
1927
|
+
}
|
|
1928
|
+
</div>
|
|
1929
|
+
}
|
|
1930
|
+
</div>
|
|
1931
|
+
} @else {
|
|
1932
|
+
<kendo-grid [data]="singleRecordProperties" [resizable]="true" class="detail-grid">
|
|
1933
|
+
<kendo-grid-column field="key" title="Property" [width]="180">
|
|
1934
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1935
|
+
<div class="property-name-cell">
|
|
1936
|
+
<kendo-svgicon [icon]="getTypeIcon(dataItem.type)" class="type-icon"></kendo-svgicon>
|
|
1937
|
+
<span class="property-name">{{ dataItem.key }}</span>
|
|
1938
|
+
</div>
|
|
1939
|
+
</ng-template>
|
|
1940
|
+
</kendo-grid-column>
|
|
1941
|
+
<kendo-grid-column field="formattedValue" title="Value">
|
|
1942
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1943
|
+
<span class="property-value" [title]="dataItem.formattedValue">{{ dataItem.formattedValue }}</span>
|
|
1944
|
+
</ng-template>
|
|
1945
|
+
</kendo-grid-column>
|
|
1946
|
+
<kendo-grid-column field="type" title="Type" [width]="120">
|
|
1947
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1948
|
+
<span class="type-badge">{{ formatTypeName(dataItem.type) }}</span>
|
|
1949
|
+
</ng-template>
|
|
1950
|
+
</kendo-grid-column>
|
|
1951
|
+
</kendo-grid>
|
|
1952
|
+
}
|
|
1953
|
+
</div>
|
|
1954
|
+
`, styles: [":host{display:flex;flex-direction:column;height:100%;width:100%}.record-detail-content{display:flex;flex-direction:column;height:100%;gap:8px;padding:12px 16px;box-sizing:border-box;overflow:hidden}.record-toolbar{display:flex;align-items:center;gap:8px;flex-shrink:0;padding-bottom:4px;border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.toolbar-spacer{flex:1}.search-input{flex:0 1 220px;min-width:0;padding:4px 8px;font:inherit;color:var(--kendo-color-on-app-surface, #1d1b20);background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:3px;outline:none}.search-input::placeholder{color:var(--kendo-color-subtle, #6c757d)}.search-input:focus{border-color:var(--kendo-color-primary, #0d6efd)}.search-clear{flex-shrink:0;width:22px;height:22px;padding:0;background:transparent;border:none;cursor:pointer;font-size:1.1em;line-height:1;color:var(--kendo-color-subtle, #6c757d);border-radius:3px}.search-clear:hover{color:var(--kendo-color-on-app-surface, #1d1b20);background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 8%,transparent)}.match-count{flex-shrink:0;font-size:.8em;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.no-matches{padding:16px;text-align:center;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.record-array-list{display:flex;flex-direction:column;gap:8px;overflow-y:auto;flex:1;min-height:0}.record-array-item{display:block;flex-shrink:0;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden}.array-item-header{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--kendo-color-surface-alt, #f8f9fa);transition:background-color .15s ease}.array-item-header:hover{background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent)}.record-chevron{width:14px;height:14px;color:var(--kendo-color-subtle);flex-shrink:0}.array-item-index{font-family:Roboto Mono,monospace;font-size:.8em;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.array-item-label{font-size:.85em;color:var(--kendo-color-on-app-surface, #1d1b20);font-weight:500}.array-item-summary{margin-left:auto;font-size:.75em;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.detail-grid{display:block!important;height:auto!important;border:none;border-top:1px solid var(--kendo-color-border, #dee2e6)}:host ::ng-deep .detail-grid .k-grid-aria-root{height:auto}.property-name-cell{display:flex;align-items:center;gap:8px}.type-icon{width:16px;height:16px;opacity:.7}.property-name{font-weight:500}.property-value{word-break:break-word;white-space:pre-wrap}.type-badge{font-size:.75em;padding:2px 6px;border-radius:3px;text-transform:uppercase;font-weight:500;background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 12%,transparent);color:var(--kendo-color-on-app-surface, #1d1b20)}\n"] }]
|
|
1955
|
+
}], propDecorators: { attributeName: [{
|
|
1956
|
+
type: Input
|
|
1957
|
+
}], value: [{
|
|
1958
|
+
type: Input
|
|
1959
|
+
}], type: [{
|
|
1960
|
+
type: Input
|
|
1961
|
+
}], closed: [{
|
|
1962
|
+
type: Output
|
|
1963
|
+
}] } });
|
|
1964
|
+
|
|
1479
1965
|
/**
|
|
1480
1966
|
* Component for displaying property values with appropriate formatting
|
|
1481
1967
|
*/
|
|
@@ -1483,11 +1969,13 @@ class PropertyValueDisplayComponent {
|
|
|
1483
1969
|
value;
|
|
1484
1970
|
type = AttributeValueTypeDto.StringDto;
|
|
1485
1971
|
displayMode = PropertyDisplayMode.Text;
|
|
1972
|
+
attributeName = 'Record';
|
|
1486
1973
|
/** Emitted when a binary download is requested */
|
|
1487
1974
|
binaryDownload = new EventEmitter();
|
|
1488
1975
|
// Expansion state
|
|
1489
1976
|
isExpanded = false;
|
|
1490
|
-
|
|
1977
|
+
windowService = inject(WindowService);
|
|
1978
|
+
// Pre-computed template properties — recomputed in ngOnInit and ngOnChanges so Kendo Grid row recycling (cell component reuse with new inputs) does not display stale values.
|
|
1491
1979
|
expandableRecord = false;
|
|
1492
1980
|
complexType = false;
|
|
1493
1981
|
binaryLinkedWithDownload = false;
|
|
@@ -1499,13 +1987,33 @@ class PropertyValueDisplayComponent {
|
|
|
1499
1987
|
binarySize = null;
|
|
1500
1988
|
binaryContentType = null;
|
|
1501
1989
|
formattedBinarySize = '';
|
|
1990
|
+
// RecordArray table-mode state — used when the array is uniform enough to be
|
|
1991
|
+
// displayed as a compact table (one row per record, columns = union of keys).
|
|
1992
|
+
// Falls back to the per-item nested-property layout otherwise.
|
|
1993
|
+
useRecordArrayTable = false;
|
|
1994
|
+
recordArrayColumns = [];
|
|
1995
|
+
recordArrayRows = [];
|
|
1996
|
+
/** Hard cap so we don't render a horizontally-unmanageable table. */
|
|
1997
|
+
static MAX_TABLE_COLUMNS = 12;
|
|
1502
1998
|
PropertyDisplayMode = PropertyDisplayMode;
|
|
1503
1999
|
AttributeValueTypeDto = AttributeValueTypeDto;
|
|
1504
2000
|
Array = Array;
|
|
1505
2001
|
chevronRightIcon = chevronRightIcon;
|
|
1506
2002
|
chevronDownIcon = chevronDownIcon;
|
|
1507
2003
|
downloadIcon = downloadIcon;
|
|
2004
|
+
windowIcon = windowIcon;
|
|
1508
2005
|
ngOnInit() {
|
|
2006
|
+
this.recomputeDerivedValues();
|
|
2007
|
+
}
|
|
2008
|
+
ngOnChanges(changes) {
|
|
2009
|
+
// Collapse any user-driven expansion carried over from a recycled cell
|
|
2010
|
+
// when the underlying data changes; displayMode changes do not qualify.
|
|
2011
|
+
if (changes['value'] || changes['type']) {
|
|
2012
|
+
this.isExpanded = false;
|
|
2013
|
+
}
|
|
2014
|
+
this.recomputeDerivedValues();
|
|
2015
|
+
}
|
|
2016
|
+
recomputeDerivedValues() {
|
|
1509
2017
|
this.expandableRecord = this.computeIsExpandableRecord();
|
|
1510
2018
|
this.complexType = this.computeIsComplexType();
|
|
1511
2019
|
this.binaryLinkedWithDownload = this.computeIsBinaryLinkedWithDownload();
|
|
@@ -1513,6 +2021,7 @@ class PropertyValueDisplayComponent {
|
|
|
1513
2021
|
this.recordSummary = this.computeRecordSummary();
|
|
1514
2022
|
this.typeIndicator = this.computeTypeIndicator();
|
|
1515
2023
|
this.typeDescription = this.computeTypeDescription();
|
|
2024
|
+
this.computeRecordArrayTable();
|
|
1516
2025
|
if (this.binaryLinkedWithDownload) {
|
|
1517
2026
|
const bv = this.value;
|
|
1518
2027
|
this.binaryFilename = bv?.filename || null;
|
|
@@ -1520,6 +2029,12 @@ class PropertyValueDisplayComponent {
|
|
|
1520
2029
|
this.binaryContentType = bv?.contentType || null;
|
|
1521
2030
|
this.formattedBinarySize = this.formatFileSize(this.binarySize);
|
|
1522
2031
|
}
|
|
2032
|
+
else {
|
|
2033
|
+
this.binaryFilename = null;
|
|
2034
|
+
this.binarySize = null;
|
|
2035
|
+
this.binaryContentType = null;
|
|
2036
|
+
this.formattedBinarySize = '';
|
|
2037
|
+
}
|
|
1523
2038
|
}
|
|
1524
2039
|
computeFormattedValue() {
|
|
1525
2040
|
if (this.value === null) {
|
|
@@ -1565,6 +2080,44 @@ class PropertyValueDisplayComponent {
|
|
|
1565
2080
|
|| this.type === AttributeValueTypeDto.RecordArrayDto;
|
|
1566
2081
|
return isRecordType && this.value != null && typeof this.value === 'object';
|
|
1567
2082
|
}
|
|
2083
|
+
/**
|
|
2084
|
+
* For RecordArray values, attempt to render as a compact table when the
|
|
2085
|
+
* records share enough structure: ≥ 2 items, every item is object-like, and
|
|
2086
|
+
* the union of keys stays within MAX_TABLE_COLUMNS. Columns are ordered by
|
|
2087
|
+
* first appearance. Rows are stored as plain objects keyed by column name
|
|
2088
|
+
* so the template can do `row[col]` lookups cheaply.
|
|
2089
|
+
*/
|
|
2090
|
+
computeRecordArrayTable() {
|
|
2091
|
+
this.useRecordArrayTable = false;
|
|
2092
|
+
this.recordArrayColumns = [];
|
|
2093
|
+
this.recordArrayRows = [];
|
|
2094
|
+
if (this.type !== AttributeValueTypeDto.RecordArrayDto)
|
|
2095
|
+
return;
|
|
2096
|
+
if (!Array.isArray(this.value) || this.value.length < 2)
|
|
2097
|
+
return;
|
|
2098
|
+
if (!this.value.every(item => item != null && typeof item === 'object'))
|
|
2099
|
+
return;
|
|
2100
|
+
const cols = [];
|
|
2101
|
+
const seen = new Set();
|
|
2102
|
+
const rows = [];
|
|
2103
|
+
for (const item of this.value) {
|
|
2104
|
+
const props = this.getObjectProperties(item);
|
|
2105
|
+
const row = {};
|
|
2106
|
+
for (const { key, value } of props) {
|
|
2107
|
+
if (!seen.has(key)) {
|
|
2108
|
+
seen.add(key);
|
|
2109
|
+
cols.push(key);
|
|
2110
|
+
}
|
|
2111
|
+
row[key] = value;
|
|
2112
|
+
}
|
|
2113
|
+
rows.push(row);
|
|
2114
|
+
}
|
|
2115
|
+
if (cols.length === 0 || cols.length > PropertyValueDisplayComponent.MAX_TABLE_COLUMNS)
|
|
2116
|
+
return;
|
|
2117
|
+
this.recordArrayColumns = cols;
|
|
2118
|
+
this.recordArrayRows = rows;
|
|
2119
|
+
this.useRecordArrayTable = true;
|
|
2120
|
+
}
|
|
1568
2121
|
computeIsComplexType() {
|
|
1569
2122
|
const isComplexDataType = [
|
|
1570
2123
|
AttributeValueTypeDto.RecordDto,
|
|
@@ -1700,6 +2253,39 @@ class PropertyValueDisplayComponent {
|
|
|
1700
2253
|
toggleExpansion() {
|
|
1701
2254
|
this.isExpanded = !this.isExpanded;
|
|
1702
2255
|
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Open the record-detail viewer in a Kendo Window. Using `WindowService.open`
|
|
2258
|
+
* (instead of an inline `<kendo-window>`) is what makes the window mount at
|
|
2259
|
+
* the application root with proper viewport positioning. An inline window
|
|
2260
|
+
* inherits its tile's `position: relative` ancestor and ends up anchored
|
|
2261
|
+
* inside that tile's box rather than on the meshboard surface.
|
|
2262
|
+
*/
|
|
2263
|
+
openDetailDialog(event) {
|
|
2264
|
+
event.stopPropagation();
|
|
2265
|
+
const ref = this.windowService.open({
|
|
2266
|
+
title: this.computeDialogTitle(),
|
|
2267
|
+
content: RecordDetailDialogComponent,
|
|
2268
|
+
width: 720,
|
|
2269
|
+
height: 560,
|
|
2270
|
+
minWidth: 420,
|
|
2271
|
+
minHeight: 280,
|
|
2272
|
+
});
|
|
2273
|
+
const instance = ref.content.instance;
|
|
2274
|
+
instance.attributeName = this.attributeName;
|
|
2275
|
+
instance.value = this.value;
|
|
2276
|
+
instance.type = this.type;
|
|
2277
|
+
instance.recompute();
|
|
2278
|
+
}
|
|
2279
|
+
computeDialogTitle() {
|
|
2280
|
+
const formatted = this.attributeName
|
|
2281
|
+
.replace(/([A-Z])/g, ' $1')
|
|
2282
|
+
.replace(/^./, s => s.toUpperCase())
|
|
2283
|
+
.trim();
|
|
2284
|
+
if (this.type === AttributeValueTypeDto.RecordArrayDto && Array.isArray(this.value)) {
|
|
2285
|
+
return `${formatted} (${this.value.length} record${this.value.length !== 1 ? 's' : ''})`;
|
|
2286
|
+
}
|
|
2287
|
+
return formatted;
|
|
2288
|
+
}
|
|
1703
2289
|
/**
|
|
1704
2290
|
* Compute summary text for record header
|
|
1705
2291
|
*/
|
|
@@ -1829,7 +2415,7 @@ class PropertyValueDisplayComponent {
|
|
|
1829
2415
|
}
|
|
1830
2416
|
}
|
|
1831
2417
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PropertyValueDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1832
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PropertyValueDisplayComponent, isStandalone: true, selector: "mm-property-value-display", inputs: { value: "value", type: "type", displayMode: "displayMode" }, outputs: { binaryDownload: "binaryDownload" }, ngImport: i0, template: `
|
|
2418
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: PropertyValueDisplayComponent, isStandalone: true, selector: "mm-property-value-display", inputs: { value: "value", type: "type", displayMode: "displayMode", attributeName: "attributeName" }, outputs: { binaryDownload: "binaryDownload" }, usesOnChanges: true, ngImport: i0, template: `
|
|
1833
2419
|
<div class="property-value-display" [ngClass]="'type-' + type.toLowerCase()">
|
|
1834
2420
|
|
|
1835
2421
|
@if (expandableRecord) {
|
|
@@ -1841,6 +2427,15 @@ class PropertyValueDisplayComponent {
|
|
|
1841
2427
|
class="expand-icon">
|
|
1842
2428
|
</kendo-svgicon>
|
|
1843
2429
|
<span class="record-summary">{{ recordSummary }}</span>
|
|
2430
|
+
<button
|
|
2431
|
+
kendoButton
|
|
2432
|
+
size="small"
|
|
2433
|
+
fillMode="flat"
|
|
2434
|
+
[svgIcon]="windowIcon"
|
|
2435
|
+
title="Show details"
|
|
2436
|
+
class="detail-button"
|
|
2437
|
+
(click)="openDetailDialog($event)">
|
|
2438
|
+
</button>
|
|
1844
2439
|
<span class="type-indicator" [title]="typeDescription">
|
|
1845
2440
|
{{ typeIndicator }}
|
|
1846
2441
|
</span>
|
|
@@ -1849,23 +2444,58 @@ class PropertyValueDisplayComponent {
|
|
|
1849
2444
|
<!-- Expanded Content -->
|
|
1850
2445
|
@if (isExpanded) {
|
|
1851
2446
|
<div class="record-content">
|
|
1852
|
-
@if (
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
<
|
|
1857
|
-
|
|
1858
|
-
<
|
|
1859
|
-
|
|
1860
|
-
<
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
2447
|
+
@if (useRecordArrayTable) {
|
|
2448
|
+
<!-- Uniform record array → compact table with sticky header -->
|
|
2449
|
+
<div class="record-table-container">
|
|
2450
|
+
<table class="record-table">
|
|
2451
|
+
<thead>
|
|
2452
|
+
<tr>
|
|
2453
|
+
<th class="row-index">#</th>
|
|
2454
|
+
@for (col of recordArrayColumns; track col) {
|
|
2455
|
+
<th>{{ col }}</th>
|
|
2456
|
+
}
|
|
2457
|
+
</tr>
|
|
2458
|
+
</thead>
|
|
2459
|
+
<tbody>
|
|
2460
|
+
@for (row of recordArrayRows; track $index) {
|
|
2461
|
+
<tr>
|
|
2462
|
+
<td class="row-index">{{ $index }}</td>
|
|
2463
|
+
@for (col of recordArrayColumns; track col) {
|
|
2464
|
+
<td>
|
|
2465
|
+
@let v = row[col];
|
|
2466
|
+
@if (v !== null && v !== undefined) {
|
|
2467
|
+
<mm-property-value-display
|
|
2468
|
+
[value]="v"
|
|
2469
|
+
[type]="getPropertyType(v)">
|
|
2470
|
+
</mm-property-value-display>
|
|
2471
|
+
}
|
|
2472
|
+
</td>
|
|
2473
|
+
}
|
|
2474
|
+
</tr>
|
|
1865
2475
|
}
|
|
2476
|
+
</tbody>
|
|
2477
|
+
</table>
|
|
2478
|
+
</div>
|
|
2479
|
+
} @else if (type === AttributeValueTypeDto.RecordArrayDto && Array.isArray(value)) {
|
|
2480
|
+
<!-- Heterogeneous array (or single item) — fallback to per-item nesting, capped height -->
|
|
2481
|
+
<div class="record-array-list">
|
|
2482
|
+
@for (item of value; track $index) {
|
|
2483
|
+
<div class="array-item">
|
|
2484
|
+
<span class="array-index">[{{ $index }}]</span>
|
|
2485
|
+
<div class="nested-properties">
|
|
2486
|
+
@for (prop of getObjectProperties(item); track prop.key) {
|
|
2487
|
+
<div class="nested-property">
|
|
2488
|
+
<span class="property-key">{{ prop.key }}:</span>
|
|
2489
|
+
<mm-property-value-display
|
|
2490
|
+
[value]="prop.value"
|
|
2491
|
+
[type]="getPropertyType(prop.value)">
|
|
2492
|
+
</mm-property-value-display>
|
|
2493
|
+
</div>
|
|
2494
|
+
}
|
|
2495
|
+
</div>
|
|
1866
2496
|
</div>
|
|
1867
|
-
|
|
1868
|
-
|
|
2497
|
+
}
|
|
2498
|
+
</div>
|
|
1869
2499
|
} @else {
|
|
1870
2500
|
<div class="nested-properties">
|
|
1871
2501
|
@for (prop of getObjectProperties(value); track prop.key) {
|
|
@@ -1926,8 +2556,9 @@ class PropertyValueDisplayComponent {
|
|
|
1926
2556
|
</span>
|
|
1927
2557
|
}
|
|
1928
2558
|
}
|
|
2559
|
+
|
|
1929
2560
|
</div>
|
|
1930
|
-
`, isInline: true, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:var(--kendo-color-
|
|
2561
|
+
`, isInline: true, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 12%,transparent);border-radius:3px;color:var(--kendo-color-on-app-surface, #1d1b20);white-space:nowrap;flex-shrink:0}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:2px 0;border-radius:3px;transition:background-color .15s ease}.record-header:hover{background-color:var(--kendo-color-base-subtle, rgba(0,0,0,.04))}.expand-icon{flex-shrink:0;width:14px;height:14px;color:var(--kendo-color-subtle)}.record-summary{color:var(--kendo-color-subtle);font-size:.85em;font-style:italic;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-button{flex-shrink:0;opacity:.6;transition:opacity .15s ease}.detail-button:hover{opacity:1}.record-content{margin-left:20px;padding-left:8px;border-left:1px solid var(--kendo-color-border, #dee2e6)}.array-item{margin:4px 0}.array-index{font-family:Roboto Mono,monospace;font-size:.8em;color:var(--kendo-color-subtle)}.record-array-list{max-height:320px;overflow-y:auto}.record-table-container{max-height:320px;overflow:auto;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:3px;margin-top:4px}.record-table{width:100%;border-collapse:collapse;font-size:.85em;table-layout:auto}.record-table th{position:sticky;top:0;z-index:1;background:var(--kendo-color-surface-alt, #f8f9fa);color:var(--kendo-color-subtle);text-align:left;padding:4px 8px;border-bottom:1px solid var(--kendo-color-border, #dee2e6);font-weight:500;font-size:.85em;white-space:nowrap}.record-table td{padding:3px 8px;border-bottom:1px solid color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 8%,transparent);vertical-align:top;word-break:break-word}.record-table tr:last-child td{border-bottom:none}.record-table tr:hover td{background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent)}.record-table .row-index{color:var(--kendo-color-subtle);font-family:Roboto Mono,monospace;font-size:.85em;text-align:right;width:1px;white-space:nowrap}.nested-properties{margin-left:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;padding:2px 0}.property-key{font-weight:500;white-space:nowrap;flex-shrink:0;color:var(--kendo-color-subtle);font-size:.85em}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode", "attributeName"], outputs: ["binaryDownload"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1931
2562
|
}
|
|
1932
2563
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PropertyValueDisplayComponent, decorators: [{
|
|
1933
2564
|
type: Component,
|
|
@@ -1943,6 +2574,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1943
2574
|
class="expand-icon">
|
|
1944
2575
|
</kendo-svgicon>
|
|
1945
2576
|
<span class="record-summary">{{ recordSummary }}</span>
|
|
2577
|
+
<button
|
|
2578
|
+
kendoButton
|
|
2579
|
+
size="small"
|
|
2580
|
+
fillMode="flat"
|
|
2581
|
+
[svgIcon]="windowIcon"
|
|
2582
|
+
title="Show details"
|
|
2583
|
+
class="detail-button"
|
|
2584
|
+
(click)="openDetailDialog($event)">
|
|
2585
|
+
</button>
|
|
1946
2586
|
<span class="type-indicator" [title]="typeDescription">
|
|
1947
2587
|
{{ typeIndicator }}
|
|
1948
2588
|
</span>
|
|
@@ -1951,23 +2591,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1951
2591
|
<!-- Expanded Content -->
|
|
1952
2592
|
@if (isExpanded) {
|
|
1953
2593
|
<div class="record-content">
|
|
1954
|
-
@if (
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
<
|
|
1959
|
-
|
|
1960
|
-
<
|
|
1961
|
-
|
|
1962
|
-
<
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2594
|
+
@if (useRecordArrayTable) {
|
|
2595
|
+
<!-- Uniform record array → compact table with sticky header -->
|
|
2596
|
+
<div class="record-table-container">
|
|
2597
|
+
<table class="record-table">
|
|
2598
|
+
<thead>
|
|
2599
|
+
<tr>
|
|
2600
|
+
<th class="row-index">#</th>
|
|
2601
|
+
@for (col of recordArrayColumns; track col) {
|
|
2602
|
+
<th>{{ col }}</th>
|
|
2603
|
+
}
|
|
2604
|
+
</tr>
|
|
2605
|
+
</thead>
|
|
2606
|
+
<tbody>
|
|
2607
|
+
@for (row of recordArrayRows; track $index) {
|
|
2608
|
+
<tr>
|
|
2609
|
+
<td class="row-index">{{ $index }}</td>
|
|
2610
|
+
@for (col of recordArrayColumns; track col) {
|
|
2611
|
+
<td>
|
|
2612
|
+
@let v = row[col];
|
|
2613
|
+
@if (v !== null && v !== undefined) {
|
|
2614
|
+
<mm-property-value-display
|
|
2615
|
+
[value]="v"
|
|
2616
|
+
[type]="getPropertyType(v)">
|
|
2617
|
+
</mm-property-value-display>
|
|
2618
|
+
}
|
|
2619
|
+
</td>
|
|
2620
|
+
}
|
|
2621
|
+
</tr>
|
|
1967
2622
|
}
|
|
2623
|
+
</tbody>
|
|
2624
|
+
</table>
|
|
2625
|
+
</div>
|
|
2626
|
+
} @else if (type === AttributeValueTypeDto.RecordArrayDto && Array.isArray(value)) {
|
|
2627
|
+
<!-- Heterogeneous array (or single item) — fallback to per-item nesting, capped height -->
|
|
2628
|
+
<div class="record-array-list">
|
|
2629
|
+
@for (item of value; track $index) {
|
|
2630
|
+
<div class="array-item">
|
|
2631
|
+
<span class="array-index">[{{ $index }}]</span>
|
|
2632
|
+
<div class="nested-properties">
|
|
2633
|
+
@for (prop of getObjectProperties(item); track prop.key) {
|
|
2634
|
+
<div class="nested-property">
|
|
2635
|
+
<span class="property-key">{{ prop.key }}:</span>
|
|
2636
|
+
<mm-property-value-display
|
|
2637
|
+
[value]="prop.value"
|
|
2638
|
+
[type]="getPropertyType(prop.value)">
|
|
2639
|
+
</mm-property-value-display>
|
|
2640
|
+
</div>
|
|
2641
|
+
}
|
|
2642
|
+
</div>
|
|
1968
2643
|
</div>
|
|
1969
|
-
|
|
1970
|
-
|
|
2644
|
+
}
|
|
2645
|
+
</div>
|
|
1971
2646
|
} @else {
|
|
1972
2647
|
<div class="nested-properties">
|
|
1973
2648
|
@for (prop of getObjectProperties(value); track prop.key) {
|
|
@@ -2028,14 +2703,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2028
2703
|
</span>
|
|
2029
2704
|
}
|
|
2030
2705
|
}
|
|
2706
|
+
|
|
2031
2707
|
</div>
|
|
2032
|
-
`, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:var(--kendo-color-
|
|
2708
|
+
`, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 12%,transparent);border-radius:3px;color:var(--kendo-color-on-app-surface, #1d1b20);white-space:nowrap;flex-shrink:0}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:2px 0;border-radius:3px;transition:background-color .15s ease}.record-header:hover{background-color:var(--kendo-color-base-subtle, rgba(0,0,0,.04))}.expand-icon{flex-shrink:0;width:14px;height:14px;color:var(--kendo-color-subtle)}.record-summary{color:var(--kendo-color-subtle);font-size:.85em;font-style:italic;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-button{flex-shrink:0;opacity:.6;transition:opacity .15s ease}.detail-button:hover{opacity:1}.record-content{margin-left:20px;padding-left:8px;border-left:1px solid var(--kendo-color-border, #dee2e6)}.array-item{margin:4px 0}.array-index{font-family:Roboto Mono,monospace;font-size:.8em;color:var(--kendo-color-subtle)}.record-array-list{max-height:320px;overflow-y:auto}.record-table-container{max-height:320px;overflow:auto;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:3px;margin-top:4px}.record-table{width:100%;border-collapse:collapse;font-size:.85em;table-layout:auto}.record-table th{position:sticky;top:0;z-index:1;background:var(--kendo-color-surface-alt, #f8f9fa);color:var(--kendo-color-subtle);text-align:left;padding:4px 8px;border-bottom:1px solid var(--kendo-color-border, #dee2e6);font-weight:500;font-size:.85em;white-space:nowrap}.record-table td{padding:3px 8px;border-bottom:1px solid color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 8%,transparent);vertical-align:top;word-break:break-word}.record-table tr:last-child td{border-bottom:none}.record-table tr:hover td{background:color-mix(in srgb,var(--kendo-color-on-app-surface, #1d1b20) 6%,transparent)}.record-table .row-index{color:var(--kendo-color-subtle);font-family:Roboto Mono,monospace;font-size:.85em;text-align:right;width:1px;white-space:nowrap}.nested-properties{margin-left:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;padding:2px 0}.property-key{font-weight:500;white-space:nowrap;flex-shrink:0;color:var(--kendo-color-subtle);font-size:.85em}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"] }]
|
|
2033
2709
|
}], propDecorators: { value: [{
|
|
2034
2710
|
type: Input
|
|
2035
2711
|
}], type: [{
|
|
2036
2712
|
type: Input
|
|
2037
2713
|
}], displayMode: [{
|
|
2038
2714
|
type: Input
|
|
2715
|
+
}], attributeName: [{
|
|
2716
|
+
type: Input
|
|
2039
2717
|
}], binaryDownload: [{
|
|
2040
2718
|
type: Output
|
|
2041
2719
|
}] } });
|
|
@@ -2243,6 +2921,7 @@ class PropertyGridComponent {
|
|
|
2243
2921
|
<mm-property-value-display
|
|
2244
2922
|
[value]="dataItem.value"
|
|
2245
2923
|
[type]="dataItem.type"
|
|
2924
|
+
[attributeName]="dataItem.displayName || dataItem.name"
|
|
2246
2925
|
(binaryDownload)="onBinaryDownload($event)">
|
|
2247
2926
|
</mm-property-value-display>
|
|
2248
2927
|
</ng-template>
|
|
@@ -2265,7 +2944,7 @@ class PropertyGridComponent {
|
|
|
2265
2944
|
|
|
2266
2945
|
</kendo-grid>
|
|
2267
2946
|
</div>
|
|
2268
|
-
`, isInline: true, styles: [".mm-property-grid{display:flex;flex-direction:column;border:1px solid var(--kendo-color-border);border-radius:4px;overflow:hidden}.search-toolbar{padding:8px;border-bottom:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle)}.property-grid{flex:1;border:none}.property-name-cell{display:flex;align-items:center;gap:8px;min-height:24px}.type-icon{width:16px;height:16px;opacity:.7}.property-info{display:flex;align-items:center;gap:4px;flex:1}.property-name{font-weight:500}.required-indicator{color:var(--kendo-color-error);font-weight:700}.readonly-indicator{font-size:12px;opacity:.7}.property-editor{width:100%;min-width:200px}.validation-error{color:var(--kendo-color-error);font-size:.8em;margin-top:4px}.type-badge{font-size:.75em;padding:2px 6px;border-radius:3px;text-transform:uppercase;font-weight:500;background:var(--kendo-color-base-subtle);color:var(--kendo-color-on-base)}.grid-toolbar{padding:8px;border-top:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle);display:flex;align-items:center;gap:8px}.changes-indicator{margin-left:auto;font-size:.9em;color:var(--kendo-color-primary);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode"], outputs: ["binaryDownload"] }] });
|
|
2947
|
+
`, isInline: true, styles: [".mm-property-grid{display:flex;flex-direction:column;border:1px solid var(--kendo-color-border);border-radius:4px;overflow:hidden}.search-toolbar{padding:8px;border-bottom:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle)}.property-grid{flex:1;border:none}.property-name-cell{display:flex;align-items:center;gap:8px;min-height:24px}.type-icon{width:16px;height:16px;opacity:.7}.property-info{display:flex;align-items:center;gap:4px;flex:1}.property-name{font-weight:500}.required-indicator{color:var(--kendo-color-error);font-weight:700}.readonly-indicator{font-size:12px;opacity:.7}.property-editor{width:100%;min-width:200px}.validation-error{color:var(--kendo-color-error);font-size:.8em;margin-top:4px}.type-badge{font-size:.75em;padding:2px 6px;border-radius:3px;text-transform:uppercase;font-weight:500;background:var(--kendo-color-base-subtle);color:var(--kendo-color-on-base)}.grid-toolbar{padding:8px;border-top:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle);display:flex;align-items:center;gap:8px}.changes-indicator{margin-left:auto;font-size:.9em;color:var(--kendo-color-primary);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode", "attributeName"], outputs: ["binaryDownload"] }] });
|
|
2269
2948
|
}
|
|
2270
2949
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: PropertyGridComponent, decorators: [{
|
|
2271
2950
|
type: Component,
|
|
@@ -2338,6 +3017,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2338
3017
|
<mm-property-value-display
|
|
2339
3018
|
[value]="dataItem.value"
|
|
2340
3019
|
[type]="dataItem.type"
|
|
3020
|
+
[attributeName]="dataItem.displayName || dataItem.name"
|
|
2341
3021
|
(binaryDownload)="onBinaryDownload($event)">
|
|
2342
3022
|
</mm-property-value-display>
|
|
2343
3023
|
</ng-template>
|
|
@@ -7128,21 +7808,45 @@ const DEFAULT_RUNTIME_BROWSER_MESSAGES = {
|
|
|
7128
7808
|
class DataMappingListComponent {
|
|
7129
7809
|
mappings = [];
|
|
7130
7810
|
sourceDataPoints = [];
|
|
7811
|
+
/**
|
|
7812
|
+
* Optional expression validator function. When provided, expressions are validated
|
|
7813
|
+
* on change and feedback (error or preview) is shown below the expression field.
|
|
7814
|
+
* The host app can provide an implementation using any expression engine
|
|
7815
|
+
* (e.g., ExpressionEvaluatorService from octo-process-diagrams).
|
|
7816
|
+
*/
|
|
7817
|
+
expressionValidator;
|
|
7131
7818
|
addMapping = new EventEmitter();
|
|
7132
7819
|
removeMapping = new EventEmitter();
|
|
7133
7820
|
selectTarget = new EventEmitter();
|
|
7134
7821
|
selectSourceAttribute = new EventEmitter();
|
|
7135
7822
|
selectTargetAttribute = new EventEmitter();
|
|
7136
7823
|
mappingChanged = new EventEmitter();
|
|
7824
|
+
navigateToTarget = new EventEmitter();
|
|
7825
|
+
saveAll = new EventEmitter();
|
|
7137
7826
|
onSourceDataPointChange(mapping, value) {
|
|
7138
7827
|
mapping.sourceAttributePath = value;
|
|
7139
7828
|
this.mappingChanged.emit(mapping);
|
|
7140
7829
|
}
|
|
7141
|
-
|
|
7830
|
+
onExpressionChange(mapping, expression) {
|
|
7831
|
+
mapping.mappingExpression = expression;
|
|
7832
|
+
if (this.expressionValidator && expression && expression.trim() !== '') {
|
|
7833
|
+
const result = this.expressionValidator(expression);
|
|
7834
|
+
mapping._expressionValid = result.valid;
|
|
7835
|
+
mapping._expressionError = result.error;
|
|
7836
|
+
mapping._expressionPreview = result.preview;
|
|
7837
|
+
}
|
|
7838
|
+
else {
|
|
7839
|
+
mapping._expressionValid = undefined;
|
|
7840
|
+
mapping._expressionError = undefined;
|
|
7841
|
+
mapping._expressionPreview = undefined;
|
|
7842
|
+
}
|
|
7843
|
+
this.mappingChanged.emit(mapping);
|
|
7844
|
+
}
|
|
7142
7845
|
plusIcon = plusIcon;
|
|
7143
7846
|
trashIcon = trashIcon;
|
|
7847
|
+
linkIcon = hyperlinkOpenIcon;
|
|
7144
7848
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DataMappingListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7145
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DataMappingListComponent, isStandalone: true, selector: "mm-data-mapping-list", inputs: { mappings: "mappings", sourceDataPoints: "sourceDataPoints" }, outputs: { addMapping: "addMapping", removeMapping: "removeMapping", selectTarget: "selectTarget", selectSourceAttribute: "selectSourceAttribute", selectTargetAttribute: "selectTargetAttribute", mappingChanged: "mappingChanged", saveAll: "saveAll" }, ngImport: i0, template: `
|
|
7849
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DataMappingListComponent, isStandalone: true, selector: "mm-data-mapping-list", inputs: { mappings: "mappings", sourceDataPoints: "sourceDataPoints", expressionValidator: "expressionValidator" }, outputs: { addMapping: "addMapping", removeMapping: "removeMapping", selectTarget: "selectTarget", selectSourceAttribute: "selectSourceAttribute", selectTargetAttribute: "selectTargetAttribute", mappingChanged: "mappingChanged", navigateToTarget: "navigateToTarget", saveAll: "saveAll" }, ngImport: i0, template: `
|
|
7146
7850
|
<div class="mapping-list">
|
|
7147
7851
|
<div class="mapping-toolbar">
|
|
7148
7852
|
<button kendoButton themeColor="primary" size="small" [svgIcon]="plusIcon"
|
|
@@ -7184,16 +7888,43 @@ class DataMappingListComponent {
|
|
|
7184
7888
|
<label>Expression</label>
|
|
7185
7889
|
<kendo-textbox [(value)]="mapping.mappingExpression"
|
|
7186
7890
|
placeholder="e.g. value > 0 ? value : 0"
|
|
7187
|
-
(valueChange)="
|
|
7891
|
+
(valueChange)="onExpressionChange(mapping, $event)">
|
|
7188
7892
|
</kendo-textbox>
|
|
7893
|
+
@if (mapping.mappingExpression && expressionValidator) {
|
|
7894
|
+
@if (mapping._expressionValid === false) {
|
|
7895
|
+
<div class="expression-feedback expression-error">{{ mapping._expressionError }}</div>
|
|
7896
|
+
} @else if (mapping._expressionValid === true && mapping._expressionPreview) {
|
|
7897
|
+
<div class="expression-feedback expression-success">value=42 → {{ mapping._expressionPreview }}</div>
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7189
7900
|
</div>
|
|
7190
7901
|
<div class="mapping-row">
|
|
7191
7902
|
<label>Target Entity</label>
|
|
7192
|
-
|
|
7193
|
-
<
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7903
|
+
@if (mapping.targetRtId) {
|
|
7904
|
+
<div class="entity-info-display">
|
|
7905
|
+
<div class="entity-info-main">
|
|
7906
|
+
<span class="entity-name">{{ mapping.targetName || mapping.targetRtId }}</span>
|
|
7907
|
+
@if (mapping.targetRtId) {
|
|
7908
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="linkIcon"
|
|
7909
|
+
title="Navigate to entity"
|
|
7910
|
+
(click)="navigateToTarget.emit(mapping)"></button>
|
|
7911
|
+
}
|
|
7912
|
+
</div>
|
|
7913
|
+
<div class="entity-info-details">
|
|
7914
|
+
<span class="entity-detail-item">{{ mapping.targetCkTypeId }}</span>
|
|
7915
|
+
<span class="entity-detail-separator">@</span>
|
|
7916
|
+
<span class="entity-detail-item">{{ mapping.targetRtId }}</span>
|
|
7917
|
+
</div>
|
|
7918
|
+
<button kendoButton fillMode="flat" size="small"
|
|
7919
|
+
(click)="selectTarget.emit(mapping)">Change...</button>
|
|
7920
|
+
</div>
|
|
7921
|
+
} @else {
|
|
7922
|
+
<div class="target-display">
|
|
7923
|
+
<span class="target-info">(not set)</span>
|
|
7924
|
+
<button kendoButton fillMode="flat" size="small"
|
|
7925
|
+
(click)="selectTarget.emit(mapping)">Select...</button>
|
|
7926
|
+
</div>
|
|
7927
|
+
}
|
|
7197
7928
|
</div>
|
|
7198
7929
|
<div class="mapping-row">
|
|
7199
7930
|
<label>Target Attribute</label>
|
|
@@ -7216,7 +7947,7 @@ class DataMappingListComponent {
|
|
|
7216
7947
|
</div>
|
|
7217
7948
|
}
|
|
7218
7949
|
</div>
|
|
7219
|
-
`, isInline: true, styles: [".mapping-list{display:flex;flex-direction:column;gap:12px}.mapping-toolbar{display:flex;justify-content:flex-end}.mapping-empty-hint{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-size:.85rem}.mapping-card{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.mapping-card-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.mapping-card-header .mapping-name{flex:1}.mapping-card-body{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.mapping-row{display:flex;flex-direction:column;gap:3px}.mapping-row label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.target-display{display:flex;align-items:center;gap:8px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa);min-height:30px}.target-display .target-info{flex:1;font-size:.85rem;font-family:monospace}.mapping-actions{display:flex;justify-content:flex-end;padding-top:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: TextBoxModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: SVGIconModule }] });
|
|
7950
|
+
`, isInline: true, styles: [".mapping-list{display:flex;flex-direction:column;gap:12px}.mapping-toolbar{display:flex;justify-content:flex-end}.mapping-empty-hint{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-size:.85rem}.mapping-card{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.mapping-card-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.mapping-card-header .mapping-name{flex:1}.mapping-card-body{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.mapping-row{display:flex;flex-direction:column;gap:3px}.mapping-row label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.target-display{display:flex;align-items:center;gap:8px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa);min-height:30px}.target-display .target-info{flex:1;font-size:.85rem;font-family:monospace}.mapping-actions{display:flex;justify-content:flex-end;padding-top:4px}.entity-info-display{display:flex;flex-direction:column;gap:2px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa)}.entity-info-main{display:flex;align-items:center;gap:4px}.entity-name{flex:1;font-size:.85rem;font-weight:600}.entity-info-details{display:flex;align-items:center;gap:2px;font-size:.7rem;font-family:monospace;color:var(--kendo-color-subtle, #6c757d)}.entity-detail-separator{color:var(--kendo-color-subtle, #6c757d)}.expression-feedback{font-size:.75rem;padding:2px 0;font-family:monospace}.expression-error{color:var(--kendo-color-error, #dc3545)}.expression-success{color:var(--kendo-color-success, #28a745)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: TextBoxModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: SVGIconModule }] });
|
|
7220
7951
|
}
|
|
7221
7952
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DataMappingListComponent, decorators: [{
|
|
7222
7953
|
type: Component,
|
|
@@ -7269,16 +8000,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
7269
8000
|
<label>Expression</label>
|
|
7270
8001
|
<kendo-textbox [(value)]="mapping.mappingExpression"
|
|
7271
8002
|
placeholder="e.g. value > 0 ? value : 0"
|
|
7272
|
-
(valueChange)="
|
|
8003
|
+
(valueChange)="onExpressionChange(mapping, $event)">
|
|
7273
8004
|
</kendo-textbox>
|
|
8005
|
+
@if (mapping.mappingExpression && expressionValidator) {
|
|
8006
|
+
@if (mapping._expressionValid === false) {
|
|
8007
|
+
<div class="expression-feedback expression-error">{{ mapping._expressionError }}</div>
|
|
8008
|
+
} @else if (mapping._expressionValid === true && mapping._expressionPreview) {
|
|
8009
|
+
<div class="expression-feedback expression-success">value=42 → {{ mapping._expressionPreview }}</div>
|
|
8010
|
+
}
|
|
8011
|
+
}
|
|
7274
8012
|
</div>
|
|
7275
8013
|
<div class="mapping-row">
|
|
7276
8014
|
<label>Target Entity</label>
|
|
7277
|
-
|
|
7278
|
-
<
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
8015
|
+
@if (mapping.targetRtId) {
|
|
8016
|
+
<div class="entity-info-display">
|
|
8017
|
+
<div class="entity-info-main">
|
|
8018
|
+
<span class="entity-name">{{ mapping.targetName || mapping.targetRtId }}</span>
|
|
8019
|
+
@if (mapping.targetRtId) {
|
|
8020
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="linkIcon"
|
|
8021
|
+
title="Navigate to entity"
|
|
8022
|
+
(click)="navigateToTarget.emit(mapping)"></button>
|
|
8023
|
+
}
|
|
8024
|
+
</div>
|
|
8025
|
+
<div class="entity-info-details">
|
|
8026
|
+
<span class="entity-detail-item">{{ mapping.targetCkTypeId }}</span>
|
|
8027
|
+
<span class="entity-detail-separator">@</span>
|
|
8028
|
+
<span class="entity-detail-item">{{ mapping.targetRtId }}</span>
|
|
8029
|
+
</div>
|
|
8030
|
+
<button kendoButton fillMode="flat" size="small"
|
|
8031
|
+
(click)="selectTarget.emit(mapping)">Change...</button>
|
|
8032
|
+
</div>
|
|
8033
|
+
} @else {
|
|
8034
|
+
<div class="target-display">
|
|
8035
|
+
<span class="target-info">(not set)</span>
|
|
8036
|
+
<button kendoButton fillMode="flat" size="small"
|
|
8037
|
+
(click)="selectTarget.emit(mapping)">Select...</button>
|
|
8038
|
+
</div>
|
|
8039
|
+
}
|
|
7282
8040
|
</div>
|
|
7283
8041
|
<div class="mapping-row">
|
|
7284
8042
|
<label>Target Attribute</label>
|
|
@@ -7301,11 +8059,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
7301
8059
|
</div>
|
|
7302
8060
|
}
|
|
7303
8061
|
</div>
|
|
7304
|
-
`, styles: [".mapping-list{display:flex;flex-direction:column;gap:12px}.mapping-toolbar{display:flex;justify-content:flex-end}.mapping-empty-hint{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-size:.85rem}.mapping-card{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.mapping-card-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.mapping-card-header .mapping-name{flex:1}.mapping-card-body{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.mapping-row{display:flex;flex-direction:column;gap:3px}.mapping-row label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.target-display{display:flex;align-items:center;gap:8px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa);min-height:30px}.target-display .target-info{flex:1;font-size:.85rem;font-family:monospace}.mapping-actions{display:flex;justify-content:flex-end;padding-top:4px}\n"] }]
|
|
8062
|
+
`, styles: [".mapping-list{display:flex;flex-direction:column;gap:12px}.mapping-toolbar{display:flex;justify-content:flex-end}.mapping-empty-hint{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-size:.85rem}.mapping-card{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.mapping-card-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.mapping-card-header .mapping-name{flex:1}.mapping-card-body{padding:10px 12px;display:flex;flex-direction:column;gap:8px}.mapping-row{display:flex;flex-direction:column;gap:3px}.mapping-row label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.target-display{display:flex;align-items:center;gap:8px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa);min-height:30px}.target-display .target-info{flex:1;font-size:.85rem;font-family:monospace}.mapping-actions{display:flex;justify-content:flex-end;padding-top:4px}.entity-info-display{display:flex;flex-direction:column;gap:2px;padding:4px 8px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;background:var(--kendo-color-surface-alt, #f8f9fa)}.entity-info-main{display:flex;align-items:center;gap:4px}.entity-name{flex:1;font-size:.85rem;font-weight:600}.entity-info-details{display:flex;align-items:center;gap:2px;font-size:.7rem;font-family:monospace;color:var(--kendo-color-subtle, #6c757d)}.entity-detail-separator{color:var(--kendo-color-subtle, #6c757d)}.expression-feedback{font-size:.75rem;padding:2px 0;font-family:monospace}.expression-error{color:var(--kendo-color-error, #dc3545)}.expression-success{color:var(--kendo-color-success, #28a745)}\n"] }]
|
|
7305
8063
|
}], propDecorators: { mappings: [{
|
|
7306
8064
|
type: Input
|
|
7307
8065
|
}], sourceDataPoints: [{
|
|
7308
8066
|
type: Input
|
|
8067
|
+
}], expressionValidator: [{
|
|
8068
|
+
type: Input
|
|
7309
8069
|
}], addMapping: [{
|
|
7310
8070
|
type: Output
|
|
7311
8071
|
}], removeMapping: [{
|
|
@@ -7318,6 +8078,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
7318
8078
|
type: Output
|
|
7319
8079
|
}], mappingChanged: [{
|
|
7320
8080
|
type: Output
|
|
8081
|
+
}], navigateToTarget: [{
|
|
8082
|
+
type: Output
|
|
7321
8083
|
}], saveAll: [{
|
|
7322
8084
|
type: Output
|
|
7323
8085
|
}] } });
|
|
@@ -7333,6 +8095,11 @@ class EntityDetailViewComponent {
|
|
|
7333
8095
|
showDataMapping = true;
|
|
7334
8096
|
dataMappings = [];
|
|
7335
8097
|
sourceDataPoints = [];
|
|
8098
|
+
/**
|
|
8099
|
+
* Optional expression validator function passed through to DataMappingListComponent.
|
|
8100
|
+
* When provided, mapping expressions are validated on change with visual feedback.
|
|
8101
|
+
*/
|
|
8102
|
+
expressionValidator;
|
|
7336
8103
|
retry = new EventEmitter();
|
|
7337
8104
|
propertyChange = new EventEmitter();
|
|
7338
8105
|
navigateToEntity = new EventEmitter();
|
|
@@ -7526,6 +8293,14 @@ class EntityDetailViewComponent {
|
|
|
7526
8293
|
getAssociationCount() {
|
|
7527
8294
|
return this.entity?.associations?.definitions?.totalCount ?? 0;
|
|
7528
8295
|
}
|
|
8296
|
+
onNavigateToMappingTarget(mapping) {
|
|
8297
|
+
if (mapping.targetRtId && mapping.targetCkTypeId) {
|
|
8298
|
+
this.navigateToEntity.emit({
|
|
8299
|
+
rtId: mapping.targetRtId,
|
|
8300
|
+
ckTypeId: mapping.targetCkTypeId,
|
|
8301
|
+
});
|
|
8302
|
+
}
|
|
8303
|
+
}
|
|
7529
8304
|
copyToClipboard(value, label) {
|
|
7530
8305
|
if (!value)
|
|
7531
8306
|
return;
|
|
@@ -7593,7 +8368,7 @@ class EntityDetailViewComponent {
|
|
|
7593
8368
|
}
|
|
7594
8369
|
}
|
|
7595
8370
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EntityDetailViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7596
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: EntityDetailViewComponent, isStandalone: true, selector: "mm-entity-detail-view", inputs: { entity: "entity", loading: "loading", error: "error", showHeader: "showHeader", messages: "messages", showDataMapping: "showDataMapping", dataMappings: "dataMappings", sourceDataPoints: "sourceDataPoints" }, outputs: { retry: "retry", propertyChange: "propertyChange", navigateToEntity: "navigateToEntity", addMappingRequested: "addMappingRequested", removeMappingRequested: "removeMappingRequested", selectMappingTarget: "selectMappingTarget", selectSourceAttributeRequested: "selectSourceAttributeRequested", selectTargetAttributeRequested: "selectTargetAttributeRequested", mappingChanged: "mappingChanged", saveAllMappingsRequested: "saveAllMappingsRequested" }, viewQueries: [{ propertyName: "associationsDataSource", first: true, predicate: ["associationsDir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
8371
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: EntityDetailViewComponent, isStandalone: true, selector: "mm-entity-detail-view", inputs: { entity: "entity", loading: "loading", error: "error", showHeader: "showHeader", messages: "messages", showDataMapping: "showDataMapping", dataMappings: "dataMappings", sourceDataPoints: "sourceDataPoints", expressionValidator: "expressionValidator" }, outputs: { retry: "retry", propertyChange: "propertyChange", navigateToEntity: "navigateToEntity", addMappingRequested: "addMappingRequested", removeMappingRequested: "removeMappingRequested", selectMappingTarget: "selectMappingTarget", selectSourceAttributeRequested: "selectSourceAttributeRequested", selectTargetAttributeRequested: "selectTargetAttributeRequested", mappingChanged: "mappingChanged", saveAllMappingsRequested: "saveAllMappingsRequested" }, viewQueries: [{ propertyName: "associationsDataSource", first: true, predicate: ["associationsDir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
7597
8372
|
@if (loading) {
|
|
7598
8373
|
<div class="loading-state">
|
|
7599
8374
|
<p>{{ _messages.loadingEntityDetails }}</p>
|
|
@@ -7810,12 +8585,14 @@ class EntityDetailViewComponent {
|
|
|
7810
8585
|
<mm-data-mapping-list
|
|
7811
8586
|
[mappings]="dataMappings"
|
|
7812
8587
|
[sourceDataPoints]="sourceDataPoints"
|
|
8588
|
+
[expressionValidator]="expressionValidator"
|
|
7813
8589
|
(addMapping)="addMappingRequested.emit()"
|
|
7814
8590
|
(removeMapping)="removeMappingRequested.emit($event)"
|
|
7815
8591
|
(selectTarget)="selectMappingTarget.emit($event)"
|
|
7816
8592
|
(selectSourceAttribute)="selectSourceAttributeRequested.emit($event)"
|
|
7817
8593
|
(selectTargetAttribute)="selectTargetAttributeRequested.emit($event)"
|
|
7818
8594
|
(mappingChanged)="mappingChanged.emit($event)"
|
|
8595
|
+
(navigateToTarget)="onNavigateToMappingTarget($event)"
|
|
7819
8596
|
(saveAll)="saveAllMappingsRequested.emit()"
|
|
7820
8597
|
></mm-data-mapping-list>
|
|
7821
8598
|
</div>
|
|
@@ -7825,7 +8602,7 @@ class EntityDetailViewComponent {
|
|
|
7825
8602
|
</kendo-tabstrip>
|
|
7826
8603
|
</div>
|
|
7827
8604
|
}
|
|
7828
|
-
`, isInline: true, styles: [".loading-state,.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;text-align:center;min-height:200px}.loading-state .error-message,.error-state .error-message{margin-bottom:16px;font-family:Roboto,sans-serif;color:#e74c3c}.entity-content{flex:1;display:flex;flex-direction:column;gap:24px}.entity-content .basic-info-card{padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-content .basic-info-card:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-content .basic-info-card .basic-info-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:20px}.entity-content .basic-info-card .basic-info-grid .info-item{display:flex;flex-direction:column;gap:8px}.entity-content .basic-info-card .basic-info-grid .info-item label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80)}.entity-content .basic-info-card .basic-info-grid .info-item .value{font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word;background:var(--deep-sea-40);padding:8px 12px;border-radius:4px;border:1px solid var(--octo-mint-15)}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action{display:flex;align-items:center}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action .value{flex:1;font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word}.entity-content .entity-tabs{flex:1;min-height:400px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;overflow:hidden;position:relative}.entity-content .entity-tabs:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);z-index:1}.entity-content .entity-tabs ::ng-deep .k-tabstrip{background:transparent}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{background:linear-gradient(90deg,var(--octo-mint-10),transparent);border-bottom:1px solid var(--octo-mint-20);padding-left:20px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{background:transparent;border:none;color:rgba(var(--octo-text-color),.7);font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;padding:12px 20px;margin-right:4px;border-radius:4px 4px 0 0;transition:all .2s ease}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item:hover{background:var(--octo-mint-10);color:var(--octo-mint)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item.k-active{background:linear-gradient(180deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-bottom:2px solid var(--octo-mint);box-shadow:0 0 10px var(--octo-mint-30)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-content{background:transparent;border:none;padding:0}.entity-content .entity-tabs .tab-content{padding:20px 24px;height:100%;overflow-y:auto}.entity-content .entity-tabs .tab-content .empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 40px;text-align:center}.entity-content .entity-tabs .tab-content .empty-state kendo-svgicon{font-size:64px;margin-bottom:20px;color:var(--octo-mint-40);text-shadow:0 0 20px var(--octo-mint-30)}.entity-content .entity-tabs .tab-content .empty-state p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.5);letter-spacing:.5px}.entity-content .entity-tabs .tab-content.properties-tab{padding:0;height:100%}.entity-content .entity-tabs .tab-content.properties-tab mm-property-grid{display:block;height:100%;width:100%}.entity-content .entity-tabs .tab-content.associations-tab{display:flex;flex-direction:column;gap:16px;padding:0;height:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:16px 20px;background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{display:flex;align-items:center;gap:10px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);white-space:nowrap}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist{width:160px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:220px}.entity-content .entity-tabs .tab-content.associations-tab mm-list-view{flex:1;display:block;height:calc(100% - 70px)}.entity-content .entity-tabs .tab-content.mapping-tab{padding:12px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty{display:flex;flex-direction:column;align-items:center;padding:24px 20px;text-align:center}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty kendo-svgicon{font-size:36px;margin-bottom:10px;opacity:.5}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty p{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-config{display:flex;flex-direction:column;gap:20px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section .section-header{padding:8px 14px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section .section-body{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-field{display:flex;flex-direction:column;gap:4px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-field label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display{display:flex;align-items:center;gap:8px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display .target-type{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace;padding:2px 6px;border-radius:3px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display .target-name{font-weight:600;flex:1}.entity-content .entity-tabs .tab-content.mapping-tab .field-hint{font-size:.7rem;color:var(--kendo-color-subtle, #6c757d);font-style:italic;line-height:1.3}.entity-content .entity-tabs .tab-content.mapping-tab .attribute-picker{display:flex;align-items:center;gap:8px;padding:4px 10px;border-radius:4px;border:1px solid var(--kendo-color-border, #dee2e6);background:var(--kendo-color-surface-alt, #f8f9fa);min-height:32px}.entity-content .entity-tabs .tab-content.mapping-tab .attribute-picker .attribute-value{flex:1;font-family:monospace;font-size:.85rem}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-actions{display:flex;gap:8px;justify-content:flex-end;padding-top:4px}@media(max-width:768px){.entity-content{gap:16px}.entity-content .basic-info-card{padding:16px 20px}.entity-content .basic-info-card .basic-info-grid{grid-template-columns:1fr;gap:16px}.entity-content .entity-tabs{min-height:300px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{padding-left:12px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{padding:10px 14px;font-size:.75rem}.entity-content .entity-tabs .tab-content{padding:16px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{flex-direction:column;align-items:flex-start;gap:12px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{width:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist,.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TabStripModule }, { kind: "component", type: i1$4.TabStripComponent, selector: "kendo-tabstrip", inputs: ["height", "animate", "tabAlignment", "tabPosition", "keepTabContent", "closable", "scrollable", "size", "closeIcon", "closeIconClass", "closeSVGIcon", "showContentArea"], outputs: ["tabSelect", "tabClose", "tabScroll"], exportAs: ["kendoTabStrip"] }, { kind: "component", type: i1$4.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i1$4.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i1$4.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i1$4.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i1$4.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: TextBoxModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: PropertyGridComponent, selector: "mm-property-grid", inputs: ["data", "config", "showTypeColumn"], outputs: ["propertyChange", "saveRequested", "binaryDownload"] }, { kind: "component", type: ListViewComponent, selector: "mm-list-view", inputs: ["pageSize", "skip", "rowIsClickable", "showRowCheckBoxes", "showRowSelectAllCheckBox", "contextMenuType", "leftToolbarActions", "rightToolbarActions", "actionCommandItems", "contextMenuCommandItems", "excelExportFileName", "pdfExportFileName", "pageable", "sortable", "rowFilterEnabled", "searchTextBoxEnabled", "rowClass", "messages", "selectable", "columns"], outputs: ["rowClicked"] }, { kind: "directive", type: EntityAssociationsDataSourceDirective, selector: "[mmEntityAssociationsDataSource]", exportAs: ["mmEntityAssociationsDataSource"] }, { kind: "component", type: DataMappingListComponent, selector: "mm-data-mapping-list", inputs: ["mappings", "sourceDataPoints"], outputs: ["addMapping", "removeMapping", "selectTarget", "selectSourceAttribute", "selectTargetAttribute", "mappingChanged", "saveAll"] }] });
|
|
8605
|
+
`, isInline: true, styles: [".loading-state,.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;text-align:center;min-height:200px}.loading-state .error-message,.error-state .error-message{margin-bottom:16px;font-family:Roboto,sans-serif;color:#e74c3c}.entity-content{flex:1;display:flex;flex-direction:column;gap:24px}.entity-content .basic-info-card{padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-content .basic-info-card:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-content .basic-info-card .basic-info-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:20px}.entity-content .basic-info-card .basic-info-grid .info-item{display:flex;flex-direction:column;gap:8px}.entity-content .basic-info-card .basic-info-grid .info-item label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80)}.entity-content .basic-info-card .basic-info-grid .info-item .value{font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word;background:var(--deep-sea-40);padding:8px 12px;border-radius:4px;border:1px solid var(--octo-mint-15)}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action{display:flex;align-items:center}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action .value{flex:1;font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word}.entity-content .entity-tabs{flex:1;min-height:400px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;overflow:hidden;position:relative}.entity-content .entity-tabs:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);z-index:1}.entity-content .entity-tabs ::ng-deep .k-tabstrip{background:transparent}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{background:linear-gradient(90deg,var(--octo-mint-10),transparent);border-bottom:1px solid var(--octo-mint-20);padding-left:20px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{background:transparent;border:none;color:rgba(var(--octo-text-color),.7);font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;padding:12px 20px;margin-right:4px;border-radius:4px 4px 0 0;transition:all .2s ease}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item:hover{background:var(--octo-mint-10);color:var(--octo-mint)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item.k-active{background:linear-gradient(180deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-bottom:2px solid var(--octo-mint);box-shadow:0 0 10px var(--octo-mint-30)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-content{background:transparent;border:none;padding:0}.entity-content .entity-tabs .tab-content{padding:20px 24px;height:100%;overflow-y:auto}.entity-content .entity-tabs .tab-content .empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 40px;text-align:center}.entity-content .entity-tabs .tab-content .empty-state kendo-svgicon{font-size:64px;margin-bottom:20px;color:var(--octo-mint-40);text-shadow:0 0 20px var(--octo-mint-30)}.entity-content .entity-tabs .tab-content .empty-state p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.5);letter-spacing:.5px}.entity-content .entity-tabs .tab-content.properties-tab{padding:0;height:100%}.entity-content .entity-tabs .tab-content.properties-tab mm-property-grid{display:block;height:100%;width:100%}.entity-content .entity-tabs .tab-content.associations-tab{display:flex;flex-direction:column;gap:16px;padding:0;height:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:16px 20px;background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{display:flex;align-items:center;gap:10px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);white-space:nowrap}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist{width:160px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:220px}.entity-content .entity-tabs .tab-content.associations-tab mm-list-view{flex:1;display:block;height:calc(100% - 70px)}.entity-content .entity-tabs .tab-content.mapping-tab{padding:12px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty{display:flex;flex-direction:column;align-items:center;padding:24px 20px;text-align:center}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty kendo-svgicon{font-size:36px;margin-bottom:10px;opacity:.5}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-empty p{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-config{display:flex;flex-direction:column;gap:20px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;overflow:hidden}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section .section-header{padding:8px 14px;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #ff6358)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-section .section-body{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-field{display:flex;flex-direction:column;gap:4px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-field label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display{display:flex;align-items:center;gap:8px}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display .target-type{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace;padding:2px 6px;border-radius:3px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6)}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-target-display .target-name{font-weight:600;flex:1}.entity-content .entity-tabs .tab-content.mapping-tab .field-hint{font-size:.7rem;color:var(--kendo-color-subtle, #6c757d);font-style:italic;line-height:1.3}.entity-content .entity-tabs .tab-content.mapping-tab .attribute-picker{display:flex;align-items:center;gap:8px;padding:4px 10px;border-radius:4px;border:1px solid var(--kendo-color-border, #dee2e6);background:var(--kendo-color-surface-alt, #f8f9fa);min-height:32px}.entity-content .entity-tabs .tab-content.mapping-tab .attribute-picker .attribute-value{flex:1;font-family:monospace;font-size:.85rem}.entity-content .entity-tabs .tab-content.mapping-tab .mapping-actions{display:flex;gap:8px;justify-content:flex-end;padding-top:4px}@media(max-width:768px){.entity-content{gap:16px}.entity-content .basic-info-card{padding:16px 20px}.entity-content .basic-info-card .basic-info-grid{grid-template-columns:1fr;gap:16px}.entity-content .entity-tabs{min-height:300px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{padding-left:12px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{padding:10px 14px;font-size:.75rem}.entity-content .entity-tabs .tab-content{padding:16px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{flex-direction:column;align-items:flex-start;gap:12px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{width:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist,.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TabStripModule }, { kind: "component", type: i1$4.TabStripComponent, selector: "kendo-tabstrip", inputs: ["height", "animate", "tabAlignment", "tabPosition", "keepTabContent", "closable", "scrollable", "size", "closeIcon", "closeIconClass", "closeSVGIcon", "showContentArea"], outputs: ["tabSelect", "tabClose", "tabScroll"], exportAs: ["kendoTabStrip"] }, { kind: "component", type: i1$4.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i1$4.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i1$4.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i1$4.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i1$4.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: TextBoxModule }, { kind: "component", type: i5.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: PropertyGridComponent, selector: "mm-property-grid", inputs: ["data", "config", "showTypeColumn"], outputs: ["propertyChange", "saveRequested", "binaryDownload"] }, { kind: "component", type: ListViewComponent, selector: "mm-list-view", inputs: ["pageSize", "skip", "rowIsClickable", "showRowCheckBoxes", "showRowSelectAllCheckBox", "contextMenuType", "leftToolbarActions", "rightToolbarActions", "actionCommandItems", "contextMenuCommandItems", "excelExportFileName", "pdfExportFileName", "pageable", "sortable", "rowFilterEnabled", "searchTextBoxEnabled", "rowClass", "messages", "selectable", "columns"], outputs: ["rowClicked"] }, { kind: "directive", type: EntityAssociationsDataSourceDirective, selector: "[mmEntityAssociationsDataSource]", exportAs: ["mmEntityAssociationsDataSource"] }, { kind: "component", type: DataMappingListComponent, selector: "mm-data-mapping-list", inputs: ["mappings", "sourceDataPoints", "expressionValidator"], outputs: ["addMapping", "removeMapping", "selectTarget", "selectSourceAttribute", "selectTargetAttribute", "mappingChanged", "navigateToTarget", "saveAll"] }] });
|
|
7829
8606
|
}
|
|
7830
8607
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EntityDetailViewComponent, decorators: [{
|
|
7831
8608
|
type: Component,
|
|
@@ -8058,12 +8835,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
8058
8835
|
<mm-data-mapping-list
|
|
8059
8836
|
[mappings]="dataMappings"
|
|
8060
8837
|
[sourceDataPoints]="sourceDataPoints"
|
|
8838
|
+
[expressionValidator]="expressionValidator"
|
|
8061
8839
|
(addMapping)="addMappingRequested.emit()"
|
|
8062
8840
|
(removeMapping)="removeMappingRequested.emit($event)"
|
|
8063
8841
|
(selectTarget)="selectMappingTarget.emit($event)"
|
|
8064
8842
|
(selectSourceAttribute)="selectSourceAttributeRequested.emit($event)"
|
|
8065
8843
|
(selectTargetAttribute)="selectTargetAttributeRequested.emit($event)"
|
|
8066
8844
|
(mappingChanged)="mappingChanged.emit($event)"
|
|
8845
|
+
(navigateToTarget)="onNavigateToMappingTarget($event)"
|
|
8067
8846
|
(saveAll)="saveAllMappingsRequested.emit()"
|
|
8068
8847
|
></mm-data-mapping-list>
|
|
8069
8848
|
</div>
|
|
@@ -8090,6 +8869,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
8090
8869
|
type: Input
|
|
8091
8870
|
}], sourceDataPoints: [{
|
|
8092
8871
|
type: Input
|
|
8872
|
+
}], expressionValidator: [{
|
|
8873
|
+
type: Input
|
|
8093
8874
|
}], retry: [{
|
|
8094
8875
|
type: Output
|
|
8095
8876
|
}], propertyChange: [{
|
|
@@ -8609,7 +9390,7 @@ class EntityDetailComponent {
|
|
|
8609
9390
|
>
|
|
8610
9391
|
</mm-entity-detail-view>
|
|
8611
9392
|
</div>
|
|
8612
|
-
`, isInline: true, styles: [":host{display:block;height:100%;width:100%}.entity-detail{height:100%;display:flex;flex-direction:column;padding:24px;box-sizing:border-box;overflow-y:auto}.entity-detail .entity-detail-header{display:flex;align-items:center;gap:20px;margin-bottom:24px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-detail .entity-detail-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-detail .entity-detail-header .header-info{flex:1}.entity-detail .entity-detail-header .header-info .entity-title h2{margin:0 0 8px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color);text-shadow:0 0 10px rgba(0,0,0,.3)}.entity-detail .entity-detail-header .header-info .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;background:var(--deep-sea-60);padding:6px 12px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block;color:var(--neo-cyan)}.entity-detail mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}@media(max-width:768px){.entity-detail{padding:16px}.entity-detail .entity-detail-header{flex-direction:column;align-items:flex-start;gap:12px;padding:16px 20px}.entity-detail .entity-detail-header .header-info .entity-title h2{font-size:1.1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages", "showDataMapping", "dataMappings", "sourceDataPoints"], outputs: ["retry", "propertyChange", "navigateToEntity", "addMappingRequested", "removeMappingRequested", "selectMappingTarget", "selectSourceAttributeRequested", "selectTargetAttributeRequested", "mappingChanged", "saveAllMappingsRequested"] }] });
|
|
9393
|
+
`, isInline: true, styles: [":host{display:block;height:100%;width:100%}.entity-detail{height:100%;display:flex;flex-direction:column;padding:24px;box-sizing:border-box;overflow-y:auto}.entity-detail .entity-detail-header{display:flex;align-items:center;gap:20px;margin-bottom:24px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-detail .entity-detail-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-detail .entity-detail-header .header-info{flex:1}.entity-detail .entity-detail-header .header-info .entity-title h2{margin:0 0 8px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color);text-shadow:0 0 10px rgba(0,0,0,.3)}.entity-detail .entity-detail-header .header-info .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;background:var(--deep-sea-60);padding:6px 12px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block;color:var(--neo-cyan)}.entity-detail mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}@media(max-width:768px){.entity-detail{padding:16px}.entity-detail .entity-detail-header{flex-direction:column;align-items:flex-start;gap:12px;padding:16px 20px}.entity-detail .entity-detail-header .header-info .entity-title h2{font-size:1.1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages", "showDataMapping", "dataMappings", "sourceDataPoints", "expressionValidator"], outputs: ["retry", "propertyChange", "navigateToEntity", "addMappingRequested", "removeMappingRequested", "selectMappingTarget", "selectSourceAttributeRequested", "selectTargetAttributeRequested", "mappingChanged", "saveAllMappingsRequested"] }] });
|
|
8613
9394
|
}
|
|
8614
9395
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EntityDetailComponent, decorators: [{
|
|
8615
9396
|
type: Component,
|
|
@@ -11975,6 +12756,10 @@ class RuntimeBrowserDetailsComponent {
|
|
|
11975
12756
|
// Data Mapping state (list of DataPointMapping entities)
|
|
11976
12757
|
dataMappings = [];
|
|
11977
12758
|
sourceDataPoints = [];
|
|
12759
|
+
/**
|
|
12760
|
+
* Optional expression validator function passed through to EntityDetailViewComponent → DataMappingListComponent.
|
|
12761
|
+
*/
|
|
12762
|
+
expressionValidator;
|
|
11978
12763
|
detailsIcon = eyeIcon;
|
|
11979
12764
|
fullEntity = null;
|
|
11980
12765
|
loadRequestToken = 0;
|
|
@@ -12654,7 +13439,7 @@ class RuntimeBrowserDetailsComponent {
|
|
|
12654
13439
|
}
|
|
12655
13440
|
}
|
|
12656
13441
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12657
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RuntimeBrowserDetailsComponent, isStandalone: true, selector: "mm-runtime-browser-details", inputs: { selectedItem: "selectedItem", showDataMapping: "showDataMapping", messages: "messages" }, outputs: { entitySaved: "entitySaved" }, viewQueries: [{ propertyName: "dataSourceDirective", first: true, predicate: ["dir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
13442
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RuntimeBrowserDetailsComponent, isStandalone: true, selector: "mm-runtime-browser-details", inputs: { selectedItem: "selectedItem", showDataMapping: "showDataMapping", messages: "messages", expressionValidator: "expressionValidator" }, outputs: { entitySaved: "entitySaved" }, viewQueries: [{ propertyName: "dataSourceDirective", first: true, predicate: ["dir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
12658
13443
|
<div class="runtime-browser-details">
|
|
12659
13444
|
@if (isCreateModeEnabled) {
|
|
12660
13445
|
<mm-create-editor-component
|
|
@@ -12696,6 +13481,7 @@ class RuntimeBrowserDetailsComponent {
|
|
|
12696
13481
|
[showDataMapping]="showDataMapping"
|
|
12697
13482
|
[dataMappings]="dataMappings"
|
|
12698
13483
|
[sourceDataPoints]="sourceDataPoints"
|
|
13484
|
+
[expressionValidator]="expressionValidator"
|
|
12699
13485
|
(retry)="loadFullEntityDetails()"
|
|
12700
13486
|
(navigateToEntity)="
|
|
12701
13487
|
navigateToEntity($event.rtId, $event.ckTypeId)
|
|
@@ -12794,7 +13580,7 @@ class RuntimeBrowserDetailsComponent {
|
|
|
12794
13580
|
}
|
|
12795
13581
|
}
|
|
12796
13582
|
</div>
|
|
12797
|
-
`, isInline: true, styles: [":host{display:block;height:100%;width:100%}.runtime-browser-details{display:flex;flex-direction:column;flex:1;min-height:0;padding:24px;box-sizing:border-box;overflow-y:auto;background:linear-gradient(180deg,var(--surface-elevated) 0%,var(--deep-sea) 100%)}.runtime-browser-details .no-selection{display:flex;align-items:center;justify-content:center;flex:1;min-height:0}.runtime-browser-details .no-selection .placeholder-content{text-align:center;max-width:400px;padding:40px;background:linear-gradient(135deg,var(--iron-navy-80),var(--surface-elevated-90));border:1px solid var(--octo-mint-30);border-radius:8px 24px;box-shadow:0 0 30px var(--octo-mint-10),inset 0 0 40px var(--octo-mint-03)}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon{margin-bottom:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:64px;color:var(--octo-mint-50);text-shadow:0 0 20px var(--octo-mint-50);animation:lcars-icon-pulse 3s ease-in-out infinite}.runtime-browser-details .no-selection .placeholder-content h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:700;letter-spacing:2px;text-transform:uppercase;color:var(--octo-mint);text-shadow:0 0 15px var(--octo-mint-50)}.runtime-browser-details .no-selection .placeholder-content p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;line-height:1.6;color:rgba(var(--octo-text-color),.7);letter-spacing:.5px}.runtime-browser-details .entity-details{height:100%;display:flex;flex-direction:column;overflow:hidden}.runtime-browser-details .entity-details .details-header{display:flex;align-items:center;gap:16px;padding:16px 20px 16px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;margin-bottom:20px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.runtime-browser-details .entity-details .details-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.runtime-browser-details .entity-details .details-header .entity-icon{font-size:28px;color:var(--octo-mint);text-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .details-header .entity-title{flex:1}.runtime-browser-details .entity-details .details-header .entity-title h3{margin:0 0 6px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .details-header .entity-title .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block}.runtime-browser-details .entity-details mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}.runtime-browser-details .entity-details .ck-model-details,.runtime-browser-details .entity-details .ck-models-root{padding:24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-model-details:before,.runtime-browser-details .entity-details .ck-models-root:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-model-details h3,.runtime-browser-details .entity-details .ck-models-root h3{margin:0 0 20px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-model-details p,.runtime-browser-details .entity-details .ck-models-root p{margin:0 0 12px;font-family:Roboto,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.85)}.runtime-browser-details .entity-details .ck-model-details p strong,.runtime-browser-details .entity-details .ck-models-root p strong{font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);margin-right:12px}.runtime-browser-details .entity-details .ck-model-details p.info-text,.runtime-browser-details .entity-details .ck-models-root p.info-text{color:rgba(var(--octo-text-color),.6);font-style:italic;margin-top:24px;padding:16px 20px;background:linear-gradient(135deg,var(--neo-cyan-10),var(--neo-cyan-05));border:1px solid var(--neo-cyan-30);border-radius:4px 12px}.runtime-browser-details .entity-details .ck-type-details{display:flex;flex-direction:column;height:100%;padding:0}.runtime-browser-details .entity-details .ck-type-details .type-header{margin-bottom:20px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-type-details .type-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-type-details .type-header h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata{display:flex;gap:10px;align-items:center}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge{padding:6px 14px;border-radius:4px;font-family:Montserrat,sans-serif;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.abstract{background:linear-gradient(135deg,var(--royal-violet-30),var(--royal-violet-15));border:1px solid var(--royal-violet-50);color:var(--royal-violet-light-20);box-shadow:0 0 10px var(--royal-violet-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.final{background:linear-gradient(135deg,var(--toffee-30),var(--toffee-15));border:1px solid var(--toffee-50);color:var(--toffee);box-shadow:0 0 10px var(--toffee-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .base-type{font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30)}.runtime-browser-details .entity-details .ck-type-details .entities-table{flex:1;display:flex;flex-direction:column;overflow:hidden;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;padding:20px}.runtime-browser-details .entity-details .ck-type-details .entities-table h4{margin:0 0 16px;font-family:Montserrat,sans-serif;font-size:1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-mint)}.runtime-browser-details .entity-details .ck-type-details .entities-table mm-list-view{flex:1;display:flex;flex-direction:column;overflow:hidden}@keyframes lcars-icon-pulse{0%,to{opacity:.5;transform:scale(1)}50%{opacity:.8;transform:scale(1.05)}}@media(max-width:768px){.runtime-browser-details{padding:16px}.runtime-browser-details .no-selection .placeholder-content{padding:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:48px}.runtime-browser-details .no-selection .placeholder-content h3{font-size:1.1rem}.runtime-browser-details .entity-details .details-header{flex-direction:column;align-items:flex-start;gap:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages", "showDataMapping", "dataMappings", "sourceDataPoints"], outputs: ["retry", "propertyChange", "navigateToEntity", "addMappingRequested", "removeMappingRequested", "selectMappingTarget", "selectSourceAttributeRequested", "selectTargetAttributeRequested", "mappingChanged", "saveAllMappingsRequested"] }, { kind: "component", type: ListViewComponent, selector: "mm-list-view", inputs: ["pageSize", "skip", "rowIsClickable", "showRowCheckBoxes", "showRowSelectAllCheckBox", "contextMenuType", "leftToolbarActions", "rightToolbarActions", "actionCommandItems", "contextMenuCommandItems", "excelExportFileName", "pdfExportFileName", "pageable", "sortable", "rowFilterEnabled", "searchTextBoxEnabled", "rowClass", "messages", "selectable", "columns"], outputs: ["rowClicked"] }, { kind: "directive", type: CkTypeEntitiesDataSourceDirective, selector: "[mmCkTypeEntitiesDataSource]", exportAs: ["mmCkTypeEntitiesDataSource"] }, { kind: "component", type: CreateEditorComponent, selector: "mm-create-editor-component", inputs: ["createInput", "messages"], outputs: ["createOutput", "cancelRequested"] }, { kind: "component", type: UpdateEditorComponent, selector: "mm-update-editor-component", inputs: ["updateInput", "messages"], outputs: ["updateOutput", "cancelRequested"] }] });
|
|
13583
|
+
`, isInline: true, styles: [":host{display:block;height:100%;width:100%}.runtime-browser-details{display:flex;flex-direction:column;flex:1;min-height:0;padding:24px;box-sizing:border-box;overflow-y:auto;background:linear-gradient(180deg,var(--surface-elevated) 0%,var(--deep-sea) 100%)}.runtime-browser-details .no-selection{display:flex;align-items:center;justify-content:center;flex:1;min-height:0}.runtime-browser-details .no-selection .placeholder-content{text-align:center;max-width:400px;padding:40px;background:linear-gradient(135deg,var(--iron-navy-80),var(--surface-elevated-90));border:1px solid var(--octo-mint-30);border-radius:8px 24px;box-shadow:0 0 30px var(--octo-mint-10),inset 0 0 40px var(--octo-mint-03)}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon{margin-bottom:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:64px;color:var(--octo-mint-50);text-shadow:0 0 20px var(--octo-mint-50);animation:lcars-icon-pulse 3s ease-in-out infinite}.runtime-browser-details .no-selection .placeholder-content h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:700;letter-spacing:2px;text-transform:uppercase;color:var(--octo-mint);text-shadow:0 0 15px var(--octo-mint-50)}.runtime-browser-details .no-selection .placeholder-content p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;line-height:1.6;color:rgba(var(--octo-text-color),.7);letter-spacing:.5px}.runtime-browser-details .entity-details{height:100%;display:flex;flex-direction:column;overflow:hidden}.runtime-browser-details .entity-details .details-header{display:flex;align-items:center;gap:16px;padding:16px 20px 16px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;margin-bottom:20px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.runtime-browser-details .entity-details .details-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.runtime-browser-details .entity-details .details-header .entity-icon{font-size:28px;color:var(--octo-mint);text-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .details-header .entity-title{flex:1}.runtime-browser-details .entity-details .details-header .entity-title h3{margin:0 0 6px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .details-header .entity-title .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block}.runtime-browser-details .entity-details mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}.runtime-browser-details .entity-details .ck-model-details,.runtime-browser-details .entity-details .ck-models-root{padding:24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-model-details:before,.runtime-browser-details .entity-details .ck-models-root:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-model-details h3,.runtime-browser-details .entity-details .ck-models-root h3{margin:0 0 20px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-model-details p,.runtime-browser-details .entity-details .ck-models-root p{margin:0 0 12px;font-family:Roboto,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.85)}.runtime-browser-details .entity-details .ck-model-details p strong,.runtime-browser-details .entity-details .ck-models-root p strong{font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);margin-right:12px}.runtime-browser-details .entity-details .ck-model-details p.info-text,.runtime-browser-details .entity-details .ck-models-root p.info-text{color:rgba(var(--octo-text-color),.6);font-style:italic;margin-top:24px;padding:16px 20px;background:linear-gradient(135deg,var(--neo-cyan-10),var(--neo-cyan-05));border:1px solid var(--neo-cyan-30);border-radius:4px 12px}.runtime-browser-details .entity-details .ck-type-details{display:flex;flex-direction:column;height:100%;padding:0}.runtime-browser-details .entity-details .ck-type-details .type-header{margin-bottom:20px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-type-details .type-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-type-details .type-header h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata{display:flex;gap:10px;align-items:center}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge{padding:6px 14px;border-radius:4px;font-family:Montserrat,sans-serif;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.abstract{background:linear-gradient(135deg,var(--royal-violet-30),var(--royal-violet-15));border:1px solid var(--royal-violet-50);color:var(--royal-violet-light-20);box-shadow:0 0 10px var(--royal-violet-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.final{background:linear-gradient(135deg,var(--toffee-30),var(--toffee-15));border:1px solid var(--toffee-50);color:var(--toffee);box-shadow:0 0 10px var(--toffee-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .base-type{font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30)}.runtime-browser-details .entity-details .ck-type-details .entities-table{flex:1;display:flex;flex-direction:column;overflow:hidden;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;padding:20px}.runtime-browser-details .entity-details .ck-type-details .entities-table h4{margin:0 0 16px;font-family:Montserrat,sans-serif;font-size:1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-mint)}.runtime-browser-details .entity-details .ck-type-details .entities-table mm-list-view{flex:1;display:flex;flex-direction:column;overflow:hidden}@keyframes lcars-icon-pulse{0%,to{opacity:.5;transform:scale(1)}50%{opacity:.8;transform:scale(1.05)}}@media(max-width:768px){.runtime-browser-details{padding:16px}.runtime-browser-details .no-selection .placeholder-content{padding:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:48px}.runtime-browser-details .no-selection .placeholder-content h3{font-size:1.1rem}.runtime-browser-details .entity-details .details-header{flex-direction:column;align-items:flex-start;gap:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages", "showDataMapping", "dataMappings", "sourceDataPoints", "expressionValidator"], outputs: ["retry", "propertyChange", "navigateToEntity", "addMappingRequested", "removeMappingRequested", "selectMappingTarget", "selectSourceAttributeRequested", "selectTargetAttributeRequested", "mappingChanged", "saveAllMappingsRequested"] }, { kind: "component", type: ListViewComponent, selector: "mm-list-view", inputs: ["pageSize", "skip", "rowIsClickable", "showRowCheckBoxes", "showRowSelectAllCheckBox", "contextMenuType", "leftToolbarActions", "rightToolbarActions", "actionCommandItems", "contextMenuCommandItems", "excelExportFileName", "pdfExportFileName", "pageable", "sortable", "rowFilterEnabled", "searchTextBoxEnabled", "rowClass", "messages", "selectable", "columns"], outputs: ["rowClicked"] }, { kind: "directive", type: CkTypeEntitiesDataSourceDirective, selector: "[mmCkTypeEntitiesDataSource]", exportAs: ["mmCkTypeEntitiesDataSource"] }, { kind: "component", type: CreateEditorComponent, selector: "mm-create-editor-component", inputs: ["createInput", "messages"], outputs: ["createOutput", "cancelRequested"] }, { kind: "component", type: UpdateEditorComponent, selector: "mm-update-editor-component", inputs: ["updateInput", "messages"], outputs: ["updateOutput", "cancelRequested"] }] });
|
|
12798
13584
|
}
|
|
12799
13585
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserDetailsComponent, decorators: [{
|
|
12800
13586
|
type: Component,
|
|
@@ -12849,6 +13635,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
12849
13635
|
[showDataMapping]="showDataMapping"
|
|
12850
13636
|
[dataMappings]="dataMappings"
|
|
12851
13637
|
[sourceDataPoints]="sourceDataPoints"
|
|
13638
|
+
[expressionValidator]="expressionValidator"
|
|
12852
13639
|
(retry)="loadFullEntityDetails()"
|
|
12853
13640
|
(navigateToEntity)="
|
|
12854
13641
|
navigateToEntity($event.rtId, $event.ckTypeId)
|
|
@@ -12959,6 +13746,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
12959
13746
|
}], dataSourceDirective: [{
|
|
12960
13747
|
type: ViewChild,
|
|
12961
13748
|
args: ["dir", { static: false }]
|
|
13749
|
+
}], expressionValidator: [{
|
|
13750
|
+
type: Input
|
|
12962
13751
|
}] } });
|
|
12963
13752
|
|
|
12964
13753
|
class RuntimeBrowserComponent {
|
|
@@ -12977,6 +13766,11 @@ class RuntimeBrowserComponent {
|
|
|
12977
13766
|
isEditing = false;
|
|
12978
13767
|
messages = input({}, ...(ngDevMode ? [{ debugName: "messages" }] : /* istanbul ignore next */ []));
|
|
12979
13768
|
showDataMapping = input(true, ...(ngDevMode ? [{ debugName: "showDataMapping" }] : /* istanbul ignore next */ []));
|
|
13769
|
+
/**
|
|
13770
|
+
* Optional expression validator function for DataPointMapping expressions.
|
|
13771
|
+
* Passed through to RuntimeBrowserDetailsComponent → EntityDetailViewComponent → DataMappingListComponent.
|
|
13772
|
+
*/
|
|
13773
|
+
expressionValidator = input(undefined, ...(ngDevMode ? [{ debugName: "expressionValidator" }] : /* istanbul ignore next */ []));
|
|
12980
13774
|
resolvedMessages = computed(() => ({
|
|
12981
13775
|
...DEFAULT_RUNTIME_BROWSER_MESSAGES,
|
|
12982
13776
|
...this.messages(),
|
|
@@ -13538,7 +14332,7 @@ class RuntimeBrowserComponent {
|
|
|
13538
14332
|
}
|
|
13539
14333
|
}
|
|
13540
14334
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13541
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: RuntimeBrowserComponent, isStandalone: true, selector: "mm-runtime-browser", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, showDataMapping: { classPropertyName: "showDataMapping", publicName: "showDataMapping", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "treeDetail", first: true, predicate: ["treeDetail"], descendants: true }, { propertyName: "detailsPanel", first: true, predicate: ["detailsPanel"], descendants: true }], ngImport: i0, template: `
|
|
14335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: RuntimeBrowserComponent, isStandalone: true, selector: "mm-runtime-browser", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, showDataMapping: { classPropertyName: "showDataMapping", publicName: "showDataMapping", isSignal: true, isRequired: false, transformFunction: null }, expressionValidator: { classPropertyName: "expressionValidator", publicName: "expressionValidator", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "treeDetail", first: true, predicate: ["treeDetail"], descendants: true }, { propertyName: "detailsPanel", first: true, predicate: ["detailsPanel"], descendants: true }], ngImport: i0, template: `
|
|
13542
14336
|
<div class="runtime-browser-container kendo-theme-provider">
|
|
13543
14337
|
<!-- LCARS Header -->
|
|
13544
14338
|
<div class="lcars-page-header">
|
|
@@ -13580,6 +14374,7 @@ class RuntimeBrowserComponent {
|
|
|
13580
14374
|
[selectedItem]="selectedItem"
|
|
13581
14375
|
[messages]="resolvedMessages()"
|
|
13582
14376
|
[showDataMapping]="showDataMapping()"
|
|
14377
|
+
[expressionValidator]="expressionValidator()"
|
|
13583
14378
|
(entitySaved)="onEntitySaved($event)"
|
|
13584
14379
|
>
|
|
13585
14380
|
</mm-runtime-browser-details>
|
|
@@ -13599,7 +14394,7 @@ class RuntimeBrowserComponent {
|
|
|
13599
14394
|
</div>
|
|
13600
14395
|
</div>
|
|
13601
14396
|
</div>
|
|
13602
|
-
`, isInline: true, styles: [".runtime-browser-container{display:flex;flex-direction:column;height:100%;padding:16px;gap:16px}::ng-deep mm-base-tree-detail .k-splitter{background:transparent;border:none}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar{background:linear-gradient(180deg,var(--octo-mint-30),transparent);width:4px!important}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar:hover{background:linear-gradient(180deg,var(--octo-mint-50),var(--octo-mint-20))}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf{font-family:Roboto,sans-serif;transition:all .2s ease;border-radius:4px}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf:hover{background:var(--octo-mint-10);color:var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected{background:linear-gradient(90deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-left:3px solid var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected:hover{background:linear-gradient(90deg,var(--octo-mint-25),transparent)}::ng-deep mm-base-tree-detail .toolbar{background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}::ng-deep mm-base-tree-detail .base-tree-detail-container{height:100%;display:flex;flex-direction:column}::ng-deep mm-base-tree-detail .base-tree-detail-container .k-splitter{flex:1;min-height:0}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane{display:flex!important;flex-direction:column!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details{display:flex!important;flex:1!important;min-height:0!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details>.runtime-browser-details{flex:1;display:flex;flex-direction:column;min-height:0}@media(max-width:1024px){.runtime-browser-container{padding:12px;gap:12px}}@media(max-width:768px){.runtime-browser-container{padding:8px;gap:10px}}\n"], dependencies: [{ kind: "component", type: BaseTreeDetailComponent, selector: "mm-base-tree-detail", inputs: ["treeDataSource", "leftPaneSize", "leftToolbarActions", "rightToolbarActions"], outputs: ["nodeSelected", "nodeDropped"] }, { kind: "component", type: RuntimeBrowserDetailsComponent, selector: "mm-runtime-browser-details", inputs: ["selectedItem", "showDataMapping", "messages"], outputs: ["entitySaved"] }] });
|
|
14397
|
+
`, isInline: true, styles: [".runtime-browser-container{display:flex;flex-direction:column;height:100%;padding:16px;gap:16px}::ng-deep mm-base-tree-detail .k-splitter{background:transparent;border:none}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar{background:linear-gradient(180deg,var(--octo-mint-30),transparent);width:4px!important}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar:hover{background:linear-gradient(180deg,var(--octo-mint-50),var(--octo-mint-20))}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf{font-family:Roboto,sans-serif;transition:all .2s ease;border-radius:4px}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf:hover{background:var(--octo-mint-10);color:var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected{background:linear-gradient(90deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-left:3px solid var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected:hover{background:linear-gradient(90deg,var(--octo-mint-25),transparent)}::ng-deep mm-base-tree-detail .toolbar{background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}::ng-deep mm-base-tree-detail .base-tree-detail-container{height:100%;display:flex;flex-direction:column}::ng-deep mm-base-tree-detail .base-tree-detail-container .k-splitter{flex:1;min-height:0}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane{display:flex!important;flex-direction:column!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details{display:flex!important;flex:1!important;min-height:0!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details>.runtime-browser-details{flex:1;display:flex;flex-direction:column;min-height:0}@media(max-width:1024px){.runtime-browser-container{padding:12px;gap:12px}}@media(max-width:768px){.runtime-browser-container{padding:8px;gap:10px}}\n"], dependencies: [{ kind: "component", type: BaseTreeDetailComponent, selector: "mm-base-tree-detail", inputs: ["treeDataSource", "leftPaneSize", "leftToolbarActions", "rightToolbarActions"], outputs: ["nodeSelected", "nodeDropped"] }, { kind: "component", type: RuntimeBrowserDetailsComponent, selector: "mm-runtime-browser-details", inputs: ["selectedItem", "showDataMapping", "messages", "expressionValidator"], outputs: ["entitySaved"] }] });
|
|
13603
14398
|
}
|
|
13604
14399
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserComponent, decorators: [{
|
|
13605
14400
|
type: Component,
|
|
@@ -13645,6 +14440,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
13645
14440
|
[selectedItem]="selectedItem"
|
|
13646
14441
|
[messages]="resolvedMessages()"
|
|
13647
14442
|
[showDataMapping]="showDataMapping()"
|
|
14443
|
+
[expressionValidator]="expressionValidator()"
|
|
13648
14444
|
(entitySaved)="onEntitySaved($event)"
|
|
13649
14445
|
>
|
|
13650
14446
|
</mm-runtime-browser-details>
|
|
@@ -13665,7 +14461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
13665
14461
|
</div>
|
|
13666
14462
|
</div>
|
|
13667
14463
|
`, styles: [".runtime-browser-container{display:flex;flex-direction:column;height:100%;padding:16px;gap:16px}::ng-deep mm-base-tree-detail .k-splitter{background:transparent;border:none}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar{background:linear-gradient(180deg,var(--octo-mint-30),transparent);width:4px!important}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar:hover{background:linear-gradient(180deg,var(--octo-mint-50),var(--octo-mint-20))}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf{font-family:Roboto,sans-serif;transition:all .2s ease;border-radius:4px}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf:hover{background:var(--octo-mint-10);color:var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected{background:linear-gradient(90deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-left:3px solid var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected:hover{background:linear-gradient(90deg,var(--octo-mint-25),transparent)}::ng-deep mm-base-tree-detail .toolbar{background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}::ng-deep mm-base-tree-detail .base-tree-detail-container{height:100%;display:flex;flex-direction:column}::ng-deep mm-base-tree-detail .base-tree-detail-container .k-splitter{flex:1;min-height:0}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane{display:flex!important;flex-direction:column!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details{display:flex!important;flex:1!important;min-height:0!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details>.runtime-browser-details{flex:1;display:flex;flex-direction:column;min-height:0}@media(max-width:1024px){.runtime-browser-container{padding:12px;gap:12px}}@media(max-width:768px){.runtime-browser-container{padding:8px;gap:10px}}\n"] }]
|
|
13668
|
-
}], propDecorators: { messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], showDataMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDataMapping", required: false }] }], treeDetail: [{
|
|
14464
|
+
}], propDecorators: { messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], showDataMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDataMapping", required: false }] }], expressionValidator: [{ type: i0.Input, args: [{ isSignal: true, alias: "expressionValidator", required: false }] }], treeDetail: [{
|
|
13669
14465
|
type: ViewChild,
|
|
13670
14466
|
args: ['treeDetail', { static: false }]
|
|
13671
14467
|
}], detailsPanel: [{
|
|
@@ -13709,7 +14505,7 @@ class RuntimeBrowserPageComponent {
|
|
|
13709
14505
|
? this.injectedMessages
|
|
13710
14506
|
: DEFAULT_RUNTIME_BROWSER_MESSAGES;
|
|
13711
14507
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13712
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: RuntimeBrowserPageComponent, isStandalone: true, selector: "mm-runtime-browser-page", ngImport: i0, template: `<mm-runtime-browser [messages]="messages" />`, isInline: true, dependencies: [{ kind: "component", type: RuntimeBrowserComponent, selector: "mm-runtime-browser", inputs: ["messages", "showDataMapping"] }] });
|
|
14508
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: RuntimeBrowserPageComponent, isStandalone: true, selector: "mm-runtime-browser-page", ngImport: i0, template: `<mm-runtime-browser [messages]="messages" />`, isInline: true, dependencies: [{ kind: "component", type: RuntimeBrowserComponent, selector: "mm-runtime-browser", inputs: ["messages", "showDataMapping", "expressionValidator"] }] });
|
|
13713
14509
|
}
|
|
13714
14510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RuntimeBrowserPageComponent, decorators: [{
|
|
13715
14511
|
type: Component,
|
|
@@ -13778,6 +14574,630 @@ function createRuntimeBrowserRoutes(options) {
|
|
|
13778
14574
|
return [mainRoute, entityRoute];
|
|
13779
14575
|
}
|
|
13780
14576
|
|
|
14577
|
+
const GetDataPointMappingsDocumentDto = gql `
|
|
14578
|
+
query getDataPointMappings($ckTypeId: String!, $after: String, $first: Int, $fieldFilters: [FieldFilter], $sort: [Sort]) {
|
|
14579
|
+
runtime {
|
|
14580
|
+
runtimeEntities(
|
|
14581
|
+
ckId: $ckTypeId
|
|
14582
|
+
after: $after
|
|
14583
|
+
first: $first
|
|
14584
|
+
fieldFilter: $fieldFilters
|
|
14585
|
+
sortOrder: $sort
|
|
14586
|
+
) {
|
|
14587
|
+
totalCount
|
|
14588
|
+
pageInfo {
|
|
14589
|
+
endCursor
|
|
14590
|
+
hasNextPage
|
|
14591
|
+
}
|
|
14592
|
+
items {
|
|
14593
|
+
rtId
|
|
14594
|
+
ckTypeId
|
|
14595
|
+
rtWellKnownName
|
|
14596
|
+
attributes(resolveEnumValuesToNames: true) {
|
|
14597
|
+
items {
|
|
14598
|
+
attributeName
|
|
14599
|
+
value
|
|
14600
|
+
}
|
|
14601
|
+
}
|
|
14602
|
+
associations {
|
|
14603
|
+
definitions(direction: OUTBOUND, first: 10) {
|
|
14604
|
+
items {
|
|
14605
|
+
targetRtId
|
|
14606
|
+
targetCkTypeId
|
|
14607
|
+
originRtId
|
|
14608
|
+
originCkTypeId
|
|
14609
|
+
ckAssociationRoleId
|
|
14610
|
+
}
|
|
14611
|
+
}
|
|
14612
|
+
}
|
|
14613
|
+
}
|
|
14614
|
+
}
|
|
14615
|
+
}
|
|
14616
|
+
}
|
|
14617
|
+
`;
|
|
14618
|
+
class GetDataPointMappingsDtoGQL extends i1$3.Query {
|
|
14619
|
+
document = GetDataPointMappingsDocumentDto;
|
|
14620
|
+
constructor(apollo) {
|
|
14621
|
+
super(apollo);
|
|
14622
|
+
}
|
|
14623
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetDataPointMappingsDtoGQL, deps: [{ token: i1$3.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
14624
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetDataPointMappingsDtoGQL, providedIn: 'root' });
|
|
14625
|
+
}
|
|
14626
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetDataPointMappingsDtoGQL, decorators: [{
|
|
14627
|
+
type: Injectable,
|
|
14628
|
+
args: [{
|
|
14629
|
+
providedIn: 'root'
|
|
14630
|
+
}]
|
|
14631
|
+
}], ctorParameters: () => [{ type: i1$3.Apollo }] });
|
|
14632
|
+
|
|
14633
|
+
const DATA_POINT_MAPPING_CK_TYPE = 'System.Communication/DataPointMapping';
|
|
14634
|
+
class DataMappingOverviewComponent {
|
|
14635
|
+
getMappingsGQL = inject(GetDataPointMappingsDtoGQL);
|
|
14636
|
+
getEntityByIdGQL = inject(GetRuntimeEntityByIdDtoGQL);
|
|
14637
|
+
updateEntitiesGQL = inject(UpdateRuntimeEntitiesDtoGQL);
|
|
14638
|
+
deleteEntitiesGQL = inject(DeleteEntitiesDtoGQL);
|
|
14639
|
+
navigateToEntity = new EventEmitter();
|
|
14640
|
+
// State
|
|
14641
|
+
mappings = signal([], ...(ngDevMode ? [{ debugName: "mappings" }] : /* istanbul ignore next */ []));
|
|
14642
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
14643
|
+
selectedMapping = signal(null, ...(ngDevMode ? [{ debugName: "selectedMapping" }] : /* istanbul ignore next */ []));
|
|
14644
|
+
pageSize = 20;
|
|
14645
|
+
skip = 0;
|
|
14646
|
+
gridData = computed(() => ({
|
|
14647
|
+
data: this.mappings().slice(this.skip, this.skip + this.pageSize),
|
|
14648
|
+
total: this.mappings().length,
|
|
14649
|
+
}), ...(ngDevMode ? [{ debugName: "gridData" }] : /* istanbul ignore next */ []));
|
|
14650
|
+
summary = computed(() => {
|
|
14651
|
+
const items = this.mappings();
|
|
14652
|
+
return {
|
|
14653
|
+
total: items.length,
|
|
14654
|
+
valid: items.filter(m => m.validationStatus === 'valid').length,
|
|
14655
|
+
warnings: items.filter(m => m.validationStatus === 'warning').length,
|
|
14656
|
+
errors: items.filter(m => m.validationStatus === 'error').length,
|
|
14657
|
+
disabled: items.filter(m => !m.enabled).length,
|
|
14658
|
+
};
|
|
14659
|
+
}, ...(ngDevMode ? [{ debugName: "summary" }] : /* istanbul ignore next */ []));
|
|
14660
|
+
refreshIcon = arrowRotateCwIcon;
|
|
14661
|
+
checkIcon = checkCircleIcon;
|
|
14662
|
+
warnIcon = exclamationCircleIcon;
|
|
14663
|
+
errorIcon = xCircleIcon;
|
|
14664
|
+
deleteIcon = trashIcon;
|
|
14665
|
+
ngOnInit() {
|
|
14666
|
+
this.loadMappings();
|
|
14667
|
+
}
|
|
14668
|
+
async loadMappings() {
|
|
14669
|
+
this.loading.set(true);
|
|
14670
|
+
try {
|
|
14671
|
+
const result = await firstValueFrom(this.getMappingsGQL.fetch({
|
|
14672
|
+
variables: {
|
|
14673
|
+
ckTypeId: DATA_POINT_MAPPING_CK_TYPE,
|
|
14674
|
+
first: 500,
|
|
14675
|
+
},
|
|
14676
|
+
fetchPolicy: 'network-only',
|
|
14677
|
+
}));
|
|
14678
|
+
const entities = result.data?.runtime?.runtimeEntities?.items ?? [];
|
|
14679
|
+
const items = entities
|
|
14680
|
+
.filter((e) => e != null)
|
|
14681
|
+
.map(entity => this.mapEntityToOverviewItem(entity));
|
|
14682
|
+
// Run validation
|
|
14683
|
+
items.forEach(item => this.validateMapping(item, items));
|
|
14684
|
+
this.mappings.set(items);
|
|
14685
|
+
// Resolve entity names in background (non-blocking)
|
|
14686
|
+
this.resolveEntityNames(items);
|
|
14687
|
+
}
|
|
14688
|
+
catch (err) {
|
|
14689
|
+
console.error('Error loading DataPointMappings:', err);
|
|
14690
|
+
}
|
|
14691
|
+
finally {
|
|
14692
|
+
this.loading.set(false);
|
|
14693
|
+
}
|
|
14694
|
+
}
|
|
14695
|
+
onPageChange(event) {
|
|
14696
|
+
this.skip = event.skip;
|
|
14697
|
+
this.pageSize = event.take;
|
|
14698
|
+
}
|
|
14699
|
+
onCellClick(event) {
|
|
14700
|
+
this.selectedMapping.set(event.dataItem);
|
|
14701
|
+
}
|
|
14702
|
+
async onToggleEnabled(item, enabled) {
|
|
14703
|
+
try {
|
|
14704
|
+
await firstValueFrom(this.updateEntitiesGQL.mutate({
|
|
14705
|
+
variables: {
|
|
14706
|
+
entities: [{
|
|
14707
|
+
rtId: item.rtId,
|
|
14708
|
+
item: {
|
|
14709
|
+
ckTypeId: DATA_POINT_MAPPING_CK_TYPE,
|
|
14710
|
+
attributes: [{ attributeName: 'Enabled', value: enabled }],
|
|
14711
|
+
},
|
|
14712
|
+
}],
|
|
14713
|
+
},
|
|
14714
|
+
}));
|
|
14715
|
+
item.enabled = enabled;
|
|
14716
|
+
this.mappings.set([...this.mappings()]);
|
|
14717
|
+
}
|
|
14718
|
+
catch (err) {
|
|
14719
|
+
console.error('Error toggling mapping enabled state:', err);
|
|
14720
|
+
}
|
|
14721
|
+
}
|
|
14722
|
+
async onDeleteMapping(item) {
|
|
14723
|
+
try {
|
|
14724
|
+
await firstValueFrom(this.deleteEntitiesGQL.mutate({
|
|
14725
|
+
variables: {
|
|
14726
|
+
rtEntityIds: [{ rtId: item.rtId, ckTypeId: DATA_POINT_MAPPING_CK_TYPE }],
|
|
14727
|
+
deleteStrategy: DeleteStrategiesDto.EraseDto,
|
|
14728
|
+
},
|
|
14729
|
+
}));
|
|
14730
|
+
const updated = this.mappings().filter(m => m.rtId !== item.rtId);
|
|
14731
|
+
this.mappings.set(updated);
|
|
14732
|
+
if (this.selectedMapping()?.rtId === item.rtId) {
|
|
14733
|
+
this.selectedMapping.set(null);
|
|
14734
|
+
}
|
|
14735
|
+
}
|
|
14736
|
+
catch (err) {
|
|
14737
|
+
console.error('Error deleting mapping:', err);
|
|
14738
|
+
}
|
|
14739
|
+
}
|
|
14740
|
+
mapEntityToOverviewItem(entity) {
|
|
14741
|
+
const attrs = entity.attributes?.items ?? [];
|
|
14742
|
+
const assocs = entity.associations?.definitions?.items ?? [];
|
|
14743
|
+
const getAttr = (name) => attrs.find(a => a?.attributeName === name)?.value ?? '';
|
|
14744
|
+
const mapsFrom = assocs.find(a => a && String(a.ckAssociationRoleId).includes('MapsFrom'));
|
|
14745
|
+
const mapsTo = assocs.find(a => a && String(a.ckAssociationRoleId).includes('MapsTo'));
|
|
14746
|
+
const enabledRaw = attrs.find(a => a?.attributeName === 'Enabled')?.value;
|
|
14747
|
+
const enabled = enabledRaw === true || enabledRaw === 'true' || enabledRaw === 'True';
|
|
14748
|
+
return {
|
|
14749
|
+
rtId: String(entity.rtId),
|
|
14750
|
+
name: getAttr('Name') || `Mapping ${String(entity.rtId).slice(-6)}`,
|
|
14751
|
+
enabled,
|
|
14752
|
+
sourceAttributePath: getAttr('SourceAttributePath'),
|
|
14753
|
+
mappingExpression: getAttr('MappingExpression'),
|
|
14754
|
+
targetAttributePath: getAttr('TargetAttributePath'),
|
|
14755
|
+
sourceRtId: mapsFrom ? String(mapsFrom.targetRtId) : '',
|
|
14756
|
+
sourceCkTypeId: mapsFrom ? String(mapsFrom.targetCkTypeId) : '',
|
|
14757
|
+
sourceName: '',
|
|
14758
|
+
targetRtId: mapsTo ? String(mapsTo.targetRtId) : '',
|
|
14759
|
+
targetCkTypeId: mapsTo ? String(mapsTo.targetCkTypeId) : '',
|
|
14760
|
+
targetName: '',
|
|
14761
|
+
validationStatus: 'valid',
|
|
14762
|
+
validationMessages: [],
|
|
14763
|
+
};
|
|
14764
|
+
}
|
|
14765
|
+
validateMapping(item, allItems) {
|
|
14766
|
+
const messages = [];
|
|
14767
|
+
// Error: No source entity
|
|
14768
|
+
if (!item.sourceRtId) {
|
|
14769
|
+
messages.push({ level: 'error', code: 'SOURCE_MISSING', message: 'No MapsFrom source entity configured' });
|
|
14770
|
+
}
|
|
14771
|
+
// Error: No target entity
|
|
14772
|
+
if (!item.targetRtId) {
|
|
14773
|
+
messages.push({ level: 'error', code: 'TARGET_MISSING', message: 'No MapsTo target entity configured' });
|
|
14774
|
+
}
|
|
14775
|
+
// Error: No target attribute
|
|
14776
|
+
if (!item.targetAttributePath) {
|
|
14777
|
+
messages.push({ level: 'error', code: 'TARGET_ATTR_MISSING', message: 'TargetAttributePath is not set' });
|
|
14778
|
+
}
|
|
14779
|
+
// Warning: Duplicate mapping (same source → same target + attribute)
|
|
14780
|
+
const duplicates = allItems.filter(m => m.rtId !== item.rtId &&
|
|
14781
|
+
m.sourceRtId === item.sourceRtId &&
|
|
14782
|
+
m.sourceAttributePath === item.sourceAttributePath &&
|
|
14783
|
+
m.targetRtId === item.targetRtId &&
|
|
14784
|
+
m.targetAttributePath === item.targetAttributePath);
|
|
14785
|
+
if (duplicates.length > 0) {
|
|
14786
|
+
messages.push({ level: 'warning', code: 'DUPLICATE', message: 'Duplicate mapping — same source and target attribute' });
|
|
14787
|
+
}
|
|
14788
|
+
item.validationMessages = messages;
|
|
14789
|
+
item.validationStatus = messages.some(m => m.level === 'error')
|
|
14790
|
+
? 'error'
|
|
14791
|
+
: messages.some(m => m.level === 'warning')
|
|
14792
|
+
? 'warning'
|
|
14793
|
+
: 'valid';
|
|
14794
|
+
}
|
|
14795
|
+
/**
|
|
14796
|
+
* Resolves entity names for all unique source/target rtIds.
|
|
14797
|
+
* Updates items in-place and triggers signal update.
|
|
14798
|
+
*/
|
|
14799
|
+
async resolveEntityNames(items) {
|
|
14800
|
+
// Collect unique entity references (rtId + ckTypeId pairs)
|
|
14801
|
+
const entityRefs = new Map();
|
|
14802
|
+
for (const item of items) {
|
|
14803
|
+
if (item.sourceRtId && item.sourceCkTypeId) {
|
|
14804
|
+
entityRefs.set(item.sourceRtId, { rtId: item.sourceRtId, ckTypeId: item.sourceCkTypeId });
|
|
14805
|
+
}
|
|
14806
|
+
if (item.targetRtId && item.targetCkTypeId) {
|
|
14807
|
+
entityRefs.set(item.targetRtId, { rtId: item.targetRtId, ckTypeId: item.targetCkTypeId });
|
|
14808
|
+
}
|
|
14809
|
+
}
|
|
14810
|
+
// Load entity names in parallel
|
|
14811
|
+
const nameMap = new Map();
|
|
14812
|
+
const loadPromises = [...entityRefs.values()].map(async (ref) => {
|
|
14813
|
+
try {
|
|
14814
|
+
const result = await firstValueFrom(this.getEntityByIdGQL.fetch({
|
|
14815
|
+
variables: { rtId: ref.rtId, ckTypeId: ref.ckTypeId },
|
|
14816
|
+
}));
|
|
14817
|
+
const entity = result.data?.runtime?.runtimeEntities?.items?.[0];
|
|
14818
|
+
if (entity) {
|
|
14819
|
+
const nameAttr = entity.attributes?.items?.find(a => a?.attributeName === 'Name');
|
|
14820
|
+
const name = nameAttr?.value
|
|
14821
|
+
?? entity.rtWellKnownName
|
|
14822
|
+
?? '';
|
|
14823
|
+
if (name) {
|
|
14824
|
+
nameMap.set(ref.rtId, name);
|
|
14825
|
+
}
|
|
14826
|
+
}
|
|
14827
|
+
}
|
|
14828
|
+
catch {
|
|
14829
|
+
// Entity not found or access denied — leave name empty
|
|
14830
|
+
}
|
|
14831
|
+
});
|
|
14832
|
+
await Promise.all(loadPromises);
|
|
14833
|
+
// Update items with resolved names
|
|
14834
|
+
let changed = false;
|
|
14835
|
+
for (const item of items) {
|
|
14836
|
+
const sourceName = nameMap.get(item.sourceRtId);
|
|
14837
|
+
if (sourceName && sourceName !== item.sourceName) {
|
|
14838
|
+
item.sourceName = sourceName;
|
|
14839
|
+
changed = true;
|
|
14840
|
+
}
|
|
14841
|
+
const targetName = nameMap.get(item.targetRtId);
|
|
14842
|
+
if (targetName && targetName !== item.targetName) {
|
|
14843
|
+
item.targetName = targetName;
|
|
14844
|
+
changed = true;
|
|
14845
|
+
}
|
|
14846
|
+
}
|
|
14847
|
+
// Trigger signal update to refresh the grid
|
|
14848
|
+
if (changed) {
|
|
14849
|
+
this.mappings.set([...items]);
|
|
14850
|
+
}
|
|
14851
|
+
}
|
|
14852
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DataMappingOverviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14853
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DataMappingOverviewComponent, isStandalone: true, selector: "mm-data-mapping-overview", outputs: { navigateToEntity: "navigateToEntity" }, ngImport: i0, template: `
|
|
14854
|
+
<div class="mapping-overview">
|
|
14855
|
+
<!-- Summary Bar -->
|
|
14856
|
+
<div class="summary-bar">
|
|
14857
|
+
<div class="summary-item">
|
|
14858
|
+
<span class="summary-count">{{ summary().total }}</span>
|
|
14859
|
+
<span class="summary-label">Total</span>
|
|
14860
|
+
</div>
|
|
14861
|
+
<div class="summary-item summary-valid">
|
|
14862
|
+
<span class="summary-count">{{ summary().valid }}</span>
|
|
14863
|
+
<span class="summary-label">Valid</span>
|
|
14864
|
+
</div>
|
|
14865
|
+
<div class="summary-item summary-warnings">
|
|
14866
|
+
<span class="summary-count">{{ summary().warnings }}</span>
|
|
14867
|
+
<span class="summary-label">Warnings</span>
|
|
14868
|
+
</div>
|
|
14869
|
+
<div class="summary-item summary-errors">
|
|
14870
|
+
<span class="summary-count">{{ summary().errors }}</span>
|
|
14871
|
+
<span class="summary-label">Errors</span>
|
|
14872
|
+
</div>
|
|
14873
|
+
<div class="summary-item summary-disabled">
|
|
14874
|
+
<span class="summary-count">{{ summary().disabled }}</span>
|
|
14875
|
+
<span class="summary-label">Disabled</span>
|
|
14876
|
+
</div>
|
|
14877
|
+
<div class="summary-spacer"></div>
|
|
14878
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="refreshIcon"
|
|
14879
|
+
(click)="loadMappings()">Refresh</button>
|
|
14880
|
+
</div>
|
|
14881
|
+
|
|
14882
|
+
<!-- Mapping Grid -->
|
|
14883
|
+
<kendo-grid
|
|
14884
|
+
[data]="gridData()"
|
|
14885
|
+
[pageSize]="pageSize"
|
|
14886
|
+
[skip]="skip"
|
|
14887
|
+
[pageable]="{ buttonCount: 3, pageSizes: [10, 20, 50] }"
|
|
14888
|
+
[sortable]="true"
|
|
14889
|
+
[height]="500"
|
|
14890
|
+
(pageChange)="onPageChange($event)"
|
|
14891
|
+
(cellClick)="onCellClick($event)"
|
|
14892
|
+
>
|
|
14893
|
+
<kendo-grid-column title="" field="validationStatus" [width]="40" [sortable]="false">
|
|
14894
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14895
|
+
@if (dataItem.validationStatus === 'valid') {
|
|
14896
|
+
<kendo-svgicon [icon]="checkIcon" class="status-valid"></kendo-svgicon>
|
|
14897
|
+
} @else if (dataItem.validationStatus === 'warning') {
|
|
14898
|
+
<kendo-svgicon [icon]="warnIcon" class="status-warning"></kendo-svgicon>
|
|
14899
|
+
} @else {
|
|
14900
|
+
<kendo-svgicon [icon]="errorIcon" class="status-error"></kendo-svgicon>
|
|
14901
|
+
}
|
|
14902
|
+
</ng-template>
|
|
14903
|
+
</kendo-grid-column>
|
|
14904
|
+
|
|
14905
|
+
<kendo-grid-column title="Mapping Name" field="name" [width]="200">
|
|
14906
|
+
</kendo-grid-column>
|
|
14907
|
+
|
|
14908
|
+
<kendo-grid-column title="Source" field="sourceName" [width]="200">
|
|
14909
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14910
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: dataItem.sourceRtId, ckTypeId: dataItem.sourceCkTypeId })">
|
|
14911
|
+
{{ dataItem.sourceName || dataItem.sourceRtId | slice:-8 }}
|
|
14912
|
+
</span>
|
|
14913
|
+
<div class="entity-type-hint">{{ dataItem.sourceCkTypeId }}</div>
|
|
14914
|
+
</ng-template>
|
|
14915
|
+
</kendo-grid-column>
|
|
14916
|
+
|
|
14917
|
+
<kendo-grid-column title="Source Attr" field="sourceAttributePath" [width]="120">
|
|
14918
|
+
</kendo-grid-column>
|
|
14919
|
+
|
|
14920
|
+
<kendo-grid-column title="Expression" field="mappingExpression" [width]="160">
|
|
14921
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14922
|
+
@if (dataItem.mappingExpression) {
|
|
14923
|
+
<code class="expression-cell">{{ dataItem.mappingExpression }}</code>
|
|
14924
|
+
}
|
|
14925
|
+
</ng-template>
|
|
14926
|
+
</kendo-grid-column>
|
|
14927
|
+
|
|
14928
|
+
<kendo-grid-column title="Target" field="targetName" [width]="200">
|
|
14929
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14930
|
+
@if (dataItem.targetRtId) {
|
|
14931
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: dataItem.targetRtId, ckTypeId: dataItem.targetCkTypeId })">
|
|
14932
|
+
{{ dataItem.targetName || dataItem.targetRtId | slice:-8 }}
|
|
14933
|
+
</span>
|
|
14934
|
+
<div class="entity-type-hint">{{ dataItem.targetCkTypeId }}</div>
|
|
14935
|
+
} @else {
|
|
14936
|
+
<span class="no-target">(no target)</span>
|
|
14937
|
+
}
|
|
14938
|
+
</ng-template>
|
|
14939
|
+
</kendo-grid-column>
|
|
14940
|
+
|
|
14941
|
+
<kendo-grid-column title="Target Attr" field="targetAttributePath" [width]="120">
|
|
14942
|
+
</kendo-grid-column>
|
|
14943
|
+
|
|
14944
|
+
<kendo-grid-column title="Enabled" field="enabled" [width]="80">
|
|
14945
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14946
|
+
<kendo-switch [checked]="dataItem.enabled" size="small"
|
|
14947
|
+
(valueChange)="onToggleEnabled(dataItem, $event)">
|
|
14948
|
+
</kendo-switch>
|
|
14949
|
+
</ng-template>
|
|
14950
|
+
</kendo-grid-column>
|
|
14951
|
+
|
|
14952
|
+
<kendo-grid-column title="" [width]="50" [sortable]="false">
|
|
14953
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
14954
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="deleteIcon"
|
|
14955
|
+
(click)="onDeleteMapping(dataItem); $event.stopPropagation()">
|
|
14956
|
+
</button>
|
|
14957
|
+
</ng-template>
|
|
14958
|
+
</kendo-grid-column>
|
|
14959
|
+
</kendo-grid>
|
|
14960
|
+
|
|
14961
|
+
<!-- Detail Panel (selected mapping) -->
|
|
14962
|
+
@if (selectedMapping()) {
|
|
14963
|
+
<div class="detail-panel">
|
|
14964
|
+
<h4>{{ selectedMapping()!.name || 'Mapping Details' }}</h4>
|
|
14965
|
+
<div class="detail-grid">
|
|
14966
|
+
<div class="detail-row">
|
|
14967
|
+
<label>Source Entity</label>
|
|
14968
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: selectedMapping()!.sourceRtId, ckTypeId: selectedMapping()!.sourceCkTypeId })">
|
|
14969
|
+
{{ selectedMapping()!.sourceName || selectedMapping()!.sourceRtId }}
|
|
14970
|
+
</span>
|
|
14971
|
+
<span class="entity-type-hint">{{ selectedMapping()!.sourceCkTypeId }}</span>
|
|
14972
|
+
</div>
|
|
14973
|
+
<div class="detail-row">
|
|
14974
|
+
<label>Source Attribute</label>
|
|
14975
|
+
<span>{{ selectedMapping()!.sourceAttributePath || '(default)' }}</span>
|
|
14976
|
+
</div>
|
|
14977
|
+
<div class="detail-row">
|
|
14978
|
+
<label>Expression</label>
|
|
14979
|
+
<code>{{ selectedMapping()!.mappingExpression || '(none — pass through)' }}</code>
|
|
14980
|
+
</div>
|
|
14981
|
+
<div class="detail-row">
|
|
14982
|
+
<label>Target Entity</label>
|
|
14983
|
+
@if (selectedMapping()!.targetRtId) {
|
|
14984
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: selectedMapping()!.targetRtId, ckTypeId: selectedMapping()!.targetCkTypeId })">
|
|
14985
|
+
{{ selectedMapping()!.targetName || selectedMapping()!.targetRtId }}
|
|
14986
|
+
</span>
|
|
14987
|
+
<span class="entity-type-hint">{{ selectedMapping()!.targetCkTypeId }}</span>
|
|
14988
|
+
} @else {
|
|
14989
|
+
<span class="no-target">(no target configured)</span>
|
|
14990
|
+
}
|
|
14991
|
+
</div>
|
|
14992
|
+
<div class="detail-row">
|
|
14993
|
+
<label>Target Attribute</label>
|
|
14994
|
+
<span>{{ selectedMapping()!.targetAttributePath || '(not set)' }}</span>
|
|
14995
|
+
</div>
|
|
14996
|
+
<div class="detail-row">
|
|
14997
|
+
<label>Enabled</label>
|
|
14998
|
+
<span>{{ selectedMapping()!.enabled ? 'Yes' : 'No' }}</span>
|
|
14999
|
+
</div>
|
|
15000
|
+
</div>
|
|
15001
|
+
|
|
15002
|
+
@if (selectedMapping()!.validationMessages.length > 0) {
|
|
15003
|
+
<div class="validation-section">
|
|
15004
|
+
<h5>Validation</h5>
|
|
15005
|
+
@for (msg of selectedMapping()!.validationMessages; track msg.code) {
|
|
15006
|
+
<div class="validation-msg" [class]="'validation-' + msg.level">
|
|
15007
|
+
{{ msg.message }}
|
|
15008
|
+
</div>
|
|
15009
|
+
}
|
|
15010
|
+
</div>
|
|
15011
|
+
}
|
|
15012
|
+
</div>
|
|
15013
|
+
}
|
|
15014
|
+
|
|
15015
|
+
@if (loading()) {
|
|
15016
|
+
<div class="loading-overlay">Loading mappings...</div>
|
|
15017
|
+
}
|
|
15018
|
+
</div>
|
|
15019
|
+
`, isInline: true, styles: [".mapping-overview{display:flex;flex-direction:column;gap:12px;padding:16px}.summary-bar{display:flex;gap:16px;align-items:center;padding:8px 12px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;background:var(--kendo-color-surface-alt, #f8f9fa)}.summary-item{display:flex;flex-direction:column;align-items:center;min-width:60px}.summary-count{font-size:1.2rem;font-weight:700}.summary-label{font-size:.7rem;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.summary-valid .summary-count{color:var(--kendo-color-success, #28a745)}.summary-warnings .summary-count{color:var(--kendo-color-warning, #ffc107)}.summary-errors .summary-count{color:var(--kendo-color-error, #dc3545)}.summary-disabled .summary-count{color:var(--kendo-color-subtle, #6c757d)}.summary-spacer{flex:1}.status-valid{color:var(--kendo-color-success, #28a745)}.status-warning{color:var(--kendo-color-warning, #ffc107)}.status-error{color:var(--kendo-color-error, #dc3545)}.entity-ref{cursor:pointer;color:var(--kendo-color-primary, #ff6358);font-family:monospace;font-size:.85rem}.entity-ref:hover{text-decoration:underline}.no-target{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.entity-type-hint{font-size:.7rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace}.expression-cell{font-size:.85rem;background:var(--kendo-color-surface-alt, #f8f9fa);padding:2px 4px;border-radius:3px}.detail-panel{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;padding:12px 16px}.detail-panel h4{margin:0 0 12px;font-size:.9rem;font-weight:600}.detail-grid{display:grid;grid-template-columns:120px 1fr;gap:6px 12px}.detail-row{display:contents}.detail-row label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d);padding-top:2px}.detail-row span,.detail-row code{font-size:.85rem}.validation-section{margin-top:12px;padding-top:8px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.validation-section h5{margin:0 0 6px;font-size:.8rem;font-weight:600}.validation-msg{font-size:.8rem;padding:2px 0}.validation-error{color:var(--kendo-color-error, #dc3545)}.validation-warning{color:var(--kendo-color-warning, #ffc107)}.validation-info{color:var(--kendo-color-info, #17a2b8)}.loading-overlay{text-align:center;padding:20px;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: BadgeModule }, { kind: "ngmodule", type: SwitchModule }, { kind: "component", type: i5.SwitchComponent, selector: "kendo-switch", inputs: ["focusableId", "onLabel", "offLabel", "checked", "disabled", "readonly", "tabindex", "size", "thumbRounded", "trackRounded", "tabIndex"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoSwitch"] }, { kind: "pipe", type: i1$2.SlicePipe, name: "slice" }] });
|
|
15020
|
+
}
|
|
15021
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DataMappingOverviewComponent, decorators: [{
|
|
15022
|
+
type: Component,
|
|
15023
|
+
args: [{ selector: 'mm-data-mapping-overview', standalone: true, imports: [
|
|
15024
|
+
CommonModule,
|
|
15025
|
+
ButtonModule,
|
|
15026
|
+
SVGIconModule,
|
|
15027
|
+
GridModule,
|
|
15028
|
+
BadgeModule,
|
|
15029
|
+
SwitchModule,
|
|
15030
|
+
], template: `
|
|
15031
|
+
<div class="mapping-overview">
|
|
15032
|
+
<!-- Summary Bar -->
|
|
15033
|
+
<div class="summary-bar">
|
|
15034
|
+
<div class="summary-item">
|
|
15035
|
+
<span class="summary-count">{{ summary().total }}</span>
|
|
15036
|
+
<span class="summary-label">Total</span>
|
|
15037
|
+
</div>
|
|
15038
|
+
<div class="summary-item summary-valid">
|
|
15039
|
+
<span class="summary-count">{{ summary().valid }}</span>
|
|
15040
|
+
<span class="summary-label">Valid</span>
|
|
15041
|
+
</div>
|
|
15042
|
+
<div class="summary-item summary-warnings">
|
|
15043
|
+
<span class="summary-count">{{ summary().warnings }}</span>
|
|
15044
|
+
<span class="summary-label">Warnings</span>
|
|
15045
|
+
</div>
|
|
15046
|
+
<div class="summary-item summary-errors">
|
|
15047
|
+
<span class="summary-count">{{ summary().errors }}</span>
|
|
15048
|
+
<span class="summary-label">Errors</span>
|
|
15049
|
+
</div>
|
|
15050
|
+
<div class="summary-item summary-disabled">
|
|
15051
|
+
<span class="summary-count">{{ summary().disabled }}</span>
|
|
15052
|
+
<span class="summary-label">Disabled</span>
|
|
15053
|
+
</div>
|
|
15054
|
+
<div class="summary-spacer"></div>
|
|
15055
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="refreshIcon"
|
|
15056
|
+
(click)="loadMappings()">Refresh</button>
|
|
15057
|
+
</div>
|
|
15058
|
+
|
|
15059
|
+
<!-- Mapping Grid -->
|
|
15060
|
+
<kendo-grid
|
|
15061
|
+
[data]="gridData()"
|
|
15062
|
+
[pageSize]="pageSize"
|
|
15063
|
+
[skip]="skip"
|
|
15064
|
+
[pageable]="{ buttonCount: 3, pageSizes: [10, 20, 50] }"
|
|
15065
|
+
[sortable]="true"
|
|
15066
|
+
[height]="500"
|
|
15067
|
+
(pageChange)="onPageChange($event)"
|
|
15068
|
+
(cellClick)="onCellClick($event)"
|
|
15069
|
+
>
|
|
15070
|
+
<kendo-grid-column title="" field="validationStatus" [width]="40" [sortable]="false">
|
|
15071
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15072
|
+
@if (dataItem.validationStatus === 'valid') {
|
|
15073
|
+
<kendo-svgicon [icon]="checkIcon" class="status-valid"></kendo-svgicon>
|
|
15074
|
+
} @else if (dataItem.validationStatus === 'warning') {
|
|
15075
|
+
<kendo-svgicon [icon]="warnIcon" class="status-warning"></kendo-svgicon>
|
|
15076
|
+
} @else {
|
|
15077
|
+
<kendo-svgicon [icon]="errorIcon" class="status-error"></kendo-svgicon>
|
|
15078
|
+
}
|
|
15079
|
+
</ng-template>
|
|
15080
|
+
</kendo-grid-column>
|
|
15081
|
+
|
|
15082
|
+
<kendo-grid-column title="Mapping Name" field="name" [width]="200">
|
|
15083
|
+
</kendo-grid-column>
|
|
15084
|
+
|
|
15085
|
+
<kendo-grid-column title="Source" field="sourceName" [width]="200">
|
|
15086
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15087
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: dataItem.sourceRtId, ckTypeId: dataItem.sourceCkTypeId })">
|
|
15088
|
+
{{ dataItem.sourceName || dataItem.sourceRtId | slice:-8 }}
|
|
15089
|
+
</span>
|
|
15090
|
+
<div class="entity-type-hint">{{ dataItem.sourceCkTypeId }}</div>
|
|
15091
|
+
</ng-template>
|
|
15092
|
+
</kendo-grid-column>
|
|
15093
|
+
|
|
15094
|
+
<kendo-grid-column title="Source Attr" field="sourceAttributePath" [width]="120">
|
|
15095
|
+
</kendo-grid-column>
|
|
15096
|
+
|
|
15097
|
+
<kendo-grid-column title="Expression" field="mappingExpression" [width]="160">
|
|
15098
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15099
|
+
@if (dataItem.mappingExpression) {
|
|
15100
|
+
<code class="expression-cell">{{ dataItem.mappingExpression }}</code>
|
|
15101
|
+
}
|
|
15102
|
+
</ng-template>
|
|
15103
|
+
</kendo-grid-column>
|
|
15104
|
+
|
|
15105
|
+
<kendo-grid-column title="Target" field="targetName" [width]="200">
|
|
15106
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15107
|
+
@if (dataItem.targetRtId) {
|
|
15108
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: dataItem.targetRtId, ckTypeId: dataItem.targetCkTypeId })">
|
|
15109
|
+
{{ dataItem.targetName || dataItem.targetRtId | slice:-8 }}
|
|
15110
|
+
</span>
|
|
15111
|
+
<div class="entity-type-hint">{{ dataItem.targetCkTypeId }}</div>
|
|
15112
|
+
} @else {
|
|
15113
|
+
<span class="no-target">(no target)</span>
|
|
15114
|
+
}
|
|
15115
|
+
</ng-template>
|
|
15116
|
+
</kendo-grid-column>
|
|
15117
|
+
|
|
15118
|
+
<kendo-grid-column title="Target Attr" field="targetAttributePath" [width]="120">
|
|
15119
|
+
</kendo-grid-column>
|
|
15120
|
+
|
|
15121
|
+
<kendo-grid-column title="Enabled" field="enabled" [width]="80">
|
|
15122
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15123
|
+
<kendo-switch [checked]="dataItem.enabled" size="small"
|
|
15124
|
+
(valueChange)="onToggleEnabled(dataItem, $event)">
|
|
15125
|
+
</kendo-switch>
|
|
15126
|
+
</ng-template>
|
|
15127
|
+
</kendo-grid-column>
|
|
15128
|
+
|
|
15129
|
+
<kendo-grid-column title="" [width]="50" [sortable]="false">
|
|
15130
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
15131
|
+
<button kendoButton fillMode="flat" size="small" [svgIcon]="deleteIcon"
|
|
15132
|
+
(click)="onDeleteMapping(dataItem); $event.stopPropagation()">
|
|
15133
|
+
</button>
|
|
15134
|
+
</ng-template>
|
|
15135
|
+
</kendo-grid-column>
|
|
15136
|
+
</kendo-grid>
|
|
15137
|
+
|
|
15138
|
+
<!-- Detail Panel (selected mapping) -->
|
|
15139
|
+
@if (selectedMapping()) {
|
|
15140
|
+
<div class="detail-panel">
|
|
15141
|
+
<h4>{{ selectedMapping()!.name || 'Mapping Details' }}</h4>
|
|
15142
|
+
<div class="detail-grid">
|
|
15143
|
+
<div class="detail-row">
|
|
15144
|
+
<label>Source Entity</label>
|
|
15145
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: selectedMapping()!.sourceRtId, ckTypeId: selectedMapping()!.sourceCkTypeId })">
|
|
15146
|
+
{{ selectedMapping()!.sourceName || selectedMapping()!.sourceRtId }}
|
|
15147
|
+
</span>
|
|
15148
|
+
<span class="entity-type-hint">{{ selectedMapping()!.sourceCkTypeId }}</span>
|
|
15149
|
+
</div>
|
|
15150
|
+
<div class="detail-row">
|
|
15151
|
+
<label>Source Attribute</label>
|
|
15152
|
+
<span>{{ selectedMapping()!.sourceAttributePath || '(default)' }}</span>
|
|
15153
|
+
</div>
|
|
15154
|
+
<div class="detail-row">
|
|
15155
|
+
<label>Expression</label>
|
|
15156
|
+
<code>{{ selectedMapping()!.mappingExpression || '(none — pass through)' }}</code>
|
|
15157
|
+
</div>
|
|
15158
|
+
<div class="detail-row">
|
|
15159
|
+
<label>Target Entity</label>
|
|
15160
|
+
@if (selectedMapping()!.targetRtId) {
|
|
15161
|
+
<span class="entity-ref" (click)="navigateToEntity.emit({ rtId: selectedMapping()!.targetRtId, ckTypeId: selectedMapping()!.targetCkTypeId })">
|
|
15162
|
+
{{ selectedMapping()!.targetName || selectedMapping()!.targetRtId }}
|
|
15163
|
+
</span>
|
|
15164
|
+
<span class="entity-type-hint">{{ selectedMapping()!.targetCkTypeId }}</span>
|
|
15165
|
+
} @else {
|
|
15166
|
+
<span class="no-target">(no target configured)</span>
|
|
15167
|
+
}
|
|
15168
|
+
</div>
|
|
15169
|
+
<div class="detail-row">
|
|
15170
|
+
<label>Target Attribute</label>
|
|
15171
|
+
<span>{{ selectedMapping()!.targetAttributePath || '(not set)' }}</span>
|
|
15172
|
+
</div>
|
|
15173
|
+
<div class="detail-row">
|
|
15174
|
+
<label>Enabled</label>
|
|
15175
|
+
<span>{{ selectedMapping()!.enabled ? 'Yes' : 'No' }}</span>
|
|
15176
|
+
</div>
|
|
15177
|
+
</div>
|
|
15178
|
+
|
|
15179
|
+
@if (selectedMapping()!.validationMessages.length > 0) {
|
|
15180
|
+
<div class="validation-section">
|
|
15181
|
+
<h5>Validation</h5>
|
|
15182
|
+
@for (msg of selectedMapping()!.validationMessages; track msg.code) {
|
|
15183
|
+
<div class="validation-msg" [class]="'validation-' + msg.level">
|
|
15184
|
+
{{ msg.message }}
|
|
15185
|
+
</div>
|
|
15186
|
+
}
|
|
15187
|
+
</div>
|
|
15188
|
+
}
|
|
15189
|
+
</div>
|
|
15190
|
+
}
|
|
15191
|
+
|
|
15192
|
+
@if (loading()) {
|
|
15193
|
+
<div class="loading-overlay">Loading mappings...</div>
|
|
15194
|
+
}
|
|
15195
|
+
</div>
|
|
15196
|
+
`, styles: [".mapping-overview{display:flex;flex-direction:column;gap:12px;padding:16px}.summary-bar{display:flex;gap:16px;align-items:center;padding:8px 12px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;background:var(--kendo-color-surface-alt, #f8f9fa)}.summary-item{display:flex;flex-direction:column;align-items:center;min-width:60px}.summary-count{font-size:1.2rem;font-weight:700}.summary-label{font-size:.7rem;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d)}.summary-valid .summary-count{color:var(--kendo-color-success, #28a745)}.summary-warnings .summary-count{color:var(--kendo-color-warning, #ffc107)}.summary-errors .summary-count{color:var(--kendo-color-error, #dc3545)}.summary-disabled .summary-count{color:var(--kendo-color-subtle, #6c757d)}.summary-spacer{flex:1}.status-valid{color:var(--kendo-color-success, #28a745)}.status-warning{color:var(--kendo-color-warning, #ffc107)}.status-error{color:var(--kendo-color-error, #dc3545)}.entity-ref{cursor:pointer;color:var(--kendo-color-primary, #ff6358);font-family:monospace;font-size:.85rem}.entity-ref:hover{text-decoration:underline}.no-target{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.entity-type-hint{font-size:.7rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace}.expression-cell{font-size:.85rem;background:var(--kendo-color-surface-alt, #f8f9fa);padding:2px 4px;border-radius:3px}.detail-panel{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:6px;padding:12px 16px}.detail-panel h4{margin:0 0 12px;font-size:.9rem;font-weight:600}.detail-grid{display:grid;grid-template-columns:120px 1fr;gap:6px 12px}.detail-row{display:contents}.detail-row label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #6c757d);padding-top:2px}.detail-row span,.detail-row code{font-size:.85rem}.validation-section{margin-top:12px;padding-top:8px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.validation-section h5{margin:0 0 6px;font-size:.8rem;font-weight:600}.validation-msg{font-size:.8rem;padding:2px 0}.validation-error{color:var(--kendo-color-error, #dc3545)}.validation-warning{color:var(--kendo-color-warning, #ffc107)}.validation-info{color:var(--kendo-color-info, #17a2b8)}.loading-overlay{text-align:center;padding:20px;color:var(--kendo-color-subtle, #6c757d)}\n"] }]
|
|
15197
|
+
}], propDecorators: { navigateToEntity: [{
|
|
15198
|
+
type: Output
|
|
15199
|
+
}] } });
|
|
15200
|
+
|
|
13781
15201
|
class TenantSwitcherComponent {
|
|
13782
15202
|
currentTenantId = null;
|
|
13783
15203
|
allowedTenants = [];
|
|
@@ -13955,5 +15375,5 @@ function provideOctoUi() {
|
|
|
13955
15375
|
* Generated bundle index. Do not edit.
|
|
13956
15376
|
*/
|
|
13957
15377
|
|
|
13958
|
-
export { AssociationValidationService, AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DEFAULT_RUNTIME_BROWSER_MESSAGES, DefaultPropertyCategory, EntityDetailComponent, EntityIdInfoComponent, EntitySelectorDialogComponent, EntitySelectorDialogService, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RUNTIME_BROWSER_MESSAGES, RtEntityIdHelper, RuntimeBrowserComponent, RuntimeBrowserOutletComponent, RuntimeBrowserPageComponent, RuntimeBrowserStateService, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, TenantSwitcherComponent, account_tree, add, analytics, app_registration, article, botService, category, chat, checklist, code, component_exchange, computer, createRuntimeBrowserRoutes, customer, dashboard, event_list, graphic_eq, group, identityService, insert_link, manage_accounts, more_time, notifications, page_info, pages, person_search, playlist_add_check, pool, power, provideOctoUi, publicIcon, query_builder, schedule_send, settings, sort, storage, swagger, swagger_asset, swagger_bot, swagger_communication, swagger_identity, team_dashboard, tenancy, text_snippet, travel_explore, user_diagnostics, webhook, work };
|
|
15378
|
+
export { AssociationValidationService, AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DEFAULT_RUNTIME_BROWSER_MESSAGES, DataMappingOverviewComponent, DefaultPropertyCategory, EntityDetailComponent, EntityIdInfoComponent, EntitySelectorDialogComponent, EntitySelectorDialogService, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RUNTIME_BROWSER_MESSAGES, RecordDetailDialogComponent, RtEntityIdHelper, RuntimeBrowserComponent, RuntimeBrowserOutletComponent, RuntimeBrowserPageComponent, RuntimeBrowserStateService, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, TenantSwitcherComponent, account_tree, add, analytics, app_registration, article, botService, category, chat, checklist, code, component_exchange, computer, createRuntimeBrowserRoutes, customer, dashboard, event_list, graphic_eq, group, identityService, insert_link, manage_accounts, more_time, notifications, page_info, pages, person_search, playlist_add_check, pool, power, provideOctoUi, publicIcon, query_builder, schedule_send, settings, sort, storage, swagger, swagger_asset, swagger_bot, swagger_communication, swagger_identity, team_dashboard, tenancy, text_snippet, travel_explore, user_diagnostics, webhook, work };
|
|
13959
15379
|
//# sourceMappingURL=meshmakers-octo-ui.mjs.map
|