mirror of https://github.com/halo-dev/halo-admin
refactor: grant permissions to user
Signed-off-by: Ryan Wang <i@ryanc.cc>pull/624/head
parent
3e8112cbbb
commit
e92d102bf4
|
@ -18,6 +18,7 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
import UserEditingModal from "./components/UserEditingModal.vue";
|
||||
import UserPasswordChangeModal from "./components/UserPasswordChangeModal.vue";
|
||||
import GrantPermissionModal from "./components/GrantPermissionModal.vue";
|
||||
import { inject, onMounted, ref, watch } from "vue";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
import type { User, UserList } from "@halo-dev/api-client";
|
||||
|
@ -30,6 +31,8 @@ const dialog = useDialog();
|
|||
const checkedAll = ref(false);
|
||||
const editingModal = ref<boolean>(false);
|
||||
const passwordChangeModal = ref<boolean>(false);
|
||||
const grantPermissionModal = ref<boolean>(false);
|
||||
|
||||
const users = ref<UserList>({
|
||||
page: 1,
|
||||
size: 10,
|
||||
|
@ -41,7 +44,7 @@ const users = ref<UserList>({
|
|||
hasPrevious: false,
|
||||
});
|
||||
const selectedUserNames = ref<string[]>([]);
|
||||
const selectedUser = ref<User | null>(null);
|
||||
const selectedUser = ref<User>();
|
||||
const currentUser = inject<User>("currentUser");
|
||||
|
||||
const handleFetchUsers = async () => {
|
||||
|
@ -54,7 +57,7 @@ const handleFetchUsers = async () => {
|
|||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
selectedUser.value = null;
|
||||
selectedUser.value = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -149,6 +152,11 @@ const handleOpenPasswordChangeModal = (user: User) => {
|
|||
passwordChangeModal.value = true;
|
||||
};
|
||||
|
||||
const handleOpenGrantPermissionModal = (user: User) => {
|
||||
selectedUser.value = user;
|
||||
grantPermissionModal.value = true;
|
||||
};
|
||||
|
||||
const getRoles = (user: User) => {
|
||||
return JSON.parse(
|
||||
user.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]"
|
||||
|
@ -184,6 +192,12 @@ onMounted(() => {
|
|||
@close="handleFetchUsers"
|
||||
/>
|
||||
|
||||
<GrantPermissionModal
|
||||
v-model:visible="grantPermissionModal"
|
||||
:user="selectedUser"
|
||||
@close="handleFetchUsers"
|
||||
/>
|
||||
|
||||
<VPageHeader title="用户">
|
||||
<template #icon>
|
||||
<IconUserSettings class="mr-2 self-center" />
|
||||
|
@ -419,6 +433,15 @@ onMounted(() => {
|
|||
>
|
||||
修改密码
|
||||
</VButton>
|
||||
<VButton
|
||||
v-if="currentUser?.metadata.name !== user.metadata.name"
|
||||
v-close-popper
|
||||
v-permission="['system:users:manage']"
|
||||
block
|
||||
@click="handleOpenGrantPermissionModal(user)"
|
||||
>
|
||||
分配角色
|
||||
</VButton>
|
||||
<VButton
|
||||
v-if="currentUser?.metadata.name !== user.metadata.name"
|
||||
v-close-popper
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<script lang="ts" setup>
|
||||
import { rbacAnnotations } from "@/constants/annotations";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
import type { FormKitOptionsList } from "@formkit/inputs";
|
||||
import type { User } from "@halo-dev/api-client";
|
||||
import { VModal, VSpace, VButton } from "@halo-dev/components";
|
||||
import SubmitButton from "@/components/button/SubmitButton.vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useFetchRole } from "../../roles/composables/use-role";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
visible: boolean;
|
||||
user?: User;
|
||||
}>(),
|
||||
{
|
||||
visible: false,
|
||||
user: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "update:visible", visible: boolean): void;
|
||||
(event: "close"): void;
|
||||
}>();
|
||||
|
||||
const selectedRole = ref("");
|
||||
const saving = ref(false);
|
||||
|
||||
const { roles } = useFetchRole();
|
||||
const rolesMap = computed<FormKitOptionsList>(() => {
|
||||
return [
|
||||
{
|
||||
label: "请选择角色",
|
||||
value: "",
|
||||
},
|
||||
...roles.value.map((role) => {
|
||||
return {
|
||||
label:
|
||||
role.metadata?.annotations?.[rbacAnnotations.DISPLAY_NAME] ||
|
||||
role.metadata.name,
|
||||
value: role.metadata?.name,
|
||||
};
|
||||
}),
|
||||
];
|
||||
});
|
||||
|
||||
const handleGrantPermission = async () => {
|
||||
try {
|
||||
saving.value = true;
|
||||
await apiClient.user.grantPermission({
|
||||
name: props.user.metadata.name,
|
||||
grantRequest: {
|
||||
roles: [selectedRole.value],
|
||||
},
|
||||
});
|
||||
onVisibleChange(false);
|
||||
} catch (error) {
|
||||
console.log("Failed to grant permission to user", error);
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onVisibleChange = (visible: boolean) => {
|
||||
emit("update:visible", visible);
|
||||
if (!visible) {
|
||||
emit("close");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VModal
|
||||
title="分类角色"
|
||||
:visible="visible"
|
||||
:width="500"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<FormKit
|
||||
id="grant-permission-form"
|
||||
name="grant-permission-form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleGrantPermission"
|
||||
>
|
||||
<FormKit
|
||||
v-model="selectedRole"
|
||||
:options="rolesMap"
|
||||
label="角色"
|
||||
type="select"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
<template #footer>
|
||||
<VSpace>
|
||||
<SubmitButton
|
||||
v-if="visible"
|
||||
:loading="saving"
|
||||
type="secondary"
|
||||
@submit="$formkit.submit('grant-permission-form')"
|
||||
>
|
||||
</SubmitButton>
|
||||
<VButton @click="onVisibleChange(false)">取消 Esc</VButton>
|
||||
</VSpace>
|
||||
</template>
|
||||
</VModal>
|
||||
</template>
|
|
@ -20,22 +20,17 @@ import YAML from "yaml";
|
|||
import cloneDeep from "lodash.clonedeep";
|
||||
import { reset } from "@formkit/core";
|
||||
|
||||
// constants
|
||||
import { rbacAnnotations } from "@/constants/annotations";
|
||||
|
||||
// hooks
|
||||
import { useFetchRole } from "@/modules/system/roles/composables/use-role";
|
||||
import type { FormKitOptionsList } from "@formkit/inputs";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
visible: boolean;
|
||||
user: User | null;
|
||||
user?: User;
|
||||
}>(),
|
||||
{
|
||||
visible: false,
|
||||
user: null,
|
||||
user: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -66,7 +61,6 @@ const formState = ref<User>(cloneDeep(initialFormState));
|
|||
const saving = ref(false);
|
||||
const rawMode = ref(false);
|
||||
const raw = ref("");
|
||||
const selectedRole = ref("");
|
||||
|
||||
const isUpdateMode = computed(() => {
|
||||
return !!formState.value.metadata.creationTimestamp;
|
||||
|
@ -80,18 +74,6 @@ const modalWidth = computed(() => {
|
|||
return rawMode.value ? 800 : 700;
|
||||
});
|
||||
|
||||
const { roles } = useFetchRole();
|
||||
const rolesMap = computed<FormKitOptionsList>(() => {
|
||||
return roles.value.map((role) => {
|
||||
return {
|
||||
label:
|
||||
role.metadata?.annotations?.[rbacAnnotations.DISPLAY_NAME] ||
|
||||
role.metadata.name,
|
||||
value: role.metadata?.name,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
|
@ -129,33 +111,20 @@ const handleResetForm = () => {
|
|||
const handleCreateUser = async () => {
|
||||
try {
|
||||
saving.value = true;
|
||||
let user: User;
|
||||
|
||||
if (isUpdateMode.value) {
|
||||
const response = await apiClient.extension.user.updatev1alpha1User({
|
||||
await apiClient.extension.user.updatev1alpha1User({
|
||||
name: formState.value.metadata.name,
|
||||
user: formState.value,
|
||||
});
|
||||
user = response.data;
|
||||
} else {
|
||||
const response = await apiClient.extension.user.createv1alpha1User({
|
||||
await apiClient.extension.user.createv1alpha1User({
|
||||
user: formState.value,
|
||||
});
|
||||
user = response.data;
|
||||
}
|
||||
|
||||
if (selectedRole.value) {
|
||||
await apiClient.user.grantPermission({
|
||||
name: user.metadata.name,
|
||||
grantRequest: {
|
||||
roles: [selectedRole.value],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onVisibleChange(false);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Failed to create or update user", e);
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
|
@ -219,12 +188,6 @@ const handleRawModeChange = () => {
|
|||
name="email"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="selectedRole"
|
||||
:options="rolesMap"
|
||||
label="角色"
|
||||
type="select"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.spec.phone"
|
||||
label="手机号"
|
||||
|
|
|
@ -11,11 +11,11 @@ import { setFocus } from "@/formkit/utils/focus";
|
|||
const props = withDefaults(
|
||||
defineProps<{
|
||||
visible: boolean;
|
||||
user: User | null;
|
||||
user?: User;
|
||||
}>(),
|
||||
{
|
||||
visible: false,
|
||||
user: null,
|
||||
user: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue