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 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()">&#x2715;</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()">&#x2715;</collection-deleter>
@@ -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 = 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
 
@@ -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
- items.push(firstItemTemplate.innerHTML);
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
- items.push(noItemTemplate.innerHTML);
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
- this.destroy();
44
- this.render();
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 = this.inputElement.value;
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
- return (this.inputElement && this.inputElement.value) || '';
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
- let oldValue = this.inputElement.checked;
68
- this.inputElement.checked = newValue;
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
- let oldValue = this.inputElement.value;
79
+ oldValue = this.inputElement.value;
75
80
  this.inputElement.value = newValue;
76
81
  if (oldValue !== newValue) {
77
82
  this.triggerChange();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasufy-components",
3
- "version": "3.11.0",
3
+ "version": "3.13.0",
4
4
  "description": "Components for Saasufy.",
5
5
  "main": "index.js",
6
6
  "scripts": {