@itfin/components 1.4.28 → 1.4.33

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 (40) hide show
  1. package/libs/air-datepicker/air-datepicker.js +1 -1
  2. package/package.json +1 -1
  3. package/src/components/app/App.vue +3 -6
  4. package/src/components/checkbox/Checkbox.vue +1 -1
  5. package/src/components/checkbox/RadioBox.vue +6 -13
  6. package/src/components/customize/PropertyItem.vue +13 -5
  7. package/src/components/datepicker/DatePickerInline.vue +129 -62
  8. package/src/components/filter/FilterPanel.vue +37 -16
  9. package/src/components/icon/components/nomi-.DS_Store +0 -0
  10. package/src/components/icon/components/nomi-arrow_left.vue +4 -0
  11. package/src/components/icon/components/nomi-balance_turnover.vue +5 -0
  12. package/src/components/icon/components/nomi-bar-horizontal.vue +7 -0
  13. package/src/components/icon/components/nomi-chart-funnel.vue +6 -0
  14. package/src/components/icon/components/nomi-chart-kpi.vue +8 -0
  15. package/src/components/icon/components/nomi-check-alt.vue +4 -0
  16. package/src/components/icon/components/nomi-control-panel.vue +8 -0
  17. package/src/components/icon/components/nomi-credit.vue +4 -0
  18. package/src/components/icon/components/nomi-goods-turnover.vue +4 -0
  19. package/src/components/icon/components/nomi-goods.vue +5 -0
  20. package/src/components/icon/components/nomi-help-alt.vue +4 -0
  21. package/src/components/icon/components/nomi-link.vue +6 -0
  22. package/src/components/icon/components/nomi-menu.vue +3 -3
  23. package/src/components/icon/components/nomi-minus.vue +1 -1
  24. package/src/components/icon/components/nomi-pc.vue +4 -0
  25. package/src/components/icon/components/nomi-promo.vue +4 -0
  26. package/src/components/icon/components/nomi-transactions_delete.vue +5 -0
  27. package/src/components/icon/components/nomi-types.vue +7 -0
  28. package/src/components/icon/components/nomi-warning_triangle.vue +6 -0
  29. package/src/components/panels/PanelItemEdit.vue +6 -8
  30. package/src/components/panels/PanelLink.vue +6 -15
  31. package/src/components/panels/PanelList.vue +7 -3
  32. package/src/components/panels/helpers.ts +10 -4
  33. package/src/components/table/Table2.vue +65 -61
  34. package/src/components/table/TableBody.vue +6 -0
  35. package/src/components/table/TableGroup.vue +14 -4
  36. package/src/components/table/TableHeader.vue +12 -7
  37. package/src/components/table/TableRowToggle.vue +9 -1
  38. package/src/components/table/TableRows.vue +55 -43
  39. package/src/components/table/table2.scss +15 -25
  40. package/src/components/view/View.vue +15 -8
@@ -1,19 +1,19 @@
1
1
  <template>
2
- <div v-loading="loading" class="px-3 pt-2 h-100 d-flex flex-column">
2
+ <div v-loading="loading" class="px-3 pt-2 h-100">
3
3
  <itf-form
4
4
  ref="editForm"
5
- class="d-flex flex-column justify-content-between flex-grow-1"
5
+ class="d-flex flex-column justify-content-between h-100"
6
6
  @keydown.native.shift.enter.stop.prevent="onSaveClick"
7
7
  @keydown.native.esc.stop.prevent="$emit('cancel')"
8
8
  >
9
9
  <slot></slot>
10
10
  <div class="py-3 justify-content-end d-flex align-items-center sticky-container">
11
11
  <div v-if="!hideFooter">
12
- <itf-button v-tooltip.delay="'Hot key: Esc'" secondary squircle :loading="loading" :disabled="loading" @click="$emit('cancel')">
13
- <span>{{ cancelBtnText }}</span>
12
+ <itf-button v-tooltip.delay="'Hot key: Esc'" secondary :loading="loading" :disabled="loading" @click="$emit('cancel')">
13
+ <span>{{ $t('components.modal.cancel') }}</span>
14
14
  </itf-button>
