@webitel/ui-datalist 26.12.5 → 26.12.7

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 (47) hide show
  1. package/Readme.md +18 -0
  2. package/package.json +4 -4
  3. package/src/index.ts +5 -2
  4. package/src/modules/filters/modules/filterConfig/components/grantee/index.ts +1 -1
  5. package/src/modules/filters/modules/filterConfig/components/index.ts +8 -0
  6. package/src/modules/filters/modules/filterConfig/components/trigger-job-state/trigger-job-state-filter-value-field.vue +87 -0
  7. package/src/modules/filters/modules/filterConfig/components/trigger-job-state/trigger-job-state-filter-value-preview.vue +42 -0
  8. package/src/modules/filters/modules/filterConfig/enums/FilterOption.ts +2 -0
  9. package/src/modules/headers/__tests__/createTableHeadersStore.spec.ts +80 -0
  10. package/src/modules/headers/createTableHeadersStore.ts +51 -11
  11. package/src/modules/permissions/components/_internal/permissions-role-row.vue +25 -0
  12. package/src/modules/permissions/components/_internal/permissions-role-select.vue +35 -0
  13. package/src/modules/permissions/components/_internal/permissions-tab-content.vue +161 -0
  14. package/src/modules/permissions/components/_internal/permissions-tab-role-popup.vue +94 -0
  15. package/src/modules/{permissions-page → permissions}/components/permissions-tab.vue +5 -5
  16. package/src/modules/permissions/composables/useAccessModeOptions.ts +48 -0
  17. package/src/modules/permissions/index.ts +40 -0
  18. package/src/modules/permissions/stores/_internals/headers.ts +52 -0
  19. package/src/modules/{permissions-page → permissions}/stores/createPermissionsStore.ts +19 -44
  20. package/src/modules/{permissions-page → permissions}/types/Permission.types.ts +2 -2
  21. package/src/modules/permissions/types/PermissionsUserAccess.ts +10 -0
  22. package/types/.tsbuildinfo +1 -1
  23. package/types/index.d.ts +2 -2
  24. package/types/modules/filter-presets/stores/createFilterPresetsStore.d.ts +1 -1
  25. package/types/modules/filters/modules/filterConfig/components/grantee/index.d.ts +1 -1
  26. package/types/modules/filters/modules/filterConfig/components/index.d.ts +4 -2
  27. package/types/modules/filters/modules/filterConfig/components/trigger-job-state/trigger-job-state-filter-value-field.vue.d.ts +18 -0
  28. package/types/modules/filters/modules/filterConfig/components/trigger-job-state/trigger-job-state-filter-value-preview.vue.d.ts +6 -0
  29. package/types/modules/filters/modules/filterConfig/enums/FilterOption.d.ts +2 -0
  30. package/types/modules/filters/scripts/variableFilters.d.ts +1 -0
  31. package/types/modules/headers/createTableHeadersStore.d.ts +6 -0
  32. package/types/modules/permissions/components/_internal/permissions-role-row.vue.d.ts +17 -0
  33. package/types/modules/permissions/components/_internal/permissions-role-select.vue.d.ts +11 -0
  34. package/types/modules/permissions/components/_internal/permissions-tab-content.vue.d.ts +32 -0
  35. package/types/modules/permissions/components/_internal/permissions-tab-role-popup.vue.d.ts +10 -0
  36. package/types/modules/{permissions-page → permissions}/components/permissions-tab.vue.d.ts +1 -1
  37. package/types/modules/permissions/composables/useAccessModeOptions.d.ts +22 -0
  38. package/types/modules/permissions/index.d.ts +17 -0
  39. package/types/modules/permissions/stores/_internals/headers.d.ts +22 -0
  40. package/types/modules/{permissions-page → permissions}/stores/createPermissionsStore.d.ts +5 -3
  41. package/types/modules/{permissions-page → permissions}/types/Permission.types.d.ts +2 -2
  42. package/types/modules/permissions/types/PermissionsUserAccess.d.ts +3 -0
  43. package/src/modules/permissions-page/index.ts +0 -23
  44. package/src/modules/permissions-page/scripts/PermissionsApiModule.ts +0 -57
  45. package/src/modules/permissions-page/scripts/__tests__/PermissionsApiModule.spec.ts +0 -31
  46. package/types/modules/permissions-page/index.d.ts +0 -7
  47. package/types/modules/permissions-page/scripts/PermissionsApiModule.d.ts +0 -9
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <wt-popup
3
+ :shown="shown"
4
+ overflow
5
+ size="sm"
6
+ @close="close"
7
+ >
8
+ <template #title>
9
+ {{ `${t('reusable.new')} ${t('objects.grantee', 1).toLowerCase()}` }}
10
+ </template>
11
+ <template #main>
12
+ <permissions-role-select
13
+ v-model:model-value="grantee"
14
+ :clearable="false"
15
+ :placeholder="t('objects.role', 1)"
16
+ :search-method="getAvailableGrantees"
17
+ />
18
+ </template>
19
+ <template #actions>
20
+ <wt-button @click="save(grantee)">
21
+ {{ t('reusable.add') }}
22
+ </wt-button>
23
+ <wt-button
24
+ color="secondary"
25
+ @click="close"
26
+ >
27
+ {{ t('reusable.close') }}
28
+ </wt-button>
29
+ </template>
30
+ </wt-popup>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { RolesAPI } from '@webitel/api-services/api';
35
+ import { computed, ref } from 'vue';
36
+ import { useI18n } from 'vue-i18n';
37
+ import { useRoute, useRouter } from 'vue-router';
38
+
39
+ import type { PermissionGrantee } from '../../types/Permission.types';
40
+ import PermissionsRoleSelect from './permissions-role-select.vue';
41
+
42
+ const props = withDefaults(
43
+ defineProps<{
44
+ existingGranteeIds?: PermissionGrantee['id'][];
45
+ addRolePermissions: (role: PermissionGrantee) => Promise<unknown>;
46
+ }>(),
47
+ {
48
+ existingGranteeIds: () => [],
49
+ },
50
+ );
51
+
52
+ const { t } = useI18n();
53
+ const router = useRouter();
54
+ const route = useRoute();
55
+
56
+ const grantee = ref<PermissionGrantee | null>(null);
57
+
58
+ /** [Claude] opened by the route, the tab's "add" action sets `permissionId` */
59
+ const shown = computed(() => !!route.params.permissionId);
60
+
61
+ const close = () => {
62
+ const { query, hash, name } = route;
63
+ const { permissionId, ...params } = route.params;
64
+
65
+ grantee.value = null;
66
+
67
+ return router.push({
68
+ query,
69
+ hash,
70
+ name,
71
+ params,
72
+ });
73
+ };
74
+
75
+ const getAvailableGrantees = async (params: Record<string, unknown>) => {
76
+ const { items, ...rest } = await RolesAPI.getLookup(params);
77
+ return {
78
+ /** [Claude] acl grantee ids come as strings, role ids as numbers */
79
+ items: (items as PermissionGrantee[]).filter(
80
+ (role) =>
81
+ !props.existingGranteeIds.some((id) => String(id) === String(role.id)),
82
+ ),
83
+ ...rest,
84
+ };
85
+ };
86
+
87
+ const save = async (newGrantee: PermissionGrantee | null) => {
88
+ if (!newGrantee) return;
89
+ await props.addRolePermissions(newGrantee);
90
+ return close();
91
+ };
92
+ </script>
93
+
94
+ <style lang="scss" scoped></style>
@@ -15,15 +15,15 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- import {
19
- DEFAULT_PERMISSIONS_USER_ACCESS,
20
- PermissionsTabContent,
21
- type PermissionsUserAccess,
22
- } from '@webitel/ui-sdk/modules/ObjectPermissions';
23
18
  import type { Id } from '@webitel/ui-sdk/src/api/types/ApiModule';
