Skip to content

feat: 支持子配置项收起/展开 - #308

Open
WindDrift wants to merge 3 commits into
MistEO:mainfrom
WindDrift:main
Open

feat: 支持子配置项收起/展开#308
WindDrift wants to merge 3 commits into
MistEO:mainfrom
WindDrift:main

Conversation

@WindDrift

@WindDrift WindDrift commented Aug 3, 2026

Copy link
Copy Markdown

概述

为带嵌套选项(switch / 下拉框)的配置项增加收起/展开功能,减少界面视觉噪音。

变更内容

  • 新增 OptionCollapseArrow 组件,位于开关/下拉框左侧,支持键盘与无障碍属性(aria-expandedaria-label
  • switch 与 select 类型的嵌套选项支持折叠,复用任务标题的 grid-template-rows 展开动画
  • 折叠状态按任务持久化到 store(SelectedTask.collapsedOptions,缺省展开、向后兼容);全局作用域(globalScope)用本地 state 兜底
  • 新增 toggleOptionCollapsed store action 及类型定义
  • 补充 5 种语言(en / ja / ko / zh-CN / zh-TW)的文案
  • 箭头添加 ml-auto 吸收行内空白,紧贴开关/下拉框;select 类型无子选项时由下拉框自身贴右

演示

QQ20260803-163837-HD

涉及文件

  • src/components/OptionEditor.tsx
  • src/stores/appStore.tssrc/stores/types.ts
  • src/types/interface.ts
  • src/i18n/locales/{en-US,ja-JP,ko-KR,zh-CN,zh-TW}.ts

涉及 issue #180 支持子选项折叠

本 PR 更改代码由 DeepSeek V4 Flash (effort:Max) 生成,构建和本地测试均通过,转到演示 mxu 版本

Summary by Sourcery

为开关(switch)和选择(select)配置项添加可折叠的子选项,支持按任务持久化折叠状态,并提供兼容无障碍访问的 UI 控件。

新功能:

  • 引入 OptionCollapseArrow UI 控件,用于在开关和选择输入旁切换嵌套选项的可见性。
  • 使开关和选择类型的嵌套选项可以通过动画过渡进行折叠/展开。
  • 在 store 中按任务持久化选项子树的折叠状态,并为全局作用域提供本地回退方案。
  • 为展开和折叠子选项在所有受支持语言中添加本地化标签。

增强:

  • 调整布局,使折叠箭头或选择控件根据是否存在嵌套选项对齐到右侧边缘。
Original summary in English

Summary by Sourcery

Add collapsible sub-options for switch and select configuration items, with persisted per-task collapse state and accessibility-aware UI controls.

New Features:

  • Introduce an OptionCollapseArrow UI control to toggle visibility of nested options beside switch and select inputs.
  • Enable nested options for switch and select types to be collapsed/expanded with animated transitions.
  • Persist per-task collapsed state for option subtrees in the store, with a local fallback for global scope.
  • Add localized labels for expanding and collapsing sub-options in all supported languages.

Enhancements:

  • Adjust layout so the collapse arrow or select control aligns to the right edge depending on whether nested options exist.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/stores/appStore.ts" line_range="764-773" />
<code_context>
         ),
       })),

+    toggleOptionCollapsed: (instanceId, taskId, optionKey) =>
+      set((state) => ({
+        instances: state.instances.map((i) =>
+          i.id === instanceId
+            ? {
+                ...i,
+                selectedTasks: i.selectedTasks.map((t) =>
+                  t.id === taskId
+                    ? {
+                        ...t,
+                        collapsedOptions: {
+                          ...t.collapsedOptions,
+                          [optionKey]: !t.collapsedOptions?.[optionKey],
+                        },
+                      }
</code_context>
<issue_to_address>
**issue:** 在展开(spread)`collapsedOptions` 之前,需要防止它为 `undefined`。

由于 `collapsedOptions` 的类型是 `Record<string, boolean> | undefined`,直接展开它(`{ ...t.collapsedOptions }`)会在严格模式下导致类型检查失败,错误为 “Object is possibly 'undefined'”。为了保持当前的运行时行为并满足类型要求,你可以在为 `undefined` 时将其默认处理为空对象:

```ts
collapsedOptions: {
  ...(t.collapsedOptions ?? {}),
  [optionKey]: !t.collapsedOptions?.[optionKey],
},
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,请考虑分享 ✨
帮我变得更有用!请对每条评论点击 👍 或 👎,我会根据这些反馈来改进对你代码的审查。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/stores/appStore.ts" line_range="764-773" />
<code_context>
         ),
       })),

+    toggleOptionCollapsed: (instanceId, taskId, optionKey) =>
+      set((state) => ({
+        instances: state.instances.map((i) =>
+          i.id === instanceId
+            ? {
+                ...i,
+                selectedTasks: i.selectedTasks.map((t) =>
+                  t.id === taskId
+                    ? {
+                        ...t,
+                        collapsedOptions: {
+                          ...t.collapsedOptions,
+                          [optionKey]: !t.collapsedOptions?.[optionKey],
+                        },
+                      }
</code_context>
<issue_to_address>
**issue:** Guard against `collapsedOptions` being undefined before spreading it.

Because `collapsedOptions` is typed as `Record<string, boolean> | undefined`, spreading it directly (`{ ...t.collapsedOptions }`) will fail type-checking in strict mode with “Object is possibly 'undefined'”. To keep the current runtime behavior and satisfy the types, you can default to an empty object when undefined:

```ts
collapsedOptions: {
  ...(t.collapsedOptions ?? {}),
  [optionKey]: !t.collapsedOptions?.[optionKey],
},
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/stores/appStore.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant