拆分规则阻断与搜索未命中状态弹窗

CustomWorldEntityCatalog 改用共享状态弹窗承接 minimum-playable 提示
PlatformEntryFlowShellImpl 将公开编号搜索未命中分支改用共享状态弹窗
保留命中用户摘要弹层布局并补充相关测试与文档记录
This commit is contained in:
2026-06-10 21:32:00 +08:00
parent a076faf652
commit a33914aa5a
5 changed files with 63 additions and 35 deletions

View File

@@ -29,6 +29,7 @@ import { PlatformMediaFrame } from './common/PlatformMediaFrame';
import { PlatformPillBadge } from './common/PlatformPillBadge';
import { PlatformProgressBar } from './common/PlatformProgressBar';
import { PlatformStatGrid } from './common/PlatformStatGrid';
import { PlatformStatusDialog } from './common/PlatformStatusDialog';
import { PlatformStatusMessage } from './common/PlatformStatusMessage';
import { PlatformSubpanel } from './common/PlatformSubpanel';
import { PlatformTextField } from './common/PlatformTextField';
@@ -934,20 +935,10 @@ export function CustomWorldEntityCatalog({
};
const confirmDialogConfig = (() => {
if (!confirmState) {
if (!confirmState || confirmState.kind === 'minimum-playable') {
return null;
}
if (confirmState.kind === 'minimum-playable') {
return {
title: '无法删除',
confirmLabel: '知道了',
confirmTone: 'primary' as const,
showCancel: false,
body: '至少保留一个可扮演角色,才能正常进入自定义世界。',
};
}
if (confirmState.kind === 'delete-playable') {
return {
title: '删除角色',
@@ -1450,11 +1441,24 @@ export function CustomWorldEntityCatalog({
confirmLabel={confirmDialogConfig.confirmLabel}
confirmTone={confirmDialogConfig.confirmTone}
showCancel={confirmDialogConfig.showCancel}
closeOnBackdrop={confirmState?.kind !== 'minimum-playable'}
>
{confirmDialogConfig.body}
</UnifiedConfirmDialog>
) : null}
{confirmState?.kind === 'minimum-playable' ? (
<PlatformStatusDialog
status="error"
title="无法删除"
description="至少保留一个可扮演角色,才能正常进入自定义世界。"
onClose={closeConfirmDialog}
closeOnBackdrop={false}
action={{
label: '知道了',
onClick: closeConfirmDialog,
surface: 'platform',
}}
/>
) : null}
</div>
);
}

View File

@@ -1257,7 +1257,7 @@ test('可扮演角色删除改用统一确认弹窗', async () => {
);
});
test('最后一个可扮演角色不可删除时使用统一提示弹窗', async () => {
test('最后一个可扮演角色不可删除时使用平台状态弹窗', async () => {
const user = userEvent.setup();
const handleProfileChange = vi.fn();
@@ -1283,6 +1283,9 @@ test('最后一个可扮演角色不可删除时使用统一提示弹窗', async
),
).toBeTruthy();
fireEvent.click(dialog.parentElement as HTMLElement);
expect(screen.getByRole('dialog', { name: '无法删除' })).toBeTruthy();
await user.click(within(dialog).getByRole('button', { name: '知道了' }));
expect(handleProfileChange).not.toHaveBeenCalled();

View File

@@ -17079,7 +17079,32 @@ export function PlatformEntryFlowShellImpl({
{pendingDeleteCreationWork?.detail}
</UnifiedConfirmDialog>
<AnimatePresence>
{searchedPublicUser || publicSearchError ? (
{publicSearchError ? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<PlatformStatusDialog
status="error"
title="未找到结果"
description="公开编号搜索"
onClose={closePublicSearchResult}
showHeader
showCloseButton
closeLabel="关闭搜索结果"
overlayClassName={`platform-theme ${platformThemeClass} !items-center bg-black/45 !p-4`}
panelClassName="platform-remap-surface rounded-[1.6rem]"
action={{
label: '知道了',
onClick: closePublicSearchResult,
surface: 'platform',
}}
>
{publicSearchError}
</PlatformStatusDialog>
</motion.div>
) : searchedPublicUser ? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@@ -17087,7 +17112,7 @@ export function PlatformEntryFlowShellImpl({
>
<UnifiedModal
open
title={publicSearchError ? '未找到结果' : '命中用户'}
title="命中用户"
description="公开编号搜索"
onClose={closePublicSearchResult}
closeOnBackdrop={false}
@@ -17097,26 +17122,20 @@ export function PlatformEntryFlowShellImpl({
overlayClassName={`platform-theme ${platformThemeClass} !items-center bg-black/45 !p-4`}
panelClassName="platform-remap-surface rounded-[1.6rem]"
>
{publicSearchError ? (
<PlatformStatusMessage tone="neutral" surface="platform" size="md">
{publicSearchError}
</PlatformStatusMessage>
) : searchedPublicUser ? (
<PlatformSubpanel
as="section"
surface="flat"
radius="sm"
padding="md"
title={searchedPublicUser.displayName}
titleVariant="strong"
bodyClassName="mt-3"
>
<PlatformFieldLabel></PlatformFieldLabel>
<div className="mt-1 text-sm font-semibold text-[var(--platform-text-base)]">
{searchedPublicUser.publicUserCode}
</div>
</PlatformSubpanel>
) : null}
<PlatformSubpanel
as="section"
surface="flat"
radius="sm"
padding="md"
title={searchedPublicUser.displayName}
titleVariant="strong"
bodyClassName="mt-3"
>
<PlatformFieldLabel></PlatformFieldLabel>
<div className="mt-1 text-sm font-semibold text-[var(--platform-text-base)]">
{searchedPublicUser.publicUserCode}
</div>
</PlatformSubpanel>
</UnifiedModal>
</motion.div>
) : null}