扩展状态弹窗承接提示类 notice
扩展 PlatformStatusDialog 支持标题栏提示与关闭路径 PlatformEntryFlowShellImpl 改用共享状态弹窗承接泥点提示与作品不可用提示 RpgCreationEntityEditorShared 改用共享状态弹窗承接编辑器提示 补充状态弹窗与编辑器提示测试并更新文档记录
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import {
|
||||
cleanup,
|
||||
fireEvent,
|
||||
render,
|
||||
screen,
|
||||
waitFor,
|
||||
@@ -857,11 +858,15 @@ test('可扮演角色至少保留一个背景章节时使用统一提示弹窗',
|
||||
await user.click(deleteChapterButtons()[0]!);
|
||||
|
||||
const dialog = await screen.findByRole('dialog', { name: '提示' });
|
||||
const actionButton = within(dialog).getByRole('button', { name: '知道了' });
|
||||
|
||||
expect(within(dialog).getByText('至少保留一个背景章节。')).toBeTruthy();
|
||||
expect(dialog.querySelector('.platform-icon-badge')).toBeTruthy();
|
||||
expect(actionButton.className).toContain('platform-button');
|
||||
expect(alertSpy).not.toHaveBeenCalled();
|
||||
expect(screen.getByText('编辑角色:沈砺')).toBeTruthy();
|
||||
|
||||
await user.click(within(dialog).getByRole('button', { name: '知道了' }));
|
||||
await user.click(actionButton);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '提示' })).toBeNull();
|
||||
});
|
||||
@@ -1798,12 +1803,15 @@ test('场景连接缺少可连接目标时使用统一提示弹窗', async () =>
|
||||
await user.click(screen.getByText('北'));
|
||||
|
||||
const dialog = await screen.findByRole('dialog', { name: '提示' });
|
||||
const overlay = dialog.parentElement as HTMLElement;
|
||||
|
||||
expect(
|
||||
within(dialog).getByText('请先保留至少一个其他场景,才能配置连接关系。'),
|
||||
).toBeTruthy();
|
||||
expect(overlay.className).toContain('rpg-editor-notice-dialog-overlay');
|
||||
expect(alertSpy).not.toHaveBeenCalled();
|
||||
|
||||
await user.click(within(dialog).getByRole('button', { name: '知道了' }));
|
||||
fireEvent.click(overlay);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '提示' })).toBeNull();
|
||||
});
|
||||
@@ -2000,6 +2008,11 @@ test('场景保存缺少主角色时使用统一提示弹窗', async () => {
|
||||
expect(alertSpy).not.toHaveBeenCalled();
|
||||
expect(screen.getByText('编辑场景:空港栈桥')).toBeTruthy();
|
||||
|
||||
fireEvent.keyDown(window, { key: 'Escape' });
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '提示' })).toBeNull();
|
||||
});
|
||||
|
||||
alertSpy.mockRestore();
|
||||
});
|
||||
|
||||
|
||||
@@ -96,3 +96,37 @@ test('supports custom badge icon label and action button styling', () => {
|
||||
expect(action.className).toContain('border-slate-950');
|
||||
expect(action.className).toContain('bg-slate-950');
|
||||
});
|
||||
|
||||
test('supports header notice layout with body content and close button', () => {
|
||||
const onClose = vi.fn();
|
||||
|
||||
render(
|
||||
<PlatformStatusDialog
|
||||
status="error"
|
||||
title="泥点不足"
|
||||
description="当前表单不会丢失,关闭后可继续编辑或补足泥点再继续。"
|
||||
onClose={onClose}
|
||||
showHeader
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
action={{ label: '知道了', onClick: onClose, surface: 'platform' }}
|
||||
>
|
||||
本次需要 6 泥点,当前 5 泥点。
|
||||
</PlatformStatusDialog>,
|
||||
);
|
||||
|
||||
const dialog = screen.getByRole('dialog', { name: '泥点不足' });
|
||||
|
||||
expect(
|
||||
dialog.querySelector('.mt-4.text-xl.font-black.text-\\[var\\(--platform-text-strong\\)\\]'),
|
||||
).toBeNull();
|
||||
expect(screen.getByText('本次需要 6 泥点,当前 5 泥点。')).toBeTruthy();
|
||||
expect(
|
||||
screen.getByText(
|
||||
'当前表单不会丢失,关闭后可继续编辑或补足泥点再继续。',
|
||||
),
|
||||
).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '关闭' }));
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -39,8 +39,15 @@ type PlatformStatusDialogProps = {
|
||||
status: PlatformStatusDialogStatus;
|
||||
title: string;
|
||||
description?: ReactNode;
|
||||
children?: ReactNode;
|
||||
onClose: () => void;
|
||||
action?: PlatformStatusDialogAction;
|
||||
showHeader?: boolean;
|
||||
showBodyTitle?: boolean;
|
||||
showCloseButton?: boolean;
|
||||
closeOnBackdrop?: boolean;
|
||||
closeOnEscape?: boolean;
|
||||
closeLabel?: string;
|
||||
closeDisabled?: boolean;
|
||||
zIndexClassName?: string;
|
||||
overlayClassName?: string;
|
||||
@@ -101,8 +108,15 @@ export function PlatformStatusDialog({
|
||||
status,
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
onClose,
|
||||
action,
|
||||
showHeader = false,
|
||||
showBodyTitle,
|
||||
showCloseButton = false,
|
||||
closeOnBackdrop = false,
|
||||
closeOnEscape = false,
|
||||
closeLabel,
|
||||
closeDisabled = false,
|
||||
zIndexClassName = 'z-[90]',
|
||||
overlayClassName = DEFAULT_OVERLAY_CLASS,
|
||||
@@ -114,24 +128,26 @@ export function PlatformStatusDialog({
|
||||
}: PlatformStatusDialogProps) {
|
||||
const visualConfig = getStatusVisualConfig(status);
|
||||
const badgeIcon = icon ?? visualConfig.icon;
|
||||
const shouldRenderBodyTitle = showBodyTitle ?? !showHeader;
|
||||
|
||||
return (
|
||||
<UnifiedModal
|
||||
open={open}
|
||||
title={title}
|
||||
onClose={onClose}
|
||||
showHeader={false}
|
||||
showCloseButton={false}
|
||||
showHeader={showHeader}
|
||||
showCloseButton={showCloseButton}
|
||||
closeLabel={closeLabel}
|
||||
closeDisabled={closeDisabled}
|
||||
closeOnBackdrop={false}
|
||||
closeOnEscape={false}
|
||||
closeOnBackdrop={closeOnBackdrop}
|
||||
closeOnEscape={closeOnEscape}
|
||||
portal={false}
|
||||
size="sm"
|
||||
zIndexClassName={zIndexClassName}
|
||||
overlayClassName={overlayClassName}
|
||||
panelClassName={panelClassName}
|
||||
bodyClassName={bodyClassName}
|
||||
>
|
||||
>
|
||||
<PlatformIconBadge
|
||||
icon={badgeIcon}
|
||||
label={iconLabel}
|
||||
@@ -145,9 +161,16 @@ export function PlatformStatusDialog({
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
/>
|
||||
<div className="mt-4 text-xl font-black text-[var(--platform-text-strong)]">
|
||||
{title}
|
||||
</div>
|
||||
{shouldRenderBodyTitle ? (
|
||||
<div className="mt-4 text-xl font-black text-[var(--platform-text-strong)]">
|
||||
{title}
|
||||
</div>
|
||||
) : null}
|
||||
{children ? (
|
||||
<div className="mt-3 text-sm font-semibold leading-6 text-[var(--platform-text-base)]">
|
||||
{children}
|
||||
</div>
|
||||
) : null}
|
||||
{description ? (
|
||||
<div className="mt-3 text-sm font-semibold leading-6 text-[var(--platform-text-soft)]">
|
||||
{description}
|
||||
|
||||
@@ -365,6 +365,7 @@ import type { CustomWorldProfile } from '../../types';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
|
||||
import { PlatformStatusDialog } from '../common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
import { PublishShareModal } from '../common/PublishShareModal';
|
||||
@@ -16996,19 +16997,30 @@ export function PlatformEntryFlowShellImpl({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<UnifiedConfirmDialog
|
||||
<PlatformStatusDialog
|
||||
open={Boolean(draftGenerationPointNotice)}
|
||||
status="error"
|
||||
title={draftGenerationPointNotice?.title ?? '泥点提示'}
|
||||
description={draftGenerationPointNoticeDescription}
|
||||
onClose={() => setDraftGenerationPointNotice(null)}
|
||||
confirmLabel="知道了"
|
||||
showHeader
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
iconClassName={
|
||||
draftGenerationPointNotice?.title === '读取泥点余额失败'
|
||||
? undefined
|
||||
: 'bg-amber-100/80 text-amber-600'
|
||||
}
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: () => setDraftGenerationPointNotice(null),
|
||||
surface: 'platform',
|
||||
}}
|
||||
>
|
||||
{draftGenerationPointNotice?.message}
|
||||
</UnifiedConfirmDialog>
|
||||
</PlatformStatusDialog>
|
||||
<PublishShareModal
|
||||
open={Boolean(publishSharePayload)}
|
||||
payload={publishSharePayload}
|
||||
@@ -17026,18 +17038,24 @@ export function PlatformEntryFlowShellImpl({
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.5rem]"
|
||||
/>
|
||||
<UnifiedConfirmDialog
|
||||
<PlatformStatusDialog
|
||||
open={Boolean(workNotFoundRecoveryDialog)}
|
||||
status="error"
|
||||
title="作品不可用"
|
||||
onClose={confirmWorkNotFoundRecovery}
|
||||
confirmLabel="知道了"
|
||||
showHeader
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: confirmWorkNotFoundRecovery,
|
||||
surface: 'platform',
|
||||
}}
|
||||
>
|
||||
{workNotFoundRecoveryDialog?.message}
|
||||
</UnifiedConfirmDialog>
|
||||
</PlatformStatusDialog>
|
||||
<UnifiedConfirmDialog
|
||||
open={Boolean(pendingDeleteCreationWork)}
|
||||
title="删除作品"
|
||||
|
||||
@@ -102,6 +102,7 @@ import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton';
|
||||
import { PlatformOverlayBadge } from '../common/PlatformOverlayBadge';
|
||||
import { PlatformPillBadge } from '../common/PlatformPillBadge';
|
||||
import { PlatformSlotBadge } from '../common/PlatformSlotBadge';
|
||||
import { PlatformStatusDialog } from '../common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
import { PlatformUploadPreviewCard } from '../common/PlatformUploadPreviewCard';
|
||||
@@ -1494,16 +1495,27 @@ function EditorNoticeDialog({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
return (
|
||||
<UnifiedConfirmDialog
|
||||
open
|
||||
<PlatformStatusDialog
|
||||
status="error"
|
||||
title="提示"
|
||||
description={message}
|
||||
onClose={onClose}
|
||||
confirmLabel="知道了"
|
||||
overlayClassName="z-[140] !items-center"
|
||||
showHeader
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
closeOnEscape
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: onClose,
|
||||
surface: 'platform',
|
||||
size: 'sm',
|
||||
fullWidth: false,
|
||||
className: 'min-h-0 rounded-full px-4 py-2',
|
||||
}}
|
||||
zIndexClassName="z-[140]"
|
||||
overlayClassName="rpg-editor-notice-dialog-overlay !items-center"
|
||||
panelClassName="platform-remap-surface rounded-[1.5rem]"
|
||||
>
|
||||
{message}
|
||||
</UnifiedConfirmDialog>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user