@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
@@ -1,32 +1,37 @@
1
1
  const snkDataUnitMessages = {
2
2
  saveInfo: {
3
- clone: "Duplicação realizada!",
4
- insert: "Inclusão realizada!",
5
- update: "Alteração realizada!"
3
+ clone: 'Duplicação realizada!',
4
+ insert: 'Inclusão realizada!',
5
+ update: 'Alteração realizada!',
6
+ updateMultiples: 'Múltiplos registros alterados com sucesso!'
6
7
  },
7
8
  cancelInfo: {
8
- clone: "Duplicação descartada!",
9
- insert: "A inclusão foi descartada!",
10
- update: "A edição foi descartada!"
9
+ clone: 'Duplicação descartada!',
10
+ insert: 'A inclusão foi descartada!',
11
+ update: 'A edição foi descartada!',
12
+ updateMultiples: 'A edição de múltiplos registros foi descartada com sucesso!'
11
13
  },
12
14
  confirm: {
13
- cancel: "Cancelar",
14
- delete: "Excluir",
15
- yes: "Sim",
16
- no: "Não"
15
+ cancel: 'Cancelar',
16
+ delete: 'Excluir',
17
+ updateMultipleConfirm: 'Confirmar edição',
18
+ yes: 'Sim',
19
+ no: 'Não',
17
20
  },
18
- removeInfo: "Registro removido com sucesso!",
19
- cancelConfirmationTitle: "Aviso",
20
- cancelConfirmation: "As alterações realizadas serão descartadas<br/><br/><b>Você realmente gostaria de cancelar?",
21
- removeConfirmationTitle: "Aviso",
22
- removeConfirmation: "Deseja realmente excluir o registro atual?",
23
- forbidden: "Sem permissão",
24
- forbiddenUpdate: "Não é possível fazer alterações. Verifique as permissões de acesso.",
25
- forbiddenInsert: "Não é possível incluir. Verifique as permissões de acesso.",
26
- forbiddenClone: "Não é possível duplicar. Verifique as permissões de acesso.",
27
- forbiddenRemove: "Não é possível remover. Verifique as permissões de acesso.",
28
- removeAllConfirmation: "Os <strong>{{size}} registros selecionados</strong> serão excluídos.<br/><br/><strong>Você realmente gostaria de continuar?</strong>",
29
- removeAllInfo: "Os {{size}} registros foram removidos com sucesso!",
30
- fieldNameRequired: necessário informar o nome da coluna."
21
+ removeInfo: 'Registro removido com sucesso!',
22
+ cancelConfirmationTitle: 'Aviso',
23
+ cancelConfirmation: 'As alterações realizadas serão descartadas<br/><br/><b>Você realmente gostaria de cancelar?',
24
+ removeConfirmationTitle: 'Aviso',
25
+ removeConfirmation: 'Deseja realmente excluir o registro atual?',
26
+ multipleUpdateConfirmationTitle: 'Confirmar edição múltipla',
27
+ multipleUpdateConfirmationMessage: 'As informações dos campos abaixo foram alteradas e serão aplicadas a {{size}} registros',
28
+ forbidden: 'Sem permissão',
29
+ forbiddenUpdate: 'Não é possível fazer alterações. Verifique as permissões de acesso.',
30
+ forbiddenInsert: 'Não é possível incluir. Verifique as permissões de acesso.',
31
+ forbiddenClone: 'Não é possível duplicar. Verifique as permissões de acesso.',
32
+ forbiddenRemove: 'Não é possível remover. Verifique as permissões de acesso.',
33
+ removeAllConfirmation: 'Os <strong>{{size}} registros selecionados</strong> serão excluídos.<br/><br/><strong>Você realmente gostaria de continuar?</strong>',
34
+ removeAllInfo: 'Os {{size}} registros foram removidos com sucesso!',
35
+ fieldNameRequired: 'É necessário informar o nome da coluna.',
31
36
  };
32
37
  export default snkDataUnitMessages;
