kindy-editor 3.2.1 → 3.2.2
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-lib/assets/{worker-_GAJUHf5.js → worker-DO8U44KQ.js} +1 -0
- package/dist-lib/builder.js +4 -4
- package/dist-lib/{editorApp-7-JzxxVn.js → editorApp-N20nk5uQ.js} +9214 -8515
- package/dist-lib/events.js +1 -1
- package/dist-lib/export.js +1396 -1385
- package/dist-lib/generate-toc.js +3 -3
- package/dist-lib/import.js +2 -2
- package/dist-lib/index-Dd7gMK7l.js +12857 -0
- package/dist-lib/{kindy-editor-DKDwpt09.js → kindy-editor-D4xSNtvA.js} +133 -83
- package/dist-lib/kindy-editor.js +1 -1
- package/dist-lib/{parse-D4RpPrd7.js → parse-JE_w0NNt.js} +3 -3
- package/dist-lib/{pipeline-DhhBcLvV.js → pipeline-CgbvBwNe.js} +1 -1
- package/dist-lib/recalc-docx.js +1 -1
- package/dist-lib/{recalcToc-n50vq4nC.js → recalcToc-DKJK9f5X.js} +1 -1
- package/dist-lib/{stylesheet-E5bu1xch.js → stylesheet-COz2MSt6.js} +1 -1
- package/dist-lib/{toc-DSwkNKls.js → toc-C6XLbDEA.js} +389 -360
- package/dist-lib/{webmcp-KVT__0GH.js → webmcp-DrpPKUeh.js} +2 -2
- package/docs/.vitepress/config.ts +2 -0
- package/docs/public-events.md +1 -0
- package/docs/template-variables.md +310 -0
- package/package.json +1 -1
- package/types/kindy-editor.d.ts +122 -3
- package/dist-lib/index-Brv5TV-9.js +0 -11822
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as j, j as _, A as F, t as k, D as L } from "./toc-
|
|
1
|
+
import { a as j, j as _, A as F, t as k, D as L } from "./toc-C6XLbDEA.js";
|
|
2
2
|
const s = (e) => Math.round(e * 100) / 100;
|
|
3
3
|
function A(e) {
|
|
4
4
|
const o = { font: e.fontFamily, sizePx: e.fontSizePx };
|
|
@@ -332,7 +332,7 @@ function H(e, o = {}, r = {}) {
|
|
|
332
332
|
if (i && e.search(i).total === 0)
|
|
333
333
|
return e.searchClear(), f(`text not found: ${i}`);
|
|
334
334
|
if (!e.getSelection()) return f("no selection (pass 'find' or select_range first)");
|
|
335
|
-
const { insertText: d } = await import("./editorApp-
|
|
335
|
+
const { insertText: d } = await import("./editorApp-N20nk5uQ.js").then((m) => m.c);
|
|
336
336
|
return e.dispatch(d(t)), i && e.searchClear(), g("inserted");
|
|
337
337
|
}
|
|
338
338
|
}), a({
|
|
@@ -6,6 +6,7 @@ export default defineConfig({
|
|
|
6
6
|
themeConfig: {
|
|
7
7
|
nav: [
|
|
8
8
|
{ text: 'Home', link: '/' },
|
|
9
|
+
{ text: 'Template Variables', link: '/template-variables' },
|
|
9
10
|
{ text: 'Fonts & CDN', link: '/fonts' },
|
|
10
11
|
{ text: 'Table editing', link: '/table-editing' },
|
|
11
12
|
{ text: 'Public Events', link: '/public-events' },
|
|
@@ -16,6 +17,7 @@ export default defineConfig({
|
|
|
16
17
|
text: 'Integration & Events',
|
|
17
18
|
items: [
|
|
18
19
|
{ text: 'Overview', link: '/' },
|
|
20
|
+
{ text: 'Template Variables & Metadata', link: '/template-variables' },
|
|
19
21
|
{ text: 'Fonts & CDN', link: '/fonts' },
|
|
20
22
|
{ text: 'Table editing', link: '/table-editing' },
|
|
21
23
|
{ text: 'Public Events API', link: '/public-events' },
|
package/docs/public-events.md
CHANGED
|
@@ -98,6 +98,7 @@ general-purpose analytics services.
|
|
|
98
98
|
| Export | `document.export.*` |
|
|
99
99
|
| Changes | `document.change.applied`, `document.change.committed`, `document.change.rejected`, `document.remoteChange.applied` |
|
|
100
100
|
| Review | `review.operation.applied`, `review.suggestion.*`, `review.thread.*`, `review.comment.*` |
|
|
101
|
+
| Template & Metadata | `template.variable.clicked`, `template.variable.changed`, `template.displayMode.changed` |
|
|
101
102
|
| Collaboration | `collaboration.connecting`, `collaboration.connected`, `collaboration.disconnected`, `collaboration.user.*`, `collaboration.presence.changed` |
|
|
102
103
|
| Other | `document.shared`, `selection.changed`, `custom` |
|
|
103
104
|
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Template Variables & Contract Metadata API
|
|
2
|
+
|
|
3
|
+
Kindy Editor hỗ trợ quản lý các **biến mẫu (Template Variables)** và **Metadata Hợp đồng** trực tiếp trong mô hình tài liệu (AST level).
|
|
4
|
+
|
|
5
|
+
Các biến mẫu được liên kết chặt chẽ với văn bản thông qua thuộc tính `CharStyle.variableKey`, đảm bảo tính toàn vẹn (atomic tokens), hỗ trợ định dạng tự động theo kiểu dữ liệu (`TEXT`, `NUMBER`, `DATE`, `CURRENCY`, `SELECT`), và cung cấp hệ thống event phong phú để host application (React, Vue, Angular, v.v.) tự do dựng giao diện popover/drawer theo design system riêng.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Khởi tạo & Cấu hình (Options)
|
|
10
|
+
|
|
11
|
+
Khi khởi tạo `KindyEditor`, bạn có thể cấu hình các tùy chọn liên quan đến biến mẫu:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { KindyEditor } from "kindy-editor";
|
|
15
|
+
import type { VariableClickInfo } from "kindy-editor";
|
|
16
|
+
|
|
17
|
+
const editor = new KindyEditor({
|
|
18
|
+
container: document.getElementById("editor-container")!,
|
|
19
|
+
|
|
20
|
+
// Callback khi người dùng click vào một biến mẫu trong văn bản
|
|
21
|
+
onVariableClick: (info: VariableClickInfo) => {
|
|
22
|
+
console.log("Clicked variable:", info.key, info.def);
|
|
23
|
+
// info.clientRect chứa tọa độ viewport { top, left, width, height }
|
|
24
|
+
// để host app hiển thị Popover / Drawer / Modal tùy biến
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// Có hiển thị Popover mặc định của editor không (mặc định: false)
|
|
28
|
+
// Nếu đặt là false, host app toàn quyền hiển thị UI qua onVariableClick
|
|
29
|
+
showVariablePopover: false,
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Các phương thức của Editor API (`EditorHandle` / `KindyEditor`)
|
|
36
|
+
|
|
37
|
+
Tất cả các phương thức sau có thể gọi thông qua instance của `KindyEditor` hoặc thông qua `handle` nhận được từ `onReady` / `editor.ready`:
|
|
38
|
+
|
|
39
|
+
### 2.1. `setTemplateVariables(values, options?)`
|
|
40
|
+
Cập nhật giá trị hàng loạt biến mà không cần reload tài liệu. Trạng thái con trỏ, lịch sử undo/redo và vị trí scroll đều được bảo toàn.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
await editor.setTemplateVariables(
|
|
44
|
+
{
|
|
45
|
+
contract_code: "HD-2026/001",
|
|
46
|
+
contract_value: 25000000,
|
|
47
|
+
signing_date: "2026-10-04",
|
|
48
|
+
customer_name: "Công ty Cổ phần Công nghệ ABC",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
author: { id: "user-1", firstName: "Hùng", lastName: "Ngô" },
|
|
52
|
+
source: "sidebar", // "api" | "editor" | "sidebar" | "inline" | "import" | "palette"
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2.2. `insertTemplateVariable(item, author?)`
|
|
58
|
+
Chèn một token biến mẫu atomic tại vị trí con trỏ hiện tại (hoặc thay thế vùng chọn hiện tại).
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
await editor.insertTemplateVariable(
|
|
62
|
+
{
|
|
63
|
+
key: "contract_value",
|
|
64
|
+
label: "Giá trị hợp đồng",
|
|
65
|
+
dataType: "CURRENCY",
|
|
66
|
+
value: 50000000,
|
|
67
|
+
defaultValue: "{{contract_value}}",
|
|
68
|
+
group: "TAI_CHINH",
|
|
69
|
+
metadataId: 102,
|
|
70
|
+
},
|
|
71
|
+
{ id: "user-1", firstName: "Hùng", lastName: "Ngô" }
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2.3. `setVariableDisplayMode(mode)` & `getVariableDisplayMode()`
|
|
76
|
+
Thay đổi chế độ hiển thị biến trên toàn bộ văn bản:
|
|
77
|
+
* `'code'` / `'placeholder'`: Hiển thị mã placeholder, ví dụ `{{contract_code}}`. Thích hợp khi soạn thảo mẫu hợp đồng (Template Editor).
|
|
78
|
+
* `'value'`: Hiển thị giá trị thực tế sau khi đã format theo `dataType`, ví dụ `HD-2026/001` hoặc `25.000.000 VNĐ`. Nếu biến chưa có giá trị, tự động fallback về mã placeholder.
|
|
79
|
+
* `'label'`: Hiển thị nhãn tiếng Việt của biến.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// Chuyển sang hiển thị giá trị thực tế
|
|
83
|
+
await editor.setVariableDisplayMode("value");
|
|
84
|
+
|
|
85
|
+
// Đọc chế độ hiện tại
|
|
86
|
+
const currentMode = await editor.getVariableDisplayMode(); // "value" | "code"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2.4. `getTemplateVariables()` & `getTemplateVariable(key)`
|
|
90
|
+
Truy vấn danh sách hoặc chi tiết các biến đã đăng ký trong tài liệu.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// Lấy toàn bộ biến đã đăng ký
|
|
94
|
+
const allVariables = await editor.getTemplateVariables();
|
|
95
|
+
console.log(allVariables["contract_code"]);
|
|
96
|
+
|
|
97
|
+
// Lấy 1 biến cụ thể
|
|
98
|
+
const codeVar = await editor.getTemplateVariable("contract_code");
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 2.5. `getUsedMetadataIds()`
|
|
102
|
+
Trả về danh sách các `metadataId` (ID số định danh từ cơ sở dữ liệu backend) hiện đang thực sự được nhúng trong tài liệu. Rất hữu ích cho backend khi cần kiểm tra những metadata nào đang được văn bản sử dụng.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const usedIds = await editor.getUsedMetadataIds();
|
|
106
|
+
// Ví dụ: [101, 102, 105]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2.6. `setMetadataCatalog(catalog)` & `openMetadataPalette()`
|
|
110
|
+
Cung cấp danh mục các biến từ backend cho tính năng gợi ý autocomplete (`@`), hoặc chủ động mở thanh tìm kiếm biến tại vị trí con trỏ.
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
// Cung cấp danh mục biến cho autocomplete
|
|
114
|
+
await editor.setMetadataCatalog([
|
|
115
|
+
{
|
|
116
|
+
key: "contract_code",
|
|
117
|
+
label: "Mã hợp đồng",
|
|
118
|
+
dataType: "TEXT",
|
|
119
|
+
group: "THONG_TIN_CHUNG",
|
|
120
|
+
metadataId: 1,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
key: "contract_value",
|
|
124
|
+
label: "Giá trị hợp đồng",
|
|
125
|
+
dataType: "CURRENCY",
|
|
126
|
+
group: "TAI_CHINH",
|
|
127
|
+
metadataId: 2,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
key: "effective_date",
|
|
131
|
+
label: "Ngày hiệu lực",
|
|
132
|
+
dataType: "DATE",
|
|
133
|
+
dateFormat: "dd/MM/yyyy",
|
|
134
|
+
group: "THOI_HAN",
|
|
135
|
+
metadataId: 3,
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
// Chủ động mở bảng chọn @ tại vị trí con trỏ
|
|
140
|
+
await editor.openMetadataPalette();
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 3. Public Events API
|
|
146
|
+
|
|
147
|
+
Lắng nghe các sự kiện liên quan đến Template Variables thông qua `editor.on(...)`:
|
|
148
|
+
|
|
149
|
+
### 3.1. `template.variable.clicked`
|
|
150
|
+
Kích hoạt khi người dùng click vào một biến mẫu trong văn bản:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
editor.on("template.variable.clicked", (event) => {
|
|
154
|
+
const { key, def, position, rect, clientRect } = event.data;
|
|
155
|
+
|
|
156
|
+
console.log(`Clicked variable: ${key}`);
|
|
157
|
+
console.log(`Current value:`, def.value);
|
|
158
|
+
console.log(`Bounding Box trên màn hình:`, clientRect);
|
|
159
|
+
// clientRect: { left, top, right, bottom, width, height }
|
|
160
|
+
// Dùng để định vị floating popover/tooltip cạnh biến vừa click
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3.2. `template.variable.changed`
|
|
165
|
+
Kích hoạt khi một biến được tạo mới, cập nhật giá trị hoặc hoàn tác:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
editor.on("template.variable.changed", (event) => {
|
|
169
|
+
const { key, newValue, previousValue, action, source, def } = event.data;
|
|
170
|
+
console.log(`Variable ${key} was ${action} from source ${source}`);
|
|
171
|
+
console.log(`Old: ${previousValue} -> New: ${newValue}`);
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 3.3. `template.displayMode.changed`
|
|
176
|
+
Kích hoạt khi chế độ hiển thị biến thay đổi:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
editor.on("template.displayMode.changed", (event) => {
|
|
180
|
+
const { mode, previousMode } = event.data;
|
|
181
|
+
console.log(`Display mode changed from ${previousMode} to ${mode}`);
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 4. Định dạng tự động theo Kiểu dữ liệu (`MetadataDataType`)
|
|
188
|
+
|
|
189
|
+
Khi ở chế độ `value`, hàm định dạng tự động chuyển đổi giá trị dựa vào trường `dataType`:
|
|
190
|
+
|
|
191
|
+
| `dataType` | Ví dụ đầu vào | Kết quả hiển thị |
|
|
192
|
+
| :--- | :--- | :--- |
|
|
193
|
+
| `TEXT` | `"Hà Nội"` | `Hà Nội` |
|
|
194
|
+
| `NUMBER` | `1500000` | `1.500.000` (định dạng theo locale vi-VN) |
|
|
195
|
+
| `CURRENCY` | `25000000` | `25.000.000 VNĐ` |
|
|
196
|
+
| `DATE` | `"2026-10-04"` | `04/10/2026` (hỗ trợ `dateFormat: "dd/MM/yyyy"` hoặc `"yyyy-MM-dd"`) |
|
|
197
|
+
| `SELECT` | `"Đã ký"` | `Đã ký` |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 5. Tương tác Người dùng (UX & Hành vi gõ phím)
|
|
202
|
+
|
|
203
|
+
1. **Kích hoạt Autocomplete qua `@`**:
|
|
204
|
+
- Khi gõ ký tự `@` ở đầu dòng hoặc sau một khoảng trắng, bảng **Metadata Palette** sẽ tự động mở ra.
|
|
205
|
+
- Người dùng có thể dùng các phím mũi tên `↑` `↓` để duyệt, `Enter` hoặc `Tab` để chèn, và `Escape` để đóng.
|
|
206
|
+
- Gõ email (ví dụ: `sales@gmail.com`) sẽ **không** bị kích hoạt bảng chọn vì trước `@` không phải là khoảng trắng.
|
|
207
|
+
|
|
208
|
+
2. **Tính chất Atomic Token**:
|
|
209
|
+
- Khi bấm phím `Backspace` hoặc `Delete` tại biên của biến, toàn bộ token biến sẽ được xóa sạch trong một thao tác (thay vì xóa từng ký tự placeholder).
|
|
210
|
+
- Khi gõ phím tiếp theo ngay sau một biến, văn bản mới sẽ tự động nhận style thông thường và không bị dính thuộc tính `variableKey`.
|
|
211
|
+
- Khi click vào biến, văn bản của biến sẽ tự động được chọn toàn bộ.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 6. Ví dụ Tích hợp với React
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
219
|
+
import { KindyEditor, type VariableClickInfo } from "kindy-editor";
|
|
220
|
+
import "kindy-editor/style";
|
|
221
|
+
|
|
222
|
+
export function ContractEditor() {
|
|
223
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
224
|
+
const editorRef = useRef<KindyEditor | null>(null);
|
|
225
|
+
const [selectedVar, setSelectedVar] = useState<VariableClickInfo | null>(null);
|
|
226
|
+
|
|
227
|
+
useEffect(() => {
|
|
228
|
+
if (!containerRef.current) return;
|
|
229
|
+
|
|
230
|
+
const editor = new KindyEditor({
|
|
231
|
+
container: containerRef.current,
|
|
232
|
+
showVariablePopover: false, // tắt popup mặc định để dùng React Popover
|
|
233
|
+
onVariableClick: (info) => {
|
|
234
|
+
setSelectedVar(info);
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
editorRef.current = editor;
|
|
239
|
+
|
|
240
|
+
// Lắng nghe sự kiện click ra ngoài để đóng popover
|
|
241
|
+
const handleMouseDown = (e: MouseEvent) => {
|
|
242
|
+
if (!(e.target as HTMLElement).closest(".custom-variable-popover")) {
|
|
243
|
+
setSelectedVar(null);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
window.addEventListener("mousedown", handleMouseDown);
|
|
247
|
+
|
|
248
|
+
return () => {
|
|
249
|
+
window.removeEventListener("mousedown", handleMouseDown);
|
|
250
|
+
editor.destroy();
|
|
251
|
+
};
|
|
252
|
+
}, []);
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<div style={{ position: "relative", width: "100%", height: "100vh" }}>
|
|
256
|
+
{/* Editor Canvas Container */}
|
|
257
|
+
<div ref={containerRef} style={{ width: "100%", height: "100%" }} />
|
|
258
|
+
|
|
259
|
+
{/* Custom React Floating Popover */}
|
|
260
|
+
{selectedVar && selectedVar.clientRect && (
|
|
261
|
+
<div
|
|
262
|
+
className="custom-variable-popover"
|
|
263
|
+
style={{
|
|
264
|
+
position: "fixed",
|
|
265
|
+
left: `${selectedVar.clientRect.left}px`,
|
|
266
|
+
top: `${selectedVar.clientRect.bottom + 8}px`,
|
|
267
|
+
background: "#ffffff",
|
|
268
|
+
border: "1px solid #e2e8f0",
|
|
269
|
+
borderRadius: "8px",
|
|
270
|
+
boxShadow: "0 10px 15px -3px rgba(0,0,0,0.1)",
|
|
271
|
+
padding: "12px 16px",
|
|
272
|
+
zIndex: 1000,
|
|
273
|
+
minWidth: "260px",
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<div style={{ fontWeight: "bold", color: "#0284c7" }}>
|
|
277
|
+
{selectedVar.def.label} ({`{{${selectedVar.key}}}`})
|
|
278
|
+
</div>
|
|
279
|
+
<div style={{ fontSize: "12px", color: "#64748b", marginTop: "4px" }}>
|
|
280
|
+
Loại: {selectedVar.def.dataType}
|
|
281
|
+
</div>
|
|
282
|
+
<div style={{ fontSize: "14px", marginTop: "6px" }}>
|
|
283
|
+
Giá trị: <strong>{String(selectedVar.def.value ?? "Chưa có")}</strong>
|
|
284
|
+
</div>
|
|
285
|
+
<button
|
|
286
|
+
onClick={() => {
|
|
287
|
+
const nextVal = prompt("Nhập giá trị mới:", String(selectedVar.def.value ?? ""));
|
|
288
|
+
if (nextVal !== null) {
|
|
289
|
+
editorRef.current?.setTemplateVariables({ [selectedVar.key]: nextVal });
|
|
290
|
+
setSelectedVar(null);
|
|
291
|
+
}
|
|
292
|
+
}}
|
|
293
|
+
style={{
|
|
294
|
+
marginTop: "8px",
|
|
295
|
+
padding: "4px 8px",
|
|
296
|
+
background: "#0284c7",
|
|
297
|
+
color: "#fff",
|
|
298
|
+
border: "none",
|
|
299
|
+
borderRadius: "4px",
|
|
300
|
+
cursor: "pointer",
|
|
301
|
+
}}
|
|
302
|
+
>
|
|
303
|
+
Chỉnh sửa giá trị
|
|
304
|
+
</button>
|
|
305
|
+
</div>
|
|
306
|
+
)}
|
|
307
|
+
</div>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
```
|
package/package.json
CHANGED
package/types/kindy-editor.d.ts
CHANGED
|
@@ -54,7 +54,71 @@ export interface RevealRangeOptions {
|
|
|
54
54
|
align?: "center" | "nearest" | "top" | "bottom";
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export type TemplateVariableValues = Record<string, string | number | null | undefined>;
|
|
57
|
+
export type TemplateVariableValues = Record<string, string | number | boolean | null | undefined>;
|
|
58
|
+
|
|
59
|
+
export type MetadataDataType = "TEXT" | "NUMBER" | "DATE" | "CURRENCY" | "SELECT";
|
|
60
|
+
export type VariableDisplayMode = "code" | "value" | "placeholder" | "label";
|
|
61
|
+
|
|
62
|
+
export interface VariableBoundingBox {
|
|
63
|
+
left: number;
|
|
64
|
+
top: number;
|
|
65
|
+
right: number;
|
|
66
|
+
bottom: number;
|
|
67
|
+
width: number;
|
|
68
|
+
height: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface VariableClickInfo {
|
|
72
|
+
key: string;
|
|
73
|
+
def: TemplateVariableDef;
|
|
74
|
+
position: DocPosition;
|
|
75
|
+
rect: VariableBoundingBox;
|
|
76
|
+
clientRect?: VariableBoundingBox;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface MetadataAuditEntry {
|
|
80
|
+
id: string;
|
|
81
|
+
author: UserInfo;
|
|
82
|
+
timestamp: number;
|
|
83
|
+
previousValue: unknown;
|
|
84
|
+
newValue: unknown;
|
|
85
|
+
action: "created" | "updated" | "reverted";
|
|
86
|
+
source?: "api" | "editor" | "sidebar" | "palette" | "inline" | "import";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface TemplateVariableDef {
|
|
90
|
+
key: string;
|
|
91
|
+
label: string;
|
|
92
|
+
dataType: MetadataDataType;
|
|
93
|
+
dateFormat?: string;
|
|
94
|
+
value?: unknown;
|
|
95
|
+
defaultValue?: string;
|
|
96
|
+
metadataId?: number | string;
|
|
97
|
+
group?: string;
|
|
98
|
+
createdBy?: UserInfo;
|
|
99
|
+
createdAt?: number;
|
|
100
|
+
lastModifiedBy?: UserInfo;
|
|
101
|
+
lastModifiedAt?: number;
|
|
102
|
+
history?: MetadataAuditEntry[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface SetTemplateVariablesOptions {
|
|
106
|
+
author?: UserInfo;
|
|
107
|
+
source?: "api" | "editor" | "sidebar" | "inline" | "import" | "palette";
|
|
108
|
+
trackInReview?: boolean;
|
|
109
|
+
metadata?: Record<string, Partial<TemplateVariableDef>>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface InsertTemplateVariableItem {
|
|
113
|
+
key: string;
|
|
114
|
+
label: string;
|
|
115
|
+
dataType?: MetadataDataType;
|
|
116
|
+
dateFormat?: string;
|
|
117
|
+
value?: unknown;
|
|
118
|
+
defaultValue?: string;
|
|
119
|
+
metadataId?: number | string;
|
|
120
|
+
group?: string;
|
|
121
|
+
}
|
|
58
122
|
|
|
59
123
|
export interface EditorPermissions {
|
|
60
124
|
editContent: boolean;
|
|
@@ -547,6 +611,13 @@ export interface KindyEditorOptions {
|
|
|
547
611
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
548
612
|
/** Granular capabilities governing content edits, annotations, and selection. */
|
|
549
613
|
permissions?: Partial<EditorPermissions>;
|
|
614
|
+
/** Callback fired when a template variable token is clicked in the editor.
|
|
615
|
+
* Provides variable key, definition, doc position, and bounding rects (container & client viewport).
|
|
616
|
+
* Allows host application (React/Vue/etc.) to render custom modals, drawers, or popovers. */
|
|
617
|
+
onVariableClick?: (info: VariableClickInfo) => void;
|
|
618
|
+
/** Whether to show the built-in variable audit popover UI on click. Defaults to false.
|
|
619
|
+
* When false, the built-in popover does not appear, leaving UI rendering to the host via onVariableClick / event. */
|
|
620
|
+
showVariablePopover?: boolean;
|
|
550
621
|
}
|
|
551
622
|
|
|
552
623
|
/** Initial view-chrome state (see KindyEditorOptions.view). Every field is
|
|
@@ -805,7 +876,31 @@ export interface EditorHandle {
|
|
|
805
876
|
revealRange(range: ExternalRange, options?: RevealRangeOptions): void;
|
|
806
877
|
/** Live-update {{KEY}} template placeholders in the document without full reload,
|
|
807
878
|
* preserving zoom, scroll position, and selection. */
|
|
808
|
-
setTemplateVariables(values: TemplateVariableValues): void;
|
|
879
|
+
setTemplateVariables(values: TemplateVariableValues, options?: SetTemplateVariablesOptions): void;
|
|
880
|
+
/** Revert a template variable to an earlier value recorded in its audit history. */
|
|
881
|
+
revertTemplateVariable(key: string, historyId: string, actor?: UserInfo): boolean;
|
|
882
|
+
/** Insert an atomic template variable token at current caret/selection. */
|
|
883
|
+
insertTemplateVariable(item: InsertTemplateVariableItem, author?: UserInfo): boolean;
|
|
884
|
+
/** Open the contract metadata palette autocomplete at current caret position. */
|
|
885
|
+
openMetadataPalette(): void;
|
|
886
|
+
/** Set template variable display mode ('code' | 'value' | 'placeholder'). */
|
|
887
|
+
setVariableDisplayMode(mode: VariableDisplayMode): void;
|
|
888
|
+
/** Get current template variable display mode. */
|
|
889
|
+
getVariableDisplayMode(): VariableDisplayMode;
|
|
890
|
+
/** Get all registered template variables in the document. */
|
|
891
|
+
getTemplateVariables(): Record<string, TemplateVariableDef>;
|
|
892
|
+
/** Get a single registered template variable definition by key. */
|
|
893
|
+
getTemplateVariable(key: string): TemplateVariableDef | null;
|
|
894
|
+
/** Get audit trail history for a template variable. */
|
|
895
|
+
getVariableHistory(key: string): MetadataAuditEntry[];
|
|
896
|
+
/** Open built-in variable popover explicitly. */
|
|
897
|
+
openVariablePopover(key: string, pos?: DocPosition): void;
|
|
898
|
+
/** Close built-in variable popover. */
|
|
899
|
+
closeVariablePopover(): void;
|
|
900
|
+
/** Get all metadata IDs (numbers) currently used by template variables in the document. */
|
|
901
|
+
getUsedMetadataIds(): number[];
|
|
902
|
+
/** Set custom metadata catalog for autocomplete palette. */
|
|
903
|
+
setMetadataCatalog(catalog: TemplateVariableDef[]): void;
|
|
809
904
|
/** Update fine-grained capabilities (e.g. allow comments/selection in view mode). */
|
|
810
905
|
setPermissions(permissions: Partial<EditorPermissions>): void;
|
|
811
906
|
/** Current effective permissions. */
|
|
@@ -894,7 +989,31 @@ export declare class KindyEditor {
|
|
|
894
989
|
revealRange(range: ExternalRange, options?: RevealRangeOptions): Promise<void>;
|
|
895
990
|
/** Live-update {{KEY}} template placeholders in the document without full reload,
|
|
896
991
|
* preserving zoom, scroll position, and selection. */
|
|
897
|
-
setTemplateVariables(values: TemplateVariableValues): Promise<void>;
|
|
992
|
+
setTemplateVariables(values: TemplateVariableValues, options?: SetTemplateVariablesOptions): Promise<void>;
|
|
993
|
+
/** Revert a template variable to an earlier value recorded in its audit history. */
|
|
994
|
+
revertTemplateVariable(key: string, historyId: string, actor?: UserInfo): Promise<boolean>;
|
|
995
|
+
/** Insert an atomic template variable token at current caret/selection. */
|
|
996
|
+
insertTemplateVariable(item: InsertTemplateVariableItem, author?: UserInfo): Promise<boolean>;
|
|
997
|
+
/** Open the contract metadata palette autocomplete at current caret position. */
|
|
998
|
+
openMetadataPalette(): Promise<void>;
|
|
999
|
+
/** Set template variable display mode ('code' | 'value' | 'placeholder'). */
|
|
1000
|
+
setVariableDisplayMode(mode: VariableDisplayMode): Promise<void>;
|
|
1001
|
+
/** Get current template variable display mode. */
|
|
1002
|
+
getVariableDisplayMode(): Promise<VariableDisplayMode>;
|
|
1003
|
+
/** Get all registered template variables in the document. */
|
|
1004
|
+
getTemplateVariables(): Promise<Record<string, TemplateVariableDef>>;
|
|
1005
|
+
/** Get a single registered template variable definition by key. */
|
|
1006
|
+
getTemplateVariable(key: string): Promise<TemplateVariableDef | null>;
|
|
1007
|
+
/** Get audit trail history for a template variable. */
|
|
1008
|
+
getVariableHistory(key: string): Promise<MetadataAuditEntry[]>;
|
|
1009
|
+
/** Open built-in variable popover explicitly. */
|
|
1010
|
+
openVariablePopover(key: string, pos?: DocPosition): Promise<void>;
|
|
1011
|
+
/** Close built-in variable popover. */
|
|
1012
|
+
closeVariablePopover(): Promise<void>;
|
|
1013
|
+
/** Get all metadata IDs (numbers) currently used by template variables in the document. */
|
|
1014
|
+
getUsedMetadataIds(): Promise<number[]>;
|
|
1015
|
+
/** Set custom metadata catalog for autocomplete palette. */
|
|
1016
|
+
setMetadataCatalog(catalog: TemplateVariableDef[]): Promise<void>;
|
|
898
1017
|
/** Update fine-grained capabilities (e.g. allow comments/selection in view mode). */
|
|
899
1018
|
setPermissions(permissions: Partial<EditorPermissions>): Promise<void>;
|
|
900
1019
|
/** Current effective permissions. */
|