Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions shortcuts/base/base_execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,54 @@ func TestBaseViewExecuteReadCreateDeleteAndFilter(t *testing.T) {
t.Fatalf("stdout=%s", got)
}
})

t.Run("set-visible-fields-array", func(t *testing.T) {
factory, stdout, reg := newExecuteFactory(t)
registerTokenStub(reg)
updateStub := &httpmock.Stub{
Method: "PUT",
URL: "/open-apis/base/v3/bases/app_x/tables/tbl_x/views/vew_1/visible_fields",
Body: map[string]interface{}{
"code": 0,
"data": []interface{}{"fld_primary", "fld_status"},
},
}
reg.Register(updateStub)
if err := runShortcut(t, BaseViewSetVisibleFields, []string{"+view-set-visible-fields", "--base-token", "app_x", "--table-id", "tbl_x", "--view-id", "vew_1", "--json", `["fld_status"]`}, factory, stdout); err != nil {
t.Fatalf("err=%v", err)
}
if got := stdout.String(); !strings.Contains(got, `"visible_fields"`) || !strings.Contains(got, `"fld_primary"`) {
t.Fatalf("stdout=%s", got)
}
body := string(updateStub.CapturedBody)
if !strings.Contains(body, `"visible_fields":["fld_status"]`) {
t.Fatalf("request body=%s", body)
}
})

t.Run("set-visible-fields-object", func(t *testing.T) {
factory, stdout, reg := newExecuteFactory(t)
registerTokenStub(reg)
updateStub := &httpmock.Stub{
Method: "PUT",
URL: "/open-apis/base/v3/bases/app_x/tables/tbl_x/views/vew_1/visible_fields",
Body: map[string]interface{}{
"code": 0,
"data": []interface{}{"fld_primary", "fld_status"},
},
}
reg.Register(updateStub)
if err := runShortcut(t, BaseViewSetVisibleFields, []string{"+view-set-visible-fields", "--base-token", "app_x", "--table-id", "tbl_x", "--view-id", "vew_1", "--json", `{"visible_fields":["fld_status"]}`}, factory, stdout); err != nil {
t.Fatalf("err=%v", err)
}
body := string(updateStub.CapturedBody)
if !strings.Contains(body, `"visible_fields":["fld_status"]`) {
t.Fatalf("request body=%s", body)
}
if strings.Contains(body, `{"visible_fields":{"visible_fields":`) {
t.Fatalf("request body double wrapped: %s", body)
}
})
}