24
19
  import { storeToRefs } from 'pinia';
25
20
  import { computed, onUnmounted } from 'vue';
26
21
  import type { PermissionsPiniaStore } from '../stores/createPermissionsStore';
22
+ import {
23
+ DEFAULT_PERMISSIONS_USER_ACCESS,
24
+ type PermissionsUserAccess,
25
+ } from '../types/PermissionsUserAccess';
26
+ import PermissionsTabContent from './_internal/permissions-tab-content.vue';
27
27
 
28
28
  const props = withDefaults(
29
29
  defineProps<{
@@ -0,0 +1,48 @@
1
+ import { AccessMode } from '@webitel/api-services/enums';
2
+ import { computed, type MaybeRefOrGetter, toValue } from 'vue';
3
+ import { useI18n } from 'vue-i18n';
4
+
5
+ interface AccessModeRow {
6
+ access: Record<
7
+ string,
8
+ {
9
+ id: number;
10
+ }
11
+ >;
12
+ }
13
+
14
+ /** [Claude] access mode select options, and the rows with a localized name on every rule */
15
+ export const useAccessModeOptions = <Row extends AccessModeRow>(
16
+ dataList: MaybeRefOrGetter<Row[]>,
17
+ ) => {
18
+ const { t } = useI18n();
19
+
20
+ const getAccessModeName = (mode: number) => t(`access.accessMode.${mode}`);
21
+
22
+ const accessOptions = computed(() =>
23
+ Object.values(AccessMode).map((mode) => ({
24
+ id: mode,
25
+ name: getAccessModeName(mode),
26
+ })),
27
+ );
28
+
29
+ const localizedDataList = computed(() =>
30
+ toValue(dataList).map((item) => ({
31
+ ...item,
32
+ access: Object.fromEntries(
33
+ Object.entries(item.access).map(([rule, value]) => [
34
+ rule,
35
+ {
36
+ ...value,
37
+ name: getAccessModeName(value.id),
38
+ },
39
+ ]),
40
+ ),
41
+ })),
42
+ );
43
+
44
+ return {
45
+ accessOptions,
46
+ localizedDataList,
47
+ };
48
+ };
@@ -0,0 +1,40 @@
1
+ import PermissionsRoleRow from './components/_internal/permissions-role-row.vue';
2
+ import PermissionsRoleSelect from './components/_internal/permissions-role-select.vue';
3
+ import PermissionsTabContent from './components/_internal/permissions-tab-content.vue';
4
+ import PermissionsRolePopup from './components/_internal/permissions-tab-role-popup.vue';
5
+ import PermissionsTab from './components/permissions-tab.vue';
6
+
7
+ /** [Claude] the acl enums and grants logic live in api-services; re-exported to keep permissions in one place */
8
+ export {
9
+ AccessMode,
10
+ AccessRuleColumn,
11
+ AccessRuleName,
12
+ } from '@webitel/api-services/enums';
13
+ export type { ResolveGrantsParams } from '@webitel/api-services/scripts';
14
+ export { resolveGrants } from '@webitel/api-services/scripts';
15
+
16
+ export { useAccessModeOptions } from './composables/useAccessModeOptions';
17
+ export { headers, headersWithCreate } from './stores/_internals/headers';
18
+ export type { PermissionsPiniaStore } from './stores/createPermissionsStore';
19
+ export {
20
+ createPermissionsStore,
21
+ permissionsStoreBody,
22
+ } from './stores/createPermissionsStore';
23
+ export type {
24
+ ChangeAccessModePayload,
25
+ PermissionAccessRule,
26
+ PermissionEntity,
27
+ PermissionGrantee,
28
+ PermissionsChange,
29
+ RawPermissionsApiModule,
30
+ } from './types/Permission.types';
31
+ export type { PermissionsUserAccess } from './types/PermissionsUserAccess';
32
+ export { DEFAULT_PERMISSIONS_USER_ACCESS } from './types/PermissionsUserAccess';
33
+
34
+ export {
35
+ PermissionsRolePopup,
36
+ PermissionsRoleRow,
37
+ PermissionsRoleSelect,
38
+ PermissionsTab,
39
+ PermissionsTabContent,
40
+ };
@@ -0,0 +1,52 @@
1
+ import { SortSymbols } from '@webitel/ui-sdk/src/scripts/sortQueryAdapters';
2
+
3
+ /**
4
+ * [Claude] Each rule column keeps its own `field` (`r`, `w`, `d`), so sorting
5
+ * one marks only that column and sends `sort=+r` / `+w` / `+d`. `GET
6
+ * <object>/:id/acl` has no such attributes in `fields` though — it returns the
7
+ * three rules merged into one `granted` string — so `PermissionsApiModule`
8
+ * asks for `granted` in their place.
9
+ */
10
+ export const headers = [
11
+ {
12
+ value: 'grantee',
13
+ locale: 'reusable.name',
14
+ field: 'grantee',
15
+ show: true,
16
+ sort: SortSymbols.NONE,
17
+ },
18
+ {
19
+ value: 'read',
20
+ locale: 'reusable.read',
21
+ field: 'r',
22
+ show: true,
23
+ sort: SortSymbols.NONE,
24
+ },
25
+ {
26
+ value: 'edit',
27
+ locale: 'reusable.edit',
28
+ field: 'w',
29
+ show: true,
30
+ sort: SortSymbols.NONE,
31
+ },
32
+ {
33
+ value: 'delete',
34
+ locale: 'reusable.delete',
35
+ field: 'd',
36
+ show: true,
37
+ sort: SortSymbols.NONE,
38
+ },
39
+ ];
40
+
41
+ /** [Claude] object classes OBAC also grants "create" (`x`), right after the grantee */
42
+ export const headersWithCreate = [
43
+ headers[0],
44
+ {
45
+ value: 'create',
46
+ locale: 'reusable.create',
47
+ field: 'granted',
48
+ show: true,
49
+ sort: SortSymbols.NONE,
50
+ },
51
+ ...headers.slice(1),
52
+ ];
@@ -1,5 +1,5 @@
1
- import { AccessMode, headers } from '@webitel/ui-sdk/modules/ObjectPermissions';
2
- import { AccessRuleName } from '@webitel/ui-sdk/modules/ObjectPermissions/enums';
1
+ import { AccessRuleName } from '@webitel/api-services/enums';
2
+ import { resolveGrants } from '@webitel/api-services/scripts';
3
3
  import type { Id } from '@webitel/ui-sdk/src/api/types/ApiModule';
4
4
  import type { StoreGeneric } from 'pinia';
5
5
  import { ref } from 'vue';
@@ -9,49 +9,19 @@ import {
9
9
  } from '../../_shared/createDatalistStore';
10
10
  import { tableStoreBody } from '../../table/createTableStore.store';
11
11
  import type { useTableStoreConfig } from '../../types/tableStore.types';
12
- import { PermissionsApiModule } from '../scripts/PermissionsApiModule';
13
12
  import type {
14
13
  ChangeAccessModePayload,
15
14
  PermissionEntity,
16
15
  PermissionsChange,
17
16
  RawPermissionsApiModule,
18
17
  } from '../types/Permission.types';
19
-
20
- const resolveModeId = (mode: ChangeAccessModePayload['mode']) =>
21
- typeof mode === 'number' ? mode : mode?.id;
22
-
23
- /*
24
- has | patch | got
25
- -----+-------+-----
26
- - | w | w
27
- w | w | -
28
- - | ww | ww
29
- w | ww | ww
30
- ww | ww | w
31
- ww | w | -
32
- */
33
- const resolveGrants = ({
34
- item,
35
- ruleName,
36
- mode,
37
- }: ChangeAccessModePayload): string | null => {
38
- const have = item.access[ruleName];
39
-
40
- switch (resolveModeId(mode)) {
41
- case AccessMode.Forbidden:
42
- return ruleName;
43
- case AccessMode.Allow:
44
- return have.rule || ruleName;
45
- case AccessMode.Manage:
46
- return `${ruleName}${ruleName}`;
47
- default:
48
- return null;
49
- }
50
- };
18
+ import { headers } from './_internals/headers';
51
19
 
52
20
  export const permissionsStoreBody = (
53
21
  namespace: string,
54
22
  config: useTableStoreConfig<PermissionEntity>,
23
+ /** [Claude] the entity api, whose `patchPermissions` takes acl changes, not a row patch */
24
+ permissionsApi: RawPermissionsApiModule,
55
25
  ) => {
56
26
  const tableStore = tableStoreBody<PermissionEntity>(namespace, config);
57
27
  const { dataList, selected, error, isLoading } = makeThisToRefs(
@@ -78,13 +48,10 @@ export const permissionsStoreBody = (
78
48
  };
79
49
 
80
50
  const patchPermissions = async (changes: PermissionsChange[]) => {
51
+ if (parentId.value === undefined) return;
52
+
81
53
  try {
82
- await (
83
- config.apiModule.patch as unknown as (payload: {
84
- id: Id | undefined;
85
- changes: PermissionsChange[];
86
- }) => Promise<unknown>
87
- )({
54
+ await permissionsApi.patchPermissions({
88
55
  id: parentId.value,
89
56
  changes,
90
57
  });
@@ -96,7 +63,11 @@ export const permissionsStoreBody = (
96
63
  };
97
64
 
98
65
  const changeAccessMode = async (payload: ChangeAccessModePayload) => {
99
- const grants = resolveGrants(payload);
66
+ const grants = resolveGrants({
67
+ have: payload.item.access[payload.ruleName],
68
+ ruleName: payload.ruleName,
69
+ mode: payload.mode,
70
+ });
100
71
  if (!grants) return;
101
72
 
102
73
  return patchPermissions([
@@ -152,12 +123,16 @@ export const createPermissionsStore = (
152
123
  saved by an older version would keep being sent to the api */
153
124
  disablePersistence: true,
154
125
  ...config,
155
- apiModule: PermissionsApiModule(config.apiModule),
126
+ /* [Claude] card apis carry their acl as `getPermissionsList`/`patchPermissions` (generatePermissionsApi); the table only lists it */
127
+ apiModule: {
128
+ getList: config.apiModule.getPermissionsList,
129
+ },
156
130
  headers: config.headers || headers,
157
131
  };
158
132
 
159
133
  return createDatalistStore({
160
- storeBody: () => permissionsStoreBody(namespace, normalizedConfig),
134
+ storeBody: () =>
135
+ permissionsStoreBody(namespace, normalizedConfig, config.apiModule),
161
136
  namespace,
162
137
  config: normalizedConfig,
163
138
  });
@@ -1,4 +1,4 @@
1
- import type { AccessRuleName } from '@webitel/ui-sdk/modules/ObjectPermissions/enums';
1
+ import type { AccessRuleName } from '@webitel/api-services/enums';
2
2
  import type { ApiModule, Id } from '@webitel/ui-sdk/src/api/types/ApiModule';
3
3
 
4
4
  export interface PermissionGrantee {
@@ -29,7 +29,7 @@ export interface PermissionsChange {
29
29
  * spread into every card API module (e.g. `...generatePermissionsApi(baseUrl)`).
30
30
  */
31
31
  export interface RawPermissionsApiModule {
32
- getPermissionsList: ApiModule<PermissionEntity>['getList'];
32
+ getPermissionsList: NonNullable<ApiModule<PermissionEntity>['getList']>;
33
33
  patchPermissions: (payload: {
34
34
  id: Id;
35
35
  changes: PermissionsChange[];
@@ -0,0 +1,10 @@
1
+ import { CrudAction } from '@webitel/ui-sdk/enums';
2
+
3
+ export type PermissionsUserAccess = Record<CrudAction, boolean>;
4
+
5
+ export const DEFAULT_PERMISSIONS_USER_ACCESS: PermissionsUserAccess = {
6
+ [CrudAction.Read]: false,
7
+ [CrudAction.Create]: false,
8
+ [CrudAction.Update]: false,
9
+ [CrudAction.Delete]: false,
10
+ };