@oscarpalmer/tabela 0.10.0 → 0.12.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.js +1 -0
- package/dist/components/column.component.js +4 -4
- package/dist/components/group.component.js +28 -0
- package/dist/components/row.component.js +11 -8
- package/dist/helpers/dom.helpers.js +1 -1
- package/dist/managers/column.manager.js +9 -8
- package/dist/managers/data.manager.js +95 -30
- package/dist/managers/event.manager.js +42 -23
- package/dist/managers/filter.manager.js +16 -10
- package/dist/managers/group.manager.js +46 -0
- package/dist/managers/navigation.manager.js +73 -0
- package/dist/managers/render.manager.js +61 -31
- package/dist/managers/row.manager.js +7 -7
- package/dist/managers/selection.manager.js +49 -46
- package/dist/managers/sort.manager.js +37 -9
- package/dist/models/group.model.js +0 -0
- package/dist/models/selection.model.js +0 -0
- package/dist/tabela.full.js +682 -591
- package/dist/tabela.js +31 -10
- package/package.json +1 -1
- package/src/components/body.component.ts +2 -0
- package/src/components/column.component.ts +6 -6
- package/src/components/group.component.ts +43 -0
- package/src/components/row.component.ts +14 -9
- package/src/helpers/dom.helpers.ts +3 -1
- package/src/managers/column.manager.ts +13 -15
- package/src/managers/data.manager.ts +176 -38
- package/src/managers/event.manager.ts +68 -41
- package/src/managers/filter.manager.ts +29 -20
- package/src/managers/group.manager.ts +79 -0
- package/src/managers/navigation.manager.ts +146 -0
- package/src/managers/render.manager.ts +84 -40
- package/src/managers/row.manager.ts +9 -14
- package/src/managers/selection.manager.ts +68 -67
- package/src/managers/sort.manager.ts +85 -22
- package/src/models/column.model.ts +2 -2
- package/src/models/data.model.ts +14 -3
- package/src/models/filter.model.ts +11 -3
- package/src/models/group.model.ts +4 -0
- package/src/models/render.model.ts +3 -1
- package/src/models/selection.model.ts +9 -0
- package/src/models/sort.model.ts +11 -3
- package/src/models/tabela.model.ts +14 -36
- package/src/models/tabela.options.ts +3 -2
- package/src/tabela.ts +43 -19
- package/types/components/column.component.d.ts +3 -3
- package/types/components/group.component.d.ts +14 -0
- package/types/components/row.component.d.ts +2 -2
- package/types/helpers/style.helper.d.ts +1 -1
- package/types/managers/column.manager.d.ts +6 -7
- package/types/managers/data.manager.d.ts +7 -6
- package/types/managers/event.manager.d.ts +3 -6
- package/types/managers/filter.manager.d.ts +11 -11
- package/types/managers/group.manager.d.ts +17 -0
- package/types/managers/navigation.manager.d.ts +10 -0
- package/types/managers/render.manager.d.ts +6 -7
- package/types/managers/row.manager.d.ts +4 -5
- package/types/managers/selection.manager.d.ts +12 -7
- package/types/managers/sort.manager.d.ts +11 -9
- package/types/models/column.model.d.ts +2 -2
- package/types/models/data.model.d.ts +13 -3
- package/types/models/filter.model.d.ts +10 -3
- package/types/models/group.model.d.ts +4 -0
- package/types/models/render.model.d.ts +2 -1
- package/types/models/selection.model.d.ts +8 -0
- package/types/models/sort.model.d.ts +10 -3
- package/types/models/tabela.model.d.ts +14 -33
- package/types/models/tabela.options.d.ts +3 -2
- package/types/tabela.d.ts +4 -1
package/dist/tabela.js
CHANGED
|
@@ -2,13 +2,15 @@ import { BodyComponent } from "./components/body.component.js";
|
|
|
2
2
|
import { FooterComponent } from "./components/footer.component.js";
|
|
3
3
|
import { HeaderComponent } from "./components/header.component.js";
|
|
4
4
|
import { ColumnManager } from "./managers/column.manager.js";
|
|
5
|
+
import { SortManager } from "./managers/sort.manager.js";
|
|
5
6
|
import { DataManager } from "./managers/data.manager.js";
|
|
6
7
|
import { EventManager } from "./managers/event.manager.js";
|
|
7
8
|
import { FilterManager } from "./managers/filter.manager.js";
|
|
9
|
+
import { GroupManager } from "./managers/group.manager.js";
|
|
10
|
+
import { NavigationManager } from "./managers/navigation.manager.js";
|
|
11
|
+
import { RenderManager } from "./managers/render.manager.js";
|
|
8
12
|
import { RowManager } from "./managers/row.manager.js";
|
|
9
13
|
import { SelectionManager } from "./managers/selection.manager.js";
|
|
10
|
-
import { SortManager } from "./managers/sort.manager.js";
|
|
11
|
-
import { RenderManager } from "./managers/render.manager.js";
|
|
12
14
|
var Tabela = class {
|
|
13
15
|
#components = {
|
|
14
16
|
header: void 0,
|
|
@@ -16,12 +18,15 @@ var Tabela = class {
|
|
|
16
18
|
footer: void 0
|
|
17
19
|
};
|
|
18
20
|
#element;
|
|
21
|
+
#id = getId();
|
|
19
22
|
#key;
|
|
20
23
|
#managers = {
|
|
21
24
|
column: void 0,
|
|
22
25
|
data: void 0,
|
|
23
26
|
event: void 0,
|
|
24
27
|
filter: void 0,
|
|
28
|
+
group: void 0,
|
|
29
|
+
navigation: void 0,
|
|
25
30
|
render: void 0,
|
|
26
31
|
row: void 0,
|
|
27
32
|
selection: void 0,
|
|
@@ -44,14 +49,24 @@ var Tabela = class {
|
|
|
44
49
|
this.#components.header = new HeaderComponent();
|
|
45
50
|
this.#components.body = new BodyComponent();
|
|
46
51
|
this.#components.footer = new FooterComponent();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
const state = {
|
|
53
|
+
element,
|
|
54
|
+
options,
|
|
55
|
+
components: this.#components,
|
|
56
|
+
id: this.#id,
|
|
57
|
+
key: this.#key,
|
|
58
|
+
managers: this.#managers
|
|
59
|
+
};
|
|
60
|
+
this.#managers.column = new ColumnManager(state);
|
|
61
|
+
this.#managers.data = new DataManager(state);
|
|
62
|
+
this.#managers.event = new EventManager(state);
|
|
63
|
+
this.#managers.filter = new FilterManager(state);
|
|
64
|
+
this.#managers.group = new GroupManager(state);
|
|
65
|
+
this.#managers.navigation = new NavigationManager(state);
|
|
66
|
+
this.#managers.render = new RenderManager(state);
|
|
67
|
+
this.#managers.row = new RowManager(state);
|
|
68
|
+
this.#managers.selection = new SelectionManager(state);
|
|
69
|
+
this.#managers.sort = new SortManager(state);
|
|
55
70
|
element.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
|
|
56
71
|
this.#managers.data.set(options.data);
|
|
57
72
|
this.data = this.#managers.data.handlers;
|
|
@@ -72,6 +87,7 @@ var Tabela = class {
|
|
|
72
87
|
managers.filter.destroy();
|
|
73
88
|
managers.render.destroy();
|
|
74
89
|
managers.row.destroy();
|
|
90
|
+
managers.selection.destroy();
|
|
75
91
|
managers.sort.destroy();
|
|
76
92
|
element.innerHTML = "";
|
|
77
93
|
element.role = "";
|
|
@@ -81,4 +97,9 @@ var Tabela = class {
|
|
|
81
97
|
this.#element = void 0;
|
|
82
98
|
}
|
|
83
99
|
};
|
|
100
|
+
function getId() {
|
|
101
|
+
id += 1;
|
|
102
|
+
return id;
|
|
103
|
+
}
|
|
104
|
+
var id = 0;
|
|
84
105
|
export { Tabela };
|
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {createElement} from '../helpers/dom.helpers';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Column, TabelaColumn} from '../models/column.model';
|
|
3
3
|
|
|
4
4
|
export class ColumnComponent {
|
|
5
5
|
elements: ColumnElements;
|
|
6
|
-
options:
|
|
6
|
+
options: Column;
|
|
7
7
|
|
|
8
|
-
constructor(
|
|
8
|
+
constructor(column: TabelaColumn) {
|
|
9
9
|
const width =
|
|
10
10
|
Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
|
|
11
|
-
(
|
|
11
|
+
(column.width ?? column.title.length * 1.5);
|
|
12
12
|
|
|
13
13
|
this.options = {
|
|
14
|
-
...
|
|
14
|
+
...column,
|
|
15
15
|
width,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
this.elements = createHeading(options.field, options.title, width);
|
|
18
|
+
this.elements = createHeading(this.options.field, this.options.title, width);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
destroy(): void {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {createElement} from '../helpers/dom.helpers';
|
|
2
|
+
import type {State} from '../models/tabela.model';
|
|
3
|
+
|
|
4
|
+
export class GroupComponent {
|
|
5
|
+
element: HTMLElement | undefined;
|
|
6
|
+
|
|
7
|
+
expanded = true;
|
|
8
|
+
|
|
9
|
+
filtered = 0;
|
|
10
|
+
|
|
11
|
+
selected = 0;
|
|
12
|
+
|
|
13
|
+
total = 0;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
readonly key: string,
|
|
17
|
+
readonly label: string,
|
|
18
|
+
readonly value: unknown,
|
|
19
|
+
) {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function renderGroup(state: State, component: GroupComponent): void {
|
|
23
|
+
component.element ??= createElement(
|
|
24
|
+
'div',
|
|
25
|
+
{
|
|
26
|
+
className: 'tabela__row tabela__row--group',
|
|
27
|
+
innerHTML: `<div class="tabela__cell tabela__cell--group" role="cell">
|
|
28
|
+
<button class="tabela__button tabela__button--group" data-event="group" data-key="${component.key}" type="button">
|
|
29
|
+
<span aria-hidden="true"></span>
|
|
30
|
+
<span>Open/close</span>
|
|
31
|
+
</button>
|
|
32
|
+
<p>${component.label}</p>
|
|
33
|
+
</div>`,
|
|
34
|
+
role: 'row',
|
|
35
|
+
},
|
|
36
|
+
{},
|
|
37
|
+
{
|
|
38
|
+
height: `${state.options.rowHeight}px`,
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function updateGroup(state: State, component: GroupComponent): void {}
|
|
@@ -2,7 +2,7 @@ import type {Key} from '@oscarpalmer/atoms/models';
|
|
|
2
2
|
import {setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
3
3
|
import {createCell, createRow} from '../helpers/dom.helpers';
|
|
4
4
|
import type {RenderElementPool} from '../models/render.model';
|
|
5
|
-
import type {
|
|
5
|
+
import type {State} from '../models/tabela.model';
|
|
6
6
|
|
|
7
7
|
export function removeRow(pool: RenderElementPool, row: RowComponent): void {
|
|
8
8
|
if (row.element != null) {
|
|
@@ -17,19 +17,23 @@ export function removeRow(pool: RenderElementPool, row: RowComponent): void {
|
|
|
17
17
|
row.cells = {};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export function renderRow(
|
|
21
|
-
const element = row.element ?? managers.render.pool.rows.shift() ?? createRow();
|
|
20
|
+
export function renderRow(state: State, row: RowComponent): void {
|
|
21
|
+
const element = row.element ?? state.managers.render.pool.rows.shift() ?? createRow();
|
|
22
22
|
|
|
23
23
|
row.element = element;
|
|
24
24
|
|
|
25
25
|
element.innerHTML = '';
|
|
26
26
|
|
|
27
|
-
const selected = managers.selection.items.has(row.key);
|
|
27
|
+
const selected = state.managers.selection.items.has(row.key);
|
|
28
|
+
|
|
29
|
+
const key = String(row.key);
|
|
28
30
|
|
|
29
31
|
setAttributes(element, {
|
|
30
32
|
'aria-selected': String(selected),
|
|
33
|
+
'data-active': String(state.managers.navigation.active === row.key),
|
|
31
34
|
'data-event': 'row',
|
|
32
|
-
'data-key':
|
|
35
|
+
'data-key': key,
|
|
36
|
+
id: `tabela_${state.id}_row_${key}`,
|
|
33
37
|
});
|
|
34
38
|
|
|
35
39
|
element.classList.add('tabela__row--body');
|
|
@@ -40,10 +44,10 @@ export function renderRow(managers: TabelaManagers, row: RowComponent): void {
|
|
|
40
44
|
element.classList.remove('tabela__row--selected');
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
const columns = managers.column.items;
|
|
47
|
+
const columns = state.managers.column.items;
|
|
44
48
|
const {length} = columns;
|
|
45
49
|
|
|
46
|
-
const data = managers.data.values.objects.mapped.get(row.key);
|
|
50
|
+
const data = state.managers.data.values.objects.mapped.get(row.key);
|
|
47
51
|
|
|
48
52
|
if (data == null) {
|
|
49
53
|
return;
|
|
@@ -52,10 +56,11 @@ export function renderRow(managers: TabelaManagers, row: RowComponent): void {
|
|
|
52
56
|
for (let index = 0; index < length; index += 1) {
|
|
53
57
|
const {options} = columns[index];
|
|
54
58
|
|
|
55
|
-
managers.render.pool.cells[options.field] ??= [];
|
|
59
|
+
state.managers.render.pool.cells[options.field] ??= [];
|
|
56
60
|
|
|
57
61
|
const cell =
|
|
58
|
-
managers.render.pool.cells[columns[index].options.field].shift() ??
|
|
62
|
+
state.managers.render.pool.cells[columns[index].options.field].shift() ??
|
|
63
|
+
createCell(options.width);
|
|
59
64
|
|
|
60
65
|
cell.textContent = String(data[options.field]);
|
|
61
66
|
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import {ColumnComponent} from '../components/column.component';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type {TabelaColumn} from '../models/column.model';
|
|
3
|
+
import type {State} from '../models/tabela.model';
|
|
4
4
|
|
|
5
5
|
export class ColumnManager {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
constructor(
|
|
9
|
-
|
|
10
|
-
public components: TabelaComponents,
|
|
11
|
-
columns: TabelaColumnOptions[],
|
|
12
|
-
) {
|
|
13
|
-
this.set(columns);
|
|
6
|
+
items: ColumnComponent[] = [];
|
|
7
|
+
|
|
8
|
+
constructor(public state: State) {
|
|
9
|
+
this.set(state.options.columns);
|
|
14
10
|
}
|
|
15
11
|
|
|
16
12
|
destroy(): void {
|
|
@@ -20,7 +16,8 @@ export class ColumnManager {
|
|
|
20
16
|
this.items[index].destroy();
|
|
21
17
|
}
|
|
22
18
|
|
|
23
|
-
this.items
|
|
19
|
+
this.items = undefined as never;
|
|
20
|
+
this.state = undefined as never;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
remove(field: string): void;
|
|
@@ -28,7 +25,8 @@ export class ColumnManager {
|
|
|
28
25
|
remove(fields: string[]): void;
|
|
29
26
|
|
|
30
27
|
remove(value: unknown): void {
|
|
31
|
-
const {
|
|
28
|
+
const {items, state} = this;
|
|
29
|
+
const {components, managers} = state;
|
|
32
30
|
|
|
33
31
|
const fields = (Array.isArray(value) ? value : [value]).filter(
|
|
34
32
|
item => typeof item === 'string',
|
|
@@ -58,9 +56,9 @@ export class ColumnManager {
|
|
|
58
56
|
managers.render.removeCells(fields);
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
set(columns:
|
|
62
|
-
const {
|
|
63
|
-
const {footer, header} = components;
|
|
59
|
+
set(columns: TabelaColumn[]): void {
|
|
60
|
+
const {items, state} = this;
|
|
61
|
+
const {footer, header} = state.components;
|
|
64
62
|
|
|
65
63
|
items.splice(0, items.length, ...columns.map(column => new ColumnComponent(column)));
|
|
66
64
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {select, sort} from '@oscarpalmer/atoms/array';
|
|
2
2
|
import {toMap} from '@oscarpalmer/atoms/array/to-map';
|
|
3
|
-
import {
|
|
3
|
+
import {toRecord} from '@oscarpalmer/atoms/array/to-record';
|
|
4
4
|
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
5
|
-
import type {DataValues} from '../models/data.model';
|
|
6
|
-
import type {
|
|
5
|
+
import type {DataValues, TabelaData} from '../models/data.model';
|
|
6
|
+
import type {State} from '../models/tabela.model';
|
|
7
|
+
import {GroupComponent} from '../components/group.component';
|
|
8
|
+
import {sortWithGroups} from './sort.manager';
|
|
9
|
+
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
7
10
|
|
|
8
11
|
export class DataManager {
|
|
9
12
|
handlers = Object.freeze({
|
|
@@ -15,7 +18,7 @@ export class DataManager {
|
|
|
15
18
|
update: data => void this.update(data),
|
|
16
19
|
} satisfies TabelaData);
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
values: DataValues = {
|
|
19
22
|
keys: {
|
|
20
23
|
original: [],
|
|
21
24
|
},
|
|
@@ -25,24 +28,61 @@ export class DataManager {
|
|
|
25
28
|
},
|
|
26
29
|
};
|
|
27
30
|
|
|
31
|
+
get keys(): Array<GroupComponent | Key> {
|
|
32
|
+
return this.values.keys.active ?? this.values.keys.original;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
get size(): number {
|
|
29
|
-
return this.
|
|
36
|
+
return this.keys.length;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
constructor(
|
|
33
|
-
public managers: TabelaManagers,
|
|
34
|
-
public components: TabelaComponents,
|
|
35
|
-
public field: string,
|
|
36
|
-
) {}
|
|
39
|
+
constructor(public state: State) {}
|
|
37
40
|
|
|
38
41
|
async add(data: PlainObject[], render: boolean): Promise<void> {
|
|
39
|
-
const {
|
|
42
|
+
const {state, values} = this;
|
|
43
|
+
const {length} = data;
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
const updates: PlainObject[] = [];
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
for (let index = 0; index < length; index += 1) {
|
|
48
|
+
const item = data[index];
|
|
49
|
+
const key = item[state.key] as Key;
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
if (values.objects.mapped.has(key)) {
|
|
52
|
+
updates.push(item);
|
|
53
|
+
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
values.objects.array.push(item);
|
|
58
|
+
values.objects.mapped.set(key, item);
|
|
59
|
+
|
|
60
|
+
if (!state.managers.group.enabled) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const groupKey = item[state.managers.group.field] as unknown;
|
|
65
|
+
|
|
66
|
+
let group = state.managers.group.get(groupKey);
|
|
67
|
+
|
|
68
|
+
if (group == null) {
|
|
69
|
+
group = new GroupComponent(String(groupKey), String(groupKey), groupKey);
|
|
70
|
+
|
|
71
|
+
values.objects.array.push(group);
|
|
72
|
+
|
|
73
|
+
state.managers.group.add(group);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!group.expanded) {
|
|
77
|
+
state.managers.group.collapsed.add(key);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
group.total += 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (updates.length > 0) {
|
|
84
|
+
void this.update(updates);
|
|
85
|
+
} else if (render) {
|
|
46
86
|
this.render();
|
|
47
87
|
}
|
|
48
88
|
}
|
|
@@ -63,21 +103,31 @@ export class DataManager {
|
|
|
63
103
|
values.objects.array.length = 0;
|
|
64
104
|
|
|
65
105
|
this.handlers = undefined as never;
|
|
106
|
+
this.state = undefined as never;
|
|
107
|
+
this.values = undefined as never;
|
|
66
108
|
}
|
|
67
109
|
|
|
68
110
|
get(active?: boolean): PlainObject[] {
|
|
69
111
|
const {values} = this;
|
|
70
112
|
|
|
71
113
|
return (active ?? false)
|
|
72
|
-
? (
|
|
73
|
-
|
|
114
|
+
? select(
|
|
115
|
+
values.keys.active ?? [],
|
|
116
|
+
key => !(key instanceof GroupComponent),
|
|
117
|
+
key => values.objects.mapped.get(key as Key)!,
|
|
118
|
+
)
|
|
119
|
+
: (values.objects.array.filter(item => !(item instanceof GroupComponent)) as PlainObject[]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getIndex(key: Key): number {
|
|
123
|
+
return this.keys.indexOf(key);
|
|
74
124
|
}
|
|
75
125
|
|
|
76
126
|
async remove(items: Array<Key | PlainObject>, render: boolean): Promise<void> {
|
|
77
|
-
const {
|
|
127
|
+
const {state, values} = this;
|
|
78
128
|
|
|
79
129
|
const keys = items
|
|
80
|
-
.map(value => (isPlainObject(value) ? value[
|
|
130
|
+
.map(value => (isPlainObject(value) ? value[state.key] : value) as Key)
|
|
81
131
|
.filter(key => values.objects.mapped.has(key)) as Key[];
|
|
82
132
|
|
|
83
133
|
const {length} = keys;
|
|
@@ -91,15 +141,49 @@ export class DataManager {
|
|
|
91
141
|
|
|
92
142
|
values.objects.mapped.delete(key);
|
|
93
143
|
|
|
94
|
-
const arrayIndex = values.objects.array.findIndex(
|
|
144
|
+
const arrayIndex = values.objects.array.findIndex(
|
|
145
|
+
item => !(item instanceof GroupComponent) && item[state.key] === key,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
let item: PlainObject | undefined;
|
|
95
149
|
|
|
96
150
|
if (arrayIndex > -1) {
|
|
97
|
-
values.objects.array.splice(arrayIndex, 1);
|
|
151
|
+
[item] = values.objects.array.splice(arrayIndex, 1) as PlainObject[];
|
|
98
152
|
}
|
|
99
153
|
|
|
100
154
|
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
101
155
|
|
|
102
|
-
managers.row.remove(key);
|
|
156
|
+
state.managers.row.remove(key);
|
|
157
|
+
|
|
158
|
+
if (!state.managers.group.enabled || item == null) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
state.managers.group.collapsed.delete(key);
|
|
163
|
+
|
|
164
|
+
const groupKey = item[state.managers.group.field] as unknown;
|
|
165
|
+
|
|
166
|
+
const group = state.managers.group.get(groupKey);
|
|
167
|
+
|
|
168
|
+
if (group == null) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
group.total -= 1;
|
|
173
|
+
|
|
174
|
+
if (group.total > 0) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const groupIndex = values.objects.array.findIndex(
|
|
179
|
+
item => item instanceof GroupComponent && item.value === groupKey,
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
if (groupIndex > -1) {
|
|
183
|
+
values.objects.array.splice(groupIndex, 1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
state.managers.group.remove(group);
|
|
103
187
|
}
|
|
104
188
|
|
|
105
189
|
if (render) {
|
|
@@ -108,30 +192,82 @@ export class DataManager {
|
|
|
108
192
|
}
|
|
109
193
|
|
|
110
194
|
render(): void {
|
|
111
|
-
const {
|
|
195
|
+
const {state, values} = this;
|
|
196
|
+
|
|
197
|
+
if (state.managers.group.enabled) {
|
|
198
|
+
sortWithGroups(state, values.objects.array, [
|
|
199
|
+
{
|
|
200
|
+
direction: 'ascending',
|
|
201
|
+
key: state.key,
|
|
202
|
+
},
|
|
203
|
+
]);
|
|
204
|
+
} else {
|
|
205
|
+
sort(values.objects.array as PlainObject[], [
|
|
206
|
+
{
|
|
207
|
+
direction: 'ascending',
|
|
208
|
+
key: state.key,
|
|
209
|
+
},
|
|
210
|
+
]);
|
|
211
|
+
}
|
|
112
212
|
|
|
113
|
-
values.keys.original =
|
|
213
|
+
values.keys.original = values.objects.array.map(item =>
|
|
214
|
+
item instanceof GroupComponent ? item : (item[state.key] as Key),
|
|
215
|
+
);
|
|
114
216
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
217
|
+
values.objects.mapped = toMap(
|
|
218
|
+
values.objects.array.filter(item => !(item instanceof GroupComponent)) as PlainObject[],
|
|
219
|
+
item => item[state.key] as Key,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
if (Object.keys(state.managers.filter.items).length > 0) {
|
|
223
|
+
state.managers.filter.filter();
|
|
224
|
+
} else if (state.managers.sort.items.length > 0) {
|
|
225
|
+
state.managers.sort.sort();
|
|
119
226
|
} else {
|
|
120
|
-
managers.render.update(true);
|
|
227
|
+
state.managers.render.update(true, true);
|
|
121
228
|
}
|
|
122
229
|
}
|
|
123
230
|
|
|
124
231
|
set(data: PlainObject[]): void {
|
|
125
|
-
const {
|
|
232
|
+
const {state, values} = this;
|
|
233
|
+
|
|
234
|
+
const array: Array<GroupComponent | PlainObject> = data.slice();
|
|
235
|
+
|
|
236
|
+
if (state.managers.group.enabled) {
|
|
237
|
+
const grouped = toRecord.arrays(data, state.managers.group.field) as Record<
|
|
238
|
+
string,
|
|
239
|
+
PlainObject[]
|
|
240
|
+
>;
|
|
241
|
+
|
|
242
|
+
const entries = Object.entries(grouped);
|
|
243
|
+
const {length} = entries;
|
|
244
|
+
|
|
245
|
+
const groups: GroupComponent[] = [];
|
|
246
|
+
|
|
247
|
+
for (let index = 0; index < length; index += 1) {
|
|
248
|
+
const [value, items] = entries[index];
|
|
249
|
+
|
|
250
|
+
const key = String(value);
|
|
251
|
+
|
|
252
|
+
const group = new GroupComponent(key, key, value);
|
|
253
|
+
|
|
254
|
+
group.total = items.length;
|
|
255
|
+
|
|
256
|
+
groups.push(group);
|
|
257
|
+
|
|
258
|
+
array.push(group);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
state.managers.group.set(groups);
|
|
262
|
+
}
|
|
126
263
|
|
|
127
|
-
values.objects.
|
|
128
|
-
values.objects.array = data;
|
|
264
|
+
values.objects.array = array;
|
|
129
265
|
|
|
130
266
|
this.render();
|
|
131
267
|
}
|
|
132
268
|
|
|
133
269
|
async synchronize(data: PlainObject[], remove?: boolean): Promise<void> {
|
|
134
|
-
const {
|
|
270
|
+
const {state, values} = this;
|
|
135
271
|
|
|
136
272
|
const add: PlainObject[] = [];
|
|
137
273
|
const updated: PlainObject[] = [];
|
|
@@ -142,7 +278,7 @@ export class DataManager {
|
|
|
142
278
|
|
|
143
279
|
for (let index = 0; index < length; index += 1) {
|
|
144
280
|
const object = data[index];
|
|
145
|
-
const key = object[
|
|
281
|
+
const key = object[state.key] as Key;
|
|
146
282
|
|
|
147
283
|
if (values.objects.mapped.has(key)) {
|
|
148
284
|
updated.push(object);
|
|
@@ -158,7 +294,9 @@ export class DataManager {
|
|
|
158
294
|
}
|
|
159
295
|
|
|
160
296
|
if (remove ?? false) {
|
|
161
|
-
const toRemove = values.keys.original.filter(
|
|
297
|
+
const toRemove = values.keys.original.filter(
|
|
298
|
+
key => !(key instanceof GroupComponent) && !keys.has(key),
|
|
299
|
+
) as Key[];
|
|
162
300
|
|
|
163
301
|
if (toRemove.length > 0) {
|
|
164
302
|
await this.remove(toRemove, false);
|
|
@@ -177,19 +315,19 @@ export class DataManager {
|
|
|
177
315
|
}
|
|
178
316
|
|
|
179
317
|
async update(data: PlainObject[]): Promise<void> {
|
|
180
|
-
const {
|
|
318
|
+
const {state, values} = this;
|
|
181
319
|
|
|
182
320
|
const {length} = data;
|
|
183
321
|
|
|
184
322
|
for (let index = 0; index < length; index += 1) {
|
|
185
323
|
const object = data[index];
|
|
186
|
-
const key = object[
|
|
324
|
+
const key = object[state.key] as Key;
|
|
187
325
|
const value = values.objects.mapped.get(key);
|
|
188
326
|
|
|
189
327
|
if (value != null) {
|
|
190
328
|
values.objects.mapped.set(key, {...value, ...object} as PlainObject);
|
|
191
329
|
|
|
192
|
-
managers.row.update(key);
|
|
330
|
+
state.managers.row.update(key);
|
|
193
331
|
}
|
|
194
332
|
}
|
|
195
333
|
}
|