@webitel/ui-sdk 24.10.42 → 24.10.44
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.js +1 -1
- package/dist/ui-sdk.umd.cjs +1 -1
- package/package.json +1 -1
- package/src/api/clients/_shared/generatePermissionsApi.js +97 -0
- package/src/api/clients/index.js +3 -0
- package/src/api/clients/users/users.js +3 -0
- package/src/locale/en/en.js +27 -6
- package/src/locale/ru/ru.js +27 -5
- package/src/locale/ua/ua.js +27 -5
- package/src/modules/ObjectPermissions/_internals/components/permissions-role-row.vue +28 -0
- package/src/modules/ObjectPermissions/_internals/components/permissions-role-select.vue +34 -0
- package/src/modules/ObjectPermissions/_internals/components/permissions-tab-role-popup.vue +118 -0
- package/src/modules/ObjectPermissions/_internals/enums/AccessMode.enum.js +5 -0
- package/src/modules/ObjectPermissions/_internals/modules/filters/store/filters.store.js +23 -0
- package/src/modules/ObjectPermissions/_internals/store/helpers/createObjectPermissionsStoreModule.js +27 -0
- package/src/modules/ObjectPermissions/_internals/store/modules/headers.js +28 -0
- package/src/modules/ObjectPermissions/_internals/store/modules/objectPermissionsStoreModule.js +95 -0
- package/src/modules/ObjectPermissions/components/permissions-tab.vue +214 -0
- package/src/modules/ObjectPermissions/store/index.js +7 -0
- package/src/store/new/helpers/createApiStoreModule.js +1 -1
- package/src/store/new/helpers/createBaseStoreModule.js +1 -1
- package/src/store/new/helpers/createCardStoreModule.js +1 -1
- package/src/store/new/helpers/createStoreModule.js +1 -1
- package/src/store/new/helpers/createTableStoreModule.js +1 -1
- package/src/store/new/modules/apiStoreModule/apiStoreModule.js +31 -0
- package/src/store/new/modules/cardStoreModule/useCardStore.js +3 -1
- package/src/store/new/modules/tableStoreModule/tableStoreModule.js +20 -5
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section
|
|
3
|
+
v-if="access.read"
|
|
4
|
+
class="permissions-tab"
|
|
5
|
+
>
|
|
6
|
+
<header class="content-header">
|
|
7
|
+
<h3 class="content-title">
|
|
8
|
+
{{ $t('access.operations') }}
|
|
9
|
+
</h3>
|
|
10
|
+
<div class="content-header__actions-wrap">
|
|
11
|
+
<!-- TODO replace wt-table-actions -->
|
|
12
|
+
<!-- <wt-table-actions-->
|
|
13
|
+
<!-- :icons="['refresh']"-->
|
|
14
|
+
<!-- @input="(event) => event === 'refresh' && loadData()"-->
|
|
15
|
+
<!-- >-->
|
|
16
|
+
<!-- </wt-table-actions>-->
|
|
17
|
+
<role-popup
|
|
18
|
+
v-if="props.access.add"
|
|
19
|
+
:namespace="tableNamespace"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</header>
|
|
23
|
+
|
|
24
|
+
<wt-loader v-show="isLoading" />
|
|
25
|
+
|
|
26
|
+
<!-- TODO -->
|
|
27
|
+
<!-- <wt-dummy-->
|
|
28
|
+
<!-- v-if="dummy && !isLoading"-->
|
|
29
|
+
<!-- :dark-mode="darkMode"-->
|
|
30
|
+
<!-- :src="dummy.src"-->
|
|
31
|
+
<!-- :text="dummy.text && t(dummy.text)"-->
|
|
32
|
+
<!-- class="dummy-wrapper"-->
|
|
33
|
+
<!-- />-->
|
|
34
|
+
|
|
35
|
+
<div class="table-wrapper">
|
|
36
|
+
<div
|
|
37
|
+
v-if="dataList.length && !isLoading"
|
|
38
|
+
style="display:contents;"
|
|
39
|
+
>
|
|
40
|
+
<!-- TODO -->
|
|
41
|
+
<!-- <transition-slide-->
|
|
42
|
+
<!-- :offset="{-->
|
|
43
|
+
<!-- enter: ['-5%', 0],-->
|
|
44
|
+
<!-- leave: [0, 0]-->
|
|
45
|
+
<!-- }"-->
|
|
46
|
+
<!-- duration="200"-->
|
|
47
|
+
<!-- mode="out-in"-->
|
|
48
|
+
<!-- appear-->
|
|
49
|
+
<!-- >-->
|
|
50
|
+
<wt-table
|
|
51
|
+
:data="localizedDataList"
|
|
52
|
+
:grid-actions="access.edit"
|
|
53
|
+
:headers="headers"
|
|
54
|
+
:selectable="false"
|
|
55
|
+
sortable
|
|
56
|
+
@sort="sort"
|
|
57
|
+
>
|
|
58
|
+
<template #grantee="{ item }">
|
|
59
|
+
<role-column
|
|
60
|
+
:role="item.grantee"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<template #read="{ item }">
|
|
65
|
+
<wt-select
|
|
66
|
+
:clearable="false"
|
|
67
|
+
:disabled="!access.edit"
|
|
68
|
+
:options="accessOptions"
|
|
69
|
+
:value="item.access.r"
|
|
70
|
+
@input="changeAccessMode({ item, ruleName: 'r', mode: $event })"
|
|
71
|
+
/>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<template #edit="{ item }">
|
|
75
|
+
<wt-select
|
|
76
|
+
:clearable="false"
|
|
77
|
+
:disabled="!access.edit"
|
|
78
|
+
:options="accessOptions"
|
|
79
|
+
:value="item.access.w"
|
|
80
|
+
@input="changeAccessMode({ item, ruleName: 'w', mode: $event })"
|
|
81
|
+
/>
|
|
82
|
+
</template>
|
|
83
|
+
|
|
84
|
+
<template #delete="{ item }">
|
|
85
|
+
<wt-select
|
|
86
|
+
:clearable="false"
|
|
87
|
+
:disabled="!access.edit"
|
|
88
|
+
:options="accessOptions"
|
|
89
|
+
:value="item.access.d"
|
|
90
|
+
@input="changeAccessMode({ item, ruleName: 'd', mode: $event })"
|
|
91
|
+
/>
|
|
92
|
+
</template>
|
|
93
|
+
<template #actions="{ item }">
|
|
94
|
+
<wt-icon-action
|
|
95
|
+
action="delete"
|
|
96
|
+
@click="changeAccessMode({ item, ruleName: 'r', mode: { id: AccessMode.FORBIDDEN }})"
|
|
97
|
+
/>
|
|
98
|
+
</template>
|
|
99
|
+
</wt-table>
|
|
100
|
+
<!-- </transition-slide>-->
|
|
101
|
+
</div>
|
|
102
|
+
<filter-pagination
|
|
103
|
+
:namespace="filtersNamespace"
|
|
104
|
+
:next="isNext"
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
</section>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<script setup>
|
|
111
|
+
// TODO: класи, даммі, транзішен таблички. WTEL-3392
|
|
112
|
+
|
|
113
|
+
import { computed, onUnmounted } from 'vue';
|
|
114
|
+
import { useI18n } from 'vue-i18n';
|
|
115
|
+
import { useStore } from 'vuex';
|
|
116
|
+
import { useTableStore } from '../../../store/new/index.js';
|
|
117
|
+
import FilterPagination from '../../Filters/components/filter-pagination.vue';
|
|
118
|
+
import { useTableFilters } from '../../Filters/composables/useTableFilters.js';
|
|
119
|
+
import RoleColumn from '../_internals/components/permissions-role-row.vue';
|
|
120
|
+
import RolePopup from '../_internals/components/permissions-tab-role-popup.vue';
|
|
121
|
+
import { AccessMode } from '../_internals/enums/AccessMode.enum.js';
|
|
122
|
+
|
|
123
|
+
const props = defineProps({
|
|
124
|
+
namespace: {
|
|
125
|
+
type: String,
|
|
126
|
+
required: true,
|
|
127
|
+
},
|
|
128
|
+
access: {
|
|
129
|
+
type: Object,
|
|
130
|
+
default: () => ({
|
|
131
|
+
read: true,
|
|
132
|
+
add: true,
|
|
133
|
+
edit: true,
|
|
134
|
+
delete: true,
|
|
135
|
+
}),
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const { t } = useI18n();
|
|
140
|
+
const store = useStore();
|
|
141
|
+
|
|
142
|
+
const {
|
|
143
|
+
namespace: tableNamespace,
|
|
144
|
+
|
|
145
|
+
dataList,
|
|
146
|
+
isLoading,
|
|
147
|
+
headers,
|
|
148
|
+
isNext,
|
|
149
|
+
error,
|
|
150
|
+
|
|
151
|
+
loadData, // TODO: use for refresh button
|
|
152
|
+
sort,
|
|
153
|
+
onFilterEvent,
|
|
154
|
+
} = useTableStore(`${props.namespace}/permissions`);
|
|
155
|
+
|
|
156
|
+
const localizedDataList = computed(() => {
|
|
157
|
+
return dataList.value.map((item) => {
|
|
158
|
+
const access = Object.keys(item.access).reduce((access, rule) => {
|
|
159
|
+
return {
|
|
160
|
+
...access,
|
|
161
|
+
[rule]: {
|
|
162
|
+
...item.access[rule],
|
|
163
|
+
name: t(`access.accessMode.${item.access[rule].id}`),
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}, {});
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
...item,
|
|
170
|
+
access,
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const {
|
|
176
|
+
namespace: filtersNamespace,
|
|
177
|
+
restoreFilters,
|
|
178
|
+
|
|
179
|
+
subscribe,
|
|
180
|
+
flushSubscribers,
|
|
181
|
+
} = useTableFilters(tableNamespace);
|
|
182
|
+
|
|
183
|
+
subscribe({
|
|
184
|
+
event: '*',
|
|
185
|
+
callback: onFilterEvent,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
restoreFilters();
|
|
189
|
+
|
|
190
|
+
onUnmounted(() => {
|
|
191
|
+
flushSubscribers();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// TODO
|
|
195
|
+
// const { dummy } = useDummy({
|
|
196
|
+
// namespace,
|
|
197
|
+
// hiddenText: true,
|
|
198
|
+
// });
|
|
199
|
+
|
|
200
|
+
const accessOptions = computed(() => {
|
|
201
|
+
return Object.values(AccessMode).map((mode) => ({
|
|
202
|
+
id: mode,
|
|
203
|
+
name: t(`access.accessMode.${mode}`),
|
|
204
|
+
}));
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const changeAccessMode = (payload) => (
|
|
208
|
+
store.dispatch(`${tableNamespace}/CHANGE_ACCESS_MODE`, payload)
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
</script>
|
|
212
|
+
|
|
213
|
+
<style lang="scss" scoped>
|
|
214
|
+
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import apiStoreModule from '../modules/apiStoreModule/apiStoreModule.js';
|
|
2
2
|
import { createBaseStoreModule } from './createBaseStoreModule.js';
|
|
3
3
|
|
|
4
|
-
export const createApiStoreModule = (modules
|
|
4
|
+
export const createApiStoreModule = (modules) => {
|
|
5
5
|
const modulesArr = Array.isArray(modules) ? modules : [modules];
|
|
6
6
|
|
|
7
7
|
return createBaseStoreModule([apiStoreModule(), ...modulesArr]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import baseStoreModule from '../modules/baseStoreModule/baseStoreModule.js';
|
|
2
2
|
import { createStoreModule } from './createStoreModule.js';
|
|
3
3
|
|
|
4
|
-
export const createBaseStoreModule = (modules
|
|
4
|
+
export const createBaseStoreModule = (modules) => {
|
|
5
5
|
const modulesArr = Array.isArray(modules) ? modules : [modules];
|
|
6
6
|
|
|
7
7
|
return createStoreModule([baseStoreModule(), ...modulesArr]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import cardStoreModule from '../modules/cardStoreModule/cardStoreModule.js';
|
|
2
2
|
import { createBaseStoreModule } from './createBaseStoreModule.js';
|
|
3
3
|
|
|
4
|
-
export const createCardStoreModule = (modules
|
|
4
|
+
export const createCardStoreModule = (modules) => {
|
|
5
5
|
const modulesArr = Array.isArray(modules) ? modules : [modules];
|
|
6
6
|
|
|
7
7
|
return createBaseStoreModule([cardStoreModule(), ...modulesArr]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import deepmerge from 'deepmerge';
|
|
2
2
|
import isPlainObject from 'lodash/isPlainObject.js';
|
|
3
3
|
|
|
4
|
-
export const createStoreModule = (modules
|
|
4
|
+
export const createStoreModule = (modules) => {
|
|
5
5
|
const modulesArr = Array.isArray(modules) ? modules : [modules];
|
|
6
6
|
|
|
7
7
|
const merged = deepmerge.all(modulesArr, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import tableStoreModule from '../modules/tableStoreModule/tableStoreModule.js';
|
|
2
2
|
import { createBaseStoreModule } from './createBaseStoreModule.js';
|
|
3
3
|
|
|
4
|
-
export const createTableStoreModule = (modules
|
|
4
|
+
export const createTableStoreModule = (modules) => {
|
|
5
5
|
const modulesArr = Array.isArray(modules) ? modules : [modules];
|
|
6
6
|
|
|
7
7
|
return createBaseStoreModule([tableStoreModule(), ...modulesArr]);
|
|
@@ -63,6 +63,37 @@ const actions = {
|
|
|
63
63
|
id,
|
|
64
64
|
});
|
|
65
65
|
},
|
|
66
|
+
|
|
67
|
+
GET_OBJECT_PERMISSIONS_LIST: (
|
|
68
|
+
apiContext,
|
|
69
|
+
{ context: callerContext = {}, params = {} },
|
|
70
|
+
) => {
|
|
71
|
+
if (!apiContext.state.api.getList) throw Error('No API "getPermissionsList" method provided');
|
|
72
|
+
return apiContext.state.api.getPermissionsList({
|
|
73
|
+
...callerContext.state,
|
|
74
|
+
parentId: getParentIdFromContext(callerContext),
|
|
75
|
+
...params,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
PATCH_OBJECT_PERMISSIONS_ITEM: (
|
|
80
|
+
apiContext,
|
|
81
|
+
{
|
|
82
|
+
context: callerContext = {},
|
|
83
|
+
id,
|
|
84
|
+
changes,
|
|
85
|
+
...rest
|
|
86
|
+
},
|
|
87
|
+
) => {
|
|
88
|
+
if (!apiContext.state.api.patch) throw Error('No API "patchPermissions" method provided');
|
|
89
|
+
return apiContext.state.api.patchPermissions({
|
|
90
|
+
...callerContext.state,
|
|
91
|
+
parentId: getParentIdFromContext(callerContext),
|
|
92
|
+
...rest,
|
|
93
|
+
id,
|
|
94
|
+
changes,
|
|
95
|
+
});
|
|
96
|
+
},
|
|
66
97
|
};
|
|
67
98
|
|
|
68
99
|
const mutations = {};
|
|
@@ -5,7 +5,9 @@ import getNamespacedState from '../../../helpers/getNamespacedState.js';
|
|
|
5
5
|
export const useCardStore = (namespace) => {
|
|
6
6
|
const store = useStore();
|
|
7
7
|
|
|
8
|
-
const cardNamespace =
|
|
8
|
+
const cardNamespace = namespace.endsWith('/card')
|
|
9
|
+
? namespace
|
|
10
|
+
: `${namespace}/card`;
|
|
9
11
|
|
|
10
12
|
const id = computed(() => getNamespacedState(store.state, cardNamespace).itemId);
|
|
11
13
|
const itemInstance = computed(() => getNamespacedState(store.state, cardNamespace).itemInstance);
|
|
@@ -19,13 +19,15 @@ const getters = {
|
|
|
19
19
|
// FIXME: maybe move to filters module?
|
|
20
20
|
FILTERS: (state, getters) => getters['filters/GET_FILTERS'],
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
REQUIRED_FIELDS: () => ['id'], // override me
|
|
23
|
+
|
|
24
|
+
FIELDS: (state, getters) => {
|
|
23
25
|
const fields = state.headers.reduce((fields, { show, field }) => {
|
|
24
26
|
if (show || show === undefined) return [...fields, field];
|
|
25
27
|
return fields;
|
|
26
28
|
}, []);
|
|
27
29
|
|
|
28
|
-
return [...new Set([
|
|
30
|
+
return [...new Set([getters.REQUIRED_FIELDS, ...fields])];
|
|
29
31
|
},
|
|
30
32
|
|
|
31
33
|
// main GET_LIST params collector
|
|
@@ -130,7 +132,10 @@ const actions = {
|
|
|
130
132
|
|
|
131
133
|
const params = context.getters.GET_LIST_PARAMS(query);
|
|
132
134
|
try {
|
|
133
|
-
const {
|
|
135
|
+
const {
|
|
136
|
+
items = [],
|
|
137
|
+
next = false,
|
|
138
|
+
} = await context.dispatch('GET_LIST_API', {
|
|
134
139
|
context,
|
|
135
140
|
params,
|
|
136
141
|
});
|
|
@@ -171,7 +176,7 @@ const actions = {
|
|
|
171
176
|
const changes = { [prop]: value };
|
|
172
177
|
|
|
173
178
|
try {
|
|
174
|
-
await context.dispatch('
|
|
179
|
+
await context.dispatch('PATCH_ITEM_API', {
|
|
175
180
|
context,
|
|
176
181
|
id,
|
|
177
182
|
etag,
|
|
@@ -208,7 +213,7 @@ const actions = {
|
|
|
208
213
|
|
|
209
214
|
DELETE_SINGLE: async (context, { id, etag }) => {
|
|
210
215
|
try {
|
|
211
|
-
await context.dispatch('
|
|
216
|
+
await context.dispatch('DELETE_ITEM_API', { context, id, etag });
|
|
212
217
|
} catch (err) {
|
|
213
218
|
throw err;
|
|
214
219
|
}
|
|
@@ -220,6 +225,16 @@ const actions = {
|
|
|
220
225
|
SET_SELECTED: (context, selected) => {
|
|
221
226
|
context.commit('SET', { path: 'selected', value: selected });
|
|
222
227
|
},
|
|
228
|
+
|
|
229
|
+
GET_LIST_API: (context, payload) => context.dispatch('api/GET_LIST', payload),
|
|
230
|
+
PATCH_ITEM_API: (
|
|
231
|
+
context,
|
|
232
|
+
payload,
|
|
233
|
+
) => context.dispatch('api/PATCH_ITEM', payload),
|
|
234
|
+
DELETE_ITEM_API: (
|
|
235
|
+
context,
|
|
236
|
+
payload,
|
|
237
|
+
) => context.dispatch('api/DELETE_ITEM', payload),
|
|
223
238
|
};
|
|
224
239
|
|
|
225
240
|
export default () => ({
|