ms-data-grid 0.0.17 → 0.0.18

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.
Files changed (58) hide show
  1. package/esm2022/lib/data-grid/data-grid.component.mjs +3646 -0
  2. package/esm2022/lib/data-grid/statuses.mjs +44 -0
  3. package/esm2022/lib/data-grid.module.mjs +26 -0
  4. package/esm2022/lib/data-grid.service.mjs +14 -0
  5. package/esm2022/lib/directives/draggable-header.directive.mjs +145 -0
  6. package/esm2022/lib/pipes/filter.pipe.mjs +22 -0
  7. package/esm2022/lib/services/common.service.mjs +206 -0
  8. package/esm2022/lib/services/copy-service.service.mjs +221 -0
  9. package/esm2022/lib/services/split-columns.service.mjs +143 -0
  10. package/esm2022/lib/services/swap-columns.service.mjs +118 -0
  11. package/esm2022/ms-data-grid.mjs +5 -0
  12. package/esm2022/public-api.mjs +8 -0
  13. package/fesm2022/ms-data-grid.mjs +4569 -0
  14. package/fesm2022/ms-data-grid.mjs.map +1 -0
  15. package/index.d.ts +5 -0
  16. package/lib/data-grid/data-grid.component.d.ts +469 -0
  17. package/lib/data-grid/statuses.d.ts +3 -0
  18. package/lib/data-grid.module.d.ts +14 -0
  19. package/lib/data-grid.service.d.ts +6 -0
  20. package/lib/directives/draggable-header.directive.d.ts +31 -0
  21. package/lib/pipes/filter.pipe.d.ts +7 -0
  22. package/lib/services/common.service.d.ts +17 -0
  23. package/lib/services/copy-service.service.d.ts +14 -0
  24. package/lib/services/split-columns.service.d.ts +9 -0
  25. package/lib/services/swap-columns.service.d.ts +19 -0
  26. package/package.json +45 -33
  27. package/{src/public-api.ts → public-api.d.ts} +4 -8
  28. package/CHANGELOG.md +0 -57
  29. package/DOCUMENTATION.md +0 -243
  30. package/ng-package.json +0 -10
  31. package/src/lib/css/bootstrap.css +0 -12043
  32. package/src/lib/data-grid/data-grid.component.html +0 -4806
  33. package/src/lib/data-grid/data-grid.component.scss +0 -1502
  34. package/src/lib/data-grid/data-grid.component.spec.ts +0 -28
  35. package/src/lib/data-grid/data-grid.component.ts +0 -4216
  36. package/src/lib/data-grid/statuses.ts +0 -47
  37. package/src/lib/data-grid.module.ts +0 -20
  38. package/src/lib/data-grid.service.spec.ts +0 -16
  39. package/src/lib/data-grid.service.ts +0 -9
  40. package/src/lib/directives/draggable-header.directive.spec.ts +0 -11
  41. package/src/lib/directives/draggable-header.directive.ts +0 -172
  42. package/src/lib/pipes/filter.pipe.spec.ts +0 -11
  43. package/src/lib/pipes/filter.pipe.ts +0 -16
  44. package/src/lib/services/cell-selection.service.spec.ts +0 -16
  45. package/src/lib/services/cell-selection.service.ts +0 -234
  46. package/src/lib/services/common.service.spec.ts +0 -16
  47. package/src/lib/services/common.service.ts +0 -239
  48. package/src/lib/services/copy-service.service.spec.ts +0 -16
  49. package/src/lib/services/copy-service.service.ts +0 -251
  50. package/src/lib/services/drag-drp.service.spec.ts +0 -16
  51. package/src/lib/services/drag-drp.service.ts +0 -58
  52. package/src/lib/services/split-columns.service.spec.ts +0 -16
  53. package/src/lib/services/split-columns.service.ts +0 -148
  54. package/src/lib/services/swap-columns.service.spec.ts +0 -16
  55. package/src/lib/services/swap-columns.service.ts +0 -162
  56. package/tsconfig.lib.json +0 -16
  57. package/tsconfig.lib.prod.json +0 -10
  58. package/tsconfig.spec.json +0 -14
