fix(ui): couldn't detect form changed in NotifyChannels

This commit is contained in:
Fu Diwei 2024-12-20 14:08:30 +08:00
parent 7c1a2d5f91
commit 9e1e0dee1d
3 changed files with 52 additions and 47 deletions

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useDeepCompareMemo } from "@ant-design/pro-components";
import { Button, Collapse, message, notification, Skeleton, Space, Switch, Tooltip, type CollapseProps } from "antd";
@ -9,6 +9,55 @@ import { notifyChannelsMap } from "@/domain/settings";
import { useNotifyChannelStore } from "@/stores/notify";
import { getErrMsg } from "@/utils/error";
type NotifyChannelProps = {
className?: string;
style?: React.CSSProperties;
channel: string;
};
const NotifyChannel = ({ className, style, channel }: NotifyChannelProps) => {
const { t } = useTranslation();
const [messageApi, MessageContextHolder] = message.useMessage();
const [notificationApi, NotificationContextHolder] = notification.useNotification();
const { channels, setChannel } = useNotifyChannelStore();
const channelConfig = useDeepCompareMemo(() => channels[channel], [channels, channel]);
const [channelFormChanged, setChannelFormChanged] = useState(false);
const channelFormRef = useRef<NotifyChannelEditFormInstance>(null);
const handleClickSubmit = async () => {
await channelFormRef.current!.validateFields();
try {
setChannel(channel, channelFormRef.current!.getFieldsValue());
setChannelFormChanged(false);
messageApi.success(t("common.text.operation_succeeded"));
} catch (err) {
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
}
};
return (
<div className={className} style={style}>
{MessageContextHolder}
{NotificationContextHolder}
<NotifyChannelEditForm ref={channelFormRef} channel={channel} model={channelConfig} onModelChange={() => setChannelFormChanged(true)} />
<Space>
<Button type="primary" disabled={!channelFormChanged} onClick={handleClickSubmit}>
{t("common.button.save")}
</Button>
{channelConfig != null ? <NotifyTestButton channel={channel} disabled={channelFormChanged} /> : null}
</Space>
</div>
);
};
type NotifyChannelsSemanticDOM = "collapse" | "form";
export type NotifyChannelsProps = {
@ -21,40 +70,18 @@ export type NotifyChannelsProps = {
const NotifyChannels = ({ className, classNames, style, styles }: NotifyChannelsProps) => {
const { t, i18n } = useTranslation();
const [messageApi, MessageContextHolder] = message.useMessage();
const [notificationApi, NotificationContextHolder] = notification.useNotification();
const { initialized, channels, setChannel, fetchChannels } = useNotifyChannelStore();
useEffect(() => {
fetchChannels();
}, [fetchChannels]);
const channelFormRefs = useRef<Array<NotifyChannelEditFormInstance | null>>([]);
const channelCollapseItems: CollapseProps["items"] = useDeepCompareMemo(
() =>
Array.from(notifyChannelsMap.values()).map((channel, index) => {
Array.from(notifyChannelsMap.values()).map((channel) => {
return {
key: `channel-${channel.type}`,
label: <>{t(channel.name)}</>,
children: (
<div className={classNames?.form} style={styles?.form}>
<NotifyChannelEditForm ref={(ref) => (channelFormRefs.current[index] = ref)} model={channels[channel.type]} channel={channel.type} />
<Space>
<Button type="primary" onClick={() => handleClickSubmit(channel.type, index)}>
{t("common.button.save")}
</Button>
{channels[channel.type] ? (
<Tooltip title={t("settings.notification.push_test.tooltip")}>
<>
<NotifyTestButton channel={channel.type} />
</>
</Tooltip>
) : null}
</Space>
</div>
),
children: <NotifyChannel className={classNames?.form} style={styles?.form} channel={channel.type} />,
extra: (
<div onClick={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} onMouseUp={(e) => e.stopPropagation()}>
<Switch
@ -76,28 +103,8 @@ const NotifyChannels = ({ className, classNames, style, styles }: NotifyChannels
setChannel(channel, { enabled });
};
const handleClickSubmit = async (channel: string, index: number) => {
const form = channelFormRefs.current[index];
if (!form) {
return;
}
await form.validateFields();
try {
setChannel(channel, form.getFieldsValue());
messageApi.success(t("common.text.operation_succeeded"));
} catch (err) {
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
}
};
return (
<div className={className} style={style}>
{MessageContextHolder}
{NotificationContextHolder}
{!initialized ? (
<Skeleton active />
) : (

View File

@ -27,7 +27,6 @@
"settings.notification.channel.enabled.on": "On",
"settings.notification.channel.enabled.off": "Off",
"settings.notification.push_test.button": "Send Test Notification",
"settings.notification.push_test.tooltip": "Note: Please save settings before testing push.",
"settings.notification.push_test.pushed": "Sent",
"settings.notification.channel.form.bark_server_url.label": "Server URL",
"settings.notification.channel.form.bark_server_url.placeholder": "Please enter server URL",

View File

@ -27,7 +27,6 @@
"settings.notification.channel.enabled.on": "启用",
"settings.notification.channel.enabled.off": "未启用",
"settings.notification.push_test.button": "推送测试消息",
"settings.notification.push_test.tooltip": "提示:修改后请先保存设置再测试推送。",
"settings.notification.push_test.pushed": "已推送",
"settings.notification.channel.form.bark_server_url.label": "服务器地址",
"settings.notification.channel.form.bark_server_url.placeholder": "请输入服务器地址",