@goweekdays/layer-common 0.1.0 → 1.0.1
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/CHANGELOG.md +12 -0
- package/components/ConfirmDialog.vue +66 -0
- package/components/Layout/Header.vue +1 -1
- package/components/RolePermissionFormCreate.vue +179 -0
- package/components/RolePermissionFormPreviewUpdate.vue +184 -0
- package/components/RolePermissionMain.vue +376 -0
- package/components/SwitchContext.vue +109 -0
- package/components/SwitchOrg.vue +10 -11
- package/composables/useCommonPermission.ts +71 -0
- package/composables/useLocal.ts +29 -2
- package/composables/useLocalAuth.ts +0 -22
- package/composables/useOrg.ts +25 -13
- package/composables/useOrgPermission.ts +27 -0
- package/composables/useRole.ts +5 -3
- package/composables/useSchoolPermission.ts +13 -0
- package/composables/useSubscription.ts +6 -2
- package/composables/useUser.ts +10 -10
- package/composables/useUtils.ts +19 -10
- package/nuxt.config.ts +2 -0
- package/package.json +1 -1
- package/types/org.d.ts +1 -0
- package/types/role.d.ts +1 -0
- package/types/user.d.ts +3 -1
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="px-4 pt-1 pb-2">
|
|
3
|
+
<v-col cols="12" class="mb-2">
|
|
4
|
+
<v-row no-gutters>
|
|
5
|
+
<v-btn
|
|
6
|
+
class="text-none"
|
|
7
|
+
rounded="pill"
|
|
8
|
+
variant="tonal"
|
|
9
|
+
@click="createDialog = true"
|
|
10
|
+
size="large"
|
|
11
|
+
v-if="canCreateRole"
|
|
12
|
+
>
|
|
13
|
+
Create role
|
|
14
|
+
</v-btn>
|
|
15
|
+
</v-row>
|
|
16
|
+
</v-col>
|
|
17
|
+
<v-col cols="12">
|
|
18
|
+
<v-card
|
|
19
|
+
width="100%"
|
|
20
|
+
variant="outlined"
|
|
21
|
+
border="thin"
|
|
22
|
+
rounded="lg"
|
|
23
|
+
:loading="loading"
|
|
24
|
+
>
|
|
25
|
+
<v-toolbar density="compact" color="grey-lighten-4">
|
|
26
|
+
<template #prepend>
|
|
27
|
+
<v-btn fab icon density="comfortable" @click="getRoles()">
|
|
28
|
+
<v-icon>mdi-refresh</v-icon>
|
|
29
|
+
</v-btn>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<template #append>
|
|
33
|
+
<v-row no-gutters justify="end" align="center">
|
|
34
|
+
<span class="mr-2 text-caption text-fontgray">
|
|
35
|
+
{{ pageRange }}
|
|
36
|
+
</span>
|
|
37
|
+
<local-pagination
|
|
38
|
+
v-model="page"
|
|
39
|
+
:length="pages"
|
|
40
|
+
@update:value="getRoles()"
|
|
41
|
+
/>
|
|
42
|
+
</v-row>
|
|
43
|
+
</template>
|
|
44
|
+
</v-toolbar>
|
|
45
|
+
|
|
46
|
+
<v-data-table
|
|
47
|
+
:headers="props.headers"
|
|
48
|
+
:items="items"
|
|
49
|
+
item-value="_id"
|
|
50
|
+
items-per-page="20"
|
|
51
|
+
fixed-header
|
|
52
|
+
hide-default-footer
|
|
53
|
+
hide-default-header
|
|
54
|
+
@click:row="tableRowClickHandler"
|
|
55
|
+
style="max-height: calc(100vh - (180px))"
|
|
56
|
+
>
|
|
57
|
+
<template #item.permissions="{ value }">
|
|
58
|
+
<span class="text-caption font-weight-bold text-capitalize">
|
|
59
|
+
permissions
|
|
60
|
+
</span>
|
|
61
|
+
<v-chip>{{ value.length }}</v-chip>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<template #item.action-table="{ item }" v-if="canDeleteRole">
|
|
65
|
+
<v-menu :close-on-content-click="false" offset-y width="150">
|
|
66
|
+
<template v-slot:activator="{ props }">
|
|
67
|
+
<v-icon v-bind="props">mdi-dots-horizontal</v-icon>
|
|
68
|
+
</template>
|
|
69
|
+
<v-list>
|
|
70
|
+
<v-list-item @click="openDeleteDialog(item._id)">
|
|
71
|
+
Delete Role
|
|
72
|
+
</v-list-item>
|
|
73
|
+
</v-list>
|
|
74
|
+
</v-menu>
|
|
75
|
+
</template>
|
|
76
|
+
</v-data-table>
|
|
77
|
+
</v-card>
|
|
78
|
+
</v-col>
|
|
79
|
+
|
|
80
|
+
<!-- dialogs -->
|
|
81
|
+
<v-dialog v-model="createDialog" width="500" persistent>
|
|
82
|
+
<RolePermissionFormCreate
|
|
83
|
+
@cancel="createDialog = false"
|
|
84
|
+
:permissions="props.permissions"
|
|
85
|
+
:org="props.orgId"
|
|
86
|
+
@success="success()"
|
|
87
|
+
v-model:type="type"
|
|
88
|
+
:types="props.types"
|
|
89
|
+
@success:create-more="getRoles()"
|
|
90
|
+
/>
|
|
91
|
+
</v-dialog>
|
|
92
|
+
|
|
93
|
+
<v-dialog v-model="previewDialog" width="500" persistent>
|
|
94
|
+
<RolePermissionFormPreviewUpdate
|
|
95
|
+
@cancel="previewDialog = false"
|
|
96
|
+
@success="successfulUpdate()"
|
|
97
|
+
:permissions="Permissions"
|
|
98
|
+
:original-permissions="originalPermissions"
|
|
99
|
+
v-model="selectedPermissions"
|
|
100
|
+
v-model:edit="edit"
|
|
101
|
+
:name="name"
|
|
102
|
+
:id="roleId"
|
|
103
|
+
/>
|
|
104
|
+
</v-dialog>
|
|
105
|
+
|
|
106
|
+
<ConfirmDialog
|
|
107
|
+
v-model="confirmDialog"
|
|
108
|
+
:loading="deleteLoading"
|
|
109
|
+
@submit="handleDeleteRole"
|
|
110
|
+
>
|
|
111
|
+
<template #title>
|
|
112
|
+
<span class="font-weight-medium text-h5">Delete Role</span>
|
|
113
|
+
</template>
|
|
114
|
+
|
|
115
|
+
<template #description>
|
|
116
|
+
<p class="text-subtitle-2">
|
|
117
|
+
Are you sure you want to delete this role? This action cannot be
|
|
118
|
+
undone.
|
|
119
|
+
</p>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<template #footer>
|
|
123
|
+
<v-btn
|
|
124
|
+
variant="text"
|
|
125
|
+
@click="confirmDialog = false"
|
|
126
|
+
:disabled="deleteLoading"
|
|
127
|
+
>
|
|
128
|
+
Close
|
|
129
|
+
</v-btn>
|
|
130
|
+
<v-btn
|
|
131
|
+
color="primary"
|
|
132
|
+
variant="flat"
|
|
133
|
+
@click="handleDeleteRole"
|
|
134
|
+
:loading="deleteLoading"
|
|
135
|
+
>
|
|
136
|
+
Delete Role
|
|
137
|
+
</v-btn>
|
|
138
|
+
</template>
|
|
139
|
+
</ConfirmDialog>
|
|
140
|
+
|
|
141
|
+
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
142
|
+
</v-row>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<script setup lang="ts">
|
|
146
|
+
const props = defineProps({
|
|
147
|
+
orgId: {
|
|
148
|
+
type: String,
|
|
149
|
+
default: "",
|
|
150
|
+
},
|
|
151
|
+
permissions: {
|
|
152
|
+
type: Object,
|
|
153
|
+
required: true,
|
|
154
|
+
default: () => ({}),
|
|
155
|
+
},
|
|
156
|
+
types: {
|
|
157
|
+
type: Array as PropType<Array<{ title: string; value: string }>>,
|
|
158
|
+
default: () => [],
|
|
159
|
+
},
|
|
160
|
+
headers: {
|
|
161
|
+
type: Array as PropType<Array<Record<string, any>>>,
|
|
162
|
+
default: () => [
|
|
163
|
+
{
|
|
164
|
+
title: "name",
|
|
165
|
+
value: "name",
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
title: "permissions",
|
|
169
|
+
value: "permissions",
|
|
170
|
+
},
|
|
171
|
+
{ title: "App", value: "type" },
|
|
172
|
+
{ title: "Action", value: "action-table" },
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
canCreateRole: {
|
|
176
|
+
type: Boolean,
|
|
177
|
+
default: false,
|
|
178
|
+
},
|
|
179
|
+
canViewRole: {
|
|
180
|
+
type: Boolean,
|
|
181
|
+
default: false,
|
|
182
|
+
},
|
|
183
|
+
canViewByRole: {
|
|
184
|
+
type: Boolean,
|
|
185
|
+
default: false,
|
|
186
|
+
},
|
|
187
|
+
canDeleteRole: {
|
|
188
|
+
type: Boolean,
|
|
189
|
+
default: false,
|
|
190
|
+
},
|
|
191
|
+
canUpdateRole: {
|
|
192
|
+
type: Boolean,
|
|
193
|
+
default: false,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const type = defineModel<string>("type", {
|
|
198
|
+
type: String,
|
|
199
|
+
default: "",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const { headerSearch } = useLocal();
|
|
203
|
+
|
|
204
|
+
const { getRoles: _getRoles } = useRole();
|
|
205
|
+
|
|
206
|
+
const page = ref(1);
|
|
207
|
+
const pages = ref(0);
|
|
208
|
+
const pageRange = ref("-- - -- of --");
|
|
209
|
+
|
|
210
|
+
const message = ref("");
|
|
211
|
+
const messageSnackbar = ref(false);
|
|
212
|
+
const messageColor = ref("");
|
|
213
|
+
|
|
214
|
+
const items = ref<Array<Record<string, any>>>([]);
|
|
215
|
+
|
|
216
|
+
const {
|
|
217
|
+
data: getRoleReq,
|
|
218
|
+
refresh: getRoles,
|
|
219
|
+
status: getRoleReqStatus,
|
|
220
|
+
} = useLazyAsyncData(
|
|
221
|
+
"roles-permissions-get-all",
|
|
222
|
+
() =>
|
|
223
|
+
_getRoles({
|
|
224
|
+
page: page.value,
|
|
225
|
+
search: headerSearch.value,
|
|
226
|
+
type: type.value,
|
|
227
|
+
org: props.orgId,
|
|
228
|
+
}),
|
|
229
|
+
{
|
|
230
|
+
watch: [page, headerSearch],
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const loading = computed(() => getRoleReqStatus.value === "pending");
|
|
235
|
+
|
|
236
|
+
watchEffect(() => {
|
|
237
|
+
if (getRoleReq.value) {
|
|
238
|
+
items.value = getRoleReq.value.items;
|
|
239
|
+
pages.value = getRoleReq.value.pages;
|
|
240
|
+
pageRange.value = getRoleReq.value.pageRange;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
function tableRowClickHandler(_: any, data: any) {
|
|
245
|
+
previewDialog.value = true;
|
|
246
|
+
roleId.value = data.item._id;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const createDialog = ref(false);
|
|
250
|
+
|
|
251
|
+
function success() {
|
|
252
|
+
createDialog.value = false;
|
|
253
|
+
type.value = "";
|
|
254
|
+
getRoles();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const previewDialog = ref(false);
|
|
258
|
+
|
|
259
|
+
const name = ref("");
|
|
260
|
+
const selectedPermissions = ref<Array<string>>([]);
|
|
261
|
+
const originalPermissions = ref<Array<string>>([]);
|
|
262
|
+
const edit = ref(false);
|
|
263
|
+
|
|
264
|
+
watchEffect(() => {
|
|
265
|
+
if (!edit.value) {
|
|
266
|
+
selectedPermissions.value = originalPermissions.value;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const roleId = ref("");
|
|
271
|
+
|
|
272
|
+
const { getRoleById: _getRoleById, deleteRole } = useRole();
|
|
273
|
+
|
|
274
|
+
const { data: role, refresh: getRoleById } = useLazyAsyncData(
|
|
275
|
+
"role-permissions-get-by-id",
|
|
276
|
+
() => _getRoleById(roleId.value)
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
watchEffect(() => {
|
|
280
|
+
if (roleId.value) {
|
|
281
|
+
getRoleById();
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
watchEffect(() => {
|
|
286
|
+
if (role.value) {
|
|
287
|
+
name.value = role.value.name;
|
|
288
|
+
|
|
289
|
+
selectedPermissions.value = role.value.permissions;
|
|
290
|
+
originalPermissions.value = role.value.permissions;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
function filterPermissions(
|
|
295
|
+
allPermissions: TPermissions,
|
|
296
|
+
storedPermissions: string[]
|
|
297
|
+
) {
|
|
298
|
+
const filteredPermissions: TPermissions = {};
|
|
299
|
+
|
|
300
|
+
Object.entries(allPermissions).forEach(([resource, actions]) => {
|
|
301
|
+
const filteredActions = Object.entries(actions)
|
|
302
|
+
.filter(([action]) => storedPermissions.includes(`${resource}:${action}`))
|
|
303
|
+
.reduce((acc: Record<string, any>, [action, data]) => {
|
|
304
|
+
acc[action] = data;
|
|
305
|
+
return acc;
|
|
306
|
+
}, {});
|
|
307
|
+
|
|
308
|
+
if (Object.keys(filteredActions).length > 0) {
|
|
309
|
+
filteredPermissions[resource] = filteredActions;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
return filteredPermissions;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const { permissions: orgPermissions } = useOrgPermission();
|
|
317
|
+
const { permissions: schoolPermissions } = useSchoolPermission();
|
|
318
|
+
|
|
319
|
+
const permissions = computed(() => {
|
|
320
|
+
if (role.value?.type === "organization") {
|
|
321
|
+
return orgPermissions;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (role.value?.type === "school") {
|
|
325
|
+
return schoolPermissions;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return {};
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const Permissions = computed(() => {
|
|
332
|
+
return edit.value
|
|
333
|
+
? permissions.value
|
|
334
|
+
: filterPermissions(permissions.value, selectedPermissions.value);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
function successfulUpdate() {
|
|
338
|
+
previewDialog.value = false;
|
|
339
|
+
getRoles();
|
|
340
|
+
getRoleById();
|
|
341
|
+
edit.value = false;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const confirmDialog = ref(false);
|
|
345
|
+
const selectedRoleId = ref<string | null>(null);
|
|
346
|
+
const deleteLoading = ref(false);
|
|
347
|
+
|
|
348
|
+
function openDeleteDialog(id: string) {
|
|
349
|
+
selectedRoleId.value = id;
|
|
350
|
+
confirmDialog.value = true;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function showMessage(msg: string, color: string) {
|
|
354
|
+
message.value = msg;
|
|
355
|
+
messageColor.value = color;
|
|
356
|
+
messageSnackbar.value = true;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
async function handleDeleteRole() {
|
|
360
|
+
if (!selectedRoleId.value) return;
|
|
361
|
+
deleteLoading.value = true;
|
|
362
|
+
try {
|
|
363
|
+
const res = await deleteRole(selectedRoleId.value);
|
|
364
|
+
|
|
365
|
+
confirmDialog.value = false;
|
|
366
|
+
showMessage(res.message, "success");
|
|
367
|
+
getRoles();
|
|
368
|
+
} catch (error: any) {
|
|
369
|
+
const errorMessage = error?.response?._data?.message;
|
|
370
|
+
showMessage(errorMessage, "error");
|
|
371
|
+
} finally {
|
|
372
|
+
deleteLoading.value = false;
|
|
373
|
+
selectedRoleId.value = null;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
</script>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-menu
|
|
3
|
+
v-model="menu"
|
|
4
|
+
location="bottom"
|
|
5
|
+
offset="5px"
|
|
6
|
+
:close-on-content-click="false"
|
|
7
|
+
>
|
|
8
|
+
<template #activator="{ props }">
|
|
9
|
+
<v-list class="pa-0">
|
|
10
|
+
<v-list-item
|
|
11
|
+
v-bind="props"
|
|
12
|
+
:key="props.title"
|
|
13
|
+
:prepend-icon="prop.icon"
|
|
14
|
+
append-icon="mdi-chevron-down"
|
|
15
|
+
:to="props.route"
|
|
16
|
+
class="text-subtitle-2 font-weight-bold"
|
|
17
|
+
rounded="e-pill"
|
|
18
|
+
>
|
|
19
|
+
<v-list-item-title class="text-truncate">
|
|
20
|
+
{{ name || `Select ${prop.title}` }}
|
|
21
|
+
</v-list-item-title>
|
|
22
|
+
</v-list-item>
|
|
23
|
+
</v-list>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<v-card width="300px" rounded="lg" class="pa-4">
|
|
27
|
+
<span class="text-subtitle-2 font-weight-bold">
|
|
28
|
+
Switch {{ prop.title }} context
|
|
29
|
+
</span>
|
|
30
|
+
<v-text-field
|
|
31
|
+
v-model="search"
|
|
32
|
+
@keydown.enter="emit('search')"
|
|
33
|
+
density="compact"
|
|
34
|
+
width="100%"
|
|
35
|
+
hide-details
|
|
36
|
+
class="mb-2"
|
|
37
|
+
>
|
|
38
|
+
<template #prepend-inner>
|
|
39
|
+
<v-icon>mdi-magnify</v-icon>
|
|
40
|
+
</template>
|
|
41
|
+
</v-text-field>
|
|
42
|
+
<v-divider />
|
|
43
|
+
<v-list class="pa-0 my-2" density="compact" max-height="200px">
|
|
44
|
+
<v-list-item
|
|
45
|
+
density="compact"
|
|
46
|
+
class="text-caption font-weight-bold"
|
|
47
|
+
v-for="item in prop.items"
|
|
48
|
+
:key="item.value"
|
|
49
|
+
@click="selectItem(item.value)"
|
|
50
|
+
>
|
|
51
|
+
<v-icon size="16" class="mr-2">
|
|
52
|
+
{{ selected === item.value ? "mdi-check" : "" }}
|
|
53
|
+
</v-icon>
|
|
54
|
+
|
|
55
|
+
{{ item.text }}
|
|
56
|
+
</v-list-item>
|
|
57
|
+
</v-list>
|
|
58
|
+
|
|
59
|
+
<slot name="footer"></slot>
|
|
60
|
+
</v-card>
|
|
61
|
+
</v-menu>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script setup lang="ts">
|
|
65
|
+
const prop = defineProps({
|
|
66
|
+
title: {
|
|
67
|
+
type: String,
|
|
68
|
+
required: true,
|
|
69
|
+
default: "app",
|
|
70
|
+
},
|
|
71
|
+
items: {
|
|
72
|
+
type: Array as PropType<Array<Record<string, any>>>,
|
|
73
|
+
required: false,
|
|
74
|
+
default: () => [],
|
|
75
|
+
},
|
|
76
|
+
icon: {
|
|
77
|
+
type: String,
|
|
78
|
+
required: false,
|
|
79
|
+
default: "mdi-domain",
|
|
80
|
+
},
|
|
81
|
+
logo: {
|
|
82
|
+
type: String,
|
|
83
|
+
required: false,
|
|
84
|
+
default: "",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const menu = defineModel<boolean>("menu", { required: false, default: false });
|
|
89
|
+
const selected = defineModel<string>("selected", {
|
|
90
|
+
required: false,
|
|
91
|
+
default: "",
|
|
92
|
+
});
|
|
93
|
+
const search = defineModel<string>("search", {
|
|
94
|
+
required: false,
|
|
95
|
+
default: "",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const emit = defineEmits(["search", "select"]);
|
|
99
|
+
|
|
100
|
+
const name = computed(() => {
|
|
101
|
+
return prop.items.find((item) => item.value === selected.value)?.text ?? "";
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const selectItem = (value: string) => {
|
|
105
|
+
selected.value = value;
|
|
106
|
+
menu.value = false;
|
|
107
|
+
emit("select", value);
|
|
108
|
+
};
|
|
109
|
+
</script>
|
package/components/SwitchOrg.vue
CHANGED
|
@@ -90,7 +90,7 @@ const profile = computed(() => {
|
|
|
90
90
|
return `/api/public/${currentUser.value?.profile}`;
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
const {
|
|
93
|
+
const { getByUserId: _getByUserId, currentOrg } = useOrg();
|
|
94
94
|
|
|
95
95
|
const orgs = ref<Array<Record<string, any>>>([]);
|
|
96
96
|
const page = ref(1);
|
|
@@ -106,18 +106,17 @@ watch(currentOrg, () => {
|
|
|
106
106
|
setOrg();
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
const { data: userOrgReq } = useLazyAsyncData("orgs-by-user", () => {
|
|
110
|
+
return _getByUserId({ user: currentUser.value?._id });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
watchEffect(() => {
|
|
114
|
+
if (userOrgReq.value) {
|
|
115
|
+
orgs.value = userOrgReq.value.items;
|
|
116
|
+
page.value = userOrgReq.value.page;
|
|
114
117
|
setOrg();
|
|
115
|
-
} catch (error) {
|
|
116
|
-
console.log(error);
|
|
117
118
|
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
getOrgs();
|
|
119
|
+
});
|
|
121
120
|
|
|
122
121
|
function switchOrg(org: string) {
|
|
123
122
|
navigateTo({
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export function useCommonPermissions() {
|
|
2
|
+
const invitationPermission: Record<string, TPermission> = {
|
|
3
|
+
"create-invitation": {
|
|
4
|
+
check: true,
|
|
5
|
+
description:
|
|
6
|
+
"Allows the user to create a new invitation for a invitation to join the organization.",
|
|
7
|
+
},
|
|
8
|
+
"view-invitations": {
|
|
9
|
+
check: true,
|
|
10
|
+
description:
|
|
11
|
+
"Allows the user to view the list of all invitation in the organization.",
|
|
12
|
+
},
|
|
13
|
+
"cancel-invitation": {
|
|
14
|
+
check: true,
|
|
15
|
+
description:
|
|
16
|
+
"Allows the user to permanently remove a invitation from the organization.",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const memberPermissions: Record<string, TPermission> = {
|
|
21
|
+
"view-members": {
|
|
22
|
+
check: true,
|
|
23
|
+
description:
|
|
24
|
+
"Allows the user to view the list of all members in the organization.",
|
|
25
|
+
},
|
|
26
|
+
"suspend-member": {
|
|
27
|
+
check: true,
|
|
28
|
+
description: "Allows the user to suspend a member's account temporarily.",
|
|
29
|
+
},
|
|
30
|
+
"activate-member": {
|
|
31
|
+
check: true,
|
|
32
|
+
description:
|
|
33
|
+
"Allows the user to reactivate a suspended member's account.",
|
|
34
|
+
},
|
|
35
|
+
"delete-member": {
|
|
36
|
+
check: true,
|
|
37
|
+
description:
|
|
38
|
+
"Allows the user to permanently remove a member from the organization.",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const rolePermissions: Record<string, TPermission> = {
|
|
43
|
+
"add-role": {
|
|
44
|
+
check: true,
|
|
45
|
+
description: "Allows the user to add a new role to the system.",
|
|
46
|
+
},
|
|
47
|
+
"see-all-roles": {
|
|
48
|
+
check: true,
|
|
49
|
+
description: "Allows the user to view the list of all roles.",
|
|
50
|
+
},
|
|
51
|
+
"see-role-details": {
|
|
52
|
+
check: true,
|
|
53
|
+
description: "Allows the user to view the details of a specific role.",
|
|
54
|
+
},
|
|
55
|
+
"delete-role": {
|
|
56
|
+
check: true,
|
|
57
|
+
description:
|
|
58
|
+
"Allows the user to remove a role from the system permanently.",
|
|
59
|
+
},
|
|
60
|
+
"update-role": {
|
|
61
|
+
check: true,
|
|
62
|
+
description: "Allows the user to update the details of an existing role.",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
invitationPermission,
|
|
68
|
+
memberPermissions,
|
|
69
|
+
rolePermissions,
|
|
70
|
+
};
|
|
71
|
+
}
|
package/composables/useLocal.ts
CHANGED
|
@@ -9,8 +9,14 @@ export default function useLocal() {
|
|
|
9
9
|
|
|
10
10
|
const drawer = useState("drawer", () => true);
|
|
11
11
|
|
|
12
|
-
const {
|
|
13
|
-
|
|
12
|
+
const {
|
|
13
|
+
APP_INVENTORY,
|
|
14
|
+
APP_ASSET,
|
|
15
|
+
APP_BOOK_KEEPING,
|
|
16
|
+
APP_ACCOUNTING,
|
|
17
|
+
APP_ZONAL,
|
|
18
|
+
APP_SCHOOL,
|
|
19
|
+
} = appConfig;
|
|
14
20
|
const { currentOrg } = useOrg();
|
|
15
21
|
|
|
16
22
|
const apps = computed(() => {
|
|
@@ -39,6 +45,18 @@ export default function useLocal() {
|
|
|
39
45
|
link: APP_ASSET as string,
|
|
40
46
|
landingPage: `org/${currentOrg.value ?? ""}`,
|
|
41
47
|
},
|
|
48
|
+
{
|
|
49
|
+
title: "Zonal",
|
|
50
|
+
icon: "mdi-hospital-marker",
|
|
51
|
+
link: APP_ZONAL as string,
|
|
52
|
+
landingPage: `org/${currentOrg.value ?? ""}`,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: "School",
|
|
56
|
+
icon: "mdi-school",
|
|
57
|
+
link: APP_SCHOOL as string,
|
|
58
|
+
landingPage: `org/${currentOrg.value ?? ""}`,
|
|
59
|
+
},
|
|
42
60
|
];
|
|
43
61
|
});
|
|
44
62
|
|
|
@@ -50,6 +68,11 @@ export default function useLocal() {
|
|
|
50
68
|
|
|
51
69
|
const headerSearch = useState("headerSearch", () => "");
|
|
52
70
|
|
|
71
|
+
const items = ref<Array<Record<string, any>>>([]);
|
|
72
|
+
const page = ref(1);
|
|
73
|
+
const pages = ref(0);
|
|
74
|
+
const pageRange = ref("");
|
|
75
|
+
|
|
53
76
|
return {
|
|
54
77
|
cookieConfig,
|
|
55
78
|
getUserFromCookie,
|
|
@@ -57,5 +80,9 @@ export default function useLocal() {
|
|
|
57
80
|
apps,
|
|
58
81
|
redirect,
|
|
59
82
|
headerSearch,
|
|
83
|
+
items,
|
|
84
|
+
page,
|
|
85
|
+
pages,
|
|
86
|
+
pageRange,
|
|
60
87
|
};
|
|
61
88
|
}
|
|
@@ -74,26 +74,6 @@ export default function useLocalAuth() {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
function getById(id: string) {
|
|
78
|
-
return useNuxtApp().$api<TUser>(`/api/users/id/${id}`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const user = useCookie("user", cookieConfig).value ?? "";
|
|
82
|
-
|
|
83
|
-
if (currentUser.value === null) {
|
|
84
|
-
const { data: userData } = useLazyAsyncData("getCurrentUser", async () =>
|
|
85
|
-
useNuxtApp().$api<TUser>(`/api/users/id/${user}`, {
|
|
86
|
-
method: "GET",
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
watchEffect(() => {
|
|
91
|
-
if (userData.value) {
|
|
92
|
-
currentUser.value = userData.value;
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
77
|
async function getCurrentUser() {
|
|
98
78
|
const user = useCookie("user", cookieConfig).value;
|
|
99
79
|
if (!user) return null;
|
|
@@ -157,8 +137,6 @@ export default function useLocalAuth() {
|
|
|
157
137
|
});
|
|
158
138
|
}
|
|
159
139
|
|
|
160
|
-
const permissions = useState("permissions", (): Array<string> => []);
|
|
161
|
-
|
|
162
140
|
return {
|
|
163
141
|
authenticate,
|
|
164
142
|
login,
|