mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-12 09:34:05 +08:00
🐛 fix(nacos): 优化远程配置更新提示布局
- V2 远端变更提示移入配置详情标题区,避免占据工作台整行 - 使用紧凑状态条并保留加载远端与图标式忽略操作 - 仅本地存在未保存草稿时展示覆盖风险提示,旧版 Alert 行为保持不变 - 更新配置选择与远端变更监听测试
This commit is contained in:
@@ -96,6 +96,8 @@ vi.mock('@ant-design/icons', async () => {
|
||||
const React = await import('react');
|
||||
const Icon = () => React.createElement('span', { 'data-icon': true });
|
||||
return {
|
||||
CloseOutlined: Icon,
|
||||
CloudSyncOutlined: Icon,
|
||||
DeleteOutlined: Icon,
|
||||
DownloadOutlined: Icon,
|
||||
ExperimentOutlined: Icon,
|
||||
@@ -776,16 +778,18 @@ describe('NacosViewer config selection actions', () => {
|
||||
expect(antdState.message.info).toHaveBeenCalledTimes(1);
|
||||
expect(renderedText(renderer!.toJSON())).not.toContain('Listening');
|
||||
|
||||
const compactBanner = renderer!.root.find(
|
||||
(node) => String(node.type) === 'alert',
|
||||
);
|
||||
expect(compactBanner.props.className).toBe('gn-v2-nacos-banner');
|
||||
expect(renderedText(compactBanner)).toContain('Remote config update detected');
|
||||
expect(renderedText(compactBanner)).toContain('Reload remote');
|
||||
expect(renderedText(compactBanner)).toContain('Dismiss');
|
||||
expect(renderedText(compactBanner)).not.toContain('Local draft is clean');
|
||||
expect(renderer!.root.findAll((node) => String(node.type) === 'alert')).toHaveLength(0);
|
||||
const compactNotice = renderer!.root.findByProps({
|
||||
className: 'gn-v2-nacos-remote-notice',
|
||||
});
|
||||
expect(renderedText(compactNotice)).toContain('Remote config update detected');
|
||||
expect(renderedText(compactNotice)).toContain('Reload remote');
|
||||
expect(renderedText(compactNotice)).not.toContain('Dismiss');
|
||||
expect(renderedText(compactNotice)).not.toContain('Local draft is clean');
|
||||
expect(compactNotice.findByProps({ 'aria-label': 'Dismiss' })).toBeTruthy();
|
||||
expect(
|
||||
compactBanner.findByProps({ className: 'gn-v2-nacos-banner__copy' }),
|
||||
renderer!.root.findByProps({ className: 'gn-v2-nacos-detail-pane' })
|
||||
.findByProps({ className: 'gn-v2-nacos-remote-notice' }),
|
||||
).toBeTruthy();
|
||||
|
||||
await act(async () => {
|
||||
|
||||
@@ -18,6 +18,8 @@ import {
|
||||
message,
|
||||
} from 'antd';
|
||||
import {
|
||||
CloseOutlined,
|
||||
CloudSyncOutlined,
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
ExperimentOutlined,
|
||||
@@ -1273,28 +1275,12 @@ const NacosViewer: React.FC<NacosViewerProps> = ({
|
||||
color: workbenchTheme.textPrimary,
|
||||
}}
|
||||
>
|
||||
{remoteChanged ? (
|
||||
{remoteChanged && !isV2Ui ? (
|
||||
<Alert
|
||||
type="warning"
|
||||
showIcon
|
||||
className={isV2Ui ? 'gn-v2-nacos-banner' : undefined}
|
||||
message={
|
||||
isV2Ui ? (
|
||||
<span className="gn-v2-nacos-banner__copy">
|
||||
<span className="gn-v2-nacos-banner__title">
|
||||
{tr('nacos_viewer.message.remote_changed_banner')}
|
||||
</span>
|
||||
{draftDirty ? (
|
||||
<span className="gn-v2-nacos-banner__hint" title={remoteChangedHint}>
|
||||
{remoteChangedHint}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
) : (
|
||||
tr('nacos_viewer.message.remote_changed_banner')
|
||||
)
|
||||
}
|
||||
description={isV2Ui ? undefined : remoteChangedHint}
|
||||
message={tr('nacos_viewer.message.remote_changed_banner')}
|
||||
description={remoteChangedHint}
|
||||
action={
|
||||
<Space size={4}>
|
||||
<Button size="small" type="primary" onClick={() => void handleReloadRemote()}>
|
||||
@@ -1302,7 +1288,6 @@ const NacosViewer: React.FC<NacosViewerProps> = ({
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
type={isV2Ui ? 'text' : 'default'}
|
||||
onClick={() => setRemoteChanged(false)}
|
||||
>
|
||||
{tr('nacos_viewer.action.dismiss_remote')}
|
||||
@@ -1673,6 +1658,49 @@ const NacosViewer: React.FC<NacosViewerProps> = ({
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
</div>
|
||||
{remoteChanged && isV2Ui ? (
|
||||
<div
|
||||
className={`gn-v2-nacos-remote-notice${draftDirty ? ' is-dirty' : ''}`}
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
>
|
||||
<CloudSyncOutlined className="gn-v2-nacos-remote-notice__icon" />
|
||||
<span className="gn-v2-nacos-remote-notice__copy">
|
||||
<span
|
||||
className="gn-v2-nacos-remote-notice__title"
|
||||
title={tr('nacos_viewer.message.remote_changed_banner')}
|
||||
>
|
||||
{tr('nacos_viewer.message.remote_changed_banner')}
|
||||
</span>
|
||||
{draftDirty ? (
|
||||
<span className="gn-v2-nacos-remote-notice__hint" title={remoteChangedHint}>
|
||||
{remoteChangedHint}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
<span className="gn-v2-nacos-remote-notice__actions">
|
||||
<Button
|
||||
className="gn-v2-nacos-remote-notice__reload"
|
||||
size="small"
|
||||
type="primary"
|
||||
icon={<ReloadOutlined />}
|
||||
onClick={() => void handleReloadRemote()}
|
||||
>
|
||||
{tr('nacos_viewer.action.reload_remote')}
|
||||
</Button>
|
||||
<Tooltip title={tr('nacos_viewer.action.dismiss_remote')}>
|
||||
<Button
|
||||
className="gn-v2-nacos-remote-notice__dismiss"
|
||||
size="small"
|
||||
type="text"
|
||||
icon={<CloseOutlined />}
|
||||
aria-label={tr('nacos_viewer.action.dismiss_remote')}
|
||||
onClick={() => setRemoteChanged(false)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
@@ -961,53 +961,57 @@ body[data-ui-version="v2"] .gn-v2-nacos-workbench {
|
||||
color: var(--gn-fg-1);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner {
|
||||
flex: 0 0 auto;
|
||||
align-self: center;
|
||||
width: min(820px, calc(100% - 24px));
|
||||
min-height: 40px;
|
||||
margin: 8px auto !important;
|
||||
padding: 6px 8px 6px 10px !important;
|
||||
align-items: center !important;
|
||||
border: 1px solid color-mix(in srgb, var(--gn-warn) 28%, transparent) !important;
|
||||
border-inline-start: 3px solid var(--gn-warn) !important;
|
||||
border-radius: 8px !important;
|
||||
background: color-mix(in srgb, var(--gn-warn-soft) 72%, var(--gn-bg-panel)) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner .ant-alert-icon {
|
||||
margin-inline-end: 9px;
|
||||
color: var(--gn-warn) !important;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner .ant-alert-content {
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice {
|
||||
width: auto !important;
|
||||
max-width: min(680px, 100%);
|
||||
min-width: 0;
|
||||
min-height: 30px;
|
||||
align-self: flex-end;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
box-sizing: border-box;
|
||||
padding: 3px 4px 3px 9px;
|
||||
border: 0;
|
||||
border-inline-start: 2px solid color-mix(in srgb, var(--gn-warn) 72%, transparent);
|
||||
border-radius: 4px;
|
||||
background: color-mix(in srgb, var(--gn-warn) 7%, transparent);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner .ant-alert-message {
|
||||
margin-bottom: 0;
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice.is-dirty {
|
||||
background: color-mix(in srgb, var(--gn-warn) 10%, transparent);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner__copy {
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__icon {
|
||||
flex: 0 0 auto;
|
||||
color: var(--gn-warn);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__copy {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner__title {
|
||||
flex: 0 0 auto;
|
||||
color: var(--gn-fg-1);
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner__hint {
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__title {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
flex: 0 1 auto;
|
||||
color: var(--gn-fg-1);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__hint {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
flex: 1 1 auto;
|
||||
color: var(--gn-fg-3);
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
@@ -1015,29 +1019,37 @@ body[data-ui-version="v2"] .gn-v2-nacos-banner__hint {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner .ant-alert-action {
|
||||
margin-inline-start: 12px;
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__actions {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner .ant-btn {
|
||||
height: 26px;
|
||||
padding-inline: 9px;
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice .ant-btn {
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner {
|
||||
width: calc(100% - 12px);
|
||||
margin: 6px !important;
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__reload {
|
||||
padding-inline: 7px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__dismiss {
|
||||
width: 24px;
|
||||
padding: 0;
|
||||
color: var(--gn-fg-3);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice {
|
||||
align-self: stretch;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner__copy {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-banner__hint {
|
||||
white-space: normal;
|
||||
body[data-ui-version="v2"] .gn-v2-nacos-remote-notice__hint {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user