@goweekdays/layer-common 1.1.1 → 1.2.0
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/ConfirmationPrompt.vue +80 -0
- package/components/Input/ListGroupSelection.vue +16 -2
- package/components/InvitationMain.vue +16 -4
- package/composables/useApps.ts +57 -0
- package/composables/useLocalAuth.ts +0 -8
- package/composables/useLocalSetup.ts +1 -1
- package/composables/usePermission.ts +96 -0
- package/composables/useUtils.ts +8 -0
- package/package.json +2 -2
- package/types/local.d.ts +11 -0
- package/types/permission.d.ts +22 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @goweekdays/layer-common
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1e43eff: Add app and permission management composables and types
|
|
8
|
+
|
|
9
|
+
## 1.1.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 4a76e4a: Invitation management - fix form component
|
|
14
|
+
|
|
3
15
|
## 1.1.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar density="compact" class="pl-4">
|
|
4
|
+
<span class="font-weight-medium text-h5 text-capitalize">
|
|
5
|
+
{{ localProps.title }}
|
|
6
|
+
</span>
|
|
7
|
+
</v-toolbar>
|
|
8
|
+
|
|
9
|
+
<v-card-text>
|
|
10
|
+
<p class="text-subtitle-2 text-center">
|
|
11
|
+
{{ localProps.content }}
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<v-row v-if="localProps.message" no-gutters justify="center" class="mt-4">
|
|
15
|
+
<span class="text-caption text-error text-center">
|
|
16
|
+
{{ localProps.message }}
|
|
17
|
+
</span>
|
|
18
|
+
</v-row>
|
|
19
|
+
</v-card-text>
|
|
20
|
+
|
|
21
|
+
<v-toolbar density="compact">
|
|
22
|
+
<v-row no-gutters>
|
|
23
|
+
<v-col cols="6">
|
|
24
|
+
<v-btn
|
|
25
|
+
tile
|
|
26
|
+
block
|
|
27
|
+
size="48"
|
|
28
|
+
variant="text"
|
|
29
|
+
class="text-none"
|
|
30
|
+
@click="emits('cancel')"
|
|
31
|
+
:disabled="localProps.disabled"
|
|
32
|
+
>
|
|
33
|
+
Cancel
|
|
34
|
+
</v-btn>
|
|
35
|
+
</v-col>
|
|
36
|
+
<v-col cols="6">
|
|
37
|
+
<v-btn
|
|
38
|
+
tile
|
|
39
|
+
block
|
|
40
|
+
size="48"
|
|
41
|
+
color="black"
|
|
42
|
+
variant="flat"
|
|
43
|
+
class="text-none"
|
|
44
|
+
@click="emits('confirm')"
|
|
45
|
+
:disabled="localProps.disabled"
|
|
46
|
+
>
|
|
47
|
+
{{ localProps.action }}
|
|
48
|
+
</v-btn>
|
|
49
|
+
</v-col>
|
|
50
|
+
</v-row>
|
|
51
|
+
</v-toolbar>
|
|
52
|
+
</v-card>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
const localProps = defineProps({
|
|
57
|
+
title: {
|
|
58
|
+
type: String,
|
|
59
|
+
default: "Title",
|
|
60
|
+
},
|
|
61
|
+
message: {
|
|
62
|
+
type: String,
|
|
63
|
+
default: "",
|
|
64
|
+
},
|
|
65
|
+
disabled: {
|
|
66
|
+
type: Boolean,
|
|
67
|
+
default: false,
|
|
68
|
+
},
|
|
69
|
+
action: {
|
|
70
|
+
type: String,
|
|
71
|
+
default: "Submit",
|
|
72
|
+
},
|
|
73
|
+
content: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: "Are you sure you want to proceed?",
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const emits = defineEmits(["cancel", "confirm"]);
|
|
80
|
+
</script>
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
read-only
|
|
11
11
|
open-strategy="single"
|
|
12
12
|
>
|
|
13
|
+
<template name="prepend"></template>
|
|
14
|
+
|
|
13
15
|
<template
|
|
14
16
|
v-for="(permission, permissionKey, permissionIndex) in props.items"
|
|
15
17
|
:key="permissionKey"
|
|
@@ -61,8 +63,8 @@
|
|
|
61
63
|
</span>
|
|
62
64
|
</template>
|
|
63
65
|
|
|
64
|
-
<template #prepend="{ isSelected }"
|
|
65
|
-
<v-list-item-action start>
|
|
66
|
+
<template #prepend="{ isSelected }">
|
|
67
|
+
<v-list-item-action start class="pl-1">
|
|
66
68
|
<v-checkbox-btn :model-value="isSelected"></v-checkbox-btn>
|
|
67
69
|
</v-list-item-action>
|
|
68
70
|
</template>
|
|
@@ -70,6 +72,14 @@
|
|
|
70
72
|
</template>
|
|
71
73
|
</v-list-group>
|
|
72
74
|
</template>
|
|
75
|
+
|
|
76
|
+
<slot v-if="noData" name="no-data">
|
|
77
|
+
<v-list-item>
|
|
78
|
+
<v-list-item-title>No data</v-list-item-title>
|
|
79
|
+
</v-list-item>
|
|
80
|
+
</slot>
|
|
81
|
+
|
|
82
|
+
<template name="append"></template>
|
|
73
83
|
</v-list>
|
|
74
84
|
</v-card>
|
|
75
85
|
</v-input>
|
|
@@ -90,4 +100,8 @@ const selectedActionCount = (resource: string) => {
|
|
|
90
100
|
return selected.value.filter((permission) => permission.startsWith(resource))
|
|
91
101
|
.length;
|
|
92
102
|
};
|
|
103
|
+
|
|
104
|
+
const noData = computed(() => {
|
|
105
|
+
return Object.keys(props.items).length === 0;
|
|
106
|
+
});
|
|
93
107
|
</script>
|
|
@@ -47,16 +47,20 @@
|
|
|
47
47
|
<v-tabs>
|
|
48
48
|
<v-tab
|
|
49
49
|
:to="{
|
|
50
|
-
name:
|
|
51
|
-
params:
|
|
50
|
+
name: props.route,
|
|
51
|
+
params: props.org
|
|
52
|
+
? { status: 'pending', org: props.org }
|
|
53
|
+
: { status: 'active' },
|
|
52
54
|
}"
|
|
53
55
|
>
|
|
54
56
|
Pending
|
|
55
57
|
</v-tab>
|
|
56
58
|
<v-tab
|
|
57
59
|
:to="{
|
|
58
|
-
name:
|
|
59
|
-
params:
|
|
60
|
+
name: props.route,
|
|
61
|
+
params: props.org
|
|
62
|
+
? { status: 'expired', org: props.org }
|
|
63
|
+
: { status: 'pending' },
|
|
60
64
|
}"
|
|
61
65
|
>
|
|
62
66
|
Expired
|
|
@@ -91,6 +95,10 @@
|
|
|
91
95
|
|
|
92
96
|
<script setup lang="ts">
|
|
93
97
|
const props = defineProps({
|
|
98
|
+
org: {
|
|
99
|
+
type: String,
|
|
100
|
+
default: "",
|
|
101
|
+
},
|
|
94
102
|
status: {
|
|
95
103
|
type: String,
|
|
96
104
|
default: "active",
|
|
@@ -110,6 +118,10 @@ const props = defineProps({
|
|
|
110
118
|
params: {},
|
|
111
119
|
}),
|
|
112
120
|
},
|
|
121
|
+
route: {
|
|
122
|
+
type: String,
|
|
123
|
+
default: "index",
|
|
124
|
+
},
|
|
113
125
|
});
|
|
114
126
|
|
|
115
127
|
const organization = (useRoute().params.organization as string) ?? "";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export default function useApps() {
|
|
2
|
+
const app = ref<TApp>({
|
|
3
|
+
_id: "",
|
|
4
|
+
code: "",
|
|
5
|
+
name: "",
|
|
6
|
+
description: "",
|
|
7
|
+
status: "active",
|
|
8
|
+
createdAt: "",
|
|
9
|
+
updatedAt: "",
|
|
10
|
+
deletedAt: "",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const resource = "/api/apps";
|
|
14
|
+
|
|
15
|
+
function add(value: TApp) {
|
|
16
|
+
return $fetch(resource, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: value,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getAll({
|
|
23
|
+
page = 1,
|
|
24
|
+
limit = 10,
|
|
25
|
+
search = "",
|
|
26
|
+
status = "active",
|
|
27
|
+
} = {}) {
|
|
28
|
+
return $fetch<Record<string, any>>(resource, {
|
|
29
|
+
method: "GET",
|
|
30
|
+
query: { page, limit, search, status },
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function updateById(
|
|
35
|
+
id: string,
|
|
36
|
+
value: { name: string; description: string }
|
|
37
|
+
) {
|
|
38
|
+
return $fetch(`${resource}/id/${id}`, {
|
|
39
|
+
method: "PATCH",
|
|
40
|
+
body: value,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function deleteById(id: string) {
|
|
45
|
+
return $fetch(`${resource}/id/${id}`, {
|
|
46
|
+
method: "DELETE",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
app,
|
|
52
|
+
add,
|
|
53
|
+
getAll,
|
|
54
|
+
updateById,
|
|
55
|
+
deleteById,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -8,14 +8,6 @@ export default function useLocalAuth() {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
// Get access token from cookies
|
|
12
|
-
const accessToken = useCookie("accessToken", cookieConfig).value;
|
|
13
|
-
|
|
14
|
-
if (!accessToken) {
|
|
15
|
-
// Redirect to login page if no access token
|
|
16
|
-
navigateTo({ name: "index" });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
const user = useCookie("user", cookieConfig).value;
|
|
20
12
|
|
|
21
13
|
const { data: getCurrentUserReq, error: getCurrentUserErr } =
|
|
@@ -6,7 +6,7 @@ export function useLocalSetup(type: string, org?: string) {
|
|
|
6
6
|
const { getByUserType } = useMember();
|
|
7
7
|
|
|
8
8
|
const { data: userMemberData, error: userMemberError } = useLazyAsyncData(
|
|
9
|
-
"get-member-by-id",
|
|
9
|
+
"get-member-by-id-local-setup",
|
|
10
10
|
() => getByUserType(userId.value, type, org),
|
|
11
11
|
{ watch: [userId], immediate: false }
|
|
12
12
|
);
|
|
@@ -47,8 +47,104 @@ export default function usePermission() {
|
|
|
47
47
|
return false;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
const perm = ref<TPerm>({
|
|
51
|
+
app: "",
|
|
52
|
+
key: "",
|
|
53
|
+
group: "",
|
|
54
|
+
description: "",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function addPerm(value: TPerm) {
|
|
58
|
+
return $fetch("/api/permissions", {
|
|
59
|
+
method: "POST",
|
|
60
|
+
body: value,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function updatePermById(
|
|
65
|
+
id: string,
|
|
66
|
+
value: Pick<TPerm, "key" | "group" | "description">
|
|
67
|
+
) {
|
|
68
|
+
return $fetch(`/api/permissions/id/${id}`, {
|
|
69
|
+
method: "PATCH",
|
|
70
|
+
body: value,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getAllPerm({
|
|
75
|
+
page = 1,
|
|
76
|
+
limit = 10,
|
|
77
|
+
search = "",
|
|
78
|
+
app = "",
|
|
79
|
+
status = "active",
|
|
80
|
+
} = {}) {
|
|
81
|
+
return $fetch<Record<string, any>>("/api/permissions", {
|
|
82
|
+
method: "GET",
|
|
83
|
+
query: { page, limit, search, app, status },
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function deletePermById(id: string) {
|
|
88
|
+
return $fetch(`/api/permissions/id/${id}`, {
|
|
89
|
+
method: "DELETE",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const permGroup = ref<TPermGroup>({
|
|
94
|
+
app: "",
|
|
95
|
+
key: "",
|
|
96
|
+
label: "",
|
|
97
|
+
order: 0,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
function addPermGroup(value: Pick<TPermGroup, "app" | "key" | "label">) {
|
|
101
|
+
return $fetch("/api/permissions/groups", {
|
|
102
|
+
method: "POST",
|
|
103
|
+
body: value,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function updatePermGroupById(
|
|
108
|
+
id: string,
|
|
109
|
+
value: Pick<TPermGroup, "key" | "label">
|
|
110
|
+
) {
|
|
111
|
+
return $fetch(`/api/permissions/groups/id/${id}`, {
|
|
112
|
+
method: "PATCH",
|
|
113
|
+
body: value,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getAllPermGroup({
|
|
118
|
+
page = 1,
|
|
119
|
+
limit = 10,
|
|
120
|
+
search = "",
|
|
121
|
+
app = "",
|
|
122
|
+
status = "active",
|
|
123
|
+
} = {}) {
|
|
124
|
+
return $fetch<Record<string, any>>("/api/permissions/groups", {
|
|
125
|
+
method: "GET",
|
|
126
|
+
query: { page, limit, search, app, status },
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function deletePermGroupById(id: string) {
|
|
131
|
+
return $fetch(`/api/permissions/groups/id/${id}`, {
|
|
132
|
+
method: "DELETE",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
50
136
|
return {
|
|
51
137
|
listPermissions,
|
|
52
138
|
hasPermission,
|
|
139
|
+
perm,
|
|
140
|
+
addPerm,
|
|
141
|
+
updatePermById,
|
|
142
|
+
getAllPerm,
|
|
143
|
+
deletePermById,
|
|
144
|
+
permGroup,
|
|
145
|
+
addPermGroup,
|
|
146
|
+
updatePermGroupById,
|
|
147
|
+
getAllPermGroup,
|
|
148
|
+
deletePermGroupById,
|
|
53
149
|
};
|
|
54
150
|
}
|
package/composables/useUtils.ts
CHANGED
|
@@ -74,6 +74,13 @@ export default function useUtils() {
|
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
function validateKey(value: string) {
|
|
78
|
+
const pattern = /^[a-z._-]+$/;
|
|
79
|
+
return (
|
|
80
|
+
pattern.test(value) || "Key must be lowercase and can include ., _, -"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
77
84
|
function back() {
|
|
78
85
|
useRouter().back();
|
|
79
86
|
}
|
|
@@ -296,5 +303,6 @@ export default function useUtils() {
|
|
|
296
303
|
replaceMatch,
|
|
297
304
|
setRouteParams,
|
|
298
305
|
positiveNumberRule,
|
|
306
|
+
validateKey,
|
|
299
307
|
};
|
|
300
308
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@goweekdays/layer-common",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.2.0",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"typescript": "^5.6.3",
|
|
24
24
|
"vite-plugin-vuetify": "^2.0.4",
|
|
25
25
|
"vue": "latest",
|
|
26
|
-
"vuetify": "^3.
|
|
26
|
+
"vuetify": "^3.11.6"
|
|
27
27
|
},
|
|
28
28
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
|
29
29
|
"dependencies": {
|
package/types/local.d.ts
CHANGED
|
@@ -23,3 +23,14 @@ declare type TKeyValuePair<
|
|
|
23
23
|
> = {
|
|
24
24
|
[key in K]: V;
|
|
25
25
|
};
|
|
26
|
+
|
|
27
|
+
declare type TApp = {
|
|
28
|
+
_id?: string;
|
|
29
|
+
code: string;
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
status?: string;
|
|
33
|
+
createdAt?: string | Date;
|
|
34
|
+
updatedAt?: string | Date;
|
|
35
|
+
deletedAt?: string | Date;
|
|
36
|
+
};
|
package/types/permission.d.ts
CHANGED
|
@@ -12,3 +12,25 @@ declare type TPermissions = {
|
|
|
12
12
|
[action: string]: TPermission;
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
+
|
|
16
|
+
declare type TPerm = {
|
|
17
|
+
_id?: string;
|
|
18
|
+
app: string;
|
|
19
|
+
key: string;
|
|
20
|
+
group: string;
|
|
21
|
+
description: string;
|
|
22
|
+
createdAt?: string | Date;
|
|
23
|
+
updatedAt?: string | Date;
|
|
24
|
+
deletedAt?: string | Date;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
declare type TPermGroup = {
|
|
28
|
+
_id?: string;
|
|
29
|
+
app: string;
|
|
30
|
+
key: string;
|
|
31
|
+
label: string;
|
|
32
|
+
order: number;
|
|
33
|
+
createdAt?: string | Date;
|
|
34
|
+
updatedAt?: string | Date;
|
|
35
|
+
deletedAt?: string | Date;
|
|
36
|
+
};
|