mirror of https://github.com/halo-dev/halo-admin
perf: auto focus when opening editing forms
parent
daaf5bcf7a
commit
ce93d9813b
|
@ -0,0 +1,9 @@
|
|||
export function setFocus(id: string) {
|
||||
const inputElement = document.getElementById(id);
|
||||
if (inputElement instanceof HTMLInputElement) {
|
||||
const timer = setTimeout(() => {
|
||||
inputElement?.focus();
|
||||
clearTimeout(timer);
|
||||
}, 0);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import cloneDeep from "lodash.clonedeep";
|
|||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -95,7 +96,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +122,14 @@ watch(
|
|||
:width="500"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<FormKit id="attachment-group-form" type="form" @submit="handleSave">
|
||||
<FormKit
|
||||
id="attachment-group-form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleSave"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
type="text"
|
||||
|
|
|
@ -133,7 +133,7 @@ onMounted(async () => {
|
|||
</span>
|
||||
</div>
|
||||
<FloatingDropdown v-if="!readonly">
|
||||
<IconMore />
|
||||
<IconMore @click.stop />
|
||||
<template #popper>
|
||||
<div class="w-48 p-2">
|
||||
<VSpace class="w-full" direction="column">
|
||||
|
|
|
@ -7,6 +7,7 @@ import { apiClient, useSettingForm } from "@halo-dev/admin-shared";
|
|||
import { v4 as uuid } from "uuid";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -135,11 +136,14 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
setTimeout(() => {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
const timer = setTimeout(() => {
|
||||
policyTemplate.value = undefined;
|
||||
handleResetForm();
|
||||
handleResetSettingForm();
|
||||
clearTimeout(timer);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
@ -192,9 +196,11 @@ const onVisibleChange = (visible: boolean) => {
|
|||
:actions="false"
|
||||
:preserve="true"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleSave"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
type="text"
|
||||
|
|
|
@ -12,6 +12,7 @@ import type { Category } from "@halo-dev/api-client";
|
|||
// libs
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
|
@ -105,7 +106,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +132,14 @@ watch(
|
|||
:width="600"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<FormKit id="category-form" type="form" @submit="handleSaveCategory">
|
||||
<FormKit
|
||||
id="category-form"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleSaveCategory"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
type="text"
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useRouter } from "vue-router";
|
|||
const props = withDefaults(
|
||||
defineProps<{
|
||||
tag: Tag;
|
||||
route: boolean;
|
||||
route?: boolean;
|
||||
}>(),
|
||||
{
|
||||
route: false,
|
||||
|
|
|
@ -18,6 +18,7 @@ import type { Tag } from "@halo-dev/api-client";
|
|||
// libs
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
|
@ -109,7 +110,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -141,8 +144,14 @@ watch(
|
|||
<IconArrowRight />
|
||||
</div>
|
||||
</template>
|
||||
<FormKit id="tag-form" type="form" @submit="handleSaveTag">
|
||||
<FormKit
|
||||
id="tag-form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleSaveTag"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
type="text"
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
import { VButton, VModal, VSpace } from "@halo-dev/components";
|
||||
import type { Menu } from "@halo-dev/api-client";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { computed, ref, watch, watchEffect } from "vue";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -73,27 +74,41 @@ const onVisibleChange = (visible: boolean) => {
|
|||
}
|
||||
};
|
||||
|
||||
watch(props, (newVal) => {
|
||||
const { Command_Enter } = useMagicKeys();
|
||||
let keyboardWatcher;
|
||||
if (newVal.visible) {
|
||||
keyboardWatcher = watch(Command_Enter, (v) => {
|
||||
if (v) {
|
||||
submitForm("menu-form");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
keyboardWatcher?.unwatch();
|
||||
}
|
||||
|
||||
if (newVal.visible && props.menu) {
|
||||
formState.value = cloneDeep(props.menu);
|
||||
return;
|
||||
}
|
||||
const handleResetForm = () => {
|
||||
formState.value = cloneDeep(initialFormState);
|
||||
formState.value.metadata.name = uuid();
|
||||
reset("menu-form");
|
||||
};
|
||||
|
||||
const { Command_Enter } = useMagicKeys();
|
||||
|
||||
watchEffect(() => {
|
||||
if (Command_Enter.value && props.visible) {
|
||||
submitForm("menu-form");
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.menu,
|
||||
(menu) => {
|
||||
if (menu) {
|
||||
formState.value = cloneDeep(menu);
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<VModal
|
||||
|
@ -106,9 +121,11 @@ watch(props, (newVal) => {
|
|||
id="menu-form"
|
||||
:classes="{ form: 'w-full' }"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleCreateMenu"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
help="可根据此名称查询菜单项"
|
||||
label="菜单名称"
|
||||
|
|
|
@ -9,6 +9,7 @@ import cloneDeep from "lodash.clonedeep";
|
|||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { usePostCategory } from "@/modules/contents/posts/categories/composables/use-post-category";
|
||||
import { usePostTag } from "@/modules/contents/posts/tags/composables/use-post-tag";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -114,7 +115,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +304,12 @@ watch(
|
|||
title="编辑菜单项"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<FormKit id="menuitem-form" type="form" @submit="handleSaveMenuItem">
|
||||
<FormKit
|
||||
id="menuitem-form"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleSaveMenuItem"
|
||||
>
|
||||
<FormKit
|
||||
v-model="selectedMenuItemSource"
|
||||
:options="menuItemSources"
|
||||
|
@ -314,6 +322,7 @@ watch(
|
|||
|
||||
<FormKit
|
||||
v-if="selectedMenuItemSource === 'custom'"
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="名称"
|
||||
type="text"
|
||||
|
|
|
@ -11,6 +11,7 @@ import cloneDeep from "lodash.clonedeep";
|
|||
import { reset, submitForm } from "@formkit/core";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -60,7 +61,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus("displayNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -124,9 +127,11 @@ const handleResetForm = () => {
|
|||
id="role-form"
|
||||
:actions="false"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleCreateOrUpdateRole"
|
||||
>
|
||||
<FormKit
|
||||
id="displayNameInput"
|
||||
v-model="
|
||||
formState.metadata.annotations[rbacAnnotations.DISPLAY_NAME]
|
||||
"
|
||||
|
@ -139,6 +144,7 @@ const handleResetForm = () => {
|
|||
help="角色别名,用于区分角色,不能重复,创建之后不能修改"
|
||||
label="别名"
|
||||
type="text"
|
||||
:disabled="isUpdateMode"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
|
|
|
@ -10,6 +10,7 @@ export default definePlugin({
|
|||
{
|
||||
path: "/settings",
|
||||
component: SystemSettingsLayout,
|
||||
redirect: "/settings/basic",
|
||||
children: [
|
||||
{
|
||||
path: ":group",
|
||||
|
@ -25,7 +26,7 @@ export default definePlugin({
|
|||
items: [
|
||||
{
|
||||
name: "设置",
|
||||
path: "/settings/basic",
|
||||
path: "/settings",
|
||||
icon: IconSettings,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -102,14 +102,12 @@ onMounted(() => {
|
|||
<template>
|
||||
<UserEditingModal
|
||||
v-model:visible="editingModal"
|
||||
v-permission="['system:users:manage']"
|
||||
:user="selectedUser"
|
||||
@close="onEditingModalClose"
|
||||
/>
|
||||
|
||||
<UserPasswordChangeModal
|
||||
v-model:visible="passwordChangeModal"
|
||||
v-permission="['system:users:manage']"
|
||||
:user="selectedUser"
|
||||
@close="handleFetchUsers"
|
||||
/>
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
|
||||
// libs
|
||||
import { v4 as uuid } from "uuid";
|
||||
import YAML from "yaml";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
|
@ -27,6 +26,7 @@ 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<{
|
||||
|
@ -44,41 +44,32 @@ const emit = defineEmits<{
|
|||
(event: "close"): void;
|
||||
}>();
|
||||
|
||||
interface FormState {
|
||||
user: User;
|
||||
saving: boolean;
|
||||
rawMode: boolean;
|
||||
raw: string;
|
||||
}
|
||||
|
||||
const initialFormState: FormState = {
|
||||
user: {
|
||||
spec: {
|
||||
displayName: "",
|
||||
avatar: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
password: "",
|
||||
bio: "",
|
||||
disabled: false,
|
||||
loginHistoryLimit: 0,
|
||||
},
|
||||
apiVersion: "v1alpha1",
|
||||
kind: "User",
|
||||
metadata: {
|
||||
name: uuid(),
|
||||
},
|
||||
const initialFormState: User = {
|
||||
spec: {
|
||||
displayName: "",
|
||||
avatar: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
password: "",
|
||||
bio: "",
|
||||
disabled: false,
|
||||
loginHistoryLimit: 0,
|
||||
},
|
||||
apiVersion: "v1alpha1",
|
||||
kind: "User",
|
||||
metadata: {
|
||||
name: "",
|
||||
},
|
||||
saving: false,
|
||||
rawMode: false,
|
||||
raw: "",
|
||||
};
|
||||
|
||||
const formState = ref<FormState>(cloneDeep(initialFormState));
|
||||
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.user.metadata.creationTimestamp;
|
||||
return !!formState.value.metadata.creationTimestamp;
|
||||
});
|
||||
|
||||
const creationModalTitle = computed(() => {
|
||||
|
@ -86,7 +77,7 @@ const creationModalTitle = computed(() => {
|
|||
});
|
||||
|
||||
const modalWidth = computed(() => {
|
||||
return formState.value.rawMode ? 800 : 700;
|
||||
return rawMode.value ? 800 : 700;
|
||||
});
|
||||
|
||||
const { roles } = useFetchRole();
|
||||
|
@ -112,7 +103,9 @@ watchEffect(() => {
|
|||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
if (visible) {
|
||||
setFocus(isUpdateMode.value ? "displayNameInput" : "userNameInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +115,7 @@ watch(
|
|||
() => props.user,
|
||||
(user) => {
|
||||
if (user) {
|
||||
formState.value.user = cloneDeep(user);
|
||||
formState.value = cloneDeep(user);
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
|
@ -138,24 +131,23 @@ const onVisibleChange = (visible: boolean) => {
|
|||
|
||||
const handleResetForm = () => {
|
||||
formState.value = cloneDeep(initialFormState);
|
||||
formState.value.user.metadata.name = uuid();
|
||||
reset("user-form");
|
||||
};
|
||||
|
||||
const handleCreateUser = async () => {
|
||||
try {
|
||||
formState.value.saving = true;
|
||||
saving.value = true;
|
||||
let user: User;
|
||||
|
||||
if (isUpdateMode.value) {
|
||||
const response = await apiClient.extension.user.updatev1alpha1User({
|
||||
name: formState.value.user.metadata.name,
|
||||
user: formState.value.user,
|
||||
name: formState.value.metadata.name,
|
||||
user: formState.value,
|
||||
});
|
||||
user = response.data;
|
||||
} else {
|
||||
const response = await apiClient.extension.user.createv1alpha1User({
|
||||
user: formState.value.user,
|
||||
user: formState.value,
|
||||
});
|
||||
user = response.data;
|
||||
}
|
||||
|
@ -173,17 +165,17 @@ const handleCreateUser = async () => {
|
|||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
formState.value.saving = false;
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRawModeChange = () => {
|
||||
formState.value.rawMode = !formState.value.rawMode;
|
||||
rawMode.value = !rawMode.value;
|
||||
|
||||
if (formState.value.rawMode) {
|
||||
formState.value.raw = YAML.stringify(formState.value.user);
|
||||
if (rawMode.value) {
|
||||
raw.value = YAML.stringify(formState.value);
|
||||
} else {
|
||||
formState.value.user = YAML.parse(formState.value.raw);
|
||||
formState.value = YAML.parse(raw.value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -196,35 +188,37 @@ const handleRawModeChange = () => {
|
|||
>
|
||||
<template #actions>
|
||||
<div class="modal-header-action" @click="handleRawModeChange">
|
||||
<IconCodeBoxLine v-if="!formState.rawMode" />
|
||||
<IconCodeBoxLine v-if="!rawMode" />
|
||||
<IconEye v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VCodemirror
|
||||
v-show="formState.rawMode"
|
||||
v-model="formState.raw"
|
||||
height="50vh"
|
||||
language="yaml"
|
||||
/>
|
||||
<VCodemirror v-show="rawMode" v-model="raw" height="50vh" language="yaml" />
|
||||
|
||||
<div v-show="!formState.rawMode">
|
||||
<FormKit id="user-form" type="form" @submit="handleCreateUser">
|
||||
<div v-show="!rawMode">
|
||||
<FormKit
|
||||
id="user-form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleCreateUser"
|
||||
>
|
||||
<FormKit
|
||||
v-model="formState.user.metadata.name"
|
||||
id="userNameInput"
|
||||
v-model="formState.metadata.name"
|
||||
:disabled="isUpdateMode"
|
||||
label="用户名"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.user.spec.displayName"
|
||||
id="displayNameInput"
|
||||
v-model="formState.spec.displayName"
|
||||
label="显示名称"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.user.spec.email"
|
||||
v-model="formState.spec.email"
|
||||
label="电子邮箱"
|
||||
type="email"
|
||||
validation="required"
|
||||
|
@ -236,17 +230,17 @@ const handleRawModeChange = () => {
|
|||
type="select"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.user.spec.phone"
|
||||
v-model="formState.spec.phone"
|
||||
label="手机号"
|
||||
type="text"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.user.spec.avatar"
|
||||
v-model="formState.spec.avatar"
|
||||
label="头像"
|
||||
type="text"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
v-model="formState.user.spec.bio"
|
||||
v-model="formState.spec.bio"
|
||||
label="描述"
|
||||
type="textarea"
|
||||
></FormKit>
|
||||
|
@ -255,7 +249,7 @@ const handleRawModeChange = () => {
|
|||
<template #footer>
|
||||
<VSpace>
|
||||
<VButton
|
||||
:loading="formState.saving"
|
||||
:loading="saving"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('user-form')"
|
||||
>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<script lang="ts" setup>
|
||||
import { IconSave, VButton, VModal } from "@halo-dev/components";
|
||||
import { inject, ref } from "vue";
|
||||
import { VButton, VModal, VSpace } from "@halo-dev/components";
|
||||
import { inject, ref, watch, watchEffect } from "vue";
|
||||
import type { User } from "@halo-dev/api-client";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { reset, submitForm } from "@formkit/core";
|
||||
import { useMagicKeys } from "@vueuse/core";
|
||||
import { setFocus } from "@/formkit/utils/focus";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -24,35 +27,54 @@ const emit = defineEmits<{
|
|||
const currentUser = inject<User>("currentUser");
|
||||
|
||||
interface PasswordChangeFormState {
|
||||
state: {
|
||||
password: string;
|
||||
password_confirm?: string;
|
||||
};
|
||||
submitting: boolean;
|
||||
password: string;
|
||||
password_confirm?: string;
|
||||
}
|
||||
|
||||
const formState = ref<PasswordChangeFormState>({
|
||||
state: {
|
||||
password: "",
|
||||
password_confirm: "",
|
||||
},
|
||||
submitting: false,
|
||||
const initialFormState: PasswordChangeFormState = {
|
||||
password: "",
|
||||
password_confirm: "",
|
||||
};
|
||||
|
||||
const formState = ref<PasswordChangeFormState>(cloneDeep(initialFormState));
|
||||
const saving = ref(false);
|
||||
|
||||
const { Command_Enter } = useMagicKeys();
|
||||
|
||||
watchEffect(() => {
|
||||
if (Command_Enter.value && props.visible) {
|
||||
submitForm("password-form");
|
||||
}
|
||||
});
|
||||
|
||||
const handleVisibleChange = (visible: boolean) => {
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
setFocus("passwordInput");
|
||||
} else {
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const onVisibleChange = (visible: boolean) => {
|
||||
emit("update:visible", visible);
|
||||
if (!visible) {
|
||||
formState.value.state.password = "";
|
||||
formState.value.state.password_confirm = "";
|
||||
emit("close");
|
||||
}
|
||||
};
|
||||
|
||||
const handleResetForm = () => {
|
||||
formState.value = cloneDeep(initialFormState);
|
||||
reset("password-form");
|
||||
};
|
||||
|
||||
const handleChangePassword = async () => {
|
||||
try {
|
||||
formState.value.submitting = true;
|
||||
saving.value = true;
|
||||
|
||||
const changePasswordRequest = cloneDeep(formState.value.state);
|
||||
const changePasswordRequest = cloneDeep(formState.value);
|
||||
delete changePasswordRequest.password_confirm;
|
||||
|
||||
if (props.user?.metadata.name === currentUser?.metadata.name) {
|
||||
|
@ -67,11 +89,11 @@ const handleChangePassword = async () => {
|
|||
});
|
||||
}
|
||||
|
||||
handleVisibleChange(false);
|
||||
onVisibleChange(false);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
formState.value.submitting = false;
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -81,16 +103,18 @@ const handleChangePassword = async () => {
|
|||
:visible="visible"
|
||||
:width="500"
|
||||
title="密码修改"
|
||||
@update:visible="handleVisibleChange"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<FormKit
|
||||
id="password-form"
|
||||
v-model="formState.state"
|
||||
v-model="formState"
|
||||
:actions="false"
|
||||
type="form"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="handleChangePassword"
|
||||
>
|
||||
<FormKit
|
||||
id="passwordInput"
|
||||
label="新密码"
|
||||
name="password"
|
||||
type="password"
|
||||
|
@ -104,16 +128,16 @@ const handleChangePassword = async () => {
|
|||
></FormKit>
|
||||
</FormKit>
|
||||
<template #footer>
|
||||
<VButton
|
||||
:loading="formState.submitting"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('password-form')"
|
||||
>
|
||||
<template #icon>
|
||||
<IconSave class="h-full w-full" />
|
||||
</template>
|
||||
保存
|
||||
</VButton>
|
||||
<VSpace>
|
||||
<VButton
|
||||
:loading="saving"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('password-form')"
|
||||
>
|
||||
提交 ⌘ + ↵
|
||||
</VButton>
|
||||
<VButton @click="onVisibleChange(false)">取消 Esc</VButton>
|
||||
</VSpace>
|
||||
</template>
|
||||
</VModal>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue