@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.
Files changed (108) hide show
  1. package/dist/components/body.component.d.mts +10 -1
  2. package/dist/components/body.component.mjs +8 -6
  3. package/dist/components/column.component.d.mts +15 -1
  4. package/dist/components/column.component.mjs +12 -10
  5. package/dist/components/footer.component.d.mts +12 -1
  6. package/dist/components/footer.component.mjs +6 -6
  7. package/dist/components/group.component.d.mts +19 -1
  8. package/dist/components/group.component.mjs +17 -11
  9. package/dist/components/header.component.d.mts +12 -1
  10. package/dist/components/header.component.mjs +5 -5
  11. package/dist/components/row.component.d.mts +14 -1
  12. package/dist/components/row.component.mjs +21 -17
  13. package/dist/helpers/dom.helpers.d.mts +3 -3
  14. package/dist/helpers/dom.helpers.mjs +12 -11
  15. package/dist/helpers/misc.helpers.d.mts +7 -1
  16. package/dist/helpers/misc.helpers.mjs +12 -1
  17. package/dist/index.d.mts +1 -1
  18. package/dist/managers/column.manager.d.mts +16 -1
  19. package/dist/managers/column.manager.mjs +7 -7
  20. package/dist/managers/data.manager.d.mts +26 -1
  21. package/dist/managers/data.manager.mjs +122 -88
  22. package/dist/managers/event.manager.d.mts +17 -1
  23. package/dist/managers/event.manager.mjs +35 -10
  24. package/dist/managers/filter.manager.d.mts +17 -1
  25. package/dist/managers/filter.manager.mjs +43 -35
  26. package/dist/managers/group.manager.d.mts +26 -1
  27. package/dist/managers/group.manager.mjs +36 -16
  28. package/dist/managers/navigation.manager.d.mts +15 -2
  29. package/dist/managers/navigation.manager.mjs +38 -34
  30. package/dist/managers/render.manager.d.mts +18 -1
  31. package/dist/managers/render.manager.mjs +44 -31
  32. package/dist/managers/row.manager.d.mts +18 -1
  33. package/dist/managers/row.manager.mjs +1 -1
  34. package/dist/managers/selection.manager.d.mts +22 -1
  35. package/dist/managers/selection.manager.mjs +26 -23
  36. package/dist/managers/sort.manager.d.mts +22 -1
  37. package/dist/managers/sort.manager.mjs +71 -49
  38. package/dist/managers/style.manager.d.mts +8 -1
  39. package/dist/managers/style.manager.mjs +57 -25
  40. package/dist/models/body.model.d.mts +6 -1
  41. package/dist/models/column.model.d.mts +13 -2
  42. package/dist/models/data.model.d.mts +28 -2
  43. package/dist/models/dom.model.d.mts +19 -0
  44. package/dist/models/dom.model.mjs +19 -0
  45. package/dist/models/event.model.d.mts +99 -0
  46. package/dist/models/event.model.mjs +53 -0
  47. package/dist/models/filter.model.d.mts +26 -2
  48. package/dist/models/filter.model.mjs +13 -1
  49. package/dist/models/footer.model.d.mts +7 -1
  50. package/dist/models/group.model.d.mts +19 -2
  51. package/dist/models/group.model.mjs +5 -1
  52. package/dist/models/header.model.d.mts +6 -1
  53. package/dist/models/render.model.d.mts +22 -2
  54. package/dist/models/selection.model.d.mts +11 -1
  55. package/dist/models/sort.model.d.mts +19 -2
  56. package/dist/models/sort.model.mjs +5 -1
  57. package/dist/models/style.model.d.mts +27 -21
  58. package/dist/models/style.model.mjs +27 -21
  59. package/dist/models/tabela.model.d.mts +45 -1
  60. package/dist/models/tabela.options.d.mts +13 -1
  61. package/dist/tabela.d.mts +9 -8
  62. package/dist/tabela.full.mjs +1083 -574
  63. package/dist/tabela.mjs +19 -19
  64. package/package.json +2 -4
  65. package/src/components/body.component.ts +10 -7
  66. package/src/components/column.component.ts +20 -16
  67. package/src/components/footer.component.ts +7 -10
  68. package/src/components/group.component.ts +39 -13
  69. package/src/components/header.component.ts +6 -5
  70. package/src/components/row.component.ts +27 -19
  71. package/src/helpers/dom.helpers.ts +18 -22
  72. package/src/helpers/misc.helpers.ts +17 -0
  73. package/src/managers/column.manager.ts +9 -9
  74. package/src/managers/data.manager.ts +196 -107
  75. package/src/managers/event.manager.ts +69 -12
  76. package/src/managers/filter.manager.ts +70 -41
  77. package/src/managers/group.manager.ts +60 -18
  78. package/src/managers/navigation.manager.ts +46 -49
  79. package/src/managers/render.manager.ts +60 -34
  80. package/src/managers/row.manager.ts +1 -1
  81. package/src/managers/selection.manager.ts +37 -35
  82. package/src/managers/sort.manager.ts +114 -72
  83. package/src/managers/style.manager.ts +73 -25
  84. package/src/models/column.model.ts +4 -8
  85. package/src/models/data.model.ts +13 -14
  86. package/src/models/dom.model.ts +31 -0
  87. package/src/models/event.model.ts +175 -0
  88. package/src/models/filter.model.ts +22 -2
  89. package/src/models/group.model.ts +13 -0
  90. package/src/models/render.model.ts +6 -0
  91. package/src/models/sort.model.ts +11 -5
  92. package/src/models/style.model.ts +32 -20
  93. package/src/models/tabela.model.ts +1 -0
  94. package/src/tabela.ts +26 -24
  95. package/dist/body.component-_VDOpJhV.d.mts +0 -10
  96. package/dist/body.model-2iwsovAV.d.mts +0 -7
  97. package/dist/column.component-Bx46r3JI.d.mts +0 -16
  98. package/dist/column.model-D-aw4EU4.d.mts +0 -16
  99. package/dist/filter.model-7ukJrtil.d.mts +0 -16
  100. package/dist/footer.component-Curiab8j.d.mts +0 -12
  101. package/dist/footer.model-DhqoS6ds.d.mts +0 -8
  102. package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
  103. package/dist/group.model-BsKFwHbt.d.mts +0 -10
  104. package/dist/header.component-BjjlpZIg.d.mts +0 -12
  105. package/dist/header.model-DN_KzUCV.d.mts +0 -7
  106. package/dist/selection.model-rwQe9fco.d.mts +0 -12
  107. package/dist/sort.model-CauImaLu.d.mts +0 -15
  108. package/dist/tabela.options-RkZvfptB.d.mts +0 -14
