@sankhyalabs/sankhyablocks 8.16.0-dev.102 → 8.16.0-dev.105

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.
Files changed (90) hide show
  1. package/dist/cjs/{SnkMessageBuilder-bae64d0d.js → SnkMessageBuilder-aecd7c18.js} +31 -24
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/sankhyablocks.cjs.js +1 -1
  4. package/dist/cjs/snk-actions-button_7.cjs.entry.js +2 -2
  5. package/dist/cjs/snk-application.cjs.entry.js +1 -1
  6. package/dist/cjs/snk-attach.cjs.entry.js +1 -1
  7. package/dist/cjs/snk-crud.cjs.entry.js +18 -10
  8. package/dist/cjs/snk-data-exporter.cjs.entry.js +2 -2
  9. package/dist/cjs/{snk-data-unit-4b510d6e.js → snk-data-unit-9a463a4f.js} +225 -11
  10. package/dist/cjs/snk-data-unit.cjs.entry.js +2 -2
  11. package/dist/cjs/snk-detail-view.cjs.entry.js +3 -3
  12. package/dist/cjs/snk-grid.cjs.entry.js +21 -7
  13. package/dist/cjs/{snk-guides-viewer-e8e5f7b4.js → snk-guides-viewer-c9e1e97b.js} +98 -43
  14. package/dist/cjs/snk-guides-viewer.cjs.entry.js +2 -2
  15. package/dist/cjs/snk-simple-crud.cjs.entry.js +65 -22
  16. package/dist/cjs/snk-taskbar.cjs.entry.js +2 -1
  17. package/dist/cjs/{taskbar-elements-7e19882d.js → taskbar-elements-02379452.js} +3 -0
  18. package/dist/collection/components/snk-crud/snk-crud.js +35 -9
  19. package/dist/collection/components/snk-crud/subcomponents/snk-guides-viewer.js +117 -43
  20. package/dist/collection/components/snk-data-unit/MultipleUpdateHelper.js +128 -0
  21. package/dist/collection/components/snk-data-unit/snk-data-unit.js +107 -12
  22. package/dist/collection/components/snk-grid/snk-grid.js +38 -6
  23. package/dist/collection/components/snk-simple-crud/snk-simple-crud.js +83 -22
  24. package/dist/collection/components/snk-taskbar/elements/taskbar-actions-button/taskbar-actions-button.css +13 -0
  25. package/dist/collection/components/snk-taskbar/elements/taskbar-actions-button/taskbar-actions-button.js +1 -1
  26. package/dist/collection/components/snk-taskbar/elements/taskbar-elements.js +3 -0
  27. package/dist/collection/components/snk-taskbar/snk-taskbar.js +2 -2
  28. package/dist/collection/lib/message/SnkMessageBuilder.js +1 -0
  29. package/dist/collection/lib/message/resources/snk-data-unit.msg.js +28 -23
  30. package/dist/collection/lib/message/resources/snk-taskbar.msg.js +1 -0
  31. package/dist/components/SnkMessageBuilder.js +31 -24
  32. package/dist/components/snk-crud.js +18 -9
  33. package/dist/components/snk-data-unit2.js +225 -11
  34. package/dist/components/snk-detail-view2.js +98 -43
  35. package/dist/components/snk-grid2.js +21 -6
  36. package/dist/components/snk-simple-crud2.js +66 -22
  37. package/dist/components/snk-taskbar2.js +4 -0
  38. package/dist/components/taskbar-actions-button2.js +2 -2
  39. package/dist/esm/{SnkMessageBuilder-6fff4a4c.js → SnkMessageBuilder-12f5fe1a.js} +31 -24
  40. package/dist/esm/loader.js +1 -1
  41. package/dist/esm/sankhyablocks.js +1 -1
  42. package/dist/esm/snk-actions-button_7.entry.js +2 -2
  43. package/dist/esm/snk-application.entry.js +1 -1
  44. package/dist/esm/snk-attach.entry.js +1 -1
  45. package/dist/esm/snk-crud.entry.js +18 -10
  46. package/dist/esm/snk-data-exporter.entry.js +2 -2
  47. package/dist/esm/{snk-data-unit-7d0ce406.js → snk-data-unit-affee080.js} +225 -11
  48. package/dist/esm/snk-data-unit.entry.js +2 -2
  49. package/dist/esm/snk-detail-view.entry.js +3 -3
  50. package/dist/esm/snk-grid.entry.js +21 -7
  51. package/dist/esm/{snk-guides-viewer-c44b3839.js → snk-guides-viewer-3befd409.js} +99 -44
  52. package/dist/esm/snk-guides-viewer.entry.js +2 -2
  53. package/dist/esm/snk-simple-crud.entry.js +66 -23
  54. package/dist/esm/snk-taskbar.entry.js +2 -1
  55. package/dist/esm/{taskbar-elements-d2353c64.js → taskbar-elements-c62b6c66.js} +3 -0
  56. package/dist/sankhyablocks/{p-35f85998.entry.js → p-2101be8b.entry.js} +1 -1
  57. package/dist/sankhyablocks/{p-ef6f0a1b.entry.js → p-21a5acc4.entry.js} +1 -1
  58. package/dist/sankhyablocks/p-2d6df7e7.entry.js +1 -0
  59. package/dist/sankhyablocks/p-3f624cbe.js +1 -0
  60. package/dist/sankhyablocks/p-53e1de0a.entry.js +1 -0
  61. package/dist/sankhyablocks/{p-b2a2a83e.entry.js → p-624390bb.entry.js} +1 -1
  62. package/dist/sankhyablocks/{p-5cc206bb.entry.js → p-6541bb6d.entry.js} +1 -1
  63. package/dist/sankhyablocks/p-80f8c22c.js +1 -0
  64. package/dist/sankhyablocks/p-82177c24.js +1 -0
  65. package/dist/sankhyablocks/{p-754559b9.entry.js → p-a5e5574c.entry.js} +1 -1
  66. package/dist/sankhyablocks/{p-5503e89f.entry.js → p-cbb4c043.entry.js} +1 -1
  67. package/dist/sankhyablocks/p-cf685cef.entry.js +1 -0
  68. package/dist/sankhyablocks/p-dcfc8b35.entry.js +1 -0
  69. package/dist/sankhyablocks/{p-38e3ffda.entry.js → p-ea55f2ab.entry.js} +1 -1
  70. package/dist/sankhyablocks/p-fb0f0087.js +1 -0
  71. package/dist/sankhyablocks/sankhyablocks.esm.js +1 -1
  72. package/dist/types/components/snk-crud/snk-crud.d.ts +4 -0
  73. package/dist/types/components/snk-crud/subcomponents/snk-guides-viewer.d.ts +10 -1
  74. package/dist/types/components/snk-data-unit/MultipleUpdateHelper.d.ts +9 -0
  75. package/dist/types/components/snk-data-unit/snk-data-unit.d.ts +17 -0
  76. package/dist/types/components/snk-grid/snk-grid.d.ts +5 -0
  77. package/dist/types/components/snk-simple-crud/snk-simple-crud.d.ts +9 -2
  78. package/dist/types/components/snk-taskbar/elements/taskbar-elements.d.ts +2 -1
  79. package/dist/types/components/snk-taskbar/snk-taskbar.d.ts +1 -0
  80. package/dist/types/components.d.ts +28 -0
  81. package/dist/types/lib/message/SnkMessageBuilder.d.ts +2 -1
  82. package/package.json +1 -1
  83. package/dist/sankhyablocks/p-17425c72.js +0 -1
  84. package/dist/sankhyablocks/p-3fc82614.js +0 -1
  85. package/dist/sankhyablocks/p-460f1827.entry.js +0 -1
  86. package/dist/sankhyablocks/p-6e0a5314.js +0 -1
  87. package/dist/sankhyablocks/p-835128f5.entry.js +0 -1
  88. package/dist/sankhyablocks/p-92778d5a.js +0 -1
  89. package/dist/sankhyablocks/p-a962a3e4.entry.js +0 -1
  90. package/dist/sankhyablocks/p-e35fe2bd.entry.js +0 -1
