@ai-table/grid 0.0.28 → 0.0.30
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/components/context-menu/context-menu.component.d.ts.map +1 -1
- package/constants/table.d.ts +1 -1
- package/constants/table.d.ts.map +1 -1
- package/core/types/ai-table.d.ts +7 -15
- package/core/types/ai-table.d.ts.map +1 -1
- package/core/types/core.d.ts +3 -3
- package/core/types/core.d.ts.map +1 -1
- package/core/utils/common.d.ts.map +1 -1
- package/core/utils/queries.d.ts +2 -2
- package/core/utils/queries.d.ts.map +1 -1
- package/esm2022/components/context-menu/context-menu.component.mjs +4 -11
- package/esm2022/constants/table.mjs +2 -2
- package/esm2022/core/types/ai-table.mjs +22 -16
- package/esm2022/core/types/core.mjs +1 -1
- package/esm2022/core/utils/common.mjs +6 -5
- package/esm2022/core/utils/queries.mjs +1 -1
- package/esm2022/dom-grid.component.mjs +3 -3
- package/esm2022/grid-base.component.mjs +1 -4
- package/esm2022/grid.component.mjs +46 -10
- package/esm2022/renderer/creations/create-active-cell-border.mjs +6 -3
- package/esm2022/renderer/creations/create-cells.mjs +55 -25
- package/esm2022/renderer/renderer.component.mjs +7 -3
- package/esm2022/services/event.service.mjs +3 -2
- package/esm2022/services/index.mjs +1 -2
- package/esm2022/services/selection.service.mjs +41 -16
- package/esm2022/types/grid.mjs +1 -1
- package/esm2022/types/index.mjs +2 -1
- package/esm2022/types/view.mjs +18 -0
- package/esm2022/utils/field/model/date.mjs +64 -0
- package/esm2022/utils/field/model/field.mjs +38 -0
- package/esm2022/utils/field/model/index.mjs +25 -0
- package/esm2022/utils/field/model/link.mjs +33 -0
- package/esm2022/utils/field/model/member.mjs +57 -0
- package/esm2022/utils/field/model/number.mjs +32 -0
- package/esm2022/utils/field/model/progress.mjs +38 -0
- package/esm2022/utils/field/model/rate.mjs +26 -0
- package/esm2022/utils/field/model/select.mjs +56 -0
- package/esm2022/utils/field/model/text.mjs +27 -0
- package/esm2022/utils/field/operate.mjs +47 -0
- package/esm2022/utils/index.mjs +4 -2
- package/esm2022/utils/match-keywords.mjs +11 -0
- package/fesm2022/ai-table-grid.mjs +546 -146
- package/fesm2022/ai-table-grid.mjs.map +1 -1
- package/grid-base.component.d.ts +0 -2
- package/grid-base.component.d.ts.map +1 -1
- package/grid.component.d.ts +5 -0
- package/grid.component.d.ts.map +1 -1
- package/package.json +1 -1
- package/renderer/creations/create-active-cell-border.d.ts.map +1 -1
- package/renderer/creations/create-cells.d.ts.map +1 -1
- package/renderer/renderer.component.d.ts +5 -3
- package/renderer/renderer.component.d.ts.map +1 -1
- package/services/event.service.d.ts.map +1 -1
- package/services/index.d.ts +0 -1
- package/services/index.d.ts.map +1 -1
- package/services/selection.service.d.ts +3 -2
- package/services/selection.service.d.ts.map +1 -1
- package/types/grid.d.ts +6 -5
- package/types/grid.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/view.d.ts +23 -0
- package/types/view.d.ts.map +1 -0
- package/utils/field/model/date.d.ts +9 -0
- package/utils/field/model/date.d.ts.map +1 -0
- package/utils/field/model/field.d.ts +9 -0
- package/utils/field/model/field.d.ts.map +1 -0
- package/utils/field/{index.d.ts → model/index.d.ts} +1 -1
- package/utils/field/model/index.d.ts.map +1 -0
- package/utils/field/model/link.d.ts +9 -0
- package/utils/field/model/link.d.ts.map +1 -0
- package/utils/field/model/member.d.ts +9 -0
- package/utils/field/model/member.d.ts.map +1 -0
- package/utils/field/model/number.d.ts +8 -0
- package/utils/field/model/number.d.ts.map +1 -0
- package/utils/field/model/progress.d.ts +9 -0
- package/utils/field/model/progress.d.ts.map +1 -0
- package/utils/field/model/rate.d.ts +8 -0
- package/utils/field/model/rate.d.ts.map +1 -0
- package/utils/field/model/select.d.ts +9 -0
- package/utils/field/model/select.d.ts.map +1 -0
- package/utils/field/model/text.d.ts +8 -0
- package/utils/field/model/text.d.ts.map +1 -0
- package/utils/field/operate.d.ts +9 -0
- package/utils/field/operate.d.ts.map +1 -0
- package/utils/index.d.ts +3 -1
- package/utils/index.d.ts.map +1 -1
- package/utils/match-keywords.d.ts +4 -0
- package/utils/match-keywords.d.ts.map +1 -0
- package/esm2022/services/match-cell.service.mjs +0 -45
- package/esm2022/utils/field/field.mjs +0 -3
- package/esm2022/utils/field/index.mjs +0 -22
- package/esm2022/utils/field/link.mjs +0 -12
- package/esm2022/utils/field/member.mjs +0 -19
- package/esm2022/utils/field/progress.mjs +0 -12
- package/esm2022/utils/field/select.mjs +0 -16
- package/esm2022/utils/field/text.mjs +0 -12
- package/services/match-cell.service.d.ts +0 -13
- package/services/match-cell.service.d.ts.map +0 -1
- package/utils/field/field.d.ts +0 -5
- package/utils/field/field.d.ts.map +0 -1
- package/utils/field/index.d.ts.map +0 -1
- package/utils/field/link.d.ts +0 -6
- package/utils/field/link.d.ts.map +0 -1
- package/utils/field/member.d.ts +0 -6
- package/utils/field/member.d.ts.map +0 -1
- package/utils/field/progress.d.ts +0 -6
- package/utils/field/progress.d.ts.map +0 -1
- package/utils/field/select.d.ts +0 -6
- package/utils/field/select.d.ts.map +0 -1
- package/utils/field/text.d.ts +0 -6
- package/utils/field/text.d.ts.map +0 -1
|
@@ -6,7 +6,7 @@ import ObjectID from 'bson-objectid';
|
|
|
6
6
|
import { customAlphabet } from 'nanoid';
|
|
7
7
|
import * as _ from 'lodash';
|
|
8
8
|
import ___default, { isNumber, includes, values, isString, isNil } from 'lodash';
|
|
9
|
-
import { isUndefinedOrNull, isArray, isEmpty as isEmpty$1, isObject } from 'ngx-tethys/util';
|
|
9
|
+
import { isUndefinedOrNull, isArray, isEmpty as isEmpty$1, isObject, TinyDate, helpers } from 'ngx-tethys/util';
|
|
10
10
|
import * as i1 from '@angular/forms';
|
|
11
11
|
import { FormsModule } from '@angular/forms';
|
|
12
12
|
import { ThyDatePicker, ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
|
|
@@ -43,6 +43,7 @@ import { ThyProgress } from 'ngx-tethys/progress';
|
|
|
43
43
|
import { ThyDivider } from 'ngx-tethys/divider';
|
|
44
44
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
45
45
|
import { LRUCache } from 'lru-cache';
|
|
46
|
+
import { fromUnixTime, subDays } from 'date-fns';
|
|
46
47
|
import Konva from 'konva';
|
|
47
48
|
import { Shape } from 'konva/lib/Shape';
|
|
48
49
|
import { Sprite } from 'konva/lib/shapes/Sprite';
|
|
@@ -98,32 +99,38 @@ const AITable = {
|
|
|
98
99
|
return aiTable.records();
|
|
99
100
|
},
|
|
100
101
|
getActiveCell(aiTable) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
return aiTable.selection().activeCell;
|
|
103
|
+
},
|
|
104
|
+
getActiveRecordIds(aiTable) {
|
|
105
|
+
const selectedRecords = aiTable.selection().selectedRecords;
|
|
106
|
+
const selectedCells = aiTable.selection().selectedCells;
|
|
107
|
+
let selectedRecordIds = [];
|
|
108
|
+
if (selectedRecords.size > 0) {
|
|
109
|
+
selectedRecordIds = [...selectedRecords.keys()];
|
|
110
|
+
}
|
|
111
|
+
else if (selectedCells.size > 0) {
|
|
112
|
+
selectedRecordIds = [...selectedCells].map((item) => item.split(':')[0]);
|
|
112
113
|
}
|
|
113
|
-
|
|
114
|
+
else {
|
|
115
|
+
selectedRecordIds = [];
|
|
116
|
+
}
|
|
117
|
+
return selectedRecordIds;
|
|
114
118
|
},
|
|
115
119
|
isCellVisible(aiTable, cell) {
|
|
116
120
|
const visibleRowIndexMap = aiTable.context.visibleRowsIndexMap();
|
|
117
121
|
const visibleColumnIndexMap = aiTable.context.visibleColumnsMap();
|
|
118
|
-
|
|
122
|
+
const [recordId, fieldId] = cell || [];
|
|
123
|
+
const isVisible = visibleRowIndexMap.has(recordId) && visibleColumnIndexMap.has(fieldId);
|
|
124
|
+
return isVisible;
|
|
119
125
|
},
|
|
120
126
|
getCellIndex(aiTable, cell) {
|
|
121
127
|
const visibleRowIndexMap = aiTable.context.visibleRowsIndexMap();
|
|
122
128
|
const visibleColumnIndexMap = aiTable.context.visibleColumnsMap();
|
|
123
129
|
if (AITable.isCellVisible(aiTable, cell)) {
|
|
130
|
+
const [recordId, fieldId] = cell;
|
|
124
131
|
return {
|
|
125
|
-
rowIndex: visibleRowIndexMap.get(
|
|
126
|
-
columnIndex: visibleColumnIndexMap.get(
|
|
132
|
+
rowIndex: visibleRowIndexMap.get(recordId),
|
|
133
|
+
columnIndex: visibleColumnIndexMap.get(fieldId)
|
|
127
134
|
};
|
|
128
135
|
}
|
|
129
136
|
return null;
|
|
@@ -333,6 +340,24 @@ var AITableRowType;
|
|
|
333
340
|
AITableRowType["record"] = "record";
|
|
334
341
|
})(AITableRowType || (AITableRowType = {}));
|
|
335
342
|
|
|
343
|
+
var AITableFilterOperation;
|
|
344
|
+
(function (AITableFilterOperation) {
|
|
345
|
+
AITableFilterOperation["eq"] = "eq";
|
|
346
|
+
AITableFilterOperation["gte"] = "gte";
|
|
347
|
+
AITableFilterOperation["lte"] = "lte";
|
|
348
|
+
AITableFilterOperation["gt"] = "gt";
|
|
349
|
+
AITableFilterOperation["lt"] = "lt";
|
|
350
|
+
AITableFilterOperation["in"] = "in";
|
|
351
|
+
AITableFilterOperation["contain"] = "contain";
|
|
352
|
+
AITableFilterOperation["ne"] = "ne";
|
|
353
|
+
AITableFilterOperation["nin"] = "nin";
|
|
354
|
+
AITableFilterOperation["between"] = "between";
|
|
355
|
+
AITableFilterOperation["besides"] = "besides";
|
|
356
|
+
AITableFilterOperation["empty"] = "empty";
|
|
357
|
+
AITableFilterOperation["exists"] = "exists";
|
|
358
|
+
AITableFilterOperation["notContain"] = "not_contain";
|
|
359
|
+
})(AITableFilterOperation || (AITableFilterOperation = {}));
|
|
360
|
+
|
|
336
361
|
/**
|
|
337
362
|
* 用于构建 Canvas 基础坐标系,后续的绘制工作以此为基础
|
|
338
363
|
*/
|
|
@@ -672,11 +697,12 @@ function createAITable(records, fields) {
|
|
|
672
697
|
records,
|
|
673
698
|
fields,
|
|
674
699
|
selection: signal({
|
|
675
|
-
selectedRecords: new
|
|
676
|
-
selectedFields: new
|
|
677
|
-
selectedCells: new
|
|
700
|
+
selectedRecords: new Set(),
|
|
701
|
+
selectedFields: new Set(),
|
|
702
|
+
selectedCells: new Set(),
|
|
703
|
+
activeCell: null
|
|
678
704
|
}),
|
|
679
|
-
|
|
705
|
+
keywordsMatchedCells: signal(new Set()),
|
|
680
706
|
recordsMap: computed(() => {
|
|
681
707
|
return records().reduce((object, item) => {
|
|
682
708
|
object[item._id] = item;
|
|
@@ -1541,37 +1567,34 @@ class AITableGridSelectionService {
|
|
|
1541
1567
|
}
|
|
1542
1568
|
clearSelection() {
|
|
1543
1569
|
this.aiTable.selection.set({
|
|
1544
|
-
selectedRecords: new
|
|
1545
|
-
selectedFields: new
|
|
1546
|
-
selectedCells: new
|
|
1570
|
+
selectedRecords: new Set(),
|
|
1571
|
+
selectedFields: new Set(),
|
|
1572
|
+
selectedCells: new Set(),
|
|
1573
|
+
activeCell: null
|
|
1547
1574
|
});
|
|
1548
1575
|
}
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
if (fields?.hasOwnProperty(fieldId)) {
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
this.clearSelection();
|
|
1555
|
-
this.aiTable.selection().selectedCells.set(recordId, { [fieldId]: true });
|
|
1576
|
+
setActiveCell(activeCell) {
|
|
1577
|
+
this.aiTable.selection().activeCell = activeCell;
|
|
1556
1578
|
}
|
|
1557
1579
|
selectField(fieldId) {
|
|
1558
1580
|
if (this.aiTable.selection().selectedFields.has(fieldId)) {
|
|
1559
1581
|
return;
|
|
1560
1582
|
}
|
|
1561
1583
|
this.clearSelection();
|
|
1562
|
-
this.aiTable.selection().selectedFields.
|
|
1584
|
+
this.aiTable.selection().selectedFields.add(fieldId);
|
|
1563
1585
|
}
|
|
1564
1586
|
selectRecord(recordId) {
|
|
1565
1587
|
if (this.aiTable.selection().selectedRecords.has(recordId)) {
|
|
1566
1588
|
this.aiTable.selection().selectedRecords.delete(recordId);
|
|
1567
1589
|
}
|
|
1568
1590
|
else {
|
|
1569
|
-
this.aiTable.selection().selectedRecords.
|
|
1591
|
+
this.aiTable.selection().selectedRecords.add(recordId);
|
|
1570
1592
|
}
|
|
1571
1593
|
this.aiTable.selection.set({
|
|
1572
1594
|
selectedRecords: this.aiTable.selection().selectedRecords,
|
|
1573
|
-
selectedFields: new
|
|
1574
|
-
selectedCells: new
|
|
1595
|
+
selectedFields: new Set(),
|
|
1596
|
+
selectedCells: new Set(),
|
|
1597
|
+
activeCell: null
|
|
1575
1598
|
});
|
|
1576
1599
|
}
|
|
1577
1600
|
toggleSelectAll(checked) {
|
|
@@ -1594,7 +1617,7 @@ class AITableGridSelectionService {
|
|
|
1594
1617
|
if (cellDom) {
|
|
1595
1618
|
const fieldId = cellDom.getAttribute('fieldId');
|
|
1596
1619
|
const recordId = cellDom.getAttribute('recordId');
|
|
1597
|
-
fieldId && recordId && this.
|
|
1620
|
+
fieldId && recordId && this.selectCells([recordId, fieldId]);
|
|
1598
1621
|
}
|
|
1599
1622
|
if (colDom && !fieldAction) {
|
|
1600
1623
|
const fieldId = colDom.getAttribute('fieldId');
|
|
@@ -1604,6 +1627,34 @@ class AITableGridSelectionService {
|
|
|
1604
1627
|
this.clearSelection();
|
|
1605
1628
|
}
|
|
1606
1629
|
}
|
|
1630
|
+
selectCells(startCell, endCell) {
|
|
1631
|
+
const [startRecordId, startFieldId] = startCell;
|
|
1632
|
+
const records = this.aiTable.records();
|
|
1633
|
+
const fields = this.aiTable.fields();
|
|
1634
|
+
const selectedCells = new Set();
|
|
1635
|
+
if (!endCell) {
|
|
1636
|
+
selectedCells.add(`${startRecordId}:${startFieldId}`);
|
|
1637
|
+
}
|
|
1638
|
+
else {
|
|
1639
|
+
const [endRecordId, endFieldId] = endCell;
|
|
1640
|
+
const startRowIndex = records.findIndex((record) => record._id === startRecordId);
|
|
1641
|
+
const endRowIndex = records.findIndex((record) => record._id === endRecordId);
|
|
1642
|
+
const startColIndex = fields.findIndex((field) => field._id === startFieldId);
|
|
1643
|
+
const endColIndex = fields.findIndex((field) => field._id === endFieldId);
|
|
1644
|
+
const minRowIndex = Math.min(startRowIndex, endRowIndex);
|
|
1645
|
+
const maxRowIndex = Math.max(startRowIndex, endRowIndex);
|
|
1646
|
+
const minColIndex = Math.min(startColIndex, endColIndex);
|
|
1647
|
+
const maxColIndex = Math.max(startColIndex, endColIndex);
|
|
1648
|
+
for (let i = minRowIndex; i <= maxRowIndex; i++) {
|
|
1649
|
+
for (let j = minColIndex; j <= maxColIndex; j++) {
|
|
1650
|
+
selectedCells.add(`${records[i]._id}:${fields[j]._id}`);
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
this.clearSelection();
|
|
1655
|
+
this.setActiveCell(startCell);
|
|
1656
|
+
this.aiTable.selection().selectedCells = selectedCells;
|
|
1657
|
+
}
|
|
1607
1658
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1608
1659
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridSelectionService }); }
|
|
1609
1660
|
}
|
|
@@ -1626,20 +1677,13 @@ class AITableContextMenu extends ThyDropdownAbstractMenu {
|
|
|
1626
1677
|
}
|
|
1627
1678
|
}
|
|
1628
1679
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableContextMenu, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1629
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableContextMenu, isStandalone: true, selector: "ai-table-context-menu", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, targetName: { classPropertyName: "targetName", publicName: "targetName", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "context-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-
|
|
1680
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableContextMenu, isStandalone: true, selector: "ai-table-context-menu", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, targetName: { classPropertyName: "targetName", publicName: "targetName", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "context-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prevent-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n", dependencies: [{ kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1630
1681
|
}
|
|
1631
1682
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableContextMenu, decorators: [{
|
|
1632
1683
|
type: Component,
|
|
1633
1684
|
args: [{ selector: 'ai-table-context-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1634
1685
|
class: 'context-menu'
|
|
1635
|
-
}, imports: [
|
|
1636
|
-
ThyDropdownMenuComponent,
|
|
1637
|
-
ThyDropdownMenuItemDirective,
|
|
1638
|
-
ThyDropdownMenuItemNameDirective,
|
|
1639
|
-
ThyDropdownMenuItemIconDirective,
|
|
1640
|
-
ThyIcon,
|
|
1641
|
-
NgClass
|
|
1642
|
-
], template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prohibit-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n" }]
|
|
1686
|
+
}, imports: [ThyDropdownMenuItemDirective, ThyIcon, NgClass], template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prevent-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n" }]
|
|
1643
1687
|
}] });
|
|
1644
1688
|
|
|
1645
1689
|
const GRID_CELL_EDITOR_MAP = {
|
|
@@ -1675,7 +1719,7 @@ const AI_TABLE_FIELD_ADD_BUTTON = 'AI_TABLE_FIELD_ADD_BUTTON'; // 添加列名
|
|
|
1675
1719
|
const AI_TABLE_FIELD_ADD_BUTTON_WIDTH = 100; // 添加列宽度
|
|
1676
1720
|
const AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE = 8; // 字段表列头图标的间距
|
|
1677
1721
|
const AI_TABLE_FIELD_HEAD_MORE = 'AI_TABLE_FIELD_HEAD_MORE'; // 更多图标名称
|
|
1678
|
-
const
|
|
1722
|
+
const AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS = '.ai-table-prevent-clear-selection';
|
|
1679
1723
|
const AI_TABLE_ICON_COMMON_SIZE = 16; // 表格图标的通用尺寸
|
|
1680
1724
|
const AI_TABLE_CELL = 'AI_TABLE_CELL'; // 单元格标识
|
|
1681
1725
|
// 因为 dom 的边距 12 是不包含 边框的,所以加上边框 2px 才能跟 编辑里面的内容对其;
|
|
@@ -1928,47 +1972,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
1928
1972
|
type: Injectable
|
|
1929
1973
|
}], ctorParameters: () => [{ type: i1$1.ThyPopover }] });
|
|
1930
1974
|
|
|
1931
|
-
class AITableGridMatchCellService {
|
|
1932
|
-
initialize(aiTable) {
|
|
1933
|
-
this.aiTable = aiTable;
|
|
1934
|
-
}
|
|
1935
|
-
findMatchedCells(keywords, references) {
|
|
1936
|
-
if (!keywords) {
|
|
1937
|
-
this.clearMatchedCells();
|
|
1938
|
-
return;
|
|
1939
|
-
}
|
|
1940
|
-
let matchedCells = [];
|
|
1941
|
-
this.aiTable.records().forEach((record) => {
|
|
1942
|
-
this.aiTable.fields().forEach((field) => {
|
|
1943
|
-
if (this.isCellMatchKeywords(this.aiTable, field, record._id, keywords, references)) {
|
|
1944
|
-
matchedCells.push(`${record._id}-${field._id}`);
|
|
1945
|
-
}
|
|
1946
|
-
});
|
|
1947
|
-
});
|
|
1948
|
-
this.aiTable.matchedCells.set([...matchedCells]);
|
|
1949
|
-
}
|
|
1950
|
-
clearMatchedCells() {
|
|
1951
|
-
this.aiTable.matchedCells.set([]);
|
|
1952
|
-
}
|
|
1953
|
-
isCellMatchKeywords(aiTable, field, recordId, keywords, references) {
|
|
1954
|
-
const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
|
|
1955
|
-
const transformValue = transformCellValue(aiTable, field, cellValue);
|
|
1956
|
-
const fieldMethod = ViewOperationMap[field.type];
|
|
1957
|
-
let cellFullText = fieldMethod.cellFullText(transformValue, field, references);
|
|
1958
|
-
try {
|
|
1959
|
-
return keywords && cellFullText.length && cellFullText.some((item) => item.toLowerCase().includes(keywords.toLowerCase()));
|
|
1960
|
-
}
|
|
1961
|
-
catch (error) {
|
|
1962
|
-
return false;
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1966
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService }); }
|
|
1967
|
-
}
|
|
1968
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService, decorators: [{
|
|
1969
|
-
type: Injectable
|
|
1970
|
-
}] });
|
|
1971
|
-
|
|
1972
1975
|
function getColumnIndicesMap(fields) {
|
|
1973
1976
|
const columnIndicesMap = {};
|
|
1974
1977
|
fields?.forEach((field, index) => {
|
|
@@ -2480,19 +2483,195 @@ const TextMeasure = (defaults = {}) => {
|
|
|
2480
2483
|
};
|
|
2481
2484
|
|
|
2482
2485
|
class Field {
|
|
2486
|
+
// 筛选
|
|
2487
|
+
isMeetFilter(condition, cellValue) {
|
|
2488
|
+
switch (condition.operation) {
|
|
2489
|
+
case AITableFilterOperation.empty:
|
|
2490
|
+
case AITableFilterOperation.exists: {
|
|
2491
|
+
return this.isEmptyOrNot(condition.operation, cellValue);
|
|
2492
|
+
}
|
|
2493
|
+
default: {
|
|
2494
|
+
return true;
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
// 查找
|
|
2499
|
+
cellFullText(transformValue, field, references) {
|
|
2500
|
+
let fullText = [];
|
|
2501
|
+
if (!isEmpty(transformValue)) {
|
|
2502
|
+
fullText.push(String(transformValue));
|
|
2503
|
+
}
|
|
2504
|
+
return fullText;
|
|
2505
|
+
}
|
|
2506
|
+
isEmptyOrNot(operation, cellValue) {
|
|
2507
|
+
switch (operation) {
|
|
2508
|
+
case AITableFilterOperation.empty: {
|
|
2509
|
+
return isEmpty(cellValue);
|
|
2510
|
+
}
|
|
2511
|
+
case AITableFilterOperation.exists: {
|
|
2512
|
+
return !isEmpty(cellValue);
|
|
2513
|
+
}
|
|
2514
|
+
default: {
|
|
2515
|
+
throw new Error('compare operator type error');
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
const zhIntlCollator = typeof Intl !== 'undefined' ? new Intl.Collator('zh-CN') : undefined;
|
|
2522
|
+
function compareNumber(a, b) {
|
|
2523
|
+
if (isEmpty(a) && isEmpty(b)) {
|
|
2524
|
+
return 0;
|
|
2525
|
+
}
|
|
2526
|
+
if (isEmpty(a)) {
|
|
2527
|
+
return -1;
|
|
2528
|
+
}
|
|
2529
|
+
if (isEmpty(b)) {
|
|
2530
|
+
return 1;
|
|
2531
|
+
}
|
|
2532
|
+
return a === b ? 0 : a > b ? 1 : -1;
|
|
2533
|
+
}
|
|
2534
|
+
function compareString(a, b) {
|
|
2535
|
+
if (a === b) {
|
|
2536
|
+
return 0;
|
|
2537
|
+
}
|
|
2538
|
+
if (a == null) {
|
|
2539
|
+
return -1;
|
|
2540
|
+
}
|
|
2541
|
+
if (b == null) {
|
|
2542
|
+
return 1;
|
|
2543
|
+
}
|
|
2544
|
+
// pinyin sort
|
|
2545
|
+
return a === b ? 0 : zhIntlCollator ? zhIntlCollator.compare(a, b) : a.localeCompare(b, 'zh-CN') > 0 ? 1 : -1;
|
|
2546
|
+
}
|
|
2547
|
+
function stringInclude(str, searchStr) {
|
|
2548
|
+
return str.toLowerCase().includes(searchStr.trim().toLowerCase());
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* 两数组是否有交集
|
|
2552
|
+
*/
|
|
2553
|
+
function hasIntersect(array1, array2) {
|
|
2554
|
+
if (!Array.isArray(array1) || !Array.isArray(array2)) {
|
|
2555
|
+
return false;
|
|
2556
|
+
}
|
|
2557
|
+
const set1 = new Set(array1);
|
|
2558
|
+
const set2 = new Set(array2);
|
|
2559
|
+
for (const element of set1) {
|
|
2560
|
+
if (set2.has(element)) {
|
|
2561
|
+
return true;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
return false;
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
class DateField extends Field {
|
|
2568
|
+
isMeetFilter(condition, cellValue) {
|
|
2569
|
+
const [left, right] = this.getTimeRange(condition.value);
|
|
2570
|
+
switch (condition.operation) {
|
|
2571
|
+
case AITableFilterOperation.empty:
|
|
2572
|
+
return isEmpty$1(cellValue.timestamp) || cellValue.timestamp === 0;
|
|
2573
|
+
case AITableFilterOperation.exists:
|
|
2574
|
+
return !isEmpty$1(cellValue.timestamp) && cellValue.timestamp !== 0;
|
|
2575
|
+
case AITableFilterOperation.eq:
|
|
2576
|
+
return left <= cellValue.timestamp && cellValue.timestamp < right;
|
|
2577
|
+
case AITableFilterOperation.gt:
|
|
2578
|
+
return cellValue.timestamp > right;
|
|
2579
|
+
case AITableFilterOperation.lt:
|
|
2580
|
+
return cellValue.timestamp < left;
|
|
2581
|
+
case AITableFilterOperation.between:
|
|
2582
|
+
return left <= cellValue.timestamp && cellValue.timestamp < right;
|
|
2583
|
+
default:
|
|
2584
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
compare(cellValue1, cellValue2) {
|
|
2588
|
+
const value1 = cellValueToSortValue$4(cellValue1);
|
|
2589
|
+
const value2 = cellValueToSortValue$4(cellValue2);
|
|
2590
|
+
return compareNumber(value1, value2);
|
|
2591
|
+
}
|
|
2592
|
+
getTimeRange(value) {
|
|
2593
|
+
switch (value) {
|
|
2594
|
+
case 'today':
|
|
2595
|
+
return [new TinyDate(new Date()).startOfDay().getUnixTime(), new TinyDate(new Date()).endOfDay().getUnixTime()];
|
|
2596
|
+
case 'current_week':
|
|
2597
|
+
return [
|
|
2598
|
+
new TinyDate().startOfWeek({ weekStartsOn: 1 }).getUnixTime(),
|
|
2599
|
+
new TinyDate().endOfWeek({ weekStartsOn: 1 }).getUnixTime()
|
|
2600
|
+
];
|
|
2601
|
+
case 'yesterday':
|
|
2602
|
+
return [
|
|
2603
|
+
new TinyDate(subDays(new Date(), 1)).startOfDay().getUnixTime(),
|
|
2604
|
+
new TinyDate(subDays(new Date(), 1)).endOfDay().getUnixTime()
|
|
2605
|
+
];
|
|
2606
|
+
case 'current_month':
|
|
2607
|
+
return [new TinyDate().startOfMonth().getUnixTime(), new TinyDate().endOfMonth().getUnixTime()];
|
|
2608
|
+
default:
|
|
2609
|
+
if (isArray(value)) {
|
|
2610
|
+
return [
|
|
2611
|
+
new TinyDate(fromUnixTime(value[0])).startOfDay().getUnixTime(),
|
|
2612
|
+
new TinyDate(fromUnixTime(value[1])).endOfDay().getUnixTime()
|
|
2613
|
+
];
|
|
2614
|
+
}
|
|
2615
|
+
return [
|
|
2616
|
+
new TinyDate(fromUnixTime(value)).startOfDay().getUnixTime(),
|
|
2617
|
+
new TinyDate(fromUnixTime(value)).endOfDay().getUnixTime()
|
|
2618
|
+
];
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
function cellValueToSortValue$4(cellValue) {
|
|
2623
|
+
return cellValue?.timestamp;
|
|
2483
2624
|
}
|
|
2484
2625
|
|
|
2485
2626
|
class LinkField extends Field {
|
|
2486
|
-
|
|
2487
|
-
|
|
2627
|
+
isMeetFilter(condition, cellValue) {
|
|
2628
|
+
const cellTextValue = cellValue?.text;
|
|
2629
|
+
switch (condition.operation) {
|
|
2630
|
+
case AITableFilterOperation.empty:
|
|
2631
|
+
return isEmpty(cellTextValue);
|
|
2632
|
+
case AITableFilterOperation.exists:
|
|
2633
|
+
return !isEmpty(cellTextValue);
|
|
2634
|
+
case AITableFilterOperation.contain:
|
|
2635
|
+
return !isEmpty(cellTextValue) && stringInclude(cellTextValue, condition.value);
|
|
2636
|
+
default:
|
|
2637
|
+
return super.isMeetFilter(condition, cellTextValue);
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
compare(cellValue1, cellValue2) {
|
|
2641
|
+
return compareString(cellValueToSortValue$3(cellValue1), cellValueToSortValue$3(cellValue2));
|
|
2642
|
+
}
|
|
2643
|
+
cellFullText(transformValue) {
|
|
2644
|
+
let texts = [];
|
|
2488
2645
|
if (!isEmpty(transformValue?.text)) {
|
|
2489
|
-
|
|
2646
|
+
texts.push(transformValue.text);
|
|
2490
2647
|
}
|
|
2491
|
-
return
|
|
2648
|
+
return texts;
|
|
2492
2649
|
}
|
|
2493
2650
|
}
|
|
2651
|
+
function cellValueToSortValue$3(cellValue) {
|
|
2652
|
+
return (cellValue && cellValue.text && cellValue.text.trim()) || null;
|
|
2653
|
+
}
|
|
2494
2654
|
|
|
2495
2655
|
class MemberField extends Field {
|
|
2656
|
+
isMeetFilter(condition, cellValue) {
|
|
2657
|
+
switch (condition.operation) {
|
|
2658
|
+
case AITableFilterOperation.empty:
|
|
2659
|
+
return isEmpty(cellValue);
|
|
2660
|
+
case AITableFilterOperation.exists:
|
|
2661
|
+
return !isEmpty(cellValue);
|
|
2662
|
+
case AITableFilterOperation.in:
|
|
2663
|
+
return Array.isArray(condition.value) && hasIntersect(cellValue, condition.value);
|
|
2664
|
+
case AITableFilterOperation.nin:
|
|
2665
|
+
return Array.isArray(condition.value) && !hasIntersect(cellValue, condition.value);
|
|
2666
|
+
default:
|
|
2667
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
compare(cellValue1, cellValue2, field, references, sortKey) {
|
|
2671
|
+
const value1 = cellValueToSortValue$2(cellValue1, field, references, sortKey);
|
|
2672
|
+
const value2 = cellValueToSortValue$2(cellValue2, field, references, sortKey);
|
|
2673
|
+
return compareString(value1, value2);
|
|
2674
|
+
}
|
|
2496
2675
|
cellFullText(transformValue, field, references) {
|
|
2497
2676
|
let fullText = [];
|
|
2498
2677
|
if (transformValue?.length && references) {
|
|
@@ -2509,9 +2688,78 @@ class MemberField extends Field {
|
|
|
2509
2688
|
return fullText;
|
|
2510
2689
|
}
|
|
2511
2690
|
}
|
|
2691
|
+
function cellValueToSortValue$2(cellValue, field, references, sortKey = 'display_name') {
|
|
2692
|
+
let values = [];
|
|
2693
|
+
if (cellValue?.length && references) {
|
|
2694
|
+
for (let index = 0; index < cellValue.length; index++) {
|
|
2695
|
+
const userInfo = references?.members[cellValue[index]];
|
|
2696
|
+
if (!userInfo) {
|
|
2697
|
+
continue;
|
|
2698
|
+
}
|
|
2699
|
+
const value = userInfo[sortKey];
|
|
2700
|
+
if (value) {
|
|
2701
|
+
values.push(value);
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
return values && values.length ? values.join(', ') : null;
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
class NumberField extends Field {
|
|
2709
|
+
isMeetFilter(condition, cellValue) {
|
|
2710
|
+
switch (condition.operation) {
|
|
2711
|
+
case AITableFilterOperation.empty:
|
|
2712
|
+
return isEmpty(cellValue);
|
|
2713
|
+
case AITableFilterOperation.exists:
|
|
2714
|
+
return !isEmpty(cellValue);
|
|
2715
|
+
case AITableFilterOperation.eq:
|
|
2716
|
+
return !Number.isNaN(condition.value) && cellValue != null && cellValue !== '' && condition.value === cellValue;
|
|
2717
|
+
case AITableFilterOperation.gte:
|
|
2718
|
+
return cellValue != null && cellValue !== '' && cellValue >= condition.value;
|
|
2719
|
+
case AITableFilterOperation.lte:
|
|
2720
|
+
return cellValue != null && cellValue !== '' && cellValue <= condition.value;
|
|
2721
|
+
case AITableFilterOperation.gt:
|
|
2722
|
+
return cellValue != null && cellValue !== '' && cellValue > condition.value;
|
|
2723
|
+
case AITableFilterOperation.lt:
|
|
2724
|
+
return cellValue != null && cellValue !== '' && cellValue < condition.value;
|
|
2725
|
+
case AITableFilterOperation.ne:
|
|
2726
|
+
return cellValue == null || cellValue == '' || Number.isNaN(condition.value) || cellValue !== condition.value;
|
|
2727
|
+
default:
|
|
2728
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
compare(cellValue1, cellValue2) {
|
|
2732
|
+
return compareNumber(cellValue1, cellValue2);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2512
2735
|
|
|
2513
2736
|
class ProgressField extends Field {
|
|
2514
|
-
|
|
2737
|
+
isMeetFilter(condition, cellValue) {
|
|
2738
|
+
switch (condition.operation) {
|
|
2739
|
+
case AITableFilterOperation.empty:
|
|
2740
|
+
return isEmpty(cellValue);
|
|
2741
|
+
case AITableFilterOperation.exists:
|
|
2742
|
+
return !isEmpty(cellValue);
|
|
2743
|
+
case AITableFilterOperation.eq:
|
|
2744
|
+
return !Number.isNaN(condition.value) && cellValue != null && cellValue !== '' && condition.value === cellValue;
|
|
2745
|
+
case AITableFilterOperation.gte:
|
|
2746
|
+
return cellValue != null && cellValue !== '' && cellValue >= condition.value;
|
|
2747
|
+
case AITableFilterOperation.lte:
|
|
2748
|
+
return cellValue != null && cellValue !== '' && cellValue <= condition.value;
|
|
2749
|
+
case AITableFilterOperation.gt:
|
|
2750
|
+
return cellValue != null && cellValue !== '' && cellValue > condition.value;
|
|
2751
|
+
case AITableFilterOperation.lt:
|
|
2752
|
+
return cellValue != null && cellValue !== '' && cellValue < condition.value;
|
|
2753
|
+
case AITableFilterOperation.ne:
|
|
2754
|
+
return cellValue == null || cellValue == '' || Number.isNaN(condition.value) || cellValue !== condition.value;
|
|
2755
|
+
default:
|
|
2756
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
compare(cellValue1, cellValue2) {
|
|
2760
|
+
return compareNumber(cellValue1, cellValue2);
|
|
2761
|
+
}
|
|
2762
|
+
cellFullText(transformValue) {
|
|
2515
2763
|
let fullText = [];
|
|
2516
2764
|
if (!isEmpty(transformValue)) {
|
|
2517
2765
|
fullText.push(`${transformValue}%`);
|
|
@@ -2520,40 +2768,111 @@ class ProgressField extends Field {
|
|
|
2520
2768
|
}
|
|
2521
2769
|
}
|
|
2522
2770
|
|
|
2771
|
+
class RateField extends Field {
|
|
2772
|
+
isMeetFilter(condition, cellValue) {
|
|
2773
|
+
switch (condition.operation) {
|
|
2774
|
+
case AITableFilterOperation.empty:
|
|
2775
|
+
return isEmpty(cellValue);
|
|
2776
|
+
case AITableFilterOperation.exists:
|
|
2777
|
+
return !isEmpty(cellValue);
|
|
2778
|
+
case AITableFilterOperation.in:
|
|
2779
|
+
const isContain = condition.value.some((item) => String(item) === String(cellValue));
|
|
2780
|
+
return !isEmpty(cellValue) && isContain;
|
|
2781
|
+
case AITableFilterOperation.nin:
|
|
2782
|
+
const noContain = condition.value.every((item) => String(item) !== String(cellValue));
|
|
2783
|
+
return isEmpty(cellValue) || noContain;
|
|
2784
|
+
default:
|
|
2785
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
compare(cellValue1, cellValue2) {
|
|
2789
|
+
return compareNumber(cellValue1, cellValue2);
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2523
2793
|
class SelectField extends Field {
|
|
2794
|
+
isMeetFilter(condition, cellValue) {
|
|
2795
|
+
switch (condition.operation) {
|
|
2796
|
+
case AITableFilterOperation.empty:
|
|
2797
|
+
return isEmpty(cellValue);
|
|
2798
|
+
case AITableFilterOperation.exists:
|
|
2799
|
+
return !isEmpty(cellValue);
|
|
2800
|
+
case AITableFilterOperation.in:
|
|
2801
|
+
return Array.isArray(condition.value) && hasIntersect(cellValue, condition.value);
|
|
2802
|
+
case AITableFilterOperation.nin:
|
|
2803
|
+
return Array.isArray(condition.value) && !hasIntersect(cellValue, condition.value);
|
|
2804
|
+
default:
|
|
2805
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
compare(cellValue1, cellValue2, field) {
|
|
2809
|
+
const value1 = cellValueToSortValue$1(cellValue1, field);
|
|
2810
|
+
const value2 = cellValueToSortValue$1(cellValue2, field);
|
|
2811
|
+
return compareString(value1, value2);
|
|
2812
|
+
}
|
|
2524
2813
|
cellFullText(transformValue, field) {
|
|
2525
|
-
let
|
|
2814
|
+
let fullText = [];
|
|
2815
|
+
const optionsMap = helpers.keyBy(field.settings.options || [], '_id');
|
|
2526
2816
|
if (transformValue && Array.isArray(transformValue) && transformValue.length) {
|
|
2527
2817
|
transformValue.forEach((optionId) => {
|
|
2528
|
-
const
|
|
2529
|
-
if (
|
|
2530
|
-
|
|
2818
|
+
const option = optionsMap[optionId];
|
|
2819
|
+
if (option && option.text) {
|
|
2820
|
+
fullText.push(option.text);
|
|
2531
2821
|
}
|
|
2532
2822
|
});
|
|
2533
2823
|
}
|
|
2534
|
-
return
|
|
2824
|
+
return fullText;
|
|
2535
2825
|
}
|
|
2536
2826
|
}
|
|
2827
|
+
function cellValueToSortValue$1(cellValue, field) {
|
|
2828
|
+
if (!cellValue) {
|
|
2829
|
+
return null;
|
|
2830
|
+
}
|
|
2831
|
+
const texts = [];
|
|
2832
|
+
const optionsMap = helpers.keyBy(field.settings.options || [], '_id');
|
|
2833
|
+
if (cellValue && Array.isArray(cellValue) && cellValue.length) {
|
|
2834
|
+
cellValue.forEach((optionId) => {
|
|
2835
|
+
const option = optionsMap[optionId];
|
|
2836
|
+
if (option && option.text) {
|
|
2837
|
+
texts.push(option.text);
|
|
2838
|
+
}
|
|
2839
|
+
});
|
|
2840
|
+
}
|
|
2841
|
+
return texts && texts.length ? texts.join(',') : null;
|
|
2842
|
+
}
|
|
2537
2843
|
|
|
2538
2844
|
class TextField extends Field {
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2845
|
+
isMeetFilter(condition, cellValue) {
|
|
2846
|
+
switch (condition.operation) {
|
|
2847
|
+
case AITableFilterOperation.empty:
|
|
2848
|
+
return isEmpty(cellValue);
|
|
2849
|
+
case AITableFilterOperation.exists:
|
|
2850
|
+
return !isEmpty(cellValue);
|
|
2851
|
+
case AITableFilterOperation.contain:
|
|
2852
|
+
return !isEmpty(cellValue) && stringInclude(cellValue, condition.value);
|
|
2853
|
+
default:
|
|
2854
|
+
return super.isMeetFilter(condition, cellValue);
|
|
2543
2855
|
}
|
|
2544
|
-
return fullText;
|
|
2545
2856
|
}
|
|
2857
|
+
compare(cellValue1, cellValue2) {
|
|
2858
|
+
const value1 = cellValueToSortValue(cellValue1);
|
|
2859
|
+
const value2 = cellValueToSortValue(cellValue2);
|
|
2860
|
+
return compareString(value1, value2);
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
function cellValueToSortValue(cellValue) {
|
|
2864
|
+
return (cellValue && cellValue.trim()) || null;
|
|
2546
2865
|
}
|
|
2547
2866
|
|
|
2548
2867
|
const ViewOperationMap = {
|
|
2549
2868
|
[AITableFieldType.text]: new TextField(),
|
|
2550
2869
|
[AITableFieldType.richText]: new TextField(),
|
|
2551
2870
|
[AITableFieldType.select]: new SelectField(),
|
|
2552
|
-
[AITableFieldType.date]: new
|
|
2553
|
-
[AITableFieldType.createdAt]: new
|
|
2554
|
-
[AITableFieldType.updatedAt]: new
|
|
2555
|
-
[AITableFieldType.number]: new
|
|
2556
|
-
[AITableFieldType.rate]: new
|
|
2871
|
+
[AITableFieldType.date]: new DateField(),
|
|
2872
|
+
[AITableFieldType.createdAt]: new DateField(),
|
|
2873
|
+
[AITableFieldType.updatedAt]: new DateField(),
|
|
2874
|
+
[AITableFieldType.number]: new NumberField(),
|
|
2875
|
+
[AITableFieldType.rate]: new RateField(),
|
|
2557
2876
|
[AITableFieldType.link]: new LinkField(),
|
|
2558
2877
|
[AITableFieldType.member]: new MemberField(),
|
|
2559
2878
|
[AITableFieldType.progress]: new ProgressField(),
|
|
@@ -2561,6 +2880,14 @@ const ViewOperationMap = {
|
|
|
2561
2880
|
[AITableFieldType.updatedBy]: new MemberField()
|
|
2562
2881
|
};
|
|
2563
2882
|
|
|
2883
|
+
const isCellMatchKeywords = (aiTable, field, recordId, keywords, references) => {
|
|
2884
|
+
const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
|
|
2885
|
+
const transformValue = transformCellValue(aiTable, field, cellValue);
|
|
2886
|
+
const fieldMethod = ViewOperationMap[field.type];
|
|
2887
|
+
let cellFullText = fieldMethod.cellFullText(transformValue, field, references);
|
|
2888
|
+
return keywords && cellFullText.length && cellFullText.some((text) => text.toLowerCase().includes(keywords.toLowerCase()));
|
|
2889
|
+
};
|
|
2890
|
+
|
|
2564
2891
|
class AITableGridEventService {
|
|
2565
2892
|
constructor() {
|
|
2566
2893
|
this.dblClickEvent$ = new Subject();
|
|
@@ -2645,7 +2972,8 @@ class AITableGridEventService {
|
|
|
2645
2972
|
const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
|
|
2646
2973
|
const { scrollState } = aiTable.context;
|
|
2647
2974
|
const { rowHeight, columnCount } = coordinate;
|
|
2648
|
-
const
|
|
2975
|
+
const cell = [recordId, fieldId];
|
|
2976
|
+
const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
|
|
2649
2977
|
const originX = coordinate.getColumnOffset(columnIndex);
|
|
2650
2978
|
const originY = coordinate.getRowOffset(rowIndex);
|
|
2651
2979
|
const columnWidth = coordinate.getColumnWidth(columnIndex);
|
|
@@ -2814,7 +3142,6 @@ class AITableGridBase {
|
|
|
2814
3142
|
this.aiTableGridFieldService = inject(AITableGridFieldService);
|
|
2815
3143
|
this.aiTableGridEventService = inject(AITableGridEventService);
|
|
2816
3144
|
this.aiTableGridSelectionService = inject(AITableGridSelectionService);
|
|
2817
|
-
this.aiTableGridMatchCellService = inject(AITableGridMatchCellService);
|
|
2818
3145
|
}
|
|
2819
3146
|
ngOnInit() {
|
|
2820
3147
|
this.initAITable();
|
|
@@ -2830,7 +3157,6 @@ class AITableGridBase {
|
|
|
2830
3157
|
initService() {
|
|
2831
3158
|
this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
|
|
2832
3159
|
this.aiTableGridSelectionService.initialize(this.aiTable);
|
|
2833
|
-
this.aiTableGridMatchCellService.initialize(this.aiTable);
|
|
2834
3160
|
this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
|
|
2835
3161
|
this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
|
|
2836
3162
|
this.aiTable.references.set(this.aiReferences());
|
|
@@ -2940,7 +3266,7 @@ class AITableDomGrid extends AITableGridBase {
|
|
|
2940
3266
|
});
|
|
2941
3267
|
}
|
|
2942
3268
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2943
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n #cell\n class=\"grid-cell\"\n [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3269
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2944
3270
|
}
|
|
2945
3271
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
|
|
2946
3272
|
type: Component,
|
|
@@ -2976,7 +3302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
2976
3302
|
UserPipe,
|
|
2977
3303
|
SelectSettingPipe,
|
|
2978
3304
|
MemberSettingPipe
|
|
2979
|
-
], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n #cell\n class=\"grid-cell\"\n [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
|
|
3305
|
+
], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
|
|
2980
3306
|
}] });
|
|
2981
3307
|
|
|
2982
3308
|
const KO_CONTAINER_TOKEN = new InjectionToken('KO_CONTAINER_TOKEN');
|
|
@@ -5391,28 +5717,9 @@ const createCells = (config) => {
|
|
|
5391
5717
|
break;
|
|
5392
5718
|
}
|
|
5393
5719
|
case AITableRowType.record: {
|
|
5394
|
-
let background = colors.white;
|
|
5395
5720
|
const fieldId = field._id;
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5398
|
-
const isHoverRow = isHover && targetName !== AI_TABLE_FIELD_HEAD;
|
|
5399
|
-
const activeCell = AITable.getActiveCell(aiTable);
|
|
5400
|
-
const isSiblingActiveCell = recordId === activeCell?.recordId && fieldId !== activeCell?.fieldId;
|
|
5401
|
-
const isActiveCell = recordId === activeCell?.recordId;
|
|
5402
|
-
let matchedCellsMap = {};
|
|
5403
|
-
aiTable.matchedCells().forEach((key) => {
|
|
5404
|
-
matchedCellsMap[key] = true;
|
|
5405
|
-
});
|
|
5406
|
-
const isMatchedCell = matchedCellsMap[`${recordId}-${fieldId}`];
|
|
5407
|
-
if (isMatchedCell) {
|
|
5408
|
-
background = colors.itemMatchBgColor;
|
|
5409
|
-
}
|
|
5410
|
-
else if (isCheckedRow || isSelected || isSiblingActiveCell) {
|
|
5411
|
-
background = colors.itemActiveBgColor;
|
|
5412
|
-
}
|
|
5413
|
-
else if (isHoverRow && !isActiveCell) {
|
|
5414
|
-
background = colors.gray80;
|
|
5415
|
-
}
|
|
5721
|
+
const cell = [recordId, fieldId];
|
|
5722
|
+
let background = getCellBackground(cell, isHover, targetName, aiTable);
|
|
5416
5723
|
recordRowLayout.init({
|
|
5417
5724
|
x,
|
|
5418
5725
|
y,
|
|
@@ -5426,8 +5733,8 @@ const createCells = (config) => {
|
|
|
5426
5733
|
recordRowLayout.render({
|
|
5427
5734
|
row,
|
|
5428
5735
|
style: { fill: background },
|
|
5429
|
-
isHoverRow,
|
|
5430
|
-
isCheckedRow
|
|
5736
|
+
isHoverRow: isHoverRecord(isHover, targetName),
|
|
5737
|
+
isCheckedRow: isSelectedRecord(recordId, aiTable)
|
|
5431
5738
|
});
|
|
5432
5739
|
const { width, offset } = getCellHorizontalPosition({
|
|
5433
5740
|
columnIndex,
|
|
@@ -5450,7 +5757,7 @@ const createCells = (config) => {
|
|
|
5450
5757
|
cellValue,
|
|
5451
5758
|
transformValue,
|
|
5452
5759
|
references,
|
|
5453
|
-
isActive:
|
|
5760
|
+
isActive: isSelectedField(fieldId, aiTable),
|
|
5454
5761
|
style,
|
|
5455
5762
|
colors
|
|
5456
5763
|
};
|
|
@@ -5472,6 +5779,55 @@ const createCells = (config) => {
|
|
|
5472
5779
|
}
|
|
5473
5780
|
}
|
|
5474
5781
|
};
|
|
5782
|
+
const getCellBackground = (cell, isHover, targetName, aiTable) => {
|
|
5783
|
+
const colors = AITable.getColors();
|
|
5784
|
+
const [recordId, fieldId] = cell;
|
|
5785
|
+
let background = colors.white;
|
|
5786
|
+
const _isHoverRecord = isHoverRecord(isHover, targetName);
|
|
5787
|
+
const _isSelectedRecord = isSelectedRecord(recordId, aiTable);
|
|
5788
|
+
const _isSelectedField = isSelectedField(fieldId, aiTable);
|
|
5789
|
+
const _isSiblingCell = isSiblingCell(cell, aiTable);
|
|
5790
|
+
const _isActiveCell = isActiveCell(cell, aiTable);
|
|
5791
|
+
const _isSelectedCell = isSelectedCell(cell, aiTable);
|
|
5792
|
+
const _isKeywordsMatchedCell = isKeywordsMatchedCell(cell, aiTable);
|
|
5793
|
+
if (_isKeywordsMatchedCell) {
|
|
5794
|
+
background = colors.itemMatchBgColor;
|
|
5795
|
+
}
|
|
5796
|
+
else if (_isSelectedRecord || _isSelectedField || _isSiblingCell || (_isSelectedCell && !_isActiveCell)) {
|
|
5797
|
+
background = colors.itemActiveBgColor;
|
|
5798
|
+
}
|
|
5799
|
+
else if (_isHoverRecord && !_isActiveCell) {
|
|
5800
|
+
background = colors.gray80;
|
|
5801
|
+
}
|
|
5802
|
+
return background;
|
|
5803
|
+
};
|
|
5804
|
+
const isActiveCell = (cell, aiTable) => {
|
|
5805
|
+
const [recordId, fieldId] = cell;
|
|
5806
|
+
const [activeRecordId, activeFieldId] = AITable.getActiveCell(aiTable) || [];
|
|
5807
|
+
return recordId === activeRecordId && fieldId === activeFieldId;
|
|
5808
|
+
};
|
|
5809
|
+
const isSiblingCell = (cell, aiTable) => {
|
|
5810
|
+
const [recordId, fieldId] = cell;
|
|
5811
|
+
const [activeRecordId, activeFieldId] = AITable.getActiveCell(aiTable) || [];
|
|
5812
|
+
return AITable.getActiveRecordIds(aiTable).length === 1 && recordId === activeRecordId && fieldId !== activeFieldId;
|
|
5813
|
+
};
|
|
5814
|
+
const isKeywordsMatchedCell = (cell, aiTable) => {
|
|
5815
|
+
const [recordId, fieldId] = cell;
|
|
5816
|
+
return aiTable.keywordsMatchedCells().has(`${recordId}:${fieldId}`);
|
|
5817
|
+
};
|
|
5818
|
+
const isSelectedCell = (cell, aiTable) => {
|
|
5819
|
+
const [recordId, fieldId] = cell;
|
|
5820
|
+
return aiTable.selection().selectedCells.has(`${recordId}:${fieldId}`);
|
|
5821
|
+
};
|
|
5822
|
+
const isSelectedField = (fieldId, aiTable) => {
|
|
5823
|
+
return aiTable.selection().selectedFields.has(fieldId);
|
|
5824
|
+
};
|
|
5825
|
+
const isSelectedRecord = (recordId, aiTable) => {
|
|
5826
|
+
return aiTable.selection().selectedRecords.has(recordId);
|
|
5827
|
+
};
|
|
5828
|
+
const isHoverRecord = (isHover, targetName) => {
|
|
5829
|
+
return isHover && targetName !== AI_TABLE_FIELD_HEAD;
|
|
5830
|
+
};
|
|
5475
5831
|
|
|
5476
5832
|
class AITableCells {
|
|
5477
5833
|
constructor() {
|
|
@@ -6183,8 +6539,11 @@ const createActiveCellBorder = (config) => {
|
|
|
6183
6539
|
const totalColumnCount = visibleColumns.length;
|
|
6184
6540
|
let activeCellBorder = null;
|
|
6185
6541
|
let frozenActiveCellBorder = null;
|
|
6186
|
-
if (activeCell
|
|
6187
|
-
|
|
6542
|
+
if (Array.isArray(activeCell) &&
|
|
6543
|
+
!!activeCell.length &&
|
|
6544
|
+
aiTable.context.visibleRowsIndexMap().has(activeCell[0]) &&
|
|
6545
|
+
aiTable.context.visibleColumnsMap().has(activeCell[1])) {
|
|
6546
|
+
const fieldId = activeCell[1];
|
|
6188
6547
|
const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, activeCell);
|
|
6189
6548
|
const checkIsVisible = (rowIndex, columnIndex) => {
|
|
6190
6549
|
if (columnIndex < frozenColumnCount) {
|
|
@@ -6243,6 +6602,7 @@ class AITableRenderer {
|
|
|
6243
6602
|
this.config = input.required();
|
|
6244
6603
|
this.koMousemove = output();
|
|
6245
6604
|
this.koMousedown = output();
|
|
6605
|
+
this.koMouseup = output();
|
|
6246
6606
|
this.koContextmenu = output();
|
|
6247
6607
|
this.koWheel = output();
|
|
6248
6608
|
this.koClick = output();
|
|
@@ -6377,6 +6737,9 @@ class AITableRenderer {
|
|
|
6377
6737
|
stageMousedown(e) {
|
|
6378
6738
|
this.koMousedown.emit(e);
|
|
6379
6739
|
}
|
|
6740
|
+
stageMouseup(e) {
|
|
6741
|
+
this.koMouseup.emit(e);
|
|
6742
|
+
}
|
|
6380
6743
|
stageContextmenu(e) {
|
|
6381
6744
|
this.koContextmenu.emit(e);
|
|
6382
6745
|
}
|
|
@@ -6387,7 +6750,7 @@ class AITableRenderer {
|
|
|
6387
6750
|
this.koDblclick.emit(e);
|
|
6388
6751
|
}
|
|
6389
6752
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6390
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6753
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6391
6754
|
}
|
|
6392
6755
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, decorators: [{
|
|
6393
6756
|
type: Component,
|
|
@@ -6404,13 +6767,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
6404
6767
|
AITableAddField,
|
|
6405
6768
|
AITableHoverRowHeads,
|
|
6406
6769
|
AITableOtherRows
|
|
6407
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
|
|
6770
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
|
|
6408
6771
|
}] });
|
|
6409
6772
|
|
|
6410
6773
|
class AITableGrid extends AITableGridBase {
|
|
6411
6774
|
constructor() {
|
|
6412
6775
|
super();
|
|
6413
6776
|
this.viewContainerRef = inject(ViewContainerRef);
|
|
6777
|
+
this.isDragSelecting = false;
|
|
6778
|
+
this.dragSelectionStart = null;
|
|
6414
6779
|
this.fieldHeadHeight = AI_TABLE_FIELD_HEAD_HEIGHT;
|
|
6415
6780
|
this.containerRect = signal({ width: 0, height: 0 });
|
|
6416
6781
|
this.hasContainerRect = computed(() => {
|
|
@@ -6514,7 +6879,7 @@ class AITableGrid extends AITableGridBase {
|
|
|
6514
6879
|
}
|
|
6515
6880
|
});
|
|
6516
6881
|
effect(() => {
|
|
6517
|
-
this.
|
|
6882
|
+
this.setKeywordsMatchedCells();
|
|
6518
6883
|
}, { allowSignalWrites: true });
|
|
6519
6884
|
}
|
|
6520
6885
|
ngOnInit() {
|
|
@@ -6534,6 +6899,21 @@ class AITableGrid extends AITableGridBase {
|
|
|
6534
6899
|
scrollAction: this.scrollAction
|
|
6535
6900
|
});
|
|
6536
6901
|
}
|
|
6902
|
+
setKeywordsMatchedCells() {
|
|
6903
|
+
const keywords = this.aiKeywords();
|
|
6904
|
+
let matchedCells = new Set();
|
|
6905
|
+
if (keywords) {
|
|
6906
|
+
const references = this.aiReferences();
|
|
6907
|
+
this.aiTable.records().forEach((record) => {
|
|
6908
|
+
this.aiTable.fields().forEach((field) => {
|
|
6909
|
+
if (isCellMatchKeywords(this.aiTable, field, record._id, keywords, references)) {
|
|
6910
|
+
matchedCells.add(`${record._id}:${field._id}`);
|
|
6911
|
+
}
|
|
6912
|
+
});
|
|
6913
|
+
});
|
|
6914
|
+
}
|
|
6915
|
+
this.aiTable.keywordsMatchedCells.set(matchedCells);
|
|
6916
|
+
}
|
|
6537
6917
|
stageMousemove(e) {
|
|
6538
6918
|
if (this.timer) {
|
|
6539
6919
|
cancelAnimationFrame(this.timer);
|
|
@@ -6550,6 +6930,16 @@ class AITableGrid extends AITableGridBase {
|
|
|
6550
6930
|
handleMouseStyle(curMousePosition.realTargetName, curMousePosition.areaType, this.containerElement());
|
|
6551
6931
|
context.setPointPosition(curMousePosition);
|
|
6552
6932
|
this.timer = null;
|
|
6933
|
+
if (this.isDragSelecting) {
|
|
6934
|
+
const { fieldId, recordId } = getDetailByTargetName(curMousePosition.realTargetName);
|
|
6935
|
+
if (fieldId && recordId) {
|
|
6936
|
+
const startCell = this.dragSelectionStart;
|
|
6937
|
+
const endCell = [recordId, fieldId];
|
|
6938
|
+
if (startCell && !!startCell.length) {
|
|
6939
|
+
this.aiTableGridSelectionService.selectCells(startCell, endCell);
|
|
6940
|
+
}
|
|
6941
|
+
}
|
|
6942
|
+
}
|
|
6553
6943
|
});
|
|
6554
6944
|
}
|
|
6555
6945
|
stageMousedown(e) {
|
|
@@ -6559,7 +6949,7 @@ class AITableGrid extends AITableGridBase {
|
|
|
6559
6949
|
if (mouseEvent.button === AITableMouseDownType.Right &&
|
|
6560
6950
|
recordId &&
|
|
6561
6951
|
fieldId &&
|
|
6562
|
-
this.aiTable.selection().selectedRecords.has(recordId)) {
|
|
6952
|
+
(this.aiTable.selection().selectedRecords.has(recordId) || this.aiTable.selection().selectedCells.has(`${recordId}:${fieldId}`))) {
|
|
6563
6953
|
return;
|
|
6564
6954
|
}
|
|
6565
6955
|
switch (targetName) {
|
|
@@ -6573,7 +6963,9 @@ class AITableGrid extends AITableGridBase {
|
|
|
6573
6963
|
if (!recordId || !fieldId)
|
|
6574
6964
|
return;
|
|
6575
6965
|
this.aiTableGridEventService.closeCellEditor();
|
|
6576
|
-
|
|
6966
|
+
const dragSelectionStart = [recordId, fieldId];
|
|
6967
|
+
this.updateDragSelectionState(true, dragSelectionStart);
|
|
6968
|
+
this.aiTableGridSelectionService.selectCells(dragSelectionStart);
|
|
6577
6969
|
return;
|
|
6578
6970
|
case AI_TABLE_ROW_ADD_BUTTON:
|
|
6579
6971
|
case AI_TABLE_FIELD_ADD_BUTTON:
|
|
@@ -6584,6 +6976,9 @@ class AITableGrid extends AITableGridBase {
|
|
|
6584
6976
|
this.aiTableGridSelectionService.clearSelection();
|
|
6585
6977
|
}
|
|
6586
6978
|
}
|
|
6979
|
+
stageMouseup(e) {
|
|
6980
|
+
this.updateDragSelectionState(false, null);
|
|
6981
|
+
}
|
|
6587
6982
|
stageContextmenu(e) {
|
|
6588
6983
|
const mouseEvent = e.event.evt;
|
|
6589
6984
|
mouseEvent.preventDefault();
|
|
@@ -6725,11 +7120,16 @@ class AITableGrid extends AITableGridBase {
|
|
|
6725
7120
|
fromEvent(document, 'mousedown', { passive: true })
|
|
6726
7121
|
.pipe(filter((e) => e.target instanceof Element &&
|
|
6727
7122
|
!this.containerElement().contains(e.target) &&
|
|
6728
|
-
!
|
|
7123
|
+
!e.target.closest(AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS)), takeUntilDestroyed(this.destroyRef))
|
|
6729
7124
|
.subscribe(() => {
|
|
7125
|
+
this.updateDragSelectionState(false, null);
|
|
6730
7126
|
this.aiTableGridSelectionService.clearSelection();
|
|
6731
7127
|
});
|
|
6732
7128
|
}
|
|
7129
|
+
updateDragSelectionState(isDragSelecting, dragSelectionStart) {
|
|
7130
|
+
this.isDragSelecting = isDragSelecting;
|
|
7131
|
+
this.dragSelectionStart = dragSelectionStart;
|
|
7132
|
+
}
|
|
6733
7133
|
verticalScroll(e) {
|
|
6734
7134
|
const { scrollTop } = e.target;
|
|
6735
7135
|
this.aiTable.context.setScrollState({
|
|
@@ -6801,18 +7201,18 @@ class AITableGrid extends AITableGridBase {
|
|
|
6801
7201
|
}
|
|
6802
7202
|
}
|
|
6803
7203
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6804
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService
|
|
7204
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koMouseup", "koContextmenu", "koWheel", "koClick", "koDblclick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6805
7205
|
}
|
|
6806
7206
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGrid, decorators: [{
|
|
6807
7207
|
type: Component,
|
|
6808
7208
|
args: [{ selector: 'ai-table-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
6809
7209
|
class: 'ai-table-grid'
|
|
6810
|
-
}, imports: [AITableRenderer], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService
|
|
7210
|
+
}, imports: [AITableRenderer], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n" }]
|
|
6811
7211
|
}], ctorParameters: () => [] });
|
|
6812
7212
|
|
|
6813
7213
|
/**
|
|
6814
7214
|
* Generated bundle index. Do not edit.
|
|
6815
7215
|
*/
|
|
6816
7216
|
|
|
6817
|
-
export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldPropertyEditor, AITableFieldType, AITableGrid, AITableGridEventService, AITableGridFieldService,
|
|
7217
|
+
export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldPropertyEditor, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, FONT_SIZE_SM, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, ViewOperationMap, WebOutlinedPath, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, zhIntlCollator };
|
|
6818
7218
|
//# sourceMappingURL=ai-table-grid.mjs.map
|