@openviking/react 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/1~0.js +506 -0
- package/dist/2~0.js +122 -0
- package/dist/{g~0.js → 30~0.js} +292 -167
- package/dist/client/index.d.ts +2 -1
- package/dist/client/paths.d.ts +64 -0
- package/dist/client/response.d.ts +31 -0
- package/dist/client/sse.d.ts +39 -0
- package/dist/client/stream.d.ts +26 -0
- package/dist/client/types.d.ts +104 -0
- package/dist/client.js +1 -239
- package/dist/components/agent-connect/style.css +2 -2
- package/dist/components/file-browser-entries/file-browser-entries-icons.d.ts +18 -0
- package/dist/components/file-browser-entries/file-browser-entries.d.ts +14 -0
- package/dist/components/file-browser-entries/index.d.ts +1 -0
- package/dist/components/file-browser-entries/style.css +155 -0
- package/dist/components/file-browser-entries/style.js +0 -0
- package/dist/components/file-browser-entries/types.d.ts +45 -0
- package/dist/components/file-browser-entries.js +1 -0
- package/dist/components/file-preview/file-preview-directory.d.ts +32 -0
- package/dist/components/file-preview/file-preview-header.d.ts +21 -3
- package/dist/components/file-preview/file-preview-panels.d.ts +41 -0
- package/dist/components/file-preview/file-preview-state.d.ts +10 -3
- package/dist/components/file-preview/file-preview.d.ts +2 -1
- package/dist/components/file-preview/level-selection.d.ts +25 -0
- package/dist/components/file-preview/style.css +76 -3
- package/dist/components/file-preview/types.d.ts +100 -1
- package/dist/components/file-preview/use-directory-level.d.ts +30 -0
- package/dist/components/file-preview/use-file-preview-actions-context.d.ts +6 -2
- package/dist/components/file-preview/use-file-preview-actions.d.ts +1 -1
- package/dist/components/file-preview.js +1 -1
- package/dist/components/file-tree/file-tree-info-tooltip.d.ts +7 -7
- package/dist/components/file-tree/file-tree-row-context.d.ts +0 -5
- package/dist/components/file-tree/file-tree-row-shared.d.ts +9 -2
- package/dist/components/file-tree/file-tree-tooltip-surface.d.ts +8 -8
- package/dist/components/file-tree/style.css +71 -34
- package/dist/components/file-tree/types.d.ts +20 -0
- package/dist/components/scope-switcher/style.css +2 -2
- package/dist/components/style.css +312 -47
- package/dist/components/tui/style.css +2 -2
- package/dist/components/viking-bot/style.css +2 -2
- package/dist/file-preview-viewer~0.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/l~0.js +1464 -25
- package/dist/modules/console/style.css +2 -2
- package/dist/modules/file-browser/file-browser-detail-icons.d.ts +10 -0
- package/dist/modules/file-browser/file-browser-detail.d.ts +33 -0
- package/dist/modules/file-browser/file-browser-empty.d.ts +3 -0
- package/dist/modules/file-browser/file-browser-failure.d.ts +22 -0
- package/dist/modules/file-browser/file-browser-icons.d.ts +18 -0
- package/dist/modules/file-browser/file-browser-labels.d.ts +28 -0
- package/dist/modules/file-browser/file-browser-layout.d.ts +27 -0
- package/dist/modules/file-browser/file-browser-toolbar.d.ts +18 -0
- package/dist/modules/file-browser/file-browser-tree-pane.d.ts +30 -0
- package/dist/modules/file-browser/file-browser.d.ts +14 -5
- package/dist/modules/file-browser/find-result.d.ts +24 -0
- package/dist/modules/file-browser/fs-directories.d.ts +33 -0
- package/dist/modules/file-browser/fs-file-kind.d.ts +19 -0
- package/dist/modules/file-browser/fs-icon.d.ts +17 -0
- package/dist/modules/file-browser/fs-model.d.ts +106 -0
- package/dist/modules/file-browser/fs-page.d.ts +16 -0
- package/dist/modules/file-browser/fs-path.d.ts +16 -0
- package/dist/modules/file-browser/fs-read-directory.d.ts +20 -0
- package/dist/modules/file-browser/fs-scope.d.ts +22 -0
- package/dist/modules/file-browser/fs-stat.d.ts +25 -0
- package/dist/modules/file-browser/index.d.ts +3 -1
- package/dist/modules/file-browser/style.css +4927 -35
- package/dist/modules/file-browser/tree-info-copy.d.ts +15 -0
- package/dist/modules/file-browser/tree-info-copy.zh-CN.d.ts +15 -0
- package/dist/modules/file-browser/types.d.ts +189 -44
- package/dist/modules/file-browser/use-container-width.d.ts +17 -0
- package/dist/modules/file-browser/use-file-browser.d.ts +49 -0
- package/dist/modules/file-browser/use-fs-preview.d.ts +51 -0
- package/dist/modules/file-browser/use-fs-search.d.ts +35 -0
- package/dist/modules/file-browser/use-fs-tree.d.ts +43 -0
- package/dist/modules/file-browser/use-request-scope.d.ts +39 -0
- package/dist/modules/file-browser.js +1 -1
- package/dist/modules/scope-cascade/style.css +2 -2
- package/dist/modules/style.css +4933 -41
- package/dist/n~0.js +178 -74
- package/dist/o~0.js +103 -0
- package/dist/shared/components/divider/divider.d.ts +18 -0
- package/dist/shared/components/divider/index.d.ts +1 -0
- package/dist/shared/components/divider/types.d.ts +35 -0
- package/dist/shared/components/overlay/types.d.ts +7 -0
- package/dist/shared/components/{tooltip/use-tooltip-position.d.ts → overlay/use-overlay-position.d.ts} +6 -6
- package/dist/shared/components/popover/index.d.ts +1 -0
- package/dist/shared/components/popover/popover.d.ts +23 -0
- package/dist/shared/components/popover/types.d.ts +50 -0
- package/dist/shared/components/resizable/clamp.d.ts +13 -0
- package/dist/shared/components/resizable/index.d.ts +2 -0
- package/dist/shared/components/resizable/resizable-handle.d.ts +25 -0
- package/dist/shared/components/resizable/types.d.ts +48 -0
- package/dist/shared/components/tooltip/types.d.ts +5 -5
- package/dist/style.css +5345 -188
- package/package.json +6 -1
- package/dist/components/file-tree/file-tree-tooltip.d.ts +0 -17
- package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +0 -10
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FileTreeLabels } from '../../components/file-tree/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 按语言解析目录树的文案。组件内置的是英文,模块这一层必须整份给中文——只
|
|
4
|
+
* 覆盖其中几项会让同一张卡片里中英文混排,比全英文更难读。
|
|
5
|
+
*
|
|
6
|
+
* 宿主的 `info` 逐键叠在内置值之上:整份替换会丢掉宿主没提到的键。
|
|
7
|
+
*
|
|
8
|
+
* Resolves the tree copy for a language. The component ships English, so the module
|
|
9
|
+
* supplies Chinese as a whole set — a partial override would mix languages inside
|
|
10
|
+
* one card, which reads worse than English alone.
|
|
11
|
+
*
|
|
12
|
+
* A host `info` layers key by key over the built-in values: replacing it wholesale
|
|
13
|
+
* would drop the keys the host did not mention.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveTreeLabels(locale: 'en-US' | 'zh-CN' | undefined, hostLabels: FileTreeLabels | undefined): FileTreeLabels | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FileTreeInfoLabels } from '../../components/file-tree/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 目录说明与浮层字段名的中文文案。
|
|
4
|
+
*
|
|
5
|
+
* 组件内置的是英文,模块这一层必须按当前语言整份传下去——只覆盖其中几项会让
|
|
6
|
+
* 同一张卡片里中英文混排,比全英文更难读。
|
|
7
|
+
*
|
|
8
|
+
* Chinese copy for the directory descriptions and the field names inside the
|
|
9
|
+
* popover.
|
|
10
|
+
*
|
|
11
|
+
* The component ships English; the module passes a whole set per language. A
|
|
12
|
+
* partial override would mix Chinese and English inside one card, which reads worse
|
|
13
|
+
* than English alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TREE_INFO_LABELS_ZH_CN: FileTreeInfoLabels;
|
|
@@ -1,49 +1,75 @@
|
|
|
1
|
+
import type { FilePreviewLabels, FilePreviewTab } from '../../components/file-preview/index.js';
|
|
2
|
+
import type { FileTreeEntryRow, FileTreeLabels, FileTreeRow } from '../../components/file-tree/index.js';
|
|
1
3
|
import type { OvRequestOptions } from '../../client/index.js';
|
|
2
4
|
import type { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* 文件浏览模块的可替换文案。树与预览各有自己的一套,分别透传,模块外壳只提供
|
|
7
|
+
* 自己渲染的那几条。
|
|
8
|
+
*
|
|
9
|
+
* Replaceable copy of the file browser module. The tree and the preview each keep
|
|
10
|
+
* their own set, passed through as-is; the module shell only carries the strings
|
|
11
|
+
* it renders itself.
|
|
12
|
+
*/
|
|
4
13
|
export interface FileBrowserLabels {
|
|
5
|
-
/**
|
|
6
|
-
* 占位说明。缺省为 `Placeholder. Functionality is not available yet.`。
|
|
7
|
-
* Placeholder description. Defaults to "Placeholder. Functionality is not
|
|
8
|
-
* available yet.".
|
|
9
|
-
*/
|
|
10
|
-
description?: string;
|
|
11
|
-
/** 区域标题。Area title. */
|
|
12
|
-
title?: string;
|
|
13
|
-
/** 搜索框占位文案。Search placeholder. */
|
|
14
|
-
searchPlaceholder?: string;
|
|
15
|
-
/** 搜索无结果提示。Message shown when a search returns nothing. */
|
|
16
|
-
searchEmpty?: string;
|
|
17
|
-
/** 刷新按钮的无障碍名称。Accessible name of the refresh control. */
|
|
18
|
-
refresh?: string;
|
|
19
14
|
/** 未选中资源时的提示。Message shown when no resource is selected. */
|
|
20
15
|
empty?: string;
|
|
21
16
|
/** 加载失败提示。Load failure message. */
|
|
22
17
|
error?: string;
|
|
23
18
|
/** 重试按钮文案。Retry button label. */
|
|
24
19
|
retry?: string;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
20
|
+
/** 刷新按钮的无障碍名称。Accessible name of the refresh control. */
|
|
21
|
+
refresh?: string;
|
|
22
|
+
/** 搜索框占位文案。Search placeholder. */
|
|
23
|
+
searchPlaceholder?: string;
|
|
24
|
+
/** 搜索无结果提示。Message shown when a search returns nothing. */
|
|
25
|
+
searchEmpty?: string;
|
|
26
|
+
/** 搜索请求失败的结论,原因由服务端返回。Conclusion when the search request fails; the reason comes from the server. */
|
|
27
|
+
searchFailed?: string;
|
|
28
|
+
/** 搜索进行中的提示。Message shown while a search runs. */
|
|
29
|
+
searchLoading?: string;
|
|
30
|
+
/** 预览读取正文时的提示。Message shown while the preview reads a resource. */
|
|
31
|
+
loading?: string;
|
|
32
|
+
/** 分段器里的「预览」。The "preview" segment label. */
|
|
33
|
+
previewMode?: string;
|
|
34
|
+
/** 分段器里的「源码」。The "source" segment label. */
|
|
35
|
+
sourceMode?: string;
|
|
36
|
+
/** 复制路径按钮的文案。Label of the copy-path button. */
|
|
37
|
+
copyPath?: string;
|
|
38
|
+
/** 复制正文按钮的无障碍名称。Accessible name of the copy-content button. */
|
|
39
|
+
copyContent?: string;
|
|
40
|
+
/** 下载按钮的无障碍名称。Accessible name of the download button. */
|
|
41
|
+
download?: string;
|
|
42
|
+
/** 版本历史按钮的无障碍名称。Accessible name of the version-history button. */
|
|
43
|
+
history?: string;
|
|
44
|
+
/** 视图切换分组的无障碍名称。Accessible name of the view-switch group. */
|
|
45
|
+
viewSwitch?: string;
|
|
46
|
+
/** 树与详情之间分隔条的无障碍名称。Accessible name of the divider between the tree and the detail. */
|
|
47
|
+
resizeTree?: string;
|
|
48
|
+
/** 目录预览的 L0 摘要页签。The L0 summary tab of a directory preview. */
|
|
49
|
+
l0Summary?: string;
|
|
50
|
+
/** 目录预览的 L1 总览页签。The L1 overview tab of a directory preview. */
|
|
51
|
+
l1Overview?: string;
|
|
52
|
+
/** 目录某一级摘要尚未生成时的提示。Message shown when a summary level is empty. */
|
|
53
|
+
summaryEmpty?: string;
|
|
54
|
+
/**
|
|
55
|
+
* 目录某一级摘要请求失败、且服务端没给消息时的兜底文案。与 `summaryEmpty` 是两
|
|
56
|
+
* 件事:前者是「取不到」,后者是「还没生成」,处置完全不同。
|
|
57
|
+
*
|
|
58
|
+
* Fallback copy when a summary level's request failed without a server message. It
|
|
59
|
+
* differs from `summaryEmpty`: the former is "could not load", the latter is "not
|
|
60
|
+
* generated yet", and the two call for different actions.
|
|
61
|
+
*/
|
|
62
|
+
summaryFailed?: string;
|
|
63
|
+
/** 目录树文案。Copy of the file tree. */
|
|
64
|
+
tree?: FileTreeLabels;
|
|
65
|
+
/** 预览文案。Copy of the file preview. */
|
|
66
|
+
preview?: FilePreviewLabels;
|
|
40
67
|
}
|
|
41
68
|
/**
|
|
42
69
|
* 文件浏览模块的属性。
|
|
43
70
|
*
|
|
44
71
|
* 模块自己通过 Hook 取数,props 里没有数据字段:宿主给配置、受控的当前资源、
|
|
45
|
-
*
|
|
46
|
-
* 宿主不需要重复组装。
|
|
72
|
+
* 工具栏入口、文案与请求配置。目录、搜索、预览页签与行级状态都在模块内维护。
|
|
47
73
|
*
|
|
48
74
|
* 模块只覆盖文件树与文件预览两块。命令面板属于 `console`。
|
|
49
75
|
*
|
|
@@ -52,8 +78,7 @@ export interface FileBrowserToolbarButtonProps extends Omit<HTMLAttributes<HTMLB
|
|
|
52
78
|
* The module loads its own data through a Hook, so no prop carries data: the
|
|
53
79
|
* host supplies configuration, the controlled current resource, the toolbar
|
|
54
80
|
* entries, copy and request configuration. The directory, search, preview tabs
|
|
55
|
-
* and per-row state all live inside the module
|
|
56
|
-
* them again.
|
|
81
|
+
* and per-row state all live inside the module.
|
|
57
82
|
*
|
|
58
83
|
* The module covers only the file tree and the file preview. The command panel
|
|
59
84
|
* belongs to `console`.
|
|
@@ -61,8 +86,18 @@ export interface FileBrowserToolbarButtonProps extends Omit<HTMLAttributes<HTMLB
|
|
|
61
86
|
export interface FileBrowserProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect' | 'children'> {
|
|
62
87
|
/**
|
|
63
88
|
* 受控的当前资源 URI。传入时由宿主决定当前资源,模块只上报切换意图。
|
|
89
|
+
*
|
|
90
|
+
* 用 `uri !== undefined` 判断是否受控,而不是真假值:空字符串也算宿主接管。
|
|
91
|
+
* 模块不会主动清空选中——点目录行与点面包屑祖先都带具体 URI,没有「取消选中」
|
|
92
|
+
* 的交互——因此这里不接受 `null`。
|
|
93
|
+
*
|
|
64
94
|
* The controlled current resource URI. When given, the host owns the current
|
|
65
95
|
* resource and the module only reports switch intent.
|
|
96
|
+
*
|
|
97
|
+
* Control is detected with `uri !== undefined` rather than truthiness: even an empty
|
|
98
|
+
* string counts as the host taking over. The module never clears the selection —
|
|
99
|
+
* both the row click and the breadcrumb ancestor carry a concrete URI, and there is
|
|
100
|
+
* no "deselect" interaction — so `null` is not accepted here.
|
|
66
101
|
*/
|
|
67
102
|
uri?: string;
|
|
68
103
|
/**
|
|
@@ -71,20 +106,52 @@ export interface FileBrowserProps extends Omit<HTMLAttributes<HTMLDivElement>, '
|
|
|
71
106
|
*/
|
|
72
107
|
defaultUri?: string;
|
|
73
108
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
109
|
+
* 目录树的根,缺省为 `viking://`。宿主据此把浏览范围收敛到某个子树。
|
|
110
|
+
* Root of the tree, `viking://` by default. A host narrows the browsed scope
|
|
111
|
+
* with it.
|
|
112
|
+
*/
|
|
113
|
+
rootUri?: string;
|
|
114
|
+
/**
|
|
115
|
+
* 首次加载后自动展开到的路径,逐级展开并加载。省略时只展开根,其余全部折叠。
|
|
116
|
+
* 与控制台一致:进去就能看到默认位置,不必逐层点开。
|
|
77
117
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
118
|
+
* Path to expand to after the first load, opening and loading each level. When
|
|
119
|
+
* omitted only the root is expanded and everything else stays collapsed,
|
|
120
|
+
* matching the console: the default location is visible right away.
|
|
121
|
+
*/
|
|
122
|
+
defaultExpandedUri?: string;
|
|
123
|
+
/**
|
|
124
|
+
* 透传给预览底座的文案语言。组件自身文案仍由 `labels` 控制。
|
|
125
|
+
* Language of the preview base's built-in copy. The module's own copy stays
|
|
126
|
+
* with `labels`.
|
|
127
|
+
*/
|
|
128
|
+
locale?: 'en-US' | 'zh-CN';
|
|
129
|
+
/**
|
|
130
|
+
* 工具栏上方的宿主入口,例如连接 Agent、导入资源。
|
|
131
|
+
*
|
|
132
|
+
* 两个固定入口由 `FileBrowserEntries` 提供,外观、图标、分隔线与等分排布都
|
|
133
|
+
* 在那边,宿主只决定显示哪几个与点击后做什么。搜索与刷新由模块自己渲染。
|
|
134
|
+
*
|
|
135
|
+
* Host entries above the toolbar, for example connecting an agent or importing
|
|
136
|
+
* resources.
|
|
137
|
+
*
|
|
138
|
+
* The two fixed entries come from `FileBrowserEntries`, which owns their look,
|
|
139
|
+
* icons, divider and equal-width layout; the host only decides which appear and
|
|
140
|
+
* what a click does. Search and refresh are rendered by the module itself.
|
|
82
141
|
*/
|
|
83
142
|
toolbarActions?: ReactNode;
|
|
84
143
|
/**
|
|
85
|
-
* 当前资源变化后触发,参数为新的 URI
|
|
86
|
-
*
|
|
87
|
-
*
|
|
144
|
+
* 当前资源变化后触发,参数为新的 URI。
|
|
145
|
+
*
|
|
146
|
+
* 签名允许 `null`(上游契约),但本模块目前不会主动上报它:没有「取消选中」的
|
|
147
|
+
* 交互,模块也不会自己清空选中。宿主不要依赖收到 `null` 来收起详情区。
|
|
148
|
+
*
|
|
149
|
+
* Called after the current resource changes, with the new URI.
|
|
150
|
+
*
|
|
151
|
+
* The signature allows `null` (the upstream contract), but this module never reports
|
|
152
|
+
* it today: there is no "deselect" interaction and the module does not clear the
|
|
153
|
+
* selection itself. A host must not rely on receiving `null` to collapse the detail
|
|
154
|
+
* pane.
|
|
88
155
|
*/
|
|
89
156
|
onUriChange?: (uri: string | null) => void;
|
|
90
157
|
/**
|
|
@@ -99,3 +166,81 @@ export interface FileBrowserProps extends Omit<HTMLAttributes<HTMLDivElement>, '
|
|
|
99
166
|
*/
|
|
100
167
|
requestOptions?: OvRequestOptions;
|
|
101
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* 模块 Hook 返回的视图数据与操作。宿主可以只用它自行组装视图,不需要组合
|
|
171
|
+
* 视图。
|
|
172
|
+
*
|
|
173
|
+
* The view data and operations the module Hook returns. A host may assemble its
|
|
174
|
+
* own view from these without the composite one.
|
|
175
|
+
*/
|
|
176
|
+
export interface FileBrowserApi {
|
|
177
|
+
/** 按渲染顺序排列的可见行。Visible rows in render order. */
|
|
178
|
+
rows: readonly FileTreeRow[];
|
|
179
|
+
/** 当前选中的行 id。Selected row id. */
|
|
180
|
+
selectedId: string | null;
|
|
181
|
+
/** 当前资源 URI。Current resource URI. */
|
|
182
|
+
currentUri: string | null;
|
|
183
|
+
/** 当前查询词。The current query. */
|
|
184
|
+
query: string;
|
|
185
|
+
/** 是否正在展示搜索结果。Whether search results are showing. */
|
|
186
|
+
searching: boolean;
|
|
187
|
+
/** 搜索是否进行中。Whether a search is running. */
|
|
188
|
+
searchLoading: boolean;
|
|
189
|
+
/** 刷新是否进行中。Whether a refresh is running. */
|
|
190
|
+
refreshing: boolean;
|
|
191
|
+
/** 预览底部元信息,例如字符数与更新时间;没有时为 `undefined`。 */
|
|
192
|
+
previewFooter?: string;
|
|
193
|
+
/** 首次加载是否已完成。Whether the first load has finished. */
|
|
194
|
+
isReady: boolean;
|
|
195
|
+
/** 整体加载失败的原因。Reason the whole tree failed to load. */
|
|
196
|
+
error: Error | null;
|
|
197
|
+
/**
|
|
198
|
+
* 目录列表本身的失败原因。与 {@link error} 的区别是来源单一:宿主据此在树的
|
|
199
|
+
* 位置渲染失败态并给出重试,而不是把 403 显示成「没有文件」。
|
|
200
|
+
*
|
|
201
|
+
* Why the directory listing itself failed. It differs from {@link error} by having
|
|
202
|
+
* a single source: a host renders a failure state with a retry in the tree's place
|
|
203
|
+
* instead of showing a 403 as "no files".
|
|
204
|
+
*/
|
|
205
|
+
treeError: Error | null;
|
|
206
|
+
/**
|
|
207
|
+
* 搜索请求本身的失败原因。与「搜索成功但没有结果」不同:前者要显示原因与重试,
|
|
208
|
+
* 后者才是空态文案。
|
|
209
|
+
*
|
|
210
|
+
* Why the search request failed. It differs from "the search succeeded but matched
|
|
211
|
+
* nothing": the former needs the reason and a retry, only the latter is the empty
|
|
212
|
+
* copy.
|
|
213
|
+
*/
|
|
214
|
+
searchError: Error | null;
|
|
215
|
+
/**
|
|
216
|
+
* 当前资源预览的失败原因。选中了资源但读不出来时用它区分「读失败」与「什么
|
|
217
|
+
* 都没选」。
|
|
218
|
+
*
|
|
219
|
+
* Why the preview of the current resource failed. It separates "could not read"
|
|
220
|
+
* from "nothing selected" when a resource is selected.
|
|
221
|
+
*/
|
|
222
|
+
previewError: Error | null;
|
|
223
|
+
/** 当前资源的预览页签,没有选中时为 `null`。Preview tabs of the current resource, `null` when nothing is selected. */
|
|
224
|
+
previewTabs: readonly FilePreviewTab[] | null;
|
|
225
|
+
/** 当前预览页签 key。Active preview tab key. */
|
|
226
|
+
previewKey: string | null;
|
|
227
|
+
/** 树与预览的操作。Operations of the tree and the preview. */
|
|
228
|
+
actions: FileBrowserActions;
|
|
229
|
+
}
|
|
230
|
+
/** 模块 Hook 暴露的操作。Operations the module Hook exposes. */
|
|
231
|
+
export interface FileBrowserActions {
|
|
232
|
+
/** 选中条目。Selects an entry. */
|
|
233
|
+
select: (row: FileTreeEntryRow) => Promise<void>;
|
|
234
|
+
/** 展开或折叠目录。Expands or collapses a directory. */
|
|
235
|
+
toggleExpand: (row: FileTreeEntryRow) => Promise<void>;
|
|
236
|
+
/** 加载下一页子节点。Loads the next page of children. */
|
|
237
|
+
loadMore: (row: FileTreeRow) => Promise<void>;
|
|
238
|
+
/** 重新加载失败的子节点。Retries a failed children load. */
|
|
239
|
+
retry: (row: FileTreeRow) => Promise<void>;
|
|
240
|
+
/** 重新加载整棵树并保留选中。Reloads the whole tree, keeping the selection. */
|
|
241
|
+
refresh: () => Promise<void>;
|
|
242
|
+
/** 切换预览页签。Switches the preview tab. */
|
|
243
|
+
setPreviewKey: (key: string) => void;
|
|
244
|
+
/** 更新查询词;空串回到目录树。Updates the query; an empty string returns to the tree. */
|
|
245
|
+
setQuery: (query: string) => void;
|
|
246
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 订阅元素的内容宽度,返回 ref 与当前宽度(四舍五入到整数像素)。
|
|
3
|
+
*
|
|
4
|
+
* 宽度要用来算拖拽上限,不能只在窗口 `resize` 时更新:宿主侧栏展开、字体变化
|
|
5
|
+
* 都会让容器变宽或变窄,而窗口尺寸不变。
|
|
6
|
+
*
|
|
7
|
+
* Subscribes to an element's content width, returning the ref and the current
|
|
8
|
+
* width rounded to whole pixels.
|
|
9
|
+
*
|
|
10
|
+
* The width feeds the drag limit, so a window `resize` listener is not enough: a
|
|
11
|
+
* host sidebar opening or a font change resizes the container while the window
|
|
12
|
+
* stays the same.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useContainerWidth<T extends HTMLElement>(): {
|
|
15
|
+
ref: import("react").RefObject<T | null>;
|
|
16
|
+
width: number;
|
|
17
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { OvRequestOptions } from '../../client/types.js';
|
|
2
|
+
import type { FileBrowserApi } from './types.js';
|
|
3
|
+
export interface UseFileBrowserOptions {
|
|
4
|
+
rootUri: string;
|
|
5
|
+
/**
|
|
6
|
+
* 宿主是否受控地持有当前资源。受控时 `currentUri` 就是唯一事实;非受控时
|
|
7
|
+
* `currentUri` 只是初始值,之后的选中由模块自己记在 `pendingUri` 里。
|
|
8
|
+
*
|
|
9
|
+
* 两者的区别只在「谁拥有选中」:非受控模块在初始没有选中时 `currentUri` 也是
|
|
10
|
+
* `null`,因此不能靠值来区分,必须显式声明。
|
|
11
|
+
*
|
|
12
|
+
* Whether the host owns the current resource. While controlled, `currentUri` is the
|
|
13
|
+
* single source of truth; while uncontrolled it is only the initial value and later
|
|
14
|
+
* selections live in the module's own `pendingUri`.
|
|
15
|
+
*
|
|
16
|
+
* The distinction is only about who owns the selection: an uncontrolled module also
|
|
17
|
+
* has a `null` `currentUri` when nothing is selected initially, so the value itself
|
|
18
|
+
* cannot tell the two apart and the mode has to be declared.
|
|
19
|
+
*/
|
|
20
|
+
controlled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 目录两级摘要的标题与失败兜底文案。两级摘要各自可能请求失败,失败且服务端没给
|
|
23
|
+
* 消息时用 `failure` 显示——它必须可替换,否则宿主无法本地化。
|
|
24
|
+
*
|
|
25
|
+
* Titles of the two summary levels and the fallback copy for a failure. Either level
|
|
26
|
+
* can fail; when it fails without a server message, `failure` is shown — it has to be
|
|
27
|
+
* replaceable, or a host cannot localise it.
|
|
28
|
+
*/
|
|
29
|
+
summaryLabels?: {
|
|
30
|
+
l0: string;
|
|
31
|
+
l1: string;
|
|
32
|
+
failure: string;
|
|
33
|
+
};
|
|
34
|
+
/** 首次加载后自动展开到的路径。Path to expand to after the first load. */
|
|
35
|
+
defaultExpandedUri?: string;
|
|
36
|
+
currentUri: string | null;
|
|
37
|
+
requestOptions?: OvRequestOptions;
|
|
38
|
+
onUriChange: (uri: string | null) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 文件浏览模块的取数与联动:把目录树、搜索与预览组合成一份视图数据。三者各自
|
|
42
|
+
* 取数,这里只负责把它们接起来——目录行展开树,文件行与搜索结果打开预览。
|
|
43
|
+
*
|
|
44
|
+
* Data loading and coordination of the file browser module: the tree, the search
|
|
45
|
+
* and the preview each load their own data, and this only wires them together —
|
|
46
|
+
* a directory row expands the tree, while a file row or a search result opens
|
|
47
|
+
* the preview.
|
|
48
|
+
*/
|
|
49
|
+
export declare function useFileBrowser({ rootUri, controlled, summaryLabels, defaultExpandedUri, currentUri, requestOptions, onUriChange, }: UseFileBrowserOptions): FileBrowserApi;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { FilePreviewTab } from '../../components/file-preview/index.js';
|
|
2
|
+
import type { OvClient, OvRequestOptions } from '../../client/types.js';
|
|
3
|
+
export interface PreviewState {
|
|
4
|
+
tabs: readonly FilePreviewTab[] | null;
|
|
5
|
+
activeKey: string | null;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
/** 底部元信息,例如字符数。Footer metadata such as the character count. */
|
|
8
|
+
footer?: string;
|
|
9
|
+
setActiveKey: (key: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface UseFsPreviewOptions {
|
|
12
|
+
client: OvClient | null;
|
|
13
|
+
uri: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* 当前资源的类型。目录读 L0/L1 摘要,文件读正文,`unknown` 先查一次 `fs/stat`
|
|
16
|
+
* 再决定。
|
|
17
|
+
*
|
|
18
|
+
* 传三态而不是「目录集合」:集合每次加载都会换新引用,作为 effect 依赖会让预览
|
|
19
|
+
* 反复重取。三态是稳定的字符串,换引用的问题不存在。
|
|
20
|
+
*
|
|
21
|
+
* The type of the current resource. A directory reads its L0/L1 summary, a file reads
|
|
22
|
+
* its content, and `unknown` resolves with one `fs/stat` call first.
|
|
23
|
+
*
|
|
24
|
+
* A three-state value rather than the directory set: the set gets a new identity on
|
|
25
|
+
* every load, and as an effect dependency it would make the preview reload
|
|
26
|
+
* repeatedly. The three-state value is a stable string, so that cannot happen.
|
|
27
|
+
*/
|
|
28
|
+
resourceType?: 'directory' | 'file' | 'unknown';
|
|
29
|
+
/** 目录两级摘要的标题。Titles of the two summary levels. */
|
|
30
|
+
labels?: {
|
|
31
|
+
l0: string;
|
|
32
|
+
l1: string;
|
|
33
|
+
failure: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 打开路径上的某一级祖先。面包屑与目录页签共用它。
|
|
37
|
+
* Opens one ancestor level; the breadcrumb and a directory tab share it.
|
|
38
|
+
*/
|
|
39
|
+
openParent?: (uri: string) => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* 重新取数的代次。宿主调用刷新时递增,让同一资源的正文重新请求——内容在服务
|
|
42
|
+
* 端变了而 URI 没变,只靠依赖是看不出来的。
|
|
43
|
+
*
|
|
44
|
+
* Reload generation. A host increments it on refresh so the same resource is read
|
|
45
|
+
* again: the content changed on the server while the URI did not, which
|
|
46
|
+
* dependencies alone cannot express.
|
|
47
|
+
*/
|
|
48
|
+
generation?: number;
|
|
49
|
+
requestOptions?: OvRequestOptions;
|
|
50
|
+
}
|
|
51
|
+
export declare function useFsPreview({ client, uri, resourceType, labels, openParent, generation, requestOptions, }: UseFsPreviewOptions): PreviewState;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { OvClient, OvRequestOptions } from '../../client/types.js';
|
|
2
|
+
import { type FsEntry } from './fs-model.js';
|
|
3
|
+
export interface SearchState {
|
|
4
|
+
/** 结果行;未搜索时为 `null`。Result entries, `null` before any search. */
|
|
5
|
+
results: FsEntry[] | null;
|
|
6
|
+
/** 搜索是否进行中。Whether a search is running. */
|
|
7
|
+
loading: boolean;
|
|
8
|
+
/** 搜索失败的原因。Why the search failed. */
|
|
9
|
+
error: Error | null;
|
|
10
|
+
}
|
|
11
|
+
export interface UseFsSearchOptions {
|
|
12
|
+
client: OvClient | null;
|
|
13
|
+
/** 已去抖的查询词;空串表示没有搜索。The debounced query; empty means no search. */
|
|
14
|
+
query: string;
|
|
15
|
+
targetUri: string;
|
|
16
|
+
/**
|
|
17
|
+
* 重新取数的代次。宿主调用刷新时递增,让同一查询词重新请求——外部数据变了
|
|
18
|
+
* 而查询词没变,只靠依赖是看不出来的。
|
|
19
|
+
*
|
|
20
|
+
* Reload generation. A host increments it on refresh so the same query is
|
|
21
|
+
* requested again: the data changed while the query did not, which dependencies
|
|
22
|
+
* alone cannot express.
|
|
23
|
+
*/
|
|
24
|
+
generation?: number;
|
|
25
|
+
requestOptions?: OvRequestOptions;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 语义搜索。结果按 URI 去重后合并成一个列表——搜索视图只需要「跳到哪个资源」,
|
|
29
|
+
* 类别分组对使用者没有意义。
|
|
30
|
+
*
|
|
31
|
+
* Semantic search. Results merge into one list deduplicated by URI: the search
|
|
32
|
+
* view only needs "which resource to jump to", so the category split adds
|
|
33
|
+
* nothing for the user.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useFsSearch({ client, query, targetUri, generation, requestOptions, }: UseFsSearchOptions): SearchState;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FileTreeEntryRow, FileTreeRow } from '../../components/file-tree/index.js';
|
|
2
|
+
import type { OvClient, OvRequestOptions } from '../../client/types.js';
|
|
3
|
+
export interface FsTreeState {
|
|
4
|
+
rows: readonly FileTreeRow[];
|
|
5
|
+
isReady: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
/**
|
|
8
|
+
* 树已知的目录 URI 集合,与当前是否可见无关。
|
|
9
|
+
* Directory URIs the tree knows about, whether or not they are visible.
|
|
10
|
+
*/
|
|
11
|
+
directoryUris: ReadonlySet<string>;
|
|
12
|
+
/**
|
|
13
|
+
* 该 URI 是否是树里见过的文件。与 {@link directoryUris} 都不命中即为类型未知。
|
|
14
|
+
* Whether the URI is a file the tree has seen. Missing from both this and
|
|
15
|
+
* {@link directoryUris} means the type is unknown.
|
|
16
|
+
*/
|
|
17
|
+
isKnownFile: (uri: string) => boolean;
|
|
18
|
+
toggleExpand: (row: FileTreeEntryRow) => Promise<void>;
|
|
19
|
+
open: (uri: string) => Promise<void>;
|
|
20
|
+
loadMore: (parentId: string) => Promise<void>;
|
|
21
|
+
retry: (parentId: string) => Promise<void>;
|
|
22
|
+
refresh: () => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface UseFsTreeOptions {
|
|
25
|
+
client: OvClient | null;
|
|
26
|
+
rootUri: string;
|
|
27
|
+
/**
|
|
28
|
+
* 首次加载后自动展开到的路径,逐级展开并加载子节点。省略时只展开根。
|
|
29
|
+
* Path to expand to after the first load, opening and loading each level.
|
|
30
|
+
* Omitting it leaves only the root expanded.
|
|
31
|
+
*/
|
|
32
|
+
defaultExpandedUri?: string;
|
|
33
|
+
requestOptions?: OvRequestOptions;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 目录树的取数、展开与分页。按需展开:根目录先加载,展开某个目录时才取它的
|
|
37
|
+
* 子节点,每一层各自持有分页与失败状态,一个目录出错不影响其它分支。
|
|
38
|
+
*
|
|
39
|
+
* Loading, expansion and paging of the directory tree. It loads on demand: the
|
|
40
|
+
* root first, then a directory's children when it expands. Each level keeps its
|
|
41
|
+
* own paging and failure state, so one broken directory does not affect others.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useFsTree({ client, rootUri, defaultExpandedUri, requestOptions, }: UseFsTreeOptions): FsTreeState;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { OvClient, OvRequestOptions } from '../../client/types.js';
|
|
2
|
+
import { type RequestScope } from './fs-scope.js';
|
|
3
|
+
/**
|
|
4
|
+
* 请求作用域:客户端实例、根目录与逐请求覆盖的身份字段。
|
|
5
|
+
*
|
|
6
|
+
* 换 Provider、换 `requestOptions.accountId`、换 `rootUri`,上一个作用域里还没回来
|
|
7
|
+
* 的请求都必须作废,否则 A 的响应会在 B 的树上落地。
|
|
8
|
+
*
|
|
9
|
+
* 中止是**传输副作用**,只在提交之后做,不在渲染里做:React 可以放弃一次渲染
|
|
10
|
+
* (`startTransition` + Suspense 就会),渲染里中止会把仍在屏幕上的那棵树的在途
|
|
11
|
+
* 请求杀掉。渲染里只记下「期望的作用域键」,请求回来时用它判断结果是否过期。
|
|
12
|
+
*
|
|
13
|
+
* The request scope: the client instance, the root and the per-request identity
|
|
14
|
+
* overrides.
|
|
15
|
+
*
|
|
16
|
+
* Switching the Provider, `requestOptions.accountId` or `rootUri` must invalidate the
|
|
17
|
+
* requests still in flight, or A's response lands on B's tree.
|
|
18
|
+
*
|
|
19
|
+
* Aborting is a **transport side effect** and happens only after commit, never during
|
|
20
|
+
* render: React may abandon a render (`startTransition` with Suspense does), and
|
|
21
|
+
* aborting there would kill the in-flight requests of the tree still on screen. Render
|
|
22
|
+
* only records the *desired* scope key, which a returning request compares against.
|
|
23
|
+
*/
|
|
24
|
+
export interface RequestScopeHandle {
|
|
25
|
+
/**
|
|
26
|
+
* 当前**已提交**作用域的键与控制器。
|
|
27
|
+
*
|
|
28
|
+
* 它是判断过期的唯一依据,因为只有提交才会改它:渲染期不写任何东西,被放弃的
|
|
29
|
+
* 渲染因此不会让仍在屏幕上的那棵树的结果作废。
|
|
30
|
+
*
|
|
31
|
+
* The key and controller of the **committed** scope.
|
|
32
|
+
*
|
|
33
|
+
* It is the only basis for staleness because only a commit changes it: render writes
|
|
34
|
+
* nothing, so an abandoned render cannot invalidate the results of the tree still on
|
|
35
|
+
* screen.
|
|
36
|
+
*/
|
|
37
|
+
current: () => RequestScope;
|
|
38
|
+
}
|
|
39
|
+
export declare function useRequestScope(client: OvClient | null, requestOptions: OvRequestOptions | undefined, rootUri: string): RequestScopeHandle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FileBrowser,
|
|
1
|
+
export { FileBrowser, useFileBrowser } from "../l~0.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.ov-agent-connect, .ov-file-browser, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__interaction {
|
|
1
|
+
.ov-agent-connect, .ov-divider, .ov-file-browser, .ov-file-browser-entries, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-popover, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__interaction {
|
|
2
2
|
--ov-ui-primary-default: #5252ff;
|
|
3
3
|
--ov-ui-primary-hover-default: #7075ff;
|
|
4
4
|
--ov-ui-primary-active-default: #3833d2;
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
--ov-ui-tooltip-text-default: #fff;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
.dark .ov-agent-connect, .dark .ov-file-browser, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__interaction {
|
|
33
|
+
.dark .ov-agent-connect, .dark .ov-divider, .dark .ov-file-browser, .dark .ov-file-browser-entries, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-popover, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__interaction {
|
|
34
34
|
--ov-ui-primary-default: #5f5fff;
|
|
35
35
|
--ov-ui-primary-hover-default: #7075ff;
|
|
36
36
|
--ov-ui-primary-active-default: #4242ba;
|