@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
|
@@ -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>
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {computed, ref} from 'vue'
|
|
3
|
-
import TenantList from "./TenantList.vue";
|
|
4
|
-
import {useTenant} from "../../composables/useTenant";
|
|
5
|
-
import type {ITenant, ITenantBase} from "@drax/identity-share";
|
|
6
|
-
import TenantForm from "../../forms/TenantForm.vue";
|
|
7
|
-
import TenantView from "../../views/TenantView.vue";
|
|
8
|
-
import {useI18n} from "vue-i18n";
|
|
9
|
-
const {t} = useI18n()
|
|
10
|
-
const {createTenant, editTenant, deleteTenant, loading, tenantError, inputErrors} = useTenant()
|
|
11
|
-
|
|
12
|
-
interface TenantList {
|
|
13
|
-
loadItems: () => void;
|
|
14
|
-
items: ITenant[];
|
|
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 tenantList = ref<TenantList | null>(null);
|
|
24
|
-
let form = ref<ITenantBase>({name: ""})
|
|
25
|
-
let target = ref<ITenant>();
|
|
26
|
-
let targetId = ref<string>('');
|
|
27
|
-
let filterEnable = ref(false);
|
|
28
|
-
|
|
29
|
-
function cancel() {
|
|
30
|
-
dialog.value = false
|
|
31
|
-
inputErrors.value = {}
|
|
32
|
-
tenantError.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 createTenant(form.value)
|
|
44
|
-
} else if (dialogMode.value === 'edit') {
|
|
45
|
-
await editTenant(targetId.value, form.value)
|
|
46
|
-
} else if (dialogMode.value === 'delete') {
|
|
47
|
-
await deleteTenant(targetId.value)
|
|
48
|
-
}
|
|
49
|
-
dialog.value = false
|
|
50
|
-
inputErrors.value = {}
|
|
51
|
-
tenantError.value = '';
|
|
52
|
-
if (tenantList.value !== null) {
|
|
53
|
-
tenantList.value.loadItems()
|
|
54
|
-
}
|
|
55
|
-
} catch (e) {
|
|
56
|
-
console.error(e)
|
|
57
|
-
if (e instanceof Error) {
|
|
58
|
-
tenantError.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 = 'tenant.creating';
|
|
79
|
-
form.value = {name: ""}
|
|
80
|
-
dialog.value = true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function toEdit(item: ITenant) {
|
|
84
|
-
console.log('toEdit', item)
|
|
85
|
-
dialogMode.value = 'edit';
|
|
86
|
-
dialogTitle.value = 'tenant.updating';
|
|
87
|
-
targetId.value = item.id;
|
|
88
|
-
form.value = {
|
|
89
|
-
name: item.name
|
|
90
|
-
}
|
|
91
|
-
dialog.value = true;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function toDelete(item: ITenant) {
|
|
95
|
-
console.log('toDelete', item)
|
|
96
|
-
dialogMode.value = 'delete';
|
|
97
|
-
dialogTitle.value = 'tenant.deleting';
|
|
98
|
-
target.value = item
|
|
99
|
-
const {id} = item;
|
|
100
|
-
targetId.value = id;
|
|
101
|
-
dialog.value = true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
</script>
|
|
105
|
-
|
|
106
|
-
<template>
|
|
107
|
-
<v-container fluid>
|
|
108
|
-
|
|
109
|
-
<v-card border rounded >
|
|
110
|
-
<v-toolbar class="bg-toolbar">
|
|
111
|
-
<v-toolbar-title>{{ t('tenant.managing') }}</v-toolbar-title>
|
|
112
|
-
<v-spacer></v-spacer>
|
|
113
|
-
<v-btn icon @click="filterEnable = !filterEnable">
|
|
114
|
-
<v-icon>{{ filterEnable ? 'mdi-filter' : 'mdi-filter-off' }}</v-icon>
|
|
115
|
-
</v-btn>
|
|
116
|
-
<v-btn class="font-weight-bold" color="primary" @click="toCreate">
|
|
117
|
-
{{ t('action.create') }}
|
|
118
|
-
</v-btn>
|
|
119
|
-
</v-toolbar>
|
|
120
|
-
<v-theme-provider with-background class="pa-2 rounded-b">
|
|
121
|
-
<TenantList
|
|
122
|
-
ref="tenantList"
|
|
123
|
-
@toEdit="toEdit"
|
|
124
|
-
@toDelete="toDelete"
|
|
125
|
-
:filterEnable="filterEnable"
|
|
126
|
-
/>
|
|
127
|
-
</v-theme-provider>
|
|
128
|
-
</v-card>
|
|
129
|
-
|
|
130
|
-
<v-dialog v-model="dialog" max-width="800">
|
|
131
|
-
<v-sheet border>
|
|
132
|
-
<v-toolbar>
|
|
133
|
-
<v-toolbar-title>{{ dialogTitle ? t(dialogTitle) : '-' }}</v-toolbar-title>
|
|
134
|
-
</v-toolbar>
|
|
135
|
-
<v-card class="pa-10">
|
|
136
|
-
<v-card-text v-if="tenantError">
|
|
137
|
-
<v-alert type="error">{{ tenantError }}</v-alert>
|
|
138
|
-
</v-card-text>
|
|
139
|
-
<v-card-text>
|
|
140
|
-
<TenantForm v-if="dialogMode === 'create' || dialogMode === 'edit'"
|
|
141
|
-
v-model="form"
|
|
142
|
-
:inputErrors="inputErrors"
|
|
143
|
-
@formSubmit="save"
|
|
144
|
-
/>
|
|
145
|
-
<TenantView v-if="dialogMode === 'delete' && target" :tenant="target"></TenantView>
|
|
146
|
-
</v-card-text>
|
|
147
|
-
<v-card-actions>
|
|
148
|
-
<v-spacer></v-spacer>
|
|
149
|
-
<v-btn variant="text" @click="cancel" :loading="loading">Cancelar</v-btn>
|
|
150
|
-
<v-btn variant="flat"
|
|
151
|
-
:color="dialogMode==='delete' ? 'red' : 'primary'"
|
|
152
|
-
@click="save"
|
|
153
|
-
:loading="loading"
|
|
154
|
-
>
|
|
155
|
-
{{ t(buttonText) }}
|
|
156
|
-
</v-btn>
|
|
157
|
-
</v-card-actions>
|
|
158
|
-
|
|
159
|
-
</v-card>
|
|
160
|
-
</v-sheet>
|
|
161
|
-
</v-dialog>
|
|
162
|
-
|
|
163
|
-
</v-container>
|
|
164
|
-
</template>
|
|
165
|
-
|
|
166
|
-
<style scoped>
|
|
167
|
-
|
|
168
|
-
</style>
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {defineProps, type Ref, ref} from "vue";
|
|
3
|
-
import {useTenant} from "../../composables/useTenant";
|
|
4
|
-
import {useAuth} from "../../composables/useAuth";
|
|
5
|
-
import {useI18n} from "vue-i18n";
|
|
6
|
-
import type {ITenant} from "@drax/identity-share";
|
|
7
|
-
import {formatDateTime} from "@drax/common-front";
|
|
8
|
-
|
|
9
|
-
const {hasPermission} = useAuth()
|
|
10
|
-
const {paginateTenant} = useTenant()
|
|
11
|
-
const {t} = 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 serverItems: Ref<ITenant[]> = ref([]);
|
|
23
|
-
const totalItems = ref(0)
|
|
24
|
-
const loading = ref(false)
|
|
25
|
-
const search = ref('')
|
|
26
|
-
const sortBy : Ref<any> = ref([])
|
|
27
|
-
|
|
28
|
-
const headers = ref<any>([
|
|
29
|
-
{ title: t('tenant.name') as string, key: 'name', align: 'start' },
|
|
30
|
-
{ title: t('tenant.createdAt') as string, key: 'createdAt', align: 'start' },
|
|
31
|
-
{ title: '', key: 'actions', align: 'end', minWidth: '150px' },
|
|
32
|
-
])
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
async function loadItems(){
|
|
36
|
-
try{
|
|
37
|
-
loading.value = true
|
|
38
|
-
const r = await paginateTenant({
|
|
39
|
-
page: page.value,
|
|
40
|
-
limit: itemsPerPage.value,
|
|
41
|
-
orderBy: sortBy.value[0]?.key,
|
|
42
|
-
order: sortBy.value[0]?.order,
|
|
43
|
-
search: search.value})
|
|
44
|
-
serverItems.value = r.items
|
|
45
|
-
totalItems.value = r.total
|
|
46
|
-
}catch (e){
|
|
47
|
-
console.error(e)
|
|
48
|
-
}finally {
|
|
49
|
-
loading.value = false
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
defineExpose({
|
|
56
|
-
loadItems
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<template>
|
|
62
|
-
<v-data-table-server
|
|
63
|
-
class="border"
|
|
64
|
-
v-if="hasPermission('user:manage')"
|
|
65
|
-
v-model:items-per-page="itemsPerPage"
|
|
66
|
-
:items-per-page-options="[5, 10, 20, 50]"
|
|
67
|
-
v-model:page="page"
|
|
68
|
-
v-model:sort-by="sortBy"
|
|
69
|
-
:headers="headers"
|
|
70
|
-
:items="serverItems"
|
|
71
|
-
:items-length="totalItems"
|
|
72
|
-
:loading="loading"
|
|
73
|
-
:search="search"
|
|
74
|
-
:multi-sort="false"
|
|
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
|
-
|
|
93
|
-
<template v-slot:item.createdAt="{ value }" >
|
|
94
|
-
{{formatDateTime(value)}}
|
|
95
|
-
</template>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<template v-slot:item.actions="{item}" >
|
|
99
|
-
<v-btn v-if="hasPermission('tenant:update')" icon="mdi-pencil" variant="text" color="primary" @click="$emit('toEdit', item)"></v-btn>
|
|
100
|
-
<v-btn v-if="hasPermission('tenant:delete')" icon="mdi-delete" class="mr-1" variant="text" color="red" @click="$emit('toDelete', item)"></v-btn>
|
|
101
|
-
</template>
|
|
102
|
-
|
|
103
|
-
</v-data-table-server>
|
|
104
|
-
</template>
|
|
105
|
-
|
|
106
|
-
<style scoped>
|
|
107
|
-
|
|
108
|
-
</style>
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
import {ref, defineProps, type Ref} from "vue";
|
|
4
|
-
import {useUser} from "../../composables/useUser";
|
|
5
|
-
import {useAuth} from "../../composables/useAuth";
|
|
6
|
-
import {useI18n} from "vue-i18n";
|
|
7
|
-
import type {IUser} from "@drax/identity-share";
|
|
8
|
-
|
|
9
|
-
const {hasPermission} = useAuth()
|
|
10
|
-
const {paginateUser} = useUser()
|
|
11
|
-
const {t} = 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('user.name') as string, key: 'name', align: 'start' },
|
|
25
|
-
{ title: t('user.username') as string, key: 'username', align: 'start' },
|
|
26
|
-
{ title: t('user.email') as string, key: 'email', align: 'start' },
|
|
27
|
-
{ title: t('user.role') as string, key: 'role.name', align: 'start' },
|
|
28
|
-
{ title: t('user.tenant') as string, key: 'tenant.name', align: 'start' },
|
|
29
|
-
{ title: t('user.active') as string, key: 'active', align: 'start' },
|
|
30
|
-
{ title: '', key: 'actions', align: 'end', fixed:true },
|
|
31
|
-
])
|
|
32
|
-
|
|
33
|
-
const serverItems: Ref<IUser[]> = ref([]);
|
|
34
|
-
const totalItems = ref(0)
|
|
35
|
-
const loading = ref(false)
|
|
36
|
-
const search = ref('')
|
|
37
|
-
const sortBy : Ref<any> = ref([])
|
|
38
|
-
|
|
39
|
-
async function loadItems(){
|
|
40
|
-
try{
|
|
41
|
-
loading.value = true
|
|
42
|
-
const r = await paginateUser({
|
|
43
|
-
page: page.value,
|
|
44
|
-
limit: itemsPerPage.value,
|
|
45
|
-
orderBy: sortBy.value[0]?.key,
|
|
46
|
-
order: sortBy.value[0]?.order,
|
|
47
|
-
search: search.value})
|
|
48
|
-
serverItems.value = r.items
|
|
49
|
-
totalItems.value = r.total
|
|
50
|
-
}catch (e){
|
|
51
|
-
console.error(e)
|
|
52
|
-
}finally {
|
|
53
|
-
loading.value = false
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
defineExpose({
|
|
60
|
-
loadItems
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<template>
|
|
66
|
-
<v-data-table-server
|
|
67
|
-
v-if="hasPermission('user:manage')"
|
|
68
|
-
v-model:items-per-page="itemsPerPage"
|
|
69
|
-
v-model:page="page"
|
|
70
|
-
v-model:sort-by="sortBy"
|
|
71
|
-
:items-per-page-options="[5, 10, 20, 50]"
|
|
72
|
-
:headers="headers"
|
|
73
|
-
:items="serverItems"
|
|
74
|
-
:items-length="totalItems"
|
|
75
|
-
:loading="loading"
|
|
76
|
-
:search="search"
|
|
77
|
-
item-value="name"
|
|
78
|
-
@update:options="loadItems"
|
|
79
|
-
>
|
|
80
|
-
<template v-slot:top>
|
|
81
|
-
<v-toolbar density="compact" v-if="filterEnable">
|
|
82
|
-
<v-toolbar-title>{{ t('action.filters') }}</v-toolbar-title>
|
|
83
|
-
<v-spacer></v-spacer>
|
|
84
|
-
<v-text-field v-model="search" hide-details
|
|
85
|
-
density="compact" class="mr-2"
|
|
86
|
-
variant="outlined"
|
|
87
|
-
append-inner-icon="mdi-magnify"
|
|
88
|
-
:label="t('action.search')"
|
|
89
|
-
single-line clearable @click:clear="() => search = ''"
|
|
90
|
-
/>
|
|
91
|
-
</v-toolbar>
|
|
92
|
-
</template>
|
|
93
|
-
<template v-slot:item.active="{ value }" >
|
|
94
|
-
<v-chip :color="value ? 'green':'red'" >
|
|
95
|
-
{{ value ? 'Active' : 'Inactive' }}
|
|
96
|
-
</v-chip>
|
|
97
|
-
</template>
|
|
98
|
-
|
|
99
|
-
<template v-slot:item.actions="{item}" >
|
|
100
|
-
<v-btn v-if="hasPermission('user:update')" icon="mdi-pencil" variant="text" color="primary" @click="$emit('toEdit', item)"></v-btn>
|
|
101
|
-
<v-btn v-if="hasPermission('user:update')" icon="mdi-lock" variant="text" color="orange" @click="$emit('toChangePassword', item)"></v-btn>
|
|
102
|
-
<v-btn v-if="hasPermission('user:delete')" icon="mdi-delete" class="mr-1" variant="text" color="red" @click="$emit('toDelete', item)"></v-btn>
|
|
103
|
-
</template>
|
|
104
|
-
|
|
105
|
-
</v-data-table-server>
|
|
106
|
-
</template>
|
|
107
|
-
|
|
108
|
-
<style scoped>
|
|
109
|
-
|
|
110
|
-
</style>
|