ms-data-grid 0.0.16 → 0.0.17
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/CHANGELOG.md +57 -0
- package/DOCUMENTATION.md +243 -0
- package/ng-package.json +10 -0
- package/package.json +33 -45
- package/src/lib/css/bootstrap.css +12043 -0
- package/src/lib/data-grid/data-grid.component.html +4806 -0
- package/src/lib/data-grid/data-grid.component.scss +1502 -0
- package/src/lib/data-grid/data-grid.component.spec.ts +28 -0
- package/src/lib/data-grid/data-grid.component.ts +4216 -0
- package/src/lib/data-grid/statuses.ts +47 -0
- package/src/lib/data-grid.module.ts +20 -0
- package/src/lib/data-grid.service.spec.ts +16 -0
- package/src/lib/data-grid.service.ts +9 -0
- package/src/lib/directives/draggable-header.directive.spec.ts +11 -0
- package/src/lib/directives/draggable-header.directive.ts +172 -0
- package/src/lib/pipes/filter.pipe.spec.ts +11 -0
- package/src/lib/pipes/filter.pipe.ts +16 -0
- package/src/lib/services/cell-selection.service.spec.ts +16 -0
- package/src/lib/services/cell-selection.service.ts +234 -0
- package/src/lib/services/common.service.spec.ts +16 -0
- package/src/lib/services/common.service.ts +239 -0
- package/src/lib/services/copy-service.service.spec.ts +16 -0
- package/src/lib/services/copy-service.service.ts +251 -0
- package/src/lib/services/drag-drp.service.spec.ts +16 -0
- package/src/lib/services/drag-drp.service.ts +58 -0
- package/src/lib/services/split-columns.service.spec.ts +16 -0
- package/src/lib/services/split-columns.service.ts +148 -0
- package/src/lib/services/swap-columns.service.spec.ts +16 -0
- package/src/lib/services/swap-columns.service.ts +162 -0
- package/{public-api.d.ts → src/public-api.ts} +8 -4
- package/tsconfig.lib.json +16 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +14 -0
- package/esm2022/lib/data-grid/data-grid.component.mjs +0 -3623
- package/esm2022/lib/data-grid/statuses.mjs +0 -44
- package/esm2022/lib/data-grid.module.mjs +0 -26
- package/esm2022/lib/data-grid.service.mjs +0 -14
- package/esm2022/lib/directives/draggable-header.directive.mjs +0 -145
- package/esm2022/lib/pipes/filter.pipe.mjs +0 -22
- package/esm2022/lib/services/common.service.mjs +0 -206
- package/esm2022/lib/services/copy-service.service.mjs +0 -221
- package/esm2022/lib/services/split-columns.service.mjs +0 -143
- package/esm2022/lib/services/swap-columns.service.mjs +0 -118
- package/esm2022/ms-data-grid.mjs +0 -5
- package/esm2022/public-api.mjs +0 -8
- package/fesm2022/ms-data-grid.mjs +0 -4546
- package/fesm2022/ms-data-grid.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/data-grid/data-grid.component.d.ts +0 -468
- package/lib/data-grid/statuses.d.ts +0 -3
- package/lib/data-grid.module.d.ts +0 -14
- package/lib/data-grid.service.d.ts +0 -6
- package/lib/directives/draggable-header.directive.d.ts +0 -31
- package/lib/pipes/filter.pipe.d.ts +0 -7
- package/lib/services/common.service.d.ts +0 -17
- package/lib/services/copy-service.service.d.ts +0 -14
- package/lib/services/split-columns.service.d.ts +0 -9
- package/lib/services/swap-columns.service.d.ts +0 -19
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Injectable({
|
|
4
|
+
providedIn: 'root',
|
|
5
|
+
})
|
|
6
|
+
export class SplitColumnsService {
|
|
7
|
+
prepareColumns(columns: any[], containerWidth: number): any {
|
|
8
|
+
const left: any[] = [];
|
|
9
|
+
const center: any[] = [];
|
|
10
|
+
const right: any[] = [];
|
|
11
|
+
|
|
12
|
+
for (const col of columns) {
|
|
13
|
+
if (col.children?.length) {
|
|
14
|
+
const leftChildren: any[] = [];
|
|
15
|
+
const centerChildren: any[] = [];
|
|
16
|
+
const rightChildren: any[] = [];
|
|
17
|
+
|
|
18
|
+
for (const child of col.children) {
|
|
19
|
+
if (child.is_visible === false) continue;
|
|
20
|
+
|
|
21
|
+
const pinned = child.pinned ?? col.pinned ?? null;
|
|
22
|
+
const childWithPinned = { ...child, pinned };
|
|
23
|
+
|
|
24
|
+
if (pinned === 'left') leftChildren.push(childWithPinned);
|
|
25
|
+
else if (pinned === 'right') rightChildren.push(childWithPinned);
|
|
26
|
+
else centerChildren.push(childWithPinned);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (leftChildren.length) {
|
|
30
|
+
left.push({ header: col.header, children: leftChildren, id: col?.id || col?._id });
|
|
31
|
+
}
|
|
32
|
+
if (centerChildren.length) {
|
|
33
|
+
center.push({
|
|
34
|
+
header: col.header,
|
|
35
|
+
children: centerChildren,
|
|
36
|
+
id: col.id || col._id,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (rightChildren.length) {
|
|
40
|
+
right.push({
|
|
41
|
+
header: col.header,
|
|
42
|
+
children: rightChildren,
|
|
43
|
+
id: col.id || col._id,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
} else if (col.is_visible !== false) {
|
|
47
|
+
const pinned = col.pinned ?? null;
|
|
48
|
+
if (pinned === 'left') left.push(col);
|
|
49
|
+
else if (pinned === 'right') right.push(col);
|
|
50
|
+
else center.push(col);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { left, center, right };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setColumnsQuery(columns: any[]) {
|
|
58
|
+
for (const col of columns) {
|
|
59
|
+
// if (col.children?.length) {
|
|
60
|
+
// for (const child of col.children) {
|
|
61
|
+
// if (!child?.query?.firt_value && !child?.query?._ids?.length) {
|
|
62
|
+
// child['query'] = {
|
|
63
|
+
// first_condition: 'contain',
|
|
64
|
+
// first_value: null,
|
|
65
|
+
// condition: 'none',
|
|
66
|
+
// second_condition: 'contain',
|
|
67
|
+
// second_value: null,
|
|
68
|
+
// _ids: [],
|
|
69
|
+
// };
|
|
70
|
+
// }
|
|
71
|
+
// }
|
|
72
|
+
// }
|
|
73
|
+
// if (!col?.query?.firt_value && !col?.query?._ids?.length) {
|
|
74
|
+
// col.query = {
|
|
75
|
+
// first_condition: 'contain',
|
|
76
|
+
// first_value: null,
|
|
77
|
+
// condition: 'none',
|
|
78
|
+
// second_condition: 'contain',
|
|
79
|
+
// second_value: null,
|
|
80
|
+
// _ids: [],
|
|
81
|
+
// };
|
|
82
|
+
// }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('Updated Columns: ', columns);
|
|
86
|
+
|
|
87
|
+
return columns;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
assignDefaultWidths(columns: any[], containerWidth: number): any[] {
|
|
91
|
+
const visibleLeafCols = this.getVisibleLeafColumns(columns);
|
|
92
|
+
|
|
93
|
+
if (!visibleLeafCols.length) return columns;
|
|
94
|
+
|
|
95
|
+
let defaultWidth = Math.floor(containerWidth / visibleLeafCols.length);
|
|
96
|
+
if (defaultWidth < 80) defaultWidth = 80;
|
|
97
|
+
|
|
98
|
+
const cloneColumns = (cols: any[]): any[] =>
|
|
99
|
+
cols.map((col) => {
|
|
100
|
+
if (col.children?.length) {
|
|
101
|
+
const newChildren = col.children.map((child: any) => {
|
|
102
|
+
// If visible → dynamic default width
|
|
103
|
+
// If invisible → fixed 150px
|
|
104
|
+
if (!child.width) {
|
|
105
|
+
if (child.is_visible === false) {
|
|
106
|
+
return { ...child, width: 150 };
|
|
107
|
+
} else {
|
|
108
|
+
return { ...child, width: defaultWidth };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { ...child };
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return { ...col, children: newChildren };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!col.width) {
|
|
118
|
+
if (col.is_visible === false) {
|
|
119
|
+
return { ...col, width: 150 };
|
|
120
|
+
} else {
|
|
121
|
+
return { ...col, width: defaultWidth };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return { ...col };
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return cloneColumns(columns);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
private getVisibleLeafColumns(columns: any[]): any[] {
|
|
133
|
+
const result: any[] = [];
|
|
134
|
+
|
|
135
|
+
for (const col of columns) {
|
|
136
|
+
if (col.children?.length) {
|
|
137
|
+
const visibleChildren = col.children.filter(
|
|
138
|
+
(c: any) => c.is_visible !== false
|
|
139
|
+
);
|
|
140
|
+
result.push(...visibleChildren);
|
|
141
|
+
} else if (col.is_visible !== false) {
|
|
142
|
+
result.push(col);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* tslint:disable:no-unused-variable */
|
|
2
|
+
|
|
3
|
+
import { TestBed, async, inject } from '@angular/core/testing';
|
|
4
|
+
import { SwapColumnsService } from './swap-columns.service';
|
|
5
|
+
|
|
6
|
+
describe('Service: SwapColumns', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
TestBed.configureTestingModule({
|
|
9
|
+
providers: [SwapColumnsService]
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should ...', inject([SwapColumnsService], (service: SwapColumnsService) => {
|
|
14
|
+
expect(service).toBeTruthy();
|
|
15
|
+
}));
|
|
16
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Injectable({
|
|
4
|
+
providedIn: 'root',
|
|
5
|
+
})
|
|
6
|
+
export class SwapColumnsService {
|
|
7
|
+
constructor() {}
|
|
8
|
+
|
|
9
|
+
deepClone(obj: any) {
|
|
10
|
+
return JSON.parse(JSON.stringify(obj));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
flattenColumnsWithPaths(columns: any[]): { col: any; path: number[] }[] {
|
|
14
|
+
const result: { col: any; path: number[] }[] = [];
|
|
15
|
+
|
|
16
|
+
const recurse = (cols: any[], currentPath: number[] = []) => {
|
|
17
|
+
cols.forEach((col, index) => {
|
|
18
|
+
const path = [...currentPath, index];
|
|
19
|
+
result.push({ col, path });
|
|
20
|
+
|
|
21
|
+
if (Array.isArray(col.children)) {
|
|
22
|
+
recurse(col.children, path);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
recurse(columns);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
findColumnByIndex(
|
|
32
|
+
columns: any[],
|
|
33
|
+
index: number,
|
|
34
|
+
flat: any[],
|
|
35
|
+
_path: number[][] = [],
|
|
36
|
+
currentPath: number[] = []
|
|
37
|
+
): { column: any; parent: any[]; path: number[] } | null {
|
|
38
|
+
for (let i = 0; i < columns.length; i++) {
|
|
39
|
+
const col = columns[i];
|
|
40
|
+
const nextPath = [...currentPath, i];
|
|
41
|
+
|
|
42
|
+
if (flat[index] === col) {
|
|
43
|
+
return { column: col, parent: columns, path: nextPath };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (Array.isArray(col?.children)) {
|
|
47
|
+
const result = this.findColumnByIndex(
|
|
48
|
+
col?.children,
|
|
49
|
+
index,
|
|
50
|
+
flat,
|
|
51
|
+
_path,
|
|
52
|
+
nextPath
|
|
53
|
+
);
|
|
54
|
+
if (result) return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
insertAtPath(columns: any[], path: number[], newColumn: any): any[] {
|
|
62
|
+
const cloned = this.deepClone(columns);
|
|
63
|
+
let current = cloned;
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
66
|
+
if (!current[path[i]]?.children) {
|
|
67
|
+
current[path[i]]!.children = [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
current = current[path[i]]?.children;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const insertIndex = path[path.length - 1];
|
|
74
|
+
current.splice(insertIndex, 0, newColumn);
|
|
75
|
+
return cloned;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
removeAtPath(columns: any[], path: number[]): any[] {
|
|
79
|
+
const cloned = this.deepClone(columns);
|
|
80
|
+
let current = cloned;
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
83
|
+
if (!current[path[i]]?.children) {
|
|
84
|
+
return cloned; // Safety: path is invalid
|
|
85
|
+
}
|
|
86
|
+
current = current[path[i]]?.children;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const removeIndex = path[path.length - 1];
|
|
90
|
+
if (Array.isArray(current) && current.length > removeIndex) {
|
|
91
|
+
current.splice(removeIndex, 1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return cloned;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
swapColumnsInTree(
|
|
98
|
+
currentColumn: any,
|
|
99
|
+
columns: any[],
|
|
100
|
+
fromIndex: number,
|
|
101
|
+
toIndex: number
|
|
102
|
+
): any[] {
|
|
103
|
+
const flat = this.flattenColumnsWithPaths(columns);
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
fromIndex < 0 ||
|
|
107
|
+
toIndex < 0 ||
|
|
108
|
+
fromIndex >= flat.length ||
|
|
109
|
+
toIndex >= flat.length
|
|
110
|
+
) {
|
|
111
|
+
return columns; // invalid indices
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const fromInfo = this.findColumnByIndex(columns, fromIndex, flat);
|
|
115
|
+
const toInfo = this.findColumnByIndex(columns, toIndex, flat);
|
|
116
|
+
|
|
117
|
+
if (!fromInfo || !toInfo) return columns;
|
|
118
|
+
|
|
119
|
+
const fromCol = fromInfo.column;
|
|
120
|
+
const toCol = toInfo.column;
|
|
121
|
+
|
|
122
|
+
let updatedCols = this.removeAtPath(columns, fromInfo.path);
|
|
123
|
+
|
|
124
|
+
// Case 1: Same parent
|
|
125
|
+
if (
|
|
126
|
+
JSON.stringify(fromInfo.path.slice(0, -1)) ===
|
|
127
|
+
JSON.stringify(toInfo.path.slice(0, -1))
|
|
128
|
+
) {
|
|
129
|
+
return this.insertAtPath(updatedCols, toInfo.path, fromCol);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Case 2: Drop target is a group header
|
|
133
|
+
if (Array.isArray(toCol?.children)) {
|
|
134
|
+
const cloned = this.deepClone(updatedCols);
|
|
135
|
+
let parent = cloned;
|
|
136
|
+
|
|
137
|
+
for (let i = 0; i < toInfo.path.length - 1; i++) {
|
|
138
|
+
parent = parent[toInfo.path[i]].children;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const target = parent[toInfo.path[toInfo.path.length - 1]];
|
|
142
|
+
if (!target.children) {
|
|
143
|
+
target.children = [];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
target.children.push(fromCol);
|
|
147
|
+
return cloned;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Case 3: Drop target is a regular column → wrap both into a group
|
|
151
|
+
const groupHeader = {
|
|
152
|
+
headerName: toCol.headerName || 'Group',
|
|
153
|
+
children: [toCol, fromCol],
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Remove target from its original location
|
|
157
|
+
updatedCols = this.removeAtPath(updatedCols, toInfo.path);
|
|
158
|
+
|
|
159
|
+
// Insert group at target index
|
|
160
|
+
return this.insertAtPath(updatedCols, toInfo.path, groupHeader);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of data-grid
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export * from './lib/data-grid.service';
|
|
6
|
+
export * from './lib/data-grid.module';
|
|
7
|
+
export * from './lib/data-grid/data-grid.component';
|
|
8
|
+
export * from './lib/directives/draggable-header.directive';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
|
2
|
+
{
|
|
3
|
+
"extends": "../../tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"outDir": "../../out-tsc/lib",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"inlineSources": true,
|
|
9
|
+
"types": [],
|
|
10
|
+
"target": "es2019",
|
|
11
|
+
"lib": ["es2019", "dom"]
|
|
12
|
+
},
|
|
13
|
+
"exclude": [
|
|
14
|
+
"**/*.spec.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
|
2
|
+
{
|
|
3
|
+
"extends": "../../tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"outDir": "../../out-tsc/spec",
|
|
6
|
+
"types": [
|
|
7
|
+
"jasmine"
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"**/*.spec.ts",
|
|
12
|
+
"**/*.d.ts"
|
|
13
|
+
]
|
|
14
|
+
}
|