saasufy-components 3.11.0 → 3.13.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/README.md +9 -2
- package/collection-adder.js +12 -1
- package/collection-browser.js +14 -4
- package/input-provider.js +27 -4
- package/model-input.js +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -253,7 +253,7 @@ A form component for inserting data into collections.
|
|
|
253
253
|
<collection-adder
|
|
254
254
|
collection-type="Product"
|
|
255
255
|
collection-fields="name,brand,qty"
|
|
256
|
-
model-values="categoryName=electronics"
|
|
256
|
+
model-values="categoryName=electronics,isNew:boolean=true"
|
|
257
257
|
submit-button-label="Create"
|
|
258
258
|
trim-spaces
|
|
259
259
|
></collection-adder>
|
|
@@ -263,7 +263,7 @@ A form component for inserting data into collections.
|
|
|
263
263
|
|
|
264
264
|
- `collection-type` (required): Specifies the type of collection to add the resource to when the form is submitted. This should match a `Model` available in your Saasufy service.
|
|
265
265
|
- `collection-fields`: A comma-separated list of fields from the `Model` to display as input elements inside the form for the user to fill in. Each field name in this list can optionally be followed by an input element type after a `:` character. For example `collection-fields="qty:number, size:select(small,medium,large)` will create one input element with `type="number"` and one with `type=select` with options `small`, `medium` or `large`. To make a select field optional, you can prefix the list of options with a comma; e.g. `size:select(,small,medium,large)`.
|
|
266
|
-
- `model-values`: An optional list of key-value pairs in the format `field1=value1,field2=value2` to add to the newly created resource alongside the values collected from the user via the form.
|
|
266
|
+
- `model-values`: An optional list of key-value pairs in the format `field1=value1,field2=value2` to add to the newly created resource alongside the values collected from the user via the form. For non-string values, the type should be provided in the format `fieldName:type=value`; supported types are `string`, `number` and `boolean`. Unlike `collection-fields` which are rendered as input elements in the form, `model-values` are not shown to the user.
|
|
267
267
|
- `submit-button-label`: Text to display on the submit button. If not specified, defaults to `Submit`.
|
|
268
268
|
- `hide-submit-button`: Adding this attribute will hide the submit button from the form.
|
|
269
269
|
- `success-message`: A message to show the user if the resource has been successfully added to the collection after submitting the form.
|
|
@@ -284,6 +284,13 @@ It supports either immediate deletion or deletion upon confirmation; in the latt
|
|
|
284
284
|
|
|
285
285
|
**Example usage**
|
|
286
286
|
|
|
287
|
+
```html
|
|
288
|
+
<!-- Must be placed somewhere inside a collection-browser component, typically inside the slotted item template. -->
|
|
289
|
+
<collection-deleter model-id="{{Product.id}}" onclick="deleteItem()">✕</collection-deleter>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
OR (with confirmation step)
|
|
293
|
+
|
|
287
294
|
```html
|
|
288
295
|
<!-- Must be placed somewhere inside a collection-browser component, typically inside the slotted item template. -->
|
|
289
296
|
<collection-deleter model-id="{{Product.id}}" confirm-message="Are you sure you want to delete the {{Product.name}} product?" onclick="confirmDeleteItem()">✕</collection-deleter>
|
package/collection-adder.js
CHANGED
|
@@ -154,6 +154,7 @@ class CollectionAdder extends SocketConsumer {
|
|
|
154
154
|
|
|
155
155
|
let {
|
|
156
156
|
fieldNames: modelFieldNames,
|
|
157
|
+
fieldTypes: modelFieldTypes,
|
|
157
158
|
fieldValues: modelFieldValues
|
|
158
159
|
} = convertStringToFieldParams(this.getAttribute('model-values'));
|
|
159
160
|
|
|
@@ -174,7 +175,17 @@ class CollectionAdder extends SocketConsumer {
|
|
|
174
175
|
autocorrect ? ` autocorrect="${autocorrect}"` : ''
|
|
175
176
|
}`;
|
|
176
177
|
|
|
177
|
-
this.modelFieldValues =
|
|
178
|
+
this.modelFieldValues = Object.fromEntries(
|
|
179
|
+
Object.entries(modelFieldValues).map(([key, value]) => {
|
|
180
|
+
if (modelFieldTypes[key] === 'boolean') {
|
|
181
|
+
return [ key, value !== 'false' && value !== '' ];
|
|
182
|
+
}
|
|
183
|
+
if (modelFieldTypes[key] === 'number') {
|
|
184
|
+
return [ key, Number(value) ];
|
|
185
|
+
}
|
|
186
|
+
return [ key, value ];
|
|
187
|
+
})
|
|
188
|
+
);
|
|
178
189
|
|
|
179
190
|
if (this.collection) this.collection.destroy();
|
|
180
191
|
|
package/collection-browser.js
CHANGED
|
@@ -202,14 +202,24 @@ class CollectionBrowser extends SocketConsumer {
|
|
|
202
202
|
|
|
203
203
|
let items = [];
|
|
204
204
|
|
|
205
|
+
let type = this.getAttribute('type-alias') || this.collection.type;
|
|
206
|
+
|
|
205
207
|
if (firstItemTemplate) {
|
|
206
|
-
|
|
208
|
+
let itemString = renderTemplate(
|
|
209
|
+
firstItemTemplate.innerHTML,
|
|
210
|
+
{ [`$${type}`]: this.collection.meta },
|
|
211
|
+
this.socket
|
|
212
|
+
);
|
|
213
|
+
items.push(itemString);
|
|
207
214
|
}
|
|
208
215
|
if (noItemTemplate && !this.collection.value.length) {
|
|
209
|
-
|
|
216
|
+
let itemString = renderTemplate(
|
|
217
|
+
noItemTemplate.innerHTML,
|
|
218
|
+
{ [`$${type}`]: this.collection.meta },
|
|
219
|
+
this.socket
|
|
220
|
+
);
|
|
221
|
+
items.push(itemString);
|
|
210
222
|
} else if (itemTemplate) {
|
|
211
|
-
let type = this.getAttribute('type-alias') || this.collection.type;
|
|
212
|
-
|
|
213
223
|
for (let modelItem of this.collection.value) {
|
|
214
224
|
let itemString = renderTemplate(
|
|
215
225
|
itemTemplate.innerHTML,
|
package/input-provider.js
CHANGED
|
@@ -40,8 +40,12 @@ class InputProvider extends HTMLElement {
|
|
|
40
40
|
|
|
41
41
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
42
42
|
if (!this.isReady) return;
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if (name === 'value') {
|
|
44
|
+
this.value = newValue;
|
|
45
|
+
} else {
|
|
46
|
+
this.destroy();
|
|
47
|
+
this.render();
|
|
48
|
+
}
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
triggerChange() {
|
|
@@ -53,7 +57,20 @@ class InputProvider extends HTMLElement {
|
|
|
53
57
|
if (newValue && this.hasAttribute('computable-value')) {
|
|
54
58
|
newValue = renderTemplate(newValue);
|
|
55
59
|
}
|
|
56
|
-
let oldValue
|
|
60
|
+
let oldValue;
|
|
61
|
+
if (this.inputElement.type === 'checkbox') {
|
|
62
|
+
oldValue = this.inputElement.checked;
|
|
63
|
+
if (typeof newValue === 'string') {
|
|
64
|
+
this.inputElement.checked = newValue !== 'false' && newValue !== '';
|
|
65
|
+
} else {
|
|
66
|
+
this.inputElement.checked = newValue;
|
|
67
|
+
}
|
|
68
|
+
if (oldValue !== newValue) {
|
|
69
|
+
this.triggerChange();
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
oldValue = this.inputElement.value;
|
|
57
74
|
this.inputElement.value = newValue;
|
|
58
75
|
if (oldValue !== newValue) {
|
|
59
76
|
this.triggerChange();
|
|
@@ -62,7 +79,13 @@ class InputProvider extends HTMLElement {
|
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
get value() {
|
|
65
|
-
|
|
82
|
+
if (!this.inputElement) {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
if (this.inputElement.type === 'checkbox') {
|
|
86
|
+
return this.inputElement.checked;
|
|
87
|
+
}
|
|
88
|
+
return this.inputElement.value || '';
|
|
66
89
|
}
|
|
67
90
|
|
|
68
91
|
render() {
|
package/model-input.js
CHANGED
|
@@ -63,15 +63,20 @@ class ModelInput extends SocketConsumer {
|
|
|
63
63
|
if (newValue && this.hasAttribute('computable-value')) {
|
|
64
64
|
newValue = renderTemplate(newValue);
|
|
65
65
|
}
|
|
66
|
+
let oldValue;
|
|
66
67
|
if (this.inputElement.type === 'checkbox') {
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
oldValue = this.inputElement.checked;
|
|
69
|
+
if (typeof newValue === 'string') {
|
|
70
|
+
this.inputElement.checked = newValue !== 'false' && newValue !== '';
|
|
71
|
+
} else {
|
|
72
|
+
this.inputElement.checked = newValue;
|
|
73
|
+
}
|
|
69
74
|
if (oldValue !== newValue) {
|
|
70
75
|
this.triggerChange();
|
|
71
76
|
}
|
|
72
77
|
return;
|
|
73
78
|
}
|
|
74
|
-
|
|
79
|
+
oldValue = this.inputElement.value;
|
|
75
80
|
this.inputElement.value = newValue;
|
|
76
81
|
if (oldValue !== newValue) {
|
|
77
82
|
this.triggerChange();
|