feat: add tabs to bot settings

This commit is contained in:
xmanrui 2026-09-01 02:31:57 +08:00
parent 08368c135c
commit 009f1abec9
7 changed files with 219 additions and 121 deletions

View file

@ -18,6 +18,10 @@ export const DELIVERY_ENDPOINTS = Object.freeze({
test: 'target.test',
});
export const BOT_SETTINGS_TABS = Object.freeze([
Object.freeze({ id: 'delivery', label: '投递设置' }),
]);
const CHANNEL_DEFINITIONS = Object.freeze({
weixin: {
label: '微信',
@ -654,13 +658,41 @@ export function DeliveryTargetSettingsPage({ channel, account, rpcCall, onBack }
}
};
const deliveryTab = BOT_SETTINGS_TABS[0];
const deliveryTabId = `dim-bot-settings-${deliveryTab.id}-tab`;
const deliveryPanelId = `dim-bot-settings-${deliveryTab.id}-panel`;
return h('section', {
className: 'dim-deliveryPage',
'aria-label': `${account.botName || definition.label}机器人设置`,
},
h('header', { className: 'dim-deliveryHeader' },
h(DeliveryButton, { className: 'dim-deliveryBack', onClick: onBack }, '← 返回机器人列表'),
h('div', { className: 'dim-deliveryHeaderMeta' },
h(DeliveryButton, { className: 'dim-deliveryBack', onClick: onBack }, '← 返回机器人列表')),
h('div', { className: 'dim-botSettingsTabsBar' },
h('nav', {
className: 'dim-botSettingsTabs',
role: 'tablist',
'aria-label': '机器人设置页签',
}, BOT_SETTINGS_TABS.map((tab) => h('button', {
key: tab.id,
id: `dim-bot-settings-${tab.id}-tab`,
type: 'button',
role: 'tab',
className: 'dim-botSettingsTab',
'aria-selected': tab.id === deliveryTab.id,
'aria-controls': `dim-bot-settings-${tab.id}-panel`,
tabIndex: tab.id === deliveryTab.id ? 0 : -1,
}, tab.label)))),
h('div', {
id: deliveryPanelId,
className: 'dim-botSettingsTabPanel',
role: 'tabpanel',
'aria-labelledby': deliveryTabId,
},
h('section', { className: 'dim-deliveryIdentity', 'aria-labelledby': 'dim-delivery-bot-title' },
h('div', { className: 'dim-deliveryIdentityHeading' },
h('h2', { id: 'dim-delivery-bot-title', className: 'dim-deliveryBotName' },
account.botName || '机器人设置'),
h('a', {
className: 'dim-deliveryDocsLink',
href: isEnglish() ? DELIVERY_DOCS_URL.en : DELIVERY_DOCS_URL.zh,
@ -669,11 +701,7 @@ export function DeliveryTargetSettingsPage({ channel, account, rpcCall, onBack }
'aria-label': '打开主动投递使用文档',
},
h('span', null, '使用文档'),
h('span', { 'aria-hidden': 'true' }, '↗')))),
h('section', { className: 'dim-deliveryIdentity', 'aria-labelledby': 'dim-delivery-bot-title' },
h('div', null,
h('h2', { id: 'dim-delivery-bot-title', className: 'dim-deliveryBotName' },
account.botName || '机器人设置')),
h('span', { 'aria-hidden': 'true' }, '↗'))),
h('div', { className: 'dim-deliveryBotId' },
h('span', null, 'Bot ID'),
h('code', { title: account.botId }, account.botId),
@ -745,5 +773,5 @@ export function DeliveryTargetSettingsPage({ channel, account, rpcCall, onBack }
rpcCall: invoke,
onChanged: () => loadTargets({ silent: true }),
onEdit: () => setEditor({ mode: 'edit', target, source: 'edit' }),
})))));
}))))));
}

View file

