@itfin/components 1.3.100 → 1.4.0

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 (151) hide show
  1. package/package.json +1 -1
  2. package/src/components/button/Button.vue +4 -2
  3. package/src/components/card/BentoCard.vue +70 -19
  4. package/src/components/card/BentoGrid.vue +21 -8
  5. package/src/components/filter/FilterAmountRange.vue +50 -42
  6. package/src/components/filter/FilterBadge.vue +27 -22
  7. package/src/components/filter/FilterFacetsList.vue +21 -17
  8. package/src/components/filter/FilterPanel.vue +141 -44
  9. package/src/components/filter/index.stories.js +0 -2
  10. package/src/components/form/Label.vue +19 -2
  11. package/src/components/icon/Icon.vue +4 -2
  12. package/src/components/icon/components/fi_fingerprint.vue +4 -0
  13. package/src/components/icon/components/nomi-ai.vue +6 -0
  14. package/src/components/icon/components/nomi-arrow-down.vue +4 -0
  15. package/src/components/icon/components/nomi-arrow-right-top.vue +4 -0
  16. package/src/components/icon/components/nomi-arrow-up.vue +4 -0
  17. package/src/components/icon/components/nomi-arrow_down.vue +4 -0
  18. package/src/components/icon/components/nomi-arrow_up.vue +4 -0
  19. package/src/components/icon/components/nomi-arrows.vue +7 -0
  20. package/src/components/icon/components/nomi-calendar-alt.vue +4 -0
  21. package/src/components/icon/components/nomi-calendar-alt2.vue +4 -0
  22. package/src/components/icon/components/nomi-calendar.vue +11 -0
  23. package/src/components/icon/components/nomi-card.vue +4 -0
  24. package/src/components/icon/components/nomi-clear.vue +4 -0
  25. package/src/components/icon/components/nomi-close.vue +5 -0
  26. package/src/components/icon/components/nomi-counterparty.vue +4 -0
  27. package/src/components/icon/components/nomi-dashboard.vue +4 -0
  28. package/src/components/icon/components/nomi-expand.vue +7 -0
  29. package/src/components/icon/components/nomi-eye-close.vue +4 -0
  30. package/src/components/icon/components/nomi-eye-open.vue +4 -0
  31. package/src/components/icon/components/nomi-eye.vue +4 -0
  32. package/src/components/icon/components/nomi-filter.vue +4 -0
  33. package/src/components/icon/components/nomi-help.vue +5 -0
  34. package/src/components/icon/components/nomi-hide.vue +4 -0
  35. package/src/components/icon/components/nomi-logout.vue +5 -0
  36. package/src/components/icon/components/nomi-money.vue +4 -0
  37. package/src/components/icon/components/nomi-move-left.vue +4 -0
  38. package/src/components/icon/components/nomi-move-right.vue +4 -0
  39. package/src/components/icon/components/nomi-pen.vue +5 -0
  40. package/src/components/icon/components/nomi-person.vue +5 -0
  41. package/src/components/icon/components/nomi-pin.vue +7 -0
  42. package/src/components/icon/components/nomi-project.vue +4 -0
  43. package/src/components/icon/components/nomi-recurrence.vue +2 -0
  44. package/src/components/icon/components/nomi-repeat.vue +7 -0
  45. package/src/components/icon/components/nomi-report.vue +4 -0
  46. package/src/components/icon/components/nomi-scissors.vue +4 -0
  47. package/src/components/icon/components/nomi-settings.vue +4 -0
  48. package/src/components/icon/components/nomi-sort-asc.vue +7 -0
  49. package/src/components/icon/components/nomi-sort-desc.vue +7 -0
  50. package/src/components/icon/components/nomi-table-view.vue +4 -0
  51. package/src/components/icon/components/nomi-tag.vue +4 -0
  52. package/src/components/icon/components/nomi-target.vue +4 -0
  53. package/src/components/icon/components/nomi-text.vue +6 -0
  54. package/src/components/icon/components/nomi-transactions.vue +8 -0
  55. package/src/components/icon/components/nomi-trash.vue +4 -0
  56. package/src/components/icon/components/nomi-unpin.vue +7 -0
  57. package/src/components/icon/components/nomi-user.vue +5 -0
  58. package/src/components/icon/convert-icons.js +11 -0
  59. package/src/components/icon/icons.js +332 -286
  60. package/src/components/icon/new-icons/ai.svg +5 -0
  61. package/src/components/icon/new-icons/arrow-down.svg +3 -0
  62. package/src/components/icon/new-icons/arrow-right-top.svg +3 -0
  63. package/src/components/icon/new-icons/arrow-up.svg +3 -0
  64. package/src/components/icon/new-icons/arrow_down.svg +3 -0
  65. package/src/components/icon/new-icons/arrow_up.svg +3 -0
  66. package/src/components/icon/new-icons/arrows.svg +6 -0
  67. package/src/components/icon/new-icons/calendar-alt.svg +3 -0
  68. package/src/components/icon/new-icons/calendar-alt2.svg +3 -0
  69. package/src/components/icon/new-icons/calendar.svg +10 -0
  70. package/src/components/icon/new-icons/card.svg +3 -0
  71. package/src/components/icon/new-icons/clear.svg +3 -0
  72. package/src/components/icon/new-icons/close.svg +4 -0
  73. package/src/components/icon/new-icons/counterparty.svg +3 -0
  74. package/src/components/icon/new-icons/dashboard.svg +3 -0
  75. package/src/components/icon/new-icons/expand.svg +6 -0
  76. package/src/components/icon/new-icons/eye-close.svg +3 -0
  77. package/src/components/icon/new-icons/eye-open.svg +3 -0
  78. package/src/components/icon/new-icons/eye.svg +3 -0
  79. package/src/components/icon/new-icons/filter.svg +3 -0
  80. package/src/components/icon/new-icons/help.svg +4 -0
  81. package/src/components/icon/new-icons/hide.svg +3 -0
  82. package/src/components/icon/new-icons/logout.svg +4 -0
  83. package/src/components/icon/new-icons/money.svg +3 -0
  84. package/src/components/icon/new-icons/move-left.svg +3 -0
  85. package/src/components/icon/new-icons/move-right.svg +3 -0
  86. package/src/components/icon/new-icons/pen.svg +4 -0
  87. package/src/components/icon/new-icons/person.svg +4 -0
  88. package/src/components/icon/new-icons/pin.svg +6 -0
  89. package/src/components/icon/new-icons/project.svg +3 -0
  90. package/src/components/icon/new-icons/recurrence.svg +1 -0
  91. package/src/components/icon/new-icons/repeat.svg +6 -0
  92. package/src/components/icon/new-icons/report.svg +3 -0
  93. package/src/components/icon/new-icons/scissors.svg +3 -0
  94. package/src/components/icon/new-icons/settings.svg +3 -0
  95. package/src/components/icon/new-icons/sort-asc.svg +6 -0
  96. package/src/components/icon/new-icons/sort-desc.svg +6 -0
  97. package/src/components/icon/new-icons/table-view.svg +3 -0
  98. package/src/components/icon/new-icons/tag.svg +3 -0
  99. package/src/components/icon/new-icons/target.svg +3 -0
  100. package/src/components/icon/new-icons/text.svg +5 -0
  101. package/src/components/icon/new-icons/transactions.svg +7 -0
  102. package/src/components/icon/new-icons/trash.svg +3 -0
  103. package/src/components/icon/new-icons/unpin.svg +6 -0
  104. package/src/components/icon/new-icons/user.svg +4 -0
  105. package/src/components/modal/DeleteConfirmModal.vue +0 -2
  106. package/src/components/modal/ItemEditor.vue +1 -5
  107. package/src/components/pagination/Pagination.vue +3 -2
  108. package/src/components/pagination/Pagination2.vue +179 -0
  109. package/src/components/panels/Panel.vue +23 -7
  110. package/src/components/panels/PanelItemEdit.vue +62 -0
  111. package/src/components/panels/PanelLink.vue +26 -6
  112. package/src/components/panels/PanelList.vue +27 -26
  113. package/src/components/panels/helpers.spec.ts +27 -0
  114. package/src/components/panels/helpers.ts +37 -0
  115. package/src/components/popover/NoticePopout.vue +1 -1
  116. package/src/components/select/Select.vue +1 -1
  117. package/src/components/sortable/draggable.js +2 -1
  118. package/src/components/table/Table2.vue +35 -8
  119. package/src/components/table/TableBody.vue +10 -18
  120. package/src/components/table/TableGroup.vue +29 -13
  121. package/src/components/table/TableHeader.vue +120 -69
  122. package/src/components/table/TableRowToggle.vue +51 -0
  123. package/src/components/table/TableRows.vue +20 -29
  124. package/src/components/table/index.stories.js +22 -200
  125. package/src/components/table/table2.scss +237 -68
  126. package/src/components/text-field/MoneyField.vue +23 -21
  127. package/src/components/text-field/TextField.vue +12 -8
  128. package/src/components/tree/TreeEditor.vue +615 -0
  129. package/src/components/view/View.vue +244 -0
  130. package/src/components/view/index.stories.js +588 -0
  131. package/src/helpers/formatters.js +14 -1
  132. package/src/helpers/tree/cdbl.js +32 -0
  133. package/src/helpers/tree/cint.js +43 -0
  134. package/src/helpers/tree/domDrag.js +911 -0
  135. package/src/helpers/tree/domFinds.js +20 -0
  136. package/src/helpers/tree/domGetPointFromEvent.js +53 -0
  137. package/src/helpers/tree/domIsClientXYIn.js +65 -0
  138. package/src/helpers/tree/domRemove.js +50 -0
  139. package/src/helpers/tree/evem.js +27 -0
  140. package/src/helpers/tree/genID.js +56 -0
  141. package/src/helpers/tree/isEle.js +28 -0
  142. package/src/helpers/tree/isestr.js +35 -0
  143. package/src/helpers/tree/isint.js +40 -0
  144. package/src/helpers/tree/isnbr.js +24 -0
  145. package/src/helpers/tree/isnum.js +38 -0
  146. package/src/helpers/tree/ispint.js +41 -0
  147. package/src/helpers/tree/isstr.js +27 -0
  148. package/src/helpers/tree.js +30 -0
  149. package/src/helpers/vuetifyColor.js +136 -0
  150. package/src/locales/en.js +17 -0
  151. package/src/locales/uk.js +17 -0
@@ -10,20 +10,23 @@
10
10
  <div class="b-panel__expand_text" v-text="title"></div>
11
11
  </a>
12
12
  </div>
13
- <div v-if="!nocard" v-show="!collapsed" class="b-panel-header px-3 pt-3">
13
+ <div v-if="!nocard" v-show="!collapsed" class="b-panel-header px-3 pt-3 pb-2">
14
14
  <slot name="header">
15
- <div>
15
+ <div class="d-flex gap-3 align-items-center">
16
+ <itf-button v-if="closeable" icon default class="d-md-none" @click="closePanel">
17
+ <itf-icon name="chevron_left" />
18
+ </itf-button>
16
19
  <slot name="title">
17
- <div class="b-panel__title ps-1 fw-bold h5" v-text="title"></div>
20
+ <div class="b-panel__title fw-bold mb-0 h2" v-text="title"></div>
18
21
  </slot>
19
22
  </div>
20
23
  <div class="d-flex gap-1">
21
24
  <slot name="buttons"></slot>
22
- <itf-button v-if="expandable" icon small class="b-panel__expand_button" @click="fullsizePanel">
23
- <itf-icon name="expand" />
25
+ <itf-button v-if="expandable" icon default class="b-panel__expand_button d-none d-md-block" @click="fullsizePanel">
26
+ <itf-icon new name="expand" />
24
27
  </itf-button>
