mateclaw/mateclaw-ui/src/views
matevip a168f91215 refactor(ui): split useProviders into 5 single-responsibility composables
Reshapes the Settings/Models frontend to match the channel-module split
convention (commit 22894ac4 'perf(channels): split Channels.vue...'),
zero behavior change. Paves the way for a follow-up that adds an enabled
column + AddProviderDrawer without bloating useProviders back to monolith.

Frontend split
- useProviders.ts goes from 615-line monolith to a 48-line facade that
  composes five single-responsibility slices:
    * useProviderList — providers / activeModels / currentProvider,
      loaders, status pill, icons
    * useProviderForm — create/edit modal + form, save/delete
    * useProviderDiscovery — manage-models modal, discovery, connection
      and per-model tests
    * useProviderOAuth — openai-chatgpt + claude-code OAuth flows
    * useProviderPool — manual reprobe (most pool surface inlined to
      ProviderInfo.liveness in the prior liveness change)
  Cross-composable refs flow via dep-injection arguments — no module-
  level state, no circular deps. Each composable stays independently
  testable.
- Pure helpers extracted to src/utils:
    * safeJson.ts — strict JSON-object parser
    * modelProtocol.ts — protocol <-> ChatModel class translation
- Modals (ProviderConfigModal, ManageModelsModal) loaded via
  defineAsyncComponent so the route's first paint doesn't drag along
  ~30KB of form/auth UI.
- el-skeleton placeholder during the initial Promise.all so the page
  paints something instead of blank-then-pop.

Layout regression fix
- MainLayout's <keep-alive> slot used :key='workspaceRouteKey' (a
  workspace-scoped string), shared between two <component v-if> blocks.
  Adding a second keepAlive route would have caused two components to
  mount side by side, because Vue saw identical keys and patched in
  place across the v-if boundary. Switched the key to
  ${workspaceRouteKey}:${route.path} so different routes get distinct
  vnode identities while workspace switching still busts the cache.
  Discovered while implementing the split — the multi-line HTML
  comment also had to live OUTSIDE <keep-alive>, since KeepAlive
  treats comments as children and rejects 'more than one'.

Embedding section title fix (drive-by)
- EmbeddingModelsSection.vue's scoped style didn't redeclare
  .group-title's flex layout, so the icon stacked above the title
  text instead of sitting inline. Added the missing flex rules
  locally — now matches the local-models / cloud-models group headers.

Verification
- vue-tsc 0 errors.
- Browser end-to-end: 27 cards render correctly, modals open via lazy
  load, /channels <-> /settings/models switch four times in a row with
  exactly one page title visible at each step (no stacking).
2026-04-28 15:01:14 +08:00
..
Doctor fix(ui): prevent modals from closing on backdrop click 2026-04-11 18:06:48 +08:00
layout refactor(ui): split useProviders into 5 single-responsibility composables 2026-04-28 15:01:14 +08:00
Memory feat(memory): enable Memory Browser tab + audit fixes 2026-04-21 15:28:31 +08:00
Onboarding feat(ux): Phase 1 — onboarding, doctor, templates, navigation convergence 2026-04-09 00:32:35 +08:00
Security feat(auth): password change dialog + workspace member provisioning improvements 2026-04-17 00:11:10 +08:00
Settings refactor(ui): split useProviders into 5 single-responsibility composables 2026-04-28 15:01:14 +08:00
Wiki feat(wiki): download original raw material file 2026-04-26 20:46:52 +08:00
AgentContext.vue fix(wiki): smaller batch-create + resume button for partial generation 2026-04-26 18:42:27 +08:00
Agents.vue feat(skill-market): paginated skill list with search and frosted-glass UI 2026-04-24 06:55:19 +08:00
Channels.vue perf(channels): split Channels.vue, lazy-load modal, async locales, keep-alive route 2026-04-28 11:08:36 +08:00
ChatConsole.vue fix(chat): surface SSE error in retry card and stop poll from wiping local-only failed turn 2026-04-28 00:16:14 +08:00
CronJobs.vue fix(ui): prevent modals from closing on backdrop click 2026-04-11 18:06:48 +08:00
Dashboard.vue refactor(ux): simplify interactions and humanize UI with Jobs-inspired review 2026-04-09 20:56:50 +08:00
Datasources.vue refactor(ui): minimalist login redesign, MCP fixes, Flyway upgrade compatibility 2026-04-11 23:01:08 +08:00
Login.vue feat(auth): password change dialog + workspace member provisioning improvements 2026-04-17 00:11:10 +08:00
McpServers.vue refactor(ui): minimalist login redesign, MCP fixes, Flyway upgrade compatibility 2026-04-11 23:01:08 +08:00
Plugins.vue feat(plugin): Plugin SDK + UI layout improvements 2026-04-13 18:38:03 +08:00
Sessions.vue feat(ui): add mobile responsive layout and fix hardcoded i18n strings 2026-04-05 18:56:41 +08:00
SkillMarket.vue feat(skill-market): bilingual skill display names (nameZh / nameEn) 2026-04-24 06:55:20 +08:00
TokenUsage.vue feat(ui): unify workspace and platform console surfaces 2026-04-09 19:48:17 +08:00
Tools.vue fix(ui): prevent modals from closing on backdrop click 2026-04-11 18:06:48 +08:00