@webitel/ui-sdk 24.10.46-6 → 24.10.47
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/ui-sdk.css +1 -1
- package/dist/ui-sdk.js +8243 -7749
- package/dist/ui-sdk.umd.cjs +17 -17
- package/package.json +2 -2
- package/src/api/clients/chats/closedChats.js +32 -0
- package/src/api/clients/index.js +2 -0
- package/src/components/index.js +12 -4
- package/src/components/wt-action-bar/__tests__/wt-action-bar.spec.js +9 -0
- package/src/components/wt-action-bar/wt-action-bar.vue +78 -0
- package/src/components/wt-empty/__tests__/wt-empty.spec.js +9 -0
- package/src/components/wt-empty/wt-empty.vue +140 -0
- package/src/components/wt-icon-action/wt-icon-action.vue +19 -7
- package/src/components/wt-image/__tests__/wt-image.spec.js +9 -0
- package/src/components/wt-image/wt-image.vue +124 -0
- package/src/enums/IconAction/IconAction.enum.js +15 -0
- package/src/modules/ObjectPermissions/components/permissions-tab.vue +6 -0
- package/src/modules/TableComponent/composables/useTableEmpty.js +20 -0
- package/src/store/new/modules/tableStoreModule/tableStoreModule.js +30 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-sdk",
|
|
3
|
-
"version": "24.10.
|
|
3
|
+
"version": "24.10.47",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"vue-multiselect": "^3.0.0-beta.3",
|
|
121
121
|
"vue-observe-visibility": "^2.0.0-alpha.1",
|
|
122
122
|
"vue-router": "^4.1.6",
|
|
123
|
-
"webitel-sdk": "^24.8.
|
|
123
|
+
"webitel-sdk": "^24.8.2",
|
|
124
124
|
"xlsx": "^0.18.5"
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AgentChatsServiceApi } from 'webitel-sdk';
|
|
2
|
+
import {
|
|
3
|
+
getDefaultInstance,
|
|
4
|
+
getDefaultOpenAPIConfig,
|
|
5
|
+
} from '../../defaults/index.js';
|
|
6
|
+
import applyTransform, {
|
|
7
|
+
notify,
|
|
8
|
+
snakeToCamel,
|
|
9
|
+
} from '../../transformers/index.js';
|
|
10
|
+
|
|
11
|
+
const instance = getDefaultInstance();
|
|
12
|
+
const configuration = getDefaultOpenAPIConfig();
|
|
13
|
+
|
|
14
|
+
const chatsService = new AgentChatsServiceApi(configuration, '', instance);
|
|
15
|
+
|
|
16
|
+
const getList = async (params) => {
|
|
17
|
+
try {
|
|
18
|
+
const response = await chatsService.getAgentChats();
|
|
19
|
+
const { items } = applyTransform(response.data, [
|
|
20
|
+
snakeToCamel(),
|
|
21
|
+
]);
|
|
22
|
+
return items;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
throw applyTransform(err, [notify]);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const ClosedChatsAPI = {
|
|
29
|
+
getList,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default ClosedChatsAPI;
|
package/src/api/clients/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import calendars from './calendars/calendars.js';
|
|
|
4
4
|
import chatGateways from './chatGateways/chatGateways.js';
|
|
5
5
|
import communications from './communications/communications.js';
|
|
6
6
|
import configurations from './configurations/configurations.js';
|
|
7
|
+
import closedChats from './chats/closedChats.js'
|
|
7
8
|
import flows from './flows/flow.js';
|
|
8
9
|
import gateways from './gateways/gateways.js';
|
|
9
10
|
import lists from './lists/blacklists.js';
|
|
@@ -19,6 +20,7 @@ export {
|
|
|
19
20
|
calendars,
|
|
20
21
|
chatGateways,
|
|
21
22
|
communications,
|
|
23
|
+
closedChats,
|
|
22
24
|
flows,
|
|
23
25
|
gateways,
|
|
24
26
|
lists,
|
package/src/components/index.js
CHANGED
|
@@ -12,19 +12,23 @@ import WtCopyAction from './wt-copy-action/wt-copy-action.vue';
|
|
|
12
12
|
import WtDatepicker from './wt-datepicker/wt-datepicker.vue';
|
|
13
13
|
import WtDivider from './wt-divider/wt-divider.vue';
|
|
14
14
|
import WtDummy from './wt-dummy/wt-dummy.vue';
|
|
15
|
+
import WtEmpty from './wt-empty/wt-empty.vue';
|
|
15
16
|
import WtErrorPage from './wt-error-page/wt-error-page.vue';
|
|
16
17
|
import WtExpansionPanel from './wt-expansion-panel/wt-expansion-panel.vue';
|
|
17
|
-
import WtFiltersPanelWrapper
|
|
18
|
+
import WtFiltersPanelWrapper
|
|
19
|
+
from './wt-filters-panel-wrapper/wt-filters-panel-wrapper.vue';
|
|
18
20
|
import WtHeadlineNav from './wt-headline-nav/wt-headline-nav.vue';
|
|
19
21
|
import WtHeadline from './wt-headline/wt-headline.vue';
|
|
20
22
|
import WtHint from './wt-hint/wt-hint.vue';
|
|
21
23
|
import WtIconAction from './wt-icon-action/wt-icon-action.vue';
|
|
22
24
|
import WtIconBtn from './wt-icon-btn/wt-icon-btn.vue';
|
|
23
25
|
import WtIcon from './wt-icon/wt-icon.vue';
|
|
26
|
+
import WtImage from './wt-image/wt-image.vue';
|
|
24
27
|
import WtIndicator from './wt-indicator/wt-indicator.vue';
|
|
25
28
|
import WtInputInfo from './wt-input-info/wt-input-info.vue';
|
|
26
29
|
import WtInput from './wt-input/wt-input.vue';
|
|
27
|
-
import WtIntersectionObserver
|
|
30
|
+
import WtIntersectionObserver
|
|
31
|
+
from './wt-intersection-observer/wt-intersection-observer.vue';
|
|
28
32
|
import WtItemLink from './wt-item-link/wt-item-link.vue';
|
|
29
33
|
import WtLabel from './wt-label/wt-label.vue';
|
|
30
34
|
import WtLoadBar from './wt-load-bar/wt-load-bar.vue';
|
|
@@ -32,7 +36,8 @@ import WtLoader from './wt-loader/wt-loader.vue';
|
|
|
32
36
|
import WtLogo from './wt-logo/wt-logo.vue';
|
|
33
37
|
import WtNavigationBar from './wt-navigation-bar/wt-navigation-bar.vue';
|
|
34
38
|
import WtNotification from './wt-notification/wt-notification.vue';
|
|
35
|
-
import WtNotificationsBar
|
|
39
|
+
import WtNotificationsBar
|
|
40
|
+
from './wt-notifications-bar/wt-notifications-bar.vue';
|
|
36
41
|
import WtPageHeader from './wt-page-header/wt-page-header.vue';
|
|
37
42
|
import WtPageWrapper from './wt-page-wrapper/wt-page-wrapper.vue';
|
|
38
43
|
import WtPagination from './wt-pagination/wt-pagination.vue';
|
|
@@ -48,7 +53,8 @@ import WtStatusSelect from './wt-status-select/wt-status-select.vue';
|
|
|
48
53
|
import WtStepper from './wt-stepper/wt-stepper.vue';
|
|
49
54
|
import WtSwitcher from './wt-switcher/wt-switcher.vue';
|
|
50
55
|
import WtTableActions from './wt-table-actions/wt-table-actions.vue';
|
|
51
|
-
import WtTableColumnSelect
|
|
56
|
+
import WtTableColumnSelect
|
|
57
|
+
from './wt-table-column-select/wt-table-column-select.vue';
|
|
52
58
|
import WtTable from './wt-table/wt-table.vue';
|
|
53
59
|
import WtTabs from './wt-tabs/wt-tabs.vue';
|
|
54
60
|
import WtTagsInput from './wt-tags-input/wt-tags-input.vue';
|
|
@@ -58,6 +64,8 @@ import WtTimepicker from './wt-timepicker/wt-timepicker.vue';
|
|
|
58
64
|
import WtTooltip from './wt-tooltip/wt-tooltip.vue';
|
|
59
65
|
|
|
60
66
|
const Components = {
|
|
67
|
+
WtImage,
|
|
68
|
+
WtEmpty,
|
|
61
69
|
WtLogo,
|
|
62
70
|
WtAvatar,
|
|
63
71
|
WtBadge,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="wt-action-bar">
|
|
3
|
+
<!-- @slot -->
|
|
4
|
+
<slot name="search-bar" />
|
|
5
|
+
|
|
6
|
+
<!-- @slot
|
|
7
|
+
@scope="{ `action`: IconAction enum string }"
|
|
8
|
+
-->
|
|
9
|
+
<slot
|
|
10
|
+
v-for="action in shownActions"
|
|
11
|
+
v-bind="{ action }"
|
|
12
|
+
>
|
|
13
|
+
<wt-icon-action
|
|
14
|
+
:action="action"
|
|
15
|
+
@click="emit(`click:${action}`)"
|
|
16
|
+
/>
|
|
17
|
+
</slot>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup>
|
|
22
|
+
import { computed } from 'vue';
|
|
23
|
+
import IconAction from '../../enums/IconAction/IconAction.enum.js';
|
|
24
|
+
import WtIconAction from '../wt-icon-action/wt-icon-action.vue';
|
|
25
|
+
|
|
26
|
+
const props = defineProps({
|
|
27
|
+
// options: [`table`, `card`]
|
|
28
|
+
mode: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: 'table',
|
|
31
|
+
validator: (v) => ['table', 'card'].includes(v),
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* see IconAction enum
|
|
35
|
+
*/
|
|
36
|
+
actions: {
|
|
37
|
+
type: Array,
|
|
38
|
+
default: () => [],
|
|
39
|
+
validator: (v) => v.every((action) => Object.values(IconAction).includes(action)),
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: 'md',
|
|
44
|
+
validator: (v) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(v),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const emit = defineEmits(Object.values(IconAction).map((action) => `click:${action}`));
|
|
49
|
+
|
|
50
|
+
const tableActionsOrder = [
|
|
51
|
+
IconAction.ADD,
|
|
52
|
+
IconAction.COLUMNS,
|
|
53
|
+
IconAction.COPY,
|
|
54
|
+
IconAction.DOWNLOAD,
|
|
55
|
+
IconAction.UPLOAD,
|
|
56
|
+
IconAction.FILTERS,
|
|
57
|
+
IconAction.DELETE,
|
|
58
|
+
IconAction.REFRESH,
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
// TODO
|
|
62
|
+
const cardActionsOrder = tableActionsOrder;
|
|
63
|
+
|
|
64
|
+
const shownActions = computed(() => {
|
|
65
|
+
const actionsOrder = props.mode === 'card' ? cardActionsOrder : tableActionsOrder;
|
|
66
|
+
|
|
67
|
+
return actionsOrder.filter((action) => props.actions.includes(action));
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<style lang="scss" scoped>
|
|
72
|
+
.wt-action-bar {
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
gap: var(--spacing-xs);
|
|
77
|
+
}
|
|
78
|
+
</style>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section
|
|
3
|
+
:class="[`wt-empty--${size}`]"
|
|
4
|
+
class="wt-empty"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
v-if="image || slots.media"
|
|
8
|
+
class="wt-empty__media"
|
|
9
|
+
>
|
|
10
|
+
<slot name="media">
|
|
11
|
+
<wt-image
|
|
12
|
+
:src="image"
|
|
13
|
+
alt="empty-state"
|
|
14
|
+
/>
|
|
15
|
+
</slot>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<h2
|
|
19
|
+
v-if="headline || slots.headline"
|
|
20
|
+
class="wt-empty__headline"
|
|
21
|
+
>
|
|
22
|
+
<slot name="headline">
|
|
23
|
+
{{ headline }}
|
|
24
|
+
</slot>
|
|
25
|
+
</h2>
|
|
26
|
+
|
|
27
|
+
<h3
|
|
28
|
+
v-if="title || slots.title"
|
|
29
|
+
class="wt-empty__title"
|
|
30
|
+
>
|
|
31
|
+
<slot name="title">
|
|
32
|
+
{{ title }}
|
|
33
|
+
</slot>
|
|
34
|
+
</h3>
|
|
35
|
+
|
|
36
|
+
<slot></slot>
|
|
37
|
+
|
|
38
|
+
<p
|
|
39
|
+
v-if="text || slots.text"
|
|
40
|
+
class="wt-empty__text"
|
|
41
|
+
>
|
|
42
|
+
<slot name="text">
|
|
43
|
+
{{ text }}
|
|
44
|
+
</slot>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<div
|
|
48
|
+
v-if="actionText || slots.actions"
|
|
49
|
+
class="wt-empty__actions"
|
|
50
|
+
>
|
|
51
|
+
<slot
|
|
52
|
+
name="actions"
|
|
53
|
+
v-bind="{ onClick }"
|
|
54
|
+
>
|
|
55
|
+
<wt-button
|
|
56
|
+
:color="actionColor"
|
|
57
|
+
@click="onClick"
|
|
58
|
+
>
|
|
59
|
+
{{ actionText }}
|
|
60
|
+
</wt-button>
|
|
61
|
+
</slot>
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<script setup>
|
|
67
|
+
// based on https://vuetifyjs.com/en/components/empty-states/
|
|
68
|
+
|
|
69
|
+
import { useSlots } from 'vue';
|
|
70
|
+
import WtImage from '../wt-image/wt-image.vue';
|
|
71
|
+
|
|
72
|
+
const props = defineProps({
|
|
73
|
+
image: {
|
|
74
|
+
type: [Object, null],
|
|
75
|
+
},
|
|
76
|
+
size: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: 'md',
|
|
79
|
+
validator: (v) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(v),
|
|
80
|
+
},
|
|
81
|
+
headline: {
|
|
82
|
+
type: [String, null],
|
|
83
|
+
default: '',
|
|
84
|
+
},
|
|
85
|
+
title: {
|
|
86
|
+
type: [String, null],
|
|
87
|
+
default: '',
|
|
88
|
+
},
|
|
89
|
+
text: {
|
|
90
|
+
type: [String, null],
|
|
91
|
+
default: '',
|
|
92
|
+
},
|
|
93
|
+
actionText: {
|
|
94
|
+
type: [String, null],
|
|
95
|
+
default: '',
|
|
96
|
+
},
|
|
97
|
+
actionColor: {
|
|
98
|
+
type: [String, null],
|
|
99
|
+
default: 'primary',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const emit = defineEmits([
|
|
104
|
+
'click:action',
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
const slots = useSlots();
|
|
108
|
+
|
|
109
|
+
const onClick = (params) => {
|
|
110
|
+
return emit('click:action', params);
|
|
111
|
+
};
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<style lang="scss" scoped>
|
|
115
|
+
@import '../../../src/css/main.scss';
|
|
116
|
+
|
|
117
|
+
.wt-empty {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
text-align: center;
|
|
123
|
+
gap: var(--spacing-sm);
|
|
124
|
+
|
|
125
|
+
&__media {
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
&__headline {
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&__title {
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&__text {
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
&__actions {
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
</style>
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<script setup>
|
|
10
10
|
import { computed } from 'vue';
|
|
11
|
+
import IconAction from '../../enums/IconAction/IconAction.enum.js';
|
|
11
12
|
import WtAddIconAction from './_internals/wt-add-icon-action.vue';
|
|
12
13
|
import WtDeleteIconAction from './_internals/wt-delete-icon-action.vue';
|
|
13
14
|
import WtDownloadIconAction from './_internals/wt-download-icon-action.vue';
|
|
@@ -16,10 +17,20 @@ import WtHistoryIconAction from './_internals/wt-history-icon-action.vue';
|
|
|
16
17
|
import WtRefreshIconAction from './_internals/wt-refresh-icon-action.vue';
|
|
17
18
|
|
|
18
19
|
const props = defineProps({
|
|
20
|
+
/**
|
|
21
|
+
* available actions: IconAction.DELETE, IconAction.EDIT, IconAction.ADD, IconAction.HISTORY, IconAction.DOWNLOAD, IconAction.REFRESH
|
|
22
|
+
*/
|
|
19
23
|
action: {
|
|
20
24
|
type: String,
|
|
21
25
|
required: true,
|
|
22
|
-
|
|
26
|
+
validator: (v) => Object.values([
|
|
27
|
+
IconAction.DELETE,
|
|
28
|
+
IconAction.EDIT,
|
|
29
|
+
IconAction.ADD,
|
|
30
|
+
IconAction.HISTORY,
|
|
31
|
+
IconAction.DOWNLOAD,
|
|
32
|
+
IconAction.REFRESH,
|
|
33
|
+
]).includes(v),
|
|
23
34
|
},
|
|
24
35
|
disabled: {
|
|
25
36
|
type: Boolean,
|
|
@@ -31,19 +42,20 @@ const emit = defineEmits(['click']);
|
|
|
31
42
|
|
|
32
43
|
const actionComponent = computed(() => {
|
|
33
44
|
switch (props.action) {
|
|
34
|
-
case
|
|
45
|
+
case IconAction.EDIT:
|
|
35
46
|
return WtEditIconAction;
|
|
36
|
-
case
|
|
47
|
+
case IconAction.DELETE:
|
|
37
48
|
return WtDeleteIconAction;
|
|
38
|
-
case
|
|
49
|
+
case IconAction.ADD:
|
|
39
50
|
return WtAddIconAction;
|
|
40
|
-
case
|
|
51
|
+
case IconAction.HISTORY:
|
|
41
52
|
return WtHistoryIconAction;
|
|
42
|
-
case
|
|
53
|
+
case IconAction.DOWNLOAD:
|
|
43
54
|
return WtDownloadIconAction;
|
|
44
|
-
case
|
|
55
|
+
case IconAction.REFRESH:
|
|
45
56
|
return WtRefreshIconAction;
|
|
46
57
|
default:
|
|
58
|
+
console.error(`Unknown action for wt-icon-action component: ${props.action}`);
|
|
47
59
|
return WtEditIconAction;
|
|
48
60
|
}
|
|
49
61
|
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:style="{
|
|
4
|
+
width,
|
|
5
|
+
height,
|
|
6
|
+
minWidth,
|
|
7
|
+
minHeight,
|
|
8
|
+
maxWidth,
|
|
9
|
+
maxHeight,
|
|
10
|
+
}"
|
|
11
|
+
class="wt-image"
|
|
12
|
+
>
|
|
13
|
+
<!-- @slot Replaces `<img>` tag
|
|
14
|
+
@scope `{ alt, src }`
|
|
15
|
+
-->
|
|
16
|
+
<slot v-bind="{ alt, src }">
|
|
17
|
+
<img
|
|
18
|
+
:alt="alt"
|
|
19
|
+
:src="src"
|
|
20
|
+
class="wt-image__img"
|
|
21
|
+
>
|
|
22
|
+
</slot>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup>
|
|
27
|
+
import { computed } from 'vue';
|
|
28
|
+
|
|
29
|
+
const sizeToUnits = {
|
|
30
|
+
'3xs': '32px',
|
|
31
|
+
'2xs': '64px',
|
|
32
|
+
'xs': '92px',
|
|
33
|
+
'sm': '128px',
|
|
34
|
+
'md': '192px',
|
|
35
|
+
'lg': '256px',
|
|
36
|
+
'xl': '380px',
|
|
37
|
+
'2xl': '512px',
|
|
38
|
+
'3xl': '600px',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const props = defineProps({
|
|
42
|
+
src: {
|
|
43
|
+
type: [Object, String],
|
|
44
|
+
required: true,
|
|
45
|
+
},
|
|
46
|
+
// все в одну лінію, бо повалиться дока
|
|
47
|
+
/**
|
|
48
|
+
* `'3xs': '32px', '2xs': '64px', 'xs': '92px', 'sm': '128px', 'md': '192px', 'lg': '256px', 'xl': '380px', '2xl': '512px', '3xl': '600px',`
|
|
49
|
+
*/
|
|
50
|
+
size: {
|
|
51
|
+
type: String,
|
|
52
|
+
// default: 'md',
|
|
53
|
+
// required: true,
|
|
54
|
+
validator: (v) => ['3xs', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'].includes(v),
|
|
55
|
+
},
|
|
56
|
+
alt: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: 'wt-image',
|
|
59
|
+
},
|
|
60
|
+
width: {
|
|
61
|
+
type: [String, Number],
|
|
62
|
+
},
|
|
63
|
+
height: {
|
|
64
|
+
type: [String, Number],
|
|
65
|
+
},
|
|
66
|
+
minWidth: {
|
|
67
|
+
type: [String, Number],
|
|
68
|
+
},
|
|
69
|
+
minHeight: {
|
|
70
|
+
type: [String, Number],
|
|
71
|
+
},
|
|
72
|
+
maxWidth: {
|
|
73
|
+
type: [String, Number],
|
|
74
|
+
},
|
|
75
|
+
maxHeight: {
|
|
76
|
+
type: [String, Number],
|
|
77
|
+
},
|
|
78
|
+
// aspectRatio: {
|
|
79
|
+
// type: [String, Number, null],
|
|
80
|
+
// default: 1,
|
|
81
|
+
// },
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const emit = defineEmits([]);
|
|
85
|
+
|
|
86
|
+
const width = computed(() => {
|
|
87
|
+
const width = props.size ? sizeToUnits[props.size] : props.width;
|
|
88
|
+
|
|
89
|
+
// if converted to Number without an error, it has no units in it
|
|
90
|
+
if (+width) {
|
|
91
|
+
return `${width}px`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return width;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const height = computed(() => {
|
|
98
|
+
// if (props.aspectRatio) return null;
|
|
99
|
+
|
|
100
|
+
const height = props.size ? sizeToUnits[props.size] : props.height;
|
|
101
|
+
|
|
102
|
+
// if converted to Number without an error, it has no units in it
|
|
103
|
+
if (+height) {
|
|
104
|
+
return `${height}px`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return height;
|
|
108
|
+
});
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<style lang="scss" scoped>
|
|
112
|
+
@import '../../../src/css/main.scss';
|
|
113
|
+
|
|
114
|
+
.wt-image {
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
justify-content: center;
|
|
118
|
+
|
|
119
|
+
&__img {
|
|
120
|
+
max-width: 100%;
|
|
121
|
+
max-height: 100%;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const IconAction = Object.freeze({
|
|
2
|
+
REFRESH: 'refresh',
|
|
3
|
+
ADD: 'add',
|
|
4
|
+
DELETE: 'delete',
|
|
5
|
+
FILTERS: 'filters',
|
|
6
|
+
UPLOAD: 'upload',
|
|
7
|
+
DOWNLOAD: 'download',
|
|
8
|
+
EXPORT: 'export',
|
|
9
|
+
COPY: 'copy',
|
|
10
|
+
COLUMNS: 'columns',
|
|
11
|
+
HISTORY: 'history',
|
|
12
|
+
EDIT: 'edit',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default IconAction;
|
|
@@ -121,10 +121,16 @@ import RolePopup from '../_internals/components/permissions-tab-role-popup.vue';
|
|
|
121
121
|
import { AccessMode } from '../_internals/enums/AccessMode.enum.js';
|
|
122
122
|
|
|
123
123
|
const props = defineProps({
|
|
124
|
+
/**
|
|
125
|
+
* Namespace of the parent card store
|
|
126
|
+
*/
|
|
124
127
|
namespace: {
|
|
125
128
|
type: String,
|
|
126
129
|
required: true,
|
|
127
130
|
},
|
|
131
|
+
/**
|
|
132
|
+
* Access to the component actions, related to permissions
|
|
133
|
+
*/
|
|
128
134
|
access: {
|
|
129
135
|
type: Object,
|
|
130
136
|
default: () => ({
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { useI18n } from 'vue-i18n';
|
|
3
|
+
|
|
4
|
+
export const useTableEmpty = (emptyState) => {
|
|
5
|
+
const { t } = useI18n();
|
|
6
|
+
|
|
7
|
+
const media = computed(() => {});
|
|
8
|
+
const headline = computed(() => {});
|
|
9
|
+
const title = computed(() => {});
|
|
10
|
+
const text = computed(() => {});
|
|
11
|
+
const actionText = computed(() => {});
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
media,
|
|
15
|
+
headline,
|
|
16
|
+
title,
|
|
17
|
+
text,
|
|
18
|
+
actionText,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import FilterEvent from '../../../../modules/Filters/enums/FilterEvent.enum.js';
|
|
2
|
+
import isEmpty from '../../../../scripts/isEmpty.js';
|
|
2
3
|
import {
|
|
3
4
|
queryToSortAdapter,
|
|
4
5
|
sortToQueryAdapter,
|
|
@@ -17,7 +18,7 @@ const getters = {
|
|
|
17
18
|
PARENT_ID: () => null, // override me
|
|
18
19
|
|
|
19
20
|
// FIXME: maybe move to filters module?
|
|
20
|
-
FILTERS: (state, getters) => getters['filters/GET_FILTERS'],
|
|
21
|
+
FILTERS: (state, getters) => () => getters['filters/GET_FILTERS'](),
|
|
21
22
|
|
|
22
23
|
REQUIRED_FIELDS: () => ['id'], // override me
|
|
23
24
|
|
|
@@ -30,7 +31,33 @@ const getters = {
|
|
|
30
31
|
return [...new Set([...getters.REQUIRED_FIELDS, ...fields])];
|
|
31
32
|
},
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
EMPTY_STATE: (state, getters) => {
|
|
35
|
+
if (state.isLoading) {
|
|
36
|
+
return { value: false };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (state.error) {
|
|
40
|
+
return { value: true, cause: 'error' };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!state.dataList.length) {
|
|
44
|
+
const filters = getters.FILTERS();
|
|
45
|
+
const uncheckedFilters = ['page', 'size', 'sort', 'fields'];
|
|
46
|
+
const filtersApplied = Object.entries(filters).some(
|
|
47
|
+
([filterValue, filterName]) =>
|
|
48
|
+
!isEmpty(filterValue) && !uncheckedFilters.includes(filterName),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (filtersApplied) {
|
|
52
|
+
return { value: true, cause: 'filters' };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { value: true, cause: 'empty' };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { value: false };
|
|
59
|
+
},
|
|
60
|
+
|
|
34
61
|
GET_LIST_PARAMS: (state, getters) => (overrides) => {
|
|
35
62
|
const filters = getters.FILTERS();
|
|
36
63
|
const fields = getters.FIELDS;
|
|
@@ -148,7 +175,7 @@ const actions = {
|
|
|
148
175
|
} finally {
|
|
149
176
|
setTimeout(() => {
|
|
150
177
|
context.commit('SET', { path: 'isLoading', value: false });
|
|
151
|
-
}, 100);
|
|
178
|
+
}, 100); // why 1s? https://ux.stackexchange.com/a/104782
|
|
152
179
|
}
|
|
153
180
|
},
|
|
154
181
|
|