25
- <itf-button v-if="closeable" icon small class="b-panel__expand_button" @click="closePanel">
26
- <itf-icon name="cross" />
28
+ <itf-button v-if="closeable" icon default class="b-panel__expand_button" @click="closePanel">
29
+ <itf-icon new name="close" />
27
30
  </itf-button>
28
31
  </div>
29
32
  </slot>
@@ -51,6 +54,18 @@
51
54
  background: var(--b-panel-bg);
52
55
  box-shadow: var(--b-panel-box-shadow);
53
56
 
57
+ @media (max-width: 768px) {
58
+ margin: 0;
59
+ height: 100%;
60
+ min-width: 0 !important;
61
+
62
+ position: absolute;
63
+ top: 0;
64
+ left: 0;
65
+ right: 0;
66
+ bottom: 0;
67
+ }
68
+
54
69
  &__collapsed {
55
70
  flex-basis: 38px;
56
71
  flex-grow: 0;
@@ -140,6 +155,7 @@ class Panel extends Vue {
140
155
  @Prop() title;
141
156
  @Prop() icon;
142
157
  @Prop() payload;
158
+ @Prop() panel;
143
159
  @Prop(Boolean) collapsed;
144
160
  @Prop(Boolean) closeable;
145
161
  @Prop(Boolean) expandable;
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div v-loading="loading" class="px-3 pt-2 h-100">
3
+ <itf-form
4
+ ref="editForm"
5
+ class="d-flex flex-column justify-content-between h-100"
6
+ @keydown.native.shift.enter.stop.prevent="onSaveClick"
7
+ @keydown.native.esc.stop.prevent="$emit('cancel')"
8
+ >
9
+ <slot></slot>
10
+ <div class="py-3 justify-content-end d-flex align-items-center sticky-container">
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>{{ $t('components.modal.cancel') }}</span>
14
+ </itf-button>
15
+ <itf-button v-tooltip.delay="'Hot key: Shift + Enter'" primary squircle :loading="loading" :disabled="loading" @click="onSaveClick">
16
+ <span>{{ $t('components.modal.save') }}</span>
17
+ </itf-button>
18
+ </div>
19
+ </div>
20
+ </itf-form>
21
+ </div>
22
+ </template>
23
+ <style lang="scss" scoped>
24
+ .sticky-container {
25
+ position: sticky;
26
+ top: auto;
27
+ bottom: 0;
28
+ z-index: 999;
29
+ background-color: var(--bs-body-bg);
30
+ }
31
+ </style>
32
+ <script>
33
+ import { Vue, Component, Prop } from 'vue-property-decorator';
34
+ import tooltip from '../../directives/tooltip';
35
+ import loading from '../../directives/loading';
36
+ import itfForm from '../form/Form.vue';
37
+ import itfButton from '../button/Button.vue';
38
+
39
+ @Component({
40
+ components: {
41
+ itfForm,
42
+ itfButton
43
+ },
44
+ directives: {
45
+ tooltip,
46
+ loading
47
+ },
48
+ filters: {
49
+ }
50
+ })
51
+ export default class PanelItemEdit extends Vue {
52
+ @Prop(Boolean) loading;
53
+ @Prop(Boolean) hideFooter;
54
+
55
+ onSaveClick() {
56
+ if (this.$refs.editForm && !this.$refs.editForm.doValidation()) {
57
+ return;
58
+ }
59
+ this.$emit('save');
60
+ }
61
+ }
62
+ </script>
@@ -1,9 +1,10 @@
1
1
  <template>
2
- <a :href="link" :target="target" v-on="on"><slot></slot></a>
2
+ <a :href="link" :target="target" v-on="on" :class="{[activeClass]: isActive}"><slot></slot></a>
3
3
  </template>
4
4
  <script lang="ts">
5
5
  import { Vue, Component, Inject, Prop } from 'vue-property-decorator';
6
6
  import { IPanel } from './PanelList.vue';
7
+ import {stackToHash} from "@itfin/components/src/components/panels/helpers";
7
8
 
8
9
  @Component({
9
10
  components: {
@@ -17,9 +18,12 @@ export default class PanelLink extends Vue {
17
18
  @Inject({ default: null }) panelList;
18
19
  @Inject({ default: null }) currentPanel;
19
20
 
21
+ @Prop(Boolean) global: boolean;
20
22
  @Prop(String) panel: string;
21
23
  @Prop() payload: payload;
22
24
  @Prop() target: string;
25
+ @Prop() list;
26
+ @Prop({ type: String, default: 'active' }) activeClass: string;
23
27
  @Prop(Boolean) append: boolean;
24
28
 
25
29
  get on() {
@@ -30,25 +34,41 @@ export default class PanelLink extends Vue {
30
34
  return handlers;
31
35
  }
32
36
 
37
+ get activeList() {
38
+ return this.list ?? this.panelList;
39
+ }
40
+
41
+ get isActive() {
42
+ if (!this.activeList) {
43
+ return false;
44
+ }
45
+ let stack = this.activeList.getCurrentStack();
46
+ return stack.find(s => s.type === this.panel);
47
+ }
48
+
33
49
  get link() {
34
- let stack = this.panelList.getCurrentStack();
50
+ let stack = this.activeList?.getCurrentStack() ?? [];
35
51
  if (!this.append) {
36
- stack = stack.splice(0, this.currentPanel.index + 1);
52
+ stack = stack.splice(0, this.currentPanel?.index + 1);
37
53
  }
38
- const hash = this.panelList.getLink([
54
+ const hash = stackToHash([
39
55
  ...stack,
40
56
  {
41
57
  type: this.panel,
42
58
  payload: this.payload || {}
43
59
  }
44
60
  ]);
45
- return `#${hash}`;
61
+ return hash;
46
62
  }
47
63
 
48
64
  onClick(e) {
65
+ console.info(this.activeList);
66
+ if (!this.activeList) {
67
+ return;
68
+ }
49
69
  e.preventDefault();
50
70
  e.stopPropagation();
51
- this.panelList.openPanel(this.panel, this.payload || {}, this.append ? undefined : this.currentPanel.index + 1);
71
+ this.activeList.openPanel(this.panel, this.payload || {}, this.append ? undefined : this.currentPanel?.index + 1);
52
72
  }
53
73
  }
54
74
  </script>
@@ -11,6 +11,7 @@
11
11
  <panel
12
12
  :key="n"
13
13
  :index="n"
14
+ :panel="panel"
14
15
  :title="panel.title"
15
16
  :nocard="panel.nocard"
16
17
  :icon="panel.icon"
@@ -129,25 +130,37 @@ $double-an-time: $an-time * 2;
129
130
  }
130
131
  }
131
132
 
133
+ @media (max-width: 768px) {
134
+ @keyframes slidein {
135
+ 0% {
136
+ max-width: 100%;
137
+ }
138
+ 100% {
139
+ max-width: 100%;
140
+ }
141
+ }
142
+ }
143
+
132
144
  .b-panel {
133
145
  transition: min-width $an-time linear, flex-grow $an-time linear;
134
146
 
135
147
  > div {
136
- transition: opacity $an-time linear;
148
+ //transition: opacity $an-time linear;
137
149
  }
138
150
  }
139
151
 
140
- .slide-enter-active > div {
141
- opacity: 0;
142
- }
143
-
144
- .opacity-null > div {
145
- opacity: 0 !important;
146
- }
152
+ //.slide-enter-active > div {
153
+ // opacity: 0;
154
+ //}
155
+ //
156
+ //.opacity-null > div {
157
+ // opacity: 0 !important;
158
+ //}
147
159
  </style>
148
160
  <script lang="ts">
149
161
  import { Vue, Component, Prop } from 'vue-property-decorator';
150
162
  import Panel from './Panel.vue';
163
+ import {hashToStack, stackToHash} from "@itfin/components/src/components/panels/helpers";
151
164
 
152
165
  interface VisualOptions {
153
166
  title: string;
@@ -177,6 +190,7 @@ export interface IPanel {
177
190
  getPayload: () => any;
178
191
  setPayload: (value: any) => void;
179
192
  __events: Record<string, ((event: string, ...args: any[]) => any)[]>;
193
+ permanentExpanded: boolean;
180
194
  }
181
195
 
182
196
  @Component({
@@ -199,7 +213,6 @@ export default class PanelList extends Vue {
199
213
 
200
214
  nextId:number = 0;
201
215
 
202
-
203
216
  created() {
204
217
  if (this.firstPanel) {
205
218
  this.internalOpenPanel(this.firstPanel.type, this.firstPanel.payload);
@@ -291,6 +304,7 @@ export default class PanelList extends Vue {
291
304
  this.$nextTick(() => { // щоб панелі змінювались при редагуванні
292
305
  const n = newStack.length;
293
306
  newPanel.isAnimate = isAnimation;
307
+ newPanel.permanentExpanded = !!this.panels[type].permanentExpanded;
294
308
  newPanel.emit = (event, ...args) => this.emitEvent(event, ...args);
295
309
  newPanel.open = (type, payload) => this.openPanel(type, payload, n + 1);
296
310
  newPanel.close = () => this.closePanel(newPanel);
@@ -362,7 +376,7 @@ export default class PanelList extends Vue {
362
376
  openPanel.isCollapsed = false;
363
377
  }
364
378
  const openPanelIndex = this.panelsStack.findIndex(p => p === openPanel);
365
- if (openPanelIndex > 0) {
379
+ if (openPanelIndex > 0 && !openPanel?.permanentExpanded) {
366
380
  this.panelsStack[openPanelIndex - 1].isCollapsed = false;
367
381
  }
368
382
  this.ensureOnlyTwoOpenPanels(openPanel.id);
@@ -388,30 +402,17 @@ export default class PanelList extends Vue {
388
402
  return [...this.panelsStack];
389
403
  }
390
404
 
391
- getLink(stack: IPanel[]) {
392
- return stack.map(panel => {
393
- return `${panel.type}${panel.isCollapsed ? '' : '!'}=${JSON.stringify(panel.payload || {})}`;
394
- }).join('&');
395
- }
396
-
397
405
  setPanelHash() {
398
- const hash = this.getLink(this.panelsStack);
406
+ const hash = stackToHash(this.panelsStack).replace(/^#/, '');
399
407
  this.$router.push({ hash });
400
408
  }
401
409
 
402
410
  async parsePanelHash() {
403
411
  const {hash} = location;
404
412
  if (hash) {
405
- const panels = hash.slice(1).split('&').map(item => {
406
- const [type, payload] = item.split('=');
407
- const isCollapsed = !item.includes('!');
408
- return {
409
- type: type.replace('!', ''),
410
- isCollapsed,
411
- payload: JSON.parse(decodeURIComponent(payload))
412
- };
413
- });
413
+ const panels = hashToStack(hash);
414
414
  const newStack = [];
415
+ this.panelsStack = [];
415
416
  for (const panelIndex in panels) {
416
417
  const panel = panels[panelIndex];
417
418
  if (this.panelsStack[panelIndex] && this.panelsStack[panelIndex].type === panel.type) {
@@ -0,0 +1,27 @@
1
+ import {stackToHash, hashToStack} from "./helpers";
2
+
3
+ describe('panel helpers', () => {
4
+ test('stackToHash', () => {
5
+ const stack = [
6
+ { type: 'a', payload: { a: 1 }, isCollapsed: false },
7
+ { type: 'b', payload: { b: 2 }, isCollapsed: true },
8
+ { type: 'c', payload: { c: 3 }, isCollapsed: false }
9
+ ];
10
+ expect(stackToHash(stack)).toBe('a!={"a":1}&b={"b":2}&c!={"c":3}');
11
+ });
12
+ test('hashToStack', () => {
13
+ const stack = [
14
+ { type: 'a', payload: { a: 1 }, isCollapsed: false },
15
+ { type: 'b', payload: { b: 2 }, isCollapsed: true },
16
+ { type: 'c', payload: { c: 3 }, isCollapsed: false }
17
+ ];
18
+ expect(hashToStack('a!={"a":1}&b={"b":2}&c!={"c":3}')).toEqual(stack);
19
+ expect(hashToStack('a!={"a')).toEqual([
20
+ {
21
+ "isCollapsed": false,
22
+ "payload": {},
23
+ "type": "a"
24
+ }
25
+ ]);
26
+ });
27
+ });
@@ -0,0 +1,37 @@
1
+ export interface IPanel {
2
+ type: string;
3
+ payload?: any;
4
+ isCollapsed?: boolean;
5
+ }
6
+
7
+ export function stackToHash(stack: IPanel[]) {
8
+ const hash = stack.map(panel => {
9
+ return `${panel.type}${panel.isCollapsed ? '' : '!'}=${JSON.stringify(panel.payload || {})}`;
10
+ }).join('&');
11
+ return `#${hash}`;
12
+ }
13
+
14
+
15
+ export function hashToStack(hash: string|undefined): IPanel[] {
16
+ let stack:IPanel[] = [];
17
+ if (hash) {
18
+ const str = hash.replace(/^#/, '');
19
+
20
+ stack = str.split('&').map(item => {
21
+ const [type, payload] = item.split('=');
22
+ const isCollapsed = !type.includes('!');
23
+ let payloadObj:any = {};
24
+ try {
25
+ payloadObj = JSON.parse(decodeURIComponent(payload));
26
+ } catch (e) {
27
+ // ignore
28
+ }
29
+ return {
30
+ type: type.replace('!', ''),
31
+ isCollapsed,
32
+ payload: payloadObj
33
+ };
34
+ });
35
+ }
36
+ return stack;
37
+ }
@@ -5,7 +5,7 @@
5
5
  </template>
6
6
  <style scoped lang="scss">
7
7
  .notice {
8
- position: absolute;
8
+ position: fixed;
9
9
  bottom: 10px;
10
10
  left: 50%;
11
11
  max-width: 740px;
@@ -632,7 +632,7 @@ export default {
632
632
  default(dropdownList, component, { width, top, left }) {
633
633
  dropdownList.style.top = top
634
634
  dropdownList.style.left = left
635
- dropdownList.style.minWidth = width
635
+ dropdownList.style.minWidth = width;
636
636
  dropdownList.style.width = 'max-content';
637
637
  },
638
638
  },
@@ -7,13 +7,14 @@ const SORTABLE_ATTRIBUTES = ['drag-ignore-handle', 'scrollable'];
7
7
 
8
8
  const DEFAULT_OPTIONS = {
9
9
  draggableClass: DRAGGABLE_CLASS,
10
- dragHandleClass: DRAG_HANDLE_CLASS,
10
+ // dragHandleClass: DRAG_HANDLE_CLASS,
11
11
  delay: 200,
12
12
  tresholdDistance: 2,
13
13
  draggable: `.${DRAGGABLE_CLASS}`,
14
14
  handle: `.${DRAG_HANDLE_CLASS}`,
15
15
  ignoreHandleClassList: SORTABLE_ATTRIBUTES,
16
16
  mirror: {
17
+ // appendTo: '.itf-table2 .itf-table2__header',
17
18
  yAxis: false,
18
19
  constrainDimensions: true
19
20
  },
@@ -5,10 +5,12 @@
5
5
  'table-absolute': absolute,
6
6
  'table-clickable': clickable,
7
7
  'permanent-checkboxes': selectedIds.length
8
- }" :style="{ '--indicator-area-width': `${indicatorType === 'none' ? 1 : indicatorWidth}px` }">
9
- <itf-notice-popout :visible="showGroupOperations" class="rounded-pill bg-dark text-light">
10
- <div class="d-flex gap-3 px-3 align-items-center">
11
- <div><strong>{{selectedIds.length}}</strong> selected</div>
8
+ }" :style="{ '--indicator-area-width': `${indicatorType === 'none' ? 1 : indicatorWidth}px`, '--shadow-area-width': `${shadowWidth}px` }">
9
+ <itf-notice-popout :visible="showGroupOperations" class="rounded-3 bg-black text-white">
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>
13
+ <a href="" class="me-3 opacity-50 text-white text-decoration-none" @click.stop.prevent="selectedIds = []">{{$t('components.table.cancelSelected')}}</a>
12
14
  <div>
13
15
  <slot name="group-operations"></slot>
14
16
  </div>
@@ -29,6 +31,7 @@
29
31
  :title="group.name"
30
32
  :selected-ids.sync="selectedIds"
31
33
  :add-new-rows="addNewRows"
34
+ :shadow-width="shadowWidth"
32
35
  :column-sorting="columnSorting"
33
36
  :column-resizing="columnResizing"
34
37
  :show-grouping="showGrouping"
@@ -43,6 +46,7 @@
43
46
  :currencies="currencies"
44
47
  :currency="currency"
45
48
  :subrows-property="subrowsProperty"
49
+ :divider-property="dividerProperty"
46
50
  :indicator-type="indicatorType"
47
51
  :expanded-all="expandedAll"
48
52
  :indicatorWidth="indicatorWidth"
@@ -53,9 +57,9 @@
53
57
  :editable-property="editableProperty"
54
58
  :sorting.sync="_sorting"
55
59
  :active="active"
56
- :sort-as-string="sortAsString"
57
60
  @update:expanded-ids="$emit('update:expanded-ids', $event)"
58
61
  @new="$emit('new', $event)"
62
+ @filter="$emit('filter', $event)"
59
63
  @add-column="$emit('add-column', $event)"
60
64
  >
61
65
  <template v-for="(_, name) in $slots" #[name]="slotData">
@@ -103,9 +107,11 @@ class itfTable2 extends Vue {
103
107
  @Prop({ type: String, default: null }) idProperty;
104
108
  @Prop({ type: String, default: null }) cssProperty;
105
109
  @Prop({ type: String, default: null }) subrowsProperty;
110
+ @Prop({ type: String, default: null }) dividerProperty;
106
111
  @Prop({ type: String, default: null }) editableProperty;
107
112
  @Prop({ default: null }) active;
108
113
  @Prop({ default: 45 }) indicatorWidth;
114
+ @Prop({ default: 0 }) shadowWidth;
109
115
  @Prop({ type: String, default: null, validator: (val) => ['order', 'checkbox', 'toggle', 'property', 'none'].includes(val) }) indicatorType;
110
116
  @Prop({ type: String, default: null }) stateName; // save state to storage
111
117
  @Prop({ type: Object, default: () => ({}) }) schema;
@@ -114,7 +120,6 @@ class itfTable2 extends Vue {
114
120
  @Prop({ type: Array, default: () => [] }) expandedIds;
115
121
  @Prop() currency;
116
122
  @Prop() currencies;
117
- @Prop(Boolean) sortAsString;
118
123
  @Prop(Boolean) stickyHeader;
119
124
  @Prop(Boolean) addNewRows;
120
125
  @Prop(Boolean) columnSorting;
@@ -138,7 +143,29 @@ class itfTable2 extends Vue {
138
143
  };
139
144
 
140
145
  get showGroupOperations() {
141
- return !!this.$slots['group-operations'] && this.selectedIds.length > 0;
146
+ return !!(this.$slots['group-operations'] || this.$scopedSlots['group-operations']) && this.selectedIds.length > 0;
147
+ }
148
+
149
+ resetSettings() {
150
+ const list = this.schema?.properties || [];
151
+ this.state = {
152
+ selectedIds: [],
153
+ columns: [...list]
154
+ };
155
+ this.saveTableState();
156
+ this.onSchemaUpdate();
157
+ }
158
+
159
+ getColumnVisibility(property) {
160
+ return this.state.columns.find(i => i.property === property)?.visible ?? true;
161
+ }
162
+
163
+ toggleVisibility(property) {
164
+ const column = this.state.columns.find(i => i.property === property);
165
+ if (column) {
166
+ column.visible = !column.visible;
167
+ }
168
+ this.onColumnsUpdate(this.columns);
142
169
  }
143
170
 
144
171
  getTableState() {
@@ -153,6 +180,7 @@ class itfTable2 extends Vue {
153
180
  state.selectedIds = [];
154
181
  for (const column of list) {
155
182
  const stateColumnIndex = state.columns.findIndex(i => i.property === column.property);
183
+ column.visible = (typeof column.visible === 'undefined') ? true : !!column.visible;
156
184
  if (stateColumnIndex === -1) {
157
185
  state.columns.push(column);
158
186
  } else {
@@ -181,7 +209,6 @@ class itfTable2 extends Vue {
181
209
  }
182
210
 
183
211
  mounted() {
184
- console.info(this.$scopedSlots)
185
212
  this.onSchemaUpdate();
186
213
  }
187
214
 
@@ -7,6 +7,7 @@
7
7
  :columns="columns"
8
8
  :id-property="idProperty"
9
9
  :subrows-property="subrowsProperty"
10
+ :divider-property="dividerProperty"
10
11
  :show-add-column="showAddColumn"
11
12
  :show-actions="showActions"
12
13
  :no-select-all="noSelectAll"
@@ -69,7 +70,7 @@
69
70
 
70
71
  .scroller > .table-view-item:last-child {
71
72
  .table-item-inner, .indicator {
72
- border-bottom: 1px solid var(--itf-table-border-color);
73
+ border-bottom: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
73
74
  }
74
75
  }
75
76
 
@@ -91,31 +92,21 @@
91
92
  display: flex;
92
93
  align-items: center;
93
94
  justify-content: center;
94
- min-width: var(--itf-table-min-width);
95
+ min-width: 1rem;//var(--itf-table-min-width);
95
96
  }
96
97
 
97
98
  .table-row-template, .table-view-header-value {
98
99
  .form-check {
100
+ font-size: 16px;
99
101
  padding: 0;
100
102
  margin-bottom: 0;
103
+ display: flex;
104
+ align-items: center;
101
105
 
102
106
  .form-check-input {
103
- margin-left: 0;
104
- }
105
- }
106
- }
107
- .table-row-template {
108
- .on-hover {
109
- display: none;
110
- }
111
- &:hover, .permanent-checkboxes & {
112
- .on-rest {
113
- display: none;
114
- }
115
-
116
- .on-hover {
117
- opacity: 1;
118
- display: block;
107
+ --bs-form-check-bg: #fff;
108
+ margin: 0;
109
+ border: 1px solid #0000001A;
119
110
  }
120
111
  }
121
112
  }
@@ -153,6 +144,7 @@ class itfTableBody extends Vue {
153
144
  @Prop() rows;
154
145
  @Prop() idProperty;
155
146
  @Prop() subrowsProperty;
147
+ @Prop() dividerProperty;
156
148
  @Prop() active;
157
149
  @Prop(Boolean) showAddColumn;
158
150
  @Prop(Boolean) showActions;