15
- <itf-button v-tooltip.delay="'Hot key: Shift + Enter'" primary squircle :loading="loading" :disabled="loading" @click="onSaveClick">
16
- <span>{{ saveBtnText }}</span>
15
+ <itf-button v-tooltip.delay="'Hot key: Shift + Enter'" primary :loading="loading" :disabled="loading" @click="onSaveClick">
16
+ <span>{{ $t('components.modal.save') }}</span>
17
17
  </itf-button>
18
18
  </div>
19
19
  </div>
@@ -51,8 +51,6 @@ import itfButton from '../button/Button.vue';
51
51
  export default class PanelItemEdit extends Vue {
52
52
  @Prop(Boolean) loading;
53
53
  @Prop(Boolean) hideFooter;
54
- @Prop({ type: String, default: function() { return this.$t('components.modal.save') } }) saveBtnText;
55
- @Prop({ type: String, default: function() { return this.$t('components.modal.cancel') } }) cancelBtnText;
56
54
 
57
55
  onSaveClick() {
58
56
  if (this.$refs.editForm && !this.$refs.editForm.doValidation()) {
@@ -5,7 +5,6 @@
5
5
  import { Vue, Component, Inject, Prop } from 'vue-property-decorator';
6
6
  import { IPanel } from './PanelList.vue';
7
7
  import {stackToHash} from "@itfin/components/src/components/panels/helpers";
8
- import {getRootPanelList} from "@itfin/components/src/components/panels";
9
8
 
10
9
  @Component({
11
10
  components: {
@@ -16,6 +15,7 @@ import {getRootPanelList} from "@itfin/components/src/components/panels";
16
15
  }
17
16
  })
18
17
  export default class PanelLink extends Vue {
18
+ @Inject({ default: null }) panelList;
19
19
  @Inject({ default: null }) currentPanel;
20
20
 
21
21
  @Prop(Boolean) global: boolean;
@@ -25,7 +25,6 @@ export default class PanelLink extends Vue {
25
25
  @Prop() list;
26
26
  @Prop({ type: String, default: 'active' }) activeClass: string;
27
27
  @Prop(Boolean) append: boolean;
28
- @Prop(Boolean) replace: boolean;
29
28
 
30
29
  get on() {
31
30
  const handlers = {};
@@ -36,7 +35,7 @@ export default class PanelLink extends Vue {
36
35
  }
37
36
 
38
37
  get activeList() {
39
- return this.list ?? getRootPanelList();
38
+ return this.list ?? this.panelList;
40
39
  }
41
40
 
42
41
  get isActive() {
@@ -52,9 +51,6 @@ export default class PanelLink extends Vue {
52
51
  if (!this.append) {
53
52
  stack = stack.splice(0, this.currentPanel?.index + 1);
54
53
  }
55
- if (this.replace) {
56
- stack = [];
57
- }
58
54
  const hash = stackToHash([
59
55
  ...stack,
60
56
  {
@@ -66,18 +62,13 @@ export default class PanelLink extends Vue {
66
62
  }
67
63
 
68
64
  onClick(e) {
69
- e.preventDefault();
70
- e.stopPropagation();
71
- const index = this.replace ? 0 : (this.append ? undefined : this.currentPanel?.index + 1);
72
- this.$emit('open', {
73
- panel: this.panel,
74
- payload: this.payload || {},
75
- index
76
- });
65
+ console.info(this.activeList);
77
66
  if (!this.activeList) {
78
67
  return;
79
68
  }
80
- this.activeList.openPanel(this.panel, this.payload || {}, index);
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ this.activeList.openPanel(this.panel, this.payload || {}, this.append ? undefined : this.currentPanel?.index + 1);
81
72
  }
82
73
  }
83
74
  </script>
@@ -218,6 +218,7 @@ export default class PanelList extends Vue {
218
218
  @Prop() panels: Record<string, Component>;
219
219
  @Prop({ default: () => {} }) searchPanel: (type: string) => boolean;
220
220
  @Prop({ type: String, default: 'path' }) routeType: string;
221
+ @Prop({ type: String, default: '' }) routePrefix: string;
221
222
 
222
223
  panelsStack:IPanel[] = [];
223
224
 
@@ -228,6 +229,7 @@ export default class PanelList extends Vue {
228
229
  if (this.firstPanel) {
229
230
  this.internalOpenPanel(this.firstPanel.type, this.firstPanel.payload);
230
231
  }
232
+ console.info('created');
231
233
  this.parsePanelHash(); // щоб панелі змінювались при перезавантаженні
232
234
  window.addEventListener('popstate', this.handlePopState); // щоб панелі змінювались при навігації
233
235
  }
@@ -466,9 +468,9 @@ export default class PanelList extends Vue {
466
468
  }
467
469
 
468
470
  setPanelHash() {
469
- const hash = stackToHash(this.panelsStack, this.routeType === 'path').replace(/^#/, '');
471
+ const hash = stackToHash(this.panelsStack, this.routePrefix).replace(/^#/, '');
470
472
  if (this.routeType === 'path') {
471
- this.$router.push({ path: `/${hash}` });
473
+ this.$router.push({ path: hash });
472
474
  } else {
473
475
  this.$router.push({ hash });
474
476
  }
@@ -478,7 +480,7 @@ export default class PanelList extends Vue {
478
480
  async parsePanelHash() {
479
481
  const hash = this.routeType === 'path' ? location.pathname : location.hash;
480
482
  if (hash) {
481
- const panels = hashToStack(hash, this.routeType === 'path');
483
+ const panels = hashToStack(hash, this.routePrefix);
482
484
  const newStack = [];
483
485
  this.panelsStack = [];
484
486
  for (const panelIndex in panels) {
@@ -498,12 +500,14 @@ export default class PanelList extends Vue {
498
500
  }
499
501
  }
500
502
  this.panelsStack = newStack;
503
+ console.info('set', newStack);
501
504
  this.emitEvent('panels.changed', this.panelsStack);
502
505
  this.updateTitle();
503
506
  }
504
507
  }
505
508
 
506
509
  handlePopState() {
510
+ console.info('handlePopState')
507
511
  this.parsePanelHash();
508
512
  // виправляє проблему відкритої панелі при натисканні кнопки "назад" до першої панелі
509
513
  if (this.panelsStack.length === 2) {
@@ -10,19 +10,25 @@ export interface IPanel {
10
10
  const COLLAPSE_SYMBOL = '~'
11
11
  const PARAMS_SYMBOL = ';'
12
12
 
13
- export function stackToHash(stack: IPanel[]) {
14
- const hash = stack.map(panel => {
13
+ export function stackToHash(stack: IPanel[], prefix: string = '') {
14
+ let hash = stack.map(panel => {
15
15
  let json = JSON5.stringify(panel.payload || {});
16
16
  json = json.substring(1, json.length - 1); // Remove the outer {}
17
17
  return `${panel.type}${panel.isCollapsed ? COLLAPSE_SYMBOL : ''}${json ? PARAMS_SYMBOL : ''}${json}`;
18
18
  }).join(isPathType() ? '/' : '&');
19
+ if (prefix) {
20
+ hash = `${prefix}/${hash}`;
21
+ }
19
22
  return isPathType() ? `/${hash}` : `#${hash}`;
20
23
  }
21
24
 
22
25
 
23
- export function hashToStack(hash: string|undefined): IPanel[] {
26
+ export function hashToStack(hash: string|undefined, prefix: string = ''): IPanel[] {
24
27
  let stack:IPanel[] = [];
25
- const str = hash.replace(isPathType() ? /^\// : /^#/, '');
28
+ let str = hash.replace(isPathType() ? /^\// : /^#/, '');
29
+ if (str && prefix) {
30
+ str = str.replace(new RegExp(`^${prefix}\/?`), '');
31
+ }
26
32
  if (str) {
27
33
  stack = str.split(isPathType() ? '/' : '&').map(item => {
28
34
  if (!item.includes(PARAMS_SYMBOL)) {
@@ -7,11 +7,9 @@
7
7
  'permanent-checkboxes': selectedIds.length
8
8
  }" :style="{ '--indicator-area-width': `${indicatorType === 'none' ? 1 : indicatorWidth}px`, '--shadow-area-width': `${shadowWidth}px` }">
9
9
  <itf-notice-popout :visible="showGroupOperations" class="rounded-3 bg-black text-white">
10
- <div class="d-flex gap-2 ps-2 align-items-center small itf-table2_mass-operations">
11
- <slot name="group-operations-count">
12
- <div>{{$tc('components.table.selectedItems', selectedIds.length, { n: selectedIds.length })}}</div>
13
- <div class="opacity-50">•</div>
14
- </slot>
10
+ <div class="d-flex gap-2 ps-3 align-items-center small itf-table2_mass-operations">
11
+ <div>{{$tc('components.table.selectedItems', selectedIds.length, { n: selectedIds.length })}}</div>
12
+ <div class="opacity-50">•</div>
15
13
  <a href="" class="me-3 opacity-50 text-white text-decoration-none" @click.stop.prevent="selectedIds = []">{{$t('components.table.cancelSelected')}}</a>
16
14
  <div>
17
15
  <slot name="group-operations"></slot>
@@ -19,61 +17,64 @@
19
17
  </div>
20
18
  </itf-notice-popout>
21
19
  <div class="scrollable scrollable-x">
22
- <itf-checkbox-group v-model="selectedIds">
23
- <template v-for="(group, index) in groups">
24
- <div class="table-view-body">
25
- <itf-table-group
26
- :key="index"
27
- @update="$emit('update', { ...$event, group, groupIndex: index })"
28
- @row-click="$emit('row-click', $event)"
29
- :id-property="idProperty"
30
- :columns="columns"
31
- @update:columns="onColumnsUpdate"
32
- :rows="group.rows"
33
- :title="group.name"
34
- :selected-ids.sync="selectedIds"
35
- :add-new-rows="addNewRows"
36
- :shadow-width="shadowWidth"
37
- :column-sorting="columnSorting"
38
- :column-resizing="columnResizing"
39
- :show-grouping="showGrouping"
40
- :show-summary="showSummary"
41
- :show-add-column="showAddColumn"
42
- :show-actions="showActions"
43
- :show-header="!noHeader"
44
- :schema="schema"
45
- :editable="editable"
46
- :no-column-menu="noColumnMenu"
47
- :no-select-all="noSelectAll"
48
- :currencies="currencies"
49
- :currency="currency"
50
- :subrows-property="subrowsProperty"
51
- :divider-property="dividerProperty"
52
- :indicator-type="indicatorType"
53
- :expanded-all="expandedAll"
54
- :indicatorWidth="indicatorWidth"
55
- :striped="striped"
56
- :expanded-ids="expandedIds"
57
- :css-property="cssProperty"
58
- :sticky-header="stickyHeader"
59
- :editable-property="editableProperty"
60
- :sorting.sync="_sorting"
61
- :active="active"
62
- @update:expanded-ids="$emit('update:expanded-ids', $event)"
63
- @new="$emit('new', $event)"
64
- @filter="$emit('filter', $event)"
65
- @add-column="$emit('add-column', $event)"
66
- >
67
- <template v-for="(_, name) in $slots" #[name]="slotData">
68
- <slot :name="name" v-bind="slotData || {}" />
69
- </template>
70
- <template v-for="(_, name) in $scopedSlots" #[name]="slotData">
71
- <slot :name="name" v-bind="slotData || {}" />
72
- </template>
73
- </itf-table-group>
74
- </div>
75
- </template>
76
- </itf-checkbox-group>
20
+ <itf-checkbox-group v-model="selectedIds">
21
+ <template v-for="(group, index) in groups">
22
+ <div class="table-view-body">
23
+ <itf-table-group
24
+ :key="index"
25
+ @update="$emit('update', { ...$event, group, groupIndex: index })"
26
+ @row-click="$emit('row-click', $event)"
27
+ :id-property="idProperty"
28
+ :columns="columns"
29
+ @update:columns="onColumnsUpdate"
30
+ :rows="group.rows"
31
+ :title="group.name"
32
+ :selected-ids.sync="selectedIds"
33
+ :add-new-rows="addNewRows"
34
+ :shadow-width="shadowWidth"
35
+ :column-sorting="columnSorting"
36
+ :column-resizing="columnResizing"
37
+ :show-grouping="showGrouping"
38
+ :show-summary="showSummary"
39
+ :show-add-column="showAddColumn"
40
+ :show-actions="showActions"
41
+ :show-header="!noHeader"
42
+ :schema="schema"
43
+ :editable="editable"
44
+ :no-column-menu="noColumnMenu"
45
+ :no-select-all="noSelectAll"
46
+ :currencies="currencies"
47
+ :currency="currency"
48
+ :subrows-property="subrowsProperty"
49
+ :async-subrows-property="asyncSubrowsProperty"
50
+ :divider-property="dividerProperty"
51
+ :indicator-type="indicatorType"
52
+ :expanded-all="expandedAll"
53
+ :indicatorWidth="indicatorWidth"
54
+ :striped="striped"
55
+ :expanded-ids="expandedIds"
56
+ :css-property="cssProperty"
57
+ :sticky-header="stickyHeader"
58
+ :editable-property="editableProperty"
59
+ :sorting.sync="_sorting"
60
+ :sort-as-string="sortAsString"
61
+ :active="active"
62
+ @loadChildren="$emit('loadChildren', $event)"
63
+ @update:expanded-ids="$emit('update:expanded-ids', $event)"
64
+ @new="$emit('new', $event)"
65
+ @filter="$emit('filter', $event)"
66
+ @add-column="$emit('add-column', $event)"
67
+ >
68
+ <template v-for="(_, name) in $slots" #[name]="slotData">
69
+ <slot :name="name" v-bind="slotData || {}" />
70
+ </template>
71
+ <template v-for="(_, name) in $scopedSlots" #[name]="slotData">
72
+ <slot :name="name" v-bind="slotData || {}" />
73
+ </template>
74
+ </itf-table-group>
75
+ </div>
76
+ </template>
77
+ </itf-checkbox-group>
77
78
  </div>
78
79
  </div>
79
80
 
@@ -104,11 +105,13 @@ export default @Component({
104
105
  })
105
106
  class itfTable2 extends Vue {
106
107
  // @Prop({ required: true, type: Array }) columns;
108
+ @Prop(Boolean) sortAsString;
107
109
  @Prop({ required: true, type: Array }) rows;
108
110
  @Prop({ type: String, default: null }) groupBy;
109
111
  @Prop({ type: String, default: null }) idProperty;
110
112
  @Prop({ type: String, default: null }) cssProperty;
111
113
  @Prop({ type: String, default: null }) subrowsProperty;
114
+ @Prop({ type: String, default: null }) asyncSubrowsProperty;
112
115
  @Prop({ type: String, default: null }) dividerProperty;
113
116
  @Prop({ type: String, default: null }) editableProperty;
114
117
  @Prop({ default: null }) active;
@@ -244,7 +247,8 @@ class itfTable2 extends Vue {
244
247
  @Watch('selectedIds')
245
248
  onSelectedIdsUpdate(selectedIds) {
246
249
  this.state.selectedIds = selectedIds;
247
- this.saveTableState();
250
+ // метод saveTableState не зберігає selectedIds в localStorage, не впевнений що він тут треба
251
+ // this.saveTableState();
248
252
  }
249
253
 
250
254
  onColumnsUpdate(columns) {
@@ -7,6 +7,7 @@
7
7
  :columns="columns"
8
8
  :id-property="idProperty"
9
9
  :subrows-property="subrowsProperty"
10
+ :async-subrows-property="asyncSubrowsProperty"
10
11
  :divider-property="dividerProperty"
11
12
  :show-add-column="showAddColumn"
12
13
  :show-actions="showActions"
@@ -144,6 +145,7 @@ class itfTableBody extends Vue {
144
145
  @Prop() rows;
145
146
  @Prop() idProperty;
146
147
  @Prop() subrowsProperty;
148
+ @Prop() asyncSubrowsProperty;
147
149
  @Prop() dividerProperty;
148
150
  @Prop() active;
149
151
  @Prop(Boolean) showAddColumn;
@@ -164,6 +166,10 @@ class itfTableBody extends Vue {
164
166
  this.$emit('update:expanded-ids', this.expandedIds.includes(item[this.idProperty])
165
167
  ? this.expandedIds.filter((id) => id !== item[this.idProperty])
166
168
  : [...this.expandedIds, item[this.idProperty]]);
169
+
170
+ if (this.asyncSubrowsProperty && item[this.asyncSubrowsProperty] && item[this.asyncSubrowsProperty]) {
171
+ this.$emit('loadChildren', item);
172
+ }
167
173
  }
168
174
  }
169
175
  </script>
@@ -17,7 +17,7 @@
17
17
  <div class="shadow-area"></div>
18
18
  <div class="header-wrapper" :class="{'header-additional-column': showAddColumn}" @click.prevent="toggleGroup">
19
19
  <a class="header-content position-sticky d-flex align-items-center">
20
- <itf-button squircle icon small secondary class="collapse-arrow">
20
+ <itf-button icon small secondary class="collapse-arrow">
21
21
  <itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'"/>
22
22
  </itf-button>
23
23
  <span class="d-flex align-items-center line-overflow group-header-value text-primary"
@@ -39,6 +39,7 @@
39
39
  :show-add-column="showAddColumn"
40
40
  :show-actions="showActions"
41
41
  :id-property="idProperty"
42
+ :sort-as-string="sortAsString"
42
43
  :rows="rows"
43
44
  :schema="schema"
44
45
  :editable="editable"
@@ -61,11 +62,13 @@
61
62
  @row-click="$emit('row-click', $event)"
62
63
  :id-property="idProperty"
63
64
  :subrows-property="subrowsProperty"
65
+ :async-subrows-property="asyncSubrowsProperty"
64
66
  :divider-property="dividerProperty"
65
67
  :rows="rows"
66
68
  :editable="editable"
67
69
  :currency="currency"
68
70
  :currencies="currencies"
71
+ :sort-as-string="sortAsString"
69
72
  :columns="visibleColumns"
70
73
  :no-select-all="noSelectAll"
71
74
  :selected-ids="selectedIds"
@@ -78,6 +81,7 @@
78
81
  :css-property="cssProperty"
79
82
  :editable-property="editableProperty"
80
83
  :active="active"
84
+ @loadChildren="$emit('loadChildren', $event)"
81
85
  @update:expanded-ids="$emit('update:expanded-ids', $event)"
82
86
  >
83
87
  <template v-for="(_, name) in $slots" #[name]="slotData">
@@ -91,11 +95,11 @@
91
95
 
92
96
  <!-- Лінія додати нову -->
93
97
  <div v-if="isShowTable && addNewRows"
94
- class="table-row-template d-flex align-items-stretch">
98
+ class="table-row-template table-row-template__new-row d-flex align-items-stretch">
95
99
  <div class="shadow-area"></div>
96
100
  <a href="" @click.prevent="$emit('new', title)" data-test="table-add-new-item"
97
101
  class="d-flex align-items-center flex-grow-1 table-add-new-item text-decoration-none">
98
- <span class="d-sticky d-flex align-items-center py-1">
102
+ <span class="d-sticky d-flex align-items-center py-1 px-2 small">
99
103
  <itf-icon name="plus"/>
100
104
  <span>{{ newLabel }}</span>
101
105
  </span>
@@ -264,7 +268,11 @@
264
268
  min-height: var(--table-small-row-size);
265
269
  }
266
270
 
271
+ .table-row-template.table-row-template__new-row {
272
+ min-height: 2rem;
273
+ }
267
274
  .table-add-new-item {
275
+ background-color: var(--itf-table-header-bg);
268
276
  border-right:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
269
277
  border-left:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
270
278
  border-bottom: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
@@ -273,7 +281,7 @@
273
281
  border-bottom-right-radius: var(--itf-table-table-border-radius);
274
282
 
275
283
  & > span {
276
- left: var(--shadow-area-width);
284
+ left: calc(var(--shadow-area-width) + 4px);
277
285
  position: sticky;
278
286
  padding-left: var(--shadow-area-width);
279
287
  //border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
@@ -359,6 +367,7 @@ class itfTableGroup extends Vue {
359
367
  @Prop() title;
360
368
  @Prop() idProperty;
361
369
  @Prop() subrowsProperty;
370
+ @Prop() asyncSubrowsProperty;
362
371
  @Prop() dividerProperty;
363
372
  @Prop() currency;
364
373
  @Prop() currencies;
@@ -378,6 +387,7 @@ class itfTableGroup extends Vue {
378
387
  @Prop(Boolean) expandedAll;
379
388
  @Prop(Boolean) striped;
380
389
  @Prop(Boolean) stickyHeader;
390
+ @Prop(Boolean) sortAsString;
381
391
  @Prop() indicatorWidth;
382
392
  @Prop() shadowWidth;
383
393
  @Prop() cssProperty;
@@ -4,8 +4,8 @@
4
4
  <div ref="container" class="table-row-template">
5
5
  <div accept-group="items" class="table-view-body-space" v-dropzone="{ payload: 0 }"></div>
6
6
  <div class="shadow-area"></div>
7
- <div class="table-view-header-value reserved sticky">
8
- <itf-checkbox v-if="indicatorType === 'checkbox' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
7
+ <div v-if="indicatorType !== 'none'" class="table-view-header-value reserved sticky">
8
+ <itf-checkbox v-if="indicatorType !== 'none' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
9
9
  </div>
10
10
 
11
11
  <template v-for="(column, n) in visibleAttributes">
@@ -29,14 +29,16 @@
29
29
  <div v-if="visibleHeader" group="tablecolumns"
30
30
  class="table-header"
31
31
  @drop="reorderColumns"
32
- v-draggable="{ handle: true, payload: { index: n, item: column }, mirror: {yAxis:false} }">
32
+ v-draggable="{ dragHandleClass: null, handle: true, payload: { index: n, item: column }, mirror: {yAxis:false} }">
33
33
  <itf-dropdown text append-to-body shadow ref="dropdown" class="w-100" :disabled="noColumnMenu">
34
34
  <template #button>
35
35
  <div class="itf-table2__header-title d-flex w-100 align-items-center" :title="getTitle(column.title)">
36
36
  <itf-icon class="itf-table2__header-icon" new v-if="column.icon" :name="column.icon"></itf-icon>
37
37
  <div class="flex-grow-1 w-100 itf-table2__title-container d-flex align-items-center" :class="{'justify-content-end': column.align === 'end'}">
38
- <div class="itf-table2__title text-truncate">{{getTitle(column.title)}}</div>
39
- <div v-if="column.prefix" class="itf-table2__subtitle text-truncate" v-text="column.prefix" />
38
+ <div class="itf-table2__title text-truncate">
39
+ {{getTitle(column.title)}}
40
+ <div v-if="column.prefix" class="itf-table2__subtitle text-truncate" :class="{'text-end': column.align === 'end'}" v-text="column.prefix" />
41
+ </div>
40
42
  </div>
41
43
  </div>
42
44
  <itf-icon v-if="sortColumnParams[column.property]" :name="sortColumnParams[column.property] === 'asc' ? 'sort-asc' : 'sort-desc'" new :size="20" class="ms-1" />
@@ -194,6 +196,7 @@ class itfTableHeader extends Vue {
194
196
  @Prop(Boolean) noColumnMenu;
195
197
  @Prop(Boolean) noSelectAll;
196
198
  @Prop(Boolean) editable;
199
+ @Prop(Boolean) sortAsString;
197
200
  @Prop() idProperty;
198
201
  @Prop() indicatorType;
199
202
 
@@ -411,8 +414,10 @@ class itfTableHeader extends Vue {
411
414
  }
412
415
 
413
416
  sortBy(column, order) {
414
- let sort = order === 'desc' ? `-${column.property}` : column.property;
415
- console.info(sort);
417
+ let sort = { [column.property]: order };
418
+ if (this.sortAsString) {
419
+ sort = order === 'desc' ? `-${column.property}` : column.property;
420
+ }
416
421
  this.$emit('update:sorting', sort);
417
422
  }
418
423
  }
@@ -2,7 +2,10 @@
2
2
  <div>
3
3
  <div @click.prevent.stop="toggle" class="d-flex align-items-center flex-nowrap" :class="{'active-toggle': visible}">
4
4
  <div class="item-toggle text-muted">
5
- <template v-if="visible && expanded">
5
+ <template v-if="visible && loading">
6
+ <div class="itf-spinner"></div>
7
+ </template>
8
+ <template v-else-if="visible && expanded">
6
9
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
7
10
  width="16" height="16" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
8
11
  <path d="M184.7,413.1l2.1-1.8l156.5-136c5.3-4.6,8.6-11.5,8.6-19.2c0-7.7-3.4-14.6-8.6-19.2L187.1,101l-2.6-2.3
@@ -23,6 +26,10 @@
23
26
  </div>
24
27
  </template>
25
28
  <style lang="scss" scoped>
29
+ .itf-spinner {
30
+ width: 1rem;
31
+ height: 1rem;
32
+ }
26
33
  .active-toggle {
27
34
  cursor: pointer;
28
35
  }
@@ -43,6 +50,7 @@ export default @Component({
43
50
  class itfTableRowToggle extends Vue {
44
51
  @Prop(Boolean) expanded;
45
52
  @Prop(Boolean) visible;
53
+ @Prop(Boolean) loading;
46
54
 
47
55
  toggle() {
48
56
  this.$emit('toggle');