@@ -1,4 +1,5 @@
1
1
  const snkTaskbarMessages = {
2
+ titleUpdateMultiple: "Editar Múltiplos",
2
3
  titleUpdate: "Editar",
3
4
  titlePrevious: "Anterior",
4
5
  titleNext: "Próximo",
@@ -2,34 +2,39 @@ import { ApplicationContext } from '@sankhyalabs/core';
2
2
 
3
3
  const snkDataUnitMessages = {
4
4
  saveInfo: {
5
- clone: "Duplicação realizada!",
6
- insert: "Inclusão realizada!",
7
- update: "Alteração realizada!"
5
+ clone: 'Duplicação realizada!',
6
+ insert: 'Inclusão realizada!',
7
+ update: 'Alteração realizada!',
8
+ updateMultiples: 'Múltiplos registros alterados com sucesso!'
8
9
  },
9
10
  cancelInfo: {
10
- clone: "Duplicação descartada!",
11
- insert: "A inclusão foi descartada!",
12
- update: "A edição foi descartada!"
11
+ clone: 'Duplicação descartada!',
12
+ insert: 'A inclusão foi descartada!',
13
+ update: 'A edição foi descartada!',
14
+ updateMultiples: 'A edição de múltiplos registros foi descartada com sucesso!'
13
15
  },
14
16
  confirm: {
15
- cancel: "Cancelar",
16
- delete: "Excluir",
17
- yes: "Sim",
18
- no: "Não"
19
- },
20
- removeInfo: "Registro removido com sucesso!",
21
- cancelConfirmationTitle: "Aviso",
22
- cancelConfirmation: "As alterações realizadas serão descartadas<br/><br/><b>Você realmente gostaria de cancelar?",
23
- removeConfirmationTitle: "Aviso",
24
- removeConfirmation: "Deseja realmente excluir o registro atual?",
25
- forbidden: "Sem permissão",
26
- forbiddenUpdate: "Não é possível fazer alterações. Verifique as permissões de acesso.",
27
- forbiddenInsert: "Não é possível incluir. Verifique as permissões de acesso.",
28
- forbiddenClone: "Não é possível duplicar. Verifique as permissões de acesso.",
29
- forbiddenRemove: "Não é possível remover. Verifique as permissões de acesso.",
30
- removeAllConfirmation: "Os <strong>{{size}} registros selecionados</strong> serão excluídos.<br/><br/><strong>Você realmente gostaria de continuar?</strong>",
31
- removeAllInfo: "Os {{size}} registros foram removidos com sucesso!",
32
- fieldNameRequired: necessário informar o nome da coluna."
17
+ cancel: 'Cancelar',
18
+ delete: 'Excluir',
19
+ updateMultipleConfirm: 'Confirmar edição',
20
+ yes: 'Sim',
21
+ no: 'Não',
22
+ },
23
+ removeInfo: 'Registro removido com sucesso!',
24
+ cancelConfirmationTitle: 'Aviso',
25
+ cancelConfirmation: 'As alterações realizadas serão descartadas<br/><br/><b>Você realmente gostaria de cancelar?',
26
+ removeConfirmationTitle: 'Aviso',
27
+ removeConfirmation: 'Deseja realmente excluir o registro atual?',
28
+ multipleUpdateConfirmationTitle: 'Confirmar edição múltipla',
29
+ multipleUpdateConfirmationMessage: 'As informações dos campos abaixo foram alteradas e serão aplicadas a {{size}} registros',
30
+ forbidden: 'Sem permissão',
31
+ forbiddenUpdate: 'Não é possível fazer alterações. Verifique as permissões de acesso.',
32
+ forbiddenInsert: 'Não é possível incluir. Verifique as permissões de acesso.',
33
+ forbiddenClone: 'Não é possível duplicar. Verifique as permissões de acesso.',
34
+ forbiddenRemove: 'Não é possível remover. Verifique as permissões de acesso.',
35
+ removeAllConfirmation: 'Os <strong>{{size}} registros selecionados</strong> serão excluídos.<br/><br/><strong>Você realmente gostaria de continuar?</strong>',
36
+ removeAllInfo: 'Os {{size}} registros foram removidos com sucesso!',
37
+ fieldNameRequired: 'É necessário informar o nome da coluna.',
33
38
  };
34
39
 
35
40
  const snkFilterBarMessages = {
@@ -92,6 +97,7 @@ const snkFilterBarMessages = {
92
97
  };
93
98
 
94
99
  const snkTaskbarMessages = {
100
+ titleUpdateMultiple: "Editar Múltiplos",
95
101
  titleUpdate: "Editar",
96
102
  titlePrevious: "Anterior",
97
103
  titleNext: "Próximo",
@@ -663,6 +669,7 @@ var OperationMap;
663
669
  OperationMap["INSERT"] = "insert";
664
670
  OperationMap["UPDATE"] = "update";
665
671
  OperationMap["CLEAN"] = "clean";
672
+ OperationMap["UPDATE_MULTIPLES"] = "updateMultiples";
666
673
  })(OperationMap || (OperationMap = {}));
