feat(admin): make all sortable/repeater cards collapsible, collapsed by default
- Add useCollapsibleItems: key-based open state, clickable/keyboard head, aria-expanded - sortable items with sub-fields and every inline repeater/group row now collapse - Repeater head summary falls back to the first filled field when no listPreview - Drop per-schema collapsible/defaultCollapsed for repeater groups (JS + PHP) - Align FloatBtnItemPanel head with the shared collapse attrs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8843ae4261
commit
116b6b2223
9 files changed
+114
-76
No files matched your search
@@ -143,12 +143,11 @@ test('等级 Tab 标题由显示名称动态驱动', () => {
|
||||
assert.match(rendererVue, /:name="tabName\(tab\)"/);
|
||||
assert.match(rendererVue, /:tab="tabName\(tab\)"/);
|
||||
assert.match(rendererVue, /function tabName\(tab\) \{[\s\S]*?tab\.titleKey[\s\S]*?tab\.titleFallback/);
|
||||
// 手风琴:默认收起,点击标题行展开。
|
||||
assert.match(fieldVue, /const repeaterCollapsible = computed\(\(\) => !!props\.schema\.collapsible\)/);
|
||||
assert.match(fieldVue, /const repeaterDefaultOpen = computed\(\(\) => props\.schema\.defaultCollapsed === false\)/);
|
||||
assert.match(fieldVue, /function toggleRepeaterItem\(index\)/);
|
||||
assert.match(fieldVue, /v-show="!repeaterCollapsible \|\| isRepeaterItemOpen\(index\)"/);
|
||||
// 手风琴:所有 repeater/group 行默认收起,点击标题行展开(按行 key 记录开合)。
|
||||
assert.match(fieldVue, /useCollapsibleItems\(\)/);
|
||||
assert.match(fieldVue, /v-show="isRepeaterItemOpen\(repeaterDragKey\(element\)\)"/);
|
||||
assert.match(fieldVue, /aksrt-field__repeater-summary/);
|
||||
assert.doesNotMatch(fieldVue, /schema\.collapsible|schema\.defaultCollapsed/);
|
||||
// accordion/fieldset 的 sections 分块手风琴。
|
||||
assert.match(fieldVue, /const fieldsetSections = computed\(/);
|
||||
assert.match(fieldVue, /function toggleFieldsetSection\(index\)/);
|
||||
@@ -168,8 +167,6 @@ test('结构化分组默认收起,标题行带摘要;升级价格按三块
|
||||
assert.deepStrictEqual(Object.keys(accordion.groups).sort(), [...expectedGroups].sort());
|
||||
for (const key of expectedGroups) {
|
||||
const cfg = accordion.groups[key];
|
||||
assert.strictEqual(cfg.collapsible, true, `${key} 应开启手风琴`);
|
||||
assert.strictEqual(cfg.defaultCollapsed, true, `${key} 应默认收起`);
|
||||
assert.ok(cfg.listPreview && cfg.listPreview.titleKey, `${key} 应配置标题行摘要`);
|
||||
assert.ok(cfg.listPreview.descKey, `${key} 应配置标题行时长摘要`);
|
||||
assert.strictEqual(cfg.listPreview.descUnitKey, 'unit', `${key} 时长摘要应带单位`);
|
||||
@@ -470,13 +467,11 @@ test('SPA 镜像 schema 与 PHP schema 同构', async () => {
|
||||
const points = schema.groups.find((g) => g.key === 'points-exchange').fields[1];
|
||||
assert.strictEqual(points.type, 'group');
|
||||
assert.deepStrictEqual(points.fields.map((f) => f.key), ['points', 'level', 'time', 'unit']);
|
||||
// 手风琴配置与 PHP 侧一致。
|
||||
// 标题行摘要配置与 PHP 侧一致(折叠为渲染器统一行为,不再由 schema 开关)。
|
||||
for (const key of ['vip_1_product', 'vip_2_product', 'vip_1_renew_product', 'vip_2_renew_product']) {
|
||||
const group = findGroup(schema, key);
|
||||
assert.strictEqual(group.collapsible, true, `${key} 应开启手风琴`);
|
||||
assert.strictEqual(group.defaultCollapsed, true, `${key} 应默认收起`);
|
||||
assert.strictEqual(findGroup(schema, key).listPreview.prefix, '价格:', `${key} 摘要前缀`);
|
||||
}
|
||||
assert.strictEqual(findGroup(schema, 'pay_vip_points_exchange_product').collapsible, true);
|
||||
assert.strictEqual(findGroup(schema, 'pay_vip_points_exchange_product').listPreview.prefix, '积分:');
|
||||
const upgrade = findGroup(schema, 'vip_upgrade_product');
|
||||
assert.strictEqual(upgrade.sections.length, 3);
|
||||
// SPA 默认值与 PHP 侧一致。
|
||||
|
||||
@@ -267,8 +267,6 @@ namespace {
|
||||
foreach ($tab['fields'] as $field) {
|
||||
if (($field['type'] ?? '') === 'group') {
|
||||
$out['groups'][$tab['key'] . '/' . $field['key']] = [
|
||||
'collapsible' => $field['collapsible'] ?? null,
|
||||
'defaultCollapsed' => $field['defaultCollapsed'] ?? null,
|
||||
'listPreview' => $field['listPreview'] ?? null,
|
||||
];
|
||||
}
|
||||
@@ -294,8 +292,6 @@ namespace {
|
||||
continue;
|
||||
}
|
||||
$out['groups']['points-exchange/' . $field['key']] = [
|
||||
'collapsible' => $field['collapsible'] ?? null,
|
||||
'defaultCollapsed' => $field['defaultCollapsed'] ?? null,
|
||||
'listPreview' => $field['listPreview'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user