@@ -0,0 +1,128 @@
1
+ const NO_TAB_NAME = "__NO_TAB_NAME__";
2
+ const MAIN_TAB_NAME = "__main";
3
+ export async function showConfirmMultipleUpdatePopup({ title, labelBtnConfirm, labelBtnCancel, message, changingFields, }) {
4
+ return new Promise((resolve) => {
5
+ const popup = builPopup(title, resolve);
6
+ const contentContainer = buildContentContainer();
7
+ contentContainer.appendChild(buildMessage(message));
8
+ contentContainer.appendChild(buildChangesContainer(changingFields));
9
+ const actionsContainer = buildActionsContainer();
10
+ actionsContainer.appendChild(buildCancelBtn(popup, labelBtnCancel, resolve));
11
+ actionsContainer.appendChild(buildConfirmBtn(popup, labelBtnConfirm, resolve));
12
+ contentContainer.appendChild(actionsContainer);
13
+ popup.appendChild(contentContainer);
14
+ document.body.appendChild(popup);
15
+ });
16
+ }
17
+ function groupChanges(changingFields) {
18
+ const changesMap = new Map();
19
+ changingFields.forEach(change => {
20
+ var _a;
21
+ const key = (_a = change.tabName) !== null && _a !== void 0 ? _a : NO_TAB_NAME;
22
+ if (!changesMap.has(key))
23
+ changesMap.set(key, []);
24
+ changesMap.get(key).push(change);
25
+ });
26
+ return changesMap;
27
+ }
28
+ function getTabName(tabName) {
29
+ switch (tabName) {
30
+ case NO_TAB_NAME:
31
+ return "";
32
+ case MAIN_TAB_NAME:
33
+ return "Principal";
34
+ default:
35
+ return tabName;
36
+ }
37
+ }
38
+ function buildChangesDiv(tabName, changes) {
39
+ const changeLabel = document.createElement('span');
40
+ changeLabel.innerText = getTabName(tabName);
41
+ changeLabel.style.display = 'block';
42
+ changeLabel.style.fontWeight = 'var(--text-weight--large, 500)';
43
+ changeLabel.style.fontSize = 'var(--text--medium, 14px)';
44
+ changeLabel.style.marginBottom = 'var(--space--small, 6px)';
45
+ const changeDiv = document.createElement('div');
46
+ changeDiv.style.padding = 'var(--space--medium, 12px) 0';
47
+ changeDiv.style.borderTop = '1px solid var(--color--disable-secondary, #f2f5f8)';
48
+ changeDiv.appendChild(changeLabel);
49
+ changes.forEach(change => {
50
+ const changeLine = document.createElement('span');
51
+ changeLine.innerHTML = `${change.label}: <span style="color: var(--text--primary, #626e82)">${change.value}</span>`;
52
+ changeLine.style.display = 'block';
53
+ changeLine.style.marginBottom = 'var(--space--extra-small, 3px)';
54
+ changeDiv.appendChild(changeLine);
55
+ });
56
+ return changeDiv;
57
+ }
58
+ function buildChangesContainer(changingFields) {
59
+ const changesContainer = document.createElement('div');
60
+ changesContainer.style.flexDirection = 'column';
61
+ changesContainer.style.display = 'flex';
62
+ changesContainer.style.overflow = 'auto';
63
+ changesContainer.style.maxHeight = '300px';
64
+ const changesMap = groupChanges(changingFields);
65
+ changesMap.forEach((changes, key) => {
66
+ changesContainer.appendChild(buildChangesDiv(key, changes));
67
+ });
68
+ return changesContainer;
69
+ }
70
+ function buildMessage(messageContent) {
71
+ const message = document.createElement('p');
72
+ message.textContent = messageContent;
73
+ message.style.fontSize = 'var(--text--medium, 14px)';
74
+ return message;
75
+ }
76
+ function buildContentContainer() {
77
+ const contentContainer = document.createElement('div');
78
+ contentContainer.style.display = 'flex';
79
+ contentContainer.style.flexDirection = 'column';
80
+ contentContainer.style.fontFamily = 'var(--font-pattern, Roboto)';
81
+ contentContainer.style.fontSize = 'var(--text--medium, 14px)';
82
+ return contentContainer;
83
+ }
84
+ function buildActionsContainer() {
85
+ const actionsContainer = document.createElement('div');
86
+ actionsContainer.style.display = 'flex';
87
+ actionsContainer.style.flexDirection = 'row';
88
+ actionsContainer.style.justifyContent = 'flex-end';
89
+ actionsContainer.style.gap = '5px';
90
+ return actionsContainer;
91
+ }
92
+ function builPopup(title, resolve) {
93
+ const popup = document.createElement('ez-popup');
94
+ popup.opened = true;
95
+ popup.size = 'small';
96
+ popup.ezTitle = title;
97
+ popup.heightMode = 'auto';
98
+ popup.addEventListener('ezClosePopup', () => {
99
+ document.body.removeChild(popup);
100
+ resolve(false);
101
+ }, { once: true });
102
+ popup.addEventListener('ezPopupAction', () => {
103
+ document.body.removeChild(popup);
104
+ resolve(false);
105
+ }, { once: true });
106
+ return popup;
107
+ }
108
+ function buildConfirmBtn(popup, confirmBtnLabel, resolve) {
109
+ const confirmBtn = document.createElement('ez-button');
110
+ confirmBtn.label = confirmBtnLabel;
111
+ confirmBtn.size = 'medium';
112
+ confirmBtn.classList.add('ez-button--primary');
113
+ confirmBtn.onclick = () => {
114
+ document.body.removeChild(popup);
115
+ resolve(true);
116
+ };
117
+ return confirmBtn;
118
+ }
119
+ function buildCancelBtn(popup, cancelBtnLabel, resolve) {
120
+ const cancelBtn = document.createElement('ez-button');
121
+ cancelBtn.label = cancelBtnLabel;
122
+ cancelBtn.size = 'medium';
123
+ cancelBtn.onclick = () => {
124
+ document.body.removeChild(popup);
125
+ resolve(false);
126
+ };
127
+ return cancelBtn;
128
+ }
@@ -1,11 +1,12 @@
1
- import { Host, h } from '@stencil/core';
2
- import { Action, ApplicationContext, DataUnitAction, ObjectUtils, StringUtils } from '@sankhyalabs/core';
1
+ import { h, Host } from '@stencil/core';
2
+ import { Action, ApplicationContext, DataUnitAction, ObjectUtils, StringUtils, } from '@sankhyalabs/core';
3
3
  import { ApplicationUtils, DialogType } from '@sankhyalabs/ezui/dist/collection/utils';
