@cocreate/elements 1.42.7 → 1.42.9
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/.github/workflows/automated.yml +5 -6
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/index.js +1349 -1492
package/src/index.js
CHANGED
|
@@ -26,14 +26,14 @@ import Observer from "@cocreate/observer";
|
|
|
26
26
|
import Actions from "@cocreate/actions";
|
|
27
27
|
import CRUD from "@cocreate/crud-client";
|
|
28
28
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
dotNotationToObject,
|
|
30
|
+
queryElements,
|
|
31
|
+
queryData,
|
|
32
|
+
sortData,
|
|
33
|
+
getAttributes,
|
|
34
|
+
getAttributeNames,
|
|
35
|
+
checkValue,
|
|
36
|
+
getValueFromObject
|
|
37
37
|
} from "@cocreate/utils";
|
|
38
38
|
import filter from "@cocreate/filter";
|
|
39
39
|
import { render, renderValue, renderedNodes } from "@cocreate/render";
|
|
@@ -43,9 +43,9 @@ import { reset } from "./form";
|
|
|
43
43
|
import "./value.js";
|
|
44
44
|
|
|
45
45
|
const selector = "[storage], [database], [array], [render-json]";
|
|
46
|
-
const elements = new
|
|
46
|
+
const elements = new WeakMap();
|
|
47
|
+
const forms = new WeakMap();
|
|
47
48
|
const keys = new Map();
|
|
48
|
-
const forms = new Map();
|
|
49
49
|
const debounce = new Map();
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -59,1579 +59,1436 @@ const debounce = new Map();
|
|
|
59
59
|
* - render-json: Determines how JSON data is rendered.
|
|
60
60
|
*
|
|
61
61
|
* @param {(Element|Element[])} [elements] - Optional. A single element or an array of elements to initialize.
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* If omitted, the function queries and initializes all elements containing
|
|
63
|
+
* any of these CRUD attributes: "storage", "database", "array", "render-json".
|
|
64
64
|
*/
|
|
65
65
|
async function init(element) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
66
|
+
if (
|
|
67
|
+
element &&
|
|
68
|
+
!(element instanceof HTMLCollection) &&
|
|
69
|
+
!(element instanceof NodeList) &&
|
|
70
|
+
!Array.isArray(element)
|
|
71
|
+
) {
|
|
72
|
+
element = [element];
|
|
73
|
+
} else if (!element) {
|
|
74
|
+
element = document.querySelectorAll(selector);
|
|
75
|
+
initSocket();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let promises = [];
|
|
79
|
+
for (let i = 0; i < element.length; i++) {
|
|
80
|
+
if (
|
|
81
|
+
elements.has(element[i]) ||
|
|
82
|
+
element[i].tagName === "FORM" ||
|
|
83
|
+
element[i].getAttribute("crud") === "false"
|
|
84
|
+
)
|
|
85
|
+
continue;
|
|
86
|
+
|
|
87
|
+
promises.push(
|
|
88
|
+
(async () => {
|
|
89
|
+
let data = await initElement(element[i]);
|
|
90
|
+
if (data) {
|
|
91
|
+
let dataKey = initDataKey(element[i], data);
|
|
92
|
+
return { string: dataKey.string, data };
|
|
93
|
+
}
|
|
94
|
+
})()
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let results = await Promise.all(promises);
|
|
99
|
+
let dataObjects = new Map();
|
|
100
|
+
|
|
101
|
+
for (let res of results) {
|
|
102
|
+
if (res) dataObjects.set(res.string, res.data);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (dataObjects && dataObjects.size > 0) {
|
|
106
|
+
for (let key of dataObjects.keys()) {
|
|
107
|
+
let { data, elements: mappedElements } = keys.get(key);
|
|
108
|
+
read(Array.from(mappedElements.keys()), data, { string: key });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
async function initElement(el) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return data;
|
|
114
|
+
let data = getObject(el);
|
|
115
|
+
if (!data || !data.type) return;
|
|
116
|
+
|
|
117
|
+
if (
|
|
118
|
+
data.object &&
|
|
119
|
+
data.object !== "pending" &&
|
|
120
|
+
!/^[0-9a-fA-F]{24}$/.test(data.object)
|
|
121
|
+
)
|
|
122
|
+
return;
|
|
123
|
+
|
|
124
|
+
if (!elements.has(el)) {
|
|
125
|
+
elements.set(el, "");
|
|
126
|
+
|
|
127
|
+
if (!el.elementsInputEvent) {
|
|
128
|
+
el.elementsInputEvent = true;
|
|
129
|
+
|
|
130
|
+
if (
|
|
131
|
+
["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName) ||
|
|
132
|
+
(el.hasAttribute("contenteditable") &&
|
|
133
|
+
el.getAttribute("contenteditable") !== "false") ||
|
|
134
|
+
el.contenteditable || el.value !== undefined || el.hasAttribute("value")
|
|
135
|
+
) {
|
|
136
|
+
if (el.tagName == "IFRAME") {
|
|
137
|
+
// ToDo: saving on contenteditable elements when an objectId does not exist in order to crud or crdt
|
|
138
|
+
el = el.contentDocument.documentElement;
|
|
139
|
+
el.setAttribute("contenteditable", "true");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
el.addEventListener("input", function (e) {
|
|
143
|
+
if (el.pendingObject) return;
|
|
144
|
+
|
|
145
|
+
const { object, key, isRealtime, isCrdt } =
|
|
146
|
+
getAttributes(el);
|
|
147
|
+
if (!isRealtime || isRealtime === "false" || key === "_id")
|
|
148
|
+
return;
|
|
149
|
+
if (isCrdt == "true" && object && object !== "pending")
|
|
150
|
+
return;
|
|
151
|
+
if (e.detail && e.detail.skip == true) return;
|
|
152
|
+
if (data.type !== "object" && data[data.type] === "pending")
|
|
153
|
+
return;
|
|
154
|
+
if (!el.value && !el.hasAttribute("value") && el.contenteditable && !el.hasAttribute("contenteditable")) return;
|
|
155
|
+
save(el);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
await filter.init(el);
|
|
162
|
+
|
|
163
|
+
if (el.getFilter) {
|
|
164
|
+
data.$filter = await el.getFilter();
|
|
165
|
+
|
|
166
|
+
el.setFilter = (filter) => {
|
|
167
|
+
data.$filter = filter;
|
|
168
|
+
el.hasRead = false;
|
|
169
|
+
read(el, data);
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return data;
|
|
169
174
|
}
|
|
170
175
|
|
|
171
176
|
function getObject(element) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
177
|
+
const data = getAttributes(element);
|
|
178
|
+
const crudType = ["storage", "database", "array", "index", "object"];
|
|
179
|
+
|
|
180
|
+
for (let i = 0; i < crudType.length; i++) {
|
|
181
|
+
if (!checkValue(data[crudType[i]])) return;
|
|
182
|
+
|
|
183
|
+
if (data[crudType[i]] && data[crudType[i]].includes(",")) {
|
|
184
|
+
const array = data[crudType[i]].split(",");
|
|
185
|
+
data[crudType[i]] = [];
|
|
186
|
+
|
|
187
|
+
for (let j = 0; j < array.length; j++) {
|
|
188
|
+
array[j].trim();
|
|
189
|
+
if (crudType[i] === "object") {
|
|
190
|
+
data[crudType[i]].push({ _id: array[j] });
|
|
191
|
+
} else {
|
|
192
|
+
data[crudType[i]].push(array[j]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (data.object || data.object === "" || data.key || data.key === "") {
|
|
199
|
+
if (!data.array || (data.array && !data.array.length)) return;
|
|
200
|
+
data.type = "object";
|
|
201
|
+
} else if (data.index || data.index === "") {
|
|
202
|
+
if (!data.array || (data.array && !data.array.length)) return;
|
|
203
|
+
data.type = "index";
|
|
204
|
+
} else if (data.array || data.array === "") data.type = "array";
|
|
205
|
+
else if (data.database || data.database === "") data.type = "database";
|
|
206
|
+
else if (data.storage || data.storage === "") data.type = "storage";
|
|
207
|
+
else if (data.data) data.type = "data";
|
|
208
|
+
|
|
209
|
+
delete data.isRealtime;
|
|
210
|
+
return data;
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
function initDataKey(element, data) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
214
|
+
let dataKey = getDataKey(data);
|
|
215
|
+
if (keys.has(dataKey.string))
|
|
216
|
+
keys.get(dataKey.string).elements.set(element, "");
|
|
217
|
+
else
|
|
218
|
+
keys.set(dataKey.string, {
|
|
219
|
+
elements: new Map([[element, ""]]),
|
|
220
|
+
data,
|
|
221
|
+
dataKey
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
elements.set(element, dataKey.string);
|
|
225
|
+
|
|
226
|
+
if (element.parentElement) {
|
|
227
|
+
let form = element.closest("form");
|
|
228
|
+
if (form) {
|
|
229
|
+
if (!form.save) form.save = () => save(form);
|
|
230
|
+
|
|
231
|
+
if (!form.getData) form.getData = () => getData(form);
|
|
232
|
+
|
|
233
|
+
let formObject = forms.get(form);
|
|
234
|
+
if (formObject) {
|
|
235
|
+
formObject.elements.set(element, data);
|
|
236
|
+
if (formObject.types.has(data.type))
|
|
237
|
+
formObject.types.get(data.type).set(element, data);
|
|
238
|
+
else
|
|
239
|
+
formObject.types.set(data.type, new Map([[element, data]]));
|
|
240
|
+
} else
|
|
241
|
+
forms.set(form, {
|
|
242
|
+
elements: new Map([[element, data]]),
|
|
243
|
+
types: new Map([[data.type, new Map([[element, data]])]])
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!element.read) element.read = () => read(element);
|
|
249
|
+
if (!element.save) element.save = () => save(element);
|
|
250
|
+
|
|
251
|
+
return dataKey;
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
async function read(element, data, dataKey) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
let els = Array.from(delay.elements.keys());
|
|
312
|
-
clearTimeout(delay.timer);
|
|
313
|
-
delete delay.elements;
|
|
314
|
-
delete delay.timer;
|
|
315
|
-
|
|
316
|
-
setData(els, Data);
|
|
317
|
-
});
|
|
318
|
-
}, 500);
|
|
255
|
+
if (!dataKey) dataKey = { string: elements.get(element) };
|
|
256
|
+
if (!data) {
|
|
257
|
+
let existingData = keys.get(dataKey.string);
|
|
258
|
+
if (existingData && existingData.dataKey && existingData.dataKey.object)
|
|
259
|
+
data = { ...existingData.dataKey.object };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!dataKey || !data.type) return;
|
|
263
|
+
if (!data.$filter && (!data[data.type] || !data[data.type].length)) return;
|
|
264
|
+
|
|
265
|
+
if (!(element instanceof HTMLCollection) && !Array.isArray(element))
|
|
266
|
+
element = [element];
|
|
267
|
+
|
|
268
|
+
let delay = debounce.get(dataKey.string);
|
|
269
|
+
if (!delay) debounce.set(dataKey.string, (delay = {}));
|
|
270
|
+
|
|
271
|
+
if (!delay.elements) delay.elements = new Map();
|
|
272
|
+
|
|
273
|
+
for (let el of element) {
|
|
274
|
+
const isRead = el.getAttribute("read");
|
|
275
|
+
if (
|
|
276
|
+
isRead !== "false" &&
|
|
277
|
+
!el.hasRead &&
|
|
278
|
+
(!data.$filter || (data.$filter && data.$filter.isFilter !== false))
|
|
279
|
+
) {
|
|
280
|
+
el.hasRead = true;
|
|
281
|
+
delay.elements.set(el, true);
|
|
282
|
+
} else {
|
|
283
|
+
// console.log("read skipped", el);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!delay.elements.size) return;
|
|
288
|
+
|
|
289
|
+
clearTimeout(delay.timer);
|
|
290
|
+
delay.timer = setTimeout(function () {
|
|
291
|
+
// TODO: should server support string and string array for type object, methods create, read, delete
|
|
292
|
+
if (!data.$filter && data.type === "object") {
|
|
293
|
+
if (!data.object) return;
|
|
294
|
+
else if (typeof data.object === "string")
|
|
295
|
+
data.object = { _id: data.object };
|
|
296
|
+
else if (Array.isArray(data.object)) {
|
|
297
|
+
if (data.object.length)
|
|
298
|
+
data.object = { _id: data.object[0]._id };
|
|
299
|
+
} else if (!data.object._id.match(/^[0-9a-fA-F]{24}$/)) return;
|
|
300
|
+
// if (data.object._id.startsWith('$'))
|
|
301
|
+
// return
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
data.method = data.type + ".read";
|
|
305
|
+
|
|
306
|
+
CRUD.send(data).then((responseData) => {
|
|
307
|
+
debounce.delete(dataKey.string);
|
|
308
|
+
let els = Array.from(delay.elements.keys());
|
|
309
|
+
clearTimeout(delay.timer);
|
|
310
|
+
delete delay.elements;
|
|
311
|
+
delete delay.timer;
|
|
312
|
+
|
|
313
|
+
setData(els, responseData);
|
|
314
|
+
});
|
|
315
|
+
}, 500);
|
|
319
316
|
}
|
|
320
317
|
|
|
321
318
|
function get$in(query, mergedValues = []) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
319
|
+
for (let key of Object.keys(query)) {
|
|
320
|
+
if (key === "$and" || key === "$or" || key === "$nor") {
|
|
321
|
+
for (let i = 0; i < query[key].length; i++) {
|
|
322
|
+
sort$in(query[key][i], mergedValues);
|
|
323
|
+
}
|
|
324
|
+
} else if (
|
|
325
|
+
typeof query[key] === "object" &&
|
|
326
|
+
!Array.isArray(query[key])
|
|
327
|
+
) {
|
|
328
|
+
if (query[key].$in)
|
|
329
|
+
mergedValues = [...mergedValues, ...query[key].$in];
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return mergedValues;
|
|
336
333
|
}
|
|
337
334
|
|
|
338
335
|
function sort$in(data, query) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
336
|
+
let mergedValues = get$in(query);
|
|
337
|
+
|
|
338
|
+
if (mergedValues.length) {
|
|
339
|
+
const sorted = mergedValues
|
|
340
|
+
.map((name) => data.find((career) => career.name === name))
|
|
341
|
+
.filter((career) => career !== undefined);
|
|
342
|
+
return sorted;
|
|
343
|
+
}
|
|
347
344
|
}
|
|
348
345
|
|
|
349
346
|
async function setData(element, data) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
value = data[type][0];
|
|
441
|
-
if (reference === "false") {
|
|
442
|
-
delete data[type][0].$storage;
|
|
443
|
-
delete data[type][0].$database;
|
|
444
|
-
delete data[type][0].$array;
|
|
445
|
-
}
|
|
446
|
-
} else {
|
|
447
|
-
value = CRUD.getValueFromObject(data[type][0], key);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
if (!data[type].length) continue;
|
|
452
|
-
if (isRead === "false" || isCrdt === "true") continue;
|
|
453
|
-
if (
|
|
454
|
-
isUpdate === "false" ||
|
|
455
|
-
(isListen === "false" && !data.method.endsWith(".read"))
|
|
456
|
-
)
|
|
457
|
-
continue;
|
|
458
|
-
|
|
459
|
-
// TODO: object.update data returned from server will not include $operator
|
|
460
|
-
el.setValue(value);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
347
|
+
if (!element) {
|
|
348
|
+
element = getDataElements(data);
|
|
349
|
+
if (!element.length) return;
|
|
350
|
+
}
|
|
351
|
+
if (!(element instanceof HTMLCollection) && !Array.isArray(element))
|
|
352
|
+
element = [element];
|
|
353
|
+
|
|
354
|
+
let type = data.type;
|
|
355
|
+
if (!type && data.method) {
|
|
356
|
+
type = data.method.split(".")[0];
|
|
357
|
+
} else if (type == "key") type = "object";
|
|
358
|
+
|
|
359
|
+
if (data.$filter && data.$filter.query) {
|
|
360
|
+
let sortedData = sort$in(data[type], data.$filter.query);
|
|
361
|
+
if (sortedData && sortedData.length) data[type] = sortedData;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
for (let el of element) {
|
|
365
|
+
// if rendered in server side skip
|
|
366
|
+
if (el.hasAttribute("rendered")) return el.removeAttribute("rendered");
|
|
367
|
+
if (el.hasAttribute("render-json")) {
|
|
368
|
+
console.log("render-json", "");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
let reference = el.getAttribute("reference");
|
|
372
|
+
let action = el.getAttribute("actions");
|
|
373
|
+
if (action && ["database", "array", "object", "key"].includes(action))
|
|
374
|
+
continue;
|
|
375
|
+
|
|
376
|
+
if (data.array.includes("aiConversations")) {
|
|
377
|
+
console.log("testing ai conversations");
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const { key, isRead, isUpdate, isListen, isCrdt } = getAttributes(el);
|
|
381
|
+
let elementType = el.getAttribute("type");
|
|
382
|
+
if (elementType !== "file" && (el.getFilter || el.renderValue))
|
|
383
|
+
await filterData(el, data, type, key);
|
|
384
|
+
else {
|
|
385
|
+
if (!data[type] || !data[type].length) {
|
|
386
|
+
if (el.hasAttribute("value-dispatch")) el.setValue("");
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (key && checkValue(key)) {
|
|
391
|
+
let value;
|
|
392
|
+
if (key.includes("$length")) {
|
|
393
|
+
value = CRUD.getValueFromObject(
|
|
394
|
+
data[type][0],
|
|
395
|
+
key.replace(/\.\$length$/, "")
|
|
396
|
+
);
|
|
397
|
+
if (value) value = value.length;
|
|
398
|
+
else value = 0;
|
|
399
|
+
} else {
|
|
400
|
+
let $update = data[type][0].$update;
|
|
401
|
+
if ($update) {
|
|
402
|
+
delete data[type][0].$update;
|
|
403
|
+
data[type][0] = { ...data[type][0], ...$update };
|
|
404
|
+
} else if (key === "$data") {
|
|
405
|
+
value = data;
|
|
406
|
+
} else if (key && key.startsWith("$data")) {
|
|
407
|
+
value = CRUD.getValueFromObject(data, key.slice(1));
|
|
408
|
+
} else if (key === `$${type}`) {
|
|
409
|
+
value = data[type];
|
|
410
|
+
} else if (key && key.startsWith(`$${type}`)) {
|
|
411
|
+
value = CRUD.getValueFromObject(data, key.slice(1));
|
|
412
|
+
} else if (key === "{}") {
|
|
413
|
+
value = data[type][0];
|
|
414
|
+
if (reference === "false") {
|
|
415
|
+
delete data[type][0].$storage;
|
|
416
|
+
delete data[type][0].$database;
|
|
417
|
+
delete data[type][0].$array;
|
|
418
|
+
}
|
|
419
|
+
} else {
|
|
420
|
+
value = CRUD.getValueFromObject(data[type][0], key);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (!data[type].length) continue;
|
|
425
|
+
if (isRead === "false" || isCrdt === "true") continue;
|
|
426
|
+
if (
|
|
427
|
+
isUpdate === "false" ||
|
|
428
|
+
(isListen === "false" && !data.method.endsWith(".read"))
|
|
429
|
+
)
|
|
430
|
+
continue;
|
|
431
|
+
|
|
432
|
+
// TODO: object.update data returned from server will not include $operator
|
|
433
|
+
el.setValue(value);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
464
437
|
}
|
|
465
438
|
|
|
466
439
|
async function filterData(element, data, type, key) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
// delete data[type][0].$database;
|
|
578
|
-
// delete data[type][0].$array;
|
|
579
|
-
// }
|
|
580
|
-
} else if (data) element.setValue(data);
|
|
581
|
-
|
|
582
|
-
if (data.$filter) {
|
|
583
|
-
let filterElement = filter.filters.get(element);
|
|
584
|
-
if (filterElement) filterElement.index = data.$filter.index;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (!data[type] || !Array.isArray(data[type]) || !data[type].length) return;
|
|
588
|
-
|
|
589
|
-
const evt = new CustomEvent("fetchedData", { bubbles: true });
|
|
590
|
-
element.dispatchEvent(evt);
|
|
440
|
+
let operator = "",
|
|
441
|
+
value;
|
|
442
|
+
|
|
443
|
+
if (key && !key.includes("$length") && key !== "{}") {
|
|
444
|
+
if (!data || !type) return;
|
|
445
|
+
|
|
446
|
+
if (key.startsWith("$")) {
|
|
447
|
+
operator = key.split(".")[0] || "";
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
let property = key;
|
|
451
|
+
if (operator) {
|
|
452
|
+
property = property.replace(operator + ".", "");
|
|
453
|
+
if (operator === "$sum") {
|
|
454
|
+
value = 0;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (Array.isArray(data[type])) {
|
|
458
|
+
let filteredItems = [],
|
|
459
|
+
isObject;
|
|
460
|
+
for (let doc of data[type]) {
|
|
461
|
+
if (!doc.$storage) continue;
|
|
462
|
+
// TODO: should have been handled by getDataElements()
|
|
463
|
+
if (type === "object") {
|
|
464
|
+
let _id = element.getAttribute("object");
|
|
465
|
+
if (_id && doc._id !== _id) continue;
|
|
466
|
+
let $update = doc.$update;
|
|
467
|
+
if ($update) {
|
|
468
|
+
delete doc.$update;
|
|
469
|
+
doc = { ...doc, ...$update };
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
let docValue = getValueFromObject(doc, property);
|
|
473
|
+
if (docValue) {
|
|
474
|
+
if (operator === "$sum" && typeof docValue === "number") {
|
|
475
|
+
if (typeof value !== "number") value = 0;
|
|
476
|
+
value += docValue || 0;
|
|
477
|
+
} else if (Array.isArray(docValue)) {
|
|
478
|
+
filteredItems.push(...docValue);
|
|
479
|
+
} else {
|
|
480
|
+
isObject = true;
|
|
481
|
+
filteredItems.push(docValue);
|
|
482
|
+
}
|
|
483
|
+
} else continue;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (isObject && filteredItems.length === 1) {
|
|
487
|
+
filteredItems = filteredItems[0];
|
|
488
|
+
}
|
|
489
|
+
if (!operator) data = filteredItems;
|
|
490
|
+
} else {
|
|
491
|
+
data = { [property]: data[type][property] };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
let isRendered = element.querySelector("[render-clone]");
|
|
496
|
+
if (operator) {
|
|
497
|
+
element.setValue(value);
|
|
498
|
+
} else if (
|
|
499
|
+
element.renderValue &&
|
|
500
|
+
data.method &&
|
|
501
|
+
data.method.endsWith(".read") &&
|
|
502
|
+
data.$filter &&
|
|
503
|
+
(data.$filter.overwrite || !isRendered)
|
|
504
|
+
) {
|
|
505
|
+
await element.renderValue(data);
|
|
506
|
+
} else if (
|
|
507
|
+
(data.$filter && data.$filter.loadmore) ||
|
|
508
|
+
(data.method && data.method.endsWith(".read") && isRendered)
|
|
509
|
+
) {
|
|
510
|
+
await loadMore(element, data, type);
|
|
511
|
+
} else if (
|
|
512
|
+
element.getFilter &&
|
|
513
|
+
data.method &&
|
|
514
|
+
!data.method.endsWith(".read")
|
|
515
|
+
) {
|
|
516
|
+
await checkFilters(element, data, type);
|
|
517
|
+
} else if (element.renderValue) {
|
|
518
|
+
if (key)
|
|
519
|
+
data = {[key]: data}
|
|
520
|
+
await element.renderValue(data);
|
|
521
|
+
} else if (key === "$length") {
|
|
522
|
+
element.setValue(data[type].length);
|
|
523
|
+
} else if (key && key.includes("$length")) {
|
|
524
|
+
let value = CRUD.getValueFromObject(
|
|
525
|
+
data[type][0],
|
|
526
|
+
key.replace(/\.\$length$/, "")
|
|
527
|
+
);
|
|
528
|
+
element.setValue(value.length);
|
|
529
|
+
} else if (key === "$data") {
|
|
530
|
+
value = data;
|
|
531
|
+
} else if (key && key.startsWith("$data")) {
|
|
532
|
+
value = CRUD.getValueFromObject(data, key.slice(1));
|
|
533
|
+
} else if (key === `$${type}`) {
|
|
534
|
+
value = data[type];
|
|
535
|
+
} else if (key && key.startsWith(`$${type}`)) {
|
|
536
|
+
value = CRUD.getValueFromObject(data, key.slice(1));
|
|
537
|
+
} else if (key === "{}") {
|
|
538
|
+
value = data[type][0];
|
|
539
|
+
} else if (data) element.setValue(data);
|
|
540
|
+
|
|
541
|
+
if (data.$filter) {
|
|
542
|
+
let filterElement = filter.filters.get(element);
|
|
543
|
+
if (filterElement) filterElement.index = data.$filter.index;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (!data[type] || !Array.isArray(data[type]) || !data[type].length) return;
|
|
547
|
+
|
|
548
|
+
const evt = new CustomEvent("fetchedData", { bubbles: true });
|
|
549
|
+
element.dispatchEvent(evt);
|
|
591
550
|
}
|
|
592
551
|
|
|
593
552
|
async function loadMore(element, data, type, sort) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
553
|
+
let clonedData = { ...data };
|
|
554
|
+
let renderedData = await element.getData();
|
|
555
|
+
if (!renderedData || !renderedData[type]) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
for (let i = 0; i < clonedData[type].length; i++) {
|
|
559
|
+
let index;
|
|
560
|
+
if (type === "object") {
|
|
561
|
+
index = renderedData[type].findIndex(
|
|
562
|
+
(obj) => obj._id === clonedData[type][i]._id
|
|
563
|
+
);
|
|
564
|
+
} else {
|
|
565
|
+
index = renderedData[type].findIndex(
|
|
566
|
+
(obj) => obj.name === clonedData[type][i].name
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (index >= 0) {
|
|
571
|
+
clonedData[type].splice(i, 1);
|
|
572
|
+
i--; // Adjust the index to account for the removed item
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (clonedData[type].length > 0) {
|
|
576
|
+
await element.renderValue(clonedData);
|
|
577
|
+
}
|
|
619
578
|
}
|
|
620
579
|
|
|
621
580
|
async function checkFilters(element, data, type) {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
// render({ element, data, key: type });
|
|
683
|
-
else if (data) element.setValue(data);
|
|
684
|
-
}
|
|
581
|
+
let localData;
|
|
582
|
+
if (!element.getData) {
|
|
583
|
+
// TODO: fix: getObject as this is related to render or form, but filter could exist on an input which does not have getObject
|
|
584
|
+
// TODO: generate an object of current element key: value to use with filter. because filter is used object is not defined
|
|
585
|
+
localData = getObject(element);
|
|
586
|
+
if (Array.isArray(localData[type])) localData = localData[type][0];
|
|
587
|
+
} else localData = await element.getData();
|
|
588
|
+
|
|
589
|
+
if (!localData) return;
|
|
590
|
+
|
|
591
|
+
let newData;
|
|
592
|
+
if (type) {
|
|
593
|
+
localData = localData[type];
|
|
594
|
+
newData = data[type];
|
|
595
|
+
} else newData = data;
|
|
596
|
+
|
|
597
|
+
let filter = await element.getFilter();
|
|
598
|
+
if (filter && filter.query) {
|
|
599
|
+
newData = newData.filter(item => queryData(item, filter.query));
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (!newData || !newData.length) return;
|
|
603
|
+
|
|
604
|
+
if (Array.isArray(localData)) {
|
|
605
|
+
if (Array.isArray(newData)) {
|
|
606
|
+
for (let i = 0; i < newData.length; i++) {
|
|
607
|
+
checkIndex(element, data, localData, newData[i], type, filter);
|
|
608
|
+
}
|
|
609
|
+
} else {
|
|
610
|
+
checkIndex(element, data, localData, newData, type, filter);
|
|
611
|
+
}
|
|
612
|
+
} else {
|
|
613
|
+
let primaryKey;
|
|
614
|
+
if (type === "object") {
|
|
615
|
+
primaryKey = "_id";
|
|
616
|
+
} else {
|
|
617
|
+
primaryKey = "name";
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
if (Array.isArray(newData)) {
|
|
621
|
+
for (let i = 0; i < newData.length; i++) {
|
|
622
|
+
if (
|
|
623
|
+
typeof localData === "string" &&
|
|
624
|
+
localData === newData[i][primaryKey]
|
|
625
|
+
) {
|
|
626
|
+
localData = newData[i];
|
|
627
|
+
} else if (localData[primaryKey] === newData[i][primaryKey]) {
|
|
628
|
+
localData = dotNotationToObject(newData[i], localData);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
} else if (typeof localData === "string" && localData === newData[primaryKey]) {
|
|
632
|
+
localData = newData;
|
|
633
|
+
} else if (localData[primaryKey] === newData[primaryKey]) {
|
|
634
|
+
localData = dotNotationToObject(newData, localData);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
if (element.renderValue) element.renderValue(data);
|
|
638
|
+
// render({ element, data, key: type });
|
|
639
|
+
else if (data) element.setValue(localData);
|
|
640
|
+
}
|
|
685
641
|
}
|
|
686
642
|
|
|
687
|
-
function checkIndex(element, data,
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
643
|
+
function checkIndex(element, data, localData, newData, type, filter) {
|
|
644
|
+
let index;
|
|
645
|
+
if (type === "object") {
|
|
646
|
+
index = localData.findIndex((obj) => obj._id === newData._id);
|
|
647
|
+
} else {
|
|
648
|
+
index = localData.findIndex((obj) => obj.name === newData.name);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (!data.$filter) data.$filter = {};
|
|
652
|
+
|
|
653
|
+
if (data.method.endsWith(".delete")) {
|
|
654
|
+
if (index === -1) return;
|
|
655
|
+
data.$filter.remove = true;
|
|
656
|
+
localData.splice(index, 1);
|
|
657
|
+
} else {
|
|
658
|
+
if (data.method.endsWith(".create")) {
|
|
659
|
+
if (index === -1) {
|
|
660
|
+
data.$filter.create = true;
|
|
661
|
+
if (filter && filter.sort) newData.isNewData = true;
|
|
662
|
+
else index = localData.length;
|
|
663
|
+
localData.push(newData);
|
|
664
|
+
}
|
|
665
|
+
} else {
|
|
666
|
+
if (index === -1) return;
|
|
667
|
+
data.$filter.update = true;
|
|
668
|
+
data.$filter.currentIndex = index;
|
|
669
|
+
localData[index] = dotNotationToObject(newData, localData[index]);
|
|
670
|
+
if (filter && filter.sort) {
|
|
671
|
+
localData[index].isNewData = true;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (filter && filter.sort) {
|
|
676
|
+
localData = sortData(localData, filter.sort);
|
|
677
|
+
index = localData.findIndex((obj) => obj.isNewData);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (index >= 0) {
|
|
682
|
+
if (data.$filter.currentIndex === index)
|
|
683
|
+
delete data.$filter.currentIndex;
|
|
684
|
+
data.$filter.index = index;
|
|
685
|
+
if (element.renderValue) element.renderValue(data);
|
|
686
|
+
else if (data) element.setValue(localData);
|
|
687
|
+
}
|
|
730
688
|
}
|
|
731
689
|
|
|
732
690
|
function getDataKey(data) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
691
|
+
let dataKey = {};
|
|
692
|
+
let attributes = [
|
|
693
|
+
"host",
|
|
694
|
+
"organization_id",
|
|
695
|
+
"apikey",
|
|
696
|
+
"method",
|
|
697
|
+
"type",
|
|
698
|
+
"storage",
|
|
699
|
+
"database",
|
|
700
|
+
"array",
|
|
701
|
+
"index",
|
|
702
|
+
"object",
|
|
703
|
+
"key",
|
|
704
|
+
"updateKey",
|
|
705
|
+
"$filter",
|
|
706
|
+
"upsert",
|
|
707
|
+
"namespace",
|
|
708
|
+
"room",
|
|
709
|
+
"broadcast",
|
|
710
|
+
"broadcastSender",
|
|
711
|
+
"broadcastBrowser"
|
|
712
|
+
];
|
|
713
|
+
|
|
714
|
+
for (let attribute of attributes) {
|
|
715
|
+
if (attribute === "key" && data.type === "object") continue;
|
|
716
|
+
let value = data[attribute];
|
|
717
|
+
if (value) {
|
|
718
|
+
if (Array.isArray(value)) {
|
|
719
|
+
dataKey[attribute] = [...value];
|
|
720
|
+
if (typeof value[0] === "string") dataKey[attribute].sort(); // Sort the values alphabetically
|
|
721
|
+
} else {
|
|
722
|
+
dataKey[attribute] = value;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
const object = Object.fromEntries(
|
|
728
|
+
Object.entries(dataKey).sort(([a], [b]) => a.localeCompare(b))
|
|
729
|
+
);
|
|
730
|
+
const string = JSON.stringify(object);
|
|
731
|
+
|
|
732
|
+
return { string, object };
|
|
775
733
|
}
|
|
776
734
|
|
|
777
735
|
function getDataElements(data) {
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
)
|
|
787
|
-
element.push(...matchingElements.elements.keys());
|
|
788
|
-
}
|
|
789
|
-
return element;
|
|
736
|
+
let element = [];
|
|
737
|
+
let matchingKeys = getDataKeys(data);
|
|
738
|
+
for (let i = 0; i < matchingKeys.length; i++) {
|
|
739
|
+
let matchingElements = keys.get(matchingKeys[i]);
|
|
740
|
+
if (matchingElements?.elements?.size)
|
|
741
|
+
element.push(...matchingElements.elements.keys());
|
|
742
|
+
}
|
|
743
|
+
return element;
|
|
790
744
|
}
|
|
791
745
|
|
|
792
746
|
// TODO: Correctly check for matches
|
|
793
747
|
function getDataKeys(data) {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
748
|
+
const matchingKeyStrings = [];
|
|
749
|
+
const targetKeys = [
|
|
750
|
+
"type",
|
|
751
|
+
"storage",
|
|
752
|
+
"database",
|
|
753
|
+
"array",
|
|
754
|
+
"index",
|
|
755
|
+
"object",
|
|
756
|
+
"$filter"
|
|
757
|
+
];
|
|
758
|
+
|
|
759
|
+
for (const [keyString, sortedKey] of keys.entries()) {
|
|
760
|
+
let hasMatch = true;
|
|
761
|
+
|
|
762
|
+
for (const key of targetKeys) {
|
|
763
|
+
if (
|
|
764
|
+
!data.$filter &&
|
|
765
|
+
key === "$filter" &&
|
|
766
|
+
sortedKey.data.hasOwnProperty(key)
|
|
767
|
+
)
|
|
768
|
+
hasMatch = true;
|
|
769
|
+
else if (data.hasOwnProperty(key)) {
|
|
770
|
+
if (!sortedKey.data.hasOwnProperty(key)) {
|
|
771
|
+
hasMatch = false;
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
774
|
+
if (
|
|
775
|
+
Array.isArray(sortedKey.data[key]) &&
|
|
776
|
+
Array.isArray(data[key])
|
|
777
|
+
) {
|
|
778
|
+
// if key is object check _id
|
|
779
|
+
if (key === "object" && sortedKey.data.$filter)
|
|
780
|
+
hasMatch = true;
|
|
781
|
+
else {
|
|
782
|
+
const matches = sortedKey.data[key].some((value) => {
|
|
783
|
+
if (key === "object") {
|
|
784
|
+
return data[key].some((obj) => {
|
|
785
|
+
return obj._id === value._id;
|
|
786
|
+
});
|
|
787
|
+
} else {
|
|
788
|
+
return data[key].includes(value);
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
if (!matches) {
|
|
793
|
+
hasMatch = false;
|
|
794
|
+
break;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
} else if (sortedKey.data[key] !== data[key]) {
|
|
798
|
+
hasMatch = false;
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
if (hasMatch) {
|
|
805
|
+
matchingKeyStrings.push(keyString);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return matchingKeyStrings;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function formatPayload(payload, value, element) {
|
|
813
|
+
if (!payload[payload.type] && payload.key) {
|
|
814
|
+
payload.method = payload.type + ".create";
|
|
815
|
+
if (payload.type === "object") {
|
|
816
|
+
if (!payload.object) payload.object = {};
|
|
817
|
+
else if (typeof payload.object === "string")
|
|
818
|
+
payload.object = { _id: payload.object };
|
|
819
|
+
|
|
820
|
+
if (payload.key) {
|
|
821
|
+
if (payload.key == "{}") {
|
|
822
|
+
if (Array.isArray(value)) {
|
|
823
|
+
payload.object = value;
|
|
824
|
+
} else payload.object = { ...payload.object, ...value };
|
|
825
|
+
} else payload.object[payload.key] = value;
|
|
826
|
+
}
|
|
827
|
+
if (payload.isUpsert && payload.$filter)
|
|
828
|
+
payload.method = "object.update";
|
|
829
|
+
} else payload[payload.type] = value;
|
|
830
|
+
} else if (payload[payload.type] && payload.key) {
|
|
831
|
+
let attributes = element.attributes;
|
|
832
|
+
if (payload.key.startsWith("$")) {
|
|
833
|
+
const operators = ["$rename", "$inc", "$push", "$each", "$splice", "$unset", "$delete", "$slice", "$pop", "$shift", "$addToSet", "$pull"];
|
|
834
|
+
const matchedAttr = Array.from(attributes).find(attr => operators.includes(attr.name));
|
|
835
|
+
if (matchedAttr) {
|
|
836
|
+
payload.key = matchedAttr.name + "." + payload.key;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (payload.type === "object") {
|
|
841
|
+
if (typeof payload[payload.type] === "string")
|
|
842
|
+
if (payload.key == "{}") {
|
|
843
|
+
if (Array.isArray(value))
|
|
844
|
+
payload[payload.type] = {
|
|
845
|
+
_id: payload[payload.type],
|
|
846
|
+
...value[0]
|
|
847
|
+
};
|
|
848
|
+
else
|
|
849
|
+
payload[payload.type] = {
|
|
850
|
+
_id: payload[payload.type],
|
|
851
|
+
...value
|
|
852
|
+
};
|
|
853
|
+
} else
|
|
854
|
+
payload[payload.type] = {
|
|
855
|
+
_id: payload[payload.type],
|
|
856
|
+
[payload.key]: value
|
|
857
|
+
};
|
|
858
|
+
else if (Array.isArray(payload[payload.type]))
|
|
859
|
+
if (payload.key == "{}")
|
|
860
|
+
payload[payload.type][0] = {
|
|
861
|
+
...payload[payload.type][0],
|
|
862
|
+
...value
|
|
863
|
+
};
|
|
864
|
+
else {
|
|
865
|
+
if (payload[payload.type][0]) {
|
|
866
|
+
payload[payload.type][0][payload.key] = value;
|
|
867
|
+
}
|
|
868
|
+
if (!payload[payload.type][0]._id)
|
|
869
|
+
payload.method = payload.type + ".create";
|
|
870
|
+
}
|
|
871
|
+
else if (typeof payload[payload.type] === "object")
|
|
872
|
+
if (payload.key == "{}")
|
|
873
|
+
payload[payload.type] = { ...payload[payload.type], ...value };
|
|
874
|
+
else {
|
|
875
|
+
payload[payload.type][payload.key] = value;
|
|
876
|
+
if (!payload[payload.type]._id)
|
|
877
|
+
payload.method = payload.type + ".create";
|
|
878
|
+
}
|
|
879
|
+
} else {
|
|
880
|
+
payload[payload.type] = { [payload[payload.type]]: value };
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if (payload.isUpdate || payload.isUpdate === "") {
|
|
884
|
+
if (!payload.key) return false;
|
|
885
|
+
delete payload.isUpdate;
|
|
886
|
+
payload.updateKey = { [payload.key]: value };
|
|
887
|
+
payload.method = payload.type + ".update";
|
|
888
|
+
} else if (payload.isDelete || payload.isDelete === "") {
|
|
889
|
+
delete payload.isDelete;
|
|
890
|
+
if (payload.type == "object" && payload.key) {
|
|
891
|
+
payload.method = payload.type + ".update";
|
|
892
|
+
if (typeof payload[payload.type] === "string")
|
|
893
|
+
payload[payload.type] = {
|
|
894
|
+
_id: payload[payload.type],
|
|
895
|
+
[payload.key]: undefined
|
|
896
|
+
};
|
|
897
|
+
else if (Array.isArray(payload[payload.type])) {
|
|
898
|
+
console.log(
|
|
899
|
+
"payload.type is an array function incomplete"
|
|
900
|
+
);
|
|
901
|
+
} else if (typeof payload[payload.type] === "object")
|
|
902
|
+
payload[payload.type][payload.key] = undefined;
|
|
903
|
+
} else {
|
|
904
|
+
payload.method = payload.type + ".delete";
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
return true;
|
|
856
909
|
}
|
|
857
910
|
|
|
858
911
|
async function getData(form) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
} else if (Data[Data.type] && Data.key) {
|
|
913
|
-
let attributes = element.attributes;
|
|
914
|
-
if (Data.key.startsWith("$")) {
|
|
915
|
-
for (let i = 0; i < attributes.length; i++) {
|
|
916
|
-
let operators = [
|
|
917
|
-
"$rename",
|
|
918
|
-
"$inc",
|
|
919
|
-
"$push",
|
|
920
|
-
"$each",
|
|
921
|
-
"$splice",
|
|
922
|
-
"$unset",
|
|
923
|
-
"$delete",
|
|
924
|
-
"$slice",
|
|
925
|
-
"$pop",
|
|
926
|
-
"$shift",
|
|
927
|
-
"$addToSet",
|
|
928
|
-
"$pull"
|
|
929
|
-
];
|
|
930
|
-
if (operators.includes(attributes[i].name)) {
|
|
931
|
-
Data.key = attributes[i].name + "." + Data.key;
|
|
932
|
-
break;
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
if ((Data.type = "object")) {
|
|
938
|
-
// if (Data.key == "{}") {
|
|
939
|
-
// if (!value && value !== "") continue;
|
|
940
|
-
// else if (Array.isArray(value) && !value.length)
|
|
941
|
-
// continue;
|
|
942
|
-
// }
|
|
943
|
-
|
|
944
|
-
if (typeof Data[Data.type] === "string")
|
|
945
|
-
if (Data.key == "{}") {
|
|
946
|
-
// TODO: handle if array length more than 1
|
|
947
|
-
if (Array.isArray(value))
|
|
948
|
-
Data[Data.type] = {
|
|
949
|
-
_id: Data[Data.type],
|
|
950
|
-
...value[0]
|
|
951
|
-
};
|
|
952
|
-
else
|
|
953
|
-
Data[Data.type] = {
|
|
954
|
-
_id: Data[Data.type],
|
|
955
|
-
...value
|
|
956
|
-
};
|
|
957
|
-
} else
|
|
958
|
-
Data[Data.type] = {
|
|
959
|
-
_id: Data[Data.type],
|
|
960
|
-
[Data.key]: value
|
|
961
|
-
};
|
|
962
|
-
else if (Array.isArray(Data[Data.type]))
|
|
963
|
-
if (Data.key == "{}")
|
|
964
|
-
Data[Data.type][0] = {
|
|
965
|
-
...Data[Data.type][0],
|
|
966
|
-
...value
|
|
967
|
-
};
|
|
968
|
-
else {
|
|
969
|
-
if (Data[Data.type][0]) {
|
|
970
|
-
Data[Data.type][0][Data.key] = value;
|
|
971
|
-
}
|
|
972
|
-
if (!Data[Data.type][0]._id)
|
|
973
|
-
Data.method = Data.type + ".create";
|
|
974
|
-
}
|
|
975
|
-
else if (typeof Data[Data.type] === "object")
|
|
976
|
-
if (Data.key == "{}")
|
|
977
|
-
Data[Data.type] = { ...Data[Data.type], ...value };
|
|
978
|
-
else {
|
|
979
|
-
Data[Data.type][Data.key] = value;
|
|
980
|
-
if (!Data[Data.type]._id)
|
|
981
|
-
Data.method = Data.type + ".create";
|
|
982
|
-
}
|
|
983
|
-
} else {
|
|
984
|
-
Data[Data.type] = { [Data[Data.type]]: value };
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
if (Data.isUpdate || Data.isUpdate === "") {
|
|
988
|
-
if (!Data.key) return;
|
|
989
|
-
delete Data.isUpdate;
|
|
990
|
-
Data.updateKey = { [Data.key]: value };
|
|
991
|
-
Data.method = Data.type + ".update";
|
|
992
|
-
} else if (Data.isDelete || Data.isDelete === "") {
|
|
993
|
-
delete Data.isDelete;
|
|
994
|
-
if (Data.type == "object" && Data.key) {
|
|
995
|
-
Data.method = Data.type + ".update";
|
|
996
|
-
// TODO: Data.type can be a string _id or an array for string _id needs to be converted to object
|
|
997
|
-
if (typeof Data[Data.type] === "string")
|
|
998
|
-
Data[Data.type] = {
|
|
999
|
-
_id: Data[Data.type],
|
|
1000
|
-
[Data.key]: undefined
|
|
1001
|
-
};
|
|
1002
|
-
else if (Array.isArray(Data[Data.type])) {
|
|
1003
|
-
console.log(
|
|
1004
|
-
"Data.type is an array function incomplete"
|
|
1005
|
-
);
|
|
1006
|
-
} else if (typeof Data[Data.type] === "object")
|
|
1007
|
-
Data[Data.type][Data.key] = undefined;
|
|
1008
|
-
} else {
|
|
1009
|
-
Data.method = Data.type + ".delete";
|
|
1010
|
-
}
|
|
1011
|
-
} else if (Data.type !== "object" && Data[Data.type] === "") {
|
|
1012
|
-
// if (!Data.key)
|
|
1013
|
-
// Data.method = Data.type + '.read'
|
|
1014
|
-
// else if (Data.key === 'name')
|
|
1015
|
-
// Data.method = Data.type + '.create'
|
|
1016
|
-
} else if (Data.type !== "object" && Data[Data.type]) {
|
|
1017
|
-
// if (Data.key)
|
|
1018
|
-
// Data.method = Data.type + '.update'
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
//dataKey should be used to group
|
|
1023
|
-
let key = dataKey; //+ Data.method;
|
|
1024
|
-
if (dataKeys.has(key)) {
|
|
1025
|
-
let storedData = dataKeys.get(key)[Data.type];
|
|
1026
|
-
dataKeys.get(key)[Data.type] = {
|
|
1027
|
-
...storedData,
|
|
1028
|
-
...Data[Data.type]
|
|
1029
|
-
};
|
|
1030
|
-
} else {
|
|
1031
|
-
dataKeys.set(key, Data);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
// TODO: group by methods so we can make one crud request per method
|
|
1037
|
-
let dataArray = Array.from(dataKeys.values());
|
|
1038
|
-
|
|
1039
|
-
return dataArray;
|
|
912
|
+
let dataKeys = new Map();
|
|
913
|
+
let formObject = forms.get(form);
|
|
914
|
+
if (!formObject) {
|
|
915
|
+
let elements = form.querySelectorAll(selector);
|
|
916
|
+
await init(elements);
|
|
917
|
+
return await getData(form);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
for (let type of formObject.types.values()) {
|
|
921
|
+
for (let [element, data] of type.entries()) {
|
|
922
|
+
if (
|
|
923
|
+
!element.hasAttribute("key") ||
|
|
924
|
+
element.getAttribute("save") === "false"
|
|
925
|
+
)
|
|
926
|
+
continue;
|
|
927
|
+
|
|
928
|
+
if (element.hasAttribute("actions")) {
|
|
929
|
+
let attribute = element.getAttribute("actions");
|
|
930
|
+
if (attribute.includes("save") || attribute.includes("delete")) continue;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
if (element.matches("[render-query]")) {
|
|
934
|
+
let type = element.getAttribute("type");
|
|
935
|
+
if (type !== "file") continue;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
let value = await element.getValue();
|
|
939
|
+
if (value === undefined) continue;
|
|
940
|
+
|
|
941
|
+
let payload = { ...data };
|
|
942
|
+
let dataKey = elements.get(element);
|
|
943
|
+
|
|
944
|
+
let success = formatPayload(payload, value, element);
|
|
945
|
+
if (!success) continue;
|
|
946
|
+
|
|
947
|
+
//dataKey should be used to group
|
|
948
|
+
let key = dataKey; //+ payload.method;
|
|
949
|
+
if (dataKeys.has(key)) {
|
|
950
|
+
let storedData = dataKeys.get(key)[payload.type];
|
|
951
|
+
dataKeys.get(key)[payload.type] = {
|
|
952
|
+
...storedData,
|
|
953
|
+
...payload[payload.type]
|
|
954
|
+
};
|
|
955
|
+
} else {
|
|
956
|
+
dataKeys.set(key, payload);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// TODO: group by methods so we can make one crud request per method
|
|
962
|
+
let dataArray = Array.from(dataKeys.values());
|
|
963
|
+
|
|
964
|
+
return dataArray;
|
|
1040
965
|
}
|
|
1041
966
|
|
|
1042
967
|
async function save(element, action) {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
return Data;
|
|
968
|
+
if (!element) return;
|
|
969
|
+
let data, value, form;
|
|
970
|
+
let upsert = element.getAttribute("upsert");
|
|
971
|
+
if (upsert && upsert !== "false") upsert = true;
|
|
972
|
+
if (element.tagName === "FORM") {
|
|
973
|
+
data = await element.getData();
|
|
974
|
+
} else {
|
|
975
|
+
let isSave = element.getAttribute("save");
|
|
976
|
+
if (isSave === "false") return;
|
|
977
|
+
if (action) {
|
|
978
|
+
form = element.closest("form");
|
|
979
|
+
if (form) {
|
|
980
|
+
return save(form);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
let dataKey = elements.get(element);
|
|
985
|
+
data = { ...keys.get(dataKey).dataKey.object };
|
|
986
|
+
|
|
987
|
+
value = await element.getValue();
|
|
988
|
+
let key = element.getAttribute("key");
|
|
989
|
+
|
|
990
|
+
if (typeof data[data.type] === "string")
|
|
991
|
+
if (key == "{}")
|
|
992
|
+
data[data.type] = { _id: data[data.type], ...value };
|
|
993
|
+
else data[data.type] = { _id: data[data.type], [key]: value };
|
|
994
|
+
else if (typeof data[data.type] === "object")
|
|
995
|
+
if (key == "{}") data[data.type] = { ...data[data.type], ...value };
|
|
996
|
+
else data[data.type][key] = value;
|
|
997
|
+
|
|
998
|
+
if (/\.([0-9]*)/g.test(data.key)) {
|
|
999
|
+
let splice = element.getAttribute("splice");
|
|
1000
|
+
let slice = element.getAttribute("slice");
|
|
1001
|
+
let update = element.getAttribute("update");
|
|
1002
|
+
|
|
1003
|
+
if (splice || splice === "") {
|
|
1004
|
+
data[data.type][key] = { $splice: value };
|
|
1005
|
+
} else if (slice) {
|
|
1006
|
+
data[data.type][key] = "$delete";
|
|
1007
|
+
} else if (update) {
|
|
1008
|
+
value = data.key.replace(/\[.*?\]/, "[" + value + "]");
|
|
1009
|
+
data.updateKey[key] = value;
|
|
1010
|
+
data[data.type][key] = { $update: value }; // $update is string use the value as the key name
|
|
1011
|
+
|
|
1012
|
+
// data[data.type][key] = { $update: {[value]: value} } // $update is an object use the key as the value to use for the new key
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
data = [data];
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
let responseDataList = [];
|
|
1020
|
+
for (let i = 0; i < data.length; i++) {
|
|
1021
|
+
if (data[i].type === "object") {
|
|
1022
|
+
let hasId = false;
|
|
1023
|
+
|
|
1024
|
+
// 1. Check your three scenarios just like before
|
|
1025
|
+
if (typeof data[i].object === "string") {
|
|
1026
|
+
hasId = !!data[i]._id;
|
|
1027
|
+
} else if (Array.isArray(data[i].object)) {
|
|
1028
|
+
hasId = !!data[i].object[0]?._id;
|
|
1029
|
+
} else if (typeof data[i].object === "object" && data[i].object !== null) {
|
|
1030
|
+
hasId = !!data[i].object?._id;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// 2. Apply the method based on what we found
|
|
1034
|
+
if (!data[i].object || !hasId) {
|
|
1035
|
+
data[i].method = "object.create";
|
|
1036
|
+
} else {
|
|
1037
|
+
data[i].method = "object.update";
|
|
1038
|
+
if (upsert) data[i].upsert = true;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
if (data[i].isUpsert) {
|
|
1043
|
+
data[i].upsert = true;
|
|
1044
|
+
delete data[i].isUpsert;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (data[i].method && data[i].method.endsWith(".create")) {
|
|
1048
|
+
element.setAttribute(data[i].type, "pending");
|
|
1049
|
+
} else if (
|
|
1050
|
+
data[i].method &&
|
|
1051
|
+
data[i].method.endsWith(".update") &&
|
|
1052
|
+
data[i].type == "object" &&
|
|
1053
|
+
typeof value == "string" &&
|
|
1054
|
+
window.CoCreate.crdt &&
|
|
1055
|
+
!"crdt"
|
|
1056
|
+
) {
|
|
1057
|
+
return window.CoCreate.crdt.replaceText({
|
|
1058
|
+
array: data[i].array,
|
|
1059
|
+
key: data[i].key,
|
|
1060
|
+
object: data[i].object._id,
|
|
1061
|
+
value
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
data[i] = await CRUD.send(data[i]);
|
|
1066
|
+
|
|
1067
|
+
responseDataList.push(data[i]);
|
|
1068
|
+
|
|
1069
|
+
if (
|
|
1070
|
+
data[i] &&
|
|
1071
|
+
(data[i].method.endsWith(".create") ||
|
|
1072
|
+
(data[i].type !== "object" &&
|
|
1073
|
+
data[i].method.endsWith(".update")))
|
|
1074
|
+
) {
|
|
1075
|
+
setTypeValue(element, data[i], action);
|
|
1076
|
+
} else if (data[i]) {
|
|
1077
|
+
if (action) {
|
|
1078
|
+
action.element.dispatchEvent(
|
|
1079
|
+
new CustomEvent("saved", {
|
|
1080
|
+
detail: data
|
|
1081
|
+
})
|
|
1082
|
+
);
|
|
1083
|
+
} else {
|
|
1084
|
+
document.dispatchEvent(
|
|
1085
|
+
new CustomEvent("saved", {
|
|
1086
|
+
detail: data
|
|
1087
|
+
})
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
return responseDataList;
|
|
1174
1094
|
}
|
|
1175
1095
|
|
|
1176
1096
|
function setTypeValue(element, data, action) {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
// // Set the id attribute of the element
|
|
1229
|
-
// if (key == '_id')
|
|
1230
|
-
// el.setValue(id)
|
|
1231
|
-
// let state_id = el.getAttribute('state_id');
|
|
1232
|
-
// // Set the state id to the state_ids.
|
|
1233
|
-
// if (state_id) {
|
|
1234
|
-
// state_ids.set(state_id, '');
|
|
1235
|
-
// }
|
|
1236
|
-
|
|
1237
|
-
// if (el.hasAttribute('state-object')) {
|
|
1238
|
-
// let stateObjectId = el.getAttribute('state-object');
|
|
1239
|
-
// // Set the state object id if not set.
|
|
1240
|
-
// if (stateObjectId == '') {
|
|
1241
|
-
// el.setAttribute('state-object', id);
|
|
1242
|
-
// let state_id = el.getAttribute('state_id');
|
|
1243
|
-
// // Set the state id to the state_ids.
|
|
1244
|
-
// if (state_id) {
|
|
1245
|
-
// state_ids.set(state_id, '');
|
|
1246
|
-
// }
|
|
1247
|
-
// }
|
|
1248
|
-
// }
|
|
1249
|
-
|
|
1250
|
-
// // Set the object attribute of all state_ids to the object attribute of all state_ids
|
|
1251
|
-
// if (state_ids.size > 0) {
|
|
1252
|
-
// for (let key of state_ids.keys()) {
|
|
1253
|
-
// let stateEls = document.querySelectorAll(`[state_id="${key}"]`)
|
|
1254
|
-
// for (let stateEl of stateEls) {
|
|
1255
|
-
// // if (stateEl.getAttribute('array') == array){
|
|
1256
|
-
// // Set the object id attribute to the stateEl s object if it is not set.
|
|
1257
|
-
// if (stateEl.getAttribute('object') == '') {
|
|
1258
|
-
// stateEl.setAttribute('object', id);
|
|
1259
|
-
// }
|
|
1260
|
-
// // }
|
|
1261
|
-
// }
|
|
1262
|
-
// }
|
|
1263
|
-
// }
|
|
1264
|
-
// }
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
if (action) {
|
|
1268
|
-
action.element.dispatchEvent(
|
|
1269
|
-
new CustomEvent("saved", {
|
|
1270
|
-
detail: data
|
|
1271
|
-
})
|
|
1272
|
-
);
|
|
1273
|
-
} else {
|
|
1274
|
-
document.dispatchEvent(
|
|
1275
|
-
new CustomEvent("saved", {
|
|
1276
|
-
detail: data
|
|
1277
|
-
})
|
|
1278
|
-
);
|
|
1279
|
-
}
|
|
1097
|
+
// TODO: if an array name is updated, the attibute array="" needs to be updated.
|
|
1098
|
+
|
|
1099
|
+
if (!data) return;
|
|
1100
|
+
|
|
1101
|
+
let form;
|
|
1102
|
+
if (element.tagName === "FORM") form = element;
|
|
1103
|
+
else if (element.parentElement)
|
|
1104
|
+
form = element.parentElement.closest("form");
|
|
1105
|
+
|
|
1106
|
+
if (!form) {
|
|
1107
|
+
if (data.type === "object") {
|
|
1108
|
+
if (data.object?.[0]?._id) {
|
|
1109
|
+
element.setAttribute("object", data.object[0]._id);
|
|
1110
|
+
}
|
|
1111
|
+
} else {
|
|
1112
|
+
element.setAttribute(data.type, data[data.type].name);
|
|
1113
|
+
}
|
|
1114
|
+
} else {
|
|
1115
|
+
let formObject = forms.get(form);
|
|
1116
|
+
if (form.getAttribute("object") === "pending")
|
|
1117
|
+
form.setAttribute("object", data.object[0]._id);
|
|
1118
|
+
|
|
1119
|
+
let elements = formObject.types.get(data.type);
|
|
1120
|
+
|
|
1121
|
+
for (let [el, elData] of elements.entries()) {
|
|
1122
|
+
if (data.type === "object") {
|
|
1123
|
+
if (!elData.object || elData.object === "pending") {
|
|
1124
|
+
elData.object = data.object[0]._id;
|
|
1125
|
+
el.setAttribute("object", data.object[0]._id);
|
|
1126
|
+
}
|
|
1127
|
+
} else if (!elData[data.type]) {
|
|
1128
|
+
elData[data.type] = data[data.type].name;
|
|
1129
|
+
el.setAttribute(data.type, data[data.type].name);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
setData(Array.from(elements.keys()), data);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
if (action) {
|
|
1136
|
+
action.element.dispatchEvent(
|
|
1137
|
+
new CustomEvent("saved", {
|
|
1138
|
+
detail: data
|
|
1139
|
+
})
|
|
1140
|
+
);
|
|
1141
|
+
} else {
|
|
1142
|
+
document.dispatchEvent(
|
|
1143
|
+
new CustomEvent("saved", {
|
|
1144
|
+
detail: data
|
|
1145
|
+
})
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1280
1148
|
}
|
|
1281
1149
|
|
|
1282
1150
|
async function remove(element) {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1151
|
+
if (
|
|
1152
|
+
element &&
|
|
1153
|
+
!(element instanceof HTMLCollection) &&
|
|
1154
|
+
!Array.isArray(element)
|
|
1155
|
+
)
|
|
1156
|
+
element = [element];
|
|
1157
|
+
for (let i = 0; i < element.length; i++) {
|
|
1158
|
+
delete element[i].hasRead;
|
|
1159
|
+
if (element[i].tagName === "FORM") {
|
|
1160
|
+
let form = forms.get(element[i]);
|
|
1161
|
+
if (!form) return;
|
|
1162
|
+
|
|
1163
|
+
form = form.elements;
|
|
1164
|
+
for (let el of form.keys()) {
|
|
1165
|
+
let key = elements.get(el);
|
|
1166
|
+
if (key) {
|
|
1167
|
+
keys.get(key).elements.delete(el);
|
|
1168
|
+
elements.delete(el);
|
|
1169
|
+
// debounce.delete(key)
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
let key = elements.get(element[i]);
|
|
1173
|
+
if (key) {
|
|
1174
|
+
keys.get(key).elements.delete(element[i]);
|
|
1175
|
+
if (!keys.get(key).elements.size) keys.delete(key);
|
|
1176
|
+
}
|
|
1177
|
+
elements.delete(element[i]);
|
|
1178
|
+
forms.delete(element[i]);
|
|
1179
|
+
} else {
|
|
1180
|
+
let key = elements.get(element[i]);
|
|
1181
|
+
if (key) {
|
|
1182
|
+
if (element[i].getFilter) filter.filters.delete(element[i]);
|
|
1183
|
+
keys.get(key).elements.delete(element[i]);
|
|
1184
|
+
elements.delete(element[i]);
|
|
1185
|
+
if (!keys.get(key).elements.size) keys.delete(key);
|
|
1186
|
+
|
|
1187
|
+
// debounce.delete(key)
|
|
1188
|
+
let form = element[i].closest("form");
|
|
1189
|
+
form = forms.get(form);
|
|
1190
|
+
if (form) {
|
|
1191
|
+
form.elements.delete(element[i]);
|
|
1192
|
+
if (!form.elements.size) forms.delete(form);
|
|
1193
|
+
}
|
|
1194
|
+
} else elements.delete(element[i]);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1329
1197
|
}
|
|
1330
1198
|
|
|
1331
1199
|
function initSocket() {
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1200
|
+
const type = ["storage", "database", "array", "index", "object", "filter"];
|
|
1201
|
+
const method = ["create", "update", "delete"];
|
|
1202
|
+
|
|
1203
|
+
for (let i = 0; i < type.length; i++) {
|
|
1204
|
+
for (let j = 0; j < method.length; j++) {
|
|
1205
|
+
const action = type[i] + "." + method[j];
|
|
1206
|
+
|
|
1207
|
+
CRUD.listen(action, function (data) {
|
|
1208
|
+
if (
|
|
1209
|
+
data.resolved &&
|
|
1210
|
+
data.status === "received" &&
|
|
1211
|
+
CRUD.socket.clientId === data.clientId
|
|
1212
|
+
)
|
|
1213
|
+
return;
|
|
1214
|
+
if (data.rendered) return;
|
|
1215
|
+
|
|
1216
|
+
data.rendered = true;
|
|
1217
|
+
|
|
1218
|
+
setData(null, data);
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1354
1222
|
}
|
|
1355
1223
|
|
|
1356
1224
|
Observer.init({
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1225
|
+
name: "render",
|
|
1226
|
+
types: ["addedNodes"],
|
|
1227
|
+
selector: "[render-clone]",
|
|
1228
|
+
callback: function (mutation) {
|
|
1229
|
+
if (
|
|
1230
|
+
mutation.parentElement &&
|
|
1231
|
+
!mutation.parentElement.hasAttribute("dnd")
|
|
1232
|
+
)
|
|
1233
|
+
return;
|
|
1234
|
+
let delayTimer = debounce.get(mutation);
|
|
1235
|
+
clearTimeout(delayTimer);
|
|
1236
|
+
debounce.delete(mutation.target);
|
|
1237
|
+
|
|
1238
|
+
let renderedNode = renderedNodes.get(mutation.target);
|
|
1239
|
+
if (!renderedNode) return;
|
|
1240
|
+
|
|
1241
|
+
if (!mutation.movedFrom) return;
|
|
1242
|
+
let draggedEl = mutation.target;
|
|
1243
|
+
let draggedFrom = mutation.movedFrom.parentElement;
|
|
1244
|
+
let droppedEl =
|
|
1245
|
+
mutation.target.nextElementSibling ||
|
|
1246
|
+
mutation.target.previousElementSibling;
|
|
1247
|
+
let droppedIn = mutation.parentElement;
|
|
1248
|
+
|
|
1249
|
+
if (!draggedFrom || !droppedIn) return;
|
|
1250
|
+
dndCrud(draggedEl, draggedFrom, droppedEl, droppedIn);
|
|
1251
|
+
}
|
|
1384
1252
|
});
|
|
1385
1253
|
|
|
1386
1254
|
// TODO: has the potential to work on most of the crud elements specifically if the value is an object or an array
|
|
1387
1255
|
async function dndCrud(draggedEl, draggedFrom, droppedEl, droppedIn) {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
if (to) dndCrudSend(to.newData, "update");
|
|
1256
|
+
let from = await dndCrudData(draggedEl, draggedFrom, "remove");
|
|
1257
|
+
let to = await dndCrudData(droppedEl, droppedIn, "add");
|
|
1258
|
+
|
|
1259
|
+
if (from && to && !draggedFrom.isSameNode(droppedIn)) {
|
|
1260
|
+
let element = getDataElements(from.data);
|
|
1261
|
+
if (!element.length) return;
|
|
1262
|
+
|
|
1263
|
+
if (!element.includes(droppedIn)) {
|
|
1264
|
+
if (from.keyPath.includes(".")) {
|
|
1265
|
+
let test = { [from.keyPath]: undefined };
|
|
1266
|
+
|
|
1267
|
+
from.clonedParentData = dotNotationToObject(test, from.clonedParentData);
|
|
1268
|
+
dndCrudSend(from.clonedParentData, "update");
|
|
1269
|
+
} else {
|
|
1270
|
+
const index = from.keyPath.match(/\[(\d+)\]/);
|
|
1271
|
+
let removeData = from.clonedParentData[from.clonedParentData.type].splice(
|
|
1272
|
+
index,
|
|
1273
|
+
1
|
|
1274
|
+
)[0];
|
|
1275
|
+
if (removeData) {
|
|
1276
|
+
removeData.type = from.clonedParentData.type;
|
|
1277
|
+
removeData[removeData.type] = removeData;
|
|
1278
|
+
dndCrudSend(removeData, "delete");
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
if (from.clonedParentData[from.clonedParentData.type].length)
|
|
1282
|
+
dndCrudSend(from.clonedParentData, "update");
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
if (to) dndCrudSend(to.clonedParentData, "update");
|
|
1421
1288
|
}
|
|
1422
1289
|
|
|
1423
1290
|
async function dndCrudData(element, parent, operator) {
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
return { data, newData, keyPath, clones, index };
|
|
1291
|
+
if (!elements.has(parent)) return;
|
|
1292
|
+
let data = await parent.getData();
|
|
1293
|
+
let clonedParentData = getObject(parent);
|
|
1294
|
+
|
|
1295
|
+
let { dragData, sortName, sortDirection, keyPath, clones, index } = dndNewData(
|
|
1296
|
+
element,
|
|
1297
|
+
data
|
|
1298
|
+
);
|
|
1299
|
+
clonedParentData[clonedParentData.type] = [];
|
|
1300
|
+
|
|
1301
|
+
if (sortName) {
|
|
1302
|
+
for (let i = 0; i < clones.length; i++) {
|
|
1303
|
+
if (i > index) {
|
|
1304
|
+
let previousData = data[data.type][index];
|
|
1305
|
+
dragData[sortName] = operator === "add" ? i + 1 : i - 1;
|
|
1306
|
+
|
|
1307
|
+
clonedParentData[clonedParentData.type].push({ ...previousData, ...dragData });
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
} else {
|
|
1311
|
+
clonedParentData[clonedParentData.type] = [{ ...data[data.type][index], ...dragData }];
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
return { data, clonedParentData, keyPath, clones, index };
|
|
1449
1315
|
}
|
|
1450
1316
|
|
|
1451
1317
|
function dndNewData(element, data) {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
return { Data, sortName, sortDirection, keyPath, clones, index };
|
|
1318
|
+
let dragData = {};
|
|
1319
|
+
if (data.$filter.query) {
|
|
1320
|
+
dndNewDataUpdate(dragData, data.$filter.query);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
let sortName, sortDirection;
|
|
1324
|
+
let sort = data.$filter.sort;
|
|
1325
|
+
if (sort && sort.length) {
|
|
1326
|
+
for (let i = sort.length - 1; i >= 0; i--) {
|
|
1327
|
+
if (typeof data[sort.key] === "number") {
|
|
1328
|
+
sortName = sort.key;
|
|
1329
|
+
sortDirection = sort.direction;
|
|
1330
|
+
break;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
let keyPath, clonesMap, clones, index;
|
|
1336
|
+
|
|
1337
|
+
let renderedNode = renderedNodes.get(element);
|
|
1338
|
+
if (renderedNode) {
|
|
1339
|
+
keyPath = renderedNode.keyPath;
|
|
1340
|
+
clonesMap = renderedNode.template.clones;
|
|
1341
|
+
clones = Array.from(clonesMap.values());
|
|
1342
|
+
index = clones.indexOf(element);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
return { dragData, sortName, sortDirection, keyPath, clones, index };
|
|
1481
1346
|
}
|
|
1482
1347
|
|
|
1483
|
-
function dndNewDataUpdate(
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1348
|
+
function dndNewDataUpdate(dragData, query) {
|
|
1349
|
+
for (let key of Object.keys(query)) {
|
|
1350
|
+
if (key === "$and" || key === "$or" || key === "$nor") {
|
|
1351
|
+
for (let i = 0; i < query[key].length; i++) {
|
|
1352
|
+
dndNewDataUpdate(dragData, query[key][i]);
|
|
1353
|
+
}
|
|
1354
|
+
} else if (
|
|
1355
|
+
typeof query[key] === "object" &&
|
|
1356
|
+
!Array.isArray(query[key])
|
|
1357
|
+
) {
|
|
1358
|
+
if (query[key].$eq) dragData[key] = query[key].$eq;
|
|
1359
|
+
if (query[key].$ne) dragData[key] = query[key].$ne;
|
|
1360
|
+
} else {
|
|
1361
|
+
dragData[key] = query[key];
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1499
1364
|
}
|
|
1500
1365
|
|
|
1501
1366
|
function dndCrudSend(data, crudType) {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1367
|
+
if (CRUD) {
|
|
1368
|
+
let action = data.type;
|
|
1369
|
+
action = action.charAt(0).toUpperCase() + action.slice(1);
|
|
1370
|
+
CRUD[crudType + action](data);
|
|
1371
|
+
} else console.log("dnd reordered data set as crud is unavailable");
|
|
1507
1372
|
}
|
|
1508
1373
|
|
|
1509
1374
|
Observer.init({
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1375
|
+
name: "CoCreateElementsChildList",
|
|
1376
|
+
types: ["addedNodes"],
|
|
1377
|
+
selector: selector,
|
|
1378
|
+
callback: function (mutation) {
|
|
1379
|
+
init([mutation.target]);
|
|
1380
|
+
}
|
|
1516
1381
|
});
|
|
1517
1382
|
|
|
1518
1383
|
Observer.init({
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
// debounce.delete(mutation.target)
|
|
1527
|
-
// remove(mutation.target)
|
|
1528
|
-
// }, 3000);
|
|
1529
|
-
// debounce.set(mutation.target, delayTimer)
|
|
1530
|
-
// } else
|
|
1531
|
-
if (mutation.target.hasAttribute("render-clone")) return;
|
|
1532
|
-
remove(mutation.target);
|
|
1533
|
-
}
|
|
1384
|
+
name: "CoCreateElementsRemovedNodes",
|
|
1385
|
+
types: ["removedNodes"],
|
|
1386
|
+
selector: selector,
|
|
1387
|
+
callback: function (mutation) {
|
|
1388
|
+
if (mutation.target.hasAttribute("render-clone")) return;
|
|
1389
|
+
remove(mutation.target);
|
|
1390
|
+
}
|
|
1534
1391
|
});
|
|
1535
1392
|
|
|
1536
1393
|
Observer.init({
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1394
|
+
name: "CoCreateElementsAttributes",
|
|
1395
|
+
types: ["attributes"],
|
|
1396
|
+
attributeFilter: [
|
|
1397
|
+
"organization_id",
|
|
1398
|
+
"host",
|
|
1399
|
+
"storage",
|
|
1400
|
+
"database",
|
|
1401
|
+
"array",
|
|
1402
|
+
"index",
|
|
1403
|
+
"object",
|
|
1404
|
+
"key"
|
|
1405
|
+
],
|
|
1406
|
+
// target: selector, // blocks mutations when applied
|
|
1407
|
+
callback: function (mutation) {
|
|
1408
|
+
let currentValue = mutation.target.getAttribute(mutation.attributeName);
|
|
1409
|
+
if (currentValue !== mutation.oldValue) {
|
|
1410
|
+
if (mutation.target.tagName === "FORM") return;
|
|
1411
|
+
remove(mutation.target);
|
|
1412
|
+
init([mutation.target]);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1558
1415
|
});
|
|
1559
1416
|
|
|
1560
1417
|
Actions.init([
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1418
|
+
{
|
|
1419
|
+
name: "save",
|
|
1420
|
+
endEvent: "saved",
|
|
1421
|
+
callback: (action) => {
|
|
1422
|
+
if ((action.form, action)) save(action.form, action);
|
|
1423
|
+
}
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
name: "delete",
|
|
1427
|
+
endEvent: "deleted",
|
|
1428
|
+
callback: async (action) => {
|
|
1429
|
+
// TODO: use selector to target elements for deletion if element is apart of render get render get rendering element for more crud detils
|
|
1430
|
+
// this way any selector can be used to target crud deletions not just .selected
|
|
1431
|
+
let elements = [];
|
|
1432
|
+
if (action.element.hasAttribute("delete-query")) {
|
|
1433
|
+
elements = queryElements({
|
|
1434
|
+
element: action.element,
|
|
1435
|
+
prefix: "delete"
|
|
1436
|
+
});
|
|
1437
|
+
} else {
|
|
1438
|
+
elements = [action.element];
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1442
|
+
const data = getObject(elements[i]);
|
|
1443
|
+
if (!data) return;
|
|
1444
|
+
data.method = data.type + ".delete";
|
|
1445
|
+
|
|
1446
|
+
if (elements[i].renderValue) {
|
|
1447
|
+
let selected = elements[i].querySelectorAll(".selected");
|
|
1448
|
+
data[data.type] = [];
|
|
1449
|
+
for (let j = 0; j < selected.length; j++) {
|
|
1450
|
+
let attribute = selected[j].getAttribute(data.type);
|
|
1451
|
+
if (attribute) {
|
|
1452
|
+
attribute = attribute.split(",");
|
|
1453
|
+
for (let k = 0; k < attribute.length; k++) {
|
|
1454
|
+
if (data.type === "object")
|
|
1455
|
+
data[data.type].push({ _id: attribute[k] });
|
|
1456
|
+
else {
|
|
1457
|
+
data[data.type].push(attribute[k]);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
} else if (
|
|
1463
|
+
data.type === "object" &&
|
|
1464
|
+
typeof data[data.type] === "string"
|
|
1465
|
+
)
|
|
1466
|
+
data[data.type] = { _id: data[data.type] };
|
|
1467
|
+
|
|
1468
|
+
let response = await CRUD.send(data);
|
|
1469
|
+
action.element.dispatchEvent(
|
|
1470
|
+
new CustomEvent("deleted", {
|
|
1471
|
+
detail: response
|
|
1472
|
+
})
|
|
1473
|
+
);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1620
1477
|
]);
|
|
1621
1478
|
|
|
1622
1479
|
init();
|
|
1623
1480
|
|
|
1624
1481
|
export default {
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
};
|
|
1482
|
+
init,
|
|
1483
|
+
read,
|
|
1484
|
+
save,
|
|
1485
|
+
getData,
|
|
1486
|
+
getObject,
|
|
1487
|
+
reset,
|
|
1488
|
+
elements,
|
|
1489
|
+
keys,
|
|
1490
|
+
forms,
|
|
1491
|
+
debounce,
|
|
1492
|
+
getAttributes,
|
|
1493
|
+
setTypeValue
|
|
1494
|
+
};
|