@drax/identity-vue 0.5.4 → 0.5.5
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/package.json +5 -5
- package/src/combobox/RoleCombobox.vue +9 -1
- package/src/combobox/TenantCombobox.vue +11 -9
- package/src/components/IdentityChangeOwnPassword/IdentityChangeOwnPassword.vue +4 -4
- package/src/components/IdentityProfileDrawer/IdentityProfileDrawer.vue +2 -2
- package/src/cruds/role-crud/RoleCrud.ts +9 -1
- package/src/cruds/role-crud/RoleForm.vue +116 -0
- package/src/cruds/tenant-crud/TenantCrud.ts +8 -0
- package/src/cruds/user-crud/PasswordUpdateButton.vue +25 -0
- package/src/cruds/user-crud/UserCrud.ts +11 -0
- package/src/cruds/user-crud/UserCrud.vue +4 -17
- package/src/cruds/user-crud/UserForm.vue +177 -0
- package/src/cruds/user-crud/UserPasswordDialog.vue +94 -0
- package/src/{forms → cruds/user-crud}/UserPasswordForm.vue +4 -2
- package/src/index.ts +7 -21
- package/src/pages/ProfilePage.vue +1 -1
- package/src/pages/{RoleCrudPage.vue → crud/RoleCrudPage.vue} +11 -10
- package/src/pages/{TenantCrudPage.vue → crud/TenantCrudPage.vue} +1 -1
- package/src/pages/{UserApiKeyCrudPage.vue → crud/UserApiKeyCrudPage.vue} +1 -1
- package/src/pages/crud/UserCrudPage.vue +61 -0
- package/src/routes/IdentityRoutes.ts +5 -35
- package/src/cruds/role-crud/RoleCrud.vue +0 -171
- package/src/cruds/role-crud/RoleList.vue +0 -129
- package/src/cruds/tenant-crud/TenantCrud.vue +0 -168
- package/src/cruds/tenant-crud/TenantList.vue +0 -108
- package/src/cruds/user-crud/UserList.vue +0 -110
- package/src/forms/RoleForm.vue +0 -89
- package/src/forms/RoleFormOld.vue +0 -57
- package/src/forms/TenantForm.vue +0 -48
- package/src/forms/UserCreateForm.vue +0 -115
- package/src/forms/UserEditForm.vue +0 -101
- package/src/pages/RoleCrudCustomPage.vue +0 -12
- package/src/pages/TenantCrudCustomPage.vue +0 -12
- package/src/pages/UserCrudCustomPage.vue +0 -12
- package/src/pages/UserCrudPage.vue +0 -18
|
@@ -50,7 +50,7 @@ const onSubmit = () => {
|
|
|
50
50
|
<v-sheet v-else>
|
|
51
51
|
<form ref="changeUserPassword" @submit.prevent="onSubmit">
|
|
52
52
|
|
|
53
|
-
<div class="text-subtitle-1 text-medium-emphasis">{{ t('user.newPassword') }}</div>
|
|
53
|
+
<div class="text-subtitle-1 text-medium-emphasis">{{ t('user.field.newPassword') }}</div>
|
|
54
54
|
<v-text-field
|
|
55
55
|
variant="outlined"
|
|
56
56
|
id="new-password-input"
|
|
@@ -63,7 +63,9 @@ const onSubmit = () => {
|
|
|
63
63
|
autocomplete="new-password"
|
|
64
64
|
:error-messages="$ta(inputErrors.newPassword)"
|
|
65
65
|
></v-text-field>
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
<div class="text-subtitle-1 text-medium-emphasis">{{ t('user.field.confirmPassword') }}</div>
|
|
68
|
+
|
|
67
69
|
<v-text-field
|
|
68
70
|
variant="outlined"
|
|
69
71
|
id="confirm-password-input"
|
package/src/index.ts
CHANGED
|
@@ -4,35 +4,28 @@ import IdentityProfileDrawer from "./components/IdentityProfileDrawer/IdentityPr
|
|
|
4
4
|
import IdentityProfileView from "./components/IdentityProfileView/IdentityProfileView.vue";
|
|
5
5
|
|
|
6
6
|
import UserCrud from "./cruds/user-crud/UserCrud.vue";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import UserCreateForm from "./forms/UserCreateForm.vue";
|
|
10
|
-
import UserEditForm from "./forms/UserEditForm.vue";
|
|
7
|
+
import UserCrudPage from "./pages/crud/UserCrudPage.vue";
|
|
8
|
+
import UserForm from "./cruds/user-crud/UserForm.vue";
|
|
11
9
|
import UserView from "./views/UserView.vue";
|
|
12
10
|
|
|
13
|
-
import RoleForm from "./
|
|
11
|
+
import RoleForm from "./cruds/role-crud/RoleForm.vue";
|
|
14
12
|
import RoleView from "./views/RoleView.vue";
|
|
15
|
-
import
|
|
16
|
-
import RoleList from "./cruds/role-crud/RoleList.vue";
|
|
17
|
-
import RoleCrudPage from "./pages/RoleCrudPage.vue";
|
|
13
|
+
import RoleCrudPage from "./pages/crud/RoleCrudPage.vue";
|
|
18
14
|
|
|
19
15
|
import LoginPage from "./pages/LoginPage.vue";
|
|
20
16
|
import ProfilePage from "./pages/ProfilePage.vue";
|
|
21
17
|
import PasswordPage from "./pages/PasswordPage.vue";
|
|
22
18
|
|
|
23
19
|
|
|
24
|
-
import TenantForm from "./forms/TenantForm.vue";
|
|
25
20
|
import TenantView from "./views/TenantView.vue";
|
|
26
|
-
import
|
|
27
|
-
import TenantList from "./cruds/tenant-crud/TenantList.vue";
|
|
28
|
-
import TenantCrudPage from "./pages/TenantCrudPage.vue";
|
|
21
|
+
import TenantCrudPage from "./pages/crud/TenantCrudPage.vue";
|
|
29
22
|
|
|
30
23
|
|
|
31
24
|
import UserApiKeyForm from "./forms/UserApiKeyForm.vue";
|
|
32
25
|
import UserApiKeyView from "./views/UserApiKeyView.vue";
|
|
33
26
|
import UserApiKeyCrud from "./cruds/user-api-key-crud/UserApiKeyCrud.vue";
|
|
34
27
|
import UserApiKeyList from "./cruds/user-api-key-crud/UserApiKeyList.vue";
|
|
35
|
-
import UserApiKeyCrudPage from "./pages/UserApiKeyCrudPage.vue";
|
|
28
|
+
import UserApiKeyCrudPage from "./pages/crud/UserApiKeyCrudPage.vue";
|
|
36
29
|
|
|
37
30
|
import {useAuth} from "./composables/useAuth.js";
|
|
38
31
|
import {useUser} from "./composables/useUser.js";
|
|
@@ -60,10 +53,8 @@ export {
|
|
|
60
53
|
|
|
61
54
|
//User
|
|
62
55
|
UserView,
|
|
63
|
-
|
|
64
|
-
UserEditForm,
|
|
56
|
+
UserForm,
|
|
65
57
|
UserCrud,
|
|
66
|
-
UserList,
|
|
67
58
|
UserCrudPage,
|
|
68
59
|
useAuth,
|
|
69
60
|
useUser,
|
|
@@ -71,16 +62,11 @@ export {
|
|
|
71
62
|
//Role
|
|
72
63
|
RoleView,
|
|
73
64
|
RoleForm,
|
|
74
|
-
RoleCrud,
|
|
75
|
-
RoleList,
|
|
76
65
|
RoleCrudPage,
|
|
77
66
|
useRole,
|
|
78
67
|
|
|
79
68
|
//Tenant
|
|
80
69
|
TenantView,
|
|
81
|
-
TenantForm,
|
|
82
|
-
TenantCrud,
|
|
83
|
-
TenantList,
|
|
84
70
|
TenantCrudPage,
|
|
85
71
|
useTenant,
|
|
86
72
|
|
|
@@ -16,7 +16,7 @@ const { t } = useI18n();
|
|
|
16
16
|
<identity-profile-view> </identity-profile-view>
|
|
17
17
|
<v-card-text class="text-center">
|
|
18
18
|
<v-btn color="blue" variant="tonal" @click="router.push({name: 'Password'})">
|
|
19
|
-
{{t('user.changeOwnPassword')}}
|
|
19
|
+
{{t('user.action.changeOwnPassword')}}
|
|
20
20
|
</v-btn>
|
|
21
21
|
</v-card-text>
|
|
22
22
|
</v-card>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import {Crud, useCrud} from "@drax/crud-vue";
|
|
3
|
-
import RoleCrud from "
|
|
4
|
-
import RoleForm from "
|
|
3
|
+
import RoleCrud from "../../cruds/role-crud/RoleCrud";
|
|
4
|
+
import RoleForm from "../../cruds/role-crud/RoleForm.vue";
|
|
5
5
|
import {useI18n} from "vue-i18n";
|
|
6
6
|
|
|
7
7
|
const {t, te} = useI18n()
|
|
@@ -34,14 +34,15 @@ const {
|
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<template v-slot:item.childRoles="{ value }">
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
|
|
38
|
+
<v-chip
|
|
39
|
+
v-for="role in value"
|
|
40
|
+
:key="role" color="blue"
|
|
41
|
+
class="ma-1"
|
|
42
|
+
>
|
|
43
|
+
{{ role.name }}
|
|
44
|
+
</v-chip>
|
|
45
|
+
|
|
45
46
|
</template>
|
|
46
47
|
|
|
47
48
|
<template v-slot:item.readonly="{ value }">
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {ref} from "vue"
|
|
3
|
+
import UserCrud from "../../cruds/user-crud/UserCrud";
|
|
4
|
+
import {Crud, useCrud} from "@drax/crud-vue";
|
|
5
|
+
import UserForm from "../../cruds/user-crud/UserForm.vue";
|
|
6
|
+
import PasswordUpdateButton from "../../cruds/user-crud/PasswordUpdateButton.vue";
|
|
7
|
+
import UserPasswordDialog from "../../cruds/user-crud/UserPasswordDialog.vue";
|
|
8
|
+
import type {IUser} from "@drax/identity-share";
|
|
9
|
+
|
|
10
|
+
const {onCancel, onSubmit,form, operation } = useCrud(UserCrud.instance);
|
|
11
|
+
|
|
12
|
+
const dialogPassword = ref(false);
|
|
13
|
+
const userSelected = ref();
|
|
14
|
+
|
|
15
|
+
function onChangePassword(user:IUser){
|
|
16
|
+
console.log("onChangePassword for user: ", user);
|
|
17
|
+
userSelected.value = user;
|
|
18
|
+
dialogPassword.value = true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<div>
|
|
25
|
+
<user-password-dialog
|
|
26
|
+
v-if="dialogPassword && userSelected"
|
|
27
|
+
v-model="dialogPassword"
|
|
28
|
+
:user="userSelected"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<crud :entity="UserCrud.instance">
|
|
32
|
+
|
|
33
|
+
<template v-slot:form>
|
|
34
|
+
<user-form
|
|
35
|
+
:enable-password="operation === 'create'"
|
|
36
|
+
v-model="form"
|
|
37
|
+
@submit="onSubmit"
|
|
38
|
+
@cancel="onCancel"
|
|
39
|
+
/>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
<template v-slot:item.actions="{ item }">
|
|
45
|
+
<password-update-button @click="onChangePassword(item as IUser)"></password-update-button>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<template v-slot:item.active="{ value }" >
|
|
50
|
+
<v-chip :color="value ? 'green':'red'" >
|
|
51
|
+
{{ value ? 'Active' : 'Inactive' }}
|
|
52
|
+
</v-chip>
|
|
53
|
+
</template>
|
|
54
|
+
</crud>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<style scoped>
|
|
60
|
+
|
|
61
|
+
</style>
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import LoginPage from '../pages/LoginPage.vue'
|
|
2
2
|
import ProfilePage from '../pages/ProfilePage.vue'
|
|
3
3
|
import PasswordPage from '../pages/PasswordPage.vue'
|
|
4
|
-
import UserCrudPage from '../pages/UserCrudPage.vue'
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import TenantCrudPage from '../pages/TenantCrudPage.vue'
|
|
9
|
-
import TenantCrudCustomPage from '../pages/TenantCrudCustomPage.vue'
|
|
10
|
-
import UserApiKeyCrudPage from '../pages/UserApiKeyCrudPage.vue'
|
|
4
|
+
import UserCrudPage from '../pages/crud/UserCrudPage.vue'
|
|
5
|
+
import RoleCrudPage from '../pages/crud/RoleCrudPage.vue'
|
|
6
|
+
import TenantCrudPage from '../pages/crud/TenantCrudPage.vue'
|
|
7
|
+
import UserApiKeyCrudPage from '../pages/crud/UserApiKeyCrudPage.vue'
|
|
11
8
|
|
|
12
9
|
const routes = [
|
|
13
10
|
{
|
|
@@ -74,34 +71,7 @@ const routes = [
|
|
|
74
71
|
}
|
|
75
72
|
},
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
{
|
|
79
|
-
name: 'CrudCustomTenant',
|
|
80
|
-
path: '/crud/custom/tenant',
|
|
81
|
-
component: TenantCrudCustomPage,
|
|
82
|
-
meta: {
|
|
83
|
-
auth: true,
|
|
84
|
-
permission: 'tenant:manage'
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: 'CrudRoleCustom',
|
|
89
|
-
path: '/crud/custom/role',
|
|
90
|
-
component: RoleCrudCustomPage,
|
|
91
|
-
meta: {
|
|
92
|
-
auth: true,
|
|
93
|
-
permission: 'role:manage'
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'CrudCustomUser',
|
|
98
|
-
path: '/crud/custom/user',
|
|
99
|
-
component: UserCrudCustomPage,
|
|
100
|
-
meta: {
|
|
101
|
-
auth: true,
|
|
102
|
-
permission: 'user:manage'
|
|
103
|
-
}
|
|
104
|
-
},
|
|
74
|
+
|
|
105
75
|
|
|
106
76
|
]
|
|
107
77
|
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {computed, ref} from 'vue'
|
|
3
|
-
import RoleList from "./RoleList.vue";
|
|
4
|
-
import {useRole} from "../../composables/useRole";
|
|
5
|
-
import type {IRole, IRoleBase} from "@drax/identity-share";
|
|
6
|
-
import RoleForm from "../../forms/RoleForm.vue";
|
|
7
|
-
import RoleView from "../../views/RoleView.vue";
|
|
8
|
-
import {useI18n} from "vue-i18n";
|
|
9
|
-
const {t} = useI18n()
|
|
10
|
-
const {createRole, editRole, deleteRole, loading, roleError, inputErrors} = useRole()
|
|
11
|
-
|
|
12
|
-
interface RoleList {
|
|
13
|
-
loadItems: () => void;
|
|
14
|
-
items: IRole[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type DialogMode = 'create' | 'edit' | 'delete' | null;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
let dialog = ref(false);
|
|
21
|
-
let dialogMode = ref<DialogMode>(null);
|
|
22
|
-
let dialogTitle = ref('');
|
|
23
|
-
const roleList = ref<RoleList | null>(null);
|
|
24
|
-
let form = ref<IRoleBase>({name: "", permissions: [], childRoles:[], readonly: false})
|
|
25
|
-
let target = ref<IRole>();
|
|
26
|
-
let targetId = ref<string>('');
|
|
27
|
-
let filterEnable = ref(false);
|
|
28
|
-
|
|
29
|
-
function cancel() {
|
|
30
|
-
dialog.value = false
|
|
31
|
-
inputErrors.value = {}
|
|
32
|
-
roleError.value = '';
|
|
33
|
-
dialogMode.value = null
|
|
34
|
-
dialogTitle.value = ''
|
|
35
|
-
targetId.value = ''
|
|
36
|
-
target.value = undefined
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function save() {
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
if (dialogMode.value === 'create') {
|
|
43
|
-
await createRole(form.value)
|
|
44
|
-
} else if (dialogMode.value === 'edit') {
|
|
45
|
-
await editRole(targetId.value, form.value)
|
|
46
|
-
} else if (dialogMode.value === 'delete') {
|
|
47
|
-
await deleteRole(targetId.value)
|
|
48
|
-
}
|
|
49
|
-
dialog.value = false
|
|
50
|
-
inputErrors.value = {}
|
|
51
|
-
roleError.value = '';
|
|
52
|
-
if (roleList.value !== null) {
|
|
53
|
-
roleList.value.loadItems()
|
|
54
|
-
}
|
|
55
|
-
} catch (e) {
|
|
56
|
-
console.error(e)
|
|
57
|
-
if (e instanceof Error) {
|
|
58
|
-
roleError.value = e.message
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let buttonText = computed(() => {
|
|
64
|
-
switch (dialogMode.value) {
|
|
65
|
-
case 'create':
|
|
66
|
-
return 'action.create'
|
|
67
|
-
case 'edit':
|
|
68
|
-
return 'action.update'
|
|
69
|
-
case 'delete':
|
|
70
|
-
return 'action.delete'
|
|
71
|
-
default:
|
|
72
|
-
return 'action.sent'
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
function toCreate() {
|
|
77
|
-
dialogMode.value = 'create';
|
|
78
|
-
dialogTitle.value = 'role.creating';
|
|
79
|
-
form.value = {name: "", permissions: [], childRoles:[], readonly: false}
|
|
80
|
-
dialog.value = true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function toEdit(item: IRole) {
|
|
84
|
-
dialogMode.value = 'edit';
|
|
85
|
-
dialogTitle.value = 'role.updating';
|
|
86
|
-
targetId.value = item.id;
|
|
87
|
-
form.value = {
|
|
88
|
-
name: item.name,
|
|
89
|
-
permissions: item.permissions,
|
|
90
|
-
childRoles: item.childRoles ? item.childRoles.map(c => c.id) : [],
|
|
91
|
-
readonly: item.readonly
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
dialog.value = true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function toDelete(item: IRole) {
|
|
98
|
-
console.log('toDelete', item)
|
|
99
|
-
dialogMode.value = 'delete';
|
|
100
|
-
dialogTitle.value = 'role.deleting';
|
|
101
|
-
target.value = item
|
|
102
|
-
const {id} = item;
|
|
103
|
-
targetId.value = id;
|
|
104
|
-
dialog.value = true;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
</script>
|
|
108
|
-
|
|
109
|
-
<template>
|
|
110
|
-
<v-container fluid>
|
|
111
|
-
|
|
112
|
-
<v-card border rounded>
|
|
113
|
-
<v-toolbar class="bg-toolbar">
|
|
114
|
-
<v-toolbar-title>{{t('role.managing')}}</v-toolbar-title>
|
|
115
|
-
<v-spacer></v-spacer>
|
|
116
|
-
<v-btn icon @click="filterEnable = !filterEnable">
|
|
117
|
-
<v-icon>{{ filterEnable ? 'mdi-filter' : 'mdi-filter-off' }}</v-icon>
|
|
118
|
-
</v-btn>
|
|
119
|
-
<v-btn color="primary" @click="toCreate">
|
|
120
|
-
{{t('action.create') }}
|
|
121
|
-
</v-btn>
|
|
122
|
-
</v-toolbar>
|
|
123
|
-
<v-theme-provider with-background class="pa-2 rounded-b">
|
|
124
|
-
<RoleList
|
|
125
|
-
ref="roleList"
|
|
126
|
-
@toEdit="toEdit"
|
|
127
|
-
@toDelete="toDelete"
|
|
128
|
-
:filterEnable="filterEnable"
|
|
129
|
-
/>
|
|
130
|
-
</v-theme-provider>
|
|
131
|
-
</v-card>
|
|
132
|
-
|
|
133
|
-
<v-dialog v-model="dialog" max-width="800">
|
|
134
|
-
<v-sheet border>
|
|
135
|
-
<v-toolbar>
|
|
136
|
-
<v-toolbar-title>{{ dialogTitle ? t(dialogTitle) : '-' }}</v-toolbar-title>
|
|
137
|
-
</v-toolbar>
|
|
138
|
-
<v-card class="pa-10">
|
|
139
|
-
<v-card-text v-if="roleError">
|
|
140
|
-
<v-alert type="error">{{ roleError }}</v-alert>
|
|
141
|
-
</v-card-text>
|
|
142
|
-
<v-card-text>
|
|
143
|
-
<RoleForm v-if="dialogMode === 'create' || dialogMode === 'edit'"
|
|
144
|
-
v-model="form"
|
|
145
|
-
:inputErrors="inputErrors"
|
|
146
|
-
@formSubmit="save"
|
|
147
|
-
/>
|
|
148
|
-
<RoleView v-if="dialogMode === 'delete' && target" :role="target"></RoleView>
|
|
149
|
-
</v-card-text>
|
|
150
|
-
<v-card-actions>
|
|
151
|
-
<v-spacer></v-spacer>
|
|
152
|
-
<v-btn variant="text" @click="cancel" :loading="loading">Cancelar</v-btn>
|
|
153
|
-
<v-btn variant="flat"
|
|
154
|
-
:color="dialogMode==='delete' ? 'red' : 'primary'"
|
|
155
|
-
@click="save"
|
|
156
|
-
:loading="loading"
|
|
157
|
-
>
|
|
158
|
-
{{ t(buttonText) }}
|
|
159
|
-
</v-btn>
|
|
160
|
-
</v-card-actions>
|
|
161
|
-
|
|
162
|
-
</v-card>
|
|
163
|
-
</v-sheet>
|
|
164
|
-
</v-dialog>
|
|
165
|
-
|
|
166
|
-
</v-container>
|
|
167
|
-
</template>
|
|
168
|
-
|
|
169
|
-
<style scoped>
|
|
170
|
-
|
|
171
|
-
</style>
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
import {defineProps, type Ref, ref} from "vue";
|
|
4
|
-
import {useRole} from "../../composables/useRole";
|
|
5
|
-
import {useAuth} from "../../composables/useAuth";
|
|
6
|
-
import {useI18n} from "vue-i18n";
|
|
7
|
-
import type {IRole} from "@drax/identity-share";
|
|
8
|
-
|
|
9
|
-
const {hasPermission} = useAuth()
|
|
10
|
-
const {paginateRole} = useRole()
|
|
11
|
-
const {t,te} = useI18n()
|
|
12
|
-
|
|
13
|
-
defineProps({
|
|
14
|
-
filterEnable: {
|
|
15
|
-
type: Boolean,
|
|
16
|
-
default: false,
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const itemsPerPage = ref(5)
|
|
21
|
-
const page = ref(1)
|
|
22
|
-
const headers = ref<any>([
|
|
23
|
-
//{title: 'ID', align: 'start', sortable: false, key: 'id'},
|
|
24
|
-
{ title: t('role.name') as string, key: 'name', align: 'start' },
|
|
25
|
-
{ title: t('role.childRoles') as string, key: 'childRoles', align: 'start' },
|
|
26
|
-
{ title: t('role.permissions') as string, key: 'permissions', align: 'start' },
|
|
27
|
-
{ title: t('role.readonly') as string, key: 'readonly', align: 'start' },
|
|
28
|
-
{ title: '', key: 'actions', align: 'end', minWidth: '150px' },
|
|
29
|
-
])
|
|
30
|
-
|
|
31
|
-
const serverItems: Ref<IRole[]> = ref([]);
|
|
32
|
-
const totalItems = ref(0)
|
|
33
|
-
const loading = ref(false)
|
|
34
|
-
const search = ref('')
|
|
35
|
-
const sortBy : Ref<any> = ref([])
|
|
36
|
-
|
|
37
|
-
async function loadItems(){
|
|
38
|
-
try{
|
|
39
|
-
loading.value = true
|
|
40
|
-
const r = await paginateRole({
|
|
41
|
-
page: page.value,
|
|
42
|
-
limit: itemsPerPage.value,
|
|
43
|
-
orderBy: sortBy.value[0]?.key,
|
|
44
|
-
order: sortBy.value[0]?.order,
|
|
45
|
-
search: search.value})
|
|
46
|
-
serverItems.value = r.items
|
|
47
|
-
totalItems.value = r.total
|
|
48
|
-
}catch (e){
|
|
49
|
-
console.error(e)
|
|
50
|
-
}finally {
|
|
51
|
-
loading.value = false
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
defineExpose({
|
|
58
|
-
loadItems
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<template>
|
|
64
|
-
<v-data-table-server
|
|
65
|
-
v-if="hasPermission('user:manage')"
|
|
66
|
-
v-model:items-per-page="itemsPerPage"
|
|
67
|
-
:items-per-page-options="[5, 10, 20, 50]"
|
|
68
|
-
v-model:page="page"
|
|
69
|
-
v-model:sort-by="sortBy"
|
|
70
|
-
:headers="headers"
|
|
71
|
-
:items="serverItems"
|
|
72
|
-
:items-length="totalItems"
|
|
73
|
-
:loading="loading"
|
|
74
|
-
:search="search"
|
|
75
|
-
item-value="name"
|
|
76
|
-
@update:options="loadItems"
|
|
77
|
-
>
|
|
78
|
-
<template v-slot:top>
|
|
79
|
-
<v-toolbar density="compact" v-if="filterEnable">
|
|
80
|
-
<v-toolbar-title>{{ t('action.filters') }}</v-toolbar-title>
|
|
81
|
-
<v-spacer></v-spacer>
|
|
82
|
-
<v-text-field v-model="search" hide-details
|
|
83
|
-
density="compact" class="mr-2"
|
|
84
|
-
variant="outlined"
|
|
85
|
-
append-inner-icon="mdi-magnify"
|
|
86
|
-
:label="t('action.search')"
|
|
87
|
-
single-line clearable @click:clear="() => search = ''"
|
|
88
|
-
/>
|
|
89
|
-
|
|
90
|
-
</v-toolbar>
|
|
91
|
-
</template>
|
|
92
|
-
<template v-slot:item.permissions="{ value }" >
|
|
93
|
-
<v-chip v-for="permission in value"
|
|
94
|
-
:key="permission" color="green"
|
|
95
|
-
class="ma-1"
|
|
96
|
-
>
|
|
97
|
-
{{te(`permission.${permission}`) ? t(`permission.${permission}`) : permission }}
|
|
98
|
-
</v-chip>
|
|
99
|
-
</template>
|
|
100
|
-
|
|
101
|
-
<template v-slot:item.childRoles="{ value }" >
|
|
102
|
-
<v-chip v-for="role in value"
|
|
103
|
-
:key="role" color="blue"
|
|
104
|
-
class="ma-1"
|
|
105
|
-
>
|
|
106
|
-
{{role.name}}
|
|
107
|
-
</v-chip>
|
|
108
|
-
</template>
|
|
109
|
-
|
|
110
|
-
<template v-slot:item.readonly="{ value }" >
|
|
111
|
-
<v-chip v-if="value" color="red" >
|
|
112
|
-
<v-icon class="mdi mdi-pencil-off-outline"></v-icon>
|
|
113
|
-
</v-chip>
|
|
114
|
-
<v-chip v-else color="green">
|
|
115
|
-
<v-icon class="mdi mdi-pencil-outline"></v-icon>
|
|
116
|
-
</v-chip>
|
|
117
|
-
</template>
|
|
118
|
-
|
|
119
|
-
<template v-slot:item.actions="{item}" >
|
|
120
|
-
<v-btn v-if="hasPermission('role:update')" :disabled="!!item.readonly" icon="mdi-pencil" variant="text" color="primary" @click="$emit('toEdit', item)"></v-btn>
|
|
121
|
-
<v-btn v-if="hasPermission('role:delete')" :disabled="!!item.readonly" icon="mdi-delete" class="mr-1" variant="text" color="red" @click="$emit('toDelete', item)"></v-btn>
|
|
122
|
-
</template>
|
|
123
|
-
|
|
124
|
-
</v-data-table-server>
|
|
125
|
-
</template>
|
|
126
|
-
|
|
127
|
-
<style scoped>
|
|
128
|
-
|
|
129
|
-
</style>
|