diff --git a/src/modules/system/roles/RoleList.vue b/src/modules/system/roles/RoleList.vue
index 7c80f9508..83e7426d1 100644
--- a/src/modules/system/roles/RoleList.vue
+++ b/src/modules/system/roles/RoleList.vue
@@ -1,4 +1,9 @@
diff --git a/src/modules/system/roles/components/RoleEditingModal.vue b/src/modules/system/roles/components/RoleEditingModal.vue
index ea9a90f5a..0897cdb52 100644
--- a/src/modules/system/roles/components/RoleEditingModal.vue
+++ b/src/modules/system/roles/components/RoleEditingModal.vue
@@ -1,6 +1,6 @@
@@ -198,7 +211,7 @@ const handleVisibleChange = (visible: boolean) => {
>
提交 ⌘ + ↵
- 取消 Esc
+ 取消 Esc
diff --git a/src/modules/system/roles/composables/use-role.ts b/src/modules/system/roles/composables/use-role.ts
index dba21bfc8..49df80b50 100644
--- a/src/modules/system/roles/composables/use-role.ts
+++ b/src/modules/system/roles/composables/use-role.ts
@@ -1,4 +1,5 @@
import type { Role } from "@halo-dev/api-client";
+import type { ComputedRef, Ref } from "vue";
import { computed, onMounted, ref } from "vue";
import { roleLabels } from "@/constants/labels";
import { rbacAnnotations } from "@/constants/annotations";
@@ -23,7 +24,65 @@ const initialFormState: Role = {
rules: [],
};
-export function useRoleForm() {
+interface useFetchRoleReturn {
+ roles: Ref;
+ loading: Ref;
+ handleFetchRoles: () => void;
+}
+
+interface useRoleFormReturn {
+ formState: Ref;
+ initialFormState: Role;
+ saving: Ref;
+ isUpdateMode: ComputedRef;
+ handleCreateOrUpdate: () => void;
+}
+
+interface useRoleTemplateSelectionReturn {
+ selectedRoleTemplates: Ref>;
+ roleTemplates: Ref;
+ roleTemplateGroups: ComputedRef;
+ handleRoleTemplateSelect: (e: Event) => void;
+}
+
+/**
+ * Fetch all roles(without role templates) from the API.
+ *
+ * @returns {useFetchRoleReturn}
+ */
+export function useFetchRole(): useFetchRoleReturn {
+ const roles = ref([]);
+ const loading = ref(false);
+
+ const handleFetchRoles = async () => {
+ try {
+ loading.value = true;
+ const { data } = await apiClient.extension.role.listv1alpha1Role(0, 0, [
+ `!${roleLabels.TEMPLATE}`,
+ ]);
+ roles.value = data.items;
+ } catch (e) {
+ console.error("Failed to fetch roles", e);
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ onMounted(handleFetchRoles);
+
+ return {
+ roles,
+ loading,
+ handleFetchRoles,
+ };
+}
+
+/**
+ * Create or update a role.
+ *
+ * @returns {useRoleFormReturn}
+ */
+export function useRoleForm(): useRoleFormReturn {
const formState = ref(initialFormState);
const saving = ref(false);
@@ -58,7 +117,12 @@ export function useRoleForm() {
};
}
-export function useRoleTemplateSelection() {
+/**
+ * Logic for selecting role templates
+ *
+ * @returns {useRoleTemplateSelectionReturn}
+ */
+export function useRoleTemplateSelection(): useRoleTemplateSelectionReturn {
const roleTemplates = ref([] as Role[]);
const selectedRoleTemplates = ref>(new Set());
diff --git a/src/modules/system/users/components/UserEditingModal.vue b/src/modules/system/users/components/UserEditingModal.vue
index a0f6b7d3b..9c4327f84 100644
--- a/src/modules/system/users/components/UserEditingModal.vue
+++ b/src/modules/system/users/components/UserEditingModal.vue
@@ -1,7 +1,10 @@
-