@webitel/ui-sdk 26.8.87 → 26.8.91
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.
- package/dist/{clients-BOVhef1Q.js → clients-CKEEu4i6.js} +335 -307
- package/dist/{components-DhOeTGOI.js → components-x657jfzV.js} +6 -6
- package/dist/ui-sdk.css +1 -1
- package/dist/ui-sdk.js +1 -1
- package/dist/ui-sdk.umd.cjs +637 -637
- package/dist/{wt-chat-emoji-D6mlvxYh.js → wt-chat-emoji-BM36mINn.js} +1 -1
- package/dist/{wt-display-chip-items-CjoOIGEn.js → wt-display-chip-items-Ch6lqLcB.js} +1 -1
- package/dist/{wt-send-message-popup-ClhnL3uM.js → wt-send-message-popup-D_t_B6D0.js} +2 -2
- package/dist/{wt-table-column-select-CHzqRfXf.js → wt-table-column-select-BtFhZKPT.js} +23 -16
- package/dist/{wt-type-extension-value-input-69hTFde6.js → wt-type-extension-value-input-DWUsS2CS.js} +2 -2
- package/dist/{wt-vidstack-player-BjO98yMg.js → wt-vidstack-player-Bd-axRRU.js} +1 -1
- package/package.json +5 -1
- package/src/components/wt-logo/wt-logo.vue +1 -1
- package/src/components/wt-table-column-select/wt-table-column-select.vue +21 -2
- package/src/modules/Appearance/components/wt-dark-mode-switcher.vue +1 -25
- package/src/modules/TableVariableColumnSelect/components/__tests__/wt-table-variable-column-select.spec.ts +101 -0
- package/src/modules/TableVariableColumnSelect/components/wt-table-variable-column-select.vue +278 -0
- package/src/modules/TableVariableColumnSelect/composable/__tests__/useTableVariableHeaders.spec.ts +129 -0
- package/src/modules/TableVariableColumnSelect/composable/useTableVariableHeaders.ts +59 -0
- package/src/modules/TableVariableColumnSelect/index.ts +7 -0
- package/types/.tsbuildinfo +1 -1
- package/types/modules/Appearance/components/wt-dark-mode-switcher.vue.d.ts +3 -15
- package/types/modules/TableVariableColumnSelect/components/wt-table-variable-column-select.vue.d.ts +17 -0
- package/types/modules/TableVariableColumnSelect/composable/useTableVariableHeaders.d.ts +14 -0
- package/types/modules/TableVariableColumnSelect/index.d.ts +2 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as e, i as t } from "./components-
|
|
1
|
+
import { C as e, i as t } from "./components-x657jfzV.js";
|
|
2
2
|
import { t as n } from "./_plugin-vue_export-helper-B3ysoDQm.js";
|
|
3
3
|
import { s as r } from "./utils-DReAiJBV.js";
|
|
4
4
|
import { Fragment as i, computed as a, createCommentVNode as o, createElementBlock as s, createTextVNode as c, createVNode as l, defineComponent as u, openBlock as d, renderList as f, renderSlot as p, toDisplayString as m, unref as h, withCtx as g } from "vue";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as e, r as t } from "./clients-
|
|
2
|
-
import { n } from "./components-
|
|
1
|
+
import { n as e, r as t } from "./clients-CKEEu4i6.js";
|
|
2
|
+
import { n } from "./components-x657jfzV.js";
|
|
3
3
|
import { t as r } from "./vue-i18n-B88GcHzn.js";
|
|
4
4
|
import { n as i } from "./useEventBus-B-ZeklLu.js";
|
|
5
5
|
import { createBlock as a, createTextVNode as o, createVNode as s, defineComponent as c, mergeProps as l, onMounted as u, openBlock as d, ref as f, resolveComponent as p, toDisplayString as m, unref as h, withCtx as g } from "vue";
|
|
@@ -20,30 +20,30 @@ var T = /* @__PURE__ */ e(r(), 1), E = "data:image/svg+xml,%3csvg%20viewBox='0%2
|
|
|
20
20
|
function P({ text: e, locale: t }) {
|
|
21
21
|
return !e && t ? typeof t == "string" ? k(t) : k(String(t[0]), ...t.slice(1)) : e;
|
|
22
22
|
}
|
|
23
|
-
let F = a(() => j.value.filter((e) => !r.staticHeaders.includes(e.value) && P(e)?.toLowerCase().includes(M.value?.toLowerCase())).sort((e, t) => P(e)?.localeCompare(P(t) ?? "") ?? 0));
|
|
24
|
-
function I() {
|
|
25
|
-
j.value = (0, T.default)(r.headers);
|
|
26
|
-
}
|
|
23
|
+
let F = a(() => j.value.filter((e) => !r.staticHeaders.includes(e.value) && P(e)?.toLowerCase().includes(M.value?.toLowerCase())).sort((e, t) => P(e)?.localeCompare(P(t) ?? "") ?? 0)), I = a(() => j.value.some((e) => e.show));
|
|
27
24
|
function L() {
|
|
28
|
-
|
|
25
|
+
j.value = (0, T.default)(r.headers);
|
|
29
26
|
}
|
|
30
27
|
function R() {
|
|
31
|
-
N.value = !
|
|
28
|
+
N.value = !0;
|
|
32
29
|
}
|
|
33
30
|
function z() {
|
|
34
|
-
|
|
31
|
+
N.value = !1, M.value = "";
|
|
32
|
+
}
|
|
33
|
+
function B() {
|
|
34
|
+
f("change", j.value), z();
|
|
35
35
|
}
|
|
36
36
|
return S(N, () => {
|
|
37
|
-
|
|
37
|
+
L();
|
|
38
38
|
}), (t, n) => {
|
|
39
39
|
let r = v("wt-icon-btn"), a = v("wt-icon"), f = v("wt-input-text"), p = v("wt-checkbox"), g = v("wt-empty"), S = v("wt-button"), T = v("wt-popup"), k = y("tooltip");
|
|
40
40
|
return h(), c("div", O, [w(d(r, {
|
|
41
41
|
icon: "column-select",
|
|
42
|
-
onClick:
|
|
42
|
+
onClick: R
|
|
43
43
|
}, null, 512), [[k, t.$t("webitelUI.tableColumnSelect.title")]]), d(T, {
|
|
44
44
|
shown: N.value,
|
|
45
45
|
class: "wt-table-column-select__popup",
|
|
46
|
-
onClose:
|
|
46
|
+
onClose: z
|
|
47
47
|
}, {
|
|
48
48
|
title: C(() => [u(b(t.$t("webitelUI.tableColumnSelect.title")), 1)]),
|
|
49
49
|
main: C(() => [e.enableSearch ? (h(), o(f, {
|
|
@@ -59,7 +59,10 @@ var T = /* @__PURE__ */ e(r(), 1), E = "data:image/svg+xml,%3csvg%20viewBox='0%2
|
|
|
59
59
|
onClick: n[0] ||= (e) => M.value = ""
|
|
60
60
|
})) : s("", !0)]),
|
|
61
61
|
_: 1
|
|
62
|
-
}, 8, ["model-value"])) : s("", !0), l("div", { class: m(["wt-table-column-select__popup-list-wrap", {
|
|
62
|
+
}, 8, ["model-value"])) : s("", !0), l("div", { class: m(["wt-table-column-select__popup-list-wrap", {
|
|
63
|
+
"wt-table-column-select__popup-list-wrap__height-fixed": e.enableSearch,
|
|
64
|
+
"wt-table-column-select__popup-list-wrap--empty": !F.value.length
|
|
65
|
+
}]) }, [F.value.length ? (h(), c("ul", {
|
|
63
66
|
key: 0,
|
|
64
67
|
class: m([{
|
|
65
68
|
"wt-table-column-select__popup-list--md": F.value.length > 10 && F.value.length <= 20,
|
|
@@ -79,14 +82,18 @@ var T = /* @__PURE__ */ e(r(), 1), E = "data:image/svg+xml,%3csvg%20viewBox='0%2
|
|
|
79
82
|
])]))), 128))], 2)) : (h(), o(g, {
|
|
80
83
|
key: 1,
|
|
81
84
|
image: x(A) ? x(E) : x(D),
|
|
82
|
-
text: t.$t("webitelUI.empty.text.filters")
|
|
85
|
+
text: t.$t("webitelUI.empty.text.filters"),
|
|
86
|
+
size: "sm"
|
|
83
87
|
}, null, 8, ["image", "text"]))], 2)]),
|
|
84
|
-
actions: C(() => [d(S, {
|
|
88
|
+
actions: C(() => [d(S, {
|
|
89
|
+
disabled: !I.value,
|
|
90
|
+
onClick: B
|
|
91
|
+
}, {
|
|
85
92
|
default: C(() => [u(b(t.$t("reusable.add")), 1)], void 0, !0),
|
|
86
93
|
_: 1
|
|
87
|
-
}), d(S, {
|
|
94
|
+
}, 8, ["disabled"]), d(S, {
|
|
88
95
|
color: "secondary",
|
|
89
|
-
onClick:
|
|
96
|
+
onClick: z
|
|
90
97
|
}, {
|
|
91
98
|
default: C(() => [u(b(t.$t("reusable.cancel")), 1)], void 0, !0),
|
|
92
99
|
_: 1
|
|
@@ -95,6 +102,6 @@ var T = /* @__PURE__ */ e(r(), 1), E = "data:image/svg+xml,%3csvg%20viewBox='0%2
|
|
|
95
102
|
}, 8, ["shown"])]);
|
|
96
103
|
};
|
|
97
104
|
}
|
|
98
|
-
}), [["__scopeId", "data-v-
|
|
105
|
+
}), [["__scopeId", "data-v-3cc9bbe8"]]);
|
|
99
106
|
//#endregion
|
|
100
107
|
export { k as default };
|
package/dist/{wt-type-extension-value-input-69hTFde6.js → wt-type-extension-value-input-DWUsS2CS.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as e } from "./clients-
|
|
2
|
-
import { a as t, o as n, r, s as i } from "./components-
|
|
1
|
+
import { t as e } from "./clients-CKEEu4i6.js";
|
|
2
|
+
import { a as t, o as n, r, s as i } from "./components-x657jfzV.js";
|
|
3
3
|
import { t as a } from "./enums-B_9ZBu01.js";
|
|
4
4
|
import { t as o } from "./vue-i18n-B88GcHzn.js";
|
|
5
5
|
import { computed as s, createBlock as c, createCommentVNode as l, createVNode as u, defineComponent as d, mergeModels as f, mergeProps as p, openBlock as m, renderSlot as h, resolveComponent as g, unref as _, useModel as v } from "vue";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-sdk",
|
|
3
|
-
"version": "26.8.
|
|
3
|
+
"version": "26.8.91",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "npm run docs:dev",
|
|
@@ -373,6 +373,10 @@
|
|
|
373
373
|
"types": "./types/modules/SaveCopyPopup/index.d.ts",
|
|
374
374
|
"import": "./src/modules/SaveCopyPopup/index.ts"
|
|
375
375
|
},
|
|
376
|
+
"./modules/TableVariableColumnSelect": {
|
|
377
|
+
"types": "./types/modules/TableVariableColumnSelect/index.d.ts",
|
|
378
|
+
"import": "./src/modules/TableVariableColumnSelect/index.ts"
|
|
379
|
+
},
|
|
376
380
|
"./plugins*": {
|
|
377
381
|
"types": "./types/plugins*",
|
|
378
382
|
"import": "./src/plugins*"
|
|
@@ -25,7 +25,7 @@ const props = defineProps({
|
|
|
25
25
|
const href = computed(
|
|
26
26
|
() => props.logoHref || import.meta.env.VITE_START_PAGE_URL,
|
|
27
27
|
);
|
|
28
|
-
const logoSrc = props.darkMode ? LogoDark : LogoLight;
|
|
28
|
+
const logoSrc = computed(() => (props.darkMode ? LogoDark : LogoLight));
|
|
29
29
|
|
|
30
30
|
const linkComponent = props.disabled
|
|
31
31
|
? 'span'
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
</wt-input-text>
|
|
36
36
|
<div
|
|
37
37
|
class="wt-table-column-select__popup-list-wrap"
|
|
38
|
-
:class="{
|
|
38
|
+
:class="{
|
|
39
|
+
'wt-table-column-select__popup-list-wrap__height-fixed': enableSearch,
|
|
40
|
+
'wt-table-column-select__popup-list-wrap--empty': !changeableDraft.length,
|
|
41
|
+
}"
|
|
39
42
|
>
|
|
40
43
|
<ul
|
|
41
44
|
v-if="changeableDraft.length"
|
|
@@ -63,11 +66,15 @@
|
|
|
63
66
|
v-else
|
|
64
67
|
:image="darkMode ? EmptyImageDark : EmptyImageLight"
|
|
65
68
|
:text="$t('webitelUI.empty.text.filters')"
|
|
69
|
+
size="sm"
|
|
66
70
|
/>
|
|
67
71
|
</div>
|
|
68
72
|
</template>
|
|
69
73
|
<template #actions>
|
|
70
|
-
<wt-button
|
|
74
|
+
<wt-button
|
|
75
|
+
:disabled="!hasShownColumns"
|
|
76
|
+
@click="setShownColumns"
|
|
77
|
+
>
|
|
71
78
|
{{ $t('reusable.add') }}
|
|
72
79
|
</wt-button>
|
|
73
80
|
<wt-button
|
|
@@ -147,6 +154,10 @@ const changeableDraft = computed(() =>
|
|
|
147
154
|
),
|
|
148
155
|
);
|
|
149
156
|
|
|
157
|
+
const hasShownColumns = computed(() =>
|
|
158
|
+
draft.value.some((header) => header.show),
|
|
159
|
+
);
|
|
160
|
+
|
|
150
161
|
function fillHeadersDraft() {
|
|
151
162
|
draft.value = deepCopy(props.headers);
|
|
152
163
|
}
|
|
@@ -157,6 +168,7 @@ function openPopup() {
|
|
|
157
168
|
|
|
158
169
|
function close() {
|
|
159
170
|
isColumnSelectPopup.value = false;
|
|
171
|
+
search.value = '';
|
|
160
172
|
}
|
|
161
173
|
|
|
162
174
|
function setShownColumns() {
|
|
@@ -190,6 +202,13 @@ watch(isColumnSelectPopup, () => {
|
|
|
190
202
|
height: 400px;
|
|
191
203
|
}
|
|
192
204
|
|
|
205
|
+
.wt-table-column-select__popup-list-wrap--empty {
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: center;
|
|
208
|
+
justify-content: center;
|
|
209
|
+
width: 100%;
|
|
210
|
+
}
|
|
211
|
+
|
|
193
212
|
.wt-table-column-select__popup-list {
|
|
194
213
|
max-width: 100%;
|
|
195
214
|
display: flex;
|
|
@@ -1,37 +1,15 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
2
|
+
import { ref } from 'vue';
|
|
3
3
|
|
|
4
4
|
import WtIcon from '../../../components/wt-icon/wt-icon.vue';
|
|
5
5
|
import WtSwitcher from '../../../components/wt-switcher/wt-switcher.vue';
|
|
6
6
|
|
|
7
|
-
const props = defineProps({
|
|
8
|
-
namespace: {
|
|
9
|
-
type: String,
|
|
10
|
-
default: 'appearance',
|
|
11
|
-
},
|
|
12
|
-
});
|
|
13
|
-
|
|
14
7
|
const emit = defineEmits([
|
|
15
8
|
'changedMode',
|
|
16
9
|
]);
|
|
17
10
|
|
|
18
|
-
// vuex's useStore() is just inject('store') under the hood (its default
|
|
19
|
-
// injection key) — reading it directly avoids a hard dependency on the
|
|
20
|
-
// `vuex` package, which apps that migrated fully to Pinia don't install.
|
|
21
|
-
const store = inject('store', null);
|
|
22
|
-
|
|
23
11
|
const mode = ref('light');
|
|
24
12
|
|
|
25
|
-
const setThemeToStore = (theme) => {
|
|
26
|
-
// @author @stanislav-kozak
|
|
27
|
-
// when vuex store is not initialize and we use pinia
|
|
28
|
-
if (!store) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
store.dispatch(`${props.namespace}/SET_THEME`, theme);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
13
|
const setMode = (value) => {
|
|
36
14
|
if (value === 'dark') {
|
|
37
15
|
mode.value = 'dark';
|
|
@@ -43,7 +21,6 @@ const setMode = (value) => {
|
|
|
43
21
|
localStorage.setItem('theme', 'light');
|
|
44
22
|
}
|
|
45
23
|
emit('changedMode', value);
|
|
46
|
-
setThemeToStore(mode.value);
|
|
47
24
|
};
|
|
48
25
|
|
|
49
26
|
const toggleDarkMode = () => {
|
|
@@ -52,7 +29,6 @@ const toggleDarkMode = () => {
|
|
|
52
29
|
} else {
|
|
53
30
|
setMode('light');
|
|
54
31
|
}
|
|
55
|
-
setThemeToStore(mode.value);
|
|
56
32
|
};
|
|
57
33
|
|
|
58
34
|
const cachedTheme = localStorage.getItem('theme');
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { mount, shallowMount } from '@vue/test-utils';
|
|
2
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
3
|
+
import { nextTick } from 'vue';
|
|
4
|
+
|
|
5
|
+
import WtTableVariableColumnSelect from '../wt-table-variable-column-select.vue';
|
|
6
|
+
|
|
7
|
+
const storageKey = 'test/variable-headers';
|
|
8
|
+
|
|
9
|
+
const mountSelect = (
|
|
10
|
+
props: Partial<{
|
|
11
|
+
storageKey: string;
|
|
12
|
+
title: string;
|
|
13
|
+
}> = {},
|
|
14
|
+
) =>
|
|
15
|
+
mount(WtTableVariableColumnSelect, {
|
|
16
|
+
props: {
|
|
17
|
+
storageKey,
|
|
18
|
+
title: 'Select variables',
|
|
19
|
+
...props,
|
|
20
|
+
},
|
|
21
|
+
global: {
|
|
22
|
+
stubs: {
|
|
23
|
+
WtBadge: {
|
|
24
|
+
template: '<div><slot /></div>',
|
|
25
|
+
},
|
|
26
|
+
WtIconBtn: true,
|
|
27
|
+
WtPopup: {
|
|
28
|
+
props: [
|
|
29
|
+
'shown',
|
|
30
|
+
'size',
|
|
31
|
+
],
|
|
32
|
+
template:
|
|
33
|
+
'<div v-if="shown" class="wt-popup__popup"><slot name="title" /><slot name="main" /><slot name="actions" /></div>',
|
|
34
|
+
},
|
|
35
|
+
WtInputText: true,
|
|
36
|
+
WtButton: {
|
|
37
|
+
props: [
|
|
38
|
+
'disabled',
|
|
39
|
+
'loading',
|
|
40
|
+
'color',
|
|
41
|
+
],
|
|
42
|
+
template:
|
|
43
|
+
'<button :disabled="disabled" @click="$attrs.onClick?.() || $emit(\'click\')"><slot /></button>',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('WtTableVariableColumnSelect', () => {
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
localStorage.clear();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('renders a component', () => {
|
|
55
|
+
const wrapper = shallowMount(WtTableVariableColumnSelect, {
|
|
56
|
+
props: {
|
|
57
|
+
storageKey,
|
|
58
|
+
title: 'Select variables',
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
expect(wrapper.classes('wt-table-variable-column-select')).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('opens popup on icon click', async () => {
|
|
65
|
+
const wrapper = mountSelect();
|
|
66
|
+
expect(wrapper.find('.wt-popup__popup').exists()).toBe(false);
|
|
67
|
+
|
|
68
|
+
wrapper
|
|
69
|
+
.findComponent({
|
|
70
|
+
name: 'WtIconBtn',
|
|
71
|
+
})
|
|
72
|
+
.vm.$emit('click');
|
|
73
|
+
await nextTick();
|
|
74
|
+
|
|
75
|
+
expect(wrapper.find('.wt-popup__popup').exists()).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('restores keys from localStorage and emits update:variable-headers', async () => {
|
|
79
|
+
localStorage.setItem(storageKey, 'foo;bar');
|
|
80
|
+
|
|
81
|
+
const wrapper = mountSelect();
|
|
82
|
+
await nextTick();
|
|
83
|
+
|
|
84
|
+
const emitted = wrapper.emitted('update:variable-headers');
|
|
85
|
+
expect(emitted).toBeTruthy();
|
|
86
|
+
expect(emitted?.[0]?.[0]).toEqual(
|
|
87
|
+
expect.arrayContaining([
|
|
88
|
+
expect.objectContaining({
|
|
89
|
+
field: 'variables.foo',
|
|
90
|
+
text: 'foo',
|
|
91
|
+
show: false,
|
|
92
|
+
}),
|
|
93
|
+
expect.objectContaining({
|
|
94
|
+
field: 'variables.bar',
|
|
95
|
+
text: 'bar',
|
|
96
|
+
show: false,
|
|
97
|
+
}),
|
|
98
|
+
]),
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="wt-table-variable-column-select">
|
|
3
|
+
<wt-badge
|
|
4
|
+
v-tooltip="title"
|
|
5
|
+
:hidden="!draft.length"
|
|
6
|
+
>
|
|
7
|
+
<wt-icon-btn
|
|
8
|
+
icon="variable-select"
|
|
9
|
+
@click="open"
|
|
10
|
+
/>
|
|
11
|
+
</wt-badge>
|
|
12
|
+
|
|
13
|
+
<wt-popup
|
|
14
|
+
:shown="shownPopup"
|
|
15
|
+
:size="size"
|
|
16
|
+
class="wt-table-variable-column-select__popup"
|
|
17
|
+
@close="close"
|
|
18
|
+
>
|
|
19
|
+
<template #title>
|
|
20
|
+
{{ title }}
|
|
21
|
+
</template>
|
|
22
|
+
<template #main>
|
|
23
|
+
<div class="wt-table-variable-column-select__form">
|
|
24
|
+
<wt-input-text
|
|
25
|
+
v-model:model-value="newVariableKey"
|
|
26
|
+
:label="t('vocabulary.keys', 1)"
|
|
27
|
+
class="wt-table-variable-column-select__input"
|
|
28
|
+
/>
|
|
29
|
+
<wt-button
|
|
30
|
+
:disabled="r$.$error"
|
|
31
|
+
@click="addVariableHeader(newVariableKey)"
|
|
32
|
+
>
|
|
33
|
+
{{ t('reusable.add') }}
|
|
34
|
+
</wt-button>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<ul class="wt-table-variable-column-select__list">
|
|
38
|
+
<li
|
|
39
|
+
v-for="key in draft"
|
|
40
|
+
:key="key.field"
|
|
41
|
+
class="wt-table-variable-column-select__item"
|
|
42
|
+
>
|
|
43
|
+
<span class="wt-table-variable-column-select__label">{{ key.text }}</span>
|
|
44
|
+
<wt-icon-btn
|
|
45
|
+
icon="bucket"
|
|
46
|
+
@click="deleteKey(key)"
|
|
47
|
+
/>
|
|
48
|
+
</li>
|
|
49
|
+
</ul>
|
|
50
|
+
</template>
|
|
51
|
+
<template #actions>
|
|
52
|
+
<wt-button
|
|
53
|
+
:disabled="!hasChanges"
|
|
54
|
+
:loading="isLoading"
|
|
55
|
+
@click="save"
|
|
56
|
+
>
|
|
57
|
+
{{ t('reusable.save') }}
|
|
58
|
+
</wt-button>
|
|
59
|
+
<wt-button
|
|
60
|
+
color="secondary"
|
|
61
|
+
@click="close"
|
|
62
|
+
>
|
|
63
|
+
{{ t('reusable.cancel') }}
|
|
64
|
+
</wt-button>
|
|
65
|
+
</template>
|
|
66
|
+
</wt-popup>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<script lang="ts" setup>
|
|
71
|
+
import type { Maybe } from '@regle/core';
|
|
72
|
+
import { createRule, useRegle } from '@regle/core';
|
|
73
|
+
import { computed, reactive, ref } from 'vue';
|
|
74
|
+
import { useI18n } from 'vue-i18n';
|
|
75
|
+
import { ComponentSize } from '../../../enums/ComponentSize/ComponentSize';
|
|
76
|
+
import isEmpty from '../../../scripts/isEmpty';
|
|
77
|
+
import {
|
|
78
|
+
type TableVariableHeader,
|
|
79
|
+
VARIABLE_FIELD_PREFIX,
|
|
80
|
+
} from '../composable/useTableVariableHeaders';
|
|
81
|
+
|
|
82
|
+
const props = withDefaults(
|
|
83
|
+
defineProps<{
|
|
84
|
+
storageKey: string;
|
|
85
|
+
title: string;
|
|
86
|
+
fieldPrefix?: string;
|
|
87
|
+
size?: ComponentSize;
|
|
88
|
+
}>(),
|
|
89
|
+
{
|
|
90
|
+
fieldPrefix: VARIABLE_FIELD_PREFIX,
|
|
91
|
+
size: ComponentSize.SM,
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const emit = defineEmits<{
|
|
96
|
+
'update:variable-headers': [
|
|
97
|
+
value: TableVariableHeader[],
|
|
98
|
+
];
|
|
99
|
+
}>();
|
|
100
|
+
|
|
101
|
+
const { t } = useI18n();
|
|
102
|
+
|
|
103
|
+
const shownPopup = ref(false);
|
|
104
|
+
|
|
105
|
+
const newVariableKey = ref('');
|
|
106
|
+
|
|
107
|
+
const draft = reactive<TableVariableHeader[]>([]);
|
|
108
|
+
|
|
109
|
+
let savedHeaders: TableVariableHeader[] = [];
|
|
110
|
+
|
|
111
|
+
const isLoading = ref(false);
|
|
112
|
+
|
|
113
|
+
const hasChanges = ref(false);
|
|
114
|
+
|
|
115
|
+
const variablesFromDraft = computed(() => {
|
|
116
|
+
return draft.map(({ value }) => value.replace(props.fieldPrefix, ''));
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const requiredRule = createRule({
|
|
120
|
+
validator: (value: Maybe<string>) => Boolean(value),
|
|
121
|
+
message: 'required',
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const alreadyExistsRule = createRule({
|
|
125
|
+
validator: (value: Maybe<string>) =>
|
|
126
|
+
!value || !variablesFromDraft.value.includes(value),
|
|
127
|
+
message: 'alreadyExists',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const { r$ } = useRegle(
|
|
131
|
+
{
|
|
132
|
+
newVariableKey,
|
|
133
|
+
},
|
|
134
|
+
() => ({
|
|
135
|
+
newVariableKey: {
|
|
136
|
+
required: requiredRule,
|
|
137
|
+
alreadyExists: alreadyExistsRule,
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
140
|
+
{
|
|
141
|
+
autoDirty: true,
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
r$.$touch();
|
|
145
|
+
|
|
146
|
+
const cloneHeaders = (headers: TableVariableHeader[]) =>
|
|
147
|
+
headers.map((header) => ({
|
|
148
|
+
...header,
|
|
149
|
+
}));
|
|
150
|
+
|
|
151
|
+
const replaceDraft = (headers: TableVariableHeader[]) => {
|
|
152
|
+
draft.splice(0, draft.length, ...cloneHeaders(headers));
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const open = () => {
|
|
156
|
+
replaceDraft(savedHeaders);
|
|
157
|
+
newVariableKey.value = '';
|
|
158
|
+
hasChanges.value = false;
|
|
159
|
+
shownPopup.value = true;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const close = () => {
|
|
163
|
+
replaceDraft(savedHeaders);
|
|
164
|
+
newVariableKey.value = '';
|
|
165
|
+
hasChanges.value = false;
|
|
166
|
+
shownPopup.value = false;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const deleteKey = (keyToDelete: TableVariableHeader) => {
|
|
170
|
+
draft.splice(draft.indexOf(keyToDelete), 1);
|
|
171
|
+
hasChanges.value = true;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const localStorageSeparator = ';';
|
|
175
|
+
|
|
176
|
+
const setToLocalStorage = (variableHeaders: string[]) => {
|
|
177
|
+
const storedValue = variableHeaders.join(localStorageSeparator);
|
|
178
|
+
if (storedValue) {
|
|
179
|
+
localStorage.setItem(props.storageKey, storedValue);
|
|
180
|
+
} else {
|
|
181
|
+
localStorage.removeItem(props.storageKey);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const getFromLocalStorage = () => {
|
|
186
|
+
return localStorage.getItem(props.storageKey)?.split(localStorageSeparator);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const addVariableHeader = (
|
|
190
|
+
variableKey: string,
|
|
191
|
+
{
|
|
192
|
+
trackChanges = true,
|
|
193
|
+
}: {
|
|
194
|
+
trackChanges?: boolean;
|
|
195
|
+
} = {},
|
|
196
|
+
) => {
|
|
197
|
+
const variableHeader: TableVariableHeader = {
|
|
198
|
+
value: `${props.fieldPrefix}${variableKey}`,
|
|
199
|
+
show: true,
|
|
200
|
+
field: `${props.fieldPrefix}${variableKey}`,
|
|
201
|
+
text: variableKey,
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
draft.unshift(variableHeader);
|
|
205
|
+
if (trackChanges) {
|
|
206
|
+
hasChanges.value = true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (newVariableKey.value) {
|
|
210
|
+
newVariableKey.value = '';
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const save = () => {
|
|
215
|
+
isLoading.value = true;
|
|
216
|
+
try {
|
|
217
|
+
setToLocalStorage(variablesFromDraft.value);
|
|
218
|
+
savedHeaders = cloneHeaders(draft);
|
|
219
|
+
emit('update:variable-headers', draft);
|
|
220
|
+
} finally {
|
|
221
|
+
isLoading.value = false;
|
|
222
|
+
}
|
|
223
|
+
close();
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const restore = () => {
|
|
227
|
+
const storedValue = getFromLocalStorage();
|
|
228
|
+
if (!isEmpty(storedValue)) {
|
|
229
|
+
storedValue.forEach((variableKey) => {
|
|
230
|
+
addVariableHeader(variableKey, {
|
|
231
|
+
trackChanges: false,
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
draft.forEach((variable) => {
|
|
235
|
+
variable.show = false;
|
|
236
|
+
});
|
|
237
|
+
savedHeaders = cloneHeaders(draft);
|
|
238
|
+
emit('update:variable-headers', draft);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
restore();
|
|
243
|
+
</script>
|
|
244
|
+
|
|
245
|
+
<style lang="scss" scoped>
|
|
246
|
+
.wt-table-variable-column-select {
|
|
247
|
+
line-height: 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.wt-table-variable-column-select__form {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: flex-end;
|
|
253
|
+
justify-content: space-between;
|
|
254
|
+
width: 100%;
|
|
255
|
+
gap: var(--spacing-xs);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.wt-table-variable-column-select__input {
|
|
259
|
+
flex: 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.wt-table-variable-column-select__list {
|
|
263
|
+
display: flex;
|
|
264
|
+
flex-direction: column;
|
|
265
|
+
margin-top: var(--spacing-sm);
|
|
266
|
+
gap: var(--spacing-sm);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.wt-table-variable-column-select__item {
|
|
270
|
+
display: flex;
|
|
271
|
+
justify-content: space-between;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.wt-table-variable-column-select__label {
|
|
275
|
+
display: flex;
|
|
276
|
+
align-items: center;
|
|
277
|
+
}
|
|
278
|
+
</style>
|