aloha-vue 1.2.133 → 1.2.135

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 (24) hide show
  1. package/docs/src/views/PageTable/PageTableComplex/PageTableComplexExample/PageTableComplexExample.js +0 -4
  2. package/docs/src/views/PageTable/PageTableComplex/PageTableComplexExample/PageTableComplexExample.pug +1 -0
  3. package/docs/src/views/PageTable/PageTableComplex/PageTableComplexSlotRowActions/PageTableComplexSlotRowActions.pug +1 -1
  4. package/package.json +1 -1
  5. package/src/ADropdown/ADropdown.js +6 -2
  6. package/src/ADropdown/compositionAPI/ToggleAPI.js +3 -1
  7. package/src/ATable/ATable.js +24 -10
  8. package/src/ATable/ATableGroupedHeader/ATableGroupedHeader.js +2 -2
  9. package/src/ATable/ATableGroupedHeader/compositionAPI/ColumnsGroupedAPI.js +14 -4
  10. package/src/ATable/ATableSortingAdditional/ATableSortingAdditional.js +205 -0
  11. package/src/ATable/ATableSortingAdditional/compositionAPI/AttributesAPI.js +21 -0
  12. package/src/ATable/ATableSortingAdditional/compositionAPI/ColumnsAPI.js +28 -0
  13. package/src/ATable/ATableSortingAdditional/compositionAPI/DropdownAPI.js +26 -0
  14. package/src/ATable/ATableSortingAdditional/compositionAPI/FormAPI.js +92 -0
  15. package/src/ATable/ATableSortingAdditional/compositionAPI/ModelAPI.js +128 -0
  16. package/src/ATable/ATableTdAction/ATableTdAction.js +28 -22
  17. package/src/ATable/ATableTopPanel/ATableTopPanel.js +67 -33
  18. package/src/ATable/compositionAPI/SortChangeAPI.js +11 -2
  19. package/src/ATable/i18n/de.json +12 -1
  20. package/src/plugins/AIconPlugin.js +2 -0
  21. package/src/styles/components/AFilters.scss +4 -0
  22. package/src/styles/components/ATable.scss +13 -2
  23. package/src/ui/AFieldset/AFieldset.js +21 -14
  24. package/src/ui/ASelect/ASelect.js +3 -3
@@ -90,7 +90,6 @@ export default {
90
90
  label: "Hola2",
91
91
  id: "hola2",
92
92
  keyLabel: "hola",
93
- sortId: "hola",
94
93
  hide: true,
95
94
  footerKeyLabel: "hola",
96
95
  },
@@ -115,7 +114,6 @@ export default {
115
114
  label: "Obj2",
116
115
  id: "obj2",
117
116
  keyLabel: "obj.aloha",
118
- sortId: "obj.aloha",
119
117
  footerKeyLabel: "obj.aloha",
120
118
  },
121
119
  {
@@ -147,14 +145,12 @@ export default {
147
145
  label: "safeHtml",
148
146
  id: "safeHtml",
149
147
  keyLabelSafeHtml: "test",
150
- sortId: "test",
151
148
  width: 200,
152
149
  },
153
150
  {
154
151
  label: "html",
155
152
  id: "html",
156
153
  keyLabelHtml: "test",
157
- sortId: "test",
158
154
  width: 200,
159
155
  },
160
156
  ],
