@drax/identity-vue 0.5.3 → 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 +6 -5
- package/src/combobox/RoleCombobox.vue +24 -19
- 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/components/PermissionSelector/PermissionSelector.vue +4 -7
- package/src/cruds/role-crud/RoleCrud.ts +91 -0
- package/src/cruds/role-crud/RoleForm.vue +116 -0
- package/src/cruds/tenant-crud/TenantCrud.ts +17 -3
- package/src/cruds/user-crud/PasswordUpdateButton.vue +25 -0
- package/src/cruds/user-crud/UserCrud.ts +112 -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/crud/RoleCrudPage.vue +62 -0
- 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 +70 -64
- 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 -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/RoleCrudPage.vue +0 -12
- package/src/pages/TenantCrudPageOld.vue +0 -12
- package/src/pages/UserCrudPage.vue +0 -12
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {useFormUtils, useCrudStore} from "@drax/crud-vue";
|
|
3
|
+
import {defineEmits, defineModel, defineProps, ref} from "vue";
|
|
4
|
+
import {useI18nValidation} from "@drax/common-vue";
|
|
5
|
+
import RoleCombobox from "../../combobox/RoleCombobox.vue";
|
|
6
|
+
import TenantCombobox from "../../combobox/TenantCombobox.vue";
|
|
7
|
+
import {useI18n} from "vue-i18n";
|
|
8
|
+
|
|
9
|
+
const {$ta} = useI18nValidation()
|
|
10
|
+
const {t, te} = useI18n()
|
|
11
|
+
|
|
12
|
+
defineProps({
|
|
13
|
+
enablePassword: {type: Boolean, default: false}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const valueModel = defineModel({type: [Object]})
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits(['submit', 'cancel'])
|
|
19
|
+
|
|
20
|
+
const store = useCrudStore()
|
|
21
|
+
|
|
22
|
+
const valid = ref()
|
|
23
|
+
const formRef = ref()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async function submit() {
|
|
27
|
+
store.resetErrors()
|
|
28
|
+
await formRef.value.validate()
|
|
29
|
+
if (valid.value) {
|
|
30
|
+
emit('submit', valueModel.value)
|
|
31
|
+
} else {
|
|
32
|
+
console.log('Invalid form')
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function cancel() {
|
|
37
|
+
emit('cancel')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
variant, submitColor, readonly
|
|
42
|
+
} = useFormUtils(store.operation)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
let passwordVisibility = ref(false)
|
|
46
|
+
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<v-form v-model="valid" ref="formRef" @submit.prevent="submit">
|
|
51
|
+
<v-card flat>
|
|
52
|
+
|
|
53
|
+
<v-alert v-if="valueModel.readonly && store.operation != 'view'" type="warning">
|
|
54
|
+
{{ t('role.readonly') }}
|
|
55
|
+
</v-alert>
|
|
56
|
+
|
|
57
|
+
<v-card-text v-if="store.error">
|
|
58
|
+
<v-alert color="error">{{ te(store.error) ? t(store.error) : store.error }}</v-alert>
|
|
59
|
+
</v-card-text>
|
|
60
|
+
|
|
61
|
+
<v-card-text>
|
|
62
|
+
|
|
63
|
+
<v-text-field
|
|
64
|
+
id="name-input"
|
|
65
|
+
:label="$t('user.field.name')"
|
|
66
|
+
v-model="valueModel.name"
|
|
67
|
+
prepend-inner-icon="mdi-card-account-details"
|
|
68
|
+
:variant="variant"
|
|
69
|
+
:rules="[v => !!v || t('validation.required')]"
|
|
70
|
+
:error-messages="$ta(store.inputErrors?.name)"
|
|
71
|
+
:readonly="readonly"
|
|
72
|
+
></v-text-field>
|
|
73
|
+
|
|
74
|
+
<v-text-field
|
|
75
|
+
id="username-input"
|
|
76
|
+
:label="$t('user.field.username')"
|
|
77
|
+
v-model="valueModel.username"
|
|
78
|
+
prepend-inner-icon="mdi-account-question"
|
|
79
|
+
:variant="variant"
|
|
80
|
+
:rules="[v => !!v || t('validation.required')]"
|
|
81
|
+
autocomplete="new-username"
|
|
82
|
+
:error-messages="$ta(store.inputErrors?.username)"
|
|
83
|
+
:readonly="readonly"
|
|
84
|
+
></v-text-field>
|
|
85
|
+
|
|
86
|
+
<v-text-field
|
|
87
|
+
v-if="enablePassword"
|
|
88
|
+
id="password-input"
|
|
89
|
+
:label="$t('user.field.password')"
|
|
90
|
+
v-model="valueModel.password"
|
|
91
|
+
:type="passwordVisibility ? 'text': 'password'"
|
|
92
|
+
:variant="variant"
|
|
93
|
+
:rules="[v => !!v || t('validation.required')]"
|
|
94
|
+
prepend-inner-icon="mdi-lock-outline"
|
|
95
|
+
:append-inner-icon="passwordVisibility ? 'mdi-eye-off': 'mdi-eye'"
|
|
96
|
+
@click:append-inner="passwordVisibility = !passwordVisibility"
|
|
97
|
+
autocomplete="new-password"
|
|
98
|
+
:error-messages="$ta(store.inputErrors?.password)"
|
|
99
|
+
:readonly="readonly"
|
|
100
|
+
></v-text-field>
|
|
101
|
+
|
|
102
|
+
<RoleCombobox
|
|
103
|
+
v-model="valueModel.role"
|
|
104
|
+
:label="$t('user.field.role')"
|
|
105
|
+
:variant="variant"
|
|
106
|
+
:rules="[(v:any) => !!v || t('validation.required')]"
|
|
107
|
+
:error-messages="$ta(store.inputErrors?.role)"
|
|
108
|
+
:readonly="readonly"
|
|
109
|
+
></RoleCombobox>
|
|
110
|
+
|
|
111
|
+
<TenantCombobox
|
|
112
|
+
v-model="valueModel.tenant"
|
|
113
|
+
:label="$t('user.field.tenant')"
|
|
114
|
+
:variant="variant"
|
|
115
|
+
:error-messages="$ta(store.inputErrors?.tenant)"
|
|
116
|
+
clearable
|
|
117
|
+
:readonly="readonly"
|
|
118
|
+
></TenantCombobox>
|
|
119
|
+
|
|
120
|
+
<v-text-field
|
|
121
|
+
v-model="valueModel.email"
|
|
122
|
+
:variant="variant"
|
|
123
|
+
id="email-input"
|
|
124
|
+
:label="$t('user.field.email')"
|
|
125
|
+
prepend-inner-icon="mdi-email"
|
|
126
|
+
:rules="[(v:any) => !!v || t('validation.required')]"
|
|
127
|
+
:error-messages="$ta(store.inputErrors?.email)"
|
|
128
|
+
:readonly="readonly"
|
|
129
|
+
></v-text-field>
|
|
130
|
+
|
|
131
|
+
<v-text-field
|
|
132
|
+
v-model="valueModel.phone"
|
|
133
|
+
:variant="variant"
|
|
134
|
+
id="phone-input"
|
|
135
|
+
:label="$t('user.field.phone')"
|
|
136
|
+
prepend-inner-icon="mdi-phone"
|
|
137
|
+
:rules="[(v:any) => !!v || t('validation.required')]"
|
|
138
|
+
:error-messages="$ta(store.inputErrors?.phone)"
|
|
139
|
+
:readonly="readonly"
|
|
140
|
+
></v-text-field>
|
|
141
|
+
|
|
142
|
+
<v-switch
|
|
143
|
+
id="active-input"
|
|
144
|
+
v-model="valueModel.active"
|
|
145
|
+
color="primary"
|
|
146
|
+
label="Active"
|
|
147
|
+
:true-value="true"
|
|
148
|
+
:false-value="false"
|
|
149
|
+
:readonly="readonly"
|
|
150
|
+
></v-switch>
|
|
151
|
+
|
|
152
|
+
</v-card-text>
|
|
153
|
+
|
|
154
|
+
<v-card-actions>
|
|
155
|
+
<v-spacer></v-spacer>
|
|
156
|
+
<v-btn
|
|
157
|
+
variant="text"
|
|
158
|
+
color="grey"
|
|
159
|
+
@click="cancel">
|
|
160
|
+
{{ t('action.cancel') }}
|
|
161
|
+
</v-btn>
|
|
162
|
+
<v-btn
|
|
163
|
+
v-if="!valueModel.readonly && store.operation != 'view'"
|
|
164
|
+
variant="flat"
|
|
165
|
+
:color="submitColor"
|
|
166
|
+
@click="submit"
|
|
167
|
+
>
|
|
168
|
+
{{ store.operation ? t('action.' + store.operation) : t('action.sent') }}
|
|
169
|
+
</v-btn>
|
|
170
|
+
</v-card-actions>
|
|
171
|
+
</v-card>
|
|
172
|
+
</v-form>
|
|
173
|
+
</template>
|
|
174
|
+
|
|
175
|
+
<style scoped>
|
|
176
|
+
|
|
177
|
+
</style>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import UserPasswordForm from "./UserPasswordForm.vue";
|
|
3
|
+
import {defineModel, defineProps, type PropType, ref} from "vue";
|
|
4
|
+
import type {IUserPassword} from "@drax/identity-front";
|
|
5
|
+
import type {IUser} from "@drax/identity-share";
|
|
6
|
+
import {UserSystemFactory} from "@drax/identity-front";
|
|
7
|
+
import {ClientError, type IClientInputError} from "@drax/common-front";
|
|
8
|
+
import {useI18n} from "vue-i18n";
|
|
9
|
+
|
|
10
|
+
const {t} = useI18n()
|
|
11
|
+
|
|
12
|
+
const valueModel = defineModel({type: Boolean, default: false})
|
|
13
|
+
|
|
14
|
+
const {user} = defineProps({
|
|
15
|
+
user: {type: Object as PropType<IUser>, required: true},
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const userSystem = UserSystemFactory.getInstance()
|
|
19
|
+
|
|
20
|
+
let passwordForm = ref<IUserPassword>({newPassword: "", confirmPassword: ""})
|
|
21
|
+
let passwordChanged = ref(false);
|
|
22
|
+
let inputErrors = ref<IClientInputError>()
|
|
23
|
+
let loading = ref(false);
|
|
24
|
+
let userError = ref<string>('')
|
|
25
|
+
|
|
26
|
+
async function savePassword() {
|
|
27
|
+
if (passwordForm.value.newPassword === passwordForm.value.confirmPassword) {
|
|
28
|
+
passwordChanged.value = await changeUserPassword(user.id, passwordForm.value.newPassword)
|
|
29
|
+
return
|
|
30
|
+
} else {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function changeUserPassword(id: string, newPassword: string) {
|
|
36
|
+
try {
|
|
37
|
+
loading.value = true
|
|
38
|
+
return await userSystem.changeUserPassword(id, newPassword)
|
|
39
|
+
} catch (err) {
|
|
40
|
+
if (err instanceof ClientError) {
|
|
41
|
+
inputErrors.value = err.inputErrors
|
|
42
|
+
}
|
|
43
|
+
if (err instanceof Error) {
|
|
44
|
+
userError.value = err.message
|
|
45
|
+
}
|
|
46
|
+
throw err
|
|
47
|
+
} finally {
|
|
48
|
+
loading.value = false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<v-dialog v-model="valueModel" max-width="800">
|
|
56
|
+
<v-card>
|
|
57
|
+
<v-card-title>{{t('user.operation.changePassword')}}</v-card-title>
|
|
58
|
+
<v-card-subtitle>{{t('user.field.username')}}: {{user.username}}</v-card-subtitle>
|
|
59
|
+
<v-card-text>
|
|
60
|
+
<user-password-form
|
|
61
|
+
v-model="passwordForm"
|
|
62
|
+
:inputErrors="inputErrors"
|
|
63
|
+
:passwordChanged="passwordChanged"
|
|
64
|
+
@formSubmit="savePassword"
|
|
65
|
+
/>
|
|
66
|
+
</v-card-text>
|
|
67
|
+
|
|
68
|
+
<v-card-actions>
|
|
69
|
+
<v-spacer></v-spacer>
|
|
70
|
+
<v-btn
|
|
71
|
+
variant="text"
|
|
72
|
+
color="grey"
|
|
73
|
+
@click="valueModel = false">
|
|
74
|
+
{{ passwordChanged ? t('action.close') : t('action.cancel') }}
|
|
75
|
+
</v-btn>
|
|
76
|
+
<v-btn
|
|
77
|
+
v-if="!passwordChanged"
|
|
78
|
+
variant="flat"
|
|
79
|
+
color="primary"
|
|
80
|
+
@click="savePassword"
|
|
81
|
+
:loading="loading"
|
|
82
|
+
>
|
|
83
|
+
{{ t('action.change') }}
|
|
84
|
+
</v-btn>
|
|
85
|
+
</v-card-actions>
|
|
86
|
+
|
|
87
|
+
</v-card>
|
|
88
|
+
|
|
89
|
+
</v-dialog>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<style scoped>
|
|
93
|
+
|
|
94
|
+
</style>
|
|
@@ -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>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {Crud, useCrud} from "@drax/crud-vue";
|
|
3
|
+
import RoleCrud from "../../cruds/role-crud/RoleCrud";
|
|
4
|
+
import RoleForm from "../../cruds/role-crud/RoleForm.vue";
|
|
5
|
+
import {useI18n} from "vue-i18n";
|
|
6
|
+
|
|
7
|
+
const {t, te} = useI18n()
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
onCancel, onSubmit,form
|
|
11
|
+
} = useCrud(RoleCrud.instance);
|
|
12
|
+
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<crud :entity="RoleCrud.instance">
|
|
17
|
+
|
|
18
|
+
<template v-slot:form>
|
|
19
|
+
<role-form
|
|
20
|
+
v-model="form"
|
|
21
|
+
@submit="onSubmit"
|
|
22
|
+
@cancel="onCancel"
|
|
23
|
+
/>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<template v-slot:item.permissions="{ value }">
|
|
27
|
+
<v-chip
|
|
28
|
+
v-for="permission in value"
|
|
29
|
+
:key="permission" color="green"
|
|
30
|
+
class="ma-1"
|
|
31
|
+
>
|
|
32
|
+
{{ te(`permission.${permission}`) ? t(`permission.${permission}`) : permission }}
|
|
33
|
+
</v-chip>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<template v-slot:item.childRoles="{ value }">
|
|
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
|
+
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<template v-slot:item.readonly="{ value }">
|
|
49
|
+
<v-chip v-if="value" color="red">
|
|
50
|
+
<v-icon class="mdi mdi-pencil-off-outline"></v-icon>
|
|
51
|
+
</v-chip>
|
|
52
|
+
<v-chip v-else color="green">
|
|
53
|
+
<v-icon class="mdi mdi-pencil-outline"></v-icon>
|
|
54
|
+
</v-chip>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
</crud>
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<style scoped>
|
|
61
|
+
|
|
62
|
+
</style>
|
|
@@ -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,72 +1,78 @@
|
|
|
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 RoleCrudPage from '../pages/RoleCrudPage.vue'
|
|
6
|
-
import TenantCrudPage from '../pages/TenantCrudPage.vue'
|
|
7
|
-
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'
|
|
8
8
|
|
|
9
9
|
const routes = [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
10
|
+
{
|
|
11
|
+
name: 'Login',
|
|
12
|
+
path: '/login',
|
|
13
|
+
component: LoginPage,
|
|
14
|
+
meta: {
|
|
15
|
+
auth: false,
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'Profile',
|
|
20
|
+
path: '/profile',
|
|
21
|
+
component: ProfilePage,
|
|
22
|
+
meta: {
|
|
23
|
+
auth: true,
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Password',
|
|
28
|
+
path: '/password',
|
|
29
|
+
component: PasswordPage,
|
|
30
|
+
meta: {
|
|
31
|
+
auth: true,
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
//CRUDS
|
|
35
|
+
{
|
|
36
|
+
name: 'CrudRole',
|
|
37
|
+
path: '/crud/role',
|
|
38
|
+
component: RoleCrudPage,
|
|
39
|
+
meta: {
|
|
40
|
+
auth: true,
|
|
41
|
+
permission: 'role:manage'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
{
|
|
46
|
+
name: 'CrudTenant',
|
|
47
|
+
path: '/crud/tenant',
|
|
48
|
+
component: TenantCrudPage,
|
|
49
|
+
meta: {
|
|
50
|
+
auth: true,
|
|
51
|
+
permission: 'tenant:manage'
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
name: 'CrudUser',
|
|
57
|
+
path: '/crud/user',
|
|
58
|
+
component: UserCrudPage,
|
|
59
|
+
meta: {
|
|
60
|
+
auth: true,
|
|
61
|
+
permission: 'user:manage'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'CrudUserApiKey',
|
|
66
|
+
path: '/crud/user-api-key',
|
|
67
|
+
component: UserApiKeyCrudPage,
|
|
68
|
+
meta: {
|
|
69
|
+
auth: true,
|
|
70
|
+
permission: 'userApiKey:manage'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
70
76
|
]
|
|
71
77
|
|
|
72
78
|
|