@alaarab/ogrid-angular-material 2.0.5 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/column-header-menu/column-header-menu.component.js +20 -41
- package/dist/esm/datagrid-table/datagrid-table.component.js +11 -282
- package/dist/types/column-header-menu/column-header-menu.component.d.ts +8 -9
- package/dist/types/datagrid-table/datagrid-table.component.d.ts +7 -134
- package/package.json +5 -4
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component,
|
|
7
|
+
import { Component, input, viewChild, ChangeDetectionStrategy } from '@angular/core';
|
|
8
8
|
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
|
|
9
9
|
import { MatButtonModule } from '@angular/material/button';
|
|
10
10
|
import { MatIconModule } from '@angular/material/icon';
|
|
@@ -15,65 +15,44 @@ import { COLUMN_HEADER_MENU_ITEMS } from '@alaarab/ogrid-core';
|
|
|
15
15
|
*/
|
|
16
16
|
let ColumnHeaderMenuComponent = class ColumnHeaderMenuComponent {
|
|
17
17
|
constructor() {
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
18
|
+
this.columnId = input.required();
|
|
19
|
+
this.canPinLeft = input(true);
|
|
20
|
+
this.canPinRight = input(true);
|
|
21
|
+
this.canUnpin = input(false);
|
|
22
|
+
this.onPinLeft = input(undefined);
|
|
23
|
+
this.onPinRight = input(undefined);
|
|
24
|
+
this.onUnpin = input(undefined);
|
|
25
|
+
this.menuTrigger = viewChild(MatMenuTrigger);
|
|
24
26
|
this.menuItems = COLUMN_HEADER_MENU_ITEMS;
|
|
25
27
|
}
|
|
26
28
|
handlePinLeft() {
|
|
27
|
-
if (this.canPinLeft) {
|
|
28
|
-
this.
|
|
29
|
+
if (this.canPinLeft()) {
|
|
30
|
+
this.onPinLeft()?.();
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
handlePinRight() {
|
|
32
|
-
if (this.canPinRight) {
|
|
33
|
-
this.
|
|
34
|
+
if (this.canPinRight()) {
|
|
35
|
+
this.onPinRight()?.();
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
handleUnpin() {
|
|
37
|
-
if (this.canUnpin) {
|
|
38
|
-
this.
|
|
39
|
+
if (this.canUnpin()) {
|
|
40
|
+
this.onUnpin()?.();
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
};
|
|
42
|
-
__decorate([
|
|
43
|
-
Input()
|
|
44
|
-
], ColumnHeaderMenuComponent.prototype, "columnId", void 0);
|
|
45
|
-
__decorate([
|
|
46
|
-
Input()
|
|
47
|
-
], ColumnHeaderMenuComponent.prototype, "canPinLeft", void 0);
|
|
48
|
-
__decorate([
|
|
49
|
-
Input()
|
|
50
|
-
], ColumnHeaderMenuComponent.prototype, "canPinRight", void 0);
|
|
51
|
-
__decorate([
|
|
52
|
-
Input()
|
|
53
|
-
], ColumnHeaderMenuComponent.prototype, "canUnpin", void 0);
|
|
54
|
-
__decorate([
|
|
55
|
-
Output()
|
|
56
|
-
], ColumnHeaderMenuComponent.prototype, "pinLeft", void 0);
|
|
57
|
-
__decorate([
|
|
58
|
-
Output()
|
|
59
|
-
], ColumnHeaderMenuComponent.prototype, "pinRight", void 0);
|
|
60
|
-
__decorate([
|
|
61
|
-
Output()
|
|
62
|
-
], ColumnHeaderMenuComponent.prototype, "unpin", void 0);
|
|
63
|
-
__decorate([
|
|
64
|
-
ViewChild(MatMenuTrigger)
|
|
65
|
-
], ColumnHeaderMenuComponent.prototype, "menuTrigger", void 0);
|
|
66
44
|
ColumnHeaderMenuComponent = __decorate([
|
|
67
45
|
Component({
|
|
68
46
|
selector: 'column-header-menu',
|
|
69
47
|
standalone: true,
|
|
70
48
|
imports: [MatMenuModule, MatButtonModule, MatIconModule],
|
|
49
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
71
50
|
template: `
|
|
72
51
|
<button
|
|
73
52
|
mat-icon-button
|
|
74
53
|
[matMenuTriggerFor]="menu"
|
|
75
54
|
class="column-header-menu-trigger"
|
|
76
|
-
[attr.aria-label]="'Column options for ' + columnId"
|
|
55
|
+
[attr.aria-label]="'Column options for ' + columnId()"
|
|
77
56
|
>
|
|
78
57
|
<mat-icon>more_vert</mat-icon>
|
|
79
58
|
</button>
|
|
@@ -81,21 +60,21 @@ ColumnHeaderMenuComponent = __decorate([
|
|
|
81
60
|
<mat-menu #menu="matMenu">
|
|
82
61
|
<button
|
|
83
62
|
mat-menu-item
|
|
84
|
-
[disabled]="!canPinLeft"
|
|
63
|
+
[disabled]="!canPinLeft()"
|
|
85
64
|
(click)="handlePinLeft()"
|
|
86
65
|
>
|
|
87
66
|
{{ menuItems[0].label }}
|
|
88
67
|
</button>
|
|
89
68
|
<button
|
|
90
69
|
mat-menu-item
|
|
91
|
-
[disabled]="!canPinRight"
|
|
70
|
+
[disabled]="!canPinRight()"
|
|
92
71
|
(click)="handlePinRight()"
|
|
93
72
|
>
|
|
94
73
|
{{ menuItems[1].label }}
|
|
95
74
|
</button>
|
|
96
75
|
<button
|
|
97
76
|
mat-menu-item
|
|
98
|
-
[disabled]="!canUnpin"
|
|
77
|
+
[disabled]="!canUnpin()"
|
|
99
78
|
(click)="handleUnpin()"
|
|
100
79
|
>
|
|
101
80
|
{{ menuItems[2].label }}
|
|
@@ -4,301 +4,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component, input,
|
|
8
|
-
import {
|
|
7
|
+
import { Component, input, viewChild, ChangeDetectionStrategy, } from '@angular/core';
|
|
8
|
+
import { BaseDataGridTableComponent, DataGridStateService, MarchingAntsOverlayComponent, CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, } from '@alaarab/ogrid-angular';
|
|
9
9
|
import { ColumnHeaderFilterComponent } from '../column-header-filter/column-header-filter.component';
|
|
10
10
|
import { ColumnHeaderMenuComponent } from '../column-header-menu/column-header-menu.component';
|
|
11
11
|
/**
|
|
12
12
|
* DataGridTable component using native HTML table with Material Design-inspired styling.
|
|
13
13
|
* Standalone component — this is the workhorse of the grid.
|
|
14
14
|
*/
|
|
15
|
-
let DataGridTableComponent = class DataGridTableComponent {
|
|
15
|
+
let DataGridTableComponent = class DataGridTableComponent extends BaseDataGridTableComponent {
|
|
16
16
|
constructor() {
|
|
17
|
+
super();
|
|
17
18
|
this.propsInput = input.required({ alias: 'props' });
|
|
18
19
|
this.wrapperRef = viewChild('wrapperEl');
|
|
19
20
|
this.tableContainerRef = viewChild('tableContainerEl');
|
|
20
|
-
this.
|
|
21
|
-
this.columnReorderService = new ColumnReorderService();
|
|
22
|
-
this.virtualScrollService = new VirtualScrollService();
|
|
23
|
-
this.lastMouseShift = false;
|
|
24
|
-
this.columnSizingVersion = signal(0);
|
|
25
|
-
// --- Delegated state ---
|
|
26
|
-
this.state = computed(() => this.stateService.getState());
|
|
27
|
-
this.items = computed(() => this.propsInput()?.items ?? []);
|
|
28
|
-
this.getRowId = computed(() => this.propsInput()?.getRowId ?? ((item) => item['id']));
|
|
29
|
-
this.isLoading = computed(() => this.propsInput()?.isLoading ?? false);
|
|
30
|
-
this.loadingMessage = computed(() => 'Loading\u2026');
|
|
31
|
-
this.freezeRows = computed(() => this.propsInput()?.freezeRows);
|
|
32
|
-
this.freezeCols = computed(() => this.propsInput()?.freezeCols);
|
|
33
|
-
this.layoutModeFit = computed(() => (this.propsInput()?.layoutMode ?? 'fill') === 'content');
|
|
34
|
-
this.ariaLabel = computed(() => this.propsInput()?.['aria-label'] ?? 'Data grid');
|
|
35
|
-
this.ariaLabelledBy = computed(() => this.propsInput()?.['aria-labelledby']);
|
|
36
|
-
this.emptyState = computed(() => this.propsInput()?.emptyState);
|
|
37
|
-
this.currentPage = computed(() => this.propsInput()?.currentPage ?? 1);
|
|
38
|
-
this.pageSize = computed(() => this.propsInput()?.pageSize ?? 25);
|
|
39
|
-
this.rowNumberOffset = computed(() => this.hasRowNumbersCol() ? (this.currentPage() - 1) * this.pageSize() : 0);
|
|
40
|
-
// State service outputs
|
|
41
|
-
this.visibleCols = computed(() => this.state().layout.visibleCols);
|
|
42
|
-
this.hasCheckboxCol = computed(() => this.state().layout.hasCheckboxCol);
|
|
43
|
-
this.hasRowNumbersCol = computed(() => this.state().layout.hasRowNumbersCol);
|
|
44
|
-
this.colOffset = computed(() => this.state().layout.colOffset);
|
|
45
|
-
this.containerWidth = computed(() => this.state().layout.containerWidth);
|
|
46
|
-
this.minTableWidth = computed(() => this.state().layout.minTableWidth);
|
|
47
|
-
this.desiredTableWidth = computed(() => this.state().layout.desiredTableWidth);
|
|
48
|
-
this.columnSizingOverrides = computed(() => this.state().layout.columnSizingOverrides);
|
|
49
|
-
this.selectedRowIds = computed(() => this.state().rowSelection.selectedRowIds);
|
|
50
|
-
this.allSelected = computed(() => this.state().rowSelection.allSelected);
|
|
51
|
-
this.someSelected = computed(() => this.state().rowSelection.someSelected);
|
|
52
|
-
this.editingCell = computed(() => this.state().editing.editingCell);
|
|
53
|
-
this.pendingEditorValue = computed(() => this.state().editing.pendingEditorValue);
|
|
54
|
-
this.activeCell = computed(() => this.state().interaction.activeCell);
|
|
55
|
-
this.selectionRange = computed(() => this.state().interaction.selectionRange);
|
|
56
|
-
this.hasCellSelection = computed(() => this.state().interaction.hasCellSelection);
|
|
57
|
-
this.cutRange = computed(() => this.state().interaction.cutRange);
|
|
58
|
-
this.copyRange = computed(() => this.state().interaction.copyRange);
|
|
59
|
-
this.canUndo = computed(() => this.state().interaction.canUndo);
|
|
60
|
-
this.canRedo = computed(() => this.state().interaction.canRedo);
|
|
61
|
-
this.isDragging = computed(() => this.state().interaction.isDragging);
|
|
62
|
-
this.menuPosition = computed(() => this.state().contextMenu.menuPosition);
|
|
63
|
-
this.statusBarConfig = computed(() => this.state().viewModels.statusBarConfig);
|
|
64
|
-
this.showEmptyInGrid = computed(() => this.state().viewModels.showEmptyInGrid);
|
|
65
|
-
this.headerFilterInput = computed(() => this.state().viewModels.headerFilterInput);
|
|
66
|
-
this.cellDescriptorInput = computed(() => this.state().viewModels.cellDescriptorInput);
|
|
67
|
-
this.allowOverflowX = computed(() => {
|
|
68
|
-
const p = this.propsInput();
|
|
69
|
-
if (p?.suppressHorizontalScroll)
|
|
70
|
-
return false;
|
|
71
|
-
const cw = this.containerWidth();
|
|
72
|
-
const mtw = this.minTableWidth();
|
|
73
|
-
const dtw = this.desiredTableWidth();
|
|
74
|
-
return cw > 0 && (mtw > cw || dtw > cw);
|
|
75
|
-
});
|
|
76
|
-
this.selectionCellCount = computed(() => {
|
|
77
|
-
const sr = this.selectionRange();
|
|
78
|
-
if (!sr)
|
|
79
|
-
return undefined;
|
|
80
|
-
return (Math.abs(sr.endRow - sr.startRow) + 1) * (Math.abs(sr.endCol - sr.startCol) + 1);
|
|
81
|
-
});
|
|
82
|
-
// Header rows from column definition
|
|
83
|
-
this.headerRows = computed(() => {
|
|
84
|
-
const p = this.propsInput();
|
|
85
|
-
if (!p)
|
|
86
|
-
return [];
|
|
87
|
-
return buildHeaderRows(p.columns, p.visibleColumns);
|
|
88
|
-
});
|
|
89
|
-
// Pre-computed column layouts
|
|
90
|
-
this.columnLayouts = computed(() => {
|
|
91
|
-
const cols = this.visibleCols();
|
|
92
|
-
const fc = this.freezeCols();
|
|
93
|
-
const props = this.propsInput();
|
|
94
|
-
const pinnedCols = props?.pinnedColumns ?? {};
|
|
95
|
-
return cols.map((col, colIdx) => {
|
|
96
|
-
const isFreezeCol = fc != null && fc >= 1 && colIdx < fc;
|
|
97
|
-
const runtimePinned = pinnedCols[col.columnId];
|
|
98
|
-
const pinnedLeft = runtimePinned === 'left' || (isFreezeCol && colIdx === 0);
|
|
99
|
-
const pinnedRight = runtimePinned === 'right';
|
|
100
|
-
const w = this.getColumnWidth(col);
|
|
101
|
-
return {
|
|
102
|
-
col,
|
|
103
|
-
pinnedLeft,
|
|
104
|
-
pinnedRight,
|
|
105
|
-
minWidth: col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH,
|
|
106
|
-
width: w,
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
// Wire props and wrapper element to state service
|
|
111
|
-
effect(() => {
|
|
112
|
-
const p = this.propsInput();
|
|
113
|
-
if (p)
|
|
114
|
-
this.stateService.props.set(p);
|
|
115
|
-
});
|
|
116
|
-
effect(() => {
|
|
117
|
-
const el = this.wrapperRef()?.nativeElement;
|
|
118
|
-
if (el) {
|
|
119
|
-
this.stateService.wrapperEl.set(el);
|
|
120
|
-
this.columnReorderService.wrapperEl.set(el);
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
// Wire column reorder service inputs
|
|
124
|
-
effect(() => {
|
|
125
|
-
const p = this.propsInput();
|
|
126
|
-
if (p) {
|
|
127
|
-
const cols = this.visibleCols();
|
|
128
|
-
this.columnReorderService.columns.set(cols);
|
|
129
|
-
this.columnReorderService.columnOrder.set(p.columnOrder);
|
|
130
|
-
this.columnReorderService.onColumnOrderChange.set(p.onColumnOrderChange);
|
|
131
|
-
this.columnReorderService.enabled.set(!!p.onColumnOrderChange);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
// Wire virtual scroll service inputs
|
|
135
|
-
effect(() => {
|
|
136
|
-
const p = this.propsInput();
|
|
137
|
-
if (p) {
|
|
138
|
-
this.virtualScrollService.totalRows.set(p.items.length);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
21
|
+
this.initBase();
|
|
141
22
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return colDef;
|
|
23
|
+
getProps() {
|
|
24
|
+
return this.propsInput();
|
|
145
25
|
}
|
|
146
|
-
|
|
147
|
-
return this.
|
|
26
|
+
getWrapperRef() {
|
|
27
|
+
return this.wrapperRef();
|
|
148
28
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const override = overrides[col.columnId];
|
|
152
|
-
if (override)
|
|
153
|
-
return override.widthPx;
|
|
154
|
-
return col.defaultWidth ?? col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
|
|
155
|
-
}
|
|
156
|
-
getFilterConfig(col) {
|
|
157
|
-
return getHeaderFilterConfig(col, this.headerFilterInput());
|
|
158
|
-
}
|
|
159
|
-
getCellDescriptor(item, col, rowIndex, colIdx) {
|
|
160
|
-
return getCellRenderDescriptor(item, col, rowIndex, colIdx, this.cellDescriptorInput());
|
|
161
|
-
}
|
|
162
|
-
resolveCellContent(col, item, displayValue) {
|
|
163
|
-
return resolveCellDisplayContent(col, item, displayValue);
|
|
164
|
-
}
|
|
165
|
-
resolveCellStyleFn(col, item) {
|
|
166
|
-
return resolveCellStyle(col, item);
|
|
167
|
-
}
|
|
168
|
-
getSelectValues(col) {
|
|
169
|
-
const params = col.cellEditorParams;
|
|
170
|
-
if (params && typeof params === 'object' && 'values' in params) {
|
|
171
|
-
return params.values.map(String);
|
|
172
|
-
}
|
|
173
|
-
return [];
|
|
174
|
-
}
|
|
175
|
-
formatDateForInput(value) {
|
|
176
|
-
if (!value)
|
|
177
|
-
return '';
|
|
178
|
-
const d = new Date(String(value));
|
|
179
|
-
if (Number.isNaN(d.getTime()))
|
|
180
|
-
return '';
|
|
181
|
-
return d.toISOString().split('T')[0];
|
|
182
|
-
}
|
|
183
|
-
// --- Event handlers ---
|
|
184
|
-
onWrapperMouseDown(event) {
|
|
185
|
-
this.lastMouseShift = event.shiftKey;
|
|
186
|
-
}
|
|
187
|
-
onGridKeyDown(event) {
|
|
188
|
-
this.state().interaction.handleGridKeyDown(event);
|
|
189
|
-
}
|
|
190
|
-
onCellMouseDown(event, rowIndex, globalColIndex) {
|
|
191
|
-
this.state().interaction.handleCellMouseDown(event, rowIndex, globalColIndex);
|
|
192
|
-
}
|
|
193
|
-
onCellClick(rowIndex, globalColIndex) {
|
|
194
|
-
this.state().interaction.setActiveCell({ rowIndex, columnIndex: globalColIndex });
|
|
195
|
-
}
|
|
196
|
-
onCellContextMenu(event) {
|
|
197
|
-
this.state().contextMenu.handleCellContextMenu(event);
|
|
198
|
-
}
|
|
199
|
-
onCellDblClick(rowId, columnId) {
|
|
200
|
-
this.state().editing.setEditingCell({ rowId, columnId });
|
|
201
|
-
}
|
|
202
|
-
onFillHandleMouseDown(event) {
|
|
203
|
-
this.state().interaction.handleFillHandleMouseDown(event);
|
|
204
|
-
}
|
|
205
|
-
onResizeStart(event, col) {
|
|
206
|
-
event.preventDefault();
|
|
207
|
-
const startX = event.clientX;
|
|
208
|
-
const startWidth = this.getColumnWidth(col);
|
|
209
|
-
const minWidth = col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
|
|
210
|
-
const onMove = (e) => {
|
|
211
|
-
const delta = e.clientX - startX;
|
|
212
|
-
const newWidth = Math.max(minWidth, startWidth + delta);
|
|
213
|
-
const overrides = { ...this.columnSizingOverrides(), [col.columnId]: { widthPx: newWidth } };
|
|
214
|
-
this.state().layout.setColumnSizingOverrides(overrides);
|
|
215
|
-
this.columnSizingVersion.update(v => v + 1);
|
|
216
|
-
};
|
|
217
|
-
const onUp = () => {
|
|
218
|
-
window.removeEventListener('mousemove', onMove);
|
|
219
|
-
window.removeEventListener('mouseup', onUp);
|
|
220
|
-
const finalWidth = this.getColumnWidth(col);
|
|
221
|
-
this.state().layout.onColumnResized?.(col.columnId, finalWidth);
|
|
222
|
-
};
|
|
223
|
-
window.addEventListener('mousemove', onMove);
|
|
224
|
-
window.addEventListener('mouseup', onUp);
|
|
225
|
-
}
|
|
226
|
-
onSelectAllChange(event) {
|
|
227
|
-
const checked = event.target.checked;
|
|
228
|
-
this.state().rowSelection.handleSelectAll(!!checked);
|
|
229
|
-
}
|
|
230
|
-
onRowClick(event, rowId) {
|
|
231
|
-
const p = this.propsInput();
|
|
232
|
-
if (p?.rowSelection !== 'single')
|
|
233
|
-
return;
|
|
234
|
-
const ids = this.selectedRowIds();
|
|
235
|
-
this.state().rowSelection.updateSelection(ids.has(rowId) ? new Set() : new Set([rowId]));
|
|
236
|
-
}
|
|
237
|
-
onRowCheckboxChange(rowId, event, rowIndex) {
|
|
238
|
-
const checked = event.target.checked;
|
|
239
|
-
this.state().rowSelection.handleRowCheckboxChange(rowId, checked, rowIndex, this.lastMouseShift);
|
|
240
|
-
}
|
|
241
|
-
commitEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex) {
|
|
242
|
-
this.state().editing.commitCellEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex);
|
|
243
|
-
}
|
|
244
|
-
cancelEdit() {
|
|
245
|
-
this.state().editing.setEditingCell(null);
|
|
246
|
-
}
|
|
247
|
-
onEditorKeydown(event, item, columnId, oldValue, rowIndex, globalColIndex) {
|
|
248
|
-
if (event.key === 'Enter') {
|
|
249
|
-
event.preventDefault();
|
|
250
|
-
const newValue = event.target.value;
|
|
251
|
-
this.commitEdit(item, columnId, oldValue, newValue, rowIndex, globalColIndex);
|
|
252
|
-
}
|
|
253
|
-
else if (event.key === 'Escape') {
|
|
254
|
-
event.preventDefault();
|
|
255
|
-
this.cancelEdit();
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
closeContextMenu() {
|
|
259
|
-
this.state().contextMenu.closeContextMenu();
|
|
260
|
-
}
|
|
261
|
-
handleCopy() {
|
|
262
|
-
this.state().interaction.handleCopy();
|
|
263
|
-
}
|
|
264
|
-
handleCut() {
|
|
265
|
-
this.state().interaction.handleCut();
|
|
266
|
-
}
|
|
267
|
-
handlePaste() {
|
|
268
|
-
void this.state().interaction.handlePaste();
|
|
269
|
-
}
|
|
270
|
-
handleSelectAllCells() {
|
|
271
|
-
this.state().interaction.handleSelectAllCells();
|
|
272
|
-
}
|
|
273
|
-
onUndo() {
|
|
274
|
-
this.state().interaction.onUndo?.();
|
|
275
|
-
}
|
|
276
|
-
onRedo() {
|
|
277
|
-
this.state().interaction.onRedo?.();
|
|
278
|
-
}
|
|
279
|
-
onHeaderMouseDown(columnId, event) {
|
|
280
|
-
this.columnReorderService.handleHeaderMouseDown(columnId, event);
|
|
281
|
-
}
|
|
282
|
-
// --- Column pinning methods ---
|
|
283
|
-
onPinColumn(columnId, side) {
|
|
284
|
-
const props = this.propsInput();
|
|
285
|
-
props?.onColumnPinned?.(columnId, side);
|
|
286
|
-
}
|
|
287
|
-
onUnpinColumn(columnId) {
|
|
288
|
-
const props = this.propsInput();
|
|
289
|
-
props?.onColumnPinned?.(columnId, null);
|
|
290
|
-
}
|
|
291
|
-
isPinned(columnId) {
|
|
292
|
-
const props = this.propsInput();
|
|
293
|
-
return props?.pinnedColumns?.[columnId];
|
|
294
|
-
}
|
|
295
|
-
getPinState(columnId) {
|
|
296
|
-
const pinned = this.isPinned(columnId);
|
|
297
|
-
return {
|
|
298
|
-
canPinLeft: pinned !== 'left',
|
|
299
|
-
canPinRight: pinned !== 'right',
|
|
300
|
-
canUnpin: !!pinned,
|
|
301
|
-
};
|
|
29
|
+
getTableContainerRef() {
|
|
30
|
+
return this.tableContainerRef();
|
|
302
31
|
}
|
|
303
32
|
};
|
|
304
33
|
DataGridTableComponent = __decorate([
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { EventEmitter } from '@angular/core';
|
|
2
1
|
import { MatMenuTrigger } from '@angular/material/menu';
|
|
3
2
|
/**
|
|
4
3
|
* Column header dropdown menu for pin/unpin actions.
|
|
5
4
|
* Uses Angular Material MatMenu.
|
|
6
5
|
*/
|
|
7
6
|
export declare class ColumnHeaderMenuComponent {
|
|
8
|
-
columnId: string
|
|
9
|
-
canPinLeft: boolean
|
|
10
|
-
canPinRight: boolean
|
|
11
|
-
canUnpin: boolean
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
menuTrigger
|
|
7
|
+
readonly columnId: import("@angular/core").InputSignal<string>;
|
|
8
|
+
readonly canPinLeft: import("@angular/core").InputSignal<boolean>;
|
|
9
|
+
readonly canPinRight: import("@angular/core").InputSignal<boolean>;
|
|
10
|
+
readonly canUnpin: import("@angular/core").InputSignal<boolean>;
|
|
11
|
+
readonly onPinLeft: import("@angular/core").InputSignal<(() => void) | undefined>;
|
|
12
|
+
readonly onPinRight: import("@angular/core").InputSignal<(() => void) | undefined>;
|
|
13
|
+
readonly onUnpin: import("@angular/core").InputSignal<(() => void) | undefined>;
|
|
14
|
+
readonly menuTrigger: import("@angular/core").Signal<MatMenuTrigger | undefined>;
|
|
16
15
|
readonly menuItems: import("@alaarab/ogrid-core").IColumnHeaderMenuItem[];
|
|
17
16
|
handlePinLeft(): void;
|
|
18
17
|
handlePinRight(): void;
|
|
@@ -1,143 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { ElementRef } from '@angular/core';
|
|
2
|
+
import { BaseDataGridTableComponent } from '@alaarab/ogrid-angular';
|
|
3
|
+
import type { IOGridDataGridProps } from '@alaarab/ogrid-angular';
|
|
3
4
|
/**
|
|
4
5
|
* DataGridTable component using native HTML table with Material Design-inspired styling.
|
|
5
6
|
* Standalone component — this is the workhorse of the grid.
|
|
6
7
|
*/
|
|
7
|
-
export declare class DataGridTableComponent<T> {
|
|
8
|
+
export declare class DataGridTableComponent<T> extends BaseDataGridTableComponent<T> {
|
|
8
9
|
readonly propsInput: import("@angular/core").InputSignal<IOGridDataGridProps<T>>;
|
|
9
10
|
private readonly wrapperRef;
|
|
10
11
|
private readonly tableContainerRef;
|
|
11
|
-
private readonly stateService;
|
|
12
|
-
readonly columnReorderService: ColumnReorderService<T>;
|
|
13
|
-
readonly virtualScrollService: VirtualScrollService;
|
|
14
|
-
private lastMouseShift;
|
|
15
|
-
private columnSizingVersion;
|
|
16
12
|
constructor();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
readonly isLoading: import("@angular/core").Signal<boolean>;
|
|
21
|
-
readonly loadingMessage: import("@angular/core").Signal<string>;
|
|
22
|
-
readonly freezeRows: import("@angular/core").Signal<number | undefined>;
|
|
23
|
-
readonly freezeCols: import("@angular/core").Signal<number | undefined>;
|
|
24
|
-
readonly layoutModeFit: import("@angular/core").Signal<boolean>;
|
|
25
|
-
readonly ariaLabel: import("@angular/core").Signal<string>;
|
|
26
|
-
readonly ariaLabelledBy: import("@angular/core").Signal<string | undefined>;
|
|
27
|
-
readonly emptyState: import("@angular/core").Signal<{
|
|
28
|
-
onClearAll: () => void;
|
|
29
|
-
hasActiveFilters: boolean;
|
|
30
|
-
message?: string;
|
|
31
|
-
render?: import("@angular/core").TemplateRef<unknown>;
|
|
32
|
-
} | undefined>;
|
|
33
|
-
readonly currentPage: import("@angular/core").Signal<number>;
|
|
34
|
-
readonly pageSize: import("@angular/core").Signal<number>;
|
|
35
|
-
readonly rowNumberOffset: import("@angular/core").Signal<number>;
|
|
36
|
-
readonly visibleCols: import("@angular/core").Signal<IColumnDef<T>[]>;
|
|
37
|
-
readonly hasCheckboxCol: import("@angular/core").Signal<boolean>;
|
|
38
|
-
readonly hasRowNumbersCol: import("@angular/core").Signal<boolean>;
|
|
39
|
-
readonly colOffset: import("@angular/core").Signal<number>;
|
|
40
|
-
readonly containerWidth: import("@angular/core").Signal<number>;
|
|
41
|
-
readonly minTableWidth: import("@angular/core").Signal<number>;
|
|
42
|
-
readonly desiredTableWidth: import("@angular/core").Signal<number>;
|
|
43
|
-
readonly columnSizingOverrides: import("@angular/core").Signal<Record<string, {
|
|
44
|
-
widthPx: number;
|
|
45
|
-
}>>;
|
|
46
|
-
readonly selectedRowIds: import("@angular/core").Signal<Set<RowId>>;
|
|
47
|
-
readonly allSelected: import("@angular/core").Signal<boolean>;
|
|
48
|
-
readonly someSelected: import("@angular/core").Signal<boolean>;
|
|
49
|
-
readonly editingCell: import("@angular/core").Signal<{
|
|
50
|
-
rowId: RowId;
|
|
51
|
-
columnId: string;
|
|
52
|
-
} | null>;
|
|
53
|
-
readonly pendingEditorValue: import("@angular/core").Signal<unknown>;
|
|
54
|
-
readonly activeCell: import("@angular/core").Signal<import("@alaarab/ogrid-core").IActiveCell | null>;
|
|
55
|
-
readonly selectionRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
56
|
-
readonly hasCellSelection: import("@angular/core").Signal<boolean>;
|
|
57
|
-
readonly cutRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
58
|
-
readonly copyRange: import("@angular/core").Signal<import("@alaarab/ogrid-core").ISelectionRange | null>;
|
|
59
|
-
readonly canUndo: import("@angular/core").Signal<boolean>;
|
|
60
|
-
readonly canRedo: import("@angular/core").Signal<boolean>;
|
|
61
|
-
readonly isDragging: import("@angular/core").Signal<boolean>;
|
|
62
|
-
readonly menuPosition: import("@angular/core").Signal<{
|
|
63
|
-
x: number;
|
|
64
|
-
y: number;
|
|
65
|
-
} | null>;
|
|
66
|
-
readonly statusBarConfig: import("@angular/core").Signal<import("@alaarab/ogrid-core").IStatusBarProps | null>;
|
|
67
|
-
readonly showEmptyInGrid: import("@angular/core").Signal<boolean>;
|
|
68
|
-
readonly headerFilterInput: import("@angular/core").Signal<{
|
|
69
|
-
sortBy?: string;
|
|
70
|
-
sortDirection: "asc" | "desc";
|
|
71
|
-
onColumnSort: (columnKey: string) => void;
|
|
72
|
-
filters: import("@alaarab/ogrid-core").IFilters;
|
|
73
|
-
onFilterChange: (key: string, value: import("@alaarab/ogrid-core").FilterValue | undefined) => void;
|
|
74
|
-
filterOptions: Record<string, string[]>;
|
|
75
|
-
loadingFilterOptions: Record<string, boolean>;
|
|
76
|
-
peopleSearch?: (query: string) => Promise<import("@alaarab/ogrid-core").UserLike[]>;
|
|
77
|
-
}>;
|
|
78
|
-
readonly cellDescriptorInput: import("@angular/core").Signal<{
|
|
79
|
-
editingCell: {
|
|
80
|
-
rowId: RowId;
|
|
81
|
-
columnId: string;
|
|
82
|
-
} | null;
|
|
83
|
-
activeCell: import("@alaarab/ogrid-core").IActiveCell | null;
|
|
84
|
-
selectionRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
85
|
-
cutRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
86
|
-
copyRange: import("@alaarab/ogrid-core").ISelectionRange | null;
|
|
87
|
-
colOffset: number;
|
|
88
|
-
itemsLength: number;
|
|
89
|
-
getRowId: (item: T) => RowId;
|
|
90
|
-
editable?: boolean;
|
|
91
|
-
onCellValueChanged?: ((event: import("@alaarab/ogrid-core").ICellValueChangedEvent<T>) => void) | undefined;
|
|
92
|
-
isDragging: boolean;
|
|
93
|
-
}>;
|
|
94
|
-
readonly allowOverflowX: import("@angular/core").Signal<boolean>;
|
|
95
|
-
readonly selectionCellCount: import("@angular/core").Signal<number | undefined>;
|
|
96
|
-
readonly headerRows: import("@angular/core").Signal<import("@alaarab/ogrid-core").HeaderRow<T>[]>;
|
|
97
|
-
readonly columnLayouts: import("@angular/core").Signal<{
|
|
98
|
-
col: IColumnDef<T>;
|
|
99
|
-
pinnedLeft: boolean;
|
|
100
|
-
pinnedRight: boolean;
|
|
101
|
-
minWidth: number;
|
|
102
|
-
width: number;
|
|
103
|
-
}[]>;
|
|
104
|
-
asColumnDef(colDef: unknown): IColumnDef<T>;
|
|
105
|
-
visibleColIndex(col: IColumnDef<T>): number;
|
|
106
|
-
getColumnWidth(col: IColumnDef<T>): number;
|
|
107
|
-
getFilterConfig(col: IColumnDef<T>): HeaderFilterConfig;
|
|
108
|
-
getCellDescriptor(item: T, col: IColumnDef<T>, rowIndex: number, colIdx: number): CellRenderDescriptor;
|
|
109
|
-
resolveCellContent(col: IColumnDef<T>, item: T, displayValue: unknown): string;
|
|
110
|
-
resolveCellStyleFn(col: IColumnDef<T>, item: T): Record<string, string> | undefined;
|
|
111
|
-
getSelectValues(col: IColumnDef<T>): string[];
|
|
112
|
-
formatDateForInput(value: unknown): string;
|
|
113
|
-
onWrapperMouseDown(event: MouseEvent): void;
|
|
114
|
-
onGridKeyDown(event: KeyboardEvent): void;
|
|
115
|
-
onCellMouseDown(event: MouseEvent, rowIndex: number, globalColIndex: number): void;
|
|
116
|
-
onCellClick(rowIndex: number, globalColIndex: number): void;
|
|
117
|
-
onCellContextMenu(event: MouseEvent): void;
|
|
118
|
-
onCellDblClick(rowId: RowId, columnId: string): void;
|
|
119
|
-
onFillHandleMouseDown(event: MouseEvent): void;
|
|
120
|
-
onResizeStart(event: MouseEvent, col: IColumnDef<T>): void;
|
|
121
|
-
onSelectAllChange(event: Event): void;
|
|
122
|
-
onRowClick(event: MouseEvent, rowId: RowId): void;
|
|
123
|
-
onRowCheckboxChange(rowId: RowId, event: Event, rowIndex: number): void;
|
|
124
|
-
commitEdit(item: T, columnId: string, oldValue: unknown, newValue: unknown, rowIndex: number, globalColIndex: number): void;
|
|
125
|
-
cancelEdit(): void;
|
|
126
|
-
onEditorKeydown(event: KeyboardEvent, item: T, columnId: string, oldValue: unknown, rowIndex: number, globalColIndex: number): void;
|
|
127
|
-
closeContextMenu(): void;
|
|
128
|
-
handleCopy(): void;
|
|
129
|
-
handleCut(): void;
|
|
130
|
-
handlePaste(): void;
|
|
131
|
-
handleSelectAllCells(): void;
|
|
132
|
-
onUndo(): void;
|
|
133
|
-
onRedo(): void;
|
|
134
|
-
onHeaderMouseDown(columnId: string, event: MouseEvent): void;
|
|
135
|
-
onPinColumn(columnId: string, side: 'left' | 'right'): void;
|
|
136
|
-
onUnpinColumn(columnId: string): void;
|
|
137
|
-
isPinned(columnId: string): 'left' | 'right' | undefined;
|
|
138
|
-
getPinState(columnId: string): {
|
|
139
|
-
canPinLeft: boolean;
|
|
140
|
-
canPinRight: boolean;
|
|
141
|
-
canUnpin: boolean;
|
|
142
|
-
};
|
|
13
|
+
protected getProps(): IOGridDataGridProps<T> | undefined;
|
|
14
|
+
protected getWrapperRef(): ElementRef<HTMLElement> | undefined;
|
|
15
|
+
protected getTableContainerRef(): ElementRef<HTMLElement> | undefined;
|
|
143
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-angular-material",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"description": "OGrid Angular Material – MatTable-based data grid with sorting, filtering, pagination, column chooser, and CSV export.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"files": ["dist", "README.md", "LICENSE"],
|
|
23
23
|
"engines": { "node": ">=18" },
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@alaarab/ogrid-angular": "2.0.
|
|
25
|
+
"@alaarab/ogrid-angular": "2.0.7"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@angular/core": "^21.0.0",
|
|
@@ -39,9 +39,10 @@
|
|
|
39
39
|
"@angular/material": "^21.1.4",
|
|
40
40
|
"@angular/cdk": "^21.1.4",
|
|
41
41
|
"@angular/animations": "^21.1.4",
|
|
42
|
-
"rxjs": "^7.8.
|
|
42
|
+
"rxjs": "^7.8.2",
|
|
43
43
|
"zone.js": "^0.15.0",
|
|
44
|
-
"typescript": "^5.
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
45
|
},
|
|
46
|
+
"sideEffects": false,
|
|
46
47
|
"publishConfig": { "access": "public" }
|
|
47
48
|
}
|