@@ -26,6 +26,7 @@ aloha-example(
26
26
  :rows-footer="rowsFooter"
27
27
  :is-loading-table="modelLoading"
28
28
  :is-loading-multiple-actions="false"
29
+ :is-sorting-multi-column="true"
29
30
  :views="views"
30
31
  :model-view="modelView"
31
32
  :model-is-table-without-scroll-start="true"
@@ -40,7 +40,7 @@ aloha-example(
40
40
  template(
41
41
  v-slot:rowActions="{ row }"
42
42
  )
43
- .a_btn_group(
43
+ .a_btn_group.a_btn_group_small(
44
44
  role="group"
45
45
  )
46
46
  a-button.a_btn.a_btn_primary(
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "Vue.js"
15
15
  ],
16
16
  "homepage": "https://github.com/ilia-brykin/aloha/#README.md",
17
- "version": "1.2.133",
17
+ "version": "1.2.135",
18
18
  "author": {
19
19
  "name": "Ilia Brykin",
20
20
  "email": "brykin.ilia@gmail.com"
@@ -277,7 +277,11 @@ export default {
277
277
  validator: value => difference(value, ["click", "hover", "focus"]).length === 0,
278
278
  },
279
279
  },
280
- setup(props) {
280
+ emits: [
281
+ "open",
282
+ "close",
283
+ ],
284
+ setup(props, context) {
281
285
  const {
282
286
  dropdownButtonRef,
283
287
  dropdownRef,
@@ -309,7 +313,7 @@ export default {
309
313
  timerCloseHover,
310
314
  triggerOpen,
311
315
  wasOpened,
312
- } = ToggleAPI(props, {
316
+ } = ToggleAPI(props, context, {
313
317
  dropdownButtonRef,
314
318
  dropdownRef,
315
319
  destroyPopover,
@@ -14,7 +14,7 @@ import {
14
14
  forEach,
15
15
  } from "lodash-es";
16
16
 
17
- export default function ToggleAPI(props, {
17
+ export default function ToggleAPI(props, { emit }, {
18
18
  dropdownButtonRef = ref(undefined),
19
19
  dropdownRef = ref(undefined),
20
20
  destroyPopover = () => {},
@@ -173,6 +173,7 @@ export default function ToggleAPI(props, {
173
173
  });
174
174
  }
175
175
  openDropdownGlobal();
176
+ emit("open");
176
177
  });
177
178
  };
178
179
 
@@ -216,6 +217,7 @@ export default function ToggleAPI(props, {
216
217
  setFocusToButton();
217
218
  }
218
219
  triggerOpen.value = undefined;
220
+ emit("close");
219
221
  }
220
222
 
221
223
  function onClose({ trigger } = {}) {
@@ -51,6 +51,11 @@ import {
51
51
  export default {
52
52
  name: "ATable",
53
53
  props: {
54
+ additionalSortingColumns: {
55
+ type: Array,
56
+ required: false,
57
+ default: () => [],
58
+ },
54
59
  columnActionsWidth: {
55
60
  type: Number,
56
61
  required: false,
@@ -227,7 +232,7 @@ export default {
227
232
  modelSort: {
228
233
  type: [String, Array],
229
234
  required: false,
230
- default: undefined,
235
+ default: () => [],
231
236
  },
232
237
  modelView: {
233
238
  type: [String, Number],
@@ -371,6 +376,11 @@ export default {
371
376
  empty: "_A_TABLE_EMPTY_TEXT_",
372
377
  }),
373
378
  },
379
+ useAdditionalSorting: {
380
+ type: Boolean,
381
+ required: false,
382
+ default: true,
383
+ },
374
384
  useViewSlot: {
375
385
  type: Boolean,
376
386
  required: false,
@@ -781,31 +791,35 @@ export default {
781
791
  }],
782
792
  }, [
783
793
  h(ATableTopPanel, {
794
+ additionalSortingColumns: this.additionalSortingColumns,
784
795
  areAllRowsSelected: this.areAllRowsSelected,
785
796
  areSomeRowsSelected: this.areSomeRowsSelected,
786
797
  closeMultipleActionsActive: this.closeMultipleActionsActive,
787
798
  countAllRows: this.countAllRowsLocal,
788
799
  disabledActions: this.disabledActions,
789
800
  disabledMultipleActions: this.disabledMultipleActions,
801
+ disabledSort: this.disabledSort,
790
802
  disabledViews: this.disabledViews,
803
+ hasViews: this.hasViews,
791
804
  isLabelVisible: this.isLabelVisible,
805
+ isLoadingMultipleActions: this.isLoadingMultipleActions,
806
+ isQuickSearch: this.isQuickSearch,
792
807
  label: this.label,
793
- labelTag: this.labelTag,
794
808
  labelClass: this.labelClass,
795
- tableActions: this.tableActions,
796
- multipleActions: this.multipleActions,
797
- isQuickSearch: this.isQuickSearch,
798
- isLoadingMultipleActions: this.isLoadingMultipleActions,
809
+ labelTag: this.labelTag,
799
810
  modelQuickSearch: this.modelQuickSearch,
800
- selectedRows: this.selectedRows,
801
- views: this.views,
802
- hasViews: this.hasViews,
803
- viewCurrent: this.viewCurrent,
811
+ modelSort: this.modelSortLocal,
804
812
  modelView: this.modelView,
813
+ multipleActions: this.multipleActions,
814
+ selectedRows: this.selectedRows,
805
815
  showCount: this.showCount,
816
+ tableActions: this.tableActions,
806
817
  tableActionsIndexFirstDropdownAction: this.tableActionsIndexFirstDropdownAction,
807
818
  tableActionsIndexFirstDropdownActionMobile: this.tableActionsIndexFirstDropdownActionMobile,
819
+ useAdditionalSorting: this.useAdditionalSorting,
808
820
  useViewSlot: this.useViewSlot,
821
+ viewCurrent: this.viewCurrent,
822
+ views: this.views,
809
823
  onUpdateViewCurrent: this.updateViewCurrent,
810
824
  onUpdateModelQuickSearch: this.updateModelQuickSearch,
811
825
  onToggleMultipleActionsActive: this.toggleMultipleActionsActive,
@@ -72,11 +72,11 @@ export default {
72
72
  "isMobile",
73
73
  "isMultipleActionsActive",
74
74
  ],
75
- setup() {
75
+ setup(props) {
76
76
  const {
77
77
  columnsOrdered,
78
78
  renderedGroupedColumns,
79
- } = ColumnsGroupedAPI();
79
+ } = ColumnsGroupedAPI(props);
80
80
 
81
81
  return {
82
82
  columnsOrdered,
@@ -2,6 +2,7 @@ import {
2
2
  computed,
3
3
  h,
4
4
  inject,
5
+ toRef,
5
6
  } from "vue";
6
7
 
7
8
  import ATableHeaderTh from "../../ATableHeaderTh/ATableHeaderTh";
@@ -13,11 +14,17 @@ import {
13
14
  get,
14
15
  includes,
15
16
  isArray,
16
- map, min, sortBy,
17
+ map,
18
+ min,
19
+ sortBy,
17
20
  uniqBy,
18
21
  } from "lodash-es";
19
22
 
20
- export default function ColumnsGroupedAPI() {
23
+ export default function ColumnsGroupedAPI(props) {
24
+ const modelSort = toRef(props, "modelSort");
25
+ const showFirstSortingSequenceNumber = toRef(props, "showFirstSortingSequenceNumber");
26
+ const sortingSequenceNumberClass = toRef(props, "sortingSequenceNumberClass");
27
+
21
28
  const columns = cloneDeep(map(inject("columnsFilteredForRender").value, (column, index) => {
22
29
  return {
23
30
  ...column,
@@ -112,11 +119,14 @@ export default function ColumnsGroupedAPI() {
112
119
  const getColumnsForRender = col => {
113
120
  return h(ATableHeaderTh, {
114
121
  ref: "th",
115
- column: col,
116
- columnIndex: col._index,
117
122
  class: "a_table__cell__child_group",
123
+ column: col,
118
124
  columnGroupNames: col.group,
125
+ columnIndex: col._index,
119
126
  hasMultipleActions: false,
127
+ modelSort: modelSort.value,
128
+ showFirstSortingSequenceNumber: showFirstSortingSequenceNumber.value,
129
+ sortingSequenceNumberClass: sortingSequenceNumberClass.value,
120
130
  });
121
131
  };
122
132
  const getRecursiveGroupForRender = group => {
@@ -0,0 +1,205 @@
1
+ import {
2
+ h,
3
+ onBeforeUnmount,
4
+ } from "vue";
5
+
6
+ import ADropdown from "../../ADropdown/ADropdown";
7
+ import AElement from "../../AElement/AElement";
8
+ import AForm from "../../ui/AForm/AForm";
9
+ import ATranslation from "../../ATranslation/ATranslation";
10
+
11
+ import AttributesAPI from "./compositionAPI/AttributesAPI";
12
+ import ColumnsAPI from "./compositionAPI/ColumnsAPI";
13
+ import DropdownAPI from "./compositionAPI/DropdownAPI";
14
+ import FormAPI from "./compositionAPI/FormAPI";
15
+ import ModelAPI from "./compositionAPI/ModelAPI";
16
+
17
+ export default {
18
+ name: "ATableSortingAdditional",
19
+ props: {
20
+ additionalSortingColumns: {
21
+ type: Array,
22
+ required: false,
23
+ default: () => [],
24
+ },
25
+ disabledSort: {
26
+ type: Boolean,
27
+ required: false,
28
+ },
29
+ modelSort: {
30
+ type: Array,
31
+ required: false,
32
+ },
33
+ },
34
+ setup(props) {
35
+ const {
36
+ columnsAll,
37
+ } = ColumnsAPI(props);
38
+
39
+ const {
40
+ dataForForm,
41
+ hasLastSelectOnlyOneColumn,
42
+ initDataForForm,
43
+ } = FormAPI(props, {
44
+ columnsAll,
45
+ });
46
+
47
+ const {
48
+ closeDropdown,
49
+ dropdownRef,
50
+ isDropdownVisible,
51
+ wasOpenDropdown,
52
+ } = DropdownAPI(props, {
53
+ columnsAll,
54
+ });
55
+
56
+ const {
57
+ changeModelSortInTable,
58
+ countModelSort,
59
+ destroyEventBus,
60
+ initEventBus,
61
+ initUnappliedModelSort,
62
+ removeUnappliedModelSort,
63
+ textCountModelSort,
64
+ unappliedModelSort,
65
+ updateUnappliedModelSort,
66
+ } = ModelAPI(props, {
67
+ closeDropdown,
68
+ hasLastSelectOnlyOneColumn,
69
+ initDataForForm,
70
+ wasOpenDropdown,
71
+ });
72
+
73
+ const {
74
+ excludeRenderAttributes,
75
+ idPrefix,
76
+ } = AttributesAPI();
77
+
78
+ initEventBus();
79
+
80
+ onBeforeUnmount(() => {
81
+ destroyEventBus();
82
+ });
83
+
84
+ return {
85
+ changeModelSortInTable,
86
+ closeDropdown,
87
+ countModelSort,
88
+ dataForForm,
89
+ dropdownRef,
90
+ excludeRenderAttributes,
91
+ idPrefix,
92
+ initUnappliedModelSort,
93
+ isDropdownVisible,
94
+ removeUnappliedModelSort,
95
+ textCountModelSort,
96
+ unappliedModelSort,
97
+ updateUnappliedModelSort,
98
+ wasOpenDropdown,
99
+ };
100
+ },
101
+ render() {
102
+ if (!this.isDropdownVisible) {
103
+ return null;
104
+ }
105
+
106
+ return h(ADropdown, {
107
+ ref: "dropdownRef",
108
+ buttonClass: "a_btn a_btn_secondary a_table__action",
109
+ buttonIconLeft: "ArrowDownUp",
110
+ buttonText: this.textCountModelSort,
111
+ buttonTextAriaHidden: true,
112
+ buttonTitle: "_A_TABLE_SORT_ADDITIONAL_DROPDOWN_TITLE_{{count}}_",
113
+ buttonTextScreenReader: "_A_TABLE_SORT_ADDITIONAL_DROPDOWN_TITLE_{{count}}_",
114
+ buttonTextClass: "a_badge a_bg_primary",
115
+ disabled: this.disabledSort,
116
+ dropdownClass: "a_filter_horizontal__wrapper",
117
+ dropdownRenderDefault: false,
118
+ dropdownTag: "div",
119
+ hasCaret: false,
120
+ inBody: true,
121
+ extra: {
122
+ count: this.countModelSort,
123
+ },
124
+ isCloseByClickInside: false,
125
+ lockArrowsNavigation: false,
126
+ lockTabNavigation: false,
127
+ onOpen: this.initUnappliedModelSort,
128
+ }, {
129
+ dropdown: () => {
130
+ return h("div", {
131
+ class: "a_filter_horizontal",
132
+ }, [
133
+ h("div", {
134
+ class: "a_filter_horizontal__header__wrapper",
135
+ }, [
136
+ h("div", {
137
+ class: "a_filter_horizontal__header",
138
+ }, [
139
+ h("div", {
140
+ class: "a_filter_horizontal__header__texts",
141
+ }, [
142
+ h(ATranslation, {
143
+ class: "a_filter_horizontal__header__texts__filter",
144
+ tag: "span",
145
+ text: "_A_TABLE_SORT_ADDITIONAL_HEADER_"
146
+ }),
147
+ ]),
148
+ ]),
149
+ ]),
150
+ h("div", {
151
+ class: "a_filter_horizontal__body__wrapper",
152
+ }, [
153
+ h("div", {
154
+ class: "a_filter_horizontal__body",
155
+ }, [
156
+ h(AForm, {
157
+ idPrefix: this.idPrefix,
158
+ class: "a_filter_horizontal__body__form",
159
+ classColumnDefault: "",
160
+ classColumns: "",
161
+ data: this.dataForForm,
162
+ excludeRenderAttributes: this.excludeRenderAttributes,
163
+ modelValue: this.unappliedModelSort,
164
+ showErrors: false,
165
+ onChange: this.updateUnappliedModelSort,
166
+ }, {
167
+ slotAppend: ({ item }) => h(AElement, {
168
+ type: "button",
169
+ class: "a_btn a_btn_primary a_ml_2",
170
+ title: "_A_TABLE_SORT_ADDITIONAL_BTN_DELETE_",
171
+ textScreenReader: "_A_TABLE_SORT_ADDITIONAL_BTN_DELETE_",
172
+ disabled: !this.unappliedModelSort?.[item.additionalProps.index]?.sortId,
173
+ iconLeft: "Close",
174
+ onClick: () => this.removeUnappliedModelSort({ item }),
175
+ }),
176
+ }),
177
+ ]),
178
+ h("div", {
179
+ class: "a_filter_horizontal__footer",
180
+ }, [
181
+ h("div", {
182
+ class: "a_filter_horizontal__footer__actions",
183
+ }, [
184
+ h(AElement, {
185
+ type: "button",
186
+ class: "a_btn a_btn_primary a_text_nowrap a_filter_horizontal__footer__actions__btn_search",
187
+ iconLeft: "ArrowDownUp",
188
+ text: "_A_TABLE_SORT_ADDITIONAL_START_",
189
+ disabled: this.disabledSort,
190
+ onClick: this.changeModelSortInTable,
191
+ }),
192
+ h(AElement, {
193
+ type: "button",
194
+ class: "a_btn a_btn_secondary a_text_nowrap a_filter_horizontal__footer__actions__btn_close",
195
+ text: "_A_TABLE_SORT_ADDITIONAL_CLOSE_DROPDOWN_",
196
+ onClick: this.closeDropdown,
197
+ }),
198
+ ]),
199
+ ]),
200
+ ]),
201
+ ]);
202
+ }
203
+ });
204
+ },
205
+ };
@@ -0,0 +1,21 @@
1
+ import {
2
+ computed,
3
+ inject,
4
+ } from "vue";
5
+
6
+ export default function AttributesAPI() {
7
+ const tableId = inject("tableId");
8
+
9
+ const excludeRenderAttributes = [
10
+ "additionalProps",
11
+ ];
12
+
13
+ const idPrefix = computed(() => {
14
+ return `${ tableId.value }_`;
15
+ });
16
+
17
+ return {
18
+ excludeRenderAttributes,
19
+ idPrefix,
20
+ };
21
+ }
@@ -0,0 +1,28 @@
1
+ import {
2
+ computed,
3
+ inject,
4
+ toRef,
5
+ } from "vue";
6
+
7
+ import {
8
+ filter,
9
+ } from "lodash-es";
10
+
11
+ export default function ColumnsAPI(props) {
12
+ const additionalSortingColumns = toRef(props, "additionalSortingColumns");
13
+
14
+ const columnsOrdered = inject("columnsOrdered");
15
+
16
+ const columnsAll = computed(() => {
17
+ return [
18
+ ...filter(columnsOrdered.value, column => {
19
+ return column.sortId;
20
+ }),
21
+ ...additionalSortingColumns.value,
22
+ ];
23
+ });
24
+
25
+ return {
26
+ columnsAll,
27
+ };
28
+ }
@@ -0,0 +1,26 @@
1
+ import {
2
+ computed,
3
+ ref,
4
+ } from "vue";
5
+
6
+ export default function DropdownAPI(props, {
7
+ columnsAll = computed(() => []),
8
+ }) {
9
+ const dropdownRef = ref(undefined);
10
+ const wasOpenDropdown = ref(false);
11
+
12
+ const isDropdownVisible = computed(() => {
13
+ return columnsAll.value.length > 0;
14
+ });
15
+
16
+ const closeDropdown = () => {
17
+ dropdownRef.value?.onClose({ trigger: "click" });
18
+ };
19
+
20
+ return {
21
+ closeDropdown,
22
+ dropdownRef,
23
+ isDropdownVisible,
24
+ wasOpenDropdown,
25
+ };
26
+ }
@@ -0,0 +1,92 @@
1
+ import {
2
+ computed,
3
+ ref,
4
+ } from "vue";
5
+
6
+ import {
7
+ filter,
8
+ forEach,
9
+ last,
10
+ } from "lodash-es";
11
+
12
+ export default function FormAPI(props, {
13
+ columnsAll = computed(() => []),
14
+ }) {
15
+ const dataForForm = ref([]);
16
+
17
+ const initDataForForm = ({ unappliedModelSort = [] }) => {
18
+ const DATA = [];
19
+ const DATA_MODES = [
20
+ {
21
+ label: "_A_TABLE_SORT_ADDITIONAL_DIRECTION_ASC_",
22
+ id: "asc",
23
+ },
24
+ {
25
+ label: "_A_TABLE_SORT_ADDITIONAL_DIRECTION_DESC_",
26
+ id: "desc",
27
+ },
28
+ ];
29
+ let columnsAllFiltered = columnsAll.value;
30
+ let lastSortId;
31
+ forEach(unappliedModelSort, ({ sortId }, index) => {
32
+ const isFirst = index === 0;
33
+ if (lastSortId) {
34
+ columnsAllFiltered = filter(columnsAllFiltered, column => {
35
+ return column.sortId !== lastSortId;
36
+ });
37
+ }
38
+ lastSortId = sortId;
39
+
40
+ DATA.push({
41
+ type: "fieldset",
42
+ id: `group_${ sortId }`,
43
+ label: isFirst ?
44
+ "_A_TABLE_SORT_ADDITIONAL_SORT_BY_" :
45
+ "_A_TABLE_SORT_ADDITIONAL_THEN_BY_",
46
+ children: [
47
+ {
48
+ id: `[${ index }].sortId`,
49
+ type: "select",
50
+ classColumn: "a_column a_column_12_touch a_column_7_fullhd a_column_7_widescreen a_column_7_desktop",
51
+ deselectable: false,
52
+ data: columnsAllFiltered,
53
+ keyId: "sortId",
54
+ keyLabel: "label",
55
+ translateData: true,
56
+ search: true,
57
+ label: "_A_TABLE_SORT_ADDITIONAL_COLUMN_",
58
+ },
59
+ {
60
+ id: `[${ index }].sortMode`,
61
+ type: "select",
62
+ classColumn: "a_column a_column_12_touch a_column_5_fullhd a_column_5_widescreen a_column_5_desktop a_d_flex a_align_items_center",
63
+ class: "a_width_100",
64
+ deselectable: false,
65
+ data: DATA_MODES,
66
+ keyId: "id",
67
+ keyLabel: "label",
68
+ translateData: true,
69
+ search: false,
70
+ label: "_A_TABLE_SORT_ADDITIONAL_DIRECTION_",
71
+ slotAppend: "slotAppend",
72
+ additionalProps: {
73
+ index,
74
+ },
75
+ },
76
+ ],
77
+ });
78
+ });
79
+
80
+ dataForForm.value = DATA;
81
+ };
82
+
83
+ const hasLastSelectOnlyOneColumn = computed(() => {
84
+ return last(dataForForm.value)?.children?.[0]?.data?.length === 1;
85
+ });
86
+
87
+ return {
88
+ dataForForm,
89
+ hasLastSelectOnlyOneColumn,
90
+ initDataForForm,
91
+ };
92
+ }
@@ -0,0 +1,128 @@
1
+ import {
2
+ computed,
3
+ inject,
4
+ ref,
5
+ toRef,
6
+ } from "vue";
7
+
8
+ import EventBus from "../../../utils/EventBus";
9
+ import {
10
+ cloneDeep,
11
+ forEach,
12
+ last,
13
+ startsWith,
14
+ } from "lodash-es";
15
+
16
+ export default function ModelAPI(props, {
17
+ closeDropdown = () => {},
18
+ hasLastSelectOnlyOneColumn = computed(() => false),
19
+ initDataForForm = () => {},
20
+ wasOpenDropdown = ref(false),
21
+ }) {
22
+ const modelSort = toRef(props, "modelSort");
23
+
24
+ const changeModelSort = inject("changeModelSort");
25
+ const tableId = inject("tableId");
26
+
27
+ const unappliedModelSort = ref([]);
28
+
29
+ const initUnappliedModelSort = ({ model } = {}) => {
30
+ if (wasOpenDropdown.value && !model) {
31
+ return;
32
+ }
33
+ wasOpenDropdown.value = true;
34
+
35
+ const MODEL_SORT = model ? model : cloneDeep(modelSort.value);
36
+ MODEL_SORT.push(undefined);
37
+
38
+ const UNAPPLIED_MODEL = [];
39
+ forEach(MODEL_SORT, model => {
40
+ const sortId = model ? model.replace(/^-/, "") : model;
41
+ const sortMode = startsWith(model, "-") ?
42
+ "desc" :
43
+ "asc";
44
+ UNAPPLIED_MODEL.push({
45
+ sortId,
46
+ sortMode,
47
+ });
48
+ });
49
+
50
+ unappliedModelSort.value = UNAPPLIED_MODEL;
51
+ initDataForForm({ unappliedModelSort: UNAPPLIED_MODEL });
52
+ };
53
+
54
+ const isLastModelForColumnNotEmpty = ({ model }) => {
55
+ const LAST_MODEL = last(model);
56
+
57
+ return !!LAST_MODEL.sortId;
58
+ };
59
+
60
+ const updateUnappliedModelSort = ({ model }) => {
61
+ if (isLastModelForColumnNotEmpty({ model }) && !hasLastSelectOnlyOneColumn.value) {
62
+ model.push({
63
+ sortId: undefined,
64
+ sortMode: "asc",
65
+ });
66
+ }
67
+ unappliedModelSort.value = model;
68
+ initDataForForm({ unappliedModelSort: unappliedModelSort.value });
69
+ };
70
+
71
+ const removeUnappliedModelSort = ({ item }) => {
72
+ const INDEX = item.additionalProps.index;
73
+ unappliedModelSort.value.splice(INDEX, 1);
74
+ initDataForForm({ unappliedModelSort: unappliedModelSort.value });
75
+ };
76
+
77
+ const changeModelSortInTable = () => {
78
+ const MODEL = [];
79
+ forEach(unappliedModelSort.value, modelItem => {
80
+ if (modelItem.sortId) {
81
+ MODEL.push(`${ modelItem.sortMode === "asc" ? "" : "-" }${ modelItem.sortId }`);
82
+ }
83
+ });
84
+ changeModelSort({
85
+ modelAll: MODEL,
86
+ });
87
+ closeDropdown();
88
+ };
89
+
90
+ const changeTableSorting = ({ modelSort = [], tableId: _tableId }) => {
91
+ if (_tableId !== tableId.value) {
92
+ return;
93
+ }
94
+ initUnappliedModelSort({ model: modelSort });
95
+ };
96
+
97
+ const initEventBus = () => {
98
+ EventBus.$on("changeTableSorting", changeTableSorting);
99
+ };
100
+
101
+ const destroyEventBus = () => {
102
+ EventBus.$off("changeTableSorting", changeTableSorting);
103
+ };
104
+
105
+ const countModelSort = computed(() => {
106
+ return modelSort.value?.length || 0;
107
+ });
108
+
109
+ const textCountModelSort = computed(() => {
110
+ if (countModelSort.value) {
111
+ return countModelSort.value;
112
+ }
113
+
114
+ return undefined;
115
+ });
116
+
117
+ return {
118
+ changeModelSortInTable,
119
+ countModelSort,
120
+ destroyEventBus,
121
+ initEventBus,
122
+ initUnappliedModelSort,
123
+ removeUnappliedModelSort,
124
+ textCountModelSort,
125
+ unappliedModelSort,
126
+ updateUnappliedModelSort,
127
+ };
128
+ }
@@ -138,29 +138,35 @@ export default {
138
138
  ]),
139
139
  ],
140
140
  }),
141
- this.$slots.rowActions ?
142
- this.$slots.rowActions({
143
- tableId: this.tableId,
144
- row: this.row,
145
- rowIndex: this.rowIndex,
146
- isFooter: this.isFooter,
147
- }) :
141
+ this.isRowActionsDropdownVisible || this.$slots.rowActions ?
142
+ h("div", {
143
+ class: "a_table__cell_action__group"
144
+ }, [
145
+ this.$slots.rowActions ?
146
+ this.$slots.rowActions({
147
+ tableId: this.tableId,
148
+ row: this.row,
149
+ rowIndex: this.rowIndex,
150
+ isFooter: this.isFooter,
151
+ }) :
152
+ "",
153
+ this.isRowActionsDropdownVisible && h(ADropdown, {
154
+ id: this.buttonActionsId,
155
+ actions: this.rowActionsFiltered,
156
+ buttonClass: "a_btn a_btn_secondary a_table__cell_action__btn",
157
+ buttonIconLeft: "OptionVertical",
158
+ buttonTextScreenReader: "_A_TABLE_DROPDOWN_ACTIONS_TITLE_{{rowNumber}}_",
159
+ buttonTitle: "_A_TABLE_DROPDOWN_ACTIONS_TITLE_{{rowNumber}}_",
160
+ disabled: this.disabledRowActions,
161
+ extra: {
162
+ rowNumber: this.rowNumber,
163
+ },
164
+ hasCaret: false,
165
+ inBody: true,
166
+ placement: "bottom-end",
167
+ }, this.$slots),
168
+ ]) :
148
169
  "",
149
- this.isRowActionsDropdownVisible && h(ADropdown, {
150
- id: this.buttonActionsId,
151
- actions: this.rowActionsFiltered,
152
- buttonClass: "a_btn a_btn_secondary a_table__cell_action__btn",
153
- buttonIconLeft: "OptionVertical",
154
- buttonTextScreenReader: "_A_TABLE_DROPDOWN_ACTIONS_TITLE_{{rowNumber}}_",
155
- buttonTitle: "_A_TABLE_DROPDOWN_ACTIONS_TITLE_{{rowNumber}}_",
156
- disabled: this.disabledRowActions,
157
- extra: {
158
- rowNumber: this.rowNumber,
159
- },
160
- hasCaret: false,
161
- inBody: true,
162
- placement: "bottom-end",
163
- }, this.$slots),
164
170
  ]),
165
171
  ]);
166
172
  },
@@ -6,6 +6,7 @@ import AButton from "../../AButton/AButton";
6
6
  import AGroupButtonDropdown from "../../AGroupButtonDropdown/AGroupButtonDropdown";
7
7
  import AInput from "../../ui/AInput/AInput";
8
8
  import ARadio from "../../ui/ARadio/ARadio";
9
+ import ATableSortingAdditional from "../ATableSortingAdditional/ATableSortingAdditional";
9
10
  import ATranslation from "../../ATranslation/ATranslation";
10
11
 
11
12
  import ActionsAPI from "./compositionAPI/ActionsAPI";
@@ -17,6 +18,11 @@ import ViewsAPI from "./compositionAPI/ViewsAPI";
17
18
  export default {
18
19
  name: "ATableTopPanel",
19
20
  props: {
21
+ additionalSortingColumns: {
22
+ type: Array,
23
+ required: false,
24
+ default: () => [],
25
+ },
20
26
  areAllRowsSelected: {
21
27
  type: Boolean,
22
28
  required: true,
@@ -41,6 +47,10 @@ export default {
41
47
  type: Boolean,
42
48
  required: true,
43
49
  },
50
+ disabledSort: {
51
+ type: Boolean,
52
+ required: false,
53
+ },
44
54
  disabledViews: {
45
55
  type: Boolean,
46
56
  required: true,
@@ -79,6 +89,10 @@ export default {
79
89
  type: String,
80
90
  required: true,
81
91
  },
92
+ modelSort: {
93
+ type: Array,
94
+ required: false,
95
+ },
82
96
  modelView: {
83
97
  type: String,
84
98
  required: false,
@@ -111,6 +125,11 @@ export default {
111
125
  required: false,
112
126
  default: 0,
113
127
  },
128
+ useAdditionalSorting: {
129
+ type: Boolean,
130
+ required: false,
131
+ default: true,
132
+ },
114
133
  useViewSlot: {
115
134
  type: Boolean,
116
135
  required: false,
@@ -222,10 +241,12 @@ export default {
222
241
  h("div", {
223
242
  class: "a_table__top_panel__actions",
224
243
  }, [
225
- this.$slots.tableActionsPrepend && this.$slots.tableActionsPrepend({
226
- isMultipleActionsActive: this.isMultipleActionsActive,
227
- modelView: this.modelView,
228
- }),
244
+ this.$slots.tableActionsPrepend ?
245
+ this.$slots.tableActionsPrepend({
246
+ isMultipleActionsActive: this.isMultipleActionsActive,
247
+ modelView: this.modelView,
248
+ }) :
249
+ "",
229
250
  h(AGroupButtonDropdown, {
230
251
  actions: this.tableActionsFiltered,
231
252
  actionsClasses: [],
@@ -262,35 +283,48 @@ export default {
262
283
  placement: "bottom-end",
263
284
  },
264
285
  }),
265
- this.isQuickSearch && h(AInput, {
266
- label: "_A_TABLE_QUICK_SEARCH_",
267
- class: "a_table__top_panel__actions__quick_search",
268
- modelUndefined: "",
269
- modelValue: this.modelQuickSearch,
270
- iconPrepend: "Search",
271
- "onUpdate:modelValue": this.updateModelQuickSearch,
272
- }),
273
- this.hasViews && h(ARadio, {
274
- modelValue: this.modelView,
275
- class: "a_d_inline_block",
276
- isButtonGroup: true,
277
- disabled: this.disabledViews,
278
- slotName: this.viewSlotLocal,
279
- data: this.views,
280
- keyId: "id",
281
- keyLabel: "label",
282
- hasBorder: false,
283
- classFieldset: "a_p_0",
284
- "onUpdate:modelValue": this.updateViewCurrentLocal,
285
- }, {
286
- viewSlot: arg => this.$slots.viewSlot && this.$slots.viewSlot({
287
- ...arg,
288
- }),
289
- }),
290
- this.$slots.tableActionsAppend && this.$slots.tableActionsAppend({
291
- isMultipleActionsActive: this.isMultipleActionsActive,
292
- modelView: this.modelView,
293
- }),
286
+ this.isQuickSearch ?
287
+ h(AInput, {
288
+ label: "_A_TABLE_QUICK_SEARCH_",
289
+ class: "a_table__top_panel__actions__quick_search",
290
+ modelUndefined: "",
291
+ modelValue: this.modelQuickSearch,
292
+ iconPrepend: "Search",
293
+ "onUpdate:modelValue": this.updateModelQuickSearch,
294
+ }) :
295
+ "",
296
+ this.hasViews ?
297
+ h(ARadio, {
298
+ modelValue: this.modelView,
299
+ class: "a_d_inline_block",
300
+ isButtonGroup: true,
301
+ disabled: this.disabledViews,
302
+ slotName: this.viewSlotLocal,
303
+ data: this.views,
304
+ keyId: "id",
305
+ keyLabel: "label",
306
+ hasBorder: false,
307
+ classFieldset: "a_p_0",
308
+ "onUpdate:modelValue": this.updateViewCurrentLocal,
309
+ }, {
310
+ viewSlot: arg => this.$slots.viewSlot && this.$slots.viewSlot({
311
+ ...arg,
312
+ }),
313
+ }) :
314
+ "",
315
+ this.useAdditionalSorting ?
316
+ h(ATableSortingAdditional, {
317
+ additionalSortingColumns: this.additionalSortingColumns,
318
+ disabledSort: this.disabledSort,
319
+ modelSort: this.modelSort,
320
+ }) :
321
+ "",
322
+ this.$slots.tableActionsAppend ?
323
+ this.$slots.tableActionsAppend({
324
+ isMultipleActionsActive: this.isMultipleActionsActive,
325
+ modelView: this.modelView,
326
+ }) :
327
+ "",
294
328
  ]),
295
329
  ]),
296
330
  this.isMultipleActionsActive && h("div", {
@@ -4,6 +4,7 @@ import {
4
4
  toRef,
5
5
  } from "vue";
6
6
 
7
+ import EventBus from "../../utils/EventBus";
7
8
  import {
8
9
  cloneDeep,
9
10
  } from "lodash-es";
@@ -12,6 +13,7 @@ export default function SortChangeAPI(props, { emit }, {
12
13
  modelSortLocal = ref([]),
13
14
  closePreviewAll = () => {},
14
15
  }) {
16
+ const id = toRef(props, "id");
15
17
  const isSortingMultiColumn = toRef(props, "isSortingMultiColumn");
16
18
  const sortingMultiColumnKey = toRef(props, "sortingMultiColumnKey");
17
19
 
@@ -52,15 +54,22 @@ export default function SortChangeAPI(props, { emit }, {
52
54
  modelSortLocal.value = [sortId];
53
55
  };
54
56
 
55
- const changeModelSort = ({ sortId, $event }) => {
56
- if (isSortingMultiColumnKeyPressed($event)) {
57
+ const changeModelSort = ({ sortId, $event, modelAll }) => {
58
+ if (modelAll) {
59
+ modelSortLocal.value = modelAll;
60
+ } else if (isSortingMultiColumnKeyPressed($event)) {
57
61
  changeModelSortMultiColumn({ sortId });
58
62
  } else {
59
63
  changeModelSortSingleColumn({ sortId });
60
64
  }
65
+
61
66
  emit("changeSorting", {
62
67
  modelSort: cloneDeep(modelSortLocal.value),
63
68
  });
69
+ EventBus.$emit("changeTableSorting", {
70
+ modelSort: cloneDeep(modelSortLocal.value),
71
+ tableId: id.value,
72
+ });
64
73
  closePreviewAll();
65
74
  };
66
75
 
@@ -39,5 +39,16 @@
39
39
  "_A_TABLE_SELECT_ALL_VISIBLE_POSSIBLE_ROWS_": "Alle sichtbaren, relevanten Zeilen auswählen",
40
40
  "_A_TABLE_SELECT_THIS_ROW_": "Die Zeile auswählen",
41
41
  "_A_TABLE_SORT_TITLE_": "Klicken Sie hier, um zwischen aufsteigender, absteigender und keiner Sortierung zu wechseln.",
42
- "_A_TABLE_SORT_TITLE_MULTI_COLUMN_": "Halten Sie die Umschalttaste beim Klicken gedrückt, um die Sortierung mehrerer Spalten zu kombinieren."
42
+ "_A_TABLE_SORT_TITLE_MULTI_COLUMN_": "Halten Sie die Umschalttaste beim Klicken gedrückt, um die Sortierung mehrerer Spalten zu kombinieren.",
43
+ "_A_TABLE_SORT_ADDITIONAL_HEADER_": "Sortierung",
44
+ "_A_TABLE_SORT_ADDITIONAL_SORT_BY_": "Sortieren nach",
45
+ "_A_TABLE_SORT_ADDITIONAL_THEN_BY_": "Dann nach",
46
+ "_A_TABLE_SORT_ADDITIONAL_COLUMN_": "Spalte",
47
+ "_A_TABLE_SORT_ADDITIONAL_DIRECTION_": "Reihenfolge",
48
+ "_A_TABLE_SORT_ADDITIONAL_DIRECTION_ASC_": "Aufsteigend",
49
+ "_A_TABLE_SORT_ADDITIONAL_DIRECTION_DESC_": "Absteigend",
50
+ "_A_TABLE_SORT_ADDITIONAL_CLOSE_DROPDOWN_": "Schließen",
51
+ "_A_TABLE_SORT_ADDITIONAL_START_": "Sortieren",
52
+ "_A_TABLE_SORT_ADDITIONAL_DROPDOWN_TITLE_{{count}}_": "Sortierung ändern (ausgewählte Spalten: {{ count }})",
53
+ "_A_TABLE_SORT_ADDITIONAL_BTN_DELETE_": "Sortierung aufheben"
43
54
  }
@@ -12,6 +12,7 @@ import AngleDown from "../AIcon/Icons/AngleDown";
12
12
  import AngleLeft from "../AIcon/Icons/AngleLeft";
13
13
  import AngleRight from "../AIcon/Icons/AngleRight";
14
14
  import AngleUp from "../AIcon/Icons/AngleUp";
15
+ import ArrowDownUp from "../AIcon/Icons/bootstrap-1-9-1/ArrowDownUp";
15
16
  import ArrowLeft from "../AIcon/Icons/bootstrap-1-9-1/ArrowLeft";
16
17
  import ArrowRight from "../AIcon/Icons/bootstrap-1-9-1/ArrowRight";
17
18
  import CaretDownFill from "../AIcon/Icons/bootstrap-1-9-1/CaretDownFill";
@@ -63,6 +64,7 @@ export const iconPluginOptions = ref({
63
64
  AngleLeft,
64
65
  AngleRight,
65
66
  AngleUp,
67
+ ArrowDownUp,
66
68
  ArrowLeft,
67
69
  ArrowRight,
68
70
  CaretDownFill,
@@ -99,6 +99,10 @@ $a_breakpoint_touch: 1023px !default;
99
99
  .a_form_element_number_controls .a_form_element {
100
100
  --a_input_number_width: 100% !important;
101
101
  }
102
+ .a_fieldset {
103
+ margin-top: 1rem;
104
+ margin-bottom: 1rem;
105
+ }
102
106
  }
103
107
  .a_filter_horizontal__add_filter {
104
108
  position: relative;
@@ -331,6 +331,13 @@
331
331
  > .a_table__cell__child {
332
332
  display: flex;
333
333
  justify-content: space-between;
334
+ align-items: center;
335
+ }
336
+ }
337
+ .a_table__cell_action__group {
338
+ margin-left: auto;
339
+ > * + * {
340
+ margin-left: 0.5rem;
334
341
  }
335
342
  }
336
343
  .a_table__cell_action_sticky {
@@ -436,9 +443,9 @@
436
443
  margin-right: .25rem;
437
444
  }
438
445
  .a_table__cell_action__btn {
446
+ --a_btn_padding_y: 0.25rem;
439
447
  --a_btn_padding_x: 0.5rem;
440
- --a_btn_padding_y: 0.375rem;
441
- --a_btn_line_height: 1;
448
+ --a_btn_font_size: 0.875rem;
442
449
  }
443
450
 
444
451
  .a_table__preview_right {
@@ -533,8 +540,12 @@
533
540
  .a_table_mobile__actions_parent {
534
541
  display: flex;
535
542
  align-items: center;
543
+ justify-content: space-between;
536
544
  padding-left: var(--a_table_mobile_dt_padding_left);
537
545
  padding-right: var(--a_table_mobile_dd_padding_right);
546
+ .a_table__cell_action {
547
+ flex-grow: unset;
548
+ }
538
549
  }
539
550
  .a_table_mobile__columns_btn_toggle {
540
551
  padding: 0;
@@ -156,7 +156,7 @@ export default {
156
156
  return null;
157
157
  }
158
158
 
159
- return ("div", {
159
+ return h("div", {
160
160
  style: this.componentStyleHide,
161
161
  ...this.attributesToExcludeFromRender,
162
162
  }, [
@@ -203,20 +203,27 @@ export default {
203
203
  } else if (item.classColumn) {
204
204
  classColumn = item.classColumn;
205
205
  }
206
- return h(this.componentTypesMapping[item.type], {
207
- key: itemIndex,
208
- modelValue: IS_CONTAINER ? this.modelValue : get(this.modelValue, item.id),
209
- modelDependencies: IS_CONTAINER ? this.modelValue : undefined,
206
+ return h("div", {
210
207
  class: classColumn,
211
- errors: this.errorsAll[item.id],
212
- errorsAll: this.errorsAll,
213
- idPrefix: this.idPrefix,
214
- "onUpdate:modelValue": model => this.onUpdateModelLocal({ item, model }),
215
- onUpdateData: ({ dataKeyByKeyId }) => this.onUpdateDataLocal({ item, dataKeyByKeyId }),
216
- ...item,
217
- classColumn: undefined,
218
- ...this.attributesToExcludeFromRender,
219
- }, this.$slots);
208
+ }, [
209
+ h(this.componentTypesMapping[item.type], {
210
+ key: itemIndex,
211
+ modelValue: IS_CONTAINER ? this.modelValue : get(this.modelValue, item.id),
212
+ modelDependencies: IS_CONTAINER ? this.modelValue : undefined,
213
+ errors: this.errorsAll[item.id],
214
+ errorsAll: this.errorsAll,
215
+ idPrefix: this.idPrefix,
216
+ "onUpdate:modelValue": model => this.onUpdateModelLocal({ item, model }),
217
+ onUpdateData: ({ dataKeyByKeyId }) => this.onUpdateDataLocal({ item, dataKeyByKeyId }),
218
+ ...item,
219
+ classColumn: undefined,
220
+ slotAppend: undefined,
221
+ ...this.attributesToExcludeFromRender,
222
+ }, this.$slots),
223
+ (item.slotAppend && this.$slots[item.slotAppend]) ?
224
+ this.$slots[item.slotAppend]({ item, itemIndex }) :
225
+ "",
226
+ ]);
220
227
  }),
221
228
  this.slotName &&
222
229
  this.$slots[this.slotName] &&
@@ -72,10 +72,9 @@ export default {
72
72
  required: false,
73
73
  default: () => {},
74
74
  },
75
- classColumn: {
76
- type: String,
75
+ class: {
76
+ type: [String, Object],
77
77
  required: false,
78
- default: undefined,
79
78
  },
80
79
  countMultiselect: {
81
80
  type: Number,
@@ -615,6 +614,7 @@ export default {
615
614
  }
616
615
 
617
616
  return h("div", {
617
+ class: this.class,
618
618
  style: this.componentStyleHide,
619
619
  ...this.attributesToExcludeFromRender,
620
620
  }, [