@@ -1,4 +1,7 @@
1
+ import { EVENT_DATA_ADD, EVENT_DATA_CLEAR, EVENT_DATA_REMOVE, EVENT_DATA_SYNCHRONIZE, EVENT_DATA_UPDATE, EVENT_GROUP_ADD, EVENT_GROUP_REMOVE, EVENT_GROUP_UPDATE } from "../models/event.model.mjs";
1
2
  import { GroupComponent, updateGroup } from "../components/group.component.mjs";
3
+ import { getGroup, isGroupKey } from "../helpers/misc.helpers.mjs";
4
+ import { SORT_ASCENDING } from "../models/sort.model.mjs";
2
5
  import { sortWithGroups } from "./sort.manager.mjs";
3
6
  import { chunk, select, sort } from "@oscarpalmer/atoms/array";
4
7
  import { toMap } from "@oscarpalmer/atoms/array/to-map";
@@ -8,25 +11,25 @@ import { delay } from "@oscarpalmer/atoms/promise/delay";
8
11
  import { getValue } from "@oscarpalmer/atoms/value/handle";
9
12
  //#region src/managers/data.manager.ts
10
13
  var DataManager = class {
11
- handlers = Object.freeze({
12
- add: (data) => void this.add(data, true),
13
- clear: () => void this.clear(),
14
+ handlers = {
15
+ add: (data) => this.add(data, true),
16
+ clear: () => this.clear(),
14
17
  get: (active) => this.get(active),
15
- remove: (items) => void this.remove(items, true),
16
- synchronize: (data, remove) => void this.synchronize(data, remove),
17
- update: (data) => void this.update(data)
18
- });
18
+ remove: (items) => this.remove(items, true),
19
+ synchronize: (data, remove) => this.synchronize(data, remove === true),
20
+ update: (data) => this.update(data, true)
21
+ };
19
22
  state;
20
- get items() {
21
- return this.state.items.active ?? this.state.items.original;
23
+ get keys() {
24
+ return this.state.keys.active ?? this.state.keys.original;
22
25
  }
23
26
  get size() {
24
- return this.items.length;
27
+ return this.keys.length;
25
28
  }
26
29
  constructor(state) {
27
30
  this.state = {
28
31
  ...state,
29
- items: { original: [] },
32
+ keys: { original: [] },
30
33
  values: {
31
34
  array: [],
32
35
  mapped: /* @__PURE__ */ new Map()
@@ -35,125 +38,151 @@ var DataManager = class {
35
38
  }
36
39
  async add(data, render) {
37
40
  const { state } = this;
38
- const groups = [];
39
- const updates = [];
41
+ const addedData = [];
42
+ const updatedData = [];
43
+ const addedGroups = [];
44
+ const updatedGroups = [];
40
45
  let groupColumn;
41
46
  let { length } = data;
42
47
  for (let index = 0; index < length; index += 1) {
43
48
  const item = data[index];
44
49
  const key = getValue(item, state.key);
45
50
  if (state.values.mapped.has(key)) {
46
- updates.push(item);
51
+ updatedData.push(item);
47
52
  continue;
48
53
  }
54
+ addedData.push(item);
49
55
  state.values.array.push(item);
50
56
  state.values.mapped.set(key, item);
51
57
  if (!state.managers.group.enabled) continue;
52
- const groupValue = getValue(item, state.managers.group.field);
53
- let group = state.managers.group.get(groupValue);
58
+ const groupValue = getValue(item, state.managers.group.key);
59
+ let group = state.managers.group.getForValue(groupValue);
54
60
  if (group == null) {
55
- groupColumn ??= state.managers.column.get(state.managers.group.field);
56
- group = new GroupComponent(`${groupColumn?.options.title ?? state.managers.group.field}: ${groupValue}`, groupValue);
57
- state.values.array.push(group);
58
- state.managers.group.add(group);
59
- }
61
+ groupColumn ??= state.managers.column.get(state.managers.group.key);
62
+ group = new GroupComponent(`${groupColumn?.options.label ?? state.managers.group.key}: ${groupValue}`, groupValue);
63
+ state.values.array.push(group.key);
64
+ state.managers.group.add(group, false);
65
+ addedGroups.push(group);
66
+ } else if (!addedGroups.includes(group) && !updatedGroups.includes(group)) updatedGroups.push(group);
60
67
  if (!group.expanded) state.managers.group.collapsed.add(key);
61
68
  group.total += 1;
62
- groups.push(group);
63
69
  }
64
- length = groups.length;
65
- for (let index = 0; index < length; index += 1) updateGroup(state, groups[index]);
66
- if (updates.length > 0) this.update(updates);
67
- else if (render) this.render();
70
+ length = addedGroups.length;
71
+ if (length > 0) {
72
+ state.managers.event.emit(EVENT_GROUP_ADD, addedGroups.map(getGroup));
73
+ for (let index = 0; index < length; index += 1) updateGroup(state, addedGroups[index], false);
74
+ }
75
+ length = updatedGroups.length;
76
+ if (length > 0) {
77
+ for (let index = 0; index < length; index += 1) updateGroup(state, updatedGroups[index], false);
78
+ state.managers.event.emit(EVENT_GROUP_UPDATE, updatedGroups.map(getGroup));
79
+ }
80
+ await this.update(updatedData, addedData.length === 0);
81
+ if (addedData.length === 0) return;
82
+ state.managers.event.emit(EVENT_DATA_ADD, addedData);
83
+ if (render) this.render();
68
84
  }
69
- clear() {
70
- if (this.state.values.array.length > 0) this.removeItems([], true, true);
85
+ async clear() {
86
+ if (this.state.values.array.length > 0) return this.removeItems([], true, true).then(() => void 0);
71
87
  }
72
88
  destroy() {
73
89
  const { state } = this;
74
90
  state.values.mapped.clear();
75
- state.items.active = void 0;
76
- state.items.original.length = 0;
91
+ state.keys.active = void 0;
92
+ state.keys.original.length = 0;
77
93
  state.values.array.length = 0;
78
94
  this.handlers = void 0;
79
95
  this.state = void 0;
80
96
  }
81
97
  get(active) {
82
98
  const { state } = this;
83
- return active ?? false ? select(state.items.active ?? [], (key) => !(key instanceof GroupComponent), (key) => state.values.mapped.get(key)) : state.values.array.filter((item) => !(item instanceof GroupComponent));
99
+ return (active ?? false) && state.keys.active != null ? select(state.keys.active, (key) => !isGroupKey(key), (key) => state.values.mapped.get(key)) : state.values.array.filter((item) => !isGroupKey(item));
84
100
  }
85
101
  getIndex(item) {
86
- if (item instanceof GroupComponent) return this.items.indexOf(item);
87
- return this.items.findIndex((value) => value instanceof GroupComponent ? value.key === item : value === item);
102
+ return this.keys.indexOf(item);
88
103
  }
89
104
  async remove(items, render) {
90
105
  const { state } = this;
91
- const keys = items.map((value) => isPlainObject(value) ? getValue(value, state.key) : value);
106
+ const keys = items.map((value) => isPlainObject(value) ? getValue(value, state.key) : value).filter((key) => !isGroupKey(key));
92
107
  const { length } = keys;
93
- if (length > 0) return this.removeItems(keys, false, render === true);
108
+ return length === 0 ? render ? void 0 : [] : this.removeItems(keys, false, render);
94
109
  }
95
- async removeItems(items, clear, render) {
110
+ async removeItems(keys, clear, render) {
96
111
  const { state } = this;
97
112
  if (clear) {
98
- state.items.active = void 0;
99
- state.items.original = [];
113
+ state.keys.active = void 0;
114
+ state.keys.original = [];
100
115
  state.values.array = [];
101
116
  state.values.mapped.clear();
102
117
  state.managers.row.clear();
103
118
  if (state.managers.group.enabled) state.managers.group.clear();
104
- return this.render();
119
+ state.managers.event.emit(EVENT_DATA_CLEAR);
120
+ this.render();
121
+ return render ? void 0 : [];
105
122
  }
106
- const groups = [];
107
- const chunked = chunk(items);
123
+ const removedGroups = [];
124
+ const updatedGroups = [];
125
+ const removedData = [];
126
+ const chunked = chunk(keys);
108
127
  const chunkedLength = chunked.length;
109
128
  for (let chunkedIndex = 0; chunkedIndex < chunkedLength; chunkedIndex += 1) {
110
129
  const chunk = chunked[chunkedIndex];
111
130
  const chunkLength = chunk.length;
112
- for (let itemIndex = 0; itemIndex < chunkLength; itemIndex += 1) {
113
- const item = chunk[itemIndex];
114
- const dataIndex = state.items.original.indexOf(item);
131
+ for (let keyIndex = 0; keyIndex < chunkLength; keyIndex += 1) {
132
+ const key = chunk[keyIndex];
133
+ const dataIndex = state.keys.original.indexOf(key);
115
134
  let dataValue;
116
135
  [dataValue] = state.values.array.splice(dataIndex, 1);
117
- state.items.original.splice(dataIndex, 1);
118
- state.managers.row.remove(item);
119
- state.values.mapped.delete(item);
120
- if (!state.managers.group.enabled || item instanceof GroupComponent) continue;
121
- state.managers.group.collapsed.delete(item);
122
- const groupKey = getValue(dataValue, state.managers.group.field);
123
- const group = state.managers.group.get(groupKey);
136
+ removedData.push(dataValue);
137
+ state.keys.original.splice(dataIndex, 1);
138
+ state.managers.row.remove(key);
139
+ state.values.mapped.delete(key);
140
+ if (!state.managers.group.enabled || isGroupKey(key)) continue;
141
+ state.managers.group.collapsed.delete(key);
142
+ const groupValue = getValue(dataValue, state.managers.group.key);
143
+ const group = state.managers.group.getForValue(groupValue);
124
144
  if (group == null) continue;
125
145
  group.total -= 1;
126
146
  if (group.total > 0) {
127
- groups.push(group);
147
+ updatedGroups.push(group);
128
148
  continue;
129
149
  }
130
- let groupIndex = groups.indexOf(group);
131
- if (groupIndex > -1) groups.splice(groupIndex, 1);
132
- groupIndex = state.values.array.indexOf(group);
150
+ let groupIndex = updatedGroups.indexOf(group);
151
+ if (groupIndex > -1) updatedGroups.splice(groupIndex, 1);
152
+ groupIndex = state.values.array.indexOf(group.key);
133
153
  if (groupIndex > -1) {
134
- state.items.original.splice(groupIndex, 1);
154
+ state.keys.original.splice(groupIndex, 1);
135
155
  state.values.array.splice(groupIndex, 1);
136
156
  }
137
- state.managers.group.remove(group);
138
- if (items.length >= 1e4) await delay(25);
157
+ removedGroups.push(group);
158
+ state.managers.group.remove(group, false);
159
+ if (keys.length >= 1e4) await delay(25);
139
160
  }
140
161
  }
141
- const { length } = groups;
142
- for (let index = 0; index < length; index += 1) updateGroup(state, groups[index]);
143
- if (render) return this.render();
162
+ let { length } = updatedGroups;
163
+ if (length > 0) {
164
+ for (let index = 0; index < length; index += 1) updateGroup(state, updatedGroups[index], false);
165
+ state.managers.event.emit(EVENT_GROUP_UPDATE, updatedGroups.map(getGroup));
166
+ }
167
+ length = removedGroups.length;
168
+ if (length > 0) state.managers.event.emit(EVENT_GROUP_REMOVE, removedGroups.map(getGroup));
169
+ state.managers.event.emit(EVENT_DATA_REMOVE, removedData);
170
+ if (render) this.render();
171
+ return render ? void 0 : removedData;
144
172
  }
145
173
  render() {
146
174
  const { state } = this;
147
175
  if (state.managers.group.enabled) sortWithGroups(state, state.values.array, [{
148
- direction: "ascending",
176
+ direction: SORT_ASCENDING,
149
177
  key: state.key
150
178
  }]);
151
179
  else sort(state.values.array, [{
152
- direction: "ascending",
180
+ direction: SORT_ASCENDING,
153
181
  key: state.key
154
182
  }]);
155
- state.items.original = state.values.array.map((item) => item instanceof GroupComponent ? item : getValue(item, state.key));
156
- state.values.mapped = toMap(state.values.array.filter((item) => !(item instanceof GroupComponent)), (item) => getValue(item, state.key));
183
+ state.keys.active = void 0;
184
+ state.keys.original = state.values.array.map((item) => typeof item === "string" ? item : getValue(item, state.key));
185
+ state.values.mapped = toMap(state.values.array.filter((item) => !isGroupKey(item)), (item) => getValue(item, state.key));
157
186
  if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
158
187
  else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
159
188
  else state.managers.render.update(true, true);
@@ -162,17 +191,17 @@ var DataManager = class {
162
191
  const { state } = this;
163
192
  const array = data.slice();
164
193
  if (state.managers.group.enabled) {
165
- const column = state.managers.column.get(state.managers.group.field);
166
- const grouped = toRecord.arrays(data, state.managers.group.field);
194
+ const column = state.managers.column.get(state.managers.group.key);
195
+ const grouped = toRecord.arrays(data, state.managers.group.key);
167
196
  const entries = Object.entries(grouped);
168
197
  const { length } = entries;
169
198
  const groups = [];
170
199
  for (let index = 0; index < length; index += 1) {
171
200
  const [value, items] = entries[index];
172
- const group = new GroupComponent(`${column?.options.title ?? state.managers.group.field}: ${value}`, value);
201
+ const group = new GroupComponent(`${column?.options.label ?? state.managers.group.key}: ${value}`, value);
173
202
  group.total = items.length;
174
203
  groups.push(group);
175
- array.push(group);
204
+ array.push(group.key);
176
205
  }
177
206
  state.managers.group.set(groups);
178
207
  }
@@ -181,7 +210,7 @@ var DataManager = class {
181
210
  }
182
211
  async synchronize(data, remove) {
183
212
  const { state } = this;
184
- const add = [];
213
+ const added = [];
185
214
  const updated = [];
186
215
  const keys = /* @__PURE__ */ new Set([]);
187
216
  const { length } = data;
@@ -189,33 +218,38 @@ var DataManager = class {
189
218
  const object = data[index];
190
219
  const key = getValue(object, state.key);
191
220
  if (state.values.mapped.has(key)) updated.push(object);
192
- else add.push(object);
221
+ else added.push(object);
193
222
  keys.add(key);
194
223
  }
195
224
  if (keys.size === 0) return;
196
- if (remove ?? false) {
197
- const toRemove = state.items.original.filter((key) => !(key instanceof GroupComponent) && !keys.has(key));
198
- if (toRemove.length > 0) await this.remove(toRemove, false);
225
+ let removed = [];
226
+ if (remove) {
227
+ const toRemove = state.keys.original.filter((key) => !isGroupKey(key) && !keys.has(key));
228
+ if (toRemove.length > 0) removed = await this.remove(toRemove, false);
199
229
  }
200
- await this.update(updated);
201
- if (add.length > 0) await this.add(add, false);
202
- if (add.length > 0 || (remove ?? false)) this.render();
230
+ await this.update(updated, added.length === 0);
231
+ await this.add(added, false);
232
+ state.managers.event.emit(EVENT_DATA_SYNCHRONIZE, {
233
+ added,
234
+ removed,
235
+ updated
236
+ });
237
+ if (added.length > 0 || remove) this.render();
203
238
  }
204
- async update(data) {
239
+ async update(data, render) {
205
240
  const { state } = this;
206
241
  const { length } = data;
242
+ const updated = [];
207
243
  for (let index = 0; index < length; index += 1) {
208
- const object = data[index];
209
- const key = getValue(object, state.key);
210
- const value = state.values.mapped.get(key);
211
- if (value != null) {
212
- state.values.mapped.set(key, {
213
- ...value,
214
- ...object
215
- });
216
- state.managers.row.update(key);
217
- }
244
+ const item = data[index];
245
+ const key = getValue(item, state.key);
246
+ const existing = state.keys.original.indexOf(key);
247
+ if (existing === -1) continue;
248
+ Object.assign(state.values.array[existing], item);
249
+ updated.push(state.values.array[existing]);
250
+ if (render && state.managers.render.visible.keys.has(key)) state.managers.row.update(key);
218
251
  }
252
+ if (updated.length > 0) state.managers.event.emit(EVENT_DATA_UPDATE, updated);
219
253
  }
220
254
  };
221
255
  //#endregion
@@ -1,2 +1,18 @@
1
- import { C as EventManager } from "../group.component-Cq1YYbfJ.mjs";
1
+ import { EventMap, EventName, Events, TabelaEvents } from "../models/event.model.mjs";
2
+ import { State } from "../models/tabela.model.mjs";
3
+ import { GenericCallback } from "@oscarpalmer/atoms/models";
4
+
5
+ //#region src/managers/event.manager.d.ts
6
+ declare class EventManager {
7
+ state: State;
8
+ events: Events;
9
+ handlers: TabelaEvents;
10
+ constructor(state: State);
11
+ emit<Name extends EventName>(name: Name, ...parameters: Parameters<EventMap[Name]>): void;
12
+ destroy(): void;
13
+ onSort(event: MouseEvent, target: HTMLElement): void;
14
+ subscribe(name: string, callback: GenericCallback): void;
15
+ unsubscribe(name: string, callback: GenericCallback): void;
16
+ }
17
+ //#endregion
2
18
  export { EventManager };
@@ -1,32 +1,55 @@
1
+ import { ATTRIBUTE_DATA_EVENT, ATTRIBUTE_DATA_KEY, ATTRIBUTE_DATA_SORT_DIRECTION } from "../models/dom.model.mjs";
2
+ import { CSS_TABLE } from "../models/style.model.mjs";
3
+ import { EVENT_GROUP, EVENT_HEADING } from "../models/event.model.mjs";
4
+ import { isEvent } from "../helpers/misc.helpers.mjs";
1
5
  import { on } from "@oscarpalmer/toretto/event";
2
6
  import { findAncestor } from "@oscarpalmer/toretto/find";
3
7
  //#region src/managers/event.manager.ts
4
8
  var EventManager = class {
9
+ events = {};
10
+ handlers = {
11
+ subscribe: (name, callback) => this.subscribe(name, callback),
12
+ unsubscribe: (name, callback) => this.unsubscribe(name, callback)
13
+ };
5
14
  constructor(state) {
6
15
  this.state = state;
7
16
  mapped.set(state.element, this);
8
17
  }
18
+ emit(name, ...parameters) {
19
+ if (this.events[name] == null) return;
20
+ const handlers = [...this.events[name]];
21
+ const { length } = handlers;
22
+ for (let index = 0; index < length; index += 1) handlers[index](...parameters);
23
+ }
9
24
  destroy() {
10
25
  mapped.delete(this.state.element);
11
26
  this.state = void 0;
12
27
  }
13
28
  onSort(event, target) {
14
- const direction = target.getAttribute("data-sort-direction");
15
- const field = target.getAttribute("data-field");
16
- if (field != null) this.state.managers.sort.toggle(event, field, direction);
29
+ const direction = target.getAttribute(ATTRIBUTE_DATA_SORT_DIRECTION);
30
+ const key = target.getAttribute(ATTRIBUTE_DATA_KEY);
31
+ if (key != null) this.state.managers.sort.toggle(event, key, direction);
32
+ }
33
+ subscribe(name, callback) {
34
+ if (!isEvent(name) || typeof callback !== "function") return;
35
+ this.events[name] ??= /* @__PURE__ */ new Set();
36
+ this.events[name].add(callback);
37
+ }
38
+ unsubscribe(name, callback) {
39
+ if (isEvent(name) && typeof callback === "function") this.events[name]?.delete(callback);
17
40
  }
18
41
  };
19
42
  function onClick(event) {
20
- const target = findAncestor(event, "[data-event]");
21
- const table = findAncestor(event, ".tabela__table");
43
+ const target = findAncestor(event, eventAttribute);
44
+ const table = findAncestor(event, tableClassName);
22
45
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
23
46
  const manager = mapped.get(table);
24
47
  if (manager == null) return;
25
- switch (target?.getAttribute("data-event")) {
26
- case "group":
48
+ switch (target?.getAttribute(ATTRIBUTE_DATA_EVENT)) {
49
+ case EVENT_GROUP:
27
50
  manager.state.managers.group.handle(target);
28
51
  break;
29
- case "heading":
52
+ case EVENT_HEADING:
30
53
  manager.onSort(event, target);
31
54
  break;
32
55
  case "row":
@@ -36,8 +59,8 @@ function onClick(event) {
36
59
  }
37
60
  }
38
61
  function onKeydown(event) {
39
- const target = findAncestor(event, "[data-event]");
40
- const table = findAncestor(event, ".tabela__table");
62
+ const target = findAncestor(event, eventAttribute);
63
+ const table = findAncestor(event, tableClassName);
41
64
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
42
65
  const manager = mapped.get(table);
43
66
  if (manager == null) return;
@@ -47,7 +70,9 @@ function onKeydown(event) {
47
70
  }
48
71
  manager.state.managers.navigation.handle(event);
49
72
  }
73
+ const eventAttribute = `[${ATTRIBUTE_DATA_EVENT}]`;
50
74
  const mapped = /* @__PURE__ */ new WeakMap();
75
+ const tableClassName = `.${CSS_TABLE}`;
51
76
  on(document, "click", onClick);
52
77
  on(document, "keydown", onKeydown, { passive: false });
53
78
  //#endregion
@@ -1,2 +1,18 @@
1
- import { S as FilterManager } from "../group.component-Cq1YYbfJ.mjs";
1
+ import { TabelaFilter, TabelaFilterItem } from "../models/filter.model.mjs";
2
+ import { State } from "../models/tabela.model.mjs";
3
+
4
+ //#region src/managers/filter.manager.d.ts
5
+ declare class FilterManager {
6
+ state: State;
7
+ handlers: TabelaFilter;
8
+ items: Record<string, TabelaFilterItem[]>;
9
+ constructor(state: State);
10
+ add(item: TabelaFilterItem): void;
11
+ clear(): void;
12
+ destroy(): void;
13
+ filter(): void;
14
+ remove(value: string | TabelaFilterItem): void;
15
+ set(items: TabelaFilterItem[]): void;
16
+ }
17
+ //#endregion
2
18
  export { FilterManager };
@@ -1,31 +1,34 @@
1
- import { GroupComponent } from "../components/group.component.mjs";
1
+ import { isGroupKey } from "../helpers/misc.helpers.mjs";
2
+ import { FILTER_CONTAINS, FILTER_ENDS_WITH, FILTER_EQUALS, FILTER_GREATER_THAN, FILTER_GREATER_THAN_OR_EQUAL, FILTER_LESS_THAN, FILTER_LESS_THAN_OR_EQUAL, FILTER_NOT_CONTAINS, FILTER_NOT_EQUALS, FILTER_STARTS_WITH } from "../models/filter.model.mjs";
2
3
  import { getString } from "@oscarpalmer/atoms/string";
3
4
  import { getNumber } from "@oscarpalmer/atoms/number";
4
5
  import { endsWith, includes, startsWith } from "@oscarpalmer/atoms/string/match";
5
6
  import { equal } from "@oscarpalmer/atoms/value/equal";
6
7
  //#region src/managers/filter.manager.ts
7
8
  var FilterManager = class {
8
- handlers = Object.freeze({
9
+ handlers = {
9
10
  add: (item) => this.add(item),
10
11
  clear: () => this.clear(),
11
12
  remove: (value) => this.remove(value),
12
13
  set: (items) => this.set(items)
13
- });
14
+ };
14
15
  items = {};
15
16
  constructor(state) {
16
17
  this.state = state;
17
18
  }
18
19
  add(item) {
19
- if (this.items[item.field] == null) this.items[item.field] = [];
20
- else if (this.items[item.field].findIndex((existing) => equal(existing, item)) > -1) return;
21
- this.items[item.field].push(item);
20
+ const { items, state } = this;
21
+ if (items[item.key] == null) items[item.key] = [];
22
+ else if (items[item.key].findIndex((existing) => equal(existing, item)) > -1) return;
23
+ items[item.key].push(item);
24
+ state.managers.event.emit("filter:add", [item]);
22
25
  this.filter();
23
26
  }
24
27
  clear() {
25
- if (Object.keys(this.items).length > 0) {
26
- this.items = {};
27
- this.filter();
28
- }
28
+ if (Object.keys(this.items).length === 0) return;
29
+ this.items = {};
30
+ this.state.managers.event.emit("filter:clear");
31
+ this.filter();
29
32
  }
30
33
  destroy() {
31
34
  this.handlers = void 0;
@@ -36,18 +39,18 @@ var FilterManager = class {
36
39
  const { state } = this;
37
40
  const filtered = [];
38
41
  const filters = Object.entries(this.items);
39
- const itemsLength = state.managers.data.state.items.original.length;
42
+ const itemsLength = state.managers.data.state.keys.original.length;
40
43
  rowLoop: for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
41
- const item = state.managers.data.state.items.original[itemIndex];
42
- if (item instanceof GroupComponent) {
44
+ const item = state.managers.data.state.keys.original[itemIndex];
45
+ if (isGroupKey(item)) {
43
46
  filtered.push(item);
44
47
  continue;
45
48
  }
46
49
  const row = state.managers.data.state.values.mapped.get(item);
47
50
  if (row == null) continue;
48
51
  filterLoop: for (let filterIndex = 0; filterIndex < filters.length; filterIndex += 1) {
49
- const [field, items] = filters[filterIndex];
50
- const value = row[field];
52
+ const [key, items] = filters[filterIndex];
53
+ const value = row[key];
51
54
  for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) {
52
55
  const filter = items[itemIndex];
53
56
  if (comparators[filter.comparison](value, filter.value)) continue filterLoop;
@@ -56,26 +59,31 @@ var FilterManager = class {
56
59
  }
57
60
  filtered.push(item);
58
61
  }
59
- state.managers.data.state.items.active = filtered;
62
+ state.managers.data.state.keys.active = filtered;
60
63
  if (state.managers.sort.items.length > 0) state.managers.sort.sort();
61
64
  else state.managers.render.update(true, true);
62
65
  }
63
66
  remove(value) {
67
+ const removed = [];
64
68
  if (typeof value === "string") {
65
69
  if (this.items[value] == null) return;
66
70
  const keyed = {};
67
- const filters = Object.keys(this.items);
68
- const { length } = filters;
71
+ const keys = Object.keys(this.items);
72
+ const { length } = keys;
69
73
  for (let index = 0; index < length; index += 1) {
70
- const field = filters[index];
71
- if (field !== value) keyed[field] = this.items[field];
74
+ const key = keys[index];
75
+ if (key === value) removed.push(...this.items[key]);
76
+ else keyed[key] = this.items[key];
72
77
  }
73
78
  this.items = keyed;
74
79
  } else {
75
- const { field } = value;
76
- if (this.items[field] == null) return;
77
- if (this.items[field].findIndex((item) => equal(item, value)) === -1) return;
80
+ const { key } = value;
81
+ if (this.items[key] == null) return;
82
+ const index = this.items[key].findIndex((item) => equal(item, value));
83
+ if (index === -1) return;
84
+ removed.push(this.items[key][index]);
78
85
  }
86
+ this.state.managers.event.emit("filter:remove", removed);
79
87
  this.filter();
80
88
  }
81
89
  set(items) {
@@ -83,24 +91,24 @@ var FilterManager = class {
83
91
  const { length } = items;
84
92
  for (let index = 0; index < length; index += 1) {
85
93
  const item = items[index];
86
- keyed[item.field] ??= [];
87
- keyed[item.field].push(item);
94
+ keyed[item.key] ??= [];
95
+ keyed[item.key].push(item);
88
96
  }
89
97
  this.items = keyed;
90
98
  this.filter();
91
99
  }
92
100
  };
93
101
  const comparators = {
94
- contains: (row, filter) => includes(getString(row), getString(filter), true),
95
- "ends-with": (row, filter) => endsWith(getString(row), getString(filter), true),
96
- equals: (row, filter) => equalizer(row, filter),
97
- "greater-than": (row, filter) => getNumber(row) > getNumber(filter),
98
- "greater-than-or-equal": (row, filter) => getNumber(row) >= getNumber(filter),
99
- "less-than": (row, filter) => getNumber(row) < getNumber(filter),
100
- "less-than-or-equal": (row, filter) => getNumber(row) <= getNumber(filter),
101
- "not-contains": (row, filter) => !includes(getString(row), getString(filter), true),
102
- "not-equals": (row, filter) => !equalizer(row, filter),
103
- "starts-with": (row, filter) => startsWith(getString(row), getString(filter), true)
102
+ [FILTER_CONTAINS]: (row, filter) => includes(getString(row), getString(filter), true),
103
+ [FILTER_ENDS_WITH]: (row, filter) => endsWith(getString(row), getString(filter), true),
104
+ [FILTER_EQUALS]: (row, filter) => equalizer(row, filter),
105
+ [FILTER_GREATER_THAN]: (row, filter) => getNumber(row) > getNumber(filter),
106
+ [FILTER_GREATER_THAN_OR_EQUAL]: (row, filter) => getNumber(row) >= getNumber(filter),
107
+ [FILTER_LESS_THAN]: (row, filter) => getNumber(row) < getNumber(filter),
108
+ [FILTER_LESS_THAN_OR_EQUAL]: (row, filter) => getNumber(row) <= getNumber(filter),
109
+ [FILTER_NOT_CONTAINS]: (row, filter) => !includes(getString(row), getString(filter), true),
110
+ [FILTER_NOT_EQUALS]: (row, filter) => !equalizer(row, filter),
111
+ [FILTER_STARTS_WITH]: (row, filter) => startsWith(getString(row), getString(filter), true)
104
112
  };
105
113
  const equalizer = equal.initialize({ ignoreCase: true });
106
114
  //#endregion
@@ -1,2 +1,27 @@
1
- import { x as GroupManager } from "../group.component-Cq1YYbfJ.mjs";
1
+ import { TabelaGroupHandlers } from "../models/group.model.mjs";
2
+ import { GroupComponent } from "../components/group.component.mjs";
3
+ import { State } from "../models/tabela.model.mjs";
4
+ import { Key } from "@oscarpalmer/atoms/models";
5
+
6
+ //#region src/managers/group.manager.d.ts
7
+ declare class GroupManager {
8
+ state: State;
9
+ collapsed: Set<Key>;
10
+ enabled: boolean;
11
+ key: string;
12
+ handlers: TabelaGroupHandlers;
13
+ items: GroupComponent[];
14
+ mapped: Map<string, GroupComponent>;
15
+ order: Record<never, number>;
16
+ constructor(state: State);
17
+ add(group: GroupComponent, emit: boolean): void;
18
+ clear(): void;
19
+ destroy(): void;
20
+ getForKey(key: string): GroupComponent | undefined;
21
+ getForValue(value: unknown): GroupComponent | undefined;
22
+ handle(button: HTMLElement): void;
23
+ remove(group: GroupComponent, update: boolean): void;
24
+ set(items: GroupComponent[]): void;
25
+ }
26
+ //#endregion
2
27
  export { GroupManager };