Giao diện
Kiến trúc
Tổng quan
plugin-ui-core là bộ máy vận hành giao diện động, gồm bốn thành phần chính: UiWidgetRepository (quản lý widget tree), UiWidgetSchemaService + Registry (schema validation), Variables Resolver (biến template), và Query Service (lấy dữ liệu).
UiWidgetRepository
Closure Table
Widget được lưu dạng cây qua closure table uiWidgetTreePath. Mỗi cặp ancestor-descendant được lưu kèm depth, cho phép truy vấn subtree trong một query duy nhất.
Closure table tương ứng:
| ancestor | descendant | depth |
|---|---|---|
| w1 | w1 | 0 |
| w1 | w2 | 1 |
| w1 | w3 | 1 |
| w1 | w4 | 2 |
| w1 | w5 | 2 |
| w3 | w4 | 1 |
| w3 | w5 | 1 |
Các operations chính
| Operation | Mô tả |
|---|---|
getJsonSchema | Lấy schema JSON của widget, có cache layer |
schemaToSingleNodes | Tách schema tree thành danh sách node phẳng |
duplicate | Nhân bản widget kèm toàn bộ descendants, sinh UID mới |
attach | Gắn widget vào parent tại vị trí chỉ định (position: beforeBegin, afterBegin, beforeEnd, afterEnd) |
move | Di chuyển widget sang parent khác, cập nhật closure paths |
destroy | Xóa widget kèm tất cả descendants |
mutate | Batch operations — thực hiện nhiều insert/update/delete trong một transaction |
ensureModel | Tạo widget nếu chưa tồn tại, dùng bởi plugin-client khi tạo menu |
Cache
getJsonSchema sử dụng cache layer. Cache được invalidate khi:
- Widget bị update/destroy/move.
ensureModeltạo widget mới.- Client gọi explicit
clearCache.
UiWidgetSchemaService + Registry
Schema Registry
UiWidgetSchemaRegistry cho phép plugin khác đăng ký widget use types — mỗi type định nghĩa JSON schema cho phần options của widget.
typescript
app.pm.get('ui-core').schemaRegistry.register('chart', {
type: 'object',
properties: {
chartType: { type: 'string', enum: ['bar', 'line', 'pie'] },
dataSource: { type: 'string' },
},
required: ['chartType'],
});AJV Validation
Khi save widget, UiWidgetSchemaService dùng AJV validate options theo schema đã đăng ký. Nếu widget type chưa đăng ký, validation bị bỏ qua.
Variables Resolver
Luồng resolve
VariableRegistry
Registry quản lý danh sách variable resolver. Mặc định có user variable — resolve thông tin user hiện tại từ ctx.state.currentUser.
| Method | Mô tả |
|---|---|
resolveVariablesTemplate | Resolve một biến template đơn lẻ |
resolveVariablesBatch | Resolve danh sách biến cùng lúc |
inferSelectsFromUsage | Phân tích danh sách biến để suy ra SELECT fields cần thiết (tối ưu query) |
Query Service
Query Service cho phép widget lấy dữ liệu từ data source.
Luồng thực thi
Các operations
| Operation | Mô tả |
|---|---|
run | Chạy query trực tiếp (truyền SQL/filter) |
runById | Chạy query đã lưu theo UID |
save | Lưu query để tái sử dụng |
getBind | Lấy data binding — ánh xạ giữa query result và widget field |
Query trước khi thực thi sẽ đi qua transformSQL (sanitize tham số) và parseLiquidContext (resolve biến Liquid trong SQL thành giá trị thực).