4
4
  import { OperationMap, SnkMessageBuilder } from '../../lib/message/SnkMessageBuilder';
5
5
  import { DatasetStrategy } from '../../lib/http/data-fetcher/fetchers/data-unit/loadstrategy/DatasetStrategy';
6
6
  import { getRecordValue } from '../../lib/dataUnit/ValueFormatter';
7
7
  import { convertType } from '@sankhyalabs/core/dist/dataunit/metadata/DataType';
8
8
  import { getSelectedRecordsIDsInfo } from '../../lib/utils/GetSelectedRecordsIDsInfo';
9
+ import { showConfirmMultipleUpdatePopup } from './MultipleUpdateHelper';
9
10
  export class SnkDataUnit {
10
11
  constructor() {
11
12
  this._onDataUnitResolve = [];
@@ -14,6 +15,7 @@ export class SnkDataUnit {
14
15
  this._fieldsWithRmPrecision = [];
15
16
  this._metadataByRow = new Map();
16
17
  this._rowMetadataCache = new Map();
18
+ this._formFieldsConfig = [];
17
19
  this.REGEX_DATAUNIT_NAME = /dd:\/\/(.+?)\//;
18
20
  this._dataUnitObserver = async (action) => {
19
21
  const duState = await this.buildDataState(action.type);
@@ -92,6 +94,10 @@ export class SnkDataUnit {
92
94
  this.messagesBuilderUpdated.emit(newValue);
93
95
  }
94
96
  }
97
+ onMasterFormConfigChange({ detail }) {
98
+ var _a;
99
+ this._formFieldsConfig = (_a = detail === null || detail === void 0 ? void 0 : detail.fields) !== null && _a !== void 0 ? _a : [];
100
+ }
95
101
  /**
96
102
  * Obtém o dataUnit.
97
103
  */
@@ -266,9 +272,13 @@ export class SnkDataUnit {
266
272
  this._openedAlert = false;
267
273
  }
268
274
  async interceptSavingData(action) {
269
- if (!this.beforeSave) {
270
- return action;
275
+ if (this.dataUnit.isMultipleEdition) {
276
+ const confirm = await this.confirmMultipleSavingData();
277
+ if (!confirm)
278
+ return undefined;
271
279
  }
280
+ if (!this.beforeSave)
281
+ return action;
272
282
  const continueAction = this.beforeSave(this.dataUnit);
273
283
  if (continueAction instanceof Promise) {
274
284
  const result = await continueAction;
@@ -276,6 +286,46 @@ export class SnkDataUnit {
276
286
  }
277
287
  return continueAction ? action : undefined;
278
288
  }
289
+ async confirmMultipleSavingData() {
290
+ const selectedRecords = this.dataUnit.getSelectionInfo().records;
291
+ const title = this.getMessage('snkDataUnit.multipleUpdateConfirmationTitle');
292
+ const message = this.getMessage('snkDataUnit.multipleUpdateConfirmationMessage', { size: selectedRecords.length });
293
+ const labelBtnCancel = this.getMessage('snkDataUnit.confirm.cancel');
294
+ const labelBtnConfirm = this.getMessage('snkDataUnit.confirm.updateMultipleConfirm');
295
+ return await showConfirmMultipleUpdatePopup({
296
+ title,
297
+ message,
298
+ labelBtnConfirm,
299
+ labelBtnCancel,
300
+ changingFields: this.getChangingFields(),
301
+ });
302
+ }
303
+ getChangingFields() {
304
+ const changes = this.dataUnit.buildChangesToSave();
305
+ if (!(changes === null || changes === void 0 ? void 0 : changes.length))
306
+ return [];
307
+ const change = changes[0];
308
+ const changingFields = Object.keys(change.updatingFields).map(key => this.buildChangingField(key, change[key]));
309
+ return changingFields;
310
+ }
311
+ buildChangingField(key, value) {
312
+ const fieldLabel = this.dataUnit.getField(key).label;
313
+ const formattedValue = this.dataUnit.getFormattedValue(key, value);
314
+ return {
315
+ label: fieldLabel,
316
+ value: formattedValue,
317
+ tabName: this.getFieldTabName(key),
318
+ };
319
+ }
320
+ getFieldTabName(fieldName) {
321
+ var _a;
322
+ const tab = (_a = this._formFieldsConfig.find(f => f.name === fieldName)) === null || _a === void 0 ? void 0 : _a.tab;
323
+ if (!tab)
324
+ return undefined;
325
+ if (typeof tab === 'string')
326
+ return tab;
327
+ return tab.label;
328
+ }
279
329
  interceptDataSaved(action) {
280
330
  if (this.afterSave) {
281
331
  this.afterSave(this.dataUnit);
@@ -295,7 +345,17 @@ export class SnkDataUnit {
295
345
  }
296
346
  const cancelConfirmationTitle = this.getMessage("snkDataUnit.cancelConfirmationTitle");
297
347
  const confirm = await ApplicationUtils.confirm(cancelConfirmationTitle, cancelConfirmation);
298
- confirm && this.showSuccessMessage(this.getMessage("snkDataUnit.cancelInfo"));
348
+ if (confirm) {
349
+ let editionCanceledMessage;
350
+ if (this.dataUnit.isMultipleEdition) {
351
+ const selectedRecords = this.dataUnit.getSelectionInfo().records;
352
+ editionCanceledMessage = this.buildMultipleUpdateMessage(selectedRecords, true);
353
+ }
354
+ else {
355
+ editionCanceledMessage = this.getMessage("snkDataUnit.cancelInfo");
356
+ }
357
+ this.showSuccessMessage(editionCanceledMessage);
358
+ }
299
359
  return confirm ? action : undefined;
300
360
  }
301
361
  async interceptRemovingRecords(action) {
@@ -473,24 +533,50 @@ export class SnkDataUnit {
473
533
  }
474
534
  async handleDataSaved(action) {
475
535
  var _a, _b, _c;
476
- const newRowMetadata = await this.handleLoadRowMetadata((_c = (_b = (_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.changes) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.record);
536
+ const changes = (_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.changes;
537
+ const affectedRecords = (_b = action === null || action === void 0 ? void 0 : action.payload) === null || _b === void 0 ? void 0 : _b.records;
538
+ const newRowMetadata = await this.handleLoadRowMetadata((_c = changes === null || changes === void 0 ? void 0 : changes[0]) === null || _c === void 0 ? void 0 : _c.record);
477
539
  if (newRowMetadata) {
478
540
  newRowMetadata.getProp = this.buildGetPropRowMetadata(newRowMetadata);
479
541
  }
480
- const recordId = action.payload.records[0].__record__id__;
542
+ const recordId = affectedRecords[0].__record__id__;
481
543
  this._metadataByRow.set(recordId, newRowMetadata);
482
544
  this.dataState = await this.buildDataState();
483
- let saveOperation = action.payload.changes[0]._operation.toLowerCase();
484
- if (saveOperation == 'copy')
545
+ let saveOperation = changes[0]._operation.toLowerCase();
546
+ if (saveOperation == 'copy') {
485
547
  saveOperation = OperationMap.CLONE;
486
- if (this.ignoreSaveMessage && ![OperationMap.CLONE, OperationMap.INSERT].includes(saveOperation)) {
487
- return;
488
548
  }
489
- const msg = this.getMessage("snkDataUnit.saveInfo", action.payload.records[0], saveOperation);
549
+ if (this.canIgnoreOperationMessage(saveOperation))
550
+ return;
551
+ let msg = this.buildOperationMessage(saveOperation, affectedRecords);
490
552
  if (msg != undefined) {
491
553
  this.showSuccessMessage(msg);
492
554
  }
493
555
  }
556
+ canIgnoreOperationMessage(saveOperation) {
557
+ return this.ignoreSaveMessage && !this.isCloneOrInsertOperation(saveOperation);
558
+ }
559
+ isCloneOrInsertOperation(saveOperation) {
560
+ return [OperationMap.CLONE, OperationMap.INSERT].includes(saveOperation);
561
+ }
562
+ buildOperationMessage(saveOperation, records) {
563
+ if (this.isMultiplesUpdate(saveOperation, records)) {
564
+ return this.buildMultipleUpdateMessage(records);
565
+ }
566
+ return this.getMessage('snkDataUnit.saveInfo', records[0], saveOperation);
567
+ }
568
+ buildMultipleUpdateMessage(records, isCancel) {
569
+ /**
570
+ * FIXME: No futuro, precisamos pensar em um mecanismo para deixar as mensagens de feedback mais dinâmicas.
571
+ * Podemo ocorrer cenários onde temos mais de um registro selecionado e também cenários onde a chave primária
572
+ * de um registro se trata de uma chave composta.
573
+ */
574
+ const key = `snkDataUnit.${isCancel ? 'cancelInfo' : 'saveInfo'}`;
575
+ return this.getMessage(key, { records: records }, OperationMap.UPDATE_MULTIPLES);
576
+ }
577
+ isMultiplesUpdate(saveOperation, records) {
578
+ return saveOperation === OperationMap.UPDATE && records.length > 1;
579
+ }
494
580
  handleRecordsRemoved(action) {
495
581
  var _a, _b;
496
582
  let removeFinishMsg = this.buildRemoveFinishMessage(action);
@@ -1156,6 +1242,15 @@ export class SnkDataUnit {
1156
1242
  "methodName": "observeMessagesBuilder"
1157
1243
  }];
1158
1244
  }
1245
+ static get listeners() {
1246
+ return [{
1247
+ "name": "snkMasterFormConfigChange",
1248
+ "method": "onMasterFormConfigChange",
1249
+ "target": undefined,
1250
+ "capture": false,
1251
+ "passive": false
1252
+ }];
1253
+ }
1159
1254
  }
1160
1255
  class DataStateImpl {
1161
1256
  constructor(datastate) {
@@ -27,7 +27,7 @@ export class SnkGrid {
27
27
  });
28
28
  this._headerTaskbarProcessor = new TaskbarProcessor({
29
29
  "snkGridHeaderTaskbar.unselected": ["REFRESH", "DATA_EXPORTER", "ACTIONS_BUTTON", "MORE_OPTIONS"],
30
- "snkGridHeaderTaskbar.selected": ["UPDATE", "CLONE", "REMOVE", "MORE_OPTIONS", "DIVIDER", "ATTACH", "REFRESH", "DATA_EXPORTER", "ACTIONS_BUTTON"],
30
+ "snkGridHeaderTaskbar.selected": this.getGridHeaderSelectedBtns(),
31
31
  "snkGridHeaderTaskbar.detail.unselected": ["REFRESH", "MORE_OPTIONS"],
32
32
  "snkGridHeaderTaskbar.detail.selected": ["UPDATE", "ATTACH", "CLONE", "REMOVE", "MORE_OPTIONS", "DIVIDER", "REFRESH"],
33
33
  "snkGridHeaderTaskbar.singleTaskbar.unselected": ["INSERT", "FORM_MODE", "CONFIGURATOR", "REFRESH", "DATA_EXPORTER", "ACTIONS_BUTTON", "MORE_OPTIONS"],
@@ -78,6 +78,17 @@ export class SnkGrid {
78
78
  this.enableGridInsert = false;
79
79
  this.outlineMode = false;
80
80
  this.strategyExporter = ExporterStrategy.SERVER_SIDE;
81
+ this.multipleEditionEnabled = true;
82
+ }
83
+ getGridHeaderSelectedBtns() {
84
+ const btns = [
85
+ TaskbarElement.UPDATE, TaskbarElement.CLONE, TaskbarElement.REMOVE,
86
+ TaskbarElement.MORE_OPTIONS, TaskbarElement.DIVIDER, TaskbarElement.ATTACH, TaskbarElement.FORM_MODE,
87
+ TaskbarElement.CONFIGURATOR, TaskbarElement.REFRESH, TaskbarElement.DATA_EXPORTER, TaskbarElement.ACTIONS_BUTTON
88
+ ];
89
+ if (this.multipleEditionEnabled)
90
+ btns.unshift(TaskbarElement.UPDATE_MULTIPLE);
91
+ return btns;
81
92
  }
82
93
  reloadConfig() {
83
94
  this.loadConfig();
@@ -362,20 +373,23 @@ export class SnkGrid {
362
373
  const disabledButtons = [];
363
374
  if ((_a = this._dataState) === null || _a === void 0 ? void 0 : _a.selectionInfo) {
364
375
  if (this._dataState.selectionInfo.length > 1) {
365
- disabledButtons.push(TaskbarElement.CLONE, "ATTACH", TaskbarElement.UPDATE);
376
+ disabledButtons.push(TaskbarElement.CLONE, TaskbarElement.ATTACH, TaskbarElement.UPDATE);
366
377
  }
367
378
  if (this._dataState.selectionInfo.isAllRecords()) {
368
- disabledButtons.push("REMOVE");
379
+ disabledButtons.push(TaskbarElement.REMOVE);
369
380
  }
370
381
  }
371
382
  return disabledButtons;
372
383
  }
373
384
  getInvisibleButtons() {
385
+ var _a, _b;
374
386
  let invisibleButtons = [];
375
387
  if (!this._dataUnit || this._dataUnit.records.length === 0)
376
- invisibleButtons.push("DATA_EXPORTER");
377
- if (this._dataState && this._dataState.selectionInfo.mode === SelectionMode.ALL_RECORDS)
378
- invisibleButtons.push("ACTIONS_BUTTON");
388
+ invisibleButtons.push(TaskbarElement.DATA_EXPORTER);
389
+ if (((_a = this._dataState) === null || _a === void 0 ? void 0 : _a.selectionInfo.mode) === SelectionMode.ALL_RECORDS)
390
+ invisibleButtons.push(TaskbarElement.ACTIONS_BUTTON);
391
+ if (((_b = this._dataState) === null || _b === void 0 ? void 0 : _b.selectionInfo.length) === 1)
392
+ invisibleButtons.push(TaskbarElement.UPDATE_MULTIPLE);
379
393
  return invisibleButtons;
380
394
  }
381
395
  componentWillRender() {
@@ -1026,6 +1040,24 @@ export class SnkGrid {
1026
1040
  "attribute": "strategy-exporter",
1027
1041
  "reflect": false,
1028
1042
  "defaultValue": "ExporterStrategy.SERVER_SIDE"
1043
+ },
1044
+ "multipleEditionEnabled": {
1045
+ "type": "boolean",
1046
+ "mutable": false,
1047
+ "complexType": {
1048
+ "original": "boolean",
1049
+ "resolved": "boolean",
1050
+ "references": {}
1051
+ },
1052
+ "required": false,
1053
+ "optional": false,
1054
+ "docs": {
1055
+ "tags": [],
1056
+ "text": "Habilita a edi\u00E7\u00E3o de m\u00FAltiplos registros simult\u00E2neos."
1057
+ },
1058
+ "attribute": "multiple-edition-enabled",
1059
+ "reflect": false,
1060
+ "defaultValue": "true"
1029
1061
  }
1030
1062
  };
1031
1063
  }
@@ -1,4 +1,4 @@
1
- import { ApplicationContext, DataType, ElementIDUtils, FloatingManager, JSUtils, KeyboardManager, ObjectUtils, StringUtils, UserInterface, } from '@sankhyalabs/core';
1
+ import { Action as DUAction, ApplicationContext, DataType, ElementIDUtils, FloatingManager, JSUtils, KeyboardManager, ObjectUtils, StringUtils, UserInterface, } from '@sankhyalabs/core';
2
2
  import { CSSVarsUtils } from '@sankhyalabs/ezui/dist/collection/utils';
3
3
  import { h } from '@stencil/core';
4
4
  import { SIMPLE_CRUD_MODE, VIEW_MODE } from '../../lib/utils/constants';
@@ -22,13 +22,6 @@ export class SnkSimpleCrud {
22
22
  this._formConfigFetcher = new FormConfigFetcher();
23
23
  this._customEditors = new Map();
24
24
  this._customRenders = new Map();
25
- this._taskbarProcessor = new TaskbarProcessor({
26
- "snkSimpleCrudTaskbar.form_regular": this.getButtons(false, [TaskbarElement.GRID_MODE], true),
27
- "snkSimpleCrudTaskbar.grid_regular": this.getButtons(false, [TaskbarElement.DATA_EXPORTER, TaskbarElement.FORM_MODE]),
28
- "snkSimpleCrudTaskbar.form_selected": this.getButtons(true, [TaskbarElement.GRID_MODE], true),
29
- "snkSimpleCrudTaskbar.grid_selected": this.getButtons(true, [TaskbarElement.DATA_EXPORTER, TaskbarElement.FORM_MODE]),
30
- "snkSimpleCrudTaskbar.finish_edition": this.getFinishEditionButtonsCallback.bind(this)
31
- });
32
25
  this._showPopUpGridConfig = false;
33
26
  this._currentViewMode = VIEW_MODE.GRID;
34
27
  this._config = undefined;
@@ -61,6 +54,7 @@ export class SnkSimpleCrud {
61
54
  this.ignoreReadOnlyFormFields = false;
62
55
  this.autoFocus = true;
63
56
  this.domainMessagesBuilder = undefined;
57
+ this.multipleEditionEnabled = true;
64
58
  this.layoutFormConfig = false;
65
59
  this.autoLoad = undefined;
66
60
  this.outlineMode = false;
@@ -121,8 +115,25 @@ export class SnkSimpleCrud {
121
115
  newCustomFieldProps.set(fieldName, Object.assign(Object.assign({}, currentProps), { [propName]: value }));
122
116
  this._fieldsProps = newCustomFieldProps;
123
117
  }
118
+ loadTaskbarProcessor() {
119
+ const taskbarIDs = {};
120
+ taskbarIDs[TASKBAR_ID.FORM_REGULAR] = this.getButtons(false, [TaskbarElement.GRID_MODE], true);
121
+ taskbarIDs[TASKBAR_ID.GRID_REGULAR] = this.getButtons(false, [TaskbarElement.DATA_EXPORTER, TaskbarElement.FORM_MODE]);
122
+ taskbarIDs[TASKBAR_ID.FORM_SELECTED] = this.getButtons(true, [TaskbarElement.GRID_MODE], true);
123
+ taskbarIDs[TASKBAR_ID.GRID_SELECTED] = this.getGridSelectedButtonsCallBack.bind(this);
124
+ taskbarIDs[TASKBAR_ID.FINISH_EDITION] = this.getFinishEditionButtonsCallback.bind(this);
125
+ taskbarIDs[TASKBAR_ID.MULTIPLE_EDITION] = [TaskbarElement.CANCEL];
126
+ this._taskbarProcessor = new TaskbarProcessor(taskbarIDs);
127
+ }
128
+ getGridSelectedButtonsCallBack() {
129
+ var _a, _b, _c;
130
+ if (!this.multipleEditionEnabled || ((_c = (_b = (_a = this.dataState) === null || _a === void 0 ? void 0 : _a.selectionInfo) === null || _b === void 0 ? void 0 : _b.records) === null || _c === void 0 ? void 0 : _c.length) === 1) {
131
+ return this.getButtons(true, [TaskbarElement.DATA_EXPORTER, TaskbarElement.FORM_MODE]);
132
+ }
133
+ return this.getButtons(true, [TaskbarElement.UPDATE_MULTIPLE, TaskbarElement.DATA_EXPORTER, TaskbarElement.FORM_MODE]);
134
+ }
124
135
  getFinishEditionButtonsCallback() {
125
- const btns = ["CANCEL", "SAVE"];
136
+ const btns = [TaskbarElement.CANCEL, TaskbarElement.SAVE];
126
137
  if (this.enableGridInsert && this._currentViewMode !== VIEW_MODE.ATTACHMENT) {
127
138
  btns.push(this._currentViewMode === VIEW_MODE.GRID ? TaskbarElement.FORM_MODE : TaskbarElement.GRID_MODE);
128
139
  }
@@ -158,22 +169,32 @@ export class SnkSimpleCrud {
158
169
  async goToView(view) {
159
170
  this._currentViewMode = view;
160
171
  if (this._viewStack) {
172
+ if (view === VIEW_MODE.GRID)
173
+ this.dataUnit.isMultipleEdition = false;
161
174
  this._viewStack.show(view);
162
175
  }
163
176
  }
164
177
  actionClickListener(evt) {
165
- const act = evt.detail;
166
- if (act === TaskbarElement.CONFIGURATOR) {
167
- this._snkConfigurator.open();
168
- }
169
- else if (act === TaskbarElement.GRID_MODE) {
170
- this.goToView(VIEW_MODE.GRID);
171
- }
172
- else if (act === TaskbarElement.FORM_MODE) {
173
- this.goToView(VIEW_MODE.FORM);
174
- }
178
+ this.handleTaskbarAction(evt.detail);
175
179
  evt.stopPropagation();
176
180
  }
181
+ handleTaskbarAction(action) {
182
+ switch (action) {
183
+ case TaskbarElement.CONFIGURATOR:
184
+ this._snkConfigurator.open();
185
+ break;
186
+ case TaskbarElement.GRID_MODE:
187
+ this.goToView(VIEW_MODE.GRID);
188
+ break;
189
+ case TaskbarElement.FORM_MODE:
190
+ this.goToView(VIEW_MODE.FORM);
191
+ break;
192
+ case TaskbarElement.UPDATE_MULTIPLE:
193
+ this.dataUnit.isMultipleEdition = true;
194
+ this.goToView(VIEW_MODE.FORM);
195
+ break;
196
+ }
197
+ }
177
198
  async onChangeEntityName(newValue) {
178
199
  if (this.dataUnit)
179
200
  return;
@@ -305,8 +326,10 @@ export class SnkSimpleCrud {
305
326
  this.setFormConfig(await this._formConfigManager.loadConfig());
306
327
  }
307
328
  async componentWillRender() {
329
+ this.loadTaskbarProcessor();
308
330
  this._resourceID = await this.application.getResourceID();
309
331
  this.dataExporterProviderStore();
332
+ this.dataExporterProviderStore();
310
333
  this._taskbarProcessor.process(this.getTaskBarId(), this.taskbarManager, this.dataState, this.getTaskBarDisabledButtons());
311
334
  if (this.configName === undefined) {
312
335
  return;
@@ -338,6 +361,14 @@ export class SnkSimpleCrud {
338
361
  componentDidLoad() {
339
362
  CSSVarsUtils.applyVarsGrid(this._element, this._grid);
340
363
  this.initKeyboardManager();
364
+ this.dataUnit.subscribe(this.dataUnitActionHandler.bind(this));
365
+ }
366
+ async dataUnitActionHandler(action) {
367
+ if (action.type === DUAction.EDITION_CANCELED || action.type === DUAction.DATA_SAVED) {
368
+ if (this.dataUnit.isMultipleEdition) {
369
+ this.goToView(VIEW_MODE.GRID);
370
+ }
371
+ }
341
372
  }
342
373
  setCustomRenders() {
343
374
  if (!this._grid) {
@@ -376,14 +407,17 @@ export class SnkSimpleCrud {
376
407
  getTaskBarId() {
377
408
  var _a, _b;
378
409
  if ((_a = this.dataState) === null || _a === void 0 ? void 0 : _a.isDirty) {
379
- return "snkSimpleCrudTaskbar.finish_edition";
410
+ return TASKBAR_ID.FINISH_EDITION;
411
+ }
412
+ if (this.dataUnit.isMultipleEdition) {
413
+ return TASKBAR_ID.MULTIPLE_EDITION;
380
414
  }
381
415
  if (((_b = this.dataState) === null || _b === void 0 ? void 0 : _b.selectionInfo) &&
382
416
  !this.dataState.selectionInfo.isAllRecords() &&
383
417
  this.dataState.selectionInfo.length > 0) {
384
- return this._currentViewMode === VIEW_MODE.GRID ? "snkSimpleCrudTaskbar.grid_selected" : "snkSimpleCrudTaskbar.form_selected";
418
+ return this._currentViewMode === VIEW_MODE.GRID ? TASKBAR_ID.GRID_SELECTED : TASKBAR_ID.FORM_SELECTED;
385
419
  }
386
- return this._currentViewMode === VIEW_MODE.GRID ? "snkSimpleCrudTaskbar.grid_regular" : "snkSimpleCrudTaskbar.form_regular";
420
+ return this._currentViewMode === VIEW_MODE.GRID ? TASKBAR_ID.GRID_REGULAR : TASKBAR_ID.FORM_REGULAR;
387
421
  }
388
422
  initInMemoryDataUnit() {
389
423
  this._inMemoryLoader = new InMemoryLoader(this._metadata, undefined, { autoLoad: this.autoLoad });
@@ -1237,6 +1271,24 @@ export class SnkSimpleCrud {
1237
1271
  "attribute": "domain-messages-builder",
1238
1272
  "reflect": false
1239
1273
  },
1274
+ "multipleEditionEnabled": {
1275
+ "type": "boolean",
1276
+ "mutable": false,
1277
+ "complexType": {
1278
+ "original": "boolean",
1279
+ "resolved": "boolean",
1280
+ "references": {}
1281
+ },
1282
+ "required": false,
1283
+ "optional": false,
1284
+ "docs": {
1285
+ "tags": [],
1286
+ "text": "Habilita a edi\u00E7\u00E3o de m\u00FAltiplos registros simult\u00E2neos."
1287
+ },
1288
+ "attribute": "multiple-edition-enabled",
1289
+ "reflect": false,
1290
+ "defaultValue": "true"
1291
+ },
1240
1292
  "layoutFormConfig": {
1241
1293
  "type": "boolean",
1242
1294
  "mutable": false,
@@ -1714,3 +1766,12 @@ export class SnkSimpleCrud {
1714
1766
  }];
1715
1767
  }
1716
1768
  }
1769
+ var TASKBAR_ID;
1770
+ (function (TASKBAR_ID) {
1771
+ TASKBAR_ID["FORM_REGULAR"] = "snkSimpleCrudTaskbar.form_regular";
1772
+ TASKBAR_ID["GRID_REGULAR"] = "snkSimpleCrudTaskbar.grid_regular";
1773
+ TASKBAR_ID["FORM_SELECTED"] = "snkSimpleCrudTaskbar.form_selected";
1774
+ TASKBAR_ID["GRID_SELECTED"] = "snkSimpleCrudTaskbar.grid_selected";
1775
+ TASKBAR_ID["FINISH_EDITION"] = "snkSimpleCrudTaskbar.finish_edition";
1776
+ TASKBAR_ID["MULTIPLE_EDITION"] = "snkSimpleCrudTaskbar.multiple_edition";
1777
+ })(TASKBAR_ID || (TASKBAR_ID = {}));
@@ -1,6 +1,19 @@
1
1
  :host {
2
+ /*@doc Define a largura mínima do componente.*/
3
+ --ez-dropdown--min-width: 150px;
2
4
  /*private*/
3
5
  display: flex;
4
6
  width: fit-content;
5
7
  height: fit-content;
6
8
  }
9
+
10
+ .ez-dropdown-container {
11
+ position: relative;
12
+ display: inline-block;
13
+ }
14
+
15
+ .ez-dropdown--sticky {
16
+ position: absolute;
17
+ display: block;
18
+ min-width: var(--ez-dropdown--min-width);
19
+ }
@@ -118,7 +118,7 @@ export class TaskbarActionsButton {
118
118
  this.taskbarActionsButtonDisconnected.emit();
119
119
  }
120
120
  render() {
121
- return (h(Host, null, h("div", { class: `${this.canShowDropdown() ? ' ez-elevation--16' : ''}` }, h("ez-button", { title: this.title, mode: 'icon', iconName: 'dots-vertical', size: 'small', enabled: this.enabled, onClick: () => this.controlDropdown() }), this.canShowDropdown() && h("ez-dropdown", { items: this.loadItems(), onEzClick: (evt) => this.onSelectAction(evt.detail), onEzOutsideClick: () => this._showDropdown = false, itemBuilder: (item, level) => this.dropdownItemBuilder(item, level) }))));
121
+ return (h(Host, null, h("div", { class: `${this.canShowDropdown() ? ' ez-elevation--16' : ''} ez-dropdown-container` }, h("ez-button", { title: this.title, mode: 'icon', iconName: 'dots-vertical', size: 'small', enabled: this.enabled, onClick: () => this.controlDropdown() }), this.canShowDropdown() && h("ez-dropdown", { class: `ez-dropdown--sticky`, items: this.loadItems(), onEzClick: (evt) => this.onSelectAction(evt.detail), onEzOutsideClick: () => this._showDropdown = false, itemBuilder: (item, level) => this.dropdownItemBuilder(item, level) }))));
122
122
  }
123
123
  static get is() { return "taskbar-actions-button"; }
124
124
  static get encapsulation() { return "scoped"; }
@@ -20,6 +20,7 @@ export var TaskbarElement;
20
20
  TaskbarElement["DATA_EXPORTER"] = "DATA_EXPORTER";
21
21
  TaskbarElement["ATTACH"] = "ATTACH";
22
22
  TaskbarElement["ACTIONS_BUTTON"] = "ACTIONS_BUTTON";
23
+ TaskbarElement["UPDATE_MULTIPLE"] = "UPDATE_MULTIPLE";
23
24
  })(TaskbarElement || (TaskbarElement = {}));
24
25
  export var AuthorizationElements;
25
26
  (function (AuthorizationElements) {
@@ -59,6 +60,8 @@ export const buildElem = (element, className, dataElementId, getTitle, action, i
59
60
  return iconButton("sync", element, className, dataElementId, title, action, isEnabled);
60
61
  case TaskbarElement.UPDATE:
61
62
  return iconButton("edit", element, className, dataElementId, title, action, isEnabled);
63
+ case TaskbarElement.UPDATE_MULTIPLE:
64
+ return iconButton("edit-table", element, className, dataElementId, title, action, isEnabled);
62
65
  case TaskbarElement.CLONE:
63
66
  return iconButton("copy", element, className, dataElementId, title, action, isEnabled);
64
67
  case TaskbarElement.REMOVE:
@@ -1,9 +1,8 @@
1
- import { ApplicationContext, ElementIDUtils, OverflowDirection, OverflowWatcher, StringUtils, OVERFLOWED_CLASS_NAME, LockManager, LockManagerOperation, SilentException } from '@sankhyalabs/core';
1
+ import { Action as DUAction, ApplicationContext, ElementIDUtils, LockManager, LockManagerOperation, OverflowDirection, OVERFLOWED_CLASS_NAME, OverflowWatcher, SilentException, StringUtils, } from '@sankhyalabs/core';
2
2
  import { h, Host } from '@stencil/core';
3
3
  import { AuthorizationConfig } from '../snk-configurator/AuthorizationConfig';
4
4
  import { AuthorizationElements, buildCustomButton, buildElem, TaskbarElement, VisibleWhenForbidden, } from './elements/taskbar-elements';
5
5
  import { PresentationMode } from '../../lib/@types';
6
- import { Action as DUAction } from '@sankhyalabs/core';
7
6
  export class SnkTaskbar {
8
7
  constructor() {
9
8
  this.TASKBAR_ITEM_ID_PREFIX = 'TASKBAR_ITEM_';
@@ -11,6 +10,7 @@ export class SnkTaskbar {
11
10
  this.ACTIONS_BUTTON_TAG = 'TASKBAR-ACTIONS-BUTTON';
12
11
  this.NOT_OVERFLOW_ELEMENTS = ["moreOptions", "dataExporter_snkDataExporter", "actionsButton_snkActionsButton"];
13
12
  this._titleKeyByElement = {
13
+ [TaskbarElement.UPDATE_MULTIPLE]: "snkTaskbar.titleUpdateMultiple",
14
14
  [TaskbarElement.UPDATE]: "snkTaskbar.titleUpdate",
15
15
  [TaskbarElement.PREVIOUS]: "snkTaskbar.titlePrevious",
16
16
  [TaskbarElement.NEXT]: "snkTaskbar.titleNext",
@@ -159,4 +159,5 @@ export var OperationMap;
159
159
  OperationMap["INSERT"] = "insert";
160
160
  OperationMap["UPDATE"] = "update";
161
161
  OperationMap["CLEAN"] = "clean";
162
+ OperationMap["UPDATE_MULTIPLES"] = "updateMultiples";
162
163
  })(OperationMap || (OperationMap = {}));