@oscarpalmer/tabela 0.13.0 → 0.15.0
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/components/body.component.d.mts +10 -1
- package/dist/components/body.component.mjs +8 -6
- package/dist/components/column.component.d.mts +15 -1
- package/dist/components/column.component.mjs +12 -10
- package/dist/components/footer.component.d.mts +12 -1
- package/dist/components/footer.component.mjs +6 -6
- package/dist/components/group.component.d.mts +19 -1
- package/dist/components/group.component.mjs +17 -11
- package/dist/components/header.component.d.mts +12 -1
- package/dist/components/header.component.mjs +5 -5
- package/dist/components/row.component.d.mts +14 -1
- package/dist/components/row.component.mjs +21 -17
- package/dist/helpers/dom.helpers.d.mts +3 -3
- package/dist/helpers/dom.helpers.mjs +12 -11
- package/dist/helpers/misc.helpers.d.mts +7 -1
- package/dist/helpers/misc.helpers.mjs +12 -1
- package/dist/index.d.mts +1 -1
- package/dist/managers/column.manager.d.mts +16 -1
- package/dist/managers/column.manager.mjs +7 -7
- package/dist/managers/data.manager.d.mts +26 -1
- package/dist/managers/data.manager.mjs +122 -88
- package/dist/managers/event.manager.d.mts +17 -1
- package/dist/managers/event.manager.mjs +35 -10
- package/dist/managers/filter.manager.d.mts +17 -1
- package/dist/managers/filter.manager.mjs +43 -35
- package/dist/managers/group.manager.d.mts +26 -1
- package/dist/managers/group.manager.mjs +36 -16
- package/dist/managers/navigation.manager.d.mts +15 -2
- package/dist/managers/navigation.manager.mjs +38 -34
- package/dist/managers/render.manager.d.mts +18 -1
- package/dist/managers/render.manager.mjs +44 -31
- package/dist/managers/row.manager.d.mts +18 -1
- package/dist/managers/row.manager.mjs +1 -1
- package/dist/managers/selection.manager.d.mts +22 -1
- package/dist/managers/selection.manager.mjs +26 -23
- package/dist/managers/sort.manager.d.mts +22 -1
- package/dist/managers/sort.manager.mjs +71 -49
- package/dist/managers/style.manager.d.mts +8 -1
- package/dist/managers/style.manager.mjs +57 -25
- package/dist/models/body.model.d.mts +6 -1
- package/dist/models/column.model.d.mts +13 -2
- package/dist/models/data.model.d.mts +28 -2
- package/dist/models/dom.model.d.mts +19 -0
- package/dist/models/dom.model.mjs +19 -0
- package/dist/models/event.model.d.mts +99 -0
- package/dist/models/event.model.mjs +53 -0
- package/dist/models/filter.model.d.mts +26 -2
- package/dist/models/filter.model.mjs +13 -1
- package/dist/models/footer.model.d.mts +7 -1
- package/dist/models/group.model.d.mts +19 -2
- package/dist/models/group.model.mjs +5 -1
- package/dist/models/header.model.d.mts +6 -1
- package/dist/models/render.model.d.mts +22 -2
- package/dist/models/selection.model.d.mts +11 -1
- package/dist/models/sort.model.d.mts +19 -2
- package/dist/models/sort.model.mjs +5 -1
- package/dist/models/style.model.d.mts +27 -21
- package/dist/models/style.model.mjs +27 -21
- package/dist/models/tabela.model.d.mts +45 -1
- package/dist/models/tabela.options.d.mts +13 -1
- package/dist/tabela.d.mts +9 -8
- package/dist/tabela.full.mjs +1083 -574
- package/dist/tabela.mjs +19 -19
- package/package.json +2 -4
- package/src/components/body.component.ts +10 -7
- package/src/components/column.component.ts +20 -16
- package/src/components/footer.component.ts +7 -10
- package/src/components/group.component.ts +39 -13
- package/src/components/header.component.ts +6 -5
- package/src/components/row.component.ts +27 -19
- package/src/helpers/dom.helpers.ts +18 -22
- package/src/helpers/misc.helpers.ts +17 -0
- package/src/managers/column.manager.ts +9 -9
- package/src/managers/data.manager.ts +196 -107
- package/src/managers/event.manager.ts +69 -12
- package/src/managers/filter.manager.ts +70 -41
- package/src/managers/group.manager.ts +60 -18
- package/src/managers/navigation.manager.ts +46 -49
- package/src/managers/render.manager.ts +60 -34
- package/src/managers/row.manager.ts +1 -1
- package/src/managers/selection.manager.ts +37 -35
- package/src/managers/sort.manager.ts +114 -72
- package/src/managers/style.manager.ts +73 -25
- package/src/models/column.model.ts +4 -8
- package/src/models/data.model.ts +13 -14
- package/src/models/dom.model.ts +31 -0
- package/src/models/event.model.ts +175 -0
- package/src/models/filter.model.ts +22 -2
- package/src/models/group.model.ts +13 -0
- package/src/models/render.model.ts +6 -0
- package/src/models/sort.model.ts +11 -5
- package/src/models/style.model.ts +32 -20
- package/src/models/tabela.model.ts +1 -0
- package/src/tabela.ts +26 -24
- package/dist/body.component-_VDOpJhV.d.mts +0 -10
- package/dist/body.model-2iwsovAV.d.mts +0 -7
- package/dist/column.component-Bx46r3JI.d.mts +0 -16
- package/dist/column.model-D-aw4EU4.d.mts +0 -16
- package/dist/filter.model-7ukJrtil.d.mts +0 -16
- package/dist/footer.component-Curiab8j.d.mts +0 -12
- package/dist/footer.model-DhqoS6ds.d.mts +0 -8
- package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
- package/dist/group.model-BsKFwHbt.d.mts +0 -10
- package/dist/header.component-BjjlpZIg.d.mts +0 -12
- package/dist/header.model-DN_KzUCV.d.mts +0 -7
- package/dist/selection.model-rwQe9fco.d.mts +0 -12
- package/dist/sort.model-CauImaLu.d.mts +0 -15
- package/dist/tabela.options-RkZvfptB.d.mts +0 -14
|
@@ -5,36 +5,48 @@ import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
|
5
5
|
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
6
6
|
import {delay} from '@oscarpalmer/atoms/promise/delay';
|
|
7
7
|
import {getValue} from '@oscarpalmer/atoms/value/handle';
|
|
8
|
+
import type {ColumnComponent} from '../components/column.component';
|
|
8
9
|
import {GroupComponent, updateGroup} from '../components/group.component';
|
|
9
|
-
import
|
|
10
|
+
import {getGroup, isGroupKey} from '../helpers/misc.helpers';
|
|
11
|
+
import type {DataState, DataValue, TabelaData} from '../models/data.model';
|
|
12
|
+
import {
|
|
13
|
+
EVENT_DATA_ADD,
|
|
14
|
+
EVENT_DATA_CLEAR,
|
|
15
|
+
EVENT_DATA_REMOVE,
|
|
16
|
+
EVENT_DATA_SYNCHRONIZE,
|
|
17
|
+
EVENT_DATA_UPDATE,
|
|
18
|
+
EVENT_GROUP_ADD,
|
|
19
|
+
EVENT_GROUP_REMOVE,
|
|
20
|
+
EVENT_GROUP_UPDATE,
|
|
21
|
+
} from '../models/event.model';
|
|
22
|
+
import {SORT_ASCENDING} from '../models/sort.model';
|
|
10
23
|
import type {State} from '../models/tabela.model';
|
|
11
24
|
import {sortWithGroups} from './sort.manager';
|
|
12
|
-
import type {ColumnComponent} from '../components/column.component';
|
|
13
25
|
|
|
14
26
|
export class DataManager {
|
|
15
|
-
handlers =
|
|
16
|
-
add: data =>
|
|
17
|
-
clear: () =>
|
|
27
|
+
handlers: TabelaData = {
|
|
28
|
+
add: data => this.add(data, true),
|
|
29
|
+
clear: () => this.clear(),
|
|
18
30
|
get: active => this.get(active),
|
|
19
|
-
remove: items =>
|
|
20
|
-
synchronize: (data, remove) =>
|
|
21
|
-
update: data =>
|
|
22
|
-
}
|
|
31
|
+
remove: items => this.remove(items, true),
|
|
32
|
+
synchronize: (data, remove) => this.synchronize(data, remove === true),
|
|
33
|
+
update: data => this.update(data, true),
|
|
34
|
+
};
|
|
23
35
|
|
|
24
36
|
state: DataState;
|
|
25
37
|
|
|
26
|
-
get
|
|
27
|
-
return this.state.
|
|
38
|
+
get keys(): Key[] {
|
|
39
|
+
return this.state.keys.active ?? this.state.keys.original;
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
get size(): number {
|
|
31
|
-
return this.
|
|
43
|
+
return this.keys.length;
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
constructor(state: State) {
|
|
35
47
|
this.state = {
|
|
36
48
|
...state,
|
|
37
|
-
|
|
49
|
+
keys: {
|
|
38
50
|
original: [],
|
|
39
51
|
},
|
|
40
52
|
values: {
|
|
@@ -47,8 +59,11 @@ export class DataManager {
|
|
|
47
59
|
async add(data: PlainObject[], render: boolean): Promise<void> {
|
|
48
60
|
const {state} = this;
|
|
49
61
|
|
|
50
|
-
const
|
|
51
|
-
const
|
|
62
|
+
const addedData: PlainObject[] = [];
|
|
63
|
+
const updatedData: PlainObject[] = [];
|
|
64
|
+
|
|
65
|
+
const addedGroups: GroupComponent[] = [];
|
|
66
|
+
const updatedGroups: GroupComponent[] = [];
|
|
52
67
|
|
|
53
68
|
let groupColumn: ColumnComponent | undefined;
|
|
54
69
|
let {length} = data;
|
|
@@ -58,11 +73,13 @@ export class DataManager {
|
|
|
58
73
|
const key = getValue(item, state.key) as Key;
|
|
59
74
|
|
|
60
75
|
if (state.values.mapped.has(key)) {
|
|
61
|
-
|
|
76
|
+
updatedData.push(item);
|
|
62
77
|
|
|
63
78
|
continue;
|
|
64
79
|
}
|
|
65
80
|
|
|
81
|
+
addedData.push(item);
|
|
82
|
+
|
|
66
83
|
state.values.array.push(item);
|
|
67
84
|
state.values.mapped.set(key, item);
|
|
68
85
|
|
|
@@ -70,20 +87,24 @@ export class DataManager {
|
|
|
70
87
|
continue;
|
|
71
88
|
}
|
|
72
89
|
|
|
73
|
-
const groupValue = getValue(item, state.managers.group.
|
|
90
|
+
const groupValue = getValue(item, state.managers.group.key) as Key;
|
|
74
91
|
|
|
75
|
-
let group = state.managers.group.
|
|
92
|
+
let group = state.managers.group.getForValue(groupValue);
|
|
76
93
|
|
|
77
94
|
if (group == null) {
|
|
78
|
-
groupColumn ??= state.managers.column.get(state.managers.group.
|
|
95
|
+
groupColumn ??= state.managers.column.get(state.managers.group.key);
|
|
79
96
|
|
|
80
97
|
group = new GroupComponent(
|
|
81
|
-
`${groupColumn?.options.
|
|
98
|
+
`${groupColumn?.options.label ?? state.managers.group.key}: ${groupValue}`,
|
|
82
99
|
groupValue,
|
|
83
100
|
);
|
|
84
101
|
|
|
85
|
-
state.values.array.push(group);
|
|
86
|
-
state.managers.group.add(group);
|
|
102
|
+
state.values.array.push(group.key);
|
|
103
|
+
state.managers.group.add(group, false);
|
|
104
|
+
|
|
105
|
+
addedGroups.push(group);
|
|
106
|
+
} else if (!addedGroups.includes(group) && !updatedGroups.includes(group)) {
|
|
107
|
+
updatedGroups.push(group);
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
if (!group.expanded) {
|
|
@@ -91,26 +112,44 @@ export class DataManager {
|
|
|
91
112
|
}
|
|
92
113
|
|
|
93
114
|
group.total += 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
length = addedGroups.length;
|
|
118
|
+
|
|
119
|
+
if (length > 0) {
|
|
120
|
+
state.managers.event.emit(EVENT_GROUP_ADD, addedGroups.map(getGroup));
|
|
94
121
|
|
|
95
|
-
|
|
122
|
+
for (let index = 0; index < length; index += 1) {
|
|
123
|
+
updateGroup(state, addedGroups[index], false);
|
|
124
|
+
}
|
|
96
125
|
}
|
|
97
126
|
|
|
98
|
-
length =
|
|
127
|
+
length = updatedGroups.length;
|
|
99
128
|
|
|
100
|
-
|
|
101
|
-
|
|
129
|
+
if (length > 0) {
|
|
130
|
+
for (let index = 0; index < length; index += 1) {
|
|
131
|
+
updateGroup(state, updatedGroups[index], false);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
state.managers.event.emit(EVENT_GROUP_UPDATE, updatedGroups.map(getGroup));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
await this.update(updatedData, addedData.length === 0);
|
|
138
|
+
|
|
139
|
+
if (addedData.length === 0) {
|
|
140
|
+
return;
|
|
102
141
|
}
|
|
103
142
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
143
|
+
state.managers.event.emit(EVENT_DATA_ADD, addedData);
|
|
144
|
+
|
|
145
|
+
if (render) {
|
|
107
146
|
this.render();
|
|
108
147
|
}
|
|
109
148
|
}
|
|
110
149
|
|
|
111
|
-
clear(): void {
|
|
150
|
+
async clear(): Promise<void> {
|
|
112
151
|
if (this.state.values.array.length > 0) {
|
|
113
|
-
|
|
152
|
+
return this.removeItems([], true, true).then(() => undefined);
|
|
114
153
|
}
|
|
115
154
|
}
|
|
116
155
|
|
|
@@ -119,8 +158,8 @@ export class DataManager {
|
|
|
119
158
|
|
|
120
159
|
state.values.mapped.clear();
|
|
121
160
|
|
|
122
|
-
state.
|
|
123
|
-
state.
|
|
161
|
+
state.keys.active = undefined;
|
|
162
|
+
state.keys.original.length = 0;
|
|
124
163
|
state.values.array.length = 0;
|
|
125
164
|
|
|
126
165
|
this.handlers = undefined as never;
|
|
@@ -130,45 +169,49 @@ export class DataManager {
|
|
|
130
169
|
get(active?: boolean): PlainObject[] {
|
|
131
170
|
const {state} = this;
|
|
132
171
|
|
|
133
|
-
return (active ?? false)
|
|
172
|
+
return (active ?? false) && state.keys.active != null
|
|
134
173
|
? select(
|
|
135
|
-
state.
|
|
136
|
-
key => !(key
|
|
174
|
+
state.keys.active,
|
|
175
|
+
key => !isGroupKey(key),
|
|
137
176
|
key => state.values.mapped.get(key as Key)!,
|
|
138
177
|
)
|
|
139
|
-
: (state.values.array.filter(item => !(item
|
|
178
|
+
: (state.values.array.filter(item => !isGroupKey(item)) as PlainObject[]);
|
|
140
179
|
}
|
|
141
180
|
|
|
142
|
-
getIndex(item:
|
|
143
|
-
|
|
144
|
-
return this.items.indexOf(item);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return this.items.findIndex(value =>
|
|
148
|
-
value instanceof GroupComponent ? value.key === item : value === item,
|
|
149
|
-
);
|
|
181
|
+
getIndex(item: Key): number {
|
|
182
|
+
return this.keys.indexOf(item);
|
|
150
183
|
}
|
|
151
184
|
|
|
152
|
-
async remove(items: Array<Key | PlainObject>, render:
|
|
185
|
+
async remove(items: Array<Key | PlainObject>, render: false): Promise<PlainObject[]>;
|
|
186
|
+
|
|
187
|
+
async remove(items: Array<Key | PlainObject>, render: true): Promise<void>;
|
|
188
|
+
|
|
189
|
+
async remove(items: Array<Key | PlainObject>, render: boolean): Promise<unknown> {
|
|
153
190
|
const {state} = this;
|
|
154
191
|
|
|
155
|
-
const keys = items
|
|
156
|
-
value => (isPlainObject(value) ? getValue(value, state.key) : value) as Key
|
|
157
|
-
|
|
192
|
+
const keys = items
|
|
193
|
+
.map(value => (isPlainObject(value) ? getValue(value, state.key) : value) as Key)
|
|
194
|
+
.filter(key => !isGroupKey(key));
|
|
158
195
|
|
|
159
196
|
const {length} = keys;
|
|
160
197
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
return length === 0
|
|
199
|
+
? render
|
|
200
|
+
? undefined
|
|
201
|
+
: []
|
|
202
|
+
: this.removeItems(keys, false, render as never);
|
|
164
203
|
}
|
|
165
204
|
|
|
166
|
-
async removeItems(
|
|
205
|
+
async removeItems(data: Key[], clear: boolean, render: false): Promise<PlainObject[]>;
|
|
206
|
+
|
|
207
|
+
async removeItems(data: Key[], clear: boolean, render: true): Promise<void>;
|
|
208
|
+
|
|
209
|
+
async removeItems(keys: Key[], clear: boolean, render: boolean): Promise<unknown> {
|
|
167
210
|
const {state} = this;
|
|
168
211
|
|
|
169
212
|
if (clear) {
|
|
170
|
-
state.
|
|
171
|
-
state.
|
|
213
|
+
state.keys.active = undefined;
|
|
214
|
+
state.keys.original = [];
|
|
172
215
|
state.values.array = [];
|
|
173
216
|
|
|
174
217
|
state.values.mapped.clear();
|
|
@@ -179,39 +222,48 @@ export class DataManager {
|
|
|
179
222
|
state.managers.group.clear();
|
|
180
223
|
}
|
|
181
224
|
|
|
182
|
-
|
|
225
|
+
state.managers.event.emit(EVENT_DATA_CLEAR);
|
|
226
|
+
|
|
227
|
+
this.render();
|
|
228
|
+
|
|
229
|
+
return render ? undefined : [];
|
|
183
230
|
}
|
|
184
231
|
|
|
185
|
-
const
|
|
232
|
+
const removedGroups: GroupComponent[] = [];
|
|
233
|
+
const updatedGroups: GroupComponent[] = [];
|
|
234
|
+
|
|
235
|
+
const removedData: PlainObject[] = [];
|
|
186
236
|
|
|
187
|
-
const chunked = chunk(
|
|
237
|
+
const chunked = chunk(keys);
|
|
188
238
|
const chunkedLength = chunked.length;
|
|
189
239
|
|
|
190
240
|
for (let chunkedIndex = 0; chunkedIndex < chunkedLength; chunkedIndex += 1) {
|
|
191
241
|
const chunk = chunked[chunkedIndex];
|
|
192
242
|
const chunkLength = chunk.length;
|
|
193
243
|
|
|
194
|
-
for (let
|
|
195
|
-
const
|
|
196
|
-
const dataIndex = state.
|
|
244
|
+
for (let keyIndex = 0; keyIndex < chunkLength; keyIndex += 1) {
|
|
245
|
+
const key = chunk[keyIndex];
|
|
246
|
+
const dataIndex = state.keys.original.indexOf(key);
|
|
197
247
|
|
|
198
248
|
let dataValue: PlainObject | undefined;
|
|
199
249
|
|
|
200
250
|
[dataValue] = state.values.array.splice(dataIndex, 1) as PlainObject[];
|
|
201
251
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
state.
|
|
252
|
+
removedData.push(dataValue);
|
|
253
|
+
|
|
254
|
+
state.keys.original.splice(dataIndex, 1);
|
|
255
|
+
state.managers.row.remove(key as never);
|
|
256
|
+
state.values.mapped.delete(key as Key);
|
|
205
257
|
|
|
206
|
-
if (!state.managers.group.enabled ||
|
|
258
|
+
if (!state.managers.group.enabled || isGroupKey(key)) {
|
|
207
259
|
continue;
|
|
208
260
|
}
|
|
209
261
|
|
|
210
|
-
state.managers.group.collapsed.delete(
|
|
262
|
+
state.managers.group.collapsed.delete(key as never);
|
|
211
263
|
|
|
212
|
-
const
|
|
264
|
+
const groupValue = getValue(dataValue, state.managers.group.key) as unknown;
|
|
213
265
|
|
|
214
|
-
const group = state.managers.group.
|
|
266
|
+
const group = state.managers.group.getForValue(groupValue);
|
|
215
267
|
|
|
216
268
|
if (group == null) {
|
|
217
269
|
continue;
|
|
@@ -220,41 +272,57 @@ export class DataManager {
|
|
|
220
272
|
group.total -= 1;
|
|
221
273
|
|
|
222
274
|
if (group.total > 0) {
|
|
223
|
-
|
|
275
|
+
updatedGroups.push(group);
|
|
224
276
|
|
|
225
277
|
continue;
|
|
226
278
|
}
|
|
227
279
|
|
|
228
|
-
let groupIndex =
|
|
280
|
+
let groupIndex = updatedGroups.indexOf(group);
|
|
229
281
|
|
|
230
282
|
if (groupIndex > -1) {
|
|
231
|
-
|
|
283
|
+
updatedGroups.splice(groupIndex, 1);
|
|
232
284
|
}
|
|
233
285
|
|
|
234
|
-
groupIndex = state.values.array.indexOf(group);
|
|
286
|
+
groupIndex = state.values.array.indexOf(group.key);
|
|
235
287
|
|
|
236
288
|
if (groupIndex > -1) {
|
|
237
|
-
state.
|
|
289
|
+
state.keys.original.splice(groupIndex, 1);
|
|
238
290
|
state.values.array.splice(groupIndex, 1);
|
|
239
291
|
}
|
|
240
292
|
|
|
241
|
-
|
|
293
|
+
removedGroups.push(group);
|
|
242
294
|
|
|
243
|
-
|
|
295
|
+
state.managers.group.remove(group, false);
|
|
296
|
+
|
|
297
|
+
if (keys.length >= 10_000) {
|
|
244
298
|
await delay(25);
|
|
245
299
|
}
|
|
246
300
|
}
|
|
247
301
|
}
|
|
248
302
|
|
|
249
|
-
|
|
303
|
+
let {length} = updatedGroups;
|
|
250
304
|
|
|
251
|
-
|
|
252
|
-
|
|
305
|
+
if (length > 0) {
|
|
306
|
+
for (let index = 0; index < length; index += 1) {
|
|
307
|
+
updateGroup(state, updatedGroups[index], false);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
state.managers.event.emit(EVENT_GROUP_UPDATE, updatedGroups.map(getGroup));
|
|
253
311
|
}
|
|
254
312
|
|
|
313
|
+
length = removedGroups.length;
|
|
314
|
+
|
|
315
|
+
if (length > 0) {
|
|
316
|
+
state.managers.event.emit(EVENT_GROUP_REMOVE, removedGroups.map(getGroup));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
state.managers.event.emit(EVENT_DATA_REMOVE, removedData);
|
|
320
|
+
|
|
255
321
|
if (render) {
|
|
256
|
-
|
|
322
|
+
this.render();
|
|
257
323
|
}
|
|
324
|
+
|
|
325
|
+
return render ? undefined : removedData;
|
|
258
326
|
}
|
|
259
327
|
|
|
260
328
|
render(): void {
|
|
@@ -263,25 +331,27 @@ export class DataManager {
|
|
|
263
331
|
if (state.managers.group.enabled) {
|
|
264
332
|
sortWithGroups(state, state.values.array, [
|
|
265
333
|
{
|
|
266
|
-
direction:
|
|
334
|
+
direction: SORT_ASCENDING,
|
|
267
335
|
key: state.key,
|
|
268
336
|
},
|
|
269
337
|
]);
|
|
270
338
|
} else {
|
|
271
339
|
sort(state.values.array as PlainObject[], [
|
|
272
340
|
{
|
|
273
|
-
direction:
|
|
341
|
+
direction: SORT_ASCENDING,
|
|
274
342
|
key: state.key,
|
|
275
343
|
},
|
|
276
344
|
]);
|
|
277
345
|
}
|
|
278
346
|
|
|
279
|
-
state.
|
|
280
|
-
|
|
347
|
+
state.keys.active = undefined;
|
|
348
|
+
|
|
349
|
+
state.keys.original = state.values.array.map(item =>
|
|
350
|
+
typeof item === 'string' ? item : (getValue(item, state.key) as Key),
|
|
281
351
|
);
|
|
282
352
|
|
|
283
353
|
state.values.mapped = toMap(
|
|
284
|
-
state.values.array.filter(item => !(item
|
|
354
|
+
state.values.array.filter(item => !isGroupKey(item)) as PlainObject[],
|
|
285
355
|
item => getValue(item, state.key) as Key,
|
|
286
356
|
);
|
|
287
357
|
|
|
@@ -297,12 +367,12 @@ export class DataManager {
|
|
|
297
367
|
set(data: PlainObject[]): void {
|
|
298
368
|
const {state} = this;
|
|
299
369
|
|
|
300
|
-
const array:
|
|
370
|
+
const array: DataValue[] = data.slice();
|
|
301
371
|
|
|
302
372
|
if (state.managers.group.enabled) {
|
|
303
|
-
const column = state.managers.column.get(state.managers.group.
|
|
373
|
+
const column = state.managers.column.get(state.managers.group.key);
|
|
304
374
|
|
|
305
|
-
const grouped = toRecord.arrays(data, state.managers.group.
|
|
375
|
+
const grouped = toRecord.arrays(data, state.managers.group.key) as Record<
|
|
306
376
|
string,
|
|
307
377
|
PlainObject[]
|
|
308
378
|
>;
|
|
@@ -316,7 +386,7 @@ export class DataManager {
|
|
|
316
386
|
const [value, items] = entries[index];
|
|
317
387
|
|
|
318
388
|
const group = new GroupComponent(
|
|
319
|
-
`${column?.options.
|
|
389
|
+
`${column?.options.label ?? state.managers.group.key}: ${value}`,
|
|
320
390
|
value,
|
|
321
391
|
);
|
|
322
392
|
|
|
@@ -324,7 +394,7 @@ export class DataManager {
|
|
|
324
394
|
|
|
325
395
|
groups.push(group);
|
|
326
396
|
|
|
327
|
-
array.push(group);
|
|
397
|
+
array.push(group.key);
|
|
328
398
|
}
|
|
329
399
|
|
|
330
400
|
state.managers.group.set(groups);
|
|
@@ -335,10 +405,10 @@ export class DataManager {
|
|
|
335
405
|
this.render();
|
|
336
406
|
}
|
|
337
407
|
|
|
338
|
-
async synchronize(data: PlainObject[], remove
|
|
408
|
+
async synchronize(data: PlainObject[], remove: boolean): Promise<void> {
|
|
339
409
|
const {state} = this;
|
|
340
410
|
|
|
341
|
-
const
|
|
411
|
+
const added: PlainObject[] = [];
|
|
342
412
|
const updated: PlainObject[] = [];
|
|
343
413
|
|
|
344
414
|
const keys = new Set<Key>([]);
|
|
@@ -352,7 +422,7 @@ export class DataManager {
|
|
|
352
422
|
if (state.values.mapped.has(key)) {
|
|
353
423
|
updated.push(object);
|
|
354
424
|
} else {
|
|
355
|
-
|
|
425
|
+
added.push(object);
|
|
356
426
|
}
|
|
357
427
|
|
|
358
428
|
keys.add(key);
|
|
@@ -362,43 +432,62 @@ export class DataManager {
|
|
|
362
432
|
return;
|
|
363
433
|
}
|
|
364
434
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
435
|
+
let removed: PlainObject[] = [];
|
|
436
|
+
|
|
437
|
+
if (remove) {
|
|
438
|
+
const toRemove = state.keys.original.filter(
|
|
439
|
+
key => !isGroupKey(key) && !keys.has(key),
|
|
368
440
|
) as Key[];
|
|
369
441
|
|
|
370
442
|
if (toRemove.length > 0) {
|
|
371
|
-
await this.remove(toRemove, false);
|
|
443
|
+
removed = await this.remove(toRemove, false);
|
|
372
444
|
}
|
|
373
445
|
}
|
|
374
446
|
|
|
375
|
-
await this.update(updated);
|
|
447
|
+
await this.update(updated, added.length === 0);
|
|
376
448
|
|
|
377
|
-
|
|
378
|
-
await this.add(add, false);
|
|
379
|
-
}
|
|
449
|
+
await this.add(added, false);
|
|
380
450
|
|
|
381
|
-
|
|
451
|
+
state.managers.event.emit(EVENT_DATA_SYNCHRONIZE, {
|
|
452
|
+
added,
|
|
453
|
+
removed,
|
|
454
|
+
updated,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
if (added.length > 0 || remove) {
|
|
382
458
|
this.render();
|
|
383
459
|
}
|
|
384
460
|
}
|
|
385
461
|
|
|
386
|
-
async update(data: PlainObject[]): Promise<void> {
|
|
462
|
+
async update(data: PlainObject[], render: boolean): Promise<void> {
|
|
387
463
|
const {state} = this;
|
|
388
464
|
|
|
389
465
|
const {length} = data;
|
|
390
466
|
|
|
467
|
+
const updated: PlainObject[] = [];
|
|
468
|
+
|
|
391
469
|
for (let index = 0; index < length; index += 1) {
|
|
392
|
-
const
|
|
470
|
+
const item = data[index];
|
|
393
471
|
|
|
394
|
-
const key = getValue(
|
|
395
|
-
|
|
472
|
+
const key = getValue(item, state.key) as Key;
|
|
473
|
+
|
|
474
|
+
const existing = state.keys.original.indexOf(key);
|
|
475
|
+
|
|
476
|
+
if (existing === -1) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
Object.assign(state.values.array[existing], item);
|
|
396
481
|
|
|
397
|
-
|
|
398
|
-
state.values.mapped.set(key, {...value, ...object} as PlainObject);
|
|
482
|
+
updated.push(state.values.array[existing] as PlainObject);
|
|
399
483
|
|
|
484
|
+
if (render && state.managers.render.visible.keys.has(key)) {
|
|
400
485
|
state.managers.row.update(key);
|
|
401
486
|
}
|
|
402
487
|
}
|
|
488
|
+
|
|
489
|
+
if (updated.length > 0) {
|
|
490
|
+
state.managers.event.emit(EVENT_DATA_UPDATE, updated);
|
|
491
|
+
}
|
|
403
492
|
}
|
|
404
493
|
}
|
|
@@ -1,12 +1,49 @@
|
|
|
1
|
+
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
1
2
|
import {on} from '@oscarpalmer/toretto/event';
|
|
2
3
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
4
|
+
import {isEvent} from '../helpers/misc.helpers';
|
|
5
|
+
import {
|
|
6
|
+
ATTRIBUTE_DATA_EVENT,
|
|
7
|
+
ATTRIBUTE_DATA_KEY,
|
|
8
|
+
ATTRIBUTE_DATA_SORT_DIRECTION,
|
|
9
|
+
} from '../models/dom.model';
|
|
10
|
+
import {
|
|
11
|
+
EVENT_GROUP,
|
|
12
|
+
EVENT_HEADING,
|
|
13
|
+
EVENT_ROW,
|
|
14
|
+
type EventMap,
|
|
15
|
+
type EventName,
|
|
16
|
+
type Events,
|
|
17
|
+
type TabelaEvents,
|
|
18
|
+
} from '../models/event.model';
|
|
19
|
+
import {CSS_TABLE} from '../models/style.model';
|
|
3
20
|
import type {State} from '../models/tabela.model';
|
|
4
21
|
|
|
5
22
|
export class EventManager {
|
|
23
|
+
events: Events = {};
|
|
24
|
+
|
|
25
|
+
handlers: TabelaEvents = {
|
|
26
|
+
subscribe: (name, callback) => this.subscribe(name, callback),
|
|
27
|
+
unsubscribe: (name, callback) => this.unsubscribe(name, callback),
|
|
28
|
+
};
|
|
29
|
+
|
|
6
30
|
constructor(public state: State) {
|
|
7
31
|
mapped.set(state.element, this);
|
|
8
32
|
}
|
|
9
33
|
|
|
34
|
+
emit<Name extends EventName>(name: Name, ...parameters: Parameters<EventMap[Name]>): void {
|
|
35
|
+
if (this.events[name] == null) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const handlers = [...this.events[name]];
|
|
40
|
+
const {length} = handlers;
|
|
41
|
+
|
|
42
|
+
for (let index = 0; index < length; index += 1) {
|
|
43
|
+
(handlers[index] as GenericCallback)(...parameters);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
10
47
|
destroy(): void {
|
|
11
48
|
mapped.delete(this.state.element);
|
|
12
49
|
|
|
@@ -14,18 +51,34 @@ export class EventManager {
|
|
|
14
51
|
}
|
|
15
52
|
|
|
16
53
|
onSort(event: MouseEvent, target: HTMLElement): void {
|
|
17
|
-
const direction = target.getAttribute(
|
|
18
|
-
const
|
|
54
|
+
const direction = target.getAttribute(ATTRIBUTE_DATA_SORT_DIRECTION);
|
|
55
|
+
const key = target.getAttribute(ATTRIBUTE_DATA_KEY);
|
|
56
|
+
|
|
57
|
+
if (key != null) {
|
|
58
|
+
this.state.managers.sort.toggle(event, key, direction);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
19
61
|
|
|
20
|
-
|
|
21
|
-
|
|
62
|
+
subscribe(name: string, callback: GenericCallback): void {
|
|
63
|
+
if (!isEvent(name) || typeof callback !== 'function') {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
(this.events as Record<string, Set<unknown>>)[name] ??= new Set();
|
|
68
|
+
|
|
69
|
+
(this.events[name] as Set<unknown>).add(callback);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
unsubscribe(name: string, callback: GenericCallback): void {
|
|
73
|
+
if (isEvent(name) && typeof callback === 'function') {
|
|
74
|
+
this.events[name]?.delete(callback);
|
|
22
75
|
}
|
|
23
76
|
}
|
|
24
77
|
}
|
|
25
78
|
|
|
26
79
|
function onClick(event: MouseEvent): void {
|
|
27
|
-
const target = findAncestor(event,
|
|
28
|
-
const table = findAncestor(event,
|
|
80
|
+
const target = findAncestor(event, eventAttribute);
|
|
81
|
+
const table = findAncestor(event, tableClassName);
|
|
29
82
|
|
|
30
83
|
if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) {
|
|
31
84
|
return;
|
|
@@ -37,18 +90,18 @@ function onClick(event: MouseEvent): void {
|
|
|
37
90
|
return;
|
|
38
91
|
}
|
|
39
92
|
|
|
40
|
-
const type = target?.getAttribute(
|
|
93
|
+
const type = target?.getAttribute(ATTRIBUTE_DATA_EVENT);
|
|
41
94
|
|
|
42
95
|
switch (type) {
|
|
43
|
-
case
|
|
96
|
+
case EVENT_GROUP:
|
|
44
97
|
manager.state.managers.group.handle(target);
|
|
45
98
|
break;
|
|
46
99
|
|
|
47
|
-
case
|
|
100
|
+
case EVENT_HEADING:
|
|
48
101
|
manager.onSort(event, target);
|
|
49
102
|
break;
|
|
50
103
|
|
|
51
|
-
case
|
|
104
|
+
case EVENT_ROW:
|
|
52
105
|
manager.state.managers.selection.handle(event, target);
|
|
53
106
|
break;
|
|
54
107
|
|
|
@@ -58,8 +111,8 @@ function onClick(event: MouseEvent): void {
|
|
|
58
111
|
}
|
|
59
112
|
|
|
60
113
|
function onKeydown(event: KeyboardEvent): void {
|
|
61
|
-
const target = findAncestor(event,
|
|
62
|
-
const table = findAncestor(event,
|
|
114
|
+
const target = findAncestor(event, eventAttribute);
|
|
115
|
+
const table = findAncestor(event, tableClassName);
|
|
63
116
|
|
|
64
117
|
if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) {
|
|
65
118
|
return;
|
|
@@ -82,7 +135,11 @@ function onKeydown(event: KeyboardEvent): void {
|
|
|
82
135
|
manager.state.managers.navigation.handle(event);
|
|
83
136
|
}
|
|
84
137
|
|
|
138
|
+
const eventAttribute = `[${ATTRIBUTE_DATA_EVENT}]`;
|
|
139
|
+
|
|
85
140
|
const mapped = new WeakMap<HTMLElement, EventManager>();
|
|
86
141
|
|
|
142
|
+
const tableClassName = `.${CSS_TABLE}`;
|
|
143
|
+
|
|
87
144
|
on(document, 'click', onClick);
|
|
88
145
|
on(document, 'keydown', onKeydown, {passive: false});
|