func TestBaseTableExecuteListFallbackShapes(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/base_shortcuts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func TestShortcutsCatalog(t *testing.T) {
want := []string{
"+table-list", "+table-get", "+table-create", "+table-update", "+table-delete",
"+field-list", "+field-get", "+field-create", "+field-update", "+field-delete", "+field-search-options",
"+view-list", "+view-get", "+view-create", "+view-delete", "+view-get-filter", "+view-set-filter", "+view-get-group", "+view-set-group", "+view-get-sort", "+view-set-sort", "+view-get-timebar", "+view-set-timebar", "+view-get-card", "+view-set-card", "+view-rename",
"+view-list", "+view-get", "+view-create", "+view-delete", "+view-get-filter", "+view-set-filter", "+view-set-visible-fields", "+view-get-group", "+view-set-group", "+view-get-sort", "+view-set-sort", "+view-get-timebar", "+view-set-timebar", "+view-get-card", "+view-set-card", "+view-rename",
"+record-list", "+record-get", "+record-upsert", "+record-upload-attachment", "+record-delete",
"+record-history-list",
"+base-get", "+base-copy", "+base-create",
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/shortcuts.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func Shortcuts() []common.Shortcut {
BaseViewDelete,
BaseViewGetFilter,
BaseViewSetFilter,
BaseViewSetVisibleFields,
BaseViewGetGroup,
BaseViewSetGroup,
BaseViewGetSort,
Expand Down
4 changes: 4 additions & 0 deletions shortcuts/base/view_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func dryRunViewSetFilter(_ context.Context, runtime *common.RuntimeContext) *com
return dryRunViewSetJSONObject(runtime, "filter")
}

func dryRunViewSetVisibleFields(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return dryRunViewSetWrapped(runtime, "visible_fields", "visible_fields")
}

func dryRunViewGetGroup(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return dryRunViewGetProperty(runtime, "group")
}
Expand Down
32 changes: 32 additions & 0 deletions shortcuts/base/view_set_visible_fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT

package base

import (
"context"

"github.com/larksuite/cli/shortcuts/common"
)

var BaseViewSetVisibleFields = common.Shortcut{
Service: "base",
Command: "+view-set-visible-fields",
Description: "Set view visible fields",
Risk: "write",
Scopes: []string{"base:view:write_only"},
AuthTypes: authTypes(),
Flags: []common.Flag{
baseTokenFlag(true),
tableRefFlag(true),
viewRefFlag(true),
{Name: "json", Desc: "visible fields JSON object/array", Required: true},
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
return validateViewJSONValue(runtime)
},
DryRun: dryRunViewSetVisibleFields,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
return executeViewSetWrapped(runtime, "visible_fields", "visible_fields", "visible_fields")
},
}
88 changes: 88 additions & 0 deletions skills/lark-base/references/lark-base-view-set-visible-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# base +view-set-visible-fields

> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。

更新视图可见字段列表。

## 推荐命令

```bash
lark-cli base +view-set-visible-fields \
--base-token app_xxx \
--table-id tbl_xxx \
--view-id viw_xxx \
--json '["标题","fld_status"]'
```

```bash
lark-cli base +view-set-visible-fields \
--base-token app_xxx \
--table-id tbl_xxx \
--view-id viw_xxx \
--json '{"visible_fields":["标题","fld_status"]}'
```

## JSON 结构

```json
[
"标题",
"fld_status"
]
```

```json
{
"visible_fields": ["标题", "fld_status"]
}
```

## 参数

| 参数 | 必填 | 说明 |
|------|------|------|
| `--base-token <token>` | 是 | Base Token |
| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
| `--json <body>` | 是 | JSON 对象或字符串数组 |

## API 入参详情

**HTTP 方法和路径:**

```
PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/visible_fields
```

**接口 body 线形态:**

```json
{
"visible_fields": ["标题", "fld_status"]
}
```

## 返回重点

- 返回更新后的可见字段列表。

## 结构规则

- `visible_fields`:字符串数组,每项可传字段 id 或字段名
- `--json` 可直接传数组 `[...]`,CLI 会自动包装成 `{ "visible_fields": [...] }`
- `--json` 也可直接传对象 `{ "visible_fields": [...] }`
- 后端会强制显示 `primaryField`,并且会把 `primaryField` 放在第一位;CLI 不会在本地补齐或重排

## 工作流

1. 建议优先使用字段 id,避免字段重名或后续改名带来的歧义。

## 坑点

- ⚠️ 这是写入操作,执行前必须确认。
- ⚠️ 接口最终结果会受后端 `primaryField` 强制显示规则影响,返回顺序可能与传入数组不同。
- ⚠️ 如果传字段名,必须与当前表真实字段名精确匹配。

## 参考

- [lark-base-view.md](lark-base-view.md) — view 索引页
1 change: 1 addition & 0 deletions skills/lark-base/references/lark-base-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ view 相关命令索引。
| [lark-base-view-rename.md](lark-base-view-rename.md) | `+view-rename` | 重命名视图 |
| [lark-base-view-get-filter.md](lark-base-view-get-filter.md) | `+view-get-filter` | 读取筛选配置 |
| [lark-base-view-set-filter.md](lark-base-view-set-filter.md) | `+view-set-filter` | 更新筛选配置 |
| [lark-base-view-set-visible-fields.md](lark-base-view-set-visible-fields.md) | `+view-set-visible-fields` | 更新可见字段列表 |
| [lark-base-view-get-group.md](lark-base-view-get-group.md) | `+view-get-group` | 读取分组配置 |
| [lark-base-view-set-group.md](lark-base-view-set-group.md) | `+view-set-group` | 更新分组配置 |
| [lark-base-view-get-sort.md](lark-base-view-get-sort.md) | `+view-get-sort` | 读取排序配置 |
Expand Down