Phase 007: migrate every remaining view from naive-ui to Arco Design Vue
The project now has exactly one UI library. Every naive-ui component in
packages/client/src is replaced by its Arco equivalent across 24 views and
roughly 80 components, and naive-ui is dropped from package.json along with
its transitive vueuc / @css-render / vdirs / seemly dependencies.
The migration is rendering-layer only. No store logic, no API contract, and
no /chat-run payload was touched.
Three classes of leftover were invisible to `grep naive-ui` and are now
covered by tests/client/no-naive-ui.test.ts, which asserts all three:
- dead .n-* class names in style blocks
- dead --n-* custom properties
- naive-ui in package.json
Notable behavioural traps handled along the way, recorded in
docs/arco-migration-rules.md:
- a-input-password defaults to masked; passing default-visibility="false"
would have exposed API keys in clear text
- a-upload fires a real XHR unless auto-upload is false
- nested Trigger components fight over the first element child, so the
group-chat settings dropdown was flattened
- Arco renders tooltip default-slot text inline, which was silently
collapsing the chat and group-chat toolbars
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import { NInputNumber, NSelect, NSwitch } from "naive-ui";
|
||||
import { useMessage } from "@/composables/useMessage";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useSettingsStore } from "@/stores/hermes/settings";
|
||||
@@ -15,7 +14,7 @@ const { t } = useI18n();
|
||||
const debounceTimers: Record<string, ReturnType<typeof setTimeout>> = {};
|
||||
|
||||
function save(values: Record<string, any>) {
|
||||
// NSelect/NSwitch 等一次性操作,直接保存,不需要防抖
|
||||
// 下拉/开关等一次性操作,直接保存,不需要防抖
|
||||
settingsStore.updateLocal('session_reset', values)
|
||||
settingsStore.saveSection('session_reset', values).then(() => {
|
||||
message.success(t("settings.saved"));
|
||||
@@ -66,32 +65,32 @@ async function toggleWriteApproval(section: "memory" | "skills", value: boolean)
|
||||
:label="t('settings.session.requireAuth')"
|
||||
:hint="t('settings.session.requireAuthHint')"
|
||||
>
|
||||
<NSwitch :value="settingsStore.approvals.mode === 'manual'" @update:value="toggleRequireAuth" />
|
||||
<a-switch :model-value="settingsStore.approvals.mode === 'manual'" @update:model-value="(v) => toggleRequireAuth(v as boolean)" />
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.memoryWriteApproval')"
|
||||
:hint="t('settings.session.memoryWriteApprovalHint')"
|
||||
>
|
||||
<NSwitch
|
||||
:value="settingsStore.memory.write_approval === true"
|
||||
@update:value="(value) => toggleWriteApproval('memory', value)"
|
||||
<a-switch
|
||||
:model-value="settingsStore.memory.write_approval === true"
|
||||
@update:model-value="(value) => toggleWriteApproval('memory', value as boolean)"
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.skillsWriteApproval')"
|
||||
:hint="t('settings.session.skillsWriteApprovalHint')"
|
||||
>
|
||||
<NSwitch
|
||||
:value="settingsStore.skills.write_approval === true"
|
||||
@update:value="(value) => toggleWriteApproval('skills', value)"
|
||||
<a-switch
|
||||
:model-value="settingsStore.skills.write_approval === true"
|
||||
@update:model-value="(value) => toggleWriteApproval('skills', value as boolean)"
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.mode')"
|
||||
:hint="t('settings.session.modeHint')"
|
||||
>
|
||||
<NSelect
|
||||
:value="settingsStore.sessionReset.mode || 'both'"
|
||||
<a-select
|
||||
:model-value="settingsStore.sessionReset.mode || 'both'"
|
||||
:options="[
|
||||
{ label: t('settings.session.modeBoth'), value: 'both' },
|
||||
{ label: t('settings.session.modeIdle'), value: 'idle' },
|
||||
@@ -100,44 +99,44 @@ async function toggleWriteApproval(section: "memory" | "skills", value: boolean)
|
||||
]"
|
||||
size="small"
|
||||
class="input-md"
|
||||
@update:value="(v) => save({ mode: v })"
|
||||
@update:model-value="(v) => save({ mode: v })"
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.idleMinutes')"
|
||||
:hint="t('settings.session.idleMinutesHint')"
|
||||
>
|
||||
<NInputNumber
|
||||
:value="settingsStore.sessionReset.idle_minutes"
|
||||
<a-input-number
|
||||
:model-value="settingsStore.sessionReset.idle_minutes"
|
||||
:min="10"
|
||||
:max="10080"
|
||||
:step="30"
|
||||
size="small"
|
||||
class="input-sm"
|
||||
@update:value="(v) => v != null && debouncedSave('idle_minutes', v)"
|
||||
@update:model-value="(v) => v != null && debouncedSave('idle_minutes', v)"
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.atHour')"
|
||||
:hint="t('settings.session.atHourHint')"
|
||||
>
|
||||
<NInputNumber
|
||||
:value="settingsStore.sessionReset.at_hour"
|
||||
<a-input-number
|
||||
:model-value="settingsStore.sessionReset.at_hour"
|
||||
:min="0"
|
||||
:max="23"
|
||||
:step="1"
|
||||
size="small"
|
||||
class="input-sm"
|
||||
@update:value="(v) => v != null && debouncedSave('at_hour', v)"
|
||||
@update:model-value="(v) => v != null && debouncedSave('at_hour', v)"
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
:label="t('settings.session.liveMonitorHumanOnly')"
|
||||
:hint="t('settings.session.liveMonitorHumanOnlyHint')"
|
||||
>
|
||||
<NSwitch
|
||||
:value="sessionBrowserPrefsStore.humanOnly"
|
||||
@update:value="(value) => sessionBrowserPrefsStore.setHumanOnly(value)"
|
||||
<a-switch
|
||||
:model-value="sessionBrowserPrefsStore.humanOnly"
|
||||
@update:model-value="(value) => sessionBrowserPrefsStore.setHumanOnly(value as boolean)"
|
||||
/>
|
||||
</SettingRow>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user