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