@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.
Files changed (35) hide show
  1. package/package.json +5 -5
  2. package/src/combobox/RoleCombobox.vue +9 -1
  3. package/src/combobox/TenantCombobox.vue +11 -9
  4. package/src/components/IdentityChangeOwnPassword/IdentityChangeOwnPassword.vue +4 -4
  5. package/src/components/IdentityProfileDrawer/IdentityProfileDrawer.vue +2 -2
  6. package/src/cruds/role-crud/RoleCrud.ts +9 -1
  7. package/src/cruds/role-crud/RoleForm.vue +116 -0
  8. package/src/cruds/tenant-crud/TenantCrud.ts +8 -0
  9. package/src/cruds/user-crud/PasswordUpdateButton.vue +25 -0
  10. package/src/cruds/user-crud/UserCrud.ts +11 -0
  11. package/src/cruds/user-crud/UserCrud.vue +4 -17
  12. package/src/cruds/user-crud/UserForm.vue +177 -0
  13. package/src/cruds/user-crud/UserPasswordDialog.vue +94 -0
  14. package/src/{forms → cruds/user-crud}/UserPasswordForm.vue +4 -2
  15. package/src/index.ts +7 -21
  16. package/src/pages/ProfilePage.vue +1 -1
  17. package/src/pages/{RoleCrudPage.vue → crud/RoleCrudPage.vue} +11 -10
  18. package/src/pages/{TenantCrudPage.vue → crud/TenantCrudPage.vue} +1 -1
  19. package/src/pages/{UserApiKeyCrudPage.vue → crud/UserApiKeyCrudPage.vue} +1 -1
  20. package/src/pages/crud/UserCrudPage.vue +61 -0
  21. package/src/routes/IdentityRoutes.ts +5 -35
  22. package/src/cruds/role-crud/RoleCrud.vue +0 -171
  23. package/src/cruds/role-crud/RoleList.vue +0 -129
  24. package/src/cruds/tenant-crud/TenantCrud.vue +0 -168
  25. package/src/cruds/tenant-crud/TenantList.vue +0 -108
  26. package/src/cruds/user-crud/UserList.vue +0 -110
  27. package/src/forms/RoleForm.vue +0 -89
  28. package/src/forms/RoleFormOld.vue +0 -57
  29. package/src/forms/TenantForm.vue +0 -48
  30. package/src/forms/UserCreateForm.vue +0 -115
  31. package/src/forms/UserEditForm.vue +0 -101
  32. package/src/pages/RoleCrudCustomPage.vue +0 -12
  33. package/src/pages/TenantCrudCustomPage.vue +0 -12
  34. package/src/pages/UserCrudCustomPage.vue +0 -12
  35. 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
- <div class="text-subtitle-1 text-medium-emphasis">{{ t('user.confirmPassword') }}</div>
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 UserList from "./cruds/user-crud/UserList.vue";
8
- import UserCrudPage from "./pages/UserCrudPage.vue";
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 "./forms/RoleForm.vue";
11
+ import RoleForm from "./cruds/role-crud/RoleForm.vue";
14
12
  import RoleView from "./views/RoleView.vue";
15
- import RoleCrud from "./cruds/role-crud/RoleCrud.vue";
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 TenantCrud from "./cruds/tenant-crud/TenantCrud.vue";
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
- UserCreateForm,
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 "../cruds/role-crud/RoleCrud";
4
- import RoleForm from "../forms/RoleForm.vue";
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
- <v-chip
38
- v-if="value && value.length > 0"
39
- v-for="role in value"
40
- :key="role" color="blue"
41
- class="ma-1"
42
- >
43
- {{ role.name }}
44
- </v-chip>
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 }">
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import TenantCrud from '../cruds/tenant-crud/TenantCrud'
2
+ import TenantCrud from '../../cruds/tenant-crud/TenantCrud'
3
3
  import {Crud} from "@drax/crud-vue";
4
4
  </script>
5
5
 
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
 
3
- import UserApiKeyCrud from "../cruds/user-api-key-crud/UserApiKeyCrud.vue";
3
+ import UserApiKeyCrud from "../../cruds/user-api-key-crud/UserApiKeyCrud.vue";
4
4
  </script>
5
5
 
6
6
  <template>
@@ -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 UserCrudCustomPage from '../pages/UserCrudCustomPage.vue'
6
- import RoleCrudPage from '../pages/RoleCrudPage.vue'
7
- import RoleCrudCustomPage from '../pages/RoleCrudCustomPage.vue'
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
- //CUSTOM CRUDs
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>