@ai-table/grid 0.0.28 → 0.0.30
Sign up to get free protection for your applications and to get access to all the features.
- 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
|