saasufy-components 2.14.0 → 2.15.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/README.md +288 -8
- package/collection-browser.js +3 -6
- package/collection-reducer.js +3 -6
- package/confirm-modal.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,6 @@ Components for Saasufy
|
|
|
27
27
|
|
|
28
28
|
### Display groups
|
|
29
29
|
- [render-group](#render-group)
|
|
30
|
-
- [conditional-group](#conditional-group)
|
|
31
30
|
- [if-group](#if-group)
|
|
32
31
|
- [switch-group](#switch-group)
|
|
33
32
|
- [collection-adder-group](#collection-adder-group)
|
|
@@ -69,7 +68,6 @@ To use components, you just need to include them into your `.html` file inside y
|
|
|
69
68
|
<script src="https://saasufy.com/node_modules/saasufy-components/oauth-link.js" type="module" defer></script>
|
|
70
69
|
<script src="https://saasufy.com/node_modules/saasufy-components/oauth-handler.js" type="module" defer></script>
|
|
71
70
|
<script src="https://saasufy.com/node_modules/saasufy-components/render-group.js" type="module" defer></script>
|
|
72
|
-
<script src="https://saasufy.com/node_modules/saasufy-components/conditional-group.js" type="module" defer></script>
|
|
73
71
|
<script src="https://saasufy.com/node_modules/saasufy-components/if-group.js" type="module" defer></script>
|
|
74
72
|
<script src="https://saasufy.com/node_modules/saasufy-components/switch-group.js" type="module" defer></script>
|
|
75
73
|
<script src="https://saasufy.com/node_modules/saasufy-components/collection-adder-group.js" type="module" defer></script>
|
|
@@ -332,14 +330,97 @@ In the example above, the name of the first element can be accessed with `{{Cate
|
|
|
332
330
|
|
|
333
331
|
Used for displaying and editing a single field of a model instance in real time.
|
|
334
332
|
|
|
333
|
+
**Example usage**
|
|
334
|
+
|
|
335
|
+
```html
|
|
336
|
+
<model-input
|
|
337
|
+
type="text"
|
|
338
|
+
model-type="Product"
|
|
339
|
+
model-id="{{productId}}"
|
|
340
|
+
model-field="name"
|
|
341
|
+
placeholder="Product name"
|
|
342
|
+
></model-input>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Attributes**
|
|
346
|
+
|
|
347
|
+
- `model-type` (required): Specifies the type of model to bind to. This should match a `Model` available in your Saasufy service.
|
|
348
|
+
- `model-id` (required): The id of the model instance/record to bind to.
|
|
349
|
+
- `model-field` (required): The field of the model instance/record to bind to for reading and updating.
|
|
350
|
+
- `debounce-delay`: The delay in milliseconds to wait before sending an update to the server. This is useful to batch multiple updates together (as is common when user is typing). Default is 300ms.
|
|
351
|
+
- `enable-rebound`: By default, real-time updates performed via `model-input` components are not sent back to the publishing client as it is assumed that state changes are either localized to a single `model-input` component or shared with other components on the same page via the use of `consumers`, `bind-to-collection` or `bind-to-model` attributes. There may be situations where you have a specific value displayed in multiple places on the same page/screen and want them to be updated in real-time to reflect the latest value of the model field. For convenience, you can add the `enable-rebound` attribute to the `model-input` component to force real-time updates to rebound back to the publisher and this will ensure that all components on the page will receive real-time updates (will sync with each other) without having to explicitly bind them together via the front end. Note that enabling rebound comes with additional performance overheads.
|
|
352
|
+
- `input-id`: Can be used to set an `id` attribute on the inner `input` element.
|
|
353
|
+
- `list`: If specified, this sets the list attribute of the inner `input` element to provide input suggestions (only works with standard input elements).
|
|
354
|
+
- `bind-to-model`: If this attribute exists, the `model-input` component will attempt to host its model data within the nearest compatible `model-viewer` parent component instead of creating its own model internally. This can improve efficiency/reuse of model data and provide a better user experience. For example, if the `model-input` element is re-rendered, it will not have to re-fetch its data as it will be kept inside its parent `model-viewer` component.
|
|
355
|
+
- `bind-to-collection`: If this attribute exists, the `model-input` component will attempt to host its model data within the nearest compatible `collection-browser` or `collection-reducer` parent component instead of creating its own model internally. This can improve efficiency/reuse of model data and provide a better user experience. For example, if the `model-input` element is re-rendered, it will not have to re-fetch its data as it will be kept inside its parent `collection-browser` or `collection-reducer` component. Note that the parent component will take over the responsibility for cleaning up the model; this includes scenarios where the user loads a different page of the collection/view where the specified model instance is no longer present.
|
|
356
|
+
- `type`: The type of the input component; can be `text`, `number`, `select`, `textarea` or `checkbox`.
|
|
357
|
+
- `placeholder`: Can be used to set the placeholder text on the inner input element.
|
|
358
|
+
- `consumers`: This allows you to connect this `model-input` to other elements on your page which share the same parent element. It takes a list of selectors with optional attributes to target. For example `.my-input:value` will find all elements with a `my-input` class and update their `value` attributes with the value of the `model-input` component in real-time. You can specify multiple selectors separated by commas such as `.my-input,my-div` - In this case, because attribute names are not specified, values will be injected into the `value` attribute (for input elements) or into the `innerHTML` property (for other kinds of elements). The default attribute/property depends on the element type.
|
|
359
|
+
- `show-error-message`: If this attribute is present, an error message will be displayed above the input if it fails to update the value.
|
|
360
|
+
- `options`: A comma-separated list of options to provide - This only works if the input type is `select`.
|
|
361
|
+
- `height`: Allows you to set the height of the inner `input` element programmatically.
|
|
362
|
+
- `default-value`: A default value to show the user if the underlying model field's value is null or undefined. Note that setting a default value will not affect the underlying model's value.
|
|
363
|
+
- `value`: Used to set the model's value.
|
|
364
|
+
- `hide-error-logs`: By default, this component will log errors to the console. If set, this attribute will suppress such errors from showing up on the console.
|
|
365
|
+
- `autocapitalize`: Can be `on` or `off` - It will set the auto-capitalize attribute on the inner input element. This is useful for mobile devices to enable or disable auto-capitalization of the first character which is typed into the input element.
|
|
366
|
+
- `autocorrect`: Can be `on` or `off` - It will set the auto-correct attribute on the inner input element. This is useful for mobile devices to enable or disable auto-correct.
|
|
367
|
+
|
|
335
368
|
### model-text
|
|
336
369
|
|
|
337
370
|
Used to displaying a field of a model instance in real time.
|
|
338
371
|
|
|
372
|
+
**Example usage**
|
|
373
|
+
|
|
374
|
+
```html
|
|
375
|
+
<model-text
|
|
376
|
+
type="text"
|
|
377
|
+
model-type="Product"
|
|
378
|
+
model-id="{{productId}}"
|
|
379
|
+
model-field="name"
|
|
380
|
+
></model-text>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Attributes**
|
|
384
|
+
|
|
385
|
+
- `model-type` (required): Specifies the type of model to bind to. This should match a `Model` available in your Saasufy service.
|
|
386
|
+
- `model-id` (required): The id of the model instance/record to bind to.
|
|
387
|
+
- `model-field` (required): The field of the model instance/record to bind to for reading.
|
|
388
|
+
- `bind-to-model`: If this attribute exists, the `model-text` component will attempt to fetch its model data from the nearest compatible `model-viewer` parent component instead of creating its own model internally. This can improve efficiency/reuse of model data and provide a better user experience. For example, if the `model-text` element is re-rendered, it will not have to re-fetch its data as it will be kept inside its parent `model-viewer` component.
|
|
389
|
+
- `bind-to-collection`: If this attribute exists, the `model-text` component will attempt to fetch its model data from the nearest compatible `collection-browser` or `collection-reducer` parent component instead of creating its own model internally. This can improve efficiency/reuse of model data and provide a better user experience. For example, if the `model-text` element is re-rendered, it will not have to re-fetch its data as it will be kept inside its parent `collection-browser` or `collection-reducer` component. Note that the parent component will take over the responsibility for cleaning up the model; this includes scenarios where the user loads a different page of the collection/view where the specified model instance is no longer present.
|
|
390
|
+
- `hide-error-logs`: By default, this component will log errors to the console. If set, this attribute will suppress such errors from showing up on the console.
|
|
391
|
+
|
|
339
392
|
### model-viewer
|
|
340
393
|
|
|
341
394
|
Used for rendering a single model resource using a template. This is the single-model alternative to the `collection-browser` which works with collections of models.
|
|
342
395
|
|
|
396
|
+
**Example usage**
|
|
397
|
+
|
|
398
|
+
```html
|
|
399
|
+
<model-viewer
|
|
400
|
+
model-type="Product"
|
|
401
|
+
model-id="{{modelId}}"
|
|
402
|
+
model-fields="name,desc,qty"
|
|
403
|
+
>
|
|
404
|
+
<template slot="item">
|
|
405
|
+
<div>
|
|
406
|
+
<div>Name: {{Product.name}}</div>
|
|
407
|
+
<div>Description: {{Product.desc}}</div>
|
|
408
|
+
<div>Quantity: {{Product.qty}}</div>
|
|
409
|
+
</div>
|
|
410
|
+
</template>
|
|
411
|
+
|
|
412
|
+
<div slot="viewport"></div>
|
|
413
|
+
</model-viewer>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Attributes**
|
|
417
|
+
|
|
418
|
+
- `model-type` (required): Specifies the type of model to bind to. This should match a `Model` available in your Saasufy service.
|
|
419
|
+
- `model-id` (required): The id of the model instance/record to bind to.
|
|
420
|
+
- `model-fields` (required): A comma-separated list of fields to bind to. Note that unlike with `model-input` and `model-text`, the attribute name is plural and can bind to multiple fields.
|
|
421
|
+
- `type-alias`: Allows you to provide an alternative name for your `Model` to use when injecting values inside the template. This is useful for situations where you may have multiple `model-browser` elements and/or `model-viewer` elements of the same type nested inside each other and want to avoid `Model` name clashes in the nested template definitions. For example, if the `type-alias` in the snippet above was set to `MyProduct`, then `{{Product.name}}` would become `{{MyProduct.name}}`.
|
|
422
|
+
- `hide-error-logs`: A flag which, when present, suppresses error logs from being printed to the console.
|
|
423
|
+
|
|
343
424
|
### input-provider
|
|
344
425
|
|
|
345
426
|
An input component which can pass data to other components (or HTML elements) via custom attributes.
|
|
@@ -347,6 +428,31 @@ A common use case for it is to pass user input to `collection-browser` or `model
|
|
|
347
428
|
This component can be configured to provide its data to multiple components (consumers) via custom attributes.
|
|
348
429
|
Note that an `input-provider` only targets elements which are downstream from its parent element in the HTML hierarchy.
|
|
349
430
|
|
|
431
|
+
**Example usage**
|
|
432
|
+
|
|
433
|
+
```html
|
|
434
|
+
<input-provider
|
|
435
|
+
type="text"
|
|
436
|
+
consumers=".my-input"
|
|
437
|
+
value="Hello world!"
|
|
438
|
+
placeholder="Message"
|
|
439
|
+
></input-provider>
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Attributes**
|
|
443
|
+
|
|
444
|
+
- `input-id`: Can be used to set an `id` attribute on the inner `input` element.
|
|
445
|
+
- `list`: If specified, this sets the list attribute of the inner `input` element to provide input suggestions (only works with standard input elements).
|
|
446
|
+
- `type`: The type of the input component; can be `text`, `number`, `select`, `textarea` or `checkbox`.
|
|
447
|
+
- `placeholder`: Can be used to set the placeholder text on the inner input element.
|
|
448
|
+
- `consumers`: This allows you to connect this `input-provider` to other elements on your page which share the same parent element. It takes a list of selectors with optional attributes to target. For example `.my-input:value` will find all elements with a `my-input` class and update their `value` attributes with the value of the `input-provider` component in real-time. You can specify multiple selectors separated by commas such as `.my-input,my-div` - In this case, because attribute names are not specified, values will be injected into the `value` attribute (for input elements) or into the `innerHTML` property (for other kinds of elements). The default attribute/property depends on the element type.
|
|
449
|
+
- `debounce-delay`: The delay in milliseconds to wait before triggering a change event. This is useful to batch multiple updates together (as is common when user is typing). Default is 800ms.
|
|
450
|
+
- `options`: A comma-separated list of options to provide - This only works if the input type is `select`.
|
|
451
|
+
- `height`: Allows you to set the height of the inner `input` element programmatically.
|
|
452
|
+
- `value`: Used to set the input's value.
|
|
453
|
+
- `autocapitalize`: Can be `on` or `off` - It will set the auto-capitalize attribute on the inner input element. This is useful for mobile devices to enable or disable auto-capitalization of the first character which is typed into the input element.
|
|
454
|
+
- `autocorrect`: Can be `on` or `off` - It will set the auto-correct attribute on the inner input element. This is useful for mobile devices to enable or disable auto-correct.
|
|
455
|
+
|
|
350
456
|
### log-in-form
|
|
351
457
|
|
|
352
458
|
A form component which allows end-users to authenticate themselves into your app using the Saasufy blockchain or any Capitalisk-based blockchain.
|
|
@@ -355,47 +461,221 @@ Once a user is authenticated, they will be able to access restricted data (as sp
|
|
|
355
461
|
It's also possible to specify a `success-location-hash` attribute to trigger a client-side redirect upon successful authentication.
|
|
356
462
|
The change in the location hash can then be detected by an `app-router` to switch to a different page upon successful login.
|
|
357
463
|
|
|
464
|
+
**Example usage**
|
|
465
|
+
|
|
466
|
+
```html
|
|
467
|
+
<log-in-form
|
|
468
|
+
hostname="capitalisk.com"
|
|
469
|
+
port="443"
|
|
470
|
+
network-symbol="clsk"
|
|
471
|
+
chain-module-name="capitalisk_chain"
|
|
472
|
+
secure="true"
|
|
473
|
+
></log-in-form>
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Attributes**
|
|
477
|
+
|
|
478
|
+
- `hostname` (required): The hostname of the blockchain node to match authentication details against.
|
|
479
|
+
- `port` (required): The port of the blockchain node to match authentication details against. Should be 80 for HTTP/WS or 443 for HTTPS/WSS.
|
|
480
|
+
- `network-symbol` (required): The symbol of the target blockchain.
|
|
481
|
+
- `chain-module-name` (required): The module name used by the target blockchain.
|
|
482
|
+
- `secure` (required): Should be `true` or `false` depending on whether or not the node is exposed over HTTP/WS or HTTPS/WSS.
|
|
483
|
+
- `auth-timeout`: The maximum number of milliseconds to wait for authentication to complete. Defaults to 10000 (10 seconds).
|
|
484
|
+
- `success-location-hash`: If authentication is successful, the browser's `location.hash` will be set to this value. It can be used to redirect the user to their dashboard, for example.
|
|
485
|
+
|
|
358
486
|
### log-out
|
|
359
487
|
|
|
360
488
|
A component which can be placed inside a `socket-provider` to deauthenticate the socket (e.g. on click).
|
|
361
489
|
|
|
362
|
-
Example usage
|
|
490
|
+
**Example usage**
|
|
491
|
+
|
|
492
|
+
```html
|
|
493
|
+
<log-out onclick="logOut()"><a href="javascript:void(0)">Log out</a></log-out>
|
|
494
|
+
```
|
|
363
495
|
|
|
364
496
|
### oauth-link
|
|
365
497
|
|
|
366
498
|
A link to initiate an OAuth flow to authenticate a user as part of log in. Can support a range of different OAuth providers.
|
|
367
499
|
|
|
500
|
+
**Example usage**
|
|
501
|
+
|
|
502
|
+
```html
|
|
503
|
+
<oauth-link class="log-in-oauth-section" provider="github" client-id="dabb51f8af31a0bc53bf">
|
|
504
|
+
<template slot="item">
|
|
505
|
+
<a href="https://github.com/login/oauth/authorize?client_id={{oauth.clientId}}&state={{oauth.state}}">
|
|
506
|
+
Log in with GitHub
|
|
507
|
+
</a>
|
|
508
|
+
</template>
|
|
509
|
+
<div slot="viewport"></div>
|
|
510
|
+
</oauth-link>
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Attributes**
|
|
514
|
+
|
|
515
|
+
- `provider` (required): The name of the provider. It must match the provider name specified on the `Authentication` page of your Saasufy control panel and also the value provided to the `oauth-handler` component at the end of the OAuth flow.
|
|
516
|
+
- `client-id` (required): This is the client ID from the third-party OAuth provider.
|
|
517
|
+
- `state-size`: This allows you to control the size (in bytes) of the random state string which is passed to the OAuth provider as part of the OAuth flow. Defaults to 20.
|
|
518
|
+
- `state-session-storage-key`: The state string is stored in the browser's `sessionStorage` under this key. Defaults to `oauth.state`. It must match the value provided to the `oauth-handler` component at the end of the OAuth flow.
|
|
519
|
+
|
|
368
520
|
### oauth-handler
|
|
369
521
|
|
|
370
522
|
This component handles the final stage of OAuth and then redirects the user to the relevant page/URL if successful.
|
|
371
523
|
When using an OAuth provider, the callback URL which you register with the provider must lead the user back to a page which contains this `oauth-handler` component.
|
|
372
524
|
|
|
525
|
+
**Example usage**
|
|
526
|
+
|
|
527
|
+
```html
|
|
528
|
+
<oauth-handler provider="github" success-location-hash="/chat"></oauth-handler>
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Attributes**
|
|
532
|
+
|
|
533
|
+
- `provider` (required): The name of the provider. It must match the provider name specified on the `Authentication` page of your Saasufy control panel and also the value provided to the `oauth-link` component at the start of the OAuth flow.
|
|
534
|
+
- `success-location-hash`: If authentication is successful, the browser's `location.hash` will be set to this value. It can be used to redirect the user to their dashboard, for example.
|
|
535
|
+
- `success-url`: If authentication is successful, the browser's `location.href` will be set to this value. It can be used to redirect the user to their dashboard, for example.
|
|
536
|
+
- `navigate-event-path`: If authentication is successful and a path is set via this attribute, the component will emit a `navigate` event which will bubble up the component hierarchy and can be used by a parent component to perform the success redirection. This approach can be used as an alternative to `success-location-hash` or `success-url` for doing the final redirect.
|
|
537
|
+
- `state-session-storage-key`: The state string is stored in the browser's `sessionStorage` under this key. Defaults to `oauth.state`. It must match the value provided to the `oauth-link` component at the start of the OAuth flow.
|
|
538
|
+
- `code-param-name`: The name of the query parameter which holds the `code` as provided by the OAuth provider within the OAuth callback URL. Defaults to `code`.
|
|
539
|
+
- `state-param-name`: The name of the query parameter which holds the `state` as provided by the OAuth provider within the OAuth callback URL. Defaults to `state`.
|
|
540
|
+
- `auth-timeout`: The number of milliseconds to wait for authentication to complete before timing out. Defaults to 10000 (10 seconds).
|
|
541
|
+
|
|
373
542
|
### render-group
|
|
374
543
|
|
|
375
544
|
A component which can be used to guarantee that certain children components are always rendered at the same time (once they are loaded) to provide a smooth user experience.
|
|
376
545
|
|
|
377
|
-
|
|
546
|
+
**Example usage**
|
|
378
547
|
|
|
379
|
-
|
|
380
|
-
|
|
548
|
+
```html
|
|
549
|
+
<render-group wait-for="1,2,3">
|
|
550
|
+
<model-input
|
|
551
|
+
type="text"
|
|
552
|
+
load-id="1"
|
|
553
|
+
model-type="Product"
|
|
554
|
+
model-id="{{productId}}"
|
|
555
|
+
model-field="name"
|
|
556
|
+
></model-input>
|
|
557
|
+
<model-input
|
|
558
|
+
type="text"
|
|
559
|
+
load-id="2"
|
|
560
|
+
model-type="Product"
|
|
561
|
+
model-id="{{productId}}"
|
|
562
|
+
model-field="desc"
|
|
563
|
+
></model-input>
|
|
564
|
+
<model-input
|
|
565
|
+
type="number"
|
|
566
|
+
load-id="3"
|
|
567
|
+
model-type="Product"
|
|
568
|
+
model-id="{{productId}}"
|
|
569
|
+
model-field="qty"
|
|
570
|
+
></model-input>
|
|
571
|
+
</render-group>
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**Attributes**
|
|
575
|
+
|
|
576
|
+
- `wait-for` (required): A list of components to wait for before rendering based on their `load-id` attributes.
|
|
577
|
+
The `render-group` will only render its content once all the components specified via this attribute have finished loading their data.
|
|
381
578
|
|
|
382
579
|
### if-group
|
|
383
580
|
|
|
384
581
|
A component which exposes a `show-content` property which can be set to true or false to show or hide its content.
|
|
385
|
-
It's intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false value of the `show-content` attribute can be computed using a template `{{expression}}` placeholder.
|
|
582
|
+
It's intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false value of the `show-content` attribute can be computed using a template `{{expression}}` placeholder. This component requires a template and a viewport to be slotted in. The content of the template will not be processed unless the `show-content` condition is met.
|
|
583
|
+
|
|
584
|
+
**Example usage**
|
|
585
|
+
|
|
586
|
+
```html
|
|
587
|
+
|
|
588
|
+
```
|
|
386
589
|
|
|
387
590
|
### switch-group
|
|
388
591
|
|
|
389
592
|
A component which exposes a `show-cases` property which can be set to key-value pairs in the format `key1=true,key2=false`. It can be used to conditionally display multiple slotted elements based on multiple conditions. It helps to keep HTML clean when the conditions are complex.
|
|
390
593
|
This element is intended to be placed inside a `model-viewer`, `collection-browser` or `collection-reducer` component such that the true/false values of the `show-cases` attribute can be computed using template `{{expression}}` placeholders. This component requires one or more templates and a viewport to be slotted in. The content of the templates will not be processed unless the `show-cases` condition is met. All templates must have a `slot="content"` attribute and a name attribute in the format `name="key1"` where the value `key1` corresponds to the key specified inside the `show-cases` attribute of the `switch-group`.
|
|
391
594
|
|
|
595
|
+
**Example usage**
|
|
596
|
+
|
|
597
|
+
```html
|
|
598
|
+
<switch-group show-cases="image={{!!Section.imageURL}},text={{!!Section.text}}">
|
|
599
|
+
<template slot="content" name="image">
|
|
600
|
+
<img src="{{Section.imageURL}}" alt="{{Section.imageDesc}}" />
|
|
601
|
+
</template>
|
|
602
|
+
<template slot="content" name="text">
|
|
603
|
+
<div>{{Section.text}}</div>
|
|
604
|
+
</template>
|
|
605
|
+
<div slot="viewport"></div>
|
|
606
|
+
</switch-group>
|
|
607
|
+
```
|
|
608
|
+
|
|
392
609
|
### collection-adder-group
|
|
393
610
|
|
|
394
611
|
A component which can be used to group together multiple `collection-adder` components. It can be used to insert multiple records into a collection via a single button click.
|
|
395
612
|
|
|
613
|
+
**Example usage**
|
|
614
|
+
|
|
615
|
+
```html
|
|
616
|
+
<!--
|
|
617
|
+
This collection-adder-group adds two pre-defined records into a Product
|
|
618
|
+
collection using a single button click. This example assumes that the name
|
|
619
|
+
field is the only required field in the Product model.
|
|
620
|
+
-->
|
|
621
|
+
<collection-adder-group>
|
|
622
|
+
<collection-adder
|
|
623
|
+
slot="collection-adder"
|
|
624
|
+
collection-type="Product"
|
|
625
|
+
model-values="name=Flour"
|
|
626
|
+
hide-submit-button
|
|
627
|
+
></collection-adder>
|
|
628
|
+
<collection-adder
|
|
629
|
+
slot="collection-adder"
|
|
630
|
+
collection-type="Product"
|
|
631
|
+
model-values="name=Egg"
|
|
632
|
+
hide-submit-button
|
|
633
|
+
></collection-adder>
|
|
634
|
+
<collection-adder
|
|
635
|
+
slot="collection-adder"
|
|
636
|
+
collection-type="Product"
|
|
637
|
+
model-values="name=Milk"
|
|
638
|
+
hide-submit-button
|
|
639
|
+
></collection-adder>
|
|
640
|
+
<div slot="error-container"></div>
|
|
641
|
+
<input slot="submit-button" type="button" value="Add pancake ingredients">
|
|
642
|
+
</collection-adder-group>
|
|
643
|
+
```
|
|
644
|
+
|
|
396
645
|
### confirm-modal
|
|
397
646
|
|
|
398
|
-
A modal component to prompt the user for confirmation before performing sensitive operations.
|
|
647
|
+
A modal component to prompt the user for confirmation before performing sensitive operations. Can be slotted into a `collection-browser` component.
|
|
648
|
+
|
|
649
|
+
**Example usage**
|
|
650
|
+
|
|
651
|
+
```html
|
|
652
|
+
<collection-browser
|
|
653
|
+
collection-type="Product"
|
|
654
|
+
collection-fields="name,qty"
|
|
655
|
+
collection-view="alphabeticalView"
|
|
656
|
+
collection-view-params=""
|
|
657
|
+
collection-page-size="50"
|
|
658
|
+
>
|
|
659
|
+
<template slot="item">
|
|
660
|
+
<div>
|
|
661
|
+
<div class="chat-message">{{Product.name}}</div>
|
|
662
|
+
<collection-deleter model-id="{{Product.id}}" confirm-message="Are you sure you want to delete the {{Product.name}} product?" onclick="confirmDeleteItem()">✕</collection-deleter>
|
|
663
|
+
</div>
|
|
664
|
+
</template>
|
|
665
|
+
|
|
666
|
+
<div slot="viewport" class="chat-viewport"></div>
|
|
667
|
+
|
|
668
|
+
<!-- The confirm-modal element must be specified here with slot="modal" to prompt the user for confirmation -->
|
|
669
|
+
<confirm-modal slot="modal" title="Delete confirmation" message="" confirm-button-label="Delete"></confirm-modal>
|
|
670
|
+
</collection-browser>
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**Attributes**
|
|
674
|
+
|
|
675
|
+
- `title`: The text to show in the modal's title bar.
|
|
676
|
+
- `message`: The text to show as the modal's main content.
|
|
677
|
+
- `confirm-button-label`: The text to use as the confirm button label.
|
|
678
|
+
- `cancel-button-label`: The text to use as the cancel button label.
|
|
399
679
|
|
|
400
680
|
### overlay-modal
|
|
401
681
|
|
package/collection-browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SocketConsumer } from './socket.js';
|
|
2
2
|
import AGCollection from '/node_modules/ag-collection/ag-collection.js';
|
|
3
|
-
import { renderTemplate } from './utils.js';
|
|
3
|
+
import { renderTemplate, convertStringToFieldParams } from './utils.js';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_RELOAD_DELAY = 0;
|
|
6
6
|
|
|
@@ -226,11 +226,8 @@ class CollectionBrowser extends SocketConsumer {
|
|
|
226
226
|
let collectionReloadDelay = Number(
|
|
227
227
|
this.getAttribute('collection-reload-delay') || DEFAULT_RELOAD_DELAY
|
|
228
228
|
);
|
|
229
|
-
let viewParams =
|
|
230
|
-
|
|
231
|
-
.map(pair => pair.split('='))
|
|
232
|
-
.filter(([field]) => field)
|
|
233
|
-
);
|
|
229
|
+
let { fieldValues: viewParams } = convertStringToFieldParams(collectionViewParams);
|
|
230
|
+
|
|
234
231
|
if (this.collection) this.collection.destroy();
|
|
235
232
|
this.isStale = true;
|
|
236
233
|
|
package/collection-reducer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SocketConsumer } from './socket.js';
|
|
2
2
|
import AGCollection from '/node_modules/ag-collection/ag-collection.js';
|
|
3
|
-
import { renderTemplate } from './utils.js';
|
|
3
|
+
import { renderTemplate, convertStringToFieldParams } from './utils.js';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_RELOAD_DELAY = 0;
|
|
6
6
|
|
|
@@ -183,11 +183,8 @@ class CollectionReducer extends SocketConsumer {
|
|
|
183
183
|
let collectionReloadDelay = Number(
|
|
184
184
|
this.getAttribute('collection-reload-delay') || DEFAULT_RELOAD_DELAY
|
|
185
185
|
);
|
|
186
|
-
let viewParams =
|
|
187
|
-
|
|
188
|
-
.map(pair => pair.split('='))
|
|
189
|
-
.filter(([field]) => field)
|
|
190
|
-
);
|
|
186
|
+
let { fieldValues: viewParams } = convertStringToFieldParams(collectionViewParams);
|
|
187
|
+
|
|
191
188
|
if (this.collection) this.collection.destroy();
|
|
192
189
|
this.isStale = true;
|
|
193
190
|
|
package/confirm-modal.js
CHANGED
|
@@ -13,7 +13,7 @@ class ConfirmModal extends HTMLElement {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
static get observedAttributes() {
|
|
16
|
-
return [ 'message', 'title', 'confirm-button-label' ];
|
|
16
|
+
return [ 'message', 'title', 'confirm-button-label', 'cancel-button-label' ];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -32,9 +32,10 @@ class ConfirmModal extends HTMLElement {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
render() {
|
|
35
|
-
let message = this.getAttribute('message');
|
|
35
|
+
let message = this.getAttribute('message') || '';
|
|
36
36
|
let title = this.getAttribute('title') || '';
|
|
37
37
|
let confirmButtonLabel = this.getAttribute('confirm-button-label') || 'Confirm';
|
|
38
|
+
let cancelButtonLabel = this.getAttribute('cancel-button-label') || 'Cancel';
|
|
38
39
|
|
|
39
40
|
this.innerHTML = `
|
|
40
41
|
<overlay-modal class="${this.hidden ? 'hidden' : 'visible'}">
|
|
@@ -43,7 +44,7 @@ class ConfirmModal extends HTMLElement {
|
|
|
43
44
|
<div>${message}</div>
|
|
44
45
|
<div class="confirm-modal-buttons-container">
|
|
45
46
|
<input class="modal-confirm-button" type="button" value="${confirmButtonLabel}" />
|
|
46
|
-
<input class="modal-cancel-button" type="button" value="
|
|
47
|
+
<input class="modal-cancel-button" type="button" value="${cancelButtonLabel}" />
|
|
47
48
|
</div>
|
|
48
49
|
</div>
|
|
49
50
|
</overlay-modal>
|