@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
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import type {Key} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {on} from '@oscarpalmer/toretto/event';
|
|
3
3
|
import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
|
|
4
|
+
import {GroupComponent, renderGroup} from '../components/group.component';
|
|
4
5
|
import {removeRow, renderRow} from '../components/row.component';
|
|
5
6
|
import type {RenderElementPool, RenderRange, RenderState} from '../models/render.model';
|
|
6
|
-
import type {
|
|
7
|
+
import type {State} from '../models/tabela.model';
|
|
7
8
|
|
|
8
|
-
function getRange(
|
|
9
|
-
const {components, managers, options} =
|
|
9
|
+
function getRange(state: State, down: boolean): RenderRange {
|
|
10
|
+
const {components, managers, options} = state;
|
|
10
11
|
const {clientHeight, scrollTop} = components.body.elements.group;
|
|
11
12
|
|
|
13
|
+
const {keys} = managers.data;
|
|
14
|
+
|
|
12
15
|
const first = Math.floor(scrollTop / options.rowHeight);
|
|
13
16
|
|
|
14
17
|
const last = Math.min(
|
|
15
|
-
|
|
18
|
+
keys.length - managers.group.collapsed.size - 1,
|
|
16
19
|
Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1,
|
|
17
20
|
);
|
|
18
21
|
|
|
@@ -20,11 +23,7 @@ function getRange(this: RenderManager, down: boolean): RenderRange {
|
|
|
20
23
|
const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
|
|
21
24
|
|
|
22
25
|
const start = Math.max(0, first - before);
|
|
23
|
-
|
|
24
|
-
const end = Math.min(
|
|
25
|
-
(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1,
|
|
26
|
-
last + after,
|
|
27
|
-
);
|
|
26
|
+
const end = Math.min(keys.length - managers.group.collapsed.size - 1, last + after);
|
|
28
27
|
|
|
29
28
|
return {end, start};
|
|
30
29
|
}
|
|
@@ -58,9 +57,9 @@ export class RenderManager {
|
|
|
58
57
|
|
|
59
58
|
state: RenderState;
|
|
60
59
|
|
|
61
|
-
visible = new Map<number, Key>();
|
|
60
|
+
visible = new Map<number, GroupComponent | Key>();
|
|
62
61
|
|
|
63
|
-
constructor(state:
|
|
62
|
+
constructor(state: State) {
|
|
64
63
|
this.listener = on(state.components.body.elements.group, 'scroll', onScroll.bind(this));
|
|
65
64
|
|
|
66
65
|
this.state = {
|
|
@@ -95,6 +94,10 @@ export class RenderManager {
|
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
for (const [, key] of visible) {
|
|
97
|
+
if (key instanceof GroupComponent) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
98
101
|
const row = state.managers.row.get(key);
|
|
99
102
|
|
|
100
103
|
if (row == null || row.element == null) {
|
|
@@ -123,10 +126,11 @@ export class RenderManager {
|
|
|
123
126
|
const {state, pool, visible} = this;
|
|
124
127
|
const {components, managers, options} = state;
|
|
125
128
|
|
|
126
|
-
components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
|
|
129
|
+
components.body.elements.faker.style.height = `${(managers.data.size - managers.group.collapsed.size) * options.rowHeight}px`;
|
|
127
130
|
|
|
128
131
|
const indices = new Set<number>();
|
|
129
|
-
|
|
132
|
+
|
|
133
|
+
const range = getRange(state, down);
|
|
130
134
|
|
|
131
135
|
for (let index = range.start; index <= range.end; index += 1) {
|
|
132
136
|
indices.add(index);
|
|
@@ -135,9 +139,19 @@ export class RenderManager {
|
|
|
135
139
|
let remove = rerender ?? false;
|
|
136
140
|
|
|
137
141
|
for (const [index, key] of visible) {
|
|
142
|
+
if (key instanceof GroupComponent) {
|
|
143
|
+
if (remove || !indices.has(index)) {
|
|
144
|
+
visible.delete(index);
|
|
145
|
+
|
|
146
|
+
key.element?.remove();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
const row = managers.row.get(key);
|
|
139
153
|
|
|
140
|
-
if (remove || row == null || !indices.has(index)) {
|
|
154
|
+
if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
|
|
141
155
|
visible.delete(index);
|
|
142
156
|
|
|
143
157
|
if (row != null) {
|
|
@@ -148,22 +162,46 @@ export class RenderManager {
|
|
|
148
162
|
|
|
149
163
|
const fragment = this.getFragment();
|
|
150
164
|
|
|
151
|
-
const keys = managers.data
|
|
165
|
+
const {keys} = managers.data;
|
|
152
166
|
|
|
153
167
|
let count = 0;
|
|
168
|
+
let offset = 0;
|
|
154
169
|
|
|
155
|
-
for (let index = range.start; index <= range.end; index += 1) {
|
|
170
|
+
for (let index = range.start; index <= range.end + offset; index += 1) {
|
|
156
171
|
if (visible.has(index)) {
|
|
157
172
|
continue;
|
|
158
173
|
}
|
|
159
174
|
|
|
160
175
|
const key = keys[index];
|
|
176
|
+
|
|
177
|
+
if (key instanceof GroupComponent) {
|
|
178
|
+
count += 1;
|
|
179
|
+
|
|
180
|
+
renderGroup(state, key);
|
|
181
|
+
|
|
182
|
+
visible.set(index, key);
|
|
183
|
+
|
|
184
|
+
if (key.element != null) {
|
|
185
|
+
key.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
186
|
+
|
|
187
|
+
fragment.append(key.element);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
|
|
161
193
|
const row = managers.row.get(key);
|
|
162
194
|
|
|
163
195
|
if (row == null) {
|
|
164
196
|
continue;
|
|
165
197
|
}
|
|
166
198
|
|
|
199
|
+
if (managers.group.collapsed.has(key)) {
|
|
200
|
+
offset += 1;
|
|
201
|
+
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
|
|
167
205
|
count += 1;
|
|
168
206
|
|
|
169
207
|
renderRow(state, row);
|
|
@@ -171,7 +209,7 @@ export class RenderManager {
|
|
|
171
209
|
visible.set(index, key);
|
|
172
210
|
|
|
173
211
|
if (row.element != null) {
|
|
174
|
-
row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
|
|
212
|
+
row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
175
213
|
|
|
176
214
|
fragment.append(row.element);
|
|
177
215
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type {Key} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {removeRow, renderRow, RowComponent} from '../components/row.component';
|
|
3
|
-
import type {
|
|
3
|
+
import type {State} from '../models/tabela.model';
|
|
4
4
|
|
|
5
5
|
export class RowManager {
|
|
6
6
|
components = new Map<Key, RowComponent>();
|
|
7
7
|
|
|
8
|
-
constructor(public state:
|
|
8
|
+
constructor(public state: State) {}
|
|
9
9
|
|
|
10
10
|
destroy(): void {
|
|
11
11
|
const components = [...this.components.values()];
|
|
@@ -1,57 +1,63 @@
|
|
|
1
1
|
import {isKey} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {Key} from '@oscarpalmer/atoms/models';
|
|
3
|
-
import {findAncestor, type EventPosition} from '@oscarpalmer/toretto';
|
|
4
3
|
import {setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
5
4
|
import {getPosition, on} from '@oscarpalmer/toretto/event';
|
|
5
|
+
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
6
|
+
import type {EventPosition} from '@oscarpalmer/toretto/models';
|
|
6
7
|
import {createElement} from '../helpers/dom.helpers';
|
|
7
8
|
import {getKey} from '../helpers/misc.helpers';
|
|
8
9
|
import {dragStyling} from '../helpers/style.helper';
|
|
9
|
-
import type {TabelaSelection
|
|
10
|
+
import type {TabelaSelection} from '../models/selection.model';
|
|
11
|
+
import type {State} from '../models/tabela.model';
|
|
12
|
+
import {GroupComponent} from '../components/group.component';
|
|
10
13
|
|
|
11
14
|
export class SelectionManager {
|
|
12
15
|
handlers = Object.freeze({
|
|
16
|
+
add: keys => this.add(keys),
|
|
13
17
|
clear: () => this.clear(),
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
remove: keys => this.remove(keys),
|
|
19
|
+
set: keys => this.set(keys),
|
|
16
20
|
toggle: () => this.toggle(),
|
|
17
|
-
}
|
|
21
|
+
} satisfies TabelaSelection);
|
|
18
22
|
|
|
19
23
|
items = new Set<Key>();
|
|
20
24
|
|
|
21
25
|
last: Key | undefined;
|
|
22
26
|
|
|
23
|
-
constructor(public state:
|
|
27
|
+
constructor(public state: State) {
|
|
24
28
|
mapped.set(state.element, this);
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
if (this.items.size === 0) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const removed = [...this.items];
|
|
33
|
-
|
|
34
|
-
this.items.clear();
|
|
35
|
-
|
|
36
|
-
this.update(removed);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
deselect(keys: Key[]): void {
|
|
31
|
+
add(keys: Key[]): void {
|
|
40
32
|
const {length} = keys;
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
let update = false;
|
|
43
35
|
|
|
44
36
|
for (let index = 0; index < length; index += 1) {
|
|
45
37
|
const key = keys[index];
|
|
46
38
|
|
|
47
|
-
if (this.items.
|
|
48
|
-
|
|
39
|
+
if (!this.items.has(key)) {
|
|
40
|
+
this.items.add(key);
|
|
41
|
+
|
|
42
|
+
update = true;
|
|
49
43
|
}
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
if (
|
|
53
|
-
this.update(
|
|
46
|
+
if (update) {
|
|
47
|
+
this.update([]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
clear(): void {
|
|
52
|
+
if (this.items.size === 0) {
|
|
53
|
+
return;
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
const removed = [...this.items];
|
|
57
|
+
|
|
58
|
+
this.items.clear();
|
|
59
|
+
|
|
60
|
+
this.update(removed);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
destroy(): void {
|
|
@@ -88,9 +94,9 @@ export class SelectionManager {
|
|
|
88
94
|
|
|
89
95
|
if (event.ctrlKey || event.metaKey) {
|
|
90
96
|
if (items.has(key)) {
|
|
91
|
-
this.
|
|
97
|
+
this.remove([key]);
|
|
92
98
|
} else {
|
|
93
|
-
this.
|
|
99
|
+
this.add([key]);
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
return;
|
|
@@ -111,7 +117,7 @@ export class SelectionManager {
|
|
|
111
117
|
return;
|
|
112
118
|
}
|
|
113
119
|
|
|
114
|
-
const keys = state.managers.data
|
|
120
|
+
const {keys} = state.managers.data;
|
|
115
121
|
|
|
116
122
|
const fromIndex = state.managers.data.getIndex(fromKey);
|
|
117
123
|
const toIndex = state.managers.data.getIndex(toKey);
|
|
@@ -125,11 +131,15 @@ export class SelectionManager {
|
|
|
125
131
|
const selected: Key[] = [];
|
|
126
132
|
|
|
127
133
|
for (let index = start; index <= end; index += 1) {
|
|
128
|
-
|
|
134
|
+
const key = keys[index];
|
|
135
|
+
|
|
136
|
+
if (!(key instanceof GroupComponent)) {
|
|
137
|
+
selected.push(key);
|
|
138
|
+
}
|
|
129
139
|
}
|
|
130
140
|
|
|
131
141
|
if (keyed) {
|
|
132
|
-
this.
|
|
142
|
+
this.add(selected);
|
|
133
143
|
} else {
|
|
134
144
|
this.set(selected);
|
|
135
145
|
}
|
|
@@ -139,23 +149,21 @@ export class SelectionManager {
|
|
|
139
149
|
this.state.managers.navigation.setActive(toKey, false);
|
|
140
150
|
}
|
|
141
151
|
|
|
142
|
-
|
|
152
|
+
remove(keys: Key[]): void {
|
|
143
153
|
const {length} = keys;
|
|
144
154
|
|
|
145
|
-
|
|
155
|
+
const removed: Key[] = [];
|
|
146
156
|
|
|
147
157
|
for (let index = 0; index < length; index += 1) {
|
|
148
158
|
const key = keys[index];
|
|
149
159
|
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
update = true;
|
|
160
|
+
if (this.items.delete(key)) {
|
|
161
|
+
removed.push(key);
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
164
|
|
|
157
|
-
if (
|
|
158
|
-
this.update(
|
|
165
|
+
if (removed.length > 0) {
|
|
166
|
+
this.update(removed);
|
|
159
167
|
}
|
|
160
168
|
}
|
|
161
169
|
|
|
@@ -176,13 +184,12 @@ export class SelectionManager {
|
|
|
176
184
|
|
|
177
185
|
toggle(): void {
|
|
178
186
|
const {items, state} = this;
|
|
187
|
+
const {keys} = state.managers.data;
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (items.size === all.length) {
|
|
189
|
+
if (items.size === keys.length - state.managers.group.items.length) {
|
|
183
190
|
this.clear();
|
|
184
191
|
} else {
|
|
185
|
-
this.
|
|
192
|
+
this.set(keys.filter(key => !(key instanceof GroupComponent)) as Key[]);
|
|
186
193
|
}
|
|
187
194
|
}
|
|
188
195
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {sort, type ArrayKeySorter} from '@oscarpalmer/atoms/array';
|
|
2
2
|
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {compare} from '@oscarpalmer/atoms/value/compare';
|
|
3
4
|
import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
4
|
-
import
|
|
5
|
-
import type {TabelaSort,
|
|
5
|
+
import {GroupComponent} from '../components/group.component';
|
|
6
|
+
import type {TabelaSort, TabelaSortDirection, TabelaSortItem} from '../models/sort.model';
|
|
7
|
+
import type {State} from '../models/tabela.model';
|
|
6
8
|
|
|
7
9
|
export class SortManager {
|
|
8
10
|
handlers = Object.freeze({
|
|
@@ -15,9 +17,9 @@ export class SortManager {
|
|
|
15
17
|
|
|
16
18
|
items: ArrayKeySorter<PlainObject>[] = [];
|
|
17
19
|
|
|
18
|
-
constructor(public state:
|
|
20
|
+
constructor(public state: State) {}
|
|
19
21
|
|
|
20
|
-
add(field: string, direction?:
|
|
22
|
+
add(field: string, direction?: TabelaSortDirection): void {
|
|
21
23
|
const index = this.items.findIndex(item => item.key === field);
|
|
22
24
|
|
|
23
25
|
if (index > -1) {
|
|
@@ -84,7 +86,7 @@ export class SortManager {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
set(items:
|
|
89
|
+
set(items: TabelaSortItem[]): void {
|
|
88
90
|
this.items.splice(
|
|
89
91
|
0,
|
|
90
92
|
this.items.length,
|
|
@@ -119,14 +121,7 @@ export class SortManager {
|
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
state.managers.data.values.keys.active =
|
|
122
|
-
items.length === 0
|
|
123
|
-
? undefined
|
|
124
|
-
: (sort(
|
|
125
|
-
state.managers.data.values.keys.active?.map(
|
|
126
|
-
key => state.managers.data.values.objects.mapped.get(key)!,
|
|
127
|
-
) ?? state.managers.data.values.objects.array,
|
|
128
|
-
items,
|
|
129
|
-
).map(row => row[state.key]) as Key[]);
|
|
124
|
+
items.length === 0 ? undefined : getSortedKeys(state, items);
|
|
130
125
|
|
|
131
126
|
state.managers.render.update(true, true);
|
|
132
127
|
}
|
|
@@ -147,3 +142,71 @@ export class SortManager {
|
|
|
147
142
|
}
|
|
148
143
|
}
|
|
149
144
|
}
|
|
145
|
+
|
|
146
|
+
function getSortedKeys(
|
|
147
|
+
state: State,
|
|
148
|
+
sorters: ArrayKeySorter<PlainObject>[],
|
|
149
|
+
): Array<GroupComponent | Key> {
|
|
150
|
+
const data =
|
|
151
|
+
state.managers.data.values.keys.active?.map(key =>
|
|
152
|
+
key instanceof GroupComponent ? key : state.managers.data.values.objects.mapped.get(key)!,
|
|
153
|
+
) ?? state.managers.data.values.objects.array.slice();
|
|
154
|
+
|
|
155
|
+
if (!state.managers.group.enabled) {
|
|
156
|
+
return sort(data as PlainObject[], sorters).map(
|
|
157
|
+
item => (item as PlainObject)[state.key] as Key,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return sortWithGroups(state, data, sorters).map(item =>
|
|
162
|
+
item instanceof GroupComponent ? item : (item[state.key] as Key),
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function sortWithGroups(
|
|
167
|
+
state: State,
|
|
168
|
+
data: Array<GroupComponent | PlainObject>,
|
|
169
|
+
sorters: ArrayKeySorter<PlainObject>[],
|
|
170
|
+
): Array<GroupComponent | PlainObject> {
|
|
171
|
+
const {length} = sorters;
|
|
172
|
+
|
|
173
|
+
return data.sort((first, second) => {
|
|
174
|
+
const firstValue =
|
|
175
|
+
first instanceof GroupComponent
|
|
176
|
+
? first.value
|
|
177
|
+
: (first as PlainObject)[state.managers.group.field];
|
|
178
|
+
|
|
179
|
+
const secondValue =
|
|
180
|
+
second instanceof GroupComponent
|
|
181
|
+
? second.value
|
|
182
|
+
: (second as PlainObject)[state.managers.group.field];
|
|
183
|
+
|
|
184
|
+
const firstOrder = state.managers.group.order[firstValue as never];
|
|
185
|
+
const secondOrder = state.managers.group.order[secondValue as never];
|
|
186
|
+
|
|
187
|
+
const groupComparison = compare(firstOrder, secondOrder);
|
|
188
|
+
|
|
189
|
+
if (groupComparison !== 0) {
|
|
190
|
+
return groupComparison;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const firstIsGroup = first instanceof GroupComponent;
|
|
194
|
+
const secondIsGroup = second instanceof GroupComponent;
|
|
195
|
+
|
|
196
|
+
if (firstIsGroup || secondIsGroup) {
|
|
197
|
+
return firstIsGroup && secondIsGroup ? 0 : firstIsGroup ? -1 : 1;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for (let index = 0; index < length; index += 1) {
|
|
201
|
+
const sorter = sorters[index];
|
|
202
|
+
|
|
203
|
+
const comparison = compare(first[sorter.key], second[sorter.key]);
|
|
204
|
+
|
|
205
|
+
if (comparison !== 0) {
|
|
206
|
+
return comparison * (sorter.direction === 'ascending' ? 1 : -1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return 0;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type Column = {
|
|
2
2
|
field: string;
|
|
3
3
|
title: string;
|
|
4
4
|
type: TabelaColumnType;
|
|
5
5
|
width: number;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type TabelaColumn = {
|
|
9
9
|
field: string;
|
|
10
10
|
title: string;
|
|
11
11
|
type: TabelaColumnType;
|
package/src/models/data.model.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {GroupComponent} from '../components/group.component';
|
|
2
3
|
|
|
3
4
|
export type DataValues = {
|
|
4
5
|
keys: DataValuesKeys;
|
|
@@ -6,11 +7,21 @@ export type DataValues = {
|
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
type DataValuesKeys = {
|
|
9
|
-
active?: Key
|
|
10
|
-
original: Key
|
|
10
|
+
active?: Array<GroupComponent | Key>;
|
|
11
|
+
original: Array<GroupComponent | Key>;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
type DataValuesObjects = {
|
|
14
|
-
array: PlainObject
|
|
15
|
+
array: Array<GroupComponent | PlainObject>;
|
|
15
16
|
mapped: Map<Key, PlainObject>;
|
|
16
17
|
};
|
|
18
|
+
|
|
19
|
+
export type TabelaData = {
|
|
20
|
+
add(data: PlainObject[]): void;
|
|
21
|
+
clear(): void;
|
|
22
|
+
get(active?: boolean): PlainObject[];
|
|
23
|
+
remove(keys: Key[]): void;
|
|
24
|
+
remove(data: PlainObject[]): void;
|
|
25
|
+
synchronize(data: PlainObject[], remove?: boolean): void;
|
|
26
|
+
update(data: PlainObject[]): void;
|
|
27
|
+
};
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type TabelaFilter = {
|
|
2
|
+
add(item: TabelaFilterItem): void;
|
|
3
|
+
clear(): void;
|
|
4
|
+
remove(field: string): void;
|
|
5
|
+
remove(item: TabelaFilterItem): void;
|
|
6
|
+
set(items: TabelaFilterItem[]): void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TabelaFilterComparison =
|
|
2
10
|
| 'contains'
|
|
3
11
|
| 'ends-with'
|
|
4
12
|
| 'equals'
|
|
@@ -10,8 +18,8 @@ export type FilterComparison =
|
|
|
10
18
|
| 'not-equals'
|
|
11
19
|
| 'starts-with';
|
|
12
20
|
|
|
13
|
-
export type
|
|
14
|
-
comparison:
|
|
21
|
+
export type TabelaFilterItem = {
|
|
22
|
+
comparison: TabelaFilterComparison;
|
|
15
23
|
field: string;
|
|
16
24
|
value: unknown;
|
|
17
25
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {State} from './tabela.model';
|
|
2
2
|
|
|
3
3
|
export type RenderElementPool = {
|
|
4
4
|
cells: Record<string, HTMLDivElement[]>;
|
|
@@ -13,4 +13,4 @@ export type RenderRange = {
|
|
|
13
13
|
export type RenderState = {
|
|
14
14
|
active: boolean;
|
|
15
15
|
top: number;
|
|
16
|
-
} &
|
|
16
|
+
} & State;
|
package/src/models/sort.model.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type TabelaSort = {
|
|
2
|
+
add(field: string, direction?: TabelaSortDirection): void;
|
|
3
|
+
clear(): void;
|
|
4
|
+
flip(field: string): void;
|
|
5
|
+
remove(field: string): void;
|
|
6
|
+
set(items: TabelaSortItem[]): void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TabelaSortDirection = 'ascending' | 'descending';
|
|
2
10
|
|
|
3
|
-
export type
|
|
4
|
-
direction:
|
|
11
|
+
export type TabelaSortItem = {
|
|
12
|
+
direction: TabelaSortDirection;
|
|
5
13
|
field: string;
|
|
6
14
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
1
|
import type {BodyComponent} from '../components/body.component';
|
|
3
2
|
import type {FooterComponent} from '../components/footer.component';
|
|
4
3
|
import type {HeaderComponent} from '../components/header.component';
|
|
@@ -6,44 +5,26 @@ import type {ColumnManager} from '../managers/column.manager';
|
|
|
6
5
|
import type {DataManager} from '../managers/data.manager';
|
|
7
6
|
import type {EventManager} from '../managers/event.manager';
|
|
8
7
|
import type {FilterManager} from '../managers/filter.manager';
|
|
8
|
+
import type { GroupManager } from '../managers/group.manager';
|
|
9
9
|
import type {NavigationManager} from '../managers/navigation.manager';
|
|
10
10
|
import type {RenderManager} from '../managers/render.manager';
|
|
11
11
|
import type {RowManager} from '../managers/row.manager';
|
|
12
12
|
import type {SelectionManager} from '../managers/selection.manager';
|
|
13
13
|
import type {SortManager} from '../managers/sort.manager';
|
|
14
|
-
import type {FilterItem} from './filter.model';
|
|
15
|
-
import type {SortDirection, SortItem} from './sort.model';
|
|
16
14
|
import type {TabelaOptions} from './tabela.options';
|
|
17
15
|
|
|
18
|
-
export type
|
|
16
|
+
export type Components = {
|
|
19
17
|
body: BodyComponent;
|
|
20
18
|
footer: FooterComponent;
|
|
21
19
|
header: HeaderComponent;
|
|
22
20
|
};
|
|
23
21
|
|
|
24
|
-
export type
|
|
25
|
-
add(data: PlainObject[]): void;
|
|
26
|
-
clear(): void;
|
|
27
|
-
get(active?: boolean): PlainObject[];
|
|
28
|
-
remove(keys: Key[]): void;
|
|
29
|
-
remove(data: PlainObject[]): void;
|
|
30
|
-
synchronize(data: PlainObject[], remove?: boolean): void;
|
|
31
|
-
update(data: PlainObject[]): void;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export type TabelaFilter = {
|
|
35
|
-
add(item: FilterItem): void;
|
|
36
|
-
clear(): void;
|
|
37
|
-
remove(field: string): void;
|
|
38
|
-
remove(item: FilterItem): void;
|
|
39
|
-
set(items: FilterItem[]): void;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export type TabelaManagers = {
|
|
22
|
+
export type Managers = {
|
|
43
23
|
column: ColumnManager;
|
|
44
24
|
data: DataManager;
|
|
45
25
|
event: EventManager;
|
|
46
26
|
filter: FilterManager;
|
|
27
|
+
group: GroupManager;
|
|
47
28
|
navigation: NavigationManager;
|
|
48
29
|
row: RowManager;
|
|
49
30
|
selection: SelectionManager;
|
|
@@ -51,26 +32,11 @@ export type TabelaManagers = {
|
|
|
51
32
|
render: RenderManager;
|
|
52
33
|
};
|
|
53
34
|
|
|
54
|
-
export type
|
|
55
|
-
|
|
56
|
-
deselect(keys: Key[]): void;
|
|
57
|
-
select(keys: Key[]): void;
|
|
58
|
-
toggle(): void;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export type TabelaSort = {
|
|
62
|
-
add(field: string, direction?: SortDirection): void;
|
|
63
|
-
clear(): void;
|
|
64
|
-
flip(field: string): void;
|
|
65
|
-
remove(field: string): void;
|
|
66
|
-
set(items: SortItem[]): void;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export type TabelaState = {
|
|
70
|
-
readonly components: TabelaComponents;
|
|
35
|
+
export type State = {
|
|
36
|
+
readonly components: Components;
|
|
71
37
|
readonly element: HTMLElement;
|
|
72
38
|
readonly id: number;
|
|
73
39
|
readonly key: string;
|
|
74
|
-
readonly managers:
|
|
40
|
+
readonly managers: Managers;
|
|
75
41
|
readonly options: TabelaOptions;
|
|
76
42
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {TabelaColumn} from './column.model';
|
|
3
3
|
|
|
4
4
|
export type TabelaOptions = {
|
|
5
|
-
columns:
|
|
5
|
+
columns: TabelaColumn[];
|
|
6
6
|
data: PlainObject[];
|
|
7
|
+
grouping?: string;
|
|
7
8
|
key: string;
|
|
8
9
|
label: string;
|
|
9
10
|
rowHeight: number;
|