667
674
 
668
675
  export { OperationMap as O, SnkMessageBuilder as S };
@@ -90,6 +90,7 @@ const SnkCrud$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
90
90
  this.setCustomFormTitle = undefined;
91
91
  this.strategyExporter = ExporterStrategy.SERVER_SIDE;
92
92
  this.layoutFormConfig = false;
93
+ this.multipleEditionEnabled = true;
93
94
  this.customContainerId = `SNK-CRUD-CUSTOM-CONTAINER-${StringUtils.generateUUID()}`;
94
95
  }
95
96
  /**
@@ -176,14 +177,20 @@ const SnkCrud$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
176
177
  this.setViewMode(VIEW_MODE.FORM);
177
178
  }
178
179
  async executeAction(act) {
179
- if (act === TaskbarElement.GRID_MODE)
180
- return this.setViewMode(VIEW_MODE.GRID);
181
- if (act === TaskbarElement.FORM_MODE || act === TaskbarElement.UPDATE)
182
- return this.gridToForm(act !== TaskbarElement.UPDATE);
183
- if (act === TaskbarElement.CONFIGURATOR)
184
- return this._snkConfigurator.open();
185
- if (act === "ATTACH")
186
- return this.setViewMode(VIEW_MODE.ATTACHMENT);
180
+ switch (act) {
181
+ case TaskbarElement.GRID_MODE:
182
+ return this.setViewMode(VIEW_MODE.GRID);
183
+ case TaskbarElement.FORM_MODE:
184
+ case TaskbarElement.UPDATE:
185
+ return this.gridToForm(act !== TaskbarElement.UPDATE);
186
+ case TaskbarElement.UPDATE_MULTIPLE:
187
+ this._dataUnit.isMultipleEdition = true;
188
+ return this.setViewMode(VIEW_MODE.FORM);
189
+ case TaskbarElement.CONFIGURATOR:
190
+ return this._snkConfigurator.open();
191
+ case TaskbarElement.ATTACH:
192
+ return this.setViewMode(VIEW_MODE.ATTACHMENT);
193
+ }
187
194
  }
188
195
  backView() {
189
196
  const lastView = this._viewHistory.at(-2) || VIEW_MODE.GRID;
@@ -193,6 +200,7 @@ const SnkCrud$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
193
200
  this._viewStack.show(viewMode);
194
201
  this._currentViewMode = viewMode;
195
202
  if (viewMode === VIEW_MODE.GRID) {
203
+ this._dataUnit.isMultipleEdition = false;
196
204
  this._snkGrid.setFocus();
197
205
  }
198
206
  else if (viewMode === VIEW_MODE.FORM) {
@@ -412,7 +420,7 @@ const SnkCrud$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
412
420
  return;
413
421
  }
414
422
  this._snkDataUnit.ignoreSaveMessage = (this._currentViewMode === VIEW_MODE.GRID && !this.enableGridInsert);
415
- return (h(Host, null, h("ez-view-stack", { ref: (ref) => this._viewStack = ref, "data-element-id": "crud" }, h("stack-item", { class: 'ez-flex ez-flex--column ez-size-height--full ez-size-width--full ez-padding--medium' }, h("snk-grid", { ref: (ref) => this._snkGrid = ref, class: 'ez-flex ez-flex--column ez-size-height--full ez-size-width--full', filterBarTitle: this.filterBarTitle, "data-element-id": "crud_grid", configName: this.configName, onGridDoubleClick: () => this.gridToForm(true), taskbarManager: this.taskbarManager, onActionClick: evt => this.executeAction(evt.detail), messagesBuilder: this.messagesBuilder, actionsList: this.actionsList, statusResolver: this.statusResolver, multipleSelection: this.multipleSelection, presentationMode: this.presentationMode, recordsValidator: this.recordsValidator, selectionToastConfig: this.selectionToastConfig, useEnterLikeTab: this.useEnterLikeTab, canEdit: this._canEdit, resourceID: this._resourceID, disablePersonalizedFilter: this.disablePersonalizedFilter, gridLegacyConfigName: this.gridLegacyConfigName, filterBarLegacyConfigName: this.filterBarLegacyConfigName, autoLoad: this.autoLoad, autoFocus: this.autoFocus, enableGridInsert: this.enableGridInsert, enableLockManagerTaskbarClick: this.enableLockManagerTaskbarClick, enableLockManagerLoadingComp: this.enableLockManagerLoadingComp, strategyExporter: this.strategyExporter }, h("slot", { name: "GRID_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "GRID_HEADER_CUSTOM_ELEMENTS" }), h("slot", { name: "SnkGridHeader" }), h("slot", { name: "SnkGridFooter" }), h("slot", { name: "SnkGridTaskBar" }))), h("stack-item", null, h("snk-guides-viewer", { ref: ref => this._guidesViewer = ref, entityPath: this._snkDataUnit.entityName, messagesBuilder: this.messagesBuilder, onExit: () => this.setViewMode(VIEW_MODE.GRID), dataState: this._dataState, dataUnit: this._dataUnit, actionsList: this.actionsList, taskbarManager: this.taskbarManager, configName: this.configName, onActionClick: evt => this.executeAction(evt.detail), presentationMode: this.presentationMode, "data-element-id": "crud_form", canEdit: this._canEdit, recordsValidator: this.recordsValidator, resourceID: this._resourceID, detailTaskbarCustomContainerId: this.customContainerId, formLegacyConfigName: this.formLegacyConfigName, enableGridInsert: this.enableGridInsert, getCustomTitle: this.setCustomFormTitle, ignoreReadOnlyFormFields: this.ignoreReadOnlyFormFields }, h("slot", { name: "GUIDES_VIEWER_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "SnkFormTaskBar" }))), h("stack-item", null, h("snk-attach", { registerKey: this.attachmentRegisterKey, messagesBuilder: this.messagesBuilder, entityName: this._snkDataUnit.entityName, onBack: this.backView.bind(this) })), h("snk-configurator", { ref: (ref) => this._snkConfigurator = ref, viewMode: this._currentViewMode, messagesBuilder: this.messagesBuilder, onConfigSelected: (evt) => this.setViewMode(evt.detail), onOpenConfig: (evt) => this.openConfig(evt.detail), showActionButtons: this.showActionButtons, onSave: evt => this.handleConfiguratorEvent(evt, 'SAVE'), onCancel: evt => this.handleConfiguratorEvent(evt, 'CANCEL'), resourceID: this._resourceID, customContainerId: this.customContainerId, layoutFormConfig: this.layoutFormConfig })), h("div", { id: `${this.customContainerId}` }, h("slot", { name: "SnkConfigContainerSlot" }), h("slot", { name: "DETAIL_GRID_HEADER_CUSTOM_ELEMENTS" }), h("slot", { name: "DETAIL_GRID_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "DETAIL_TASKBAR_CUSTOM_ELEMENTS" }))));
423
+ return (h(Host, null, h("ez-view-stack", { ref: (ref) => this._viewStack = ref, "data-element-id": "crud" }, h("stack-item", { class: 'ez-flex ez-flex--column ez-size-height--full ez-size-width--full ez-padding--medium' }, h("snk-grid", { ref: (ref) => this._snkGrid = ref, class: 'ez-flex ez-flex--column ez-size-height--full ez-size-width--full', filterBarTitle: this.filterBarTitle, "data-element-id": "crud_grid", configName: this.configName, onGridDoubleClick: () => this.gridToForm(true), taskbarManager: this.taskbarManager, onActionClick: evt => this.executeAction(evt.detail), messagesBuilder: this.messagesBuilder, actionsList: this.actionsList, statusResolver: this.statusResolver, multipleSelection: this.multipleSelection, presentationMode: this.presentationMode, recordsValidator: this.recordsValidator, selectionToastConfig: this.selectionToastConfig, useEnterLikeTab: this.useEnterLikeTab, canEdit: this._canEdit, resourceID: this._resourceID, disablePersonalizedFilter: this.disablePersonalizedFilter, gridLegacyConfigName: this.gridLegacyConfigName, filterBarLegacyConfigName: this.filterBarLegacyConfigName, autoLoad: this.autoLoad, autoFocus: this.autoFocus, enableGridInsert: this.enableGridInsert, enableLockManagerTaskbarClick: this.enableLockManagerTaskbarClick, enableLockManagerLoadingComp: this.enableLockManagerLoadingComp, strategyExporter: this.strategyExporter, multipleEditionEnabled: this.multipleEditionEnabled }, h("slot", { name: "GRID_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "GRID_HEADER_CUSTOM_ELEMENTS" }), h("slot", { name: "SnkGridHeader" }), h("slot", { name: "SnkGridFooter" }), h("slot", { name: "SnkGridTaskBar" }))), h("stack-item", null, h("snk-guides-viewer", { ref: ref => this._guidesViewer = ref, entityPath: this._snkDataUnit.entityName, messagesBuilder: this.messagesBuilder, onExit: () => this.setViewMode(VIEW_MODE.GRID), dataState: this._dataState, dataUnit: this._dataUnit, actionsList: this.actionsList, taskbarManager: this.taskbarManager, configName: this.configName, onActionClick: evt => this.executeAction(evt.detail), presentationMode: this.presentationMode, "data-element-id": "crud_form", canEdit: this._canEdit, recordsValidator: this.recordsValidator, resourceID: this._resourceID, detailTaskbarCustomContainerId: this.customContainerId, formLegacyConfigName: this.formLegacyConfigName, enableGridInsert: this.enableGridInsert, getCustomTitle: this.setCustomFormTitle, ignoreReadOnlyFormFields: this.ignoreReadOnlyFormFields }, h("slot", { name: "GUIDES_VIEWER_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "SnkFormTaskBar" }))), h("stack-item", null, h("snk-attach", { registerKey: this.attachmentRegisterKey, messagesBuilder: this.messagesBuilder, entityName: this._snkDataUnit.entityName, onBack: this.backView.bind(this) })), h("snk-configurator", { ref: (ref) => this._snkConfigurator = ref, viewMode: this._currentViewMode, messagesBuilder: this.messagesBuilder, onConfigSelected: (evt) => this.setViewMode(evt.detail), onOpenConfig: (evt) => this.openConfig(evt.detail), showActionButtons: this.showActionButtons, onSave: evt => this.handleConfiguratorEvent(evt, 'SAVE'), onCancel: evt => this.handleConfiguratorEvent(evt, 'CANCEL'), resourceID: this._resourceID, customContainerId: this.customContainerId, layoutFormConfig: this.layoutFormConfig })), h("div", { id: `${this.customContainerId}` }, h("slot", { name: "SnkConfigContainerSlot" }), h("slot", { name: "DETAIL_GRID_HEADER_CUSTOM_ELEMENTS" }), h("slot", { name: "DETAIL_GRID_TASKBAR_CUSTOM_ELEMENTS" }), h("slot", { name: "DETAIL_TASKBAR_CUSTOM_ELEMENTS" }))));
416
424
  }
417
425
  get _element() { return this; }
418
426
  static get watchers() { return {
@@ -446,6 +454,7 @@ const SnkCrud$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
446
454
  "setCustomFormTitle": [16],
447
455
  "strategyExporter": [1025, "strategy-exporter"],
448
456
  "layoutFormConfig": [4, "layout-form-config"],
457
+ "multipleEditionEnabled": [4, "multiple-edition-enabled"],
449
458
  "_dataUnit": [32],
450
459
  "_dataState": [32],
451
460
  "attachmentRegisterKey": [32],
@@ -6,6 +6,135 @@ import { g as getRecordValue, a as DatasetStrategy } from './dataunit-fetcher.js
6
6
  import { convertType } from '@sankhyalabs/core/dist/dataunit/metadata/DataType';
7
7
  import { g as getSelectedRecordsIDsInfo } from './GetSelectedRecordsIDsInfo.js';
8
8
 
9
+ const NO_TAB_NAME = "__NO_TAB_NAME__";
10
+ const MAIN_TAB_NAME = "__main";
11
+ async function showConfirmMultipleUpdatePopup({ title, labelBtnConfirm, labelBtnCancel, message, changingFields, }) {
12
+ return new Promise((resolve) => {
13
+ const popup = builPopup(title, resolve);
14
+ const contentContainer = buildContentContainer();
15
+ contentContainer.appendChild(buildMessage(message));
16
+ contentContainer.appendChild(buildChangesContainer(changingFields));
17
+ const actionsContainer = buildActionsContainer();
18
+ actionsContainer.appendChild(buildCancelBtn(popup, labelBtnCancel, resolve));
19
+ actionsContainer.appendChild(buildConfirmBtn(popup, labelBtnConfirm, resolve));
20
+ contentContainer.appendChild(actionsContainer);
21
+ popup.appendChild(contentContainer);
22
+ document.body.appendChild(popup);
23
+ });
24
+ }
25
+ function groupChanges(changingFields) {
26
+ const changesMap = new Map();
27
+ changingFields.forEach(change => {
28
+ var _a;
29
+ const key = (_a = change.tabName) !== null && _a !== void 0 ? _a : NO_TAB_NAME;
30
+ if (!changesMap.has(key))
31
+ changesMap.set(key, []);
32
+ changesMap.get(key).push(change);
33
+ });
34
+ return changesMap;
35
+ }
36
+ function getTabName(tabName) {
37
+ switch (tabName) {
38
+ case NO_TAB_NAME:
39
+ return "";
40
+ case MAIN_TAB_NAME:
41
+ return "Principal";
42
+ default:
43
+ return tabName;
44
+ }
45
+ }
46
+ function buildChangesDiv(tabName, changes) {
47
+ const changeLabel = document.createElement('span');
48
+ changeLabel.innerText = getTabName(tabName);
49
+ changeLabel.style.display = 'block';
50
+ changeLabel.style.fontWeight = 'var(--text-weight--large, 500)';
51
+ changeLabel.style.fontSize = 'var(--text--medium, 14px)';
52
+ changeLabel.style.marginBottom = 'var(--space--small, 6px)';
53
+ const changeDiv = document.createElement('div');
54
+ changeDiv.style.padding = 'var(--space--medium, 12px) 0';
55
+ changeDiv.style.borderTop = '1px solid var(--color--disable-secondary, #f2f5f8)';
56
+ changeDiv.appendChild(changeLabel);
57
+ changes.forEach(change => {
58
+ const changeLine = document.createElement('span');
59
+ changeLine.innerHTML = `${change.label}: <span style="color: var(--text--primary, #626e82)">${change.value}</span>`;
60
+ changeLine.style.display = 'block';
61
+ changeLine.style.marginBottom = 'var(--space--extra-small, 3px)';
62
+ changeDiv.appendChild(changeLine);
63
+ });
64
+ return changeDiv;
65
+ }
66
+ function buildChangesContainer(changingFields) {
67
+ const changesContainer = document.createElement('div');
68
+ changesContainer.style.flexDirection = 'column';
69
+ changesContainer.style.display = 'flex';
70
+ changesContainer.style.overflow = 'auto';
71
+ changesContainer.style.maxHeight = '300px';
72
+ const changesMap = groupChanges(changingFields);
73
+ changesMap.forEach((changes, key) => {
74
+ changesContainer.appendChild(buildChangesDiv(key, changes));
75
+ });
76
+ return changesContainer;
77
+ }
78
+ function buildMessage(messageContent) {
79
+ const message = document.createElement('p');
80
+ message.textContent = messageContent;
81
+ message.style.fontSize = 'var(--text--medium, 14px)';
82
+ return message;
83
+ }
84
+ function buildContentContainer() {
85
+ const contentContainer = document.createElement('div');
86
+ contentContainer.style.display = 'flex';
87
+ contentContainer.style.flexDirection = 'column';
88
+ contentContainer.style.fontFamily = 'var(--font-pattern, Roboto)';
89
+ contentContainer.style.fontSize = 'var(--text--medium, 14px)';
90
+ return contentContainer;
91
+ }
92
+ function buildActionsContainer() {
93
+ const actionsContainer = document.createElement('div');
94
+ actionsContainer.style.display = 'flex';
95
+ actionsContainer.style.flexDirection = 'row';
96
+ actionsContainer.style.justifyContent = 'flex-end';
97
+ actionsContainer.style.gap = '5px';
98
+ return actionsContainer;
99
+ }
100
+ function builPopup(title, resolve) {
101
+ const popup = document.createElement('ez-popup');
102
+ popup.opened = true;
103
+ popup.size = 'small';
104
+ popup.ezTitle = title;
105
+ popup.heightMode = 'auto';
106
+ popup.addEventListener('ezClosePopup', () => {
107
+ document.body.removeChild(popup);
108
+ resolve(false);
109
+ }, { once: true });
110
+ popup.addEventListener('ezPopupAction', () => {
111
+ document.body.removeChild(popup);
112
+ resolve(false);
113
+ }, { once: true });
114
+ return popup;
115
+ }
116
+ function buildConfirmBtn(popup, confirmBtnLabel, resolve) {
117
+ const confirmBtn = document.createElement('ez-button');
118
+ confirmBtn.label = confirmBtnLabel;
119
+ confirmBtn.size = 'medium';
120
+ confirmBtn.classList.add('ez-button--primary');
121
+ confirmBtn.onclick = () => {
122
+ document.body.removeChild(popup);
123
+ resolve(true);
124
+ };
125
+ return confirmBtn;
126
+ }
127
+ function buildCancelBtn(popup, cancelBtnLabel, resolve) {
128
+ const cancelBtn = document.createElement('ez-button');
129
+ cancelBtn.label = cancelBtnLabel;
130
+ cancelBtn.size = 'medium';
131
+ cancelBtn.onclick = () => {
132
+ document.body.removeChild(popup);
133
+ resolve(false);
134
+ };
135
+ return cancelBtn;
136
+ }
137
+
9
138
  const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
10
139
  constructor() {
11
140
  super();
@@ -22,6 +151,7 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
22
151
  this._fieldsWithRmPrecision = [];
23
152
  this._metadataByRow = new Map();
24
153
  this._rowMetadataCache = new Map();
154
+ this._formFieldsConfig = [];
25
155
  this.REGEX_DATAUNIT_NAME = /dd:\/\/(.+?)\//;
26
156
  this._dataUnitObserver = async (action) => {
27
157
  const duState = await this.buildDataState(action.type);
@@ -98,6 +228,10 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
98
228
  this.messagesBuilderUpdated.emit(newValue);
99
229
  }
100
230
  }
231
+ onMasterFormConfigChange({ detail }) {
232
+ var _a;
233
+ this._formFieldsConfig = (_a = detail === null || detail === void 0 ? void 0 : detail.fields) !== null && _a !== void 0 ? _a : [];
234
+ }
101
235
  /**
102
236
  * Obtém o dataUnit.
103
237
  */
