@vaadin/crud 24.0.0-alpha1 → 24.0.0-alpha11
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/LICENSE +1105 -248
- package/README.md +1 -1
- package/package.json +12 -12
- package/src/vaadin-crud-dialog.js +9 -3
- package/src/vaadin-crud-edit-column.d.ts +7 -2
- package/src/vaadin-crud-edit-column.js +8 -3
- package/src/vaadin-crud-edit.d.ts +7 -2
- package/src/vaadin-crud-edit.js +7 -2
- package/src/vaadin-crud-form.d.ts +7 -2
- package/src/vaadin-crud-form.js +9 -26
- package/src/vaadin-crud-grid.d.ts +7 -2
- package/src/vaadin-crud-grid.js +20 -36
- package/src/vaadin-crud-helpers.d.ts +29 -0
- package/src/vaadin-crud-helpers.js +64 -0
- package/src/vaadin-crud-include-mixin.d.ts +7 -2
- package/src/vaadin-crud-include-mixin.js +13 -5
- package/src/vaadin-crud.d.ts +50 -26
- package/src/vaadin-crud.js +203 -176
- package/theme/material/vaadin-crud-styles.js +0 -7
- package/vaadin-crud-edit-column.d.ts +1 -0
- package/vaadin-crud-edit-column.js +1 -0
- package/vaadin-crud-edit.d.ts +1 -0
- package/vaadin-crud-edit.js +1 -0
- package/web-types.json +6 -6
- package/web-types.lit.json +4 -4
package/src/vaadin-crud.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c)
|
|
4
|
-
*
|
|
3
|
+
* Copyright (c) 2000 - 2023 Vaadin Ltd.
|
|
4
|
+
*
|
|
5
|
+
* This program is available under Vaadin Commercial License and Service Terms.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* See https://vaadin.com/commercial-license-and-service-terms for the full
|
|
9
|
+
* license.
|
|
5
10
|
*/
|
|
6
11
|
import '@vaadin/button/src/vaadin-button.js';
|
|
7
12
|
import '@vaadin/dialog/src/vaadin-dialog.js';
|
|
@@ -15,8 +20,23 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
|
15
20
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
16
21
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
17
22
|
import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
|
|
18
|
-
import {
|
|
23
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
19
24
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
25
|
+
import { getProperty, setProperty } from './vaadin-crud-helpers.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @private
|
|
29
|
+
* A to initialize slotted button.
|
|
30
|
+
*/
|
|
31
|
+
class ButtonSlotController extends SlotController {
|
|
32
|
+
constructor(host, type, theme) {
|
|
33
|
+
super(host, `${type}-button`, 'vaadin-button', {
|
|
34
|
+
initializer: (button) => {
|
|
35
|
+
button.setAttribute('theme', theme);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
20
40
|
|
|
21
41
|
/**
|
|
22
42
|
* `<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.
|
|
@@ -27,23 +47,34 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
27
47
|
*
|
|
28
48
|
* A grid and an editor will be automatically generated and configured based on the data structure provided.
|
|
29
49
|
*
|
|
30
|
-
* #### Example:
|
|
31
50
|
* ```html
|
|
32
|
-
* <vaadin-crud
|
|
33
|
-
*
|
|
51
|
+
* <vaadin-crud></vaadin-crud>
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* ```js
|
|
55
|
+
* const crud = document.querySelector('vaadin-crud');
|
|
56
|
+
*
|
|
57
|
+
* crud.items = [
|
|
58
|
+
* { name: 'John', surname: 'Lennon', role: 'singer' },
|
|
59
|
+
* { name: 'Ringo', surname: 'Starr', role: 'drums' },
|
|
60
|
+
* // ... more items
|
|
61
|
+
* ];
|
|
34
62
|
* ```
|
|
35
63
|
*
|
|
36
64
|
* ### Data Provider Function
|
|
37
65
|
*
|
|
38
66
|
* Otherwise, you can provide a [`dataProvider`](#/elements/vaadin-crud#property-dataProvider) function.
|
|
39
|
-
*
|
|
40
|
-
* ```html
|
|
41
|
-
* <vaadin-crud></vaadin-crud>
|
|
42
|
-
* ```
|
|
67
|
+
*
|
|
43
68
|
* ```js
|
|
44
69
|
* const crud = document.querySelector('vaadin-crud');
|
|
45
|
-
*
|
|
46
|
-
*
|
|
70
|
+
*
|
|
71
|
+
* const users = [
|
|
72
|
+
* { name: 'John', surname: 'Lennon', role: 'singer' },
|
|
73
|
+
* { name: 'Ringo', surname: 'Starr', role: 'drums' },
|
|
74
|
+
* // ... more items
|
|
75
|
+
* ];
|
|
76
|
+
*
|
|
77
|
+
* crud.dataProvider = (params, callback) => {
|
|
47
78
|
* const chunk = users.slice(params.page * params.pageSize, params.page * params.pageSize + params.pageSize);
|
|
48
79
|
* callback(chunk, people.length);
|
|
49
80
|
* };
|
|
@@ -56,20 +87,20 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
56
87
|
*
|
|
57
88
|
* Alternatively you can fully configure the component by using `slot` names.
|
|
58
89
|
*
|
|
59
|
-
* Slot name
|
|
60
|
-
*
|
|
61
|
-
* `grid`
|
|
62
|
-
* `form`
|
|
63
|
-
* `
|
|
90
|
+
* Slot name | Description
|
|
91
|
+
* ---------------|----------------
|
|
92
|
+
* `grid` | To replace the auto-generated grid with a custom one.
|
|
93
|
+
* `form` | To replace the auto-generated form.
|
|
94
|
+
* `save-button` | To replace the "Save" button.
|
|
95
|
+
* `cancel-button`| To replace the "Cancel" button.
|
|
96
|
+
* `delete-button`| To replace the "Delete" button.
|
|
97
|
+
* `toolbar` | To provide the toolbar content (by default, it's empty).
|
|
98
|
+
* `new-button` | To replace the "New item" button.
|
|
64
99
|
*
|
|
65
100
|
* #### Example:
|
|
66
101
|
*
|
|
67
102
|
* ```html
|
|
68
|
-
* <vaadin-crud
|
|
69
|
-
* id="crud"
|
|
70
|
-
* items='[{"name": "John", "surname": "Lennon", "role": "singer"},
|
|
71
|
-
* {"name": "Ringo", "surname": "Starr", "role": "drums"}]'
|
|
72
|
-
* >
|
|
103
|
+
* <vaadin-crud id="crud">
|
|
73
104
|
* <vaadin-grid slot="grid">
|
|
74
105
|
* <vaadin-crud-edit-column></vaadin-crud-edit-column>
|
|
75
106
|
* <vaadin-grid-column id="column1"></vaadin-grid-column>
|
|
@@ -81,10 +112,12 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
81
112
|
* <vaadin-text-field label="Surname" path="surname"></vaadin-text-field>
|
|
82
113
|
* </vaadin-form-layout>
|
|
83
114
|
*
|
|
84
|
-
* <div slot="toolbar">
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* </
|
|
115
|
+
* <div slot="toolbar">Total singers: 2</div>
|
|
116
|
+
* <button slot="new-button">New singer</button>
|
|
117
|
+
*
|
|
118
|
+
* <button slot="save-button">Save changes</button>
|
|
119
|
+
* <button slot="cancel-button">Discard changes</button>
|
|
120
|
+
* <button slot="delete-button">Delete singer</button>
|
|
88
121
|
* </vaadin-crud>
|
|
89
122
|
* ```
|
|
90
123
|
* ```js
|
|
@@ -105,6 +138,12 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
105
138
|
* column2.renderer = (root, column, model) => {
|
|
106
139
|
* root.textContent = model.item.surname;
|
|
107
140
|
* };
|
|
141
|
+
*
|
|
142
|
+
* crud.items = [
|
|
143
|
+
* { name: 'John', surname: 'Lennon', role: 'singer' },
|
|
144
|
+
* { name: 'Ringo', surname: 'Starr', role: 'drums' },
|
|
145
|
+
* // ... more items
|
|
146
|
+
* ];
|
|
108
147
|
* ```
|
|
109
148
|
*
|
|
110
149
|
* ### Helpers
|
|
@@ -144,10 +183,9 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
144
183
|
* @extends HTMLElement
|
|
145
184
|
* @mixes ControllerMixin
|
|
146
185
|
* @mixes ElementMixin
|
|
147
|
-
* @mixes SlotMixin
|
|
148
186
|
* @mixes ThemableMixin
|
|
149
187
|
*/
|
|
150
|
-
class Crud extends
|
|
188
|
+
class Crud extends ControllerMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
151
189
|
static get template() {
|
|
152
190
|
return html`
|
|
153
191
|
<style>
|
|
@@ -233,23 +271,11 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
233
271
|
|
|
234
272
|
<div id="container">
|
|
235
273
|
<div id="main">
|
|
236
|
-
<slot name="grid">
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
exclude="[[exclude]]"
|
|
242
|
-
no-sort="[[noSort]]"
|
|
243
|
-
no-filter="[[noFilter]]"
|
|
244
|
-
no-head="[[noHead]]"
|
|
245
|
-
hide-edit-column="[[editOnClick]]"
|
|
246
|
-
></vaadin-crud-grid>
|
|
247
|
-
</slot>
|
|
248
|
-
|
|
249
|
-
<div id="toolbar" part="toolbar" on-click="__new">
|
|
250
|
-
<slot name="toolbar">
|
|
251
|
-
<vaadin-button new-button="" id="new" theme="primary">[[i18n.newItem]]</vaadin-button>
|
|
252
|
-
</slot>
|
|
274
|
+
<slot name="grid"></slot>
|
|
275
|
+
|
|
276
|
+
<div id="toolbar" part="toolbar">
|
|
277
|
+
<slot name="toolbar"></slot>
|
|
278
|
+
<slot name="new-button"></slot>
|
|
253
279
|
</div>
|
|
254
280
|
</div>
|
|
255
281
|
|
|
@@ -283,7 +309,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
283
309
|
theme$="[[_theme]]"
|
|
284
310
|
id="confirmCancel"
|
|
285
311
|
on-confirm="__confirmCancel"
|
|
286
|
-
cancel
|
|
312
|
+
cancel-button-visible
|
|
287
313
|
confirm-text="[[i18n.confirm.cancel.button.confirm]]"
|
|
288
314
|
cancel-text="[[i18n.confirm.cancel.button.dismiss]]"
|
|
289
315
|
header="[[i18n.confirm.cancel.title]]"
|
|
@@ -295,7 +321,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
295
321
|
theme$="[[_theme]]"
|
|
296
322
|
id="confirmDelete"
|
|
297
323
|
on-confirm="__confirmDelete"
|
|
298
|
-
cancel
|
|
324
|
+
cancel-button-visible
|
|
299
325
|
confirm-text="[[i18n.confirm.delete.button.confirm]]"
|
|
300
326
|
cancel-text="[[i18n.confirm.delete.button.dismiss]]"
|
|
301
327
|
header="[[i18n.confirm.delete.title]]"
|
|
@@ -320,7 +346,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
320
346
|
* @private
|
|
321
347
|
*/
|
|
322
348
|
_grid: {
|
|
323
|
-
type:
|
|
349
|
+
type: Object,
|
|
324
350
|
observer: '__gridChanged',
|
|
325
351
|
},
|
|
326
352
|
|
|
@@ -329,7 +355,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
329
355
|
* @private
|
|
330
356
|
*/
|
|
331
357
|
_form: {
|
|
332
|
-
type:
|
|
358
|
+
type: Object,
|
|
333
359
|
observer: '__formChanged',
|
|
334
360
|
},
|
|
335
361
|
|
|
@@ -338,34 +364,39 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
338
364
|
* @private
|
|
339
365
|
*/
|
|
340
366
|
_saveButton: {
|
|
341
|
-
type:
|
|
342
|
-
observer: '__saveButtonChanged',
|
|
367
|
+
type: Object,
|
|
343
368
|
},
|
|
344
369
|
|
|
345
370
|
/**
|
|
346
|
-
* A reference to the
|
|
371
|
+
* A reference to the delete button which will be teleported to the dialog
|
|
347
372
|
* @private
|
|
348
373
|
*/
|
|
349
374
|
_deleteButton: {
|
|
350
|
-
type:
|
|
351
|
-
observer: '__deleteButtonChanged',
|
|
375
|
+
type: Object,
|
|
352
376
|
},
|
|
353
377
|
|
|
354
378
|
/**
|
|
355
|
-
* A reference to the
|
|
379
|
+
* A reference to the cancel button which will be teleported to the dialog
|
|
356
380
|
* @private
|
|
357
381
|
*/
|
|
358
382
|
_cancelButton: {
|
|
359
|
-
type:
|
|
360
|
-
observer: '__cancelButtonChanged',
|
|
383
|
+
type: Object,
|
|
361
384
|
},
|
|
362
385
|
|
|
363
386
|
/**
|
|
364
|
-
* A reference to the editor header element
|
|
387
|
+
* A reference to the default editor header element created by the CRUD
|
|
365
388
|
* @private
|
|
366
389
|
*/
|
|
367
|
-
|
|
368
|
-
type:
|
|
390
|
+
_defaultHeader: {
|
|
391
|
+
type: Object,
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* A reference to the "New item" button
|
|
396
|
+
* @private
|
|
397
|
+
*/
|
|
398
|
+
_newButton: {
|
|
399
|
+
type: Object,
|
|
369
400
|
},
|
|
370
401
|
|
|
371
402
|
/**
|
|
@@ -604,13 +635,15 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
604
635
|
|
|
605
636
|
static get observers() {
|
|
606
637
|
return [
|
|
607
|
-
'__headerPropsChanged(
|
|
638
|
+
'__headerPropsChanged(_defaultHeader, __isNew, i18n.newItem, i18n.editItem)',
|
|
608
639
|
'__formPropsChanged(_form, _theme, include, exclude)',
|
|
640
|
+
'__gridPropsChanged(_grid, _theme, include, exclude, noFilter, noHead, noSort)',
|
|
609
641
|
'__i18nChanged(i18n, _grid)',
|
|
610
642
|
'__editOnClickChanged(editOnClick, _grid)',
|
|
611
643
|
'__saveButtonPropsChanged(_saveButton, i18n.saveItem, __isDirty)',
|
|
612
644
|
'__cancelButtonPropsChanged(_cancelButton, i18n.cancel)',
|
|
613
645
|
'__deleteButtonPropsChanged(_deleteButton, i18n.deleteItem, __isNew)',
|
|
646
|
+
'__newButtonPropsChanged(_newButton, i18n.newItem)',
|
|
614
647
|
];
|
|
615
648
|
}
|
|
616
649
|
|
|
@@ -619,59 +652,66 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
619
652
|
return ['bottom', 'aside'].includes(editorPosition);
|
|
620
653
|
}
|
|
621
654
|
|
|
622
|
-
/** @protected */
|
|
623
|
-
get slots() {
|
|
624
|
-
// NOTE: order in which the toolbar buttons are listed matters.
|
|
625
|
-
return {
|
|
626
|
-
...super.slots,
|
|
627
|
-
header: () => {
|
|
628
|
-
return document.createElement('h3');
|
|
629
|
-
},
|
|
630
|
-
form: () => {
|
|
631
|
-
return document.createElement('vaadin-crud-form');
|
|
632
|
-
},
|
|
633
|
-
'save-button': () => {
|
|
634
|
-
const button = document.createElement('vaadin-button');
|
|
635
|
-
button.id = 'save';
|
|
636
|
-
button.setAttribute('theme', 'primary');
|
|
637
|
-
return button;
|
|
638
|
-
},
|
|
639
|
-
'cancel-button': () => {
|
|
640
|
-
const button = document.createElement('vaadin-button');
|
|
641
|
-
button.id = 'cancel';
|
|
642
|
-
button.setAttribute('theme', 'tertiary');
|
|
643
|
-
return button;
|
|
644
|
-
},
|
|
645
|
-
'delete-button': () => {
|
|
646
|
-
const button = document.createElement('vaadin-button');
|
|
647
|
-
button.id = 'delete';
|
|
648
|
-
button.setAttribute('theme', 'tertiary error');
|
|
649
|
-
return button;
|
|
650
|
-
},
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
|
|
654
655
|
constructor() {
|
|
655
656
|
super();
|
|
657
|
+
|
|
658
|
+
this.__cancel = this.__cancel.bind(this);
|
|
659
|
+
this.__delete = this.__delete.bind(this);
|
|
660
|
+
this.__save = this.__save.bind(this);
|
|
661
|
+
this.__new = this.__new.bind(this);
|
|
662
|
+
this.__onFormChange = this.__onFormChange.bind(this);
|
|
663
|
+
this.__onGridEdit = this.__onGridEdit.bind(this);
|
|
664
|
+
this.__onGridSizeChanged = this.__onGridSizeChanged.bind(this);
|
|
665
|
+
this.__onGridActiveItemChanged = this.__onGridActiveItemChanged.bind(this);
|
|
666
|
+
|
|
656
667
|
this._observer = new FlattenedNodesObserver(this, (info) => {
|
|
657
668
|
this.__onDomChange(info.addedNodes);
|
|
658
669
|
});
|
|
659
670
|
}
|
|
660
671
|
|
|
672
|
+
/** @protected */
|
|
673
|
+
get _headerNode() {
|
|
674
|
+
return this._headerController && this._headerController.node;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* A reference to all fields inside the [`_form`](#/elements/vaadin-crud#property-_form) element
|
|
679
|
+
* @return {!Array<!HTMLElement>}
|
|
680
|
+
* @protected
|
|
681
|
+
*/
|
|
682
|
+
get _fields() {
|
|
683
|
+
if (!this.__fields || !this.__fields.length) {
|
|
684
|
+
this.__fields = Array.from(this._form.querySelectorAll('*')).filter((e) => e.validate || e.checkValidity);
|
|
685
|
+
}
|
|
686
|
+
return this.__fields;
|
|
687
|
+
}
|
|
688
|
+
|
|
661
689
|
/** @protected */
|
|
662
690
|
ready() {
|
|
663
691
|
super.ready();
|
|
664
|
-
|
|
665
|
-
this.__cancel = this.__cancel.bind(this);
|
|
666
|
-
this.__delete = this.__delete.bind(this);
|
|
667
|
-
this.__onFormChange = this.__onFormChange.bind(this);
|
|
668
|
-
this.__onGridEdit = this.__onGridEdit.bind(this);
|
|
669
|
-
this.__onGridSizeChanged = this.__onGridSizeChanged.bind(this);
|
|
670
|
-
this.__onGridActiveItemChanged = this.__onGridActiveItemChanged.bind(this);
|
|
671
|
-
this._grid = this.$.grid;
|
|
692
|
+
|
|
672
693
|
this.$.dialog.$.overlay.addEventListener('vaadin-overlay-outside-click', this.__cancel);
|
|
673
694
|
this.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this.__cancel);
|
|
674
695
|
|
|
696
|
+
this._headerController = new SlotController(this, 'header', 'h3', {
|
|
697
|
+
initializer: (node) => {
|
|
698
|
+
this._defaultHeader = node;
|
|
699
|
+
},
|
|
700
|
+
});
|
|
701
|
+
this.addController(this._headerController);
|
|
702
|
+
|
|
703
|
+
this._gridController = new SlotController(this, 'grid', 'vaadin-crud-grid');
|
|
704
|
+
this.addController(this._gridController);
|
|
705
|
+
|
|
706
|
+
this.addController(new SlotController(this, 'form', 'vaadin-crud-form'));
|
|
707
|
+
|
|
708
|
+
this.addController(new ButtonSlotController(this, 'new', 'primary'));
|
|
709
|
+
|
|
710
|
+
// NOTE: order in which buttons are added should match the order of slots in template
|
|
711
|
+
this.addController(new ButtonSlotController(this, 'save', 'primary'));
|
|
712
|
+
this.addController(new ButtonSlotController(this, 'cancel', 'tertiary'));
|
|
713
|
+
this.addController(new ButtonSlotController(this, 'delete', 'tertiary error'));
|
|
714
|
+
|
|
675
715
|
this.addController(
|
|
676
716
|
new MediaQueryController(this._fullscreenMediaQuery, (matches) => {
|
|
677
717
|
this._fullscreen = matches;
|
|
@@ -824,7 +864,8 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
824
864
|
/** @private */
|
|
825
865
|
__onDomChange(addedNodes) {
|
|
826
866
|
// TODO: restore default button when a corresponding slotted button is removed.
|
|
827
|
-
//
|
|
867
|
+
// This would require us to detect where to insert a button after teleporting it,
|
|
868
|
+
// which happens after opening a dialog and closing it (default editor position).
|
|
828
869
|
addedNodes
|
|
829
870
|
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
830
871
|
.forEach((node) => {
|
|
@@ -842,9 +883,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
842
883
|
this._form = node;
|
|
843
884
|
} else if (slotAttributeValue.indexOf('button') >= 0) {
|
|
844
885
|
const [button] = slotAttributeValue.split('-');
|
|
845
|
-
this
|
|
846
|
-
} else if (slotAttributeValue === 'header') {
|
|
847
|
-
this._headerNode = node;
|
|
886
|
+
this.__setupSlottedButton(button, node);
|
|
848
887
|
}
|
|
849
888
|
});
|
|
850
889
|
|
|
@@ -928,17 +967,37 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
928
967
|
if (form) {
|
|
929
968
|
form.include = include;
|
|
930
969
|
form.exclude = exclude;
|
|
931
|
-
|
|
970
|
+
|
|
971
|
+
if (theme) {
|
|
972
|
+
form.setAttribute('theme', theme);
|
|
973
|
+
} else {
|
|
974
|
+
form.removeAttribute('theme');
|
|
975
|
+
}
|
|
932
976
|
}
|
|
933
977
|
}
|
|
934
978
|
|
|
935
979
|
/**
|
|
936
|
-
* @param {HTMLElement}
|
|
937
|
-
* @param {
|
|
980
|
+
* @param {HTMLElement | undefined} form
|
|
981
|
+
* @param {string} theme
|
|
982
|
+
* @param {string | string[] | undefined} include
|
|
983
|
+
* @param {string | RegExp} exclude
|
|
938
984
|
* @private
|
|
939
985
|
*/
|
|
940
|
-
|
|
941
|
-
|
|
986
|
+
// eslint-disable-next-line max-params
|
|
987
|
+
__gridPropsChanged(grid, theme, include, exclude, noFilter, noHead, noSort) {
|
|
988
|
+
if (grid && grid === this._gridController.defaultNode) {
|
|
989
|
+
grid.include = include;
|
|
990
|
+
grid.exclude = exclude;
|
|
991
|
+
grid.noFilter = noFilter;
|
|
992
|
+
grid.noHead = noHead;
|
|
993
|
+
grid.noSort = noSort;
|
|
994
|
+
|
|
995
|
+
if (theme) {
|
|
996
|
+
grid.setAttribute('theme', theme);
|
|
997
|
+
} else {
|
|
998
|
+
grid.removeAttribute('theme');
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
942
1001
|
}
|
|
943
1002
|
|
|
944
1003
|
/**
|
|
@@ -954,15 +1013,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
954
1013
|
}
|
|
955
1014
|
}
|
|
956
1015
|
|
|
957
|
-
/**
|
|
958
|
-
* @param {HTMLElement} deleteButton
|
|
959
|
-
* @param {HTMLElement | undefined} oldDeleteButton
|
|
960
|
-
* @private
|
|
961
|
-
*/
|
|
962
|
-
__deleteButtonChanged(deleteButton, oldDeleteButton) {
|
|
963
|
-
this.__setupSlottedButton(deleteButton, oldDeleteButton, this.__delete);
|
|
964
|
-
}
|
|
965
|
-
|
|
966
1016
|
/**
|
|
967
1017
|
* @param {HTMLElement | undefined} deleteButton
|
|
968
1018
|
* @param {string} i18nLabel
|
|
@@ -976,15 +1026,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
976
1026
|
}
|
|
977
1027
|
}
|
|
978
1028
|
|
|
979
|
-
/**
|
|
980
|
-
* @param {HTMLElement} cancelButton
|
|
981
|
-
* @param {HTMLElement | undefined} oldCancelButton
|
|
982
|
-
* @private
|
|
983
|
-
*/
|
|
984
|
-
__cancelButtonChanged(cancelButton, oldCancelButton) {
|
|
985
|
-
this.__setupSlottedButton(cancelButton, oldCancelButton, this.__cancel);
|
|
986
|
-
}
|
|
987
|
-
|
|
988
1029
|
/**
|
|
989
1030
|
* @param {HTMLElement | undefined} saveButton
|
|
990
1031
|
* @param {string} i18nLabel
|
|
@@ -997,17 +1038,31 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
997
1038
|
}
|
|
998
1039
|
|
|
999
1040
|
/**
|
|
1041
|
+
* @param {HTMLElement | undefined} newButton
|
|
1042
|
+
* @param {string} i18nNewItem
|
|
1043
|
+
* @private
|
|
1044
|
+
*/
|
|
1045
|
+
__newButtonPropsChanged(newButton, i18nNewItem) {
|
|
1046
|
+
if (newButton) {
|
|
1047
|
+
newButton.textContent = i18nNewItem;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* @param {string} type
|
|
1000
1053
|
* @param {HTMLElement} newButton
|
|
1001
|
-
* @param {HTMLElement | undefined | null} oldButton
|
|
1002
|
-
* @param {Function} clickListener
|
|
1003
1054
|
* @private
|
|
1004
1055
|
*/
|
|
1005
|
-
__setupSlottedButton(
|
|
1006
|
-
|
|
1007
|
-
|
|
1056
|
+
__setupSlottedButton(type, button) {
|
|
1057
|
+
const property = `_${type}Button`;
|
|
1058
|
+
const listener = `__${type}`;
|
|
1059
|
+
|
|
1060
|
+
if (this[property] && this[property] !== button) {
|
|
1061
|
+
this[property].remove();
|
|
1008
1062
|
}
|
|
1009
1063
|
|
|
1010
|
-
|
|
1064
|
+
button.addEventListener('click', this[listener]);
|
|
1065
|
+
this[property] = button;
|
|
1011
1066
|
}
|
|
1012
1067
|
|
|
1013
1068
|
/** @private */
|
|
@@ -1018,15 +1073,17 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1018
1073
|
}
|
|
1019
1074
|
|
|
1020
1075
|
/** @private */
|
|
1021
|
-
__editOnClickChanged(editOnClick,
|
|
1022
|
-
if (!
|
|
1076
|
+
__editOnClickChanged(editOnClick, grid) {
|
|
1077
|
+
if (!grid) {
|
|
1023
1078
|
return;
|
|
1024
1079
|
}
|
|
1025
1080
|
|
|
1081
|
+
grid.hideEditColumn = editOnClick;
|
|
1082
|
+
|
|
1026
1083
|
if (editOnClick) {
|
|
1027
|
-
|
|
1084
|
+
grid.addEventListener('active-item-changed', this.__onGridActiveItemChanged);
|
|
1028
1085
|
} else {
|
|
1029
|
-
|
|
1086
|
+
grid.removeEventListener('active-item-changed', this.__onGridActiveItemChanged);
|
|
1030
1087
|
}
|
|
1031
1088
|
}
|
|
1032
1089
|
|
|
@@ -1127,7 +1184,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1127
1184
|
this._fields.forEach((e) => {
|
|
1128
1185
|
const path = e.path || e.getAttribute('path');
|
|
1129
1186
|
if (path) {
|
|
1130
|
-
e.value =
|
|
1187
|
+
e.value = getProperty(path, item);
|
|
1131
1188
|
}
|
|
1132
1189
|
});
|
|
1133
1190
|
|
|
@@ -1136,18 +1193,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1136
1193
|
}
|
|
1137
1194
|
}
|
|
1138
1195
|
|
|
1139
|
-
/**
|
|
1140
|
-
* A reference to all fields inside the [`_form`](#/elements/vaadin-crud#property-_form) element
|
|
1141
|
-
* @return {!Array<!HTMLElement>}
|
|
1142
|
-
* @protected
|
|
1143
|
-
*/
|
|
1144
|
-
get _fields() {
|
|
1145
|
-
if (!this.__fields || !this.__fields.length) {
|
|
1146
|
-
this.__fields = Array.from(this._form.querySelectorAll('*')).filter((e) => e.validate || e.checkValidity);
|
|
1147
|
-
}
|
|
1148
|
-
return this.__fields;
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
1196
|
/** @private */
|
|
1152
1197
|
__validate() {
|
|
1153
1198
|
return this._fields.every((e) => (e.validate || e.checkValidity).call(e));
|
|
@@ -1155,7 +1200,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1155
1200
|
|
|
1156
1201
|
/** @private */
|
|
1157
1202
|
__setHighlightedItem(item) {
|
|
1158
|
-
if (this._grid === this
|
|
1203
|
+
if (this._grid === this._gridController.defaultNode) {
|
|
1159
1204
|
this._grid.selectedItems = item ? [item] : [];
|
|
1160
1205
|
}
|
|
1161
1206
|
}
|
|
@@ -1171,11 +1216,8 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1171
1216
|
}
|
|
1172
1217
|
|
|
1173
1218
|
/** @private */
|
|
1174
|
-
__new(
|
|
1175
|
-
|
|
1176
|
-
if (event.composedPath().some((e) => e.nodeType === 1 && e.hasAttribute('new-button'))) {
|
|
1177
|
-
this.__confirmBeforeChangingEditedItem(null, true);
|
|
1178
|
-
}
|
|
1219
|
+
__new() {
|
|
1220
|
+
this.__confirmBeforeChangingEditedItem(null, true);
|
|
1179
1221
|
}
|
|
1180
1222
|
|
|
1181
1223
|
/** @private */
|
|
@@ -1211,7 +1253,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1211
1253
|
this._fields.forEach((e) => {
|
|
1212
1254
|
const path = e.path || e.getAttribute('path');
|
|
1213
1255
|
if (path) {
|
|
1214
|
-
|
|
1256
|
+
setProperty(path, e.value, item);
|
|
1215
1257
|
}
|
|
1216
1258
|
});
|
|
1217
1259
|
const evt = this.dispatchEvent(new CustomEvent('save', { detail: { item }, cancelable: true }));
|
|
@@ -1223,7 +1265,9 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1223
1265
|
this.items.push(item);
|
|
1224
1266
|
}
|
|
1225
1267
|
} else {
|
|
1226
|
-
|
|
1268
|
+
if (!this.editedItem) {
|
|
1269
|
+
this.editedItem = {};
|
|
1270
|
+
}
|
|
1227
1271
|
Object.assign(this.editedItem, item);
|
|
1228
1272
|
}
|
|
1229
1273
|
this._grid.clearCache();
|
|
@@ -1265,23 +1309,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
|
|
|
1265
1309
|
}
|
|
1266
1310
|
}
|
|
1267
1311
|
|
|
1268
|
-
/**
|
|
1269
|
-
* Utility method for setting nested values in JSON objects but initializing empty keys unless `Polymer.Base.set`
|
|
1270
|
-
* @private
|
|
1271
|
-
*/
|
|
1272
|
-
__set(path, val, obj) {
|
|
1273
|
-
if (obj && path) {
|
|
1274
|
-
path
|
|
1275
|
-
.split('.')
|
|
1276
|
-
.slice(0, -1)
|
|
1277
|
-
.reduce((o, p) => {
|
|
1278
|
-
o[p] = o[p] || {};
|
|
1279
|
-
return o[p];
|
|
1280
|
-
}, obj);
|
|
1281
|
-
this.set(path, val, obj);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
1312
|
/**
|
|
1286
1313
|
* Fired when user wants to edit an existing item. If the default is prevented, then
|
|
1287
1314
|
* a new item is not assigned to the form, giving that responsibility to the app, though
|
|
@@ -97,13 +97,6 @@ registerStyles(
|
|
|
97
97
|
:host([dir='rtl']) [part='toolbar'] ::slotted(*:not(:first-child)) {
|
|
98
98
|
margin-right: 0.5em;
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
vaadin-text-field[theme~='small'] {
|
|
102
|
-
height: 24px;
|
|
103
|
-
font-size: var(--material-small-font-size);
|
|
104
|
-
margin: 0;
|
|
105
|
-
padding: 0;
|
|
106
|
-
}
|
|
107
100
|
`,
|
|
108
101
|
],
|
|
109
102
|
{ moduleId: 'material-crud' },
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/vaadin-crud-edit-column.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/vaadin-crud-edit-column.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/vaadin-crud-edit.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/vaadin-crud-edit.js';
|