foggy-data-viewer 1.0.1-beta.38 → 1.0.1-beta.40
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/README.md +74 -0
- package/dist/api/listPreset.d.ts +1 -0
- package/dist/api/tableDefaultQueryConfig.d.ts +2 -0
- package/dist/components/DataTable.vue.d.ts +3 -1
- package/dist/components/DataTableWithSearch.vue.d.ts +16 -1
- package/dist/components/QueryPanel.vue.d.ts +2 -2
- package/dist/components/SearchToolbar.vue.d.ts +2 -2
- package/dist/components/composables/globalColumnRenderers.d.ts +16 -0
- package/dist/components/composables/globalSearchHooks.d.ts +21 -0
- package/dist/components/composables/index.d.ts +3 -0
- package/dist/components/composables/searchHookRegistry.d.ts +19 -0
- package/dist/components/composables/useTableQuery.d.ts +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3838 -3483
- package/dist/index.umd +1 -1
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +103 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -149,6 +149,20 @@ function handlePageChange(page: number, pageSize: number) {
|
|
|
149
149
|
|
|
150
150
|
`DataTableWithSearch` 在 `schema + fetchData` 服务端查询模式下默认 `localFilter=false`:列头筛选仍会提交给 `fetchData`,但返回数据不会再被前端二次过滤,避免聚合字段、派生字段、字典展示字段被简单本地比较误删。需要纯前端过滤时,可显式设置 `localFilter=true` 或 `schema.localFilter=true`。
|
|
151
151
|
|
|
152
|
+
### DataTableWithSearch tableInstanceId 默认查询配置
|
|
153
|
+
|
|
154
|
+
`schema + fetchData` 模式支持按 `tableInstanceId` 加载默认查询配置。默认查询配置只负责默认展示列、排序、分页和筛选;`requiredRuntimeColumns`、`lockedColumns` 由 TM/QM 产出的 `TableSchema` 提供。
|
|
155
|
+
|
|
156
|
+
```vue
|
|
157
|
+
<DataTableWithSearch
|
|
158
|
+
:schema="{ ...tableSchema, qmModel: 'TicketQueryModel', tableInstanceId: 'ticket-list' }"
|
|
159
|
+
:fetch-data="fetchTickets"
|
|
160
|
+
:default-query-config-scope="{ userId: currentUser.id, tenantId: currentTenant.id, roleIds: currentRoleIds }"
|
|
161
|
+
/>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
后端可通过 `foggy.data-viewer.table-defaults.system/tenants/roles` 配置 fallback;用户默认配置仍可通过 `listPreset` 覆盖。`requiredRuntimeColumns` 只会追加到 `fetchData(params).columns`,不会显示为普通列。
|
|
165
|
+
|
|
152
166
|
### DataTable Events
|
|
153
167
|
|
|
154
168
|
| 事件名 | 参数 | 说明 |
|
|
@@ -256,6 +270,66 @@ const columns = buildTableColumns(qmSchema, {
|
|
|
256
270
|
|
|
257
271
|
选择原则:需要绑定业务事件时优先用 `column-*` 插槽;只改显示内容时使用 `render` 更轻。
|
|
258
272
|
|
|
273
|
+
### 全局列渲染器(应用级统一增强)
|
|
274
|
+
|
|
275
|
+
业务系统可以在应用启动时注册 `globalColumnRenderers`,按列元数据统一增强单元格展示。生成的 QueryTable wrapper 不需要批量修改。
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { h } from 'vue'
|
|
279
|
+
import { globalColumnRenderers } from 'foggy-data-viewer'
|
|
280
|
+
|
|
281
|
+
const dispose = globalColumnRenderers.add({
|
|
282
|
+
id: 'app.orderNoLink',
|
|
283
|
+
priority: 100,
|
|
284
|
+
match: ({ column }) => column.name === 'orderNo' && /运单号/.test(column.title ?? ''),
|
|
285
|
+
render: ({ value }) => {
|
|
286
|
+
const text = String(value ?? '').trim()
|
|
287
|
+
if (!text) return '-'
|
|
288
|
+
return h('button', {
|
|
289
|
+
type: 'button',
|
|
290
|
+
class: 'data-viewer-link-cell',
|
|
291
|
+
onClick: (event: MouseEvent) => {
|
|
292
|
+
event.stopPropagation()
|
|
293
|
+
// 在业务应用闭包里调用 router.push(...)
|
|
294
|
+
}
|
|
295
|
+
}, text)
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
// 应用卸载或测试清理
|
|
300
|
+
dispose()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
渲染优先级固定为:`column-*` 插槽 > `column.customRender` > `globalColumnRenderers` > 默认渲染/字典/formatter。列级退出可设置 `column.uiConfig.disableGlobalRender = true`。
|
|
304
|
+
|
|
305
|
+
### 全局搜索生命周期 Hook
|
|
306
|
+
|
|
307
|
+
`globalSearchHooks` 作用于搜索动作层,早于最终 `fetchData` 和 `globalQueryHooks.onBeforeQuery`。它可以区分搜索来源和触发原因,适合埋点、默认条件补充和无效查询拦截。
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { globalSearchHooks } from 'foggy-data-viewer'
|
|
311
|
+
|
|
312
|
+
globalSearchHooks.register({
|
|
313
|
+
beforeSearch: (ctx) => {
|
|
314
|
+
if (ctx.trigger === 'search' && ctx.slice.length === 0) return false
|
|
315
|
+
return {
|
|
316
|
+
slice: [
|
|
317
|
+
...ctx.slice,
|
|
318
|
+
{ field: 'tenantId', op: '=', value: currentTenantId }
|
|
319
|
+
]
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
afterSearch: (ctx, result) => {
|
|
323
|
+
console.log(ctx.source, ctx.trigger, result.total)
|
|
324
|
+
},
|
|
325
|
+
searchError: (ctx, error) => {
|
|
326
|
+
console.warn(ctx.source, ctx.trigger, error)
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`ctx.source` 为 `search-toolbar | query-panel | column-filter | external | api`,`ctx.trigger` 为 `search | reset | filter | sort | page | refresh | reload | mount`。
|
|
332
|
+
|
|
259
333
|
## 类型定义
|
|
260
334
|
|
|
261
335
|
```typescript
|
package/dist/api/listPreset.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VxeGridInstance } from 'vxe-table';
|
|
2
|
-
import type { EnhancedColumnSchema, SliceRequestDef, FilterOption, CellCopyConfig, MemberQueryRequest, MemberQueryResponse, TableDensity } from '@/types';
|
|
2
|
+
import type { EnhancedColumnSchema, SliceRequestDef, FilterOption, CellCopyConfig, MemberQueryRequest, MemberQueryResponse, TableDensity, TableSchema } from '@/types';
|
|
3
3
|
/**
|
|
4
4
|
* DataTable 组件属性
|
|
5
5
|
*
|
|
@@ -44,6 +44,8 @@ interface Props {
|
|
|
44
44
|
filterMemberLoader?: (request: MemberQueryRequest) => Promise<MemberQueryResponse>;
|
|
45
45
|
/** QM 模型名称(远程成员加载所需) */
|
|
46
46
|
qmModel?: string;
|
|
47
|
+
/** 表格 Schema 元数据(全局列渲染器上下文使用) */
|
|
48
|
+
tableSchema?: TableSchema;
|
|
47
49
|
/** 自定义过滤器组件映射 */
|
|
48
50
|
customFilterComponents?: Record<string, unknown>;
|
|
49
51
|
/** 普通单元格悬浮复制配置 */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EnhancedColumnSchema, SliceRequestDef, FilterOption, TableSchema, FetchDataParams, FetchDataResult, OrderRequestDef, QueryHooks, MemberQueryRequest, MemberQueryResponse, CellCopyConfig, QueryMode, ListViewState, ListPresetConfig, TableDensity } from '@/types';
|
|
1
|
+
import type { EnhancedColumnSchema, SliceRequestDef, FilterOption, TableSchema, FetchDataParams, FetchDataResult, OrderRequestDef, QueryHooks, MemberQueryRequest, MemberQueryResponse, CellCopyConfig, QueryMode, ListViewState, ListPresetConfig, TableDensity, SearchHooks, TableDefaultQueryConfig, TableDefaultQueryConfigScope, TableDefaultQueryConfigLoadOptions } from '@/types';
|
|
2
2
|
import type { QueryPanelExpose, QuerySchema } from './QueryPanel.vue';
|
|
3
3
|
/**
|
|
4
4
|
* DataTableWithSearch 组件
|
|
@@ -55,14 +55,24 @@ interface Props {
|
|
|
55
55
|
filterMergeMode?: 'replace' | 'merge';
|
|
56
56
|
/** 查询钩子(声明式) */
|
|
57
57
|
queryHooks?: QueryHooks;
|
|
58
|
+
/** 搜索动作层钩子(声明式) */
|
|
59
|
+
searchHooks?: SearchHooks;
|
|
58
60
|
/** 查询 Schema(传统查询区定义) */
|
|
59
61
|
querySchema?: QuerySchema;
|
|
60
62
|
/** 是否显示传统查询区 */
|
|
61
63
|
showQueryPanel?: boolean;
|
|
62
64
|
/** QM 模型名称(远程成员加载所需) */
|
|
63
65
|
qmModel?: string;
|
|
66
|
+
/** 同一 QM 下的业务表格实例标识 */
|
|
67
|
+
tableInstanceId?: string;
|
|
64
68
|
/** 远程维度成员加载器 */
|
|
65
69
|
filterMemberLoader?: (request: MemberQueryRequest) => Promise<MemberQueryResponse>;
|
|
70
|
+
/** 已解析的表格实例默认查询配置 */
|
|
71
|
+
defaultQueryConfig?: TableDefaultQueryConfig | null;
|
|
72
|
+
/** 默认查询配置自动加载作用域 */
|
|
73
|
+
defaultQueryConfigScope?: TableDefaultQueryConfigLoadOptions;
|
|
74
|
+
/** 自定义默认查询配置加载器 */
|
|
75
|
+
defaultQueryConfigLoader?: (scope: TableDefaultQueryConfigScope) => Promise<TableDefaultQueryConfig | null>;
|
|
66
76
|
/** 启用保存查询功能 */
|
|
67
77
|
enableSavedQuery?: boolean;
|
|
68
78
|
/** 自定义列表配置 */
|
|
@@ -84,6 +94,9 @@ interface DataTableExpose {
|
|
|
84
94
|
clearSelection: (options?: ClearSelectionOptions) => void;
|
|
85
95
|
}
|
|
86
96
|
declare function clearSelectionState(options?: ClearSelectionOptions): void;
|
|
97
|
+
declare function applyTableDefaultQueryConfig(config: TableDefaultQueryConfig, options?: {
|
|
98
|
+
reload?: boolean;
|
|
99
|
+
}): void;
|
|
87
100
|
declare function searchQueryPanel(): void;
|
|
88
101
|
declare function resetQueryPanel(): void;
|
|
89
102
|
declare function getListViewState(): ListViewState;
|
|
@@ -166,6 +179,8 @@ declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
|
166
179
|
getListViewState: typeof getListViewState;
|
|
167
180
|
/** 应用列表视图状态(用于加载自定义列表) */
|
|
168
181
|
applyListViewState: typeof applyListViewState;
|
|
182
|
+
/** 应用表格实例默认查询配置 */
|
|
183
|
+
applyTableDefaultQueryConfig: typeof applyTableDefaultQueryConfig;
|
|
169
184
|
/** 重置列表视图状态 */
|
|
170
185
|
resetListViewState: typeof resetListViewState;
|
|
171
186
|
/** 获取当前查询状态(用于保存查询) */
|
|
@@ -65,12 +65,12 @@ declare const _default: import("vue").DefineComponent<Props, {
|
|
|
65
65
|
reset: typeof handleReset;
|
|
66
66
|
getSlices: () => SliceRequestDef[];
|
|
67
67
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
68
|
-
"update:modelValue": (value: SliceRequestDef[]) => any;
|
|
69
68
|
search: () => any;
|
|
70
69
|
reset: () => any;
|
|
70
|
+
"update:modelValue": (value: SliceRequestDef[]) => any;
|
|
71
71
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
72
|
-
"onUpdate:modelValue"?: (value: SliceRequestDef[]) => any;
|
|
73
72
|
onSearch?: () => any;
|
|
74
73
|
onReset?: () => any;
|
|
74
|
+
"onUpdate:modelValue"?: (value: SliceRequestDef[]) => any;
|
|
75
75
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
76
76
|
export default _default;
|
|
@@ -33,13 +33,13 @@ declare const _default: import("vue").DefineComponent<Props, {
|
|
|
33
33
|
/** 获取当前筛选条件 */
|
|
34
34
|
getFilters: () => SliceRequestDef[];
|
|
35
35
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
36
|
-
"update:modelValue": (value: SliceRequestDef[]) => any;
|
|
37
36
|
search: () => any;
|
|
38
37
|
reset: () => any;
|
|
38
|
+
"update:modelValue": (value: SliceRequestDef[]) => any;
|
|
39
39
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
40
|
-
"onUpdate:modelValue"?: (value: SliceRequestDef[]) => any;
|
|
41
40
|
onSearch?: () => any;
|
|
42
41
|
onReset?: () => any;
|
|
42
|
+
"onUpdate:modelValue"?: (value: SliceRequestDef[]) => any;
|
|
43
43
|
}>, {
|
|
44
44
|
layout: "horizontal" | "vertical";
|
|
45
45
|
showActions: boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GlobalColumnRenderContext, GlobalColumnRenderResolution, GlobalColumnRenderer } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Global column renderer registry.
|
|
4
|
+
*
|
|
5
|
+
* Host applications register business-specific renderers once at startup.
|
|
6
|
+
* DataTable keeps page-level slots and customRender ahead of this registry.
|
|
7
|
+
*/
|
|
8
|
+
export declare const globalColumnRenderers: {
|
|
9
|
+
add(renderer: GlobalColumnRenderer): () => void;
|
|
10
|
+
register(renderers: GlobalColumnRenderer | GlobalColumnRenderer[]): () => void;
|
|
11
|
+
remove(id: string): void;
|
|
12
|
+
clear(): void;
|
|
13
|
+
list(): GlobalColumnRenderer[];
|
|
14
|
+
resolve(ctx: GlobalColumnRenderContext): GlobalColumnRenderer | undefined;
|
|
15
|
+
render(ctx: GlobalColumnRenderContext): GlobalColumnRenderResolution | undefined;
|
|
16
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AfterSearchHookFn, BeforeSearchHookFn, ErrorSearchHookFn, SearchHookName, SearchHooks } from '@/types';
|
|
2
|
+
import { SearchHookRegistry } from './searchHookRegistry';
|
|
3
|
+
type SearchHookFnMap = {
|
|
4
|
+
beforeSearch: BeforeSearchHookFn;
|
|
5
|
+
afterSearch: AfterSearchHookFn;
|
|
6
|
+
searchError: ErrorSearchHookFn;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Global search lifecycle hooks.
|
|
10
|
+
*
|
|
11
|
+
* These hooks run at the DataTableWithSearch action layer, before the final
|
|
12
|
+
* fetch/query lifecycle handled by globalQueryHooks.
|
|
13
|
+
*/
|
|
14
|
+
export declare const globalSearchHooks: {
|
|
15
|
+
add<N extends SearchHookName>(name: N, fn: SearchHookFnMap[N]): () => void;
|
|
16
|
+
remove<N extends SearchHookName>(name: N, fn: SearchHookFnMap[N]): void;
|
|
17
|
+
register(hooks: SearchHooks): () => void;
|
|
18
|
+
clear(): void;
|
|
19
|
+
_getRegistry(): SearchHookRegistry;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
@@ -6,5 +6,8 @@ export { useDeferredVisibility } from './useDeferredVisibility';
|
|
|
6
6
|
export type { DeferredVisibilityOptions, DeferredVisibilityState } from './useDeferredVisibility';
|
|
7
7
|
export { HookRegistry } from './hookRegistry';
|
|
8
8
|
export { globalQueryHooks } from './globalQueryHooks';
|
|
9
|
+
export { globalColumnRenderers } from './globalColumnRenderers';
|
|
10
|
+
export { SearchHookRegistry } from './searchHookRegistry';
|
|
11
|
+
export { globalSearchHooks } from './globalSearchHooks';
|
|
9
12
|
export { useQueryState } from './useQueryState';
|
|
10
13
|
export type { UseQueryStateReturn } from './useQueryState';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AfterSearchHookFn, BeforeSearchHookFn, ErrorSearchHookFn, FetchDataResult, SearchHookContext, SearchHookName, SearchHooks } from '@/types';
|
|
2
|
+
type SearchHookFnMap = {
|
|
3
|
+
beforeSearch: BeforeSearchHookFn;
|
|
4
|
+
afterSearch: AfterSearchHookFn;
|
|
5
|
+
searchError: ErrorSearchHookFn;
|
|
6
|
+
};
|
|
7
|
+
export declare class SearchHookRegistry {
|
|
8
|
+
private hooks;
|
|
9
|
+
add<N extends SearchHookName>(name: N, fn: SearchHookFnMap[N]): () => void;
|
|
10
|
+
remove<N extends SearchHookName>(name: N, fn: SearchHookFnMap[N]): void;
|
|
11
|
+
register(hooks: SearchHooks): () => void;
|
|
12
|
+
removeRegistered(hooks: SearchHooks): void;
|
|
13
|
+
size(name: SearchHookName): number;
|
|
14
|
+
clear(): void;
|
|
15
|
+
runBefore(ctx: SearchHookContext): Promise<void | false>;
|
|
16
|
+
runAfter(ctx: SearchHookContext, result: FetchDataResult): Promise<void>;
|
|
17
|
+
runError(ctx: SearchHookContext, error: Error): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -24,6 +24,7 @@ export interface UseTableQueryReturn {
|
|
|
24
24
|
currentOrderBy: ReturnType<typeof ref<OrderRequestDef[]>>;
|
|
25
25
|
currentSlice: ReturnType<typeof ref<SliceRequestDef[]>>;
|
|
26
26
|
currentColumns: ReturnType<typeof ref<string[]>>;
|
|
27
|
+
currentTableInstanceId: ReturnType<typeof ref<string | undefined>>;
|
|
27
28
|
loadData: (trigger?: QueryTrigger) => Promise<void>;
|
|
28
29
|
refresh: () => Promise<void>;
|
|
29
30
|
reload: () => Promise<void>;
|
|
@@ -31,6 +32,7 @@ export interface UseTableQueryReturn {
|
|
|
31
32
|
setSort: (orderBy: OrderRequestDef[]) => void;
|
|
32
33
|
setSlice: (slice: SliceRequestDef[]) => void;
|
|
33
34
|
setColumns: (columns: string[]) => void;
|
|
35
|
+
setTableInstanceId: (tableInstanceId?: string) => void;
|
|
34
36
|
addHook: <N extends QueryHookName>(name: N, fn: HookFnMap[N]) => () => void;
|
|
35
37
|
removeHook: <N extends QueryHookName>(name: N, fn: HookFnMap[N]) => void;
|
|
36
38
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,4 +26,5 @@ export { saveQuery, listSavedQueries, getSavedQuery, updateSavedQuery, deleteSav
|
|
|
26
26
|
export type { SavedQueryDef, SaveQueryRequest, QueryVisibility } from './api/savedQuery';
|
|
27
27
|
export { listPresets, getDefaultListPreset, createListPreset, getListPreset, updateListPreset, deleteListPreset, setDefaultListPreset, clearDefaultListPreset } from './api/listPreset';
|
|
28
28
|
export type { ListPresetScope, SaveListPresetRequest, UpdateListPresetRequest } from './api/listPreset';
|
|
29
|
-
export
|
|
29
|
+
export { getTableDefaultQueryConfig } from './api/tableDefaultQueryConfig';
|
|
30
|
+
export type { ColumnSchema, EnhancedColumnSchema, TableConfig, TableSchema, CellRenderContext, CellRenderFn, GlobalColumnRenderContext, GlobalColumnMatchFn, GlobalColumnRenderFn, GlobalColumnRenderer, GlobalColumnRenderResolution, CellCopyConfig, QueryMode, ColumnCustomization, QueryMetaResponse, ViewerQueryRequest, ViewerDataResponse, SliceRequestDef, OrderRequestDef, FilterOption, FetchDataParams, FetchDataResult, FetchDataFn, DictItem, PaginationState, SortState, QueryHooks, QueryHookContext, QueryTrigger, QueryHookName, BeforeQueryHookFn, AfterQueryHookFn, ErrorQueryHookFn, SearchSource, SearchTrigger, SearchHookContext, SearchHookUpdate, SearchHookName, BeforeSearchHookFn, AfterSearchHookFn, ErrorSearchHookFn, SearchHooks, MaybePromise, PivotAxisField, PivotAxisPage, PivotAxisPageScope, PivotAxisRole, PivotHeaderNode, PivotHeaderRole, PivotMetric, PivotRawAxisMember, PivotRawCell, PivotRawPayload, PivotShape, PivotViewMode, PivotViewModel, ListPresetVisibility, ListPresetPlacement, ListPresetConfig, TableDefaultQueryConfig, TableDefaultQueryConfigScope, TableDefaultQueryConfigLoadOptions, TableDefaultQueryConfigSource, ColumnViewSetting, QueryConditionPreset, ListViewState, ListPresetDef, FrontendMeta, FieldMeta, FieldCategory, MemberLookupMeta, UiHintsMeta, DefaultsMeta, CapabilitiesMeta, ParamsMeta, MemberQueryRequest, MemberOption, MemberQueryResponse } from './types';
|