@ -7,6 +7,9 @@ const EN = Object.freeze({
'IM机器人': 'IM bots',
'IM机器人设置': 'IM bot settings',
'更多机器人设置': 'More bot settings',
'机器人设置': 'Bot settings',
'机器人设置页签': 'Bot settings tabs',
'投递设置': 'Delivery settings',
'IM 渠道': 'IM channels',
'让 DeepSeek Harness 触手可及': 'Connecting DeepSeek Harness',
'当前版本': 'Current version',

View file

@ -369,9 +369,18 @@ const CSS = String.raw`
.dim-botSettingsButton:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
.dim-botSettingsTooltip { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; width: max-content; padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
.dim-botSettingsAction:hover .dim-botSettingsTooltip, .dim-botSettingsAction:focus-within .dim-botSettingsTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
.dim-deliveryPage { min-width: 0; display: grid; gap: 14px; }
.dim-deliveryPage { min-width: 0; display: grid; }
.dim-deliveryHeader { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.dim-deliveryHeaderMeta { min-width: 0; display: flex; align-items: center; justify-content: flex-end; gap: 10px; text-align: right; }
.dim-botSettingsTabsBar { min-width: 0; margin-top: 10px; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
.dim-botSettingsTabs { min-width: 0; display: flex; align-items: flex-end; gap: 24px; overflow-x: auto; scrollbar-width: none; }
.dim-botSettingsTabs::-webkit-scrollbar { display: none; }
.dim-botSettingsTab { position: relative; min-height: 38px; flex: none; display: inline-flex; align-items: center; justify-content: center; padding: 6px 2px 9px; border: 0; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-size: 13px; line-height: 20px; font-weight: 560; white-space: nowrap; cursor: pointer; transition: color .15s ease; }
.dim-botSettingsTab::after { content: ''; position: absolute; right: 0; bottom: -1px; left: 0; height: 2px; border-radius: 2px 2px 0 0; background: transparent; transform: scaleX(.45); transition: background .15s ease, transform .15s ease; }
.dim-botSettingsTab:hover:not([aria-selected="true"]) { color: var(--dsw-alias-label-primary, #1f2329); }
.dim-botSettingsTab[aria-selected="true"] { color: var(--dsw-alias-state-business-primary, #3370ff); font-weight: 650; }
.dim-botSettingsTab[aria-selected="true"]::after { background: var(--dsw-alias-state-business-primary, #3370ff); transform: scaleX(1); }
.dim-botSettingsTab:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: -2px; border-radius: 5px; }
.dim-botSettingsTabPanel { min-width: 0; display: grid; gap: 14px; padding-top: 14px; }
.dim-deliveryDocsLink { min-height: 30px; flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 5px 8px; border-radius: 7px; color: var(--dsw-alias-state-business-primary, #3370ff); font-size: 12px; line-height: 18px; text-decoration: none; white-space: nowrap; }
.dim-deliveryDocsLink:hover { background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 8%, transparent); }
.dim-deliveryDocsLink:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
@ -383,6 +392,7 @@ const CSS = String.raw`
.dim-deliveryButton[data-kind="danger"] { color: var(--dsw-alias-state-error-primary, #d54941); }
.dim-deliveryBack { flex: none; border-color: transparent; background: transparent; }
.dim-deliveryIdentity, .dim-deliveryTargets { min-width: 0; padding: 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
.dim-deliveryIdentityHeading { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dim-deliveryBotName, .dim-deliverySectionHeading h3 { min-width: 0; overflow: hidden; margin: 0; font-size: 15px; line-height: 22px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.dim-deliveryIdentity > div:first-child p, .dim-deliverySectionHeading p { margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
.dim-deliveryBotId { min-width: 0; display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; align-items: center; gap: 10px; margin-top: 12px; padding: 10px 12px; border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
@ -471,8 +481,8 @@ const CSS = String.raw`
.dim-rail { grid-template-columns: minmax(0, 1fr); }
.dim-loopbackRecovery { align-items: stretch; flex-direction: column; gap: 12px; }
.dim-loopbackRecoveryAction { width: 100%; }
.dim-deliveryHeader, .dim-deliverySectionHeading { align-items: stretch; flex-direction: column; }
.dim-deliveryHeaderMeta { justify-content: space-between; text-align: left; }
.dim-deliverySectionHeading { align-items: stretch; flex-direction: column; }
.dim-botSettingsTabs { gap: 18px; }
.dim-deliveryBotId { grid-template-columns: minmax(0, 1fr) max-content; }
.dim-deliveryBotId > span { grid-column: 1 / -1; }
.dim-targetActions .dim-deliveryButton { flex: 1 1 auto; }