@@ -272,9 +406,13 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
272
406
  this._openedAlert = false;
273
407
  }
274
408
  async interceptSavingData(action) {
275
- if (!this.beforeSave) {
276
- return action;
409
+ if (this.dataUnit.isMultipleEdition) {
410
+ const confirm = await this.confirmMultipleSavingData();
411
+ if (!confirm)
412
+ return undefined;
277
413
  }
414
+ if (!this.beforeSave)
415
+ return action;
278
416
  const continueAction = this.beforeSave(this.dataUnit);
279
417
  if (continueAction instanceof Promise) {
280
418
  const result = await continueAction;
@@ -282,6 +420,46 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
282
420
  }
283
421
  return continueAction ? action : undefined;
284
422
  }
423
+ async confirmMultipleSavingData() {
424
+ const selectedRecords = this.dataUnit.getSelectionInfo().records;
425
+ const title = this.getMessage('snkDataUnit.multipleUpdateConfirmationTitle');
426
+ const message = this.getMessage('snkDataUnit.multipleUpdateConfirmationMessage', { size: selectedRecords.length });
427
+ const labelBtnCancel = this.getMessage('snkDataUnit.confirm.cancel');
428
+ const labelBtnConfirm = this.getMessage('snkDataUnit.confirm.updateMultipleConfirm');
429
+ return await showConfirmMultipleUpdatePopup({
430
+ title,
431
+ message,
432
+ labelBtnConfirm,
433
+ labelBtnCancel,
434
+ changingFields: this.getChangingFields(),
435
+ });
436
+ }
437
+ getChangingFields() {
438
+ const changes = this.dataUnit.buildChangesToSave();
439
+ if (!(changes === null || changes === void 0 ? void 0 : changes.length))
440
+ return [];
441
+ const change = changes[0];
442
+ const changingFields = Object.keys(change.updatingFields).map(key => this.buildChangingField(key, change[key]));
443
+ return changingFields;
444
+ }
445
+ buildChangingField(key, value) {
446
+ const fieldLabel = this.dataUnit.getField(key).label;
447
+ const formattedValue = this.dataUnit.getFormattedValue(key, value);
448
+ return {
449
+ label: fieldLabel,
450
+ value: formattedValue,
451
+ tabName: this.getFieldTabName(key),
452
+ };
453
+ }
454
+ getFieldTabName(fieldName) {
455
+ var _a;
456
+ const tab = (_a = this._formFieldsConfig.find(f => f.name === fieldName)) === null || _a === void 0 ? void 0 : _a.tab;
457
+ if (!tab)
458
+ return undefined;
459
+ if (typeof tab === 'string')
460
+ return tab;
461
+ return tab.label;
462
+ }
285
463
  interceptDataSaved(action) {
286
464
  if (this.afterSave) {
287
465
  this.afterSave(this.dataUnit);
@@ -301,7 +479,17 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
301
479
  }
302
480
  const cancelConfirmationTitle = this.getMessage("snkDataUnit.cancelConfirmationTitle");
303
481
  const confirm = await ApplicationUtils.confirm(cancelConfirmationTitle, cancelConfirmation);
304
- confirm && this.showSuccessMessage(this.getMessage("snkDataUnit.cancelInfo"));
482
+ if (confirm) {
483
+ let editionCanceledMessage;
484
+ if (this.dataUnit.isMultipleEdition) {
485
+ const selectedRecords = this.dataUnit.getSelectionInfo().records;
486
+ editionCanceledMessage = this.buildMultipleUpdateMessage(selectedRecords, true);
487
+ }
488
+ else {
489
+ editionCanceledMessage = this.getMessage("snkDataUnit.cancelInfo");
490
+ }
491
+ this.showSuccessMessage(editionCanceledMessage);
492
+ }
305
493
  return confirm ? action : undefined;
306
494
  }
307
495
  async interceptRemovingRecords(action) {
@@ -479,24 +667,50 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
479
667
  }
480
668
  async handleDataSaved(action) {
481
669
  var _a, _b, _c;
482
- 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);
670
+ const changes = (_a = action === null || action === void 0 ? void 0 : action.payload) === null || _a === void 0 ? void 0 : _a.changes;
671
+ const affectedRecords = (_b = action === null || action === void 0 ? void 0 : action.payload) === null || _b === void 0 ? void 0 : _b.records;
672
+ const newRowMetadata = await this.handleLoadRowMetadata((_c = changes === null || changes === void 0 ? void 0 : changes[0]) === null || _c === void 0 ? void 0 : _c.record);
483
673
  if (newRowMetadata) {
484
674
  newRowMetadata.getProp = this.buildGetPropRowMetadata(newRowMetadata);
485
675
  }
486
- const recordId = action.payload.records[0].__record__id__;
676
+ const recordId = affectedRecords[0].__record__id__;
487
677
  this._metadataByRow.set(recordId, newRowMetadata);
488
678
  this.dataState = await this.buildDataState();
489
- let saveOperation = action.payload.changes[0]._operation.toLowerCase();
490
- if (saveOperation == 'copy')
679
+ let saveOperation = changes[0]._operation.toLowerCase();
680
+ if (saveOperation == 'copy') {
491
681
  saveOperation = OperationMap.CLONE;
492
- if (this.ignoreSaveMessage && ![OperationMap.CLONE, OperationMap.INSERT].includes(saveOperation)) {
493
- return;
494
682
  }
495
- const msg = this.getMessage("snkDataUnit.saveInfo", action.payload.records[0], saveOperation);
683
+ if (this.canIgnoreOperationMessage(saveOperation))
684
+ return;
685
+ let msg = this.buildOperationMessage(saveOperation, affectedRecords);
496
686
  if (msg != undefined) {
497
687
  this.showSuccessMessage(msg);
498
688
  }
499
689
  }
690
+ canIgnoreOperationMessage(saveOperation) {
691
+ return this.ignoreSaveMessage && !this.isCloneOrInsertOperation(saveOperation);
692
+ }
693
+ isCloneOrInsertOperation(saveOperation) {
694
+ return [OperationMap.CLONE, OperationMap.INSERT].includes(saveOperation);
695
+ }
696
+ buildOperationMessage(saveOperation, records) {
697
+ if (this.isMultiplesUpdate(saveOperation, records)) {
698
+ return this.buildMultipleUpdateMessage(records);
699
+ }
700
+ return this.getMessage('snkDataUnit.saveInfo', records[0], saveOperation);
701
+ }
702
+ buildMultipleUpdateMessage(records, isCancel) {
703
+ /**
704
+ * FIXME: No futuro, precisamos pensar em um mecanismo para deixar as mensagens de feedback mais dinâmicas.
705
+ * Podemo ocorrer cenários onde temos mais de um registro selecionado e também cenários onde a chave primária
706
+ * de um registro se trata de uma chave composta.
707
+ */
708
+ const key = `snkDataUnit.${isCancel ? 'cancelInfo' : 'saveInfo'}`;
709
+ return this.getMessage(key, { records: records }, OperationMap.UPDATE_MULTIPLES);
710
+ }
711
+ isMultiplesUpdate(saveOperation, records) {
712
+ return saveOperation === OperationMap.UPDATE && records.length > 1;
713
+ }
500
714
  handleRecordsRemoved(action) {
501
715
  var _a, _b;
502
716
  let removeFinishMsg = this.buildRemoveFinishMessage(action);
@@ -703,7 +917,7 @@ const SnkDataUnit = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
703
917
  "getFieldsWithRmp": [64],
704
918
  "getFieldsWithRmPrecision": [64],
705
919
  "getRowMetadata": [64]
706
- }]);
920
+ }, [[0, "snkMasterFormConfigChange", "onMasterFormConfigChange"]]]);
707
921
  class DataStateImpl {
708
922
  constructor(datastate) {
709
923
  this.copyMode = datastate.copyMode;