@@ -1,239 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
-
3
- @Injectable({
4
- providedIn: 'root'
5
- })
6
- export class CommonService {
7
-
8
- constructor() { }
9
- gethasVisibleColumns(columns: any[]): boolean {
10
- const checkVisible = (columns: any[]): boolean => {
11
- return columns.some((col) => {
12
- if (col?.is_visible) return true;
13
- if (col?.children?.length) {
14
- return checkVisible(col.children);
15
- }
16
- return false;
17
- });
18
- };
19
- return checkVisible(columns);
20
- }
21
-
22
- gethasInVisibleColumns(columns: any[]): boolean {
23
- const checkVisible = (columns: any[]): boolean => {
24
- return columns.some((col) => {
25
- if (!col?.is_visible) return true;
26
- if (col?.children?.length) {
27
- return checkVisible(col.children);
28
- }
29
- return false;
30
- });
31
- };
32
- return checkVisible(columns);
33
- }
34
-
35
-
36
- getTotalColumnsLength(columns: any[]): number {
37
- let count = 0;
38
-
39
- columns.forEach(col => {
40
- if (col.children && Array.isArray(col.children) && col.children.length) {
41
- count += col.children.length; // count children instead of parent
42
- } else {
43
- count += 1; // count parent directly
44
- }
45
- });
46
-
47
- return count;
48
- }
49
-
50
- gethasRightPinnedColumns(columns: any[]): boolean {
51
- const checkPinnedRight = (columns: any[]): boolean => {
52
- return columns.some((col) => {
53
- if (col?.pinned === 'right' && col?.is_visible) return true;
54
- if (col?.children?.length) {
55
- return checkPinnedRight(col.children);
56
- }
57
- return false;
58
- });
59
- };
60
- return checkPinnedRight(columns);
61
- }
62
-
63
- gethasLeftPinnedColumns(columns: any[]): boolean {
64
- const checkPinnedRight = (columns: any[]): boolean => {
65
- return columns.some((col) => {
66
- if (col?.pinned === 'left' && col?.is_visible) return true;
67
- if (col?.children?.length) {
68
- return checkPinnedRight(col.children);
69
- }
70
- return false;
71
- });
72
- };
73
- return checkPinnedRight(columns);
74
- }
75
-
76
-
77
- getExpandedRowCount(data: any[]): number {
78
- let groupCount = 0;
79
- let rowCount = 0;
80
-
81
- data.forEach(group => {
82
- if (group?.isGroup) {
83
- groupCount++;
84
-
85
- if (group?.isExpand && Array.isArray(group?.children)) {
86
- group.children.forEach((child: any) => {
87
- if (child.isGroup) {
88
- if (child.isExpand && Array.isArray(child.children)) {
89
- rowCount += child.children.length;
90
- }
91
- } else {
92
- rowCount++;
93
- }
94
- });
95
- }
96
- }
97
- });
98
-
99
- if (groupCount === 0) {
100
- return data.length;
101
- }
102
-
103
- return groupCount + rowCount;
104
- }
105
-
106
-
107
- getFiltersFromColumns(columns: any[], filtersConfig:any []): any[] {
108
- const result: any[] = [];
109
-
110
- const checkColumn = (col: any) => {
111
- const hasFirstValue = col.query?.first_value != null && col.query?.first_value !== "" && filtersConfig.some((ele)=> ele.field == col.field);
112
- const hasIds = Array.isArray(col.query?._ids) && col.query._ids.length > 0 && filtersConfig.some((ele)=> ele.field == col.field);
113
- if (hasFirstValue || hasIds) {
114
- result.push({
115
- search: col.search ?? "",
116
- field: col.field,
117
- type: col.type,
118
- _ids: col.type == 'dropdown'? col.query?._ids: [],
119
- query: col.type == 'dropdown'? null : (col?.query?.first_value ? col?.query : null)
120
- });
121
- }
122
-
123
- if (Array.isArray(col.children) && col.children.length > 0) {
124
- col.children.forEach(checkColumn);
125
- }
126
- };
127
- columns.forEach(checkColumn);
128
-
129
- return result;
130
- }
131
-
132
- async applyFiltersToColumns(columns: any[], filters: any[]): Promise<any[]> {
133
- for (const col of columns) {
134
- if (!col.query) {
135
- col.query = {
136
- first_value: null,
137
- second_value: null,
138
- first_condition: col.type !== 'date'? 'contain': 'equal',
139
- second_condition: col.type !== 'date'? 'contain': 'equal',
140
- condition: 'none',
141
- _ids: []
142
- };
143
- }
144
-
145
- const filter = filters.find(f => f.field === col.field);
146
-
147
- if (filter) {
148
- if (col.type === 'dropdown') {
149
- col.filterValue = filter._ids ?? [];
150
- col.search = filter.search ?? '';
151
- col.query._ids = filter._ids ?? [];
152
- } else {
153
- col.filterValue = filter.search ?? null;
154
- col.search = filter.search ?? '';
155
- col.query.first_value = filter.query?.first_value ?? null;
156
- col.query.second_value = filter.query?.second_value ?? null;
157
- col.query.first_condition = filter.query?.first_condition ?? filter.type !== 'date'? 'contain': 'equal';
158
- col.query.second_condition = filter.query?.second_condition ?? filter.type !== 'date'? 'contain': 'equal';
159
- col.query.condition = filter.query?.condition ?? 'none';
160
- }
161
- }
162
- if (Array.isArray(col.children) && col.children.length > 0) {
163
- col.children = await this.applyFiltersToColumns(col.children, filters);
164
- }
165
- }
166
- return columns;
167
- }
168
-
169
-
170
-
171
-
172
-
173
- activeFilteredColumns: any[] = [];
174
- updateActiveFilteredColumns(columns: any[]): any[] {
175
- const collectFiltered = (cols: any[]): any[] => {
176
- let result: any[] = [];
177
-
178
- for (let i = 0; i < cols.length; i++) {
179
- const col = cols[i];
180
- if (col.children && col.children.length > 0) {
181
- result = result.concat(collectFiltered(col.children));
182
- }
183
-
184
- if (col.query) {
185
- const hasDropdownFilter =
186
- Array.isArray(col.query._ids) && col.query._ids.length > 0;
187
-
188
- const hasValueFilter =
189
- (col.query.first_value && col.query.first_value !== '') ||
190
- (col.query.second_value && col.query.second_value !== '');
191
-
192
- if (hasDropdownFilter || hasValueFilter) {
193
- result.push(col);
194
- }
195
- }
196
- }
197
- return result;
198
- };
199
- this.activeFilteredColumns = [...collectFiltered(columns)];
200
- return this.activeFilteredColumns;
201
- }
202
-
203
-
204
-
205
- hasFieldChanged(current: any, original: any, type: string): boolean {
206
- switch (type) {
207
- case 'number':
208
- return Number(current) !== Number(original);
209
-
210
- case 'string':
211
- return String(current || '') !== String(original || '');
212
-
213
- case 'dropdown':
214
- if (typeof current === 'object' && typeof original === 'object') {
215
- return current?.id !== original?.id || current?.value !== original?.value;
216
- }
217
- return current !== original;
218
-
219
- case 'boolean':
220
- return Boolean(current) !== Boolean(original);
221
-
222
- case 'date':
223
- const currentDate = new Date(current).getTime();
224
- const originalDate = new Date(original).getTime();
225
- return isNaN(currentDate) || isNaN(originalDate)
226
- ? current !== original
227
- : currentDate !== originalDate;
228
-
229
- default:
230
- return JSON.stringify(current) !== JSON.stringify(original);
231
- }
232
- }
233
-
234
-
235
- }
236
-
237
-
238
-
239
-
@@ -1,16 +0,0 @@
1
- /* tslint:disable:no-unused-variable */
2
-
3
- import { TestBed, async, inject } from '@angular/core/testing';
4
- import { CopyServiceService } from './copy-service.service';
5
-
6
- describe('Service: CopyService', () => {
7
- beforeEach(() => {
8
- TestBed.configureTestingModule({
9
- providers: [CopyServiceService]
10
- });
11
- });
12
-
13
- it('should ...', inject([CopyServiceService], (service: CopyServiceService) => {
14
- expect(service).toBeTruthy();
15
- }));
16
- });
@@ -1,251 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
-
3
- @Injectable({
4
- providedIn: 'root'
5
- })
6
- export class CopyServiceService {
7
-
8
- constructor() { }
9
- getSelectedDataForCopy(
10
- dataSet: any[],
11
- columns: any[],
12
- rowSelectedIndexes: Set<number>,
13
- selectedCells: any[],
14
- getNestedValue: (obj: any, path: string) => any
15
- ): any[][] {
16
- const copiedRows: any[][] = [];
17
- const findRowByVirtualIndex = (vIndex: number) =>
18
- dataSet.find((r: any) => r.__virtualIndex === vIndex);
19
- if (rowSelectedIndexes && rowSelectedIndexes.size > 0) {
20
- const sortedIndexes = [...rowSelectedIndexes].sort((a, b) => a - b);
21
- for (const vIndex of sortedIndexes) {
22
- const row = findRowByVirtualIndex(vIndex);
23
- if (!row) continue;
24
- const extractValue = (field: string): string => {
25
- const nested = getNestedValue(row, field);
26
- const value =
27
- nested?.value ??
28
- nested?.name ??
29
- nested ??
30
- '-';
31
-
32
- if (Array.isArray(value)) {
33
- return value
34
- .map(v =>
35
- typeof v === 'object'
36
- ? (v.departmentName ?? v.roleName ?? '')
37
- : (v?.toString() ?? '')
38
- )
39
- .join(', ');
40
- }
41
- return value ?? '';
42
- };
43
- const mapped = columns.map(col => {
44
- if (col.children && Array.isArray(col.children)) {
45
- return col.children.map((c: { field: string }) => extractValue(c.field));
46
- }
47
- return [extractValue(col.field)];
48
- });
49
- const rowValues = mapped.reduce<string[]>((acc, curr) => acc.concat(curr), []);
50
- copiedRows.push(rowValues);
51
- }
52
- }
53
- if (selectedCells && selectedCells.length > 0) {
54
- const rowsMap = new Map<number, any[]>();
55
- for (const cell of selectedCells) {
56
- const row = findRowByVirtualIndex(cell.rowIndex);
57
- if (!row) continue;
58
- const col = columns[cell.colIndex];
59
- let fieldName = col?.field;
60
- if (col?.children && col.children[cell.subColIndex]) {
61
- fieldName = col.children[cell.subColIndex].field;
62
- }
63
- let value = getNestedValue(row, fieldName) || getNestedValue(row, fieldName)?.name || getNestedValue(row, fieldName) || '-';
64
- if (Array.isArray(value)) {
65
- value = value
66
- .map(v =>
67
- typeof v === 'object'
68
- ? v.departmentName ?? v.roleName ?? ''
69
- : v?.toString() ?? ''
70
- )
71
- .join(', ');
72
- } else {
73
- value = value ?? '';
74
- }
75
- if (!rowsMap.has(cell.rowIndex)) rowsMap.set(cell.rowIndex, []);
76
- rowsMap.get(cell.rowIndex)!.push(value);
77
- }
78
- const sortedCells = [...rowsMap.entries()]
79
- .sort(([a], [b]) => a - b)
80
- .map(([_, v]) => v);
81
- copiedRows.push(...sortedCells);
82
- }
83
- if (copiedRows.length === 0) {
84
- const activeCell = document.querySelector('.active-cell');
85
- if (activeCell) return [[activeCell.textContent?.trim() || '']];
86
- }
87
-
88
- const maxCols = copiedRows.reduce((max, row) => Math.max(max, row.length), 0);
89
- return copiedRows.map(row => {
90
- const newRow = [...row];
91
- while (newRow.length < maxCols) newRow.push('');
92
- return newRow;
93
- });
94
- }
95
-
96
-
97
- copyToClipboard(
98
- selectedData: any[][],
99
- selector = '.selected-cell, .active-cell, .row-selected'
100
- ): void {
101
- if (!selectedData || selectedData.length === 0) return;
102
- const textToCopy = selectedData
103
- .map(row => row.map(cell => (cell ?? '').toString()).join('\t'))
104
- .join('\n');
105
- navigator.clipboard.writeText(textToCopy).catch(err => console.error(err));
106
- const selectedEls = document.querySelectorAll(selector);
107
- selectedEls.forEach(el => el.classList.add('flash-bg'));
108
- setTimeout(() => {
109
- selectedEls.forEach(el => el.classList.remove('flash-bg'));
110
- }, 1000);
111
- }
112
-
113
-
114
- updateRows: any[] = [];
115
- currentColums : any = []
116
- async pasteFromClipboardText(
117
- text: string,
118
- dataSet: any[],
119
- columns: any[],
120
- startRowIndex: number,
121
- startColIndex: number,
122
- startSubColIndex: number = 0
123
- ): Promise<any> {
124
- if (!text) return [];
125
- this.updateRows = [];
126
- const rows = text.split(/\r?\n/).map(r => r.split('\t'));
127
- const flattenedColumns: any[] = [];
128
- columns.forEach(col => {
129
- if (col.children?.length) {
130
- col.children.forEach((child: any) => flattenedColumns.push({ parent: col, ...child }));
131
- } else {
132
- flattenedColumns.push(col);
133
- }
134
- });
135
- let startFlattenedIndex = 0;
136
- for (let i = 0; i < startColIndex; i++) {
137
- const col = columns[i];
138
- startFlattenedIndex += col.children?.length || 1;
139
- }
140
- const startCol = columns[startColIndex];
141
- if (startCol?.children?.length) {
142
- startFlattenedIndex += Math.min(startSubColIndex, startCol.children.length - 1);
143
- }
144
-
145
- rows.forEach((rowValues, rOffset) => {
146
- const targetRowIndex = startRowIndex + rOffset;
147
- const row = dataSet.find(r => r?.__virtualIndex === targetRowIndex);
148
- if (!row) return;
149
-
150
- rowValues.forEach((value, cOffset) => {
151
- const targetIndex = startFlattenedIndex + cOffset;
152
- if (targetIndex < 0 || targetIndex >= flattenedColumns.length) return;
153
-
154
- const targetColumn = flattenedColumns[targetIndex];
155
- if(!targetColumn || !targetColumn.is_editable) return;
156
- if (targetColumn?.type === 'string') {
157
- this.currentColums.push(targetColumn);
158
- this.setNestedValue(row, targetColumn, value);
159
- } else if (targetColumn.type === 'number') {
160
- const num = Number(value);
161
- if (!isNaN(num) && value !== '') {
162
- this.currentColums.push(targetColumn);
163
- this.setNestedValue(row, targetColumn, num);
164
- }
165
- }
166
- });
167
- });
168
-
169
- return {updateRows : this.updateRows, currentColums : this.currentColums};
170
- }
171
-
172
-
173
- setNestedValue(obj: any, column: any, option: any, calledFromInput = false): void {
174
- if (column.type === 'date' || column.type === 'image') return;
175
- const path = column.field;
176
- if (!path) return;
177
- const keys = path.split('.');
178
- const lastKey = keys.pop();
179
- const parent = keys.reduce((acc: any, key: string) => (acc[key] ??= {}), obj);
180
- if (parent && lastKey) {
181
- if (typeof option === 'object' && option !== null) {
182
- parent[lastKey] = {
183
- id: option.id ?? 1,
184
- value: option.value ?? option,
185
- };
186
- } else {
187
- parent[lastKey] = option;
188
- }
189
- }
190
- const sendObj = {
191
- data: { ...obj },
192
- eventType: 'onCellEdit',
193
- };
194
- this.updateRows.push(obj);
195
- }
196
-
197
-
198
- cutSelectedSelectedData(
199
- dataSet: any[],
200
- rowSelectedIndexes: Set<number>,
201
- selectedCells: any[],
202
- columns: any[],
203
- setNestedValue: (obj: any, column: any, value: any) => void
204
- ): any {
205
- let updatedData = [...dataSet];
206
- if (rowSelectedIndexes?.size) {
207
- const indexes = [...rowSelectedIndexes];
208
- updatedData = updatedData.filter(
209
- (row: any) => !indexes.includes(row.__virtualIndex)
210
- );
211
- // rowSelectedIndexes.clear();
212
- }
213
- else if (selectedCells?.length) {
214
- this.updateRows = [];
215
- for (const cell of selectedCells) {
216
- const row = updatedData.find(r => r.__virtualIndex === cell.rowIndex);
217
- if (!row) continue;
218
- let col = columns[cell.colIndex];
219
- if (col?.children && col.children[cell.subColIndex]) {
220
- col = col.children[cell.subColIndex];
221
- }
222
- this.setNestedValue(row, col, '');
223
- }
224
- // selectedCells.length = 0;
225
- }
226
- return {updatedData: updatedData, updatedRows: this.updateRows};
227
- }
228
-
229
-
230
- cutWithAnimation(
231
- selectedData: any[][],
232
- selector = '.selected-cell, .active-cell, .row-selected'
233
- ): void {
234
- if (!selectedData || selectedData.length === 0) return;
235
-
236
- const textToCopy = selectedData
237
- .map(row => row.map(cell => (cell ?? '').toString()).join('\t'))
238
- .join('\n');
239
-
240
- navigator.clipboard.writeText(textToCopy).catch(err => console.error(err));
241
-
242
- // Apply red cut animation
243
- const selectedEls = document.querySelectorAll(selector);
244
- selectedEls.forEach(el => el.classList.add('cut-flash-bg'));
245
- setTimeout(() => {
246
- selectedEls.forEach(el => el.classList.remove('cut-flash-bg'));
247
- }, 1000);
248
- }
249
-
250
-
251
- }
@@ -1,16 +0,0 @@
1
- /* tslint:disable:no-unused-variable */
2
-
3
- import { TestBed, async, inject } from '@angular/core/testing';
4
- import { DragDrpService } from './drag-drp.service';
5
-
6
- describe('Service: DragDrp', () => {
7
- beforeEach(() => {
8
- TestBed.configureTestingModule({
9
- providers: [DragDrpService]
10
- });
11
- });
12
-
13
- it('should ...', inject([DragDrpService], (service: DragDrpService) => {
14
- expect(service).toBeTruthy();
15
- }));
16
- });
@@ -1,58 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { moveItemInArray } from '@angular/cdk/drag-drop';
3
-
4
- @Injectable({
5
- providedIn: 'root',
6
- })
7
- export class DragDrpService {
8
- constructor() {}
9
-
10
- // sortChildColumnInGroup(
11
- // columns: any[],
12
- // draggedChild: any,
13
- // section: 'leftPinnedColumns' | 'centerColumns' | 'rightPinnedColumns',
14
- // previousIndex: number,
15
- // currentIndex: number
16
- // ): any {
17
- // const pinned =
18
- // section === 'leftPinnedColumns'
19
- // ? 'left'
20
- // : section === 'rightPinnedColumns'
21
- // ? 'right'
22
- // : null;
23
-
24
- // const group = columns.find(
25
- // (col: any) =>
26
- // Array.isArray(col.children) &&
27
- // col.children.some((child: any) => child?.field === draggedChild?.field)
28
- // );
29
-
30
- // if (!group) return;
31
-
32
- // const groupIndex = columns.findIndex((col) => col.header === group.header);
33
- // const filteredGroup = group.children.filter(
34
- // (col: any) => col.pinned === pinned
35
- // );
36
-
37
- // const prevField = filteredGroup[previousIndex]?.field;
38
- // const currField = filteredGroup[currentIndex]?.field;
39
-
40
- // const visiblePrevIndex = group.children.findIndex(
41
- // (col: any) => col.field === prevField
42
- // );
43
- // const visibleCurrIndex = group.children.findIndex(
44
- // (col: any) => col.field === currField
45
- // );
46
-
47
- // moveItemInArray(
48
- // columns[groupIndex]?.children,
49
- // visiblePrevIndex,
50
- // visibleCurrIndex
51
- // );
52
-
53
- // return {
54
- // group,
55
- // movedField: currField,
56
- // };
57
- // }
58
- }
@@ -1,16 +0,0 @@
1
- /* tslint:disable:no-unused-variable */
2
-
3
- import { TestBed, async, inject } from '@angular/core/testing';
4
- import { SplitColumnsService } from './split-columns.service';
5
-
6
- describe('Service: SplitColumns', () => {
7
- beforeEach(() => {
8
- TestBed.configureTestingModule({
9
- providers: [SplitColumnsService]
10
- });
11
- });
12
-
13
- it('should ...', inject([SplitColumnsService], (service: SplitColumnsService) => {
14
- expect(service).toBeTruthy();
15
- }));
16
- });