@sneat/datagrid 0.1.2 → 0.1.4

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.
@@ -0,0 +1,326 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Input, Component, inject, EventEmitter, Output, ViewChild } from '@angular/core';
3
+ import * as i2 from '@angular/forms';
4
+ import { FormsModule } from '@angular/forms';
5
+ import * as i1 from '@angular/router';
6
+ import { RouterModule } from '@angular/router';
7
+ import { IonCardHeader, IonCardTitle, IonCardSubtitle, IonSegment, IonSegmentButton, IonLabel, IonList, IonItem, IonInput, IonBadge, IonText } from '@ionic/angular/standalone';
8
+ import { ErrorLogger } from '@sneat/core';
9
+ import { Module, Tabulator, InteractionModule, SelectRowModule, MenuModule } from 'tabulator-tables';
10
+
11
+ class CellPopoverComponent {
12
+ constructor() {
13
+ this.tab = 'rec';
14
+ }
15
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CellPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CellPopoverComponent, isStandalone: true, selector: "sneat-datatug-cell-popover", inputs: { column: "column", value: "value", fk: "fk" }, ngImport: i0, template: "<ion-card-header>\n <ion-card-title>Field: {{ column?.name }}</ion-card-title>\n <ion-card-subtitle>Value: {{ value }}</ion-card-subtitle>\n</ion-card-header>\n<h3 class=\"ion-margin\">\n References:\n @if (fk?.refTable) {\n <a routerLink=\"{{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\">\n {{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\n </a>\n }\n</h3>\n<ion-segment [(ngModel)]=\"tab\">\n <ion-segment-button value=\"rec\">\n <ion-label>Record</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"cols\">\n <ion-label>Columns</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"refs\">\n <ion-label>References</ion-label>\n </ion-segment-button>\n</ion-segment>\n\n@switch (tab) {\n @case (\"rec\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-input\n type=\"number\"\n style=\"text-align: right\"\n value=\"1\"\n readonly=\"true\"\n />\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-input\n type=\"text\"\n style=\"text-align: right\"\n value=\"Something\"\n readonly=\"true\"\n />\n </ion-item>\n </ion-list>\n }\n @case (\"cols\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">INT</ion-text>\n </ion-badge>\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">NVARCHAR</ion-text>\n </ion-badge>\n </ion-item>\n </ion-list>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: IonSegment, selector: "ion-segment", inputs: ["color", "disabled", "mode", "scrollable", "selectOnFocus", "swipeGesture", "value"] }, { kind: "component", type: IonSegmentButton, selector: "ion-segment-button", inputs: ["contentId", "disabled", "layout", "mode", "type", "value"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { kind: "component", type: IonText, selector: "ion-text", inputs: ["color", "mode"] }] }); }
17
+ }
18
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CellPopoverComponent, decorators: [{
19
+ type: Component,
20
+ args: [{ selector: 'sneat-datatug-cell-popover', imports: [
21
+ RouterModule,
22
+ FormsModule,
23
+ IonCardHeader,
24
+ IonCardTitle,
25
+ IonCardSubtitle,
26
+ IonSegment,
27
+ IonSegmentButton,
28
+ IonLabel,
29
+ IonList,
30
+ IonItem,
31
+ IonInput,
32
+ IonBadge,
33
+ IonText,
34
+ ], template: "<ion-card-header>\n <ion-card-title>Field: {{ column?.name }}</ion-card-title>\n <ion-card-subtitle>Value: {{ value }}</ion-card-subtitle>\n</ion-card-header>\n<h3 class=\"ion-margin\">\n References:\n @if (fk?.refTable) {\n <a routerLink=\"{{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\">\n {{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\n </a>\n }\n</h3>\n<ion-segment [(ngModel)]=\"tab\">\n <ion-segment-button value=\"rec\">\n <ion-label>Record</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"cols\">\n <ion-label>Columns</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"refs\">\n <ion-label>References</ion-label>\n </ion-segment-button>\n</ion-segment>\n\n@switch (tab) {\n @case (\"rec\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-input\n type=\"number\"\n style=\"text-align: right\"\n value=\"1\"\n readonly=\"true\"\n />\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-input\n type=\"text\"\n style=\"text-align: right\"\n value=\"Something\"\n readonly=\"true\"\n />\n </ion-item>\n </ion-list>\n }\n @case (\"cols\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">INT</ion-text>\n </ion-badge>\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">NVARCHAR</ion-text>\n </ion-badge>\n </ion-item>\n </ion-list>\n }\n}\n" }]
35
+ }], propDecorators: { column: [{
36
+ type: Input
37
+ }], value: [{
38
+ type: Input
39
+ }], fk: [{
40
+ type: Input
41
+ }] } });
42
+
43
+ class AdvertModule extends Module {
44
+ static { this.moduleName = 'advert'; }
45
+ initialize() {
46
+ return;
47
+ }
48
+ }
49
+ Tabulator.registerModule([
50
+ InteractionModule,
51
+ SelectRowModule,
52
+ AdvertModule,
53
+ MenuModule,
54
+ ]);
55
+ // export interface IGridDef {
56
+ // columns: IGridColumn[],
57
+ // rows?: unknown[],
58
+ // groupBy?: string;
59
+ // }
60
+ //
61
+ // export const getTabulatorCols = (cols: IGridColumn[]): any[] => cols.map(c => {
62
+ // const v = {...c};
63
+ // delete v.dbType;
64
+ // return v;
65
+ // });
66
+ //
67
+ // export interface IGridColumn {
68
+ // field: string;
69
+ // colName?: string;
70
+ // dbType: string;
71
+ // title: string;
72
+ // tooltip?: (cell: any) => string;
73
+ // formatter?: any;
74
+ // hozAlign?: 'left' | 'right';
75
+ // widthShrink?: number;
76
+ // widthGrow?: number;
77
+ // width?: number | string;
78
+ // }
79
+ /**
80
+ * This is a wrapper class for the tabulator JS library.
81
+ * For more info see http://tabulator.info
82
+ */
83
+ class DataGridComponent {
84
+ constructor() {
85
+ this.errorLogger = inject(ErrorLogger);
86
+ this.layout = 'fitColumns';
87
+ this.data = [];
88
+ this.columns = [];
89
+ this.rowSelected = new EventEmitter();
90
+ this.rowDeselected = new EventEmitter();
91
+ }
92
+ ngOnChanges(changes) {
93
+ try {
94
+ if ((changes['data'] && this.data && this.columns) ||
95
+ (changes['columns'] && this.columns) ||
96
+ (changes['rowClick'] && this.rowClick)) {
97
+ this.drawTable();
98
+ }
99
+ }
100
+ catch (ex) {
101
+ this.errorLogger.logError(ex, 'Failed to process ngOnChanges in DataGridComponent');
102
+ }
103
+ }
104
+ // ngOnDestroy(): void {
105
+ // console.log('DataGridComponent.ngOnDestroy()', this.tabulator);
106
+ // try { // TODO: destroy Tabulator
107
+ // if (this.tabulator?.element) {
108
+ // // noinspection TypeScriptValidateJSTypes
109
+ // this.tabulator.element.tabulator('destroy');
110
+ // }
111
+ // } catch (ex) {
112
+ // this.errorLogger.logError(ex, 'Failed to destroy tabulator');
113
+ // }
114
+ // }
115
+ ngAfterViewInit() {
116
+ if (this.tabulator) {
117
+ try {
118
+ this.tabulator.redraw();
119
+ }
120
+ catch (e) {
121
+ this.errorLogger.logError(e, 'Failed to redraw tabulator', {
122
+ show: false,
123
+ report: false,
124
+ });
125
+ }
126
+ }
127
+ }
128
+ drawTable() {
129
+ if (!this.data || !this.columns) {
130
+ console.warn('drawTable()', 'columns:', this.columns, 'data:', this.data);
131
+ return;
132
+ }
133
+ try {
134
+ if (!this.tabulatorDiv) {
135
+ this.errorLogger.logError(new Error('!this.tabulatorDiv'));
136
+ return;
137
+ }
138
+ if (this.tabulatorOptions) {
139
+ this.tabulatorOptions = { ...this.tabulatorOptions, data: this.data };
140
+ this.tabulator
141
+ ?.setData(this.data)
142
+ .catch(this.errorLogger.logErrorHandler('Failed to set data'));
143
+ }
144
+ else {
145
+ this.createTabulatorGrid();
146
+ }
147
+ // this.tabulatorDiv.nativeElement.appendChild(this.tab);
148
+ // tabulator.redraw();
149
+ }
150
+ catch (e) {
151
+ this.errorLogger.logError(e, 'Failed to drawTable');
152
+ }
153
+ }
154
+ createTabulatorGrid() {
155
+ this.setTabulatorOptions();
156
+ if (!this.tabulator) {
157
+ this.tabulatorOptions = {
158
+ ...this.tabulatorOptions,
159
+ // rowClick: function (e, row) {
160
+ // console.log('rowClick1', row);
161
+ // },
162
+ // rowSelect: function (row) {
163
+ // console.log('rowSelect', row);
164
+ // },
165
+ // rowDeselect: function (row) {
166
+ // console.log('rowDeselect', row);
167
+ // }
168
+ };
169
+ this.tabulator = new Tabulator(this.tabulatorDiv?.nativeElement, this.tabulatorOptions);
170
+ this.tabulator.on('rowClick', (event, row) => {
171
+ this.clickEvent = event;
172
+ if (this.rowClick) {
173
+ this.rowClick(event, row);
174
+ }
175
+ });
176
+ this.tabulator.on('rowSelected', (row) => this.rowSelected.emit({ row, event: this.clickEvent }));
177
+ this.tabulator.on('rowDeselected', (row) => this.rowDeselected.emit({ row, event: this.clickEvent }));
178
+ }
179
+ }
180
+ setTabulatorOptions() {
181
+ this.tabulatorOptions = {
182
+ // tooltipsHeader: true, // enable header tooltips
183
+ // tooltipGenerationMode: 'hover',
184
+ rowContextMenu: this.rowContextMenu,
185
+ selectableRows: this.selectable,
186
+ data: this.data,
187
+ // reactiveData: true, // enable data reactivity
188
+ columns: this.columns?.map((c) => {
189
+ const col = {
190
+ // TODO(help-wanted): Use strongly typed Tabulator col def
191
+ field: c.field,
192
+ title: c.title || c.field || c.title,
193
+ // headerTooltip: () =>
194
+ // `${c.colName || c.title || c.field}: ${c.dbType}`,
195
+ };
196
+ if (c.colName !== 'Id' && c.colName?.endsWith('Id')) {
197
+ col.formatter = 'link';
198
+ col.formatterParams = {
199
+ url: 'test-url',
200
+ };
201
+ col.cellClick = (e, cell) => {
202
+ void cell;
203
+ e.preventDefault();
204
+ e.stopPropagation();
205
+ };
206
+ }
207
+ if (c.tooltip) {
208
+ col.tooltip = c.tooltip;
209
+ }
210
+ if (c.formatter) {
211
+ col.formatter = c.formatter;
212
+ }
213
+ if (c.hozAlign) {
214
+ col.hozAlign = c.hozAlign;
215
+ }
216
+ if (c.headerHozAlign) {
217
+ col.headerHozAlign = c.headerHozAlign;
218
+ }
219
+ if (c.widthGrow) {
220
+ col.widthGrow = c.widthGrow;
221
+ }
222
+ if (c.widthShrink) {
223
+ col.widthShrink = c.widthShrink;
224
+ }
225
+ if (c.width !== undefined) {
226
+ col.width = c.width;
227
+ }
228
+ // console.log('col:', col);
229
+ return col;
230
+ }),
231
+ layout: this.layout || 'fitColumns',
232
+ };
233
+ if (this.height) {
234
+ this.tabulatorOptions = {
235
+ ...this.tabulatorOptions,
236
+ height: this.height,
237
+ };
238
+ }
239
+ if (this.maxHeight) {
240
+ this.tabulatorOptions = {
241
+ ...this.tabulatorOptions,
242
+ maxHeight: this.maxHeight,
243
+ };
244
+ }
245
+ if (this.groupBy) {
246
+ this.tabulatorOptions = {
247
+ ...this.tabulatorOptions,
248
+ groupBy: this.groupBy,
249
+ groupHeader: (value, count) => {
250
+ // value - the value all members of this group share
251
+ // count - the number of rows in this group
252
+ // data - an array of all the row data objects in this group
253
+ // group - the group component for the group
254
+ // console.log('groupHeader', value);
255
+ return `${this.groupBy}: ${value} <span class="ion-margin-start">(${count} ${count === 1 ? 'record' : 'records'})</span>`;
256
+ },
257
+ };
258
+ }
259
+ }
260
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DataGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
261
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: DataGridComponent, isStandalone: true, selector: "sneat-datagrid", inputs: { layout: "layout", data: "data", columns: "columns", groupBy: "groupBy", height: "height", maxHeight: "maxHeight", rowContextMenu: "rowContextMenu", rowClick: "rowClick", selectable: "selectable" }, outputs: { rowSelected: "rowSelected", rowDeselected: "rowDeselected" }, viewQueries: [{ propertyName: "tabulatorDiv", first: true, predicate: ["tabulatorDiv"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
262
+ <div id="tabulator" #tabulatorDiv></div>
263
+ <p class="ion-margin-start">Rows: {{ data?.length }}</p>
264
+ `, isInline: true }); }
265
+ }
266
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DataGridComponent, decorators: [{
267
+ type: Component,
268
+ args: [{
269
+ selector: 'sneat-datagrid',
270
+ template: `
271
+ <div id="tabulator" #tabulatorDiv></div>
272
+ <p class="ion-margin-start">Rows: {{ data?.length }}</p>
273
+ `,
274
+ imports: [],
275
+ }]
276
+ }], propDecorators: { layout: [{
277
+ type: Input
278
+ }], data: [{
279
+ type: Input
280
+ }], columns: [{
281
+ type: Input
282
+ }], groupBy: [{
283
+ type: Input
284
+ }], height: [{
285
+ type: Input
286
+ }], maxHeight: [{
287
+ type: Input
288
+ }], rowContextMenu: [{
289
+ type: Input
290
+ }], tabulatorDiv: [{
291
+ type: ViewChild,
292
+ args: ['tabulatorDiv', { static: true }]
293
+ }], rowClick: [{
294
+ type: Input
295
+ }], rowSelected: [{
296
+ type: Output
297
+ }], rowDeselected: [{
298
+ type: Output
299
+ }], selectable: [{
300
+ type: Input
301
+ }] } });
302
+
303
+ // export interface TabulatorOptions {
304
+ // readonly tooltipsHeader?: boolean;
305
+ // readonly tooltipGenerationMode?: 'hover' | 'mouseover';
306
+ // readonly reactiveData?: boolean;
307
+ // readonly selectable?: boolean | number | 'highlight';
308
+ // readonly data?: unknown[];
309
+ // readonly layout?: 'fitData' | 'fitColumns';
310
+ // readonly columns?: TabulatorColumn[];
311
+ // readonly height?: string | number;
312
+ // readonly maxHeight?: string | number;
313
+ // readonly groupBy?: string;
314
+ // readonly groupHeader?: (value: unknown, count: number) => string;
315
+ // readonly rowClick?: (event: Event, row: unknown) => void;
316
+ // readonly rowSelect?: (row: unknown) => void;
317
+ // readonly rowDeselect?: (row: unknown) => void;
318
+ // readonly rowContextMenu?: IRowMenu[];
319
+ // }
320
+
321
+ /**
322
+ * Generated bundle index. Do not edit.
323
+ */
324
+
325
+ export { CellPopoverComponent, DataGridComponent };
326
+ //# sourceMappingURL=sneat-datagrid.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sneat-datagrid.mjs","sources":["../../../../libs/datagrid/src/lib/components/cell-popover/cell-popover.component.ts","../../../../libs/datagrid/src/lib/components/cell-popover/cell-popover.component.html","../../../../libs/datagrid/src/lib/components/data-grid/data-grid.component.ts","../../../../libs/datagrid/src/lib/tabulator/tabulator-options.ts","../../../../libs/datagrid/src/sneat-datagrid.ts"],"sourcesContent":["import { Component, Input } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { RouterModule } from '@angular/router';\nimport {\n IonBadge,\n IonCardHeader,\n IonCardSubtitle,\n IonCardTitle,\n IonInput,\n IonItem,\n IonLabel,\n IonList,\n IonSegment,\n IonSegmentButton,\n IonText,\n} from '@ionic/angular/standalone';\n\n// TODO: Local minimal copies to avoid dependency on @sneat/datatug-main and break circular build deps\ninterface IRecordsetColumn {\n name: string;\n title?: string;\n dbType: string; // Using string here to avoid coupling to DbType type from datatug-main\n}\n\ninterface ITableRef {\n name: string;\n schema: string;\n catalog?: string;\n}\n\ninterface IForeignKey {\n name: string;\n columns: string[];\n refTable: ITableRef;\n}\n\n@Component({\n selector: 'sneat-datatug-cell-popover',\n templateUrl: './cell-popover.component.html',\n imports: [\n RouterModule,\n FormsModule,\n IonCardHeader,\n IonCardTitle,\n IonCardSubtitle,\n IonSegment,\n IonSegmentButton,\n IonLabel,\n IonList,\n IonItem,\n IonInput,\n IonBadge,\n IonText,\n ],\n})\nexport class CellPopoverComponent {\n @Input() column?: IRecordsetColumn;\n @Input() value: unknown;\n @Input() fk?: IForeignKey;\n\n public tab: 'rec' | 'cols' | 'refs' = 'rec';\n}\n","<ion-card-header>\n <ion-card-title>Field: {{ column?.name }}</ion-card-title>\n <ion-card-subtitle>Value: {{ value }}</ion-card-subtitle>\n</ion-card-header>\n<h3 class=\"ion-margin\">\n References:\n @if (fk?.refTable) {\n <a routerLink=\"{{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\">\n {{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}\n </a>\n }\n</h3>\n<ion-segment [(ngModel)]=\"tab\">\n <ion-segment-button value=\"rec\">\n <ion-label>Record</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"cols\">\n <ion-label>Columns</ion-label>\n </ion-segment-button>\n <ion-segment-button value=\"refs\">\n <ion-label>References</ion-label>\n </ion-segment-button>\n</ion-segment>\n\n@switch (tab) {\n @case (\"rec\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-input\n type=\"number\"\n style=\"text-align: right\"\n value=\"1\"\n readonly=\"true\"\n />\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-input\n type=\"text\"\n style=\"text-align: right\"\n value=\"Something\"\n readonly=\"true\"\n />\n </ion-item>\n </ion-list>\n }\n @case (\"cols\") {\n <ion-list>\n <ion-item>\n <ion-label>Id</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">INT</ion-text>\n </ion-badge>\n </ion-item>\n <ion-item>\n <ion-label>Code</ion-label>\n <ion-badge slot=\"end\" color=\"light\">\n <ion-text color=\"medium\">NVARCHAR</ion-text>\n </ion-badge>\n </ion-item>\n </ion-list>\n }\n}\n","import {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewChild,\n inject,\n} from '@angular/core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport {\n Tabulator,\n SelectRowModule,\n MenuModule,\n InteractionModule,\n Module,\n RowContextMenuSignature,\n} from 'tabulator-tables';\nimport { IGridColumn } from '@sneat/grid';\nimport { TabulatorColumn, TabulatorOptions } from '../../tabulator';\n\nclass AdvertModule extends Module {\n public static override moduleName = 'advert';\n\n override initialize() {\n return;\n }\n}\n\nTabulator.registerModule([\n InteractionModule,\n SelectRowModule,\n AdvertModule,\n MenuModule,\n]);\n\n\n// export interface IGridDef {\n// \tcolumns: IGridColumn[],\n// \trows?: unknown[],\n// \tgroupBy?: string;\n// }\n//\n// export const getTabulatorCols = (cols: IGridColumn[]): any[] => cols.map(c => {\n// \tconst v = {...c};\n// \tdelete v.dbType;\n// \treturn v;\n// });\n//\n// export interface IGridColumn {\n// \tfield: string;\n// \tcolName?: string;\n// \tdbType: string;\n// \ttitle: string;\n// \ttooltip?: (cell: any) => string;\n// \tformatter?: any;\n// \thozAlign?: 'left' | 'right';\n// \twidthShrink?: number;\n// \twidthGrow?: number;\n// \twidth?: number | string;\n// }\n\n/**\n * This is a wrapper class for the tabulator JS library.\n * For more info see http://tabulator.info\n */\n@Component({\n selector: 'sneat-datagrid',\n template: `\n <div id=\"tabulator\" #tabulatorDiv></div>\n <p class=\"ion-margin-start\">Rows: {{ data?.length }}</p>\n `,\n imports: [],\n})\nexport class DataGridComponent implements AfterViewInit, OnChanges {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n\n @Input() layout?: 'fitData' | 'fitColumns' = 'fitColumns';\n @Input() data?: unknown[] = [];\n @Input() columns?: IGridColumn[] = [];\n @Input() groupBy?: string;\n @Input() height?: string;\n @Input() maxHeight?: string | number;\n @Input() rowContextMenu?: RowContextMenuSignature;\n @ViewChild('tabulatorDiv', { static: true }) tabulatorDiv?: ElementRef;\n\n @Input() rowClick?: (event: Event, row: unknown) => void;\n\n @Output() readonly rowSelected = new EventEmitter<{\n row: unknown;\n event?: Event;\n }>();\n\n @Output() readonly rowDeselected = new EventEmitter<{\n row: unknown;\n event?: Event;\n }>();\n\n // private tab = document.createElement('div');\n private tabulator?: Tabulator;\n\n @Input() public selectable?: boolean | number | 'highlight';\n\n private tabulatorOptions?: TabulatorOptions;\n private clickEvent?: Event;\n\n ngOnChanges(changes: SimpleChanges): void {\n try {\n if (\n (changes['data'] && this.data && this.columns) ||\n (changes['columns'] && this.columns) ||\n (changes['rowClick'] && this.rowClick)\n ) {\n this.drawTable();\n }\n } catch (ex) {\n this.errorLogger.logError(\n ex,\n 'Failed to process ngOnChanges in DataGridComponent',\n );\n }\n }\n\n // ngOnDestroy(): void {\n // console.log('DataGridComponent.ngOnDestroy()', this.tabulator);\n // try { // TODO: destroy Tabulator\n // \tif (this.tabulator?.element) {\n // \t\t// noinspection TypeScriptValidateJSTypes\n // \t\tthis.tabulator.element.tabulator('destroy');\n // \t}\n // } catch (ex) {\n // \tthis.errorLogger.logError(ex, 'Failed to destroy tabulator');\n // }\n // }\n\n ngAfterViewInit(): void /* Intentionally not ngOnInit */ {\n if (this.tabulator) {\n try {\n this.tabulator.redraw();\n } catch (e) {\n this.errorLogger.logError(e, 'Failed to redraw tabulator', {\n show: false,\n report: false,\n });\n }\n }\n }\n\n private drawTable(): void {\n if (!this.data || !this.columns) {\n console.warn('drawTable()', 'columns:', this.columns, 'data:', this.data);\n return;\n }\n try {\n if (!this.tabulatorDiv) {\n this.errorLogger.logError(new Error('!this.tabulatorDiv'));\n return;\n }\n if (this.tabulatorOptions) {\n this.tabulatorOptions = { ...this.tabulatorOptions, data: this.data };\n this.tabulator\n ?.setData(this.data)\n .catch(this.errorLogger.logErrorHandler('Failed to set data'));\n } else {\n this.createTabulatorGrid();\n }\n // this.tabulatorDiv.nativeElement.appendChild(this.tab);\n // tabulator.redraw();\n } catch (e) {\n this.errorLogger.logError(e, 'Failed to drawTable');\n }\n }\n\n private createTabulatorGrid(): void {\n this.setTabulatorOptions();\n if (!this.tabulator) {\n this.tabulatorOptions = {\n ...this.tabulatorOptions,\n // rowClick: function (e, row) {\n // \tconsole.log('rowClick1', row);\n // },\n // rowSelect: function (row) {\n // \tconsole.log('rowSelect', row);\n // },\n // rowDeselect: function (row) {\n // \tconsole.log('rowDeselect', row);\n // }\n };\n this.tabulator = new Tabulator(\n this.tabulatorDiv?.nativeElement,\n this.tabulatorOptions,\n );\n this.tabulator.on('rowClick', (event: Event, row: unknown) => {\n this.clickEvent = event;\n if (this.rowClick) {\n this.rowClick(event, row);\n }\n });\n this.tabulator.on('rowSelected', (row: unknown) =>\n this.rowSelected.emit({ row, event: this.clickEvent }),\n );\n this.tabulator.on('rowDeselected', (row: unknown) =>\n this.rowDeselected.emit({ row, event: this.clickEvent }),\n );\n }\n }\n\n private setTabulatorOptions(): void {\n this.tabulatorOptions = {\n // tooltipsHeader: true, // enable header tooltips\n // tooltipGenerationMode: 'hover',\n rowContextMenu: this.rowContextMenu,\n selectableRows: this.selectable,\n data: this.data,\n // reactiveData: true, // enable data reactivity\n columns: this.columns?.map((c) => {\n const col: TabulatorColumn = {\n // TODO(help-wanted): Use strongly typed Tabulator col def\n field: c.field,\n title: c.title || c.field || c.title,\n // headerTooltip: () =>\n // \t`${c.colName || c.title || c.field}: ${c.dbType}`,\n };\n if (c.colName !== 'Id' && c.colName?.endsWith('Id')) {\n col.formatter = 'link';\n col.formatterParams = {\n url: 'test-url',\n };\n col.cellClick = (e: Event, cell: unknown) => {\n void cell;\n e.preventDefault();\n e.stopPropagation();\n };\n }\n if (c.tooltip) {\n col.tooltip = c.tooltip;\n }\n if (c.formatter) {\n col.formatter = c.formatter;\n }\n if (c.hozAlign) {\n col.hozAlign = c.hozAlign;\n }\n if (c.headerHozAlign) {\n col.headerHozAlign = c.headerHozAlign;\n }\n if (c.widthGrow) {\n col.widthGrow = c.widthGrow;\n }\n if (c.widthShrink) {\n col.widthShrink = c.widthShrink;\n }\n if (c.width !== undefined) {\n col.width = c.width;\n }\n // console.log('col:', col);\n return col;\n }),\n layout: this.layout || 'fitColumns',\n };\n if (this.height) {\n this.tabulatorOptions = {\n ...this.tabulatorOptions,\n height: this.height,\n };\n }\n if (this.maxHeight) {\n this.tabulatorOptions = {\n ...this.tabulatorOptions,\n maxHeight: this.maxHeight,\n };\n }\n if (this.groupBy) {\n this.tabulatorOptions = {\n ...this.tabulatorOptions,\n groupBy: this.groupBy,\n groupHeader: (value: unknown, count: number) => {\n // value - the value all members of this group share\n // count - the number of rows in this group\n // data - an array of all the row data objects in this group\n // group - the group component for the group\n // console.log('groupHeader', value);\n return `${\n this.groupBy\n }: ${value} <span class=\"ion-margin-start\">(${count} ${\n count === 1 ? 'record' : 'records'\n })</span>`;\n },\n };\n }\n }\n}\n","import { ColumnDefinition, Options } from 'tabulator-tables';\n\nexport type TabulatorColumn = ColumnDefinition;\n\n// export interface TabulatorColumn {\n// \tfield: string;\n// \ttitle?: string;\n// \tformatter?: 'link' | 'progress' | 'html' | 'text' | 'number' | 'money' | 'image' | 'tickCross';\n// \tformatterParams?: unknown;\n// \tcellClick?: (e: Event, cell: unknown) => void;\n// \theaderTooltip?: () => string;\n// \ttooltip?: (cell: unknown) => string;\n// \thozAlign?: 'left' | 'right';\n// \theaderHozAlign?: 'left' | 'right';\n// \twidthShrink?: number;\n// \twidthGrow?: number;\n// \twidth?: number | string;\n// }\n\nexport type TabulatorOptions = Options;\n// export interface TabulatorOptions {\n// \treadonly tooltipsHeader?: boolean;\n// \treadonly tooltipGenerationMode?: 'hover' | 'mouseover';\n// \treadonly reactiveData?: boolean;\n// \treadonly selectable?: boolean | number | 'highlight';\n// \treadonly data?: unknown[];\n// \treadonly layout?: 'fitData' | 'fitColumns';\n// \treadonly columns?: TabulatorColumn[];\n// \treadonly height?: string | number;\n// \treadonly maxHeight?: string | number;\n// \treadonly groupBy?: string;\n// \treadonly groupHeader?: (value: unknown, count: number) => string;\n// \treadonly rowClick?: (event: Event, row: unknown) => void;\n// \treadonly rowSelect?: (row: unknown) => void;\n// \treadonly rowDeselect?: (row: unknown) => void;\n// \treadonly rowContextMenu?: IRowMenu[];\n// }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;MAuDa,oBAAoB,CAAA;AAnBjC,IAAA,WAAA,GAAA;QAwBS,IAAA,CAAA,GAAG,GAA4B,KAAK;AAC5C,IAAA;8GANY,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvDjC,qsDAgEA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDxBI,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,aAAa,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,YAAY,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,eAAe,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACf,UAAU,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,YAAA,EAAA,eAAA,EAAA,cAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,YAAA,EAAA,UAAA,EAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,aAAA,EAAA,WAAA,EAAA,YAAA,EAAA,aAAA,EAAA,OAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,cAAA,EAAA,WAAA,EAAA,MAAA,EAAA,YAAA,EAAA,WAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,WAAA,EAAA,KAAA,EAAA,WAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;2FAGE,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAnBhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,EAAA,OAAA,EAE7B;wBACP,YAAY;wBACZ,WAAW;wBACX,aAAa;wBACb,YAAY;wBACZ,eAAe;wBACf,UAAU;wBACV,gBAAgB;wBAChB,QAAQ;wBACR,OAAO;wBACP,OAAO;wBACP,QAAQ;wBACR,QAAQ;wBACR,OAAO;AACR,qBAAA,EAAA,QAAA,EAAA,qsDAAA,EAAA;;sBAGA;;sBACA;;sBACA;;;AEhCH,MAAM,YAAa,SAAQ,MAAM,CAAA;aACR,IAAA,CAAA,UAAU,GAAG,QAAQ,CAAC;IAEpC,UAAU,GAAA;QACjB;IACF;;AAGF,SAAS,CAAC,cAAc,CAAC;IACvB,iBAAiB;IACjB,eAAe;IACf,YAAY;IACZ,UAAU;AACX,CAAA,CAAC;AAGF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAGG;MASU,iBAAiB,CAAA;AAR9B,IAAA,WAAA,GAAA;AASmB,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAe,WAAW,CAAC;QAEvD,IAAA,CAAA,MAAM,GAA8B,YAAY;QAChD,IAAA,CAAA,IAAI,GAAe,EAAE;QACrB,IAAA,CAAA,OAAO,GAAmB,EAAE;AASlB,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,YAAY,EAG7C;AAEe,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,YAAY,EAG/C;AAmML,IAAA;AAzLC,IAAA,WAAW,CAAC,OAAsB,EAAA;AAChC,QAAA,IAAI;AACF,YAAA,IACE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO;iBAC5C,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC;iBACnC,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EACtC;gBACA,IAAI,CAAC,SAAS,EAAE;YAClB;QACF;QAAE,OAAO,EAAE,EAAE;YACX,IAAI,CAAC,WAAW,CAAC,QAAQ,CACvB,EAAE,EACF,oDAAoD,CACrD;QACH;IACF;;;;;;;;;;;;IAcA,eAAe,GAAA;AACb,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YACzB;YAAE,OAAO,CAAC,EAAE;gBACV,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,4BAA4B,EAAE;AACzD,oBAAA,IAAI,EAAE,KAAK;AACX,oBAAA,MAAM,EAAE,KAAK;AACd,iBAAA,CAAC;YACJ;QACF;IACF;IAEQ,SAAS,GAAA;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AAC/B,YAAA,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;YACzE;QACF;AACA,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBACtB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;gBAC1D;YACF;AACA,YAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,gBAAA,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACrE,gBAAA,IAAI,CAAC;AACH,sBAAE,OAAO,CAAC,IAAI,CAAC,IAAI;qBAClB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;YAClE;iBAAO;gBACL,IAAI,CAAC,mBAAmB,EAAE;YAC5B;;;QAGF;QAAE,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,qBAAqB,CAAC;QACrD;IACF;IAEQ,mBAAmB,GAAA;QACzB,IAAI,CAAC,mBAAmB,EAAE;AAC1B,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,gBAAgB,GAAG;gBACtB,GAAG,IAAI,CAAC,gBAAgB;;;;;;;;;;aAUzB;AACD,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAC5B,IAAI,CAAC,YAAY,EAAE,aAAa,EAChC,IAAI,CAAC,gBAAgB,CACtB;AACD,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAY,EAAE,GAAY,KAAI;AAC3D,gBAAA,IAAI,CAAC,UAAU,GAAG,KAAK;AACvB,gBAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,oBAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;gBAC3B;AACF,YAAA,CAAC,CAAC;AACF,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,GAAY,KAC5C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CACvD;AACD,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,GAAY,KAC9C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CACzD;QACH;IACF;IAEQ,mBAAmB,GAAA;QACzB,IAAI,CAAC,gBAAgB,GAAG;;;YAGtB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,cAAc,EAAE,IAAI,CAAC,UAAU;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAI;;YAEf,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,KAAI;AAC/B,gBAAA,MAAM,GAAG,GAAoB;;oBAE3B,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK;;;iBAGrC;AACD,gBAAA,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE;AACnD,oBAAA,GAAG,CAAC,SAAS,GAAG,MAAM;oBACtB,GAAG,CAAC,eAAe,GAAG;AACpB,wBAAA,GAAG,EAAE,UAAU;qBAChB;oBACD,GAAG,CAAC,SAAS,GAAG,CAAC,CAAQ,EAAE,IAAa,KAAI;AAC1C,wBAAA,KAAK,IAAI;wBACT,CAAC,CAAC,cAAc,EAAE;wBAClB,CAAC,CAAC,eAAe,EAAE;AACrB,oBAAA,CAAC;gBACH;AACA,gBAAA,IAAI,CAAC,CAAC,OAAO,EAAE;AACb,oBAAA,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;gBACzB;AACA,gBAAA,IAAI,CAAC,CAAC,SAAS,EAAE;AACf,oBAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS;gBAC7B;AACA,gBAAA,IAAI,CAAC,CAAC,QAAQ,EAAE;AACd,oBAAA,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ;gBAC3B;AACA,gBAAA,IAAI,CAAC,CAAC,cAAc,EAAE;AACpB,oBAAA,GAAG,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc;gBACvC;AACA,gBAAA,IAAI,CAAC,CAAC,SAAS,EAAE;AACf,oBAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS;gBAC7B;AACA,gBAAA,IAAI,CAAC,CAAC,WAAW,EAAE;AACjB,oBAAA,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW;gBACjC;AACA,gBAAA,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE;AACzB,oBAAA,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;gBACrB;;AAEA,gBAAA,OAAO,GAAG;AACZ,YAAA,CAAC,CAAC;AACF,YAAA,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,YAAY;SACpC;AACD,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,gBAAgB,GAAG;gBACtB,GAAG,IAAI,CAAC,gBAAgB;gBACxB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB;QACH;AACA,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,IAAI,CAAC,gBAAgB,GAAG;gBACtB,GAAG,IAAI,CAAC,gBAAgB;gBACxB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B;QACH;AACA,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,gBAAgB,GAAG;gBACtB,GAAG,IAAI,CAAC,gBAAgB;gBACxB,OAAO,EAAE,IAAI,CAAC,OAAO;AACrB,gBAAA,WAAW,EAAE,CAAC,KAAc,EAAE,KAAa,KAAI;;;;;;oBAM7C,OAAO,CAAA,EACL,IAAI,CAAC,OACP,KAAK,KAAK,CAAA,iCAAA,EAAoC,KAAK,CAAA,CAAA,EACjD,KAAK,KAAK,CAAC,GAAG,QAAQ,GAAG,SAC3B,CAAA,QAAA,CAAU;gBACZ,CAAC;aACF;QACH;IACF;8GAxNW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,WAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,cAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,cAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EANlB;;;AAGT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,CAAA;;2FAGU,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAR7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,QAAQ,EAAE;;;AAGT,EAAA,CAAA;AACD,oBAAA,OAAO,EAAE,EAAE;AACZ,iBAAA;;sBAIE;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA;;sBACA,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;;sBAE1C;;sBAEA;;sBAKA;;sBAQA;;;ACtFH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/datagrid",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -10,5 +10,17 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "tslib": "2.8.1"
13
- }
13
+ },
14
+ "module": "fesm2022/sneat-datagrid.mjs",
15
+ "typings": "types/sneat-datagrid.d.ts",
16
+ "exports": {
17
+ "./package.json": {
18
+ "default": "./package.json"
19
+ },
20
+ ".": {
21
+ "types": "./types/sneat-datagrid.d.ts",
22
+ "default": "./fesm2022/sneat-datagrid.mjs"
23
+ }
24
+ },
25
+ "sideEffects": false
14
26
  }
@@ -0,0 +1,70 @@
1
+ import * as i0 from '@angular/core';
2
+ import { AfterViewInit, OnChanges, ElementRef, EventEmitter, SimpleChanges } from '@angular/core';
3
+ import { RowContextMenuSignature, ColumnDefinition, Options } from 'tabulator-tables';
4
+ import { IGridColumn } from '@sneat/grid';
5
+
6
+ interface IRecordsetColumn {
7
+ name: string;
8
+ title?: string;
9
+ dbType: string;
10
+ }
11
+ interface ITableRef {
12
+ name: string;
13
+ schema: string;
14
+ catalog?: string;
15
+ }
16
+ interface IForeignKey {
17
+ name: string;
18
+ columns: string[];
19
+ refTable: ITableRef;
20
+ }
21
+ declare class CellPopoverComponent {
22
+ column?: IRecordsetColumn;
23
+ value: unknown;
24
+ fk?: IForeignKey;
25
+ tab: 'rec' | 'cols' | 'refs';
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<CellPopoverComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<CellPopoverComponent, "sneat-datatug-cell-popover", never, { "column": { "alias": "column"; "required": false; }; "value": { "alias": "value"; "required": false; }; "fk": { "alias": "fk"; "required": false; }; }, {}, never, never, true, never>;
28
+ }
29
+
30
+ /**
31
+ * This is a wrapper class for the tabulator JS library.
32
+ * For more info see http://tabulator.info
33
+ */
34
+ declare class DataGridComponent implements AfterViewInit, OnChanges {
35
+ private readonly errorLogger;
36
+ layout?: 'fitData' | 'fitColumns';
37
+ data?: unknown[];
38
+ columns?: IGridColumn[];
39
+ groupBy?: string;
40
+ height?: string;
41
+ maxHeight?: string | number;
42
+ rowContextMenu?: RowContextMenuSignature;
43
+ tabulatorDiv?: ElementRef;
44
+ rowClick?: (event: Event, row: unknown) => void;
45
+ readonly rowSelected: EventEmitter<{
46
+ row: unknown;
47
+ event?: Event;
48
+ }>;
49
+ readonly rowDeselected: EventEmitter<{
50
+ row: unknown;
51
+ event?: Event;
52
+ }>;
53
+ private tabulator?;
54
+ selectable?: boolean | number | 'highlight';
55
+ private tabulatorOptions?;
56
+ private clickEvent?;
57
+ ngOnChanges(changes: SimpleChanges): void;
58
+ ngAfterViewInit(): void;
59
+ private drawTable;
60
+ private createTabulatorGrid;
61
+ private setTabulatorOptions;
62
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataGridComponent, never>;
63
+ static ɵcmp: i0.ɵɵComponentDeclaration<DataGridComponent, "sneat-datagrid", never, { "layout": { "alias": "layout"; "required": false; }; "data": { "alias": "data"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "groupBy": { "alias": "groupBy"; "required": false; }; "height": { "alias": "height"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; "rowContextMenu": { "alias": "rowContextMenu"; "required": false; }; "rowClick": { "alias": "rowClick"; "required": false; }; "selectable": { "alias": "selectable"; "required": false; }; }, { "rowSelected": "rowSelected"; "rowDeselected": "rowDeselected"; }, never, never, true, never>;
64
+ }
65
+
66
+ type TabulatorColumn = ColumnDefinition;
67
+ type TabulatorOptions = Options;
68
+
69
+ export { CellPopoverComponent, DataGridComponent };
70
+ export type { TabulatorColumn, TabulatorOptions };
package/eslint.config.js DELETED
@@ -1,7 +0,0 @@
1
- const baseConfig = require('../../eslint.config.js');
2
- const { sneatLibConfig } = require('../../eslint.lib.config.js');
3
-
4
- module.exports = [
5
- ...baseConfig,
6
- ...sneatLibConfig(__dirname),
7
- ];
package/ng-package.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
- "dest": "../../dist/libs/datagrid",
4
- "lib": {
5
- "entryFile": "src/index.ts"
6
- }
7
- }
package/project.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "name": "datagrid",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "projectType": "library",
5
- "sourceRoot": "libs/datagrid/src",
6
- "prefix": "sneat",
7
- "targets": {
8
- "build": {
9
- "executor": "@nx/angular:package",
10
- "outputs": [
11
- "{workspaceRoot}/dist/libs/datagrid"
12
- ],
13
- "options": {
14
- "project": "libs/datagrid/ng-package.json",
15
- "tsConfig": "libs/datagrid/tsconfig.lib.json"
16
- },
17
- "configurations": {
18
- "production": {
19
- "tsConfig": "libs/datagrid/tsconfig.lib.prod.json"
20
- },
21
- "development": {}
22
- },
23
- "defaultConfiguration": "production"
24
- },
25
- "test": {
26
- "executor": "@nx/vitest:test",
27
- "outputs": [
28
- "{workspaceRoot}/coverage/libs/datagrid"
29
- ],
30
- "options": {
31
- "tsConfig": "libs/datagrid/tsconfig.spec.json"
32
- }
33
- },
34
- "lint": {
35
- "executor": "@nx/eslint:lint"
36
- }
37
- }
38
- }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './lib/components';
2
- export * from './lib/tabulator';
@@ -1,64 +0,0 @@
1
- <ion-card-header>
2
- <ion-card-title>Field: {{ column?.name }}</ion-card-title>
3
- <ion-card-subtitle>Value: {{ value }}</ion-card-subtitle>
4
- </ion-card-header>
5
- <h3 class="ion-margin">
6
- References:
7
- @if (fk?.refTable) {
8
- <a routerLink="{{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}">
9
- {{ fk?.refTable?.schema }}.{{ fk?.refTable?.name }}
10
- </a>
11
- }
12
- </h3>
13
- <ion-segment [(ngModel)]="tab">
14
- <ion-segment-button value="rec">
15
- <ion-label>Record</ion-label>
16
- </ion-segment-button>
17
- <ion-segment-button value="cols">
18
- <ion-label>Columns</ion-label>
19
- </ion-segment-button>
20
- <ion-segment-button value="refs">
21
- <ion-label>References</ion-label>
22
- </ion-segment-button>
23
- </ion-segment>
24
-
25
- @switch (tab) {
26
- @case ("rec") {
27
- <ion-list>
28
- <ion-item>
29
- <ion-label>Id</ion-label>
30
- <ion-input
31
- type="number"
32
- style="text-align: right"
33
- value="1"
34
- readonly="true"
35
- />
36
- </ion-item>
37
- <ion-item>
38
- <ion-label>Code</ion-label>
39
- <ion-input
40
- type="text"
41
- style="text-align: right"
42
- value="Something"
43
- readonly="true"
44
- />
45
- </ion-item>
46
- </ion-list>
47
- }
48
- @case ("cols") {
49
- <ion-list>
50
- <ion-item>
51
- <ion-label>Id</ion-label>
52
- <ion-badge slot="end" color="light">
53
- <ion-text color="medium">INT</ion-text>
54
- </ion-badge>
55
- </ion-item>
56
- <ion-item>
57
- <ion-label>Code</ion-label>
58
- <ion-badge slot="end" color="light">
59
- <ion-text color="medium">NVARCHAR</ion-text>
60
- </ion-badge>
61
- </ion-item>
62
- </ion-list>
63
- }
64
- }