@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
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-dialog v-model="dialog" max-width="400" persistent>
|
|
3
|
+
<v-card class="rounded-xl pa-6" elevation="2">
|
|
4
|
+
<!-- Close Button -->
|
|
5
|
+
<v-btn
|
|
6
|
+
icon
|
|
7
|
+
variant="text"
|
|
8
|
+
size="small"
|
|
9
|
+
class="position-absolute"
|
|
10
|
+
style="top: 8px; right: 8px"
|
|
11
|
+
@click="closeDialog"
|
|
12
|
+
>
|
|
13
|
+
<v-icon>mdi-close</v-icon>
|
|
14
|
+
</v-btn>
|
|
15
|
+
|
|
16
|
+
<v-card-text class="text-center">
|
|
17
|
+
<v-row v-if="imageSrc" justify="center" class="py-10">
|
|
18
|
+
<v-img height="120" :src="imageSrc" alt="Dialog Image" contain />
|
|
19
|
+
</v-row>
|
|
20
|
+
|
|
21
|
+
<!-- Title Slot -->
|
|
22
|
+
<div class="text-h6 font-weight-medium mb-2">
|
|
23
|
+
<slot name="title"></slot>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<!-- Description Slot -->
|
|
27
|
+
<div class="text-body-1 mb-4">
|
|
28
|
+
<slot name="description"></slot>
|
|
29
|
+
</div>
|
|
30
|
+
</v-card-text>
|
|
31
|
+
|
|
32
|
+
<!-- Footer Slot -->
|
|
33
|
+
<v-card-actions>
|
|
34
|
+
<slot name="footer"></slot>
|
|
35
|
+
</v-card-actions>
|
|
36
|
+
</v-card>
|
|
37
|
+
</v-dialog>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script lang="ts" setup>
|
|
41
|
+
const props = defineProps({
|
|
42
|
+
modelValue: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
imageSrc: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: "",
|
|
49
|
+
},
|
|
50
|
+
loading: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const emit = defineEmits(["update:modelValue", "submit"]);
|
|
57
|
+
|
|
58
|
+
const dialog = computed({
|
|
59
|
+
get: () => props.modelValue,
|
|
60
|
+
set: (value) => emit("update:modelValue", value),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
function closeDialog() {
|
|
64
|
+
dialog.value = false;
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5">
|
|
6
|
+
{{ props.title }}
|
|
7
|
+
</span>
|
|
8
|
+
</v-row>
|
|
9
|
+
</v-toolbar>
|
|
10
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
11
|
+
<v-form v-model="validForm" :disabled="disable">
|
|
12
|
+
<v-row no-gutters>
|
|
13
|
+
<v-col cols="12" class="mt-2">
|
|
14
|
+
<v-row no-gutters>
|
|
15
|
+
<InputLabel class="text-capitalize" title="Name" required />
|
|
16
|
+
<v-col cols="12">
|
|
17
|
+
<v-text-field
|
|
18
|
+
v-model="name"
|
|
19
|
+
density="comfortable"
|
|
20
|
+
:rules="[requiredRule]"
|
|
21
|
+
></v-text-field>
|
|
22
|
+
</v-col>
|
|
23
|
+
</v-row>
|
|
24
|
+
</v-col>
|
|
25
|
+
|
|
26
|
+
<v-col v-if="props.types.length" cols="12" class="mt-2">
|
|
27
|
+
<v-row no-gutters>
|
|
28
|
+
<InputLabel class="text-capitalize" title="App" required />
|
|
29
|
+
<v-col cols="12">
|
|
30
|
+
<v-select
|
|
31
|
+
v-model="type"
|
|
32
|
+
:items="props.types"
|
|
33
|
+
density="comfortable"
|
|
34
|
+
:rules="[requiredRule]"
|
|
35
|
+
></v-select>
|
|
36
|
+
</v-col>
|
|
37
|
+
</v-row>
|
|
38
|
+
</v-col>
|
|
39
|
+
|
|
40
|
+
<v-col v-if="type" cols="12">
|
|
41
|
+
<InputListGroupSelection
|
|
42
|
+
v-model="selectedPermissions"
|
|
43
|
+
:items="props.permissions"
|
|
44
|
+
variant="outlined"
|
|
45
|
+
border="thin"
|
|
46
|
+
:error-messages="requireListRule(selectedPermissions)"
|
|
47
|
+
/>
|
|
48
|
+
</v-col>
|
|
49
|
+
|
|
50
|
+
<v-col cols="12" class="mt-2">
|
|
51
|
+
<v-checkbox v-model="createMore" density="comfortable" hide-details>
|
|
52
|
+
<template #label>
|
|
53
|
+
<span class="text-subtitle-2 font-weight-bold">
|
|
54
|
+
Create more
|
|
55
|
+
</span>
|
|
56
|
+
</template>
|
|
57
|
+
</v-checkbox>
|
|
58
|
+
</v-col>
|
|
59
|
+
|
|
60
|
+
<v-col cols="12" class="my-2">
|
|
61
|
+
<v-row no-gutters>
|
|
62
|
+
<v-col cols="12" class="text-center">
|
|
63
|
+
<span
|
|
64
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
65
|
+
>
|
|
66
|
+
{{ message }}
|
|
67
|
+
</span>
|
|
68
|
+
</v-col>
|
|
69
|
+
</v-row>
|
|
70
|
+
</v-col>
|
|
71
|
+
</v-row>
|
|
72
|
+
</v-form>
|
|
73
|
+
</v-card-text>
|
|
74
|
+
|
|
75
|
+
<v-toolbar>
|
|
76
|
+
<v-row class="px-6">
|
|
77
|
+
<v-col cols="6">
|
|
78
|
+
<v-btn
|
|
79
|
+
block
|
|
80
|
+
variant="text"
|
|
81
|
+
class="text-none"
|
|
82
|
+
size="large"
|
|
83
|
+
@click="cancel"
|
|
84
|
+
>
|
|
85
|
+
Cancel
|
|
86
|
+
</v-btn>
|
|
87
|
+
</v-col>
|
|
88
|
+
|
|
89
|
+
<v-col cols="6">
|
|
90
|
+
<v-btn
|
|
91
|
+
block
|
|
92
|
+
variant="flat"
|
|
93
|
+
color="black"
|
|
94
|
+
class="text-none"
|
|
95
|
+
size="large"
|
|
96
|
+
:disabled="!validForm"
|
|
97
|
+
@click="submit"
|
|
98
|
+
>
|
|
99
|
+
Submit
|
|
100
|
+
</v-btn>
|
|
101
|
+
</v-col>
|
|
102
|
+
</v-row>
|
|
103
|
+
</v-toolbar>
|
|
104
|
+
</v-card>
|
|
105
|
+
</template>
|
|
106
|
+
|
|
107
|
+
<script setup lang="ts">
|
|
108
|
+
const props = defineProps({
|
|
109
|
+
title: {
|
|
110
|
+
type: String,
|
|
111
|
+
default: "Role Permission Form",
|
|
112
|
+
},
|
|
113
|
+
permissions: {
|
|
114
|
+
type: Object,
|
|
115
|
+
default: () => ({}),
|
|
116
|
+
},
|
|
117
|
+
org: {
|
|
118
|
+
type: String,
|
|
119
|
+
default: "",
|
|
120
|
+
},
|
|
121
|
+
types: {
|
|
122
|
+
type: Array as PropType<Array<Record<string, string>>>,
|
|
123
|
+
default: () => [],
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
128
|
+
|
|
129
|
+
const validForm = ref(false);
|
|
130
|
+
|
|
131
|
+
const name = ref("");
|
|
132
|
+
const selectedPermissions = ref([]);
|
|
133
|
+
const createMore = ref(false);
|
|
134
|
+
const disable = ref(false);
|
|
135
|
+
|
|
136
|
+
const { requiredRule, requireListRule } = useUtils();
|
|
137
|
+
|
|
138
|
+
const message = ref("");
|
|
139
|
+
const type = defineModel("type", {
|
|
140
|
+
type: String,
|
|
141
|
+
default: "",
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const { createRole } = useRole();
|
|
145
|
+
|
|
146
|
+
async function submit() {
|
|
147
|
+
disable.value = true;
|
|
148
|
+
try {
|
|
149
|
+
await createRole({
|
|
150
|
+
name: name.value,
|
|
151
|
+
permissions: selectedPermissions.value,
|
|
152
|
+
type: type.value,
|
|
153
|
+
org: props.org,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
if (createMore.value) {
|
|
157
|
+
name.value = "";
|
|
158
|
+
selectedPermissions.value = [];
|
|
159
|
+
message.value = "";
|
|
160
|
+
emit("success:create-more");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
emit("success");
|
|
165
|
+
} catch (error: any) {
|
|
166
|
+
message.value = error.response._data.message;
|
|
167
|
+
} finally {
|
|
168
|
+
disable.value = false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function cancel() {
|
|
173
|
+
name.value = "";
|
|
174
|
+
selectedPermissions.value = [];
|
|
175
|
+
createMore.value = false;
|
|
176
|
+
message.value = "";
|
|
177
|
+
emit("cancel");
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5">
|
|
6
|
+
{{ props.name }}
|
|
7
|
+
</span>
|
|
8
|
+
</v-row>
|
|
9
|
+
</v-toolbar>
|
|
10
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
|
|
11
|
+
<v-form v-model="validForm" :disabled="disable">
|
|
12
|
+
<v-row no-gutters>
|
|
13
|
+
<v-col cols="12" class="mt-4">
|
|
14
|
+
<InputListGroupSelection
|
|
15
|
+
v-model="definedModel"
|
|
16
|
+
:items="props.permissions"
|
|
17
|
+
variant="outlined"
|
|
18
|
+
border="thin"
|
|
19
|
+
:error-messages="errorMessages"
|
|
20
|
+
:readonly="!edit"
|
|
21
|
+
:hint="
|
|
22
|
+
edit ? 'Select permissions' : 'Permissions are not editable'
|
|
23
|
+
"
|
|
24
|
+
persistent-hint
|
|
25
|
+
/>
|
|
26
|
+
</v-col>
|
|
27
|
+
|
|
28
|
+
<v-col v-if="edit" cols="12" class="my-2">
|
|
29
|
+
<v-row no-gutters>
|
|
30
|
+
<v-col cols="12" class="text-center">
|
|
31
|
+
<span
|
|
32
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
33
|
+
>
|
|
34
|
+
{{ message }}
|
|
35
|
+
</span>
|
|
36
|
+
</v-col>
|
|
37
|
+
</v-row>
|
|
38
|
+
</v-col>
|
|
39
|
+
|
|
40
|
+
<v-col cols="12" class="my-2">
|
|
41
|
+
<v-row no-gutters>
|
|
42
|
+
<v-col cols="12" class="text-center">
|
|
43
|
+
<span
|
|
44
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
45
|
+
>
|
|
46
|
+
{{ message }}
|
|
47
|
+
</span>
|
|
48
|
+
</v-col>
|
|
49
|
+
</v-row>
|
|
50
|
+
</v-col>
|
|
51
|
+
</v-row>
|
|
52
|
+
</v-form>
|
|
53
|
+
</v-card-text>
|
|
54
|
+
|
|
55
|
+
<v-toolbar>
|
|
56
|
+
<v-row class="px-6">
|
|
57
|
+
<v-col v-if="!edit" cols="6">
|
|
58
|
+
<v-btn
|
|
59
|
+
block
|
|
60
|
+
variant="text"
|
|
61
|
+
class="text-none"
|
|
62
|
+
size="large"
|
|
63
|
+
@click="emit('cancel')"
|
|
64
|
+
>
|
|
65
|
+
Close
|
|
66
|
+
</v-btn>
|
|
67
|
+
</v-col>
|
|
68
|
+
|
|
69
|
+
<v-col v-else cols="6">
|
|
70
|
+
<v-btn
|
|
71
|
+
block
|
|
72
|
+
variant="text"
|
|
73
|
+
class="text-none"
|
|
74
|
+
size="large"
|
|
75
|
+
@click="edit = false"
|
|
76
|
+
:disabled="disable"
|
|
77
|
+
>
|
|
78
|
+
Cancel
|
|
79
|
+
</v-btn>
|
|
80
|
+
</v-col>
|
|
81
|
+
|
|
82
|
+
<v-col v-if="!edit" cols="6">
|
|
83
|
+
<v-btn
|
|
84
|
+
block
|
|
85
|
+
variant="flat"
|
|
86
|
+
color="black"
|
|
87
|
+
class="text-none"
|
|
88
|
+
size="large"
|
|
89
|
+
:disabled="!validForm"
|
|
90
|
+
@click="edit = true"
|
|
91
|
+
>
|
|
92
|
+
Edit
|
|
93
|
+
</v-btn>
|
|
94
|
+
</v-col>
|
|
95
|
+
|
|
96
|
+
<v-col v-else cols="6">
|
|
97
|
+
<v-btn
|
|
98
|
+
block
|
|
99
|
+
variant="flat"
|
|
100
|
+
color="black"
|
|
101
|
+
class="text-none"
|
|
102
|
+
size="large"
|
|
103
|
+
:disabled="!validForm"
|
|
104
|
+
@click="submit()"
|
|
105
|
+
>
|
|
106
|
+
Submit
|
|
107
|
+
</v-btn>
|
|
108
|
+
</v-col>
|
|
109
|
+
</v-row>
|
|
110
|
+
</v-toolbar>
|
|
111
|
+
</v-card>
|
|
112
|
+
</template>
|
|
113
|
+
|
|
114
|
+
<script setup lang="ts">
|
|
115
|
+
const definedModel = defineModel<Array<string>>({
|
|
116
|
+
default: () => [],
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const props = defineProps({
|
|
120
|
+
name: {
|
|
121
|
+
type: String,
|
|
122
|
+
default: "Role",
|
|
123
|
+
},
|
|
124
|
+
id: {
|
|
125
|
+
type: String,
|
|
126
|
+
default: "",
|
|
127
|
+
},
|
|
128
|
+
permissions: {
|
|
129
|
+
type: Object,
|
|
130
|
+
default: () => ({}),
|
|
131
|
+
},
|
|
132
|
+
originalPermissions: {
|
|
133
|
+
type: Object,
|
|
134
|
+
default: () => ({}),
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const validForm = ref(false);
|
|
139
|
+
const message = ref("");
|
|
140
|
+
const disable = ref(false);
|
|
141
|
+
|
|
142
|
+
const emit = defineEmits(["success", "cancel"]);
|
|
143
|
+
|
|
144
|
+
const edit = defineModel<boolean>("edit", {
|
|
145
|
+
default: false,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
function equalListValue() {
|
|
149
|
+
return JSON.stringify(definedModel.value) ===
|
|
150
|
+
JSON.stringify(props.originalPermissions)
|
|
151
|
+
? "No changes made"
|
|
152
|
+
: "";
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const { requireListRule } = useUtils();
|
|
156
|
+
|
|
157
|
+
const errorMessages = computed(() => {
|
|
158
|
+
const equalValue = equalListValue();
|
|
159
|
+
if (edit.value && equalValue) {
|
|
160
|
+
return equalValue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const requiredValue = requireListRule(definedModel.value);
|
|
164
|
+
if (requiredValue) {
|
|
165
|
+
return requiredValue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return "";
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const { updatePermissionById } = useRole();
|
|
172
|
+
|
|
173
|
+
async function submit() {
|
|
174
|
+
disable.value = true;
|
|
175
|
+
try {
|
|
176
|
+
await updatePermissionById(props.id, definedModel.value);
|
|
177
|
+
emit("success");
|
|
178
|
+
} catch (error: any) {
|
|
179
|
+
message.value = error.response._data.message;
|
|
180
|
+
} finally {
|
|
181
|
+
disable.value = false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
</script>
|