@cocreate/elements 1.41.1 → 1.42.1
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 +28 -0
- package/demo/index.html +177 -177
- package/docs/index.html +330 -332
- package/package.json +11 -15
- package/src/fetchSrc.js +147 -154
- package/src/form.js +29 -12
- package/src/index.js +65 -39
- package/src/value.js +106 -0
- package/webpack.config.js +65 -90
package/src/index.js
CHANGED
|
@@ -40,6 +40,7 @@ import { render, renderValue, renderedNodes } from "@cocreate/render";
|
|
|
40
40
|
import "@cocreate/element-prototype";
|
|
41
41
|
import "./fetchSrc";
|
|
42
42
|
import { reset } from "./form";
|
|
43
|
+
import "./value.js";
|
|
43
44
|
|
|
44
45
|
const selector = "[storage], [database], [array], [render-json]";
|
|
45
46
|
const elements = new Map();
|
|
@@ -67,9 +68,9 @@ async function init(element) {
|
|
|
67
68
|
!(element instanceof HTMLCollection) &&
|
|
68
69
|
!(element instanceof NodeList) &&
|
|
69
70
|
!Array.isArray(element)
|
|
70
|
-
)
|
|
71
|
+
) {
|
|
71
72
|
element = [element];
|
|
72
|
-
else if (!element) {
|
|
73
|
+
} else if (!element) {
|
|
73
74
|
element = document.querySelectorAll(selector);
|
|
74
75
|
initSocket();
|
|
75
76
|
}
|
|
@@ -462,7 +463,12 @@ async function filterData(element, data, type, key) {
|
|
|
462
463
|
}
|
|
463
464
|
|
|
464
465
|
let property = key;
|
|
465
|
-
if (operator)
|
|
466
|
+
if (operator) {
|
|
467
|
+
property = property.replace(operator + ".", "");
|
|
468
|
+
if (operator === "$sum") {
|
|
469
|
+
value = 0;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
466
472
|
if (Array.isArray(data[type])) {
|
|
467
473
|
let Data = [],
|
|
468
474
|
isObject;
|
|
@@ -482,7 +488,7 @@ async function filterData(element, data, type, key) {
|
|
|
482
488
|
if (docValue) {
|
|
483
489
|
if (operator === "$sum" && typeof docValue === "number") {
|
|
484
490
|
if (typeof value !== "number") value = 0;
|
|
485
|
-
value += docValue;
|
|
491
|
+
value += docValue || 0;
|
|
486
492
|
} else if (Array.isArray(docValue)) {
|
|
487
493
|
Data.push(...docValue);
|
|
488
494
|
} else {
|
|
@@ -844,11 +850,7 @@ async function getData(form) {
|
|
|
844
850
|
if (attribute.includes("save", "delete")) continue;
|
|
845
851
|
}
|
|
846
852
|
|
|
847
|
-
if (
|
|
848
|
-
element.matches(
|
|
849
|
-
"[render-selector], [render-closest], [render-parent], [render-next], [render-previous]"
|
|
850
|
-
)
|
|
851
|
-
) {
|
|
853
|
+
if (element.matches("[render-query]")) {
|
|
852
854
|
let type = element.getAttribute("type");
|
|
853
855
|
if (type !== "file") continue;
|
|
854
856
|
}
|
|
@@ -991,7 +993,7 @@ async function getData(form) {
|
|
|
991
993
|
}
|
|
992
994
|
|
|
993
995
|
//dataKey should be used to group
|
|
994
|
-
let key = dataKey
|
|
996
|
+
let key = dataKey; //+ Data.method;
|
|
995
997
|
if (dataKeys.has(key)) {
|
|
996
998
|
let storedData = dataKeys.get(key)[Data.type];
|
|
997
999
|
dataKeys.get(key)[Data.type] = {
|
|
@@ -1010,7 +1012,7 @@ async function getData(form) {
|
|
|
1010
1012
|
return dataArray;
|
|
1011
1013
|
}
|
|
1012
1014
|
|
|
1013
|
-
async function save(element) {
|
|
1015
|
+
async function save(element, action) {
|
|
1014
1016
|
if (!element) return;
|
|
1015
1017
|
let data, value;
|
|
1016
1018
|
let upsert = element.getAttribute("upsert");
|
|
@@ -1116,19 +1118,28 @@ async function save(element) {
|
|
|
1116
1118
|
(data[i].type !== "object" &&
|
|
1117
1119
|
data[i].method.endsWith(".update")))
|
|
1118
1120
|
) {
|
|
1119
|
-
setTypeValue(element, data[i]);
|
|
1120
|
-
} else if (data[i])
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1121
|
+
setTypeValue(element, data[i], action);
|
|
1122
|
+
} else if (data[i]) {
|
|
1123
|
+
if (action) {
|
|
1124
|
+
action.element.dispatchEvent(
|
|
1125
|
+
new CustomEvent("saved", {
|
|
1126
|
+
detail: data
|
|
1127
|
+
})
|
|
1128
|
+
);
|
|
1129
|
+
} else {
|
|
1130
|
+
document.dispatchEvent(
|
|
1131
|
+
new CustomEvent("saved", {
|
|
1132
|
+
detail: data
|
|
1133
|
+
})
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1126
1137
|
}
|
|
1127
1138
|
|
|
1128
1139
|
return Data;
|
|
1129
1140
|
}
|
|
1130
1141
|
|
|
1131
|
-
function setTypeValue(element, data) {
|
|
1142
|
+
function setTypeValue(element, data, action) {
|
|
1132
1143
|
// TODO: if an array name is updated, the attibute array="" needs to be updated.
|
|
1133
1144
|
|
|
1134
1145
|
if (!data) return;
|
|
@@ -1164,7 +1175,7 @@ function setTypeValue(element, data) {
|
|
|
1164
1175
|
}
|
|
1165
1176
|
setData(Array.from(elements.keys()), data);
|
|
1166
1177
|
|
|
1167
|
-
// const state_ids = new Map()
|
|
1178
|
+
// const state_ids = new Map()
|
|
1168
1179
|
|
|
1169
1180
|
// let state_id = form.getAttribute('state_id');
|
|
1170
1181
|
// if (state_id) {
|
|
@@ -1217,11 +1228,19 @@ function setTypeValue(element, data) {
|
|
|
1217
1228
|
// }
|
|
1218
1229
|
}
|
|
1219
1230
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1231
|
+
if (action) {
|
|
1232
|
+
action.element.dispatchEvent(
|
|
1233
|
+
new CustomEvent("saved", {
|
|
1234
|
+
detail: data
|
|
1235
|
+
})
|
|
1236
|
+
);
|
|
1237
|
+
} else {
|
|
1238
|
+
document.dispatchEvent(
|
|
1239
|
+
new CustomEvent("saved", {
|
|
1240
|
+
detail: data
|
|
1241
|
+
})
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1225
1244
|
}
|
|
1226
1245
|
|
|
1227
1246
|
async function remove(element) {
|
|
@@ -1291,6 +1310,9 @@ function initSocket() {
|
|
|
1291
1310
|
if (data.rendered) return;
|
|
1292
1311
|
|
|
1293
1312
|
data.rendered = true;
|
|
1313
|
+
if (data && data.key === "answers") {
|
|
1314
|
+
console.log("test");
|
|
1315
|
+
}
|
|
1294
1316
|
|
|
1295
1317
|
setData(null, data);
|
|
1296
1318
|
});
|
|
@@ -1300,7 +1322,7 @@ function initSocket() {
|
|
|
1300
1322
|
|
|
1301
1323
|
Observer.init({
|
|
1302
1324
|
name: "render",
|
|
1303
|
-
|
|
1325
|
+
types: ["addedNodes"],
|
|
1304
1326
|
selector: "[render-clone]",
|
|
1305
1327
|
callback: function (mutation) {
|
|
1306
1328
|
if (!mutation.parentElement.hasAttribute("dnd")) return;
|
|
@@ -1449,16 +1471,16 @@ function dndCrudSend(data, crudType) {
|
|
|
1449
1471
|
|
|
1450
1472
|
Observer.init({
|
|
1451
1473
|
name: "CoCreateElementsChildList",
|
|
1452
|
-
|
|
1474
|
+
types: ["addedNodes"],
|
|
1453
1475
|
selector: selector,
|
|
1454
1476
|
callback: function (mutation) {
|
|
1455
|
-
init(mutation.
|
|
1477
|
+
init([mutation.target]);
|
|
1456
1478
|
}
|
|
1457
1479
|
});
|
|
1458
1480
|
|
|
1459
1481
|
Observer.init({
|
|
1460
1482
|
name: "CoCreateElementsRemovedNodes",
|
|
1461
|
-
|
|
1483
|
+
types: ["removedNodes"],
|
|
1462
1484
|
selector: selector,
|
|
1463
1485
|
callback: function (mutation) {
|
|
1464
1486
|
// if (mutation.target.parentElement) return
|
|
@@ -1476,8 +1498,8 @@ Observer.init({
|
|
|
1476
1498
|
|
|
1477
1499
|
Observer.init({
|
|
1478
1500
|
name: "CoCreateElementsAttributes",
|
|
1479
|
-
|
|
1480
|
-
|
|
1501
|
+
types: ["attributes"],
|
|
1502
|
+
attributeFilter: [
|
|
1481
1503
|
"organization_id",
|
|
1482
1504
|
"host",
|
|
1483
1505
|
"storage",
|
|
@@ -1491,8 +1513,8 @@ Observer.init({
|
|
|
1491
1513
|
callback: function (mutation) {
|
|
1492
1514
|
let currentValue = mutation.target.getAttribute(mutation.attributeName);
|
|
1493
1515
|
if (currentValue !== mutation.oldValue) {
|
|
1494
|
-
remove(mutation.target);
|
|
1495
1516
|
if (mutation.target.tagName === "FORM") return;
|
|
1517
|
+
remove(mutation.target);
|
|
1496
1518
|
init([mutation.target]);
|
|
1497
1519
|
}
|
|
1498
1520
|
}
|
|
@@ -1503,7 +1525,7 @@ Actions.init([
|
|
|
1503
1525
|
name: "save",
|
|
1504
1526
|
endEvent: "saved",
|
|
1505
1527
|
callback: (action) => {
|
|
1506
|
-
if (action.form) save(action.form);
|
|
1528
|
+
if ((action.form, action)) save(action.form, action);
|
|
1507
1529
|
}
|
|
1508
1530
|
},
|
|
1509
1531
|
{
|
|
@@ -1512,11 +1534,15 @@ Actions.init([
|
|
|
1512
1534
|
callback: async (action) => {
|
|
1513
1535
|
// TODO: use selector to target elements for deletion if element is apart of render get render get rendering element for more crud detils
|
|
1514
1536
|
// this way any selector can be used to target crud deletions not just .selected
|
|
1515
|
-
let elements =
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1537
|
+
let elements = [];
|
|
1538
|
+
if (action.element.hasAttribute("delete-query")) {
|
|
1539
|
+
elements = queryElements({
|
|
1540
|
+
element: action.element,
|
|
1541
|
+
prefix: "delete"
|
|
1542
|
+
});
|
|
1543
|
+
} else {
|
|
1544
|
+
elements = [action.element];
|
|
1545
|
+
}
|
|
1520
1546
|
|
|
1521
1547
|
for (let i = 0; i < elements.length; i++) {
|
|
1522
1548
|
const data = getObject(elements[i]);
|
|
@@ -1546,7 +1572,7 @@ Actions.init([
|
|
|
1546
1572
|
data[data.type] = { _id: data[data.type] };
|
|
1547
1573
|
|
|
1548
1574
|
let response = await CRUD.send(data);
|
|
1549
|
-
|
|
1575
|
+
action.element.dispatchEvent(
|
|
1550
1576
|
new CustomEvent("deleted", {
|
|
1551
1577
|
detail: response
|
|
1552
1578
|
})
|
package/src/value.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import Observer from "@cocreate/observer";
|
|
2
|
+
import "@cocreate/element-prototype";
|
|
3
|
+
import { queryElements } from "@cocreate/utils";
|
|
4
|
+
|
|
5
|
+
const selector = "[value-query]";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Initializes elements with value-* attributes to enable dynamic value retrieval and setting.
|
|
9
|
+
*
|
|
10
|
+
* @param {HTMLElement|HTMLCollection|NodeList|Array<HTMLElement>} [element] - Optional element(s) to initialize. If not provided, initializes all matching elements in the document.
|
|
11
|
+
*/
|
|
12
|
+
async function init(element) {
|
|
13
|
+
if (
|
|
14
|
+
element &&
|
|
15
|
+
!(element instanceof HTMLCollection) &&
|
|
16
|
+
!(element instanceof NodeList) &&
|
|
17
|
+
!Array.isArray(element)
|
|
18
|
+
) {
|
|
19
|
+
element = [element];
|
|
20
|
+
} else if (!element) {
|
|
21
|
+
element = document.querySelectorAll(selector);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < element.length; i++) {
|
|
25
|
+
initElement(element[i]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Initializes a single element with value-* attributes.
|
|
31
|
+
*
|
|
32
|
+
* @param {HTMLElement} element - The element to initialize.
|
|
33
|
+
*/
|
|
34
|
+
function initElement(element) {
|
|
35
|
+
let targets = queryElements({ element, prefix: "value" });
|
|
36
|
+
|
|
37
|
+
valueHandler(element, targets, true);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Handles the retrieval and setting of values based on value-* attributes.
|
|
42
|
+
*
|
|
43
|
+
* @param {HTMLElement} element - The element to set the value on.
|
|
44
|
+
* @param {object} targets - An object containing elements retrieved by queryElements().
|
|
45
|
+
*/
|
|
46
|
+
function valueHandler(element, targets, initialize) {
|
|
47
|
+
let values = [];
|
|
48
|
+
// TODO: consdier the potential of targets being an array of elements, should value be an array of the values?
|
|
49
|
+
for (let i = 0; i < targets.length; i++) {
|
|
50
|
+
if (!targets[i] || !targets[i].isConnected) {
|
|
51
|
+
targets.splice(i, 1); // Remove the element
|
|
52
|
+
i -= 1; // Adjust the index
|
|
53
|
+
continue; // Skip to the next iteration
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (initialize) {
|
|
57
|
+
// Remove existing listener (if any)
|
|
58
|
+
targets[i].removeEventListener("input", elementValueHandler);
|
|
59
|
+
|
|
60
|
+
// Add new listener
|
|
61
|
+
targets[i].addEventListener("input", elementValueHandler);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
values.push(targets[i].getValue());
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!values.length) {
|
|
68
|
+
return;
|
|
69
|
+
} else if (values.length === 1) {
|
|
70
|
+
values = values[0];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let attribute = element.getAttribute("value-attribute");
|
|
74
|
+
if (attribute) {
|
|
75
|
+
element.setAttribute(attribute, values);
|
|
76
|
+
} else {
|
|
77
|
+
element.setValue(values);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function elementValueHandler(e) {
|
|
81
|
+
valueHandler(element, targets);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
init();
|
|
86
|
+
|
|
87
|
+
Observer.init({
|
|
88
|
+
name: "CoCreateElementsValueAdded",
|
|
89
|
+
types: ["addedNodes"],
|
|
90
|
+
selector: selector,
|
|
91
|
+
callback: function (mutation) {
|
|
92
|
+
init(mutation.target);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
Observer.init({
|
|
97
|
+
name: "CoCreateElementsAttributes",
|
|
98
|
+
types: ["attributes"],
|
|
99
|
+
attributeFilter: ["value-query"],
|
|
100
|
+
callback: function (mutation) {
|
|
101
|
+
let currentValue = mutation.target.getAttribute(mutation.attributeName);
|
|
102
|
+
if (currentValue !== mutation.oldValue) {
|
|
103
|
+
initElement(mutation.target);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
package/webpack.config.js
CHANGED
|
@@ -1,90 +1,65 @@
|
|
|
1
|
-
const path = require("path")
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
module.exports = (env, argv) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
parallel: true,
|
|
67
|
-
// sourceMap: true, // Must be set to true if using source-maps in production
|
|
68
|
-
terserOptions: {
|
|
69
|
-
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
|
|
70
|
-
// extractComments: 'all',
|
|
71
|
-
compress: {
|
|
72
|
-
drop_console: true,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
}),
|
|
76
|
-
],
|
|
77
|
-
splitChunks: {
|
|
78
|
-
chunks: "all",
|
|
79
|
-
minSize: 200,
|
|
80
|
-
// maxSize: 99999,
|
|
81
|
-
//minChunks: 1,
|
|
82
|
-
|
|
83
|
-
cacheGroups: {
|
|
84
|
-
defaultVendors: false,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
}
|
|
89
|
-
return config
|
|
90
|
-
}
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
3
|
+
const { EsbuildPlugin } = require("esbuild-loader");
|
|
4
|
+
const { FileUploader } = require("@cocreate/webpack");
|
|
5
|
+
|
|
6
|
+
module.exports = async (env, argv) => {
|
|
7
|
+
const isProduction = argv && argv.mode === "production";
|
|
8
|
+
const config = {
|
|
9
|
+
entry: {
|
|
10
|
+
"CoCreate-elements": "./src/index.js"
|
|
11
|
+
},
|
|
12
|
+
output: {
|
|
13
|
+
path: path.resolve(__dirname, "dist"),
|
|
14
|
+
filename: isProduction ? "[name].min.js" : "[name].js",
|
|
15
|
+
libraryExport: "default",
|
|
16
|
+
library: ["CoCreate", "elements"],
|
|
17
|
+
clean: true
|
|
18
|
+
},
|
|
19
|
+
plugins: [
|
|
20
|
+
new MiniCssExtractPlugin({
|
|
21
|
+
filename: isProduction ? "[name].min.css" : "[name].css"
|
|
22
|
+
}),
|
|
23
|
+
new FileUploader(env, argv)
|
|
24
|
+
],
|
|
25
|
+
mode: isProduction ? "production" : "development",
|
|
26
|
+
devtool: isProduction ? "source-map" : "eval-source-map",
|
|
27
|
+
module: {
|
|
28
|
+
rules: [
|
|
29
|
+
{
|
|
30
|
+
test: /.js$/,
|
|
31
|
+
exclude: /node_modules/,
|
|
32
|
+
use: {
|
|
33
|
+
loader: "esbuild-loader",
|
|
34
|
+
options: {
|
|
35
|
+
loader: "js",
|
|
36
|
+
target: "es2017"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
test: /.css$/i,
|
|
42
|
+
use: [MiniCssExtractPlugin.loader, "css-loader"]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
optimization: {
|
|
47
|
+
minimize: isProduction,
|
|
48
|
+
minimizer: [
|
|
49
|
+
new EsbuildPlugin({
|
|
50
|
+
target: "es2017",
|
|
51
|
+
css: true
|
|
52
|
+
})
|
|
53
|
+
],
|
|
54
|
+
splitChunks: {
|
|
55
|
+
cacheGroups: {
|
|
56
|
+
defaultVendors: false
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
performance: {
|
|
61
|
+
hints: isProduction ? "warning" : false
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return config;
|
|
65
|
+
};
|