@oscarpalmer/tabela 0.11.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/column.component.js +4 -4
- package/dist/components/group.component.js +28 -0
- package/dist/helpers/dom.helpers.js +1 -1
- package/dist/managers/data.manager.js +76 -15
- package/dist/managers/event.manager.js +3 -0
- package/dist/managers/filter.manager.js +5 -0
- package/dist/managers/group.manager.js +46 -0
- package/dist/managers/navigation.manager.js +1 -1
- package/dist/managers/render.manager.js +35 -10
- package/dist/managers/selection.manager.js +32 -27
- package/dist/managers/sort.manager.js +29 -2
- package/dist/models/group.model.js +0 -0
- package/dist/models/selection.model.js +0 -0
- package/dist/tabela.full.js +364 -398
- package/dist/tabela.js +4 -1
- package/package.json +1 -1
- package/src/components/column.component.ts +6 -6
- package/src/components/group.component.ts +43 -0
- package/src/components/row.component.ts +2 -2
- package/src/helpers/dom.helpers.ts +3 -1
- package/src/managers/column.manager.ts +4 -4
- package/src/managers/data.manager.ts +155 -21
- package/src/managers/event.manager.ts +7 -3
- package/src/managers/filter.manager.ts +19 -11
- package/src/managers/group.manager.ts +79 -0
- package/src/managers/navigation.manager.ts +6 -5
- package/src/managers/render.manager.ts +55 -17
- package/src/managers/row.manager.ts +2 -2
- package/src/managers/selection.manager.ts +48 -41
- package/src/managers/sort.manager.ts +76 -13
- 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 +2 -2
- package/src/models/selection.model.ts +9 -0
- package/src/models/sort.model.ts +11 -3
- package/src/models/tabela.model.ts +7 -41
- package/src/models/tabela.options.ts +3 -2
- package/src/tabela.ts +11 -12
- 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 +5 -5
- package/types/managers/data.manager.d.ts +5 -3
- package/types/managers/event.manager.d.ts +3 -3
- 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 +3 -3
- package/types/managers/render.manager.d.ts +4 -3
- package/types/managers/row.manager.d.ts +3 -3
- package/types/managers/selection.manager.d.ts +12 -6
- package/types/managers/sort.manager.d.ts +10 -8
- 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 -2
- 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 +7 -37
- package/types/models/tabela.options.d.ts +3 -2
- package/types/tabela.d.ts +4 -1
|
@@ -2,13 +2,13 @@ import { createElement } from "../helpers/dom.helpers.js";
|
|
|
2
2
|
var ColumnComponent = class {
|
|
3
3
|
elements;
|
|
4
4
|
options;
|
|
5
|
-
constructor(
|
|
6
|
-
const width = Number.parseInt(getComputedStyle(document.body).fontSize, 10) * (
|
|
5
|
+
constructor(column) {
|
|
6
|
+
const width = Number.parseInt(getComputedStyle(document.body).fontSize, 10) * (column.width ?? column.title.length * 1.5);
|
|
7
7
|
this.options = {
|
|
8
|
-
...
|
|
8
|
+
...column,
|
|
9
9
|
width
|
|
10
10
|
};
|
|
11
|
-
this.elements = createHeading(options.field, options.title, width);
|
|
11
|
+
this.elements = createHeading(this.options.field, this.options.title, width);
|
|
12
12
|
}
|
|
13
13
|
destroy() {
|
|
14
14
|
this.elements.content.remove();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createElement } from "../helpers/dom.helpers.js";
|
|
2
|
+
var GroupComponent = class {
|
|
3
|
+
element;
|
|
4
|
+
expanded = true;
|
|
5
|
+
filtered = 0;
|
|
6
|
+
selected = 0;
|
|
7
|
+
total = 0;
|
|
8
|
+
constructor(key, label, value) {
|
|
9
|
+
this.key = key;
|
|
10
|
+
this.label = label;
|
|
11
|
+
this.value = value;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function renderGroup(state, component) {
|
|
15
|
+
component.element ??= createElement("div", {
|
|
16
|
+
className: "tabela__row tabela__row--group",
|
|
17
|
+
innerHTML: `<div class="tabela__cell tabela__cell--group" role="cell">
|
|
18
|
+
<button class="tabela__button tabela__button--group" data-event="group" data-key="${component.key}" type="button">
|
|
19
|
+
<span aria-hidden="true"></span>
|
|
20
|
+
<span>Open/close</span>
|
|
21
|
+
</button>
|
|
22
|
+
<p>${component.label}</p>
|
|
23
|
+
</div>`,
|
|
24
|
+
role: "row"
|
|
25
|
+
}, {}, { height: `${state.options.rowHeight}px` });
|
|
26
|
+
}
|
|
27
|
+
function updateGroup(state, component) {}
|
|
28
|
+
export { GroupComponent, renderGroup, updateGroup };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GroupComponent } from "../components/group.component.js";
|
|
2
|
+
import { sortWithGroups } from "./sort.manager.js";
|
|
3
|
+
import { select, sort } from "@oscarpalmer/atoms/array";
|
|
2
4
|
import { toMap } from "@oscarpalmer/atoms/array/to-map";
|
|
5
|
+
import { toRecord } from "@oscarpalmer/atoms/array/to-record";
|
|
3
6
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
4
7
|
var DataManager = class {
|
|
5
8
|
handlers = Object.freeze({
|
|
@@ -17,17 +20,41 @@ var DataManager = class {
|
|
|
17
20
|
array: []
|
|
18
21
|
}
|
|
19
22
|
};
|
|
23
|
+
get keys() {
|
|
24
|
+
return this.values.keys.active ?? this.values.keys.original;
|
|
25
|
+
}
|
|
20
26
|
get size() {
|
|
21
|
-
return this.
|
|
27
|
+
return this.keys.length;
|
|
22
28
|
}
|
|
23
29
|
constructor(state) {
|
|
24
30
|
this.state = state;
|
|
25
31
|
}
|
|
26
32
|
async add(data, render) {
|
|
27
33
|
const { state, values } = this;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
const { length } = data;
|
|
35
|
+
const updates = [];
|
|
36
|
+
for (let index = 0; index < length; index += 1) {
|
|
37
|
+
const item = data[index];
|
|
38
|
+
const key = item[state.key];
|
|
39
|
+
if (values.objects.mapped.has(key)) {
|
|
40
|
+
updates.push(item);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
values.objects.array.push(item);
|
|
44
|
+
values.objects.mapped.set(key, item);
|
|
45
|
+
if (!state.managers.group.enabled) continue;
|
|
46
|
+
const groupKey = item[state.managers.group.field];
|
|
47
|
+
let group = state.managers.group.get(groupKey);
|
|
48
|
+
if (group == null) {
|
|
49
|
+
group = new GroupComponent(String(groupKey), String(groupKey), groupKey);
|
|
50
|
+
values.objects.array.push(group);
|
|
51
|
+
state.managers.group.add(group);
|
|
52
|
+
}
|
|
53
|
+
if (!group.expanded) state.managers.group.collapsed.add(key);
|
|
54
|
+
group.total += 1;
|
|
55
|
+
}
|
|
56
|
+
if (updates.length > 0) this.update(updates);
|
|
57
|
+
else if (render) this.render();
|
|
31
58
|
}
|
|
32
59
|
clear() {
|
|
33
60
|
if (this.values.objects.array.length > 0) this.set([]);
|
|
@@ -44,11 +71,10 @@ var DataManager = class {
|
|
|
44
71
|
}
|
|
45
72
|
get(active) {
|
|
46
73
|
const { values } = this;
|
|
47
|
-
return active ?? false ? values.keys.active
|
|
74
|
+
return active ?? false ? select(values.keys.active ?? [], (key) => !(key instanceof GroupComponent), (key) => values.objects.mapped.get(key)) : values.objects.array.filter((item) => !(item instanceof GroupComponent));
|
|
48
75
|
}
|
|
49
76
|
getIndex(key) {
|
|
50
|
-
|
|
51
|
-
return (values.keys.active ?? values.keys.original).indexOf(key);
|
|
77
|
+
return this.keys.indexOf(key);
|
|
52
78
|
}
|
|
53
79
|
async remove(items, render) {
|
|
54
80
|
const { state, values } = this;
|
|
@@ -58,24 +84,59 @@ var DataManager = class {
|
|
|
58
84
|
for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
|
|
59
85
|
const key = keys[keyIndex];
|
|
60
86
|
values.objects.mapped.delete(key);
|
|
61
|
-
const arrayIndex = values.objects.array.findIndex((
|
|
62
|
-
|
|
87
|
+
const arrayIndex = values.objects.array.findIndex((item) => !(item instanceof GroupComponent) && item[state.key] === key);
|
|
88
|
+
let item;
|
|
89
|
+
if (arrayIndex > -1) [item] = values.objects.array.splice(arrayIndex, 1);
|
|
63
90
|
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
64
91
|
state.managers.row.remove(key);
|
|
92
|
+
if (!state.managers.group.enabled || item == null) continue;
|
|
93
|
+
state.managers.group.collapsed.delete(key);
|
|
94
|
+
const groupKey = item[state.managers.group.field];
|
|
95
|
+
const group = state.managers.group.get(groupKey);
|
|
96
|
+
if (group == null) continue;
|
|
97
|
+
group.total -= 1;
|
|
98
|
+
if (group.total > 0) continue;
|
|
99
|
+
const groupIndex = values.objects.array.findIndex((item) => item instanceof GroupComponent && item.value === groupKey);
|
|
100
|
+
if (groupIndex > -1) values.objects.array.splice(groupIndex, 1);
|
|
101
|
+
state.managers.group.remove(group);
|
|
65
102
|
}
|
|
66
103
|
if (render) this.render();
|
|
67
104
|
}
|
|
68
105
|
render() {
|
|
69
106
|
const { state, values } = this;
|
|
70
|
-
|
|
107
|
+
if (state.managers.group.enabled) sortWithGroups(state, values.objects.array, [{
|
|
108
|
+
direction: "ascending",
|
|
109
|
+
key: state.key
|
|
110
|
+
}]);
|
|
111
|
+
else sort(values.objects.array, [{
|
|
112
|
+
direction: "ascending",
|
|
113
|
+
key: state.key
|
|
114
|
+
}]);
|
|
115
|
+
values.keys.original = values.objects.array.map((item) => item instanceof GroupComponent ? item : item[state.key]);
|
|
116
|
+
values.objects.mapped = toMap(values.objects.array.filter((item) => !(item instanceof GroupComponent)), (item) => item[state.key]);
|
|
71
117
|
if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
|
|
72
118
|
else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
|
|
73
|
-
else state.managers.render.update(true);
|
|
119
|
+
else state.managers.render.update(true, true);
|
|
74
120
|
}
|
|
75
121
|
set(data) {
|
|
76
122
|
const { state, values } = this;
|
|
77
|
-
|
|
78
|
-
|
|
123
|
+
const array = data.slice();
|
|
124
|
+
if (state.managers.group.enabled) {
|
|
125
|
+
const grouped = toRecord.arrays(data, state.managers.group.field);
|
|
126
|
+
const entries = Object.entries(grouped);
|
|
127
|
+
const { length } = entries;
|
|
128
|
+
const groups = [];
|
|
129
|
+
for (let index = 0; index < length; index += 1) {
|
|
130
|
+
const [value, items] = entries[index];
|
|
131
|
+
const key = String(value);
|
|
132
|
+
const group = new GroupComponent(key, key, value);
|
|
133
|
+
group.total = items.length;
|
|
134
|
+
groups.push(group);
|
|
135
|
+
array.push(group);
|
|
136
|
+
}
|
|
137
|
+
state.managers.group.set(groups);
|
|
138
|
+
}
|
|
139
|
+
values.objects.array = array;
|
|
79
140
|
this.render();
|
|
80
141
|
}
|
|
81
142
|
async synchronize(data, remove) {
|
|
@@ -93,7 +154,7 @@ var DataManager = class {
|
|
|
93
154
|
}
|
|
94
155
|
if (keys.size === 0) return;
|
|
95
156
|
if (remove ?? false) {
|
|
96
|
-
const toRemove = values.keys.original.filter((key) => !keys.has(key));
|
|
157
|
+
const toRemove = values.keys.original.filter((key) => !(key instanceof GroupComponent) && !keys.has(key));
|
|
97
158
|
if (toRemove.length > 0) await this.remove(toRemove, false);
|
|
98
159
|
}
|
|
99
160
|
await this.update(updated);
|
|
@@ -22,6 +22,9 @@ function onClick(event) {
|
|
|
22
22
|
const manager = mapped.get(table);
|
|
23
23
|
if (manager == null) return;
|
|
24
24
|
switch (target?.getAttribute("data-event")) {
|
|
25
|
+
case "group":
|
|
26
|
+
manager.state.managers.group.handle(target);
|
|
27
|
+
break;
|
|
25
28
|
case "heading":
|
|
26
29
|
manager.onSort(event, target);
|
|
27
30
|
break;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GroupComponent } from "../components/group.component.js";
|
|
1
2
|
import { getNumber } from "@oscarpalmer/atoms/number";
|
|
2
3
|
import { getString } from "@oscarpalmer/atoms/string";
|
|
3
4
|
import { endsWith, includes, startsWith } from "@oscarpalmer/atoms/string/match";
|
|
@@ -37,6 +38,10 @@ var FilterManager = class {
|
|
|
37
38
|
const keysLength = state.managers.data.values.keys.original.length;
|
|
38
39
|
rowLoop: for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
|
|
39
40
|
const key = state.managers.data.values.keys.original[keyIndex];
|
|
41
|
+
if (key instanceof GroupComponent) {
|
|
42
|
+
filtered.push(key);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
40
45
|
const row = state.managers.data.values.objects.mapped.get(key);
|
|
41
46
|
if (row == null) continue;
|
|
42
47
|
filterLoop: for (let filterIndex = 0; filterIndex < filters.length; filterIndex += 1) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { sort } from "@oscarpalmer/atoms/array";
|
|
2
|
+
import { toRecord } from "@oscarpalmer/atoms/array/to-record";
|
|
3
|
+
import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
|
|
4
|
+
var GroupManager = class {
|
|
5
|
+
collapsed = /* @__PURE__ */ new Set();
|
|
6
|
+
enabled = false;
|
|
7
|
+
field;
|
|
8
|
+
items = [];
|
|
9
|
+
order = {};
|
|
10
|
+
constructor(state) {
|
|
11
|
+
this.state = state;
|
|
12
|
+
if (isNullableOrWhitespace(state.options.grouping)) return;
|
|
13
|
+
this.enabled = true;
|
|
14
|
+
this.field = state.options.grouping;
|
|
15
|
+
}
|
|
16
|
+
add(group) {
|
|
17
|
+
this.set([...this.items, group]);
|
|
18
|
+
}
|
|
19
|
+
get(value) {
|
|
20
|
+
return this.items.find((item) => item.value === value);
|
|
21
|
+
}
|
|
22
|
+
handle(button) {
|
|
23
|
+
const key = button.dataset.key;
|
|
24
|
+
const group = this.get(key);
|
|
25
|
+
if (group == null) return;
|
|
26
|
+
const { collapsed, items, state } = this;
|
|
27
|
+
group.expanded = !group.expanded;
|
|
28
|
+
const index = items.indexOf(group);
|
|
29
|
+
let first = state.managers.data.values.keys.original.indexOf(items[index]) + 1;
|
|
30
|
+
const last = items[index + 1] == null ? state.managers.data.keys.length - 1 : state.managers.data.values.keys.original.indexOf(items[index + 1]) - 1;
|
|
31
|
+
for (; first <= last; first += 1) {
|
|
32
|
+
const key = state.managers.data.values.keys.original[first];
|
|
33
|
+
if (group.expanded) collapsed.delete(key);
|
|
34
|
+
else collapsed.add(key);
|
|
35
|
+
}
|
|
36
|
+
state.managers.render.update(true, true);
|
|
37
|
+
}
|
|
38
|
+
remove(group) {
|
|
39
|
+
this.set(this.items.filter((item) => item !== group));
|
|
40
|
+
}
|
|
41
|
+
set(items) {
|
|
42
|
+
this.items = sort(items, (item) => item.label);
|
|
43
|
+
this.order = toRecord(items, "value", (_, index) => index);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export { GroupManager };
|
|
@@ -14,7 +14,7 @@ var NavigationManager = class {
|
|
|
14
14
|
event.preventDefault();
|
|
15
15
|
const { components, id, managers } = this.state;
|
|
16
16
|
const activeDescendant = components.body.elements.group.getAttribute("aria-activedescendant");
|
|
17
|
-
const keys = managers.data
|
|
17
|
+
const { keys } = managers.data;
|
|
18
18
|
const { length } = keys;
|
|
19
19
|
let next;
|
|
20
20
|
if (isNullableOrWhitespace(activeDescendant)) next = getDefaultIndex(event.key, length);
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { GroupComponent, renderGroup } from "../components/group.component.js";
|
|
1
2
|
import { removeRow, renderRow } from "../components/row.component.js";
|
|
2
3
|
import { on } from "@oscarpalmer/toretto/event";
|
|
3
|
-
function getRange(down) {
|
|
4
|
-
const { components, managers, options } =
|
|
4
|
+
function getRange(state, down) {
|
|
5
|
+
const { components, managers, options } = state;
|
|
5
6
|
const { clientHeight, scrollTop } = components.body.elements.group;
|
|
7
|
+
const { keys } = managers.data;
|
|
6
8
|
const first = Math.floor(scrollTop / options.rowHeight);
|
|
7
|
-
const last = Math.min(
|
|
9
|
+
const last = Math.min(keys.length - managers.group.collapsed.size - 1, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
|
|
8
10
|
const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
|
|
9
11
|
const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
|
|
10
12
|
const start = Math.max(0, first - before);
|
|
11
13
|
return {
|
|
12
|
-
end: Math.min(
|
|
14
|
+
end: Math.min(keys.length - managers.group.collapsed.size - 1, last + after),
|
|
13
15
|
start
|
|
14
16
|
};
|
|
15
17
|
}
|
|
@@ -59,6 +61,7 @@ var RenderManager = class {
|
|
|
59
61
|
const { length } = fields;
|
|
60
62
|
for (let index = 0; index < length; index += 1) delete pool.cells[fields[index]];
|
|
61
63
|
for (const [, key] of visible) {
|
|
64
|
+
if (key instanceof GroupComponent) continue;
|
|
62
65
|
const row = state.managers.row.get(key);
|
|
63
66
|
if (row == null || row.element == null) continue;
|
|
64
67
|
for (let index = 0; index < length; index += 1) {
|
|
@@ -76,31 +79,53 @@ var RenderManager = class {
|
|
|
76
79
|
update(down, rerender) {
|
|
77
80
|
const { state, pool, visible } = this;
|
|
78
81
|
const { components, managers, options } = state;
|
|
79
|
-
components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
|
|
82
|
+
components.body.elements.faker.style.height = `${(managers.data.size - managers.group.collapsed.size) * options.rowHeight}px`;
|
|
80
83
|
const indices = /* @__PURE__ */ new Set();
|
|
81
|
-
const range = getRange
|
|
84
|
+
const range = getRange(state, down);
|
|
82
85
|
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
83
86
|
let remove = rerender ?? false;
|
|
84
87
|
for (const [index, key] of visible) {
|
|
88
|
+
if (key instanceof GroupComponent) {
|
|
89
|
+
if (remove || !indices.has(index)) {
|
|
90
|
+
visible.delete(index);
|
|
91
|
+
key.element?.remove();
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
85
95
|
const row = managers.row.get(key);
|
|
86
|
-
if (remove || row == null || !indices.has(index)) {
|
|
96
|
+
if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
|
|
87
97
|
visible.delete(index);
|
|
88
98
|
if (row != null) removeRow(pool, row);
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
const fragment = this.getFragment();
|
|
92
|
-
const keys = managers.data
|
|
102
|
+
const { keys } = managers.data;
|
|
93
103
|
let count = 0;
|
|
94
|
-
|
|
104
|
+
let offset = 0;
|
|
105
|
+
for (let index = range.start; index <= range.end + offset; index += 1) {
|
|
95
106
|
if (visible.has(index)) continue;
|
|
96
107
|
const key = keys[index];
|
|
108
|
+
if (key instanceof GroupComponent) {
|
|
109
|
+
count += 1;
|
|
110
|
+
renderGroup(state, key);
|
|
111
|
+
visible.set(index, key);
|
|
112
|
+
if (key.element != null) {
|
|
113
|
+
key.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
114
|
+
fragment.append(key.element);
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
97
118
|
const row = managers.row.get(key);
|
|
98
119
|
if (row == null) continue;
|
|
120
|
+
if (managers.group.collapsed.has(key)) {
|
|
121
|
+
offset += 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
99
124
|
count += 1;
|
|
100
125
|
renderRow(state, row);
|
|
101
126
|
visible.set(index, key);
|
|
102
127
|
if (row.element != null) {
|
|
103
|
-
row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
|
|
128
|
+
row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
104
129
|
fragment.append(row.element);
|
|
105
130
|
}
|
|
106
131
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { createElement } from "../helpers/dom.helpers.js";
|
|
2
|
+
import { GroupComponent } from "../components/group.component.js";
|
|
2
3
|
import { getKey } from "../helpers/misc.helpers.js";
|
|
3
4
|
import { dragStyling } from "../helpers/style.helper.js";
|
|
4
5
|
import { setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
5
6
|
import { isKey } from "@oscarpalmer/atoms/is";
|
|
6
7
|
import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
7
|
-
import { findAncestor } from "@oscarpalmer/toretto";
|
|
8
|
+
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
8
9
|
var SelectionManager = class {
|
|
9
10
|
handlers = Object.freeze({
|
|
11
|
+
add: (keys) => this.add(keys),
|
|
10
12
|
clear: () => this.clear(),
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
remove: (keys) => this.remove(keys),
|
|
14
|
+
set: (keys) => this.set(keys),
|
|
13
15
|
toggle: () => this.toggle()
|
|
14
16
|
});
|
|
15
17
|
items = /* @__PURE__ */ new Set();
|
|
@@ -18,21 +20,24 @@ var SelectionManager = class {
|
|
|
18
20
|
this.state = state;
|
|
19
21
|
mapped.set(state.element, this);
|
|
20
22
|
}
|
|
23
|
+
add(keys) {
|
|
24
|
+
const { length } = keys;
|
|
25
|
+
let update = false;
|
|
26
|
+
for (let index = 0; index < length; index += 1) {
|
|
27
|
+
const key = keys[index];
|
|
28
|
+
if (!this.items.has(key)) {
|
|
29
|
+
this.items.add(key);
|
|
30
|
+
update = true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (update) this.update([]);
|
|
34
|
+
}
|
|
21
35
|
clear() {
|
|
22
36
|
if (this.items.size === 0) return;
|
|
23
37
|
const removed = [...this.items];
|
|
24
38
|
this.items.clear();
|
|
25
39
|
this.update(removed);
|
|
26
40
|
}
|
|
27
|
-
deselect(keys) {
|
|
28
|
-
const { length } = keys;
|
|
29
|
-
const removed = [];
|
|
30
|
-
for (let index = 0; index < length; index += 1) {
|
|
31
|
-
const key = keys[index];
|
|
32
|
-
if (this.items.delete(key)) removed.push(key);
|
|
33
|
-
}
|
|
34
|
-
if (removed.length > 0) this.update(removed);
|
|
35
|
-
}
|
|
36
41
|
destroy() {
|
|
37
42
|
mapped.delete(this.state.element);
|
|
38
43
|
this.handlers = void 0;
|
|
@@ -52,8 +57,8 @@ var SelectionManager = class {
|
|
|
52
57
|
this.last = key;
|
|
53
58
|
this.state.managers.navigation.setActive(key, false);
|
|
54
59
|
if (event.ctrlKey || event.metaKey) {
|
|
55
|
-
if (items.has(key)) this.
|
|
56
|
-
else this.
|
|
60
|
+
if (items.has(key)) this.remove([key]);
|
|
61
|
+
else this.add([key]);
|
|
57
62
|
return;
|
|
58
63
|
}
|
|
59
64
|
this.set([key]);
|
|
@@ -64,29 +69,29 @@ var SelectionManager = class {
|
|
|
64
69
|
const fromKey = keyed ? from : getKey(from.getAttribute("data-key"));
|
|
65
70
|
const toKey = keyed ? to : getKey(to.getAttribute("data-key"));
|
|
66
71
|
if (fromKey === toKey) return;
|
|
67
|
-
const keys = state.managers.data
|
|
72
|
+
const { keys } = state.managers.data;
|
|
68
73
|
const fromIndex = state.managers.data.getIndex(fromKey);
|
|
69
74
|
const toIndex = state.managers.data.getIndex(toKey);
|
|
70
75
|
if (fromIndex === -1 || toIndex === -1) return;
|
|
71
76
|
const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
|
|
72
77
|
const selected = [];
|
|
73
|
-
for (let index = start; index <= end; index += 1)
|
|
74
|
-
|
|
78
|
+
for (let index = start; index <= end; index += 1) {
|
|
79
|
+
const key = keys[index];
|
|
80
|
+
if (!(key instanceof GroupComponent)) selected.push(key);
|
|
81
|
+
}
|
|
82
|
+
if (keyed) this.add(selected);
|
|
75
83
|
else this.set(selected);
|
|
76
84
|
this.last = toKey;
|
|
77
85
|
this.state.managers.navigation.setActive(toKey, false);
|
|
78
86
|
}
|
|
79
|
-
|
|
87
|
+
remove(keys) {
|
|
80
88
|
const { length } = keys;
|
|
81
|
-
|
|
89
|
+
const removed = [];
|
|
82
90
|
for (let index = 0; index < length; index += 1) {
|
|
83
91
|
const key = keys[index];
|
|
84
|
-
if (
|
|
85
|
-
this.items.add(key);
|
|
86
|
-
update = true;
|
|
87
|
-
}
|
|
92
|
+
if (this.items.delete(key)) removed.push(key);
|
|
88
93
|
}
|
|
89
|
-
if (
|
|
94
|
+
if (removed.length > 0) this.update(removed);
|
|
90
95
|
}
|
|
91
96
|
set(keys) {
|
|
92
97
|
const { items } = this;
|
|
@@ -98,9 +103,9 @@ var SelectionManager = class {
|
|
|
98
103
|
}
|
|
99
104
|
toggle() {
|
|
100
105
|
const { items, state } = this;
|
|
101
|
-
const
|
|
102
|
-
if (items.size ===
|
|
103
|
-
else this.
|
|
106
|
+
const { keys } = state.managers.data;
|
|
107
|
+
if (items.size === keys.length - state.managers.group.items.length) this.clear();
|
|
108
|
+
else this.set(keys.filter((key) => !(key instanceof GroupComponent)));
|
|
104
109
|
}
|
|
105
110
|
update(removed) {
|
|
106
111
|
const items = [...removed.map((key) => ({
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { GroupComponent } from "../components/group.component.js";
|
|
1
2
|
import { setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
|
|
2
3
|
import { sort } from "@oscarpalmer/atoms/array";
|
|
4
|
+
import { compare } from "@oscarpalmer/atoms/value/compare";
|
|
3
5
|
var SortManager = class {
|
|
4
6
|
handlers = Object.freeze({
|
|
5
7
|
add: (field, direction) => this.add(field, direction),
|
|
@@ -75,7 +77,7 @@ var SortManager = class {
|
|
|
75
77
|
});
|
|
76
78
|
setAttribute(column.elements.sorter, "data-sort-position", sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : void 0);
|
|
77
79
|
}
|
|
78
|
-
state.managers.data.values.keys.active = items.length === 0 ? void 0 :
|
|
80
|
+
state.managers.data.values.keys.active = items.length === 0 ? void 0 : getSortedKeys(state, items);
|
|
79
81
|
state.managers.render.update(true, true);
|
|
80
82
|
}
|
|
81
83
|
toggle(event, field, direction) {
|
|
@@ -92,4 +94,29 @@ var SortManager = class {
|
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
};
|
|
95
|
-
|
|
97
|
+
function getSortedKeys(state, sorters) {
|
|
98
|
+
const data = state.managers.data.values.keys.active?.map((key) => key instanceof GroupComponent ? key : state.managers.data.values.objects.mapped.get(key)) ?? state.managers.data.values.objects.array.slice();
|
|
99
|
+
if (!state.managers.group.enabled) return sort(data, sorters).map((item) => item[state.key]);
|
|
100
|
+
return sortWithGroups(state, data, sorters).map((item) => item instanceof GroupComponent ? item : item[state.key]);
|
|
101
|
+
}
|
|
102
|
+
function sortWithGroups(state, data, sorters) {
|
|
103
|
+
const { length } = sorters;
|
|
104
|
+
return data.sort((first, second) => {
|
|
105
|
+
const firstValue = first instanceof GroupComponent ? first.value : first[state.managers.group.field];
|
|
106
|
+
const secondValue = second instanceof GroupComponent ? second.value : second[state.managers.group.field];
|
|
107
|
+
const firstOrder = state.managers.group.order[firstValue];
|
|
108
|
+
const secondOrder = state.managers.group.order[secondValue];
|
|
109
|
+
const groupComparison = compare(firstOrder, secondOrder);
|
|
110
|
+
if (groupComparison !== 0) return groupComparison;
|
|
111
|
+
const firstIsGroup = first instanceof GroupComponent;
|
|
112
|
+
const secondIsGroup = second instanceof GroupComponent;
|
|
113
|
+
if (firstIsGroup || secondIsGroup) return firstIsGroup && secondIsGroup ? 0 : firstIsGroup ? -1 : 1;
|
|
114
|
+
for (let index = 0; index < length; index += 1) {
|
|
115
|
+
const sorter = sorters[index];
|
|
116
|
+
const comparison = compare(first[sorter.key], second[sorter.key]);
|
|
117
|
+
if (comparison !== 0) return comparison * (sorter.direction === "ascending" ? 1 : -1);
|
|
118
|
+
}
|
|
119
|
+
return 0;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
export { SortManager, sortWithGroups };
|
|
File without changes
|
|
File without changes
|