Models and state ownership
Maintenance mode (deprecated)
@ahoo-wang/fetcher-viewer is deprecated and in maintenance mode: existing functionality is maintained, with no new features. Further data-view development belongs to @ahoo-wang/fetcher-view-engine; use View Engine for new projects. This page remains a maintenance reference for existing consumers. The packages use different models and APIs, so migration requires adaptation.
A ViewDefinition describes the fields and available filters for a data endpoint; ViewState describes one saved arrangement of that definition. The root package's model is ViewDefinition/ViewState; an unrelated view-engine package is not part of this API.
| Model | Required meaning |
|---|---|
| ViewDefinition | id/name, fields, availableFilters, dataUrl and countUrl; URLs are used by remote integrations, not automatically by View. |
| FieldDefinition | name (dotted data path), label, type, primaryKey; optional render(value,record,index), sorter and attributes. |
| ViewState | id/name/definitionId, type PERSONAL or SHARED, source SYSTEM or CUSTOM, isDefault, filters, columns, tableSize, pageSize, condition and sorter. Optional internalCondition is combined by remote data loading. |
| ViewColumn | key/name, fixed/hidden, optional width and sortOrder; presentation references a FieldDefinition by name. |
| ActionItem / TopBarActionItem | title, onClick(records), optional render(records) and Button attributes. |
| ViewMutationAction | (view, onSuccess?) => void; completion is callback-based, not an awaited Promise contract. |
State hooks
useActiveViewState initializes local state: page 1, pageSize 10, tableSize middle, condition all(), sorter []. Columns/activeFilters are required. Setters shallow-copy lists/items and condition; reset restores defaults. Later default-prop changes are not automatically controlled state updates.
useViewState composes that state with external* values and matching externalUpdate* callbacks. External values and setters are selected independently with nullish coalescing: provide both to implement a genuinely controlled dimension. A value without its external setter remains visually controlled while mutations write unused internal state. setCondition/setSorter reset page to 1 and invoke onChange; setPagination emits one change for page and size. Column/table-size changes do not fetch data. reset updates each external dimension and calls onChange once with defaults.
useViewerState additionally tracks activeView, saved views, showFilter/showViewPanel (both default true), and viewChanged against the selected baseline. Switching view resets page to 1 and restores view fields; missing definition fields are appended as visible 180px columns. reset returns the baseline ViewState. setViews manages its internal list; constructor defaults are not a fully controlled saved-view store.
mapToTableRecord returns cloned rows with key chosen from explicit primary-key path, existing key, then row index; empty input returns []. Prefer a real stable primary key across refreshes. deepEqual handles primitives, arrays, dates, regexps and enumerable object keys; it is not a cycle-safe arbitrary-object comparator. format substitutes each %@ sequentially, using empty text for missing arguments. These utilities neither fetch nor persist data.
Definition fields versus a saved arrangement
A definition is the available schema for one viewer. A saved view selects and arranges it. Give the saved view definitionId matching definition.id; this local model does not enforce that relationship at runtime. Identity validation during remote create/update belongs specifically to FetcherViewer.
| Field | Meaning and constraints |
|---|---|
definition.fields | Declares column metadata. name is a dotted data path, type selects a cell renderer, primaryKey identifies row keys. |
definition.availableFilters | Catalog grouped for filter selection; the saved view's filters contains the chosen ActiveFilter instances and initial UI values. |
definition.dataUrl / countUrl | Required strings in the model. View never calls them; FetcherViewer uses dataUrl, monitoring/count controls can use countUrl. |
view.columns | Ordered names/keys with required fixed/hidden flags; optional width is a string and sortOrder uses Ant Design values. |
view.condition / sorter | Current legacy Wow query values. filters stores UI configuration as well; a raw value can exist before a valid condition does. |
view.internalCondition? | Additional constraint ANDed by the remote loader. It is not a client-enforced permission boundary. |
view.pageSize / tableSize | Saved page size / visual density; no runtime defaults in ViewState itself. State-hook defaults are documented separately below. |
view.type / source / isDefault | PERSONAL/SHARED, SYSTEM/CUSTOM and default-selection flag. These classify views; they are not authentication claims. |
FieldDefinition.sorter? | Boolean, multiple-sort priority object or null; the table reports sort changes and the data owner applies sorting. |
FieldDefinition.attributes? / render? | Pass-through column attributes / custom renderer. They can override generated rendering settings; treat callbacks as application code. |
Use the complete local example to see a definition, ViewState, query callback and persistence acknowledgement together.
Complete example
import { useActiveViewState } from '@ahoo-wang/fetcher-viewer';
export function PageControls() {
const state = useActiveViewState({
defaultColumns: [],
defaultActiveFilters: [],
});
return (
<section>
<button onClick={() => state.setPage(state.page + 1)}>
Page {state.page}
</button>
<button onClick={state.reset}>Reset</button>
</section>
);
}Public signatures and types
These signatures follow declarations reachable from the current root entry. ? marks optional input; generics/interfaces only constrain compile-time types. Locate inherited and related types through the symbol index. Runtime defaults and failure behavior are described above.
Definition and saved-view contracts
ViewDefinition
export interface ViewDefinition {
id: string;
name: string;
fields: FieldDefinition[];
availableFilters: AvailableFilterGroup[];
dataUrl: string;
countUrl: string;
}packages/viewer/src/viewer/types.ts:15
FieldDefinition
export interface FieldDefinition
extends NamedCapable, TypeCapable, AttributesCapable {
label: string;
primaryKey: boolean;
render?: (value: any, record: any, index: number) => React.ReactNode;
sorter?:
| boolean
| {
multiple: number;
}
| null;
}packages/viewer/src/viewer/types.ts:24
ViewType
export type ViewType = 'PERSONAL' | 'SHARED';packages/viewer/src/viewer/types.ts:32
ViewSource
export type ViewSource = 'SYSTEM' | 'CUSTOM';packages/viewer/src/viewer/types.ts:33
ViewState
export interface ViewState {
id: string;
name: string;
definitionId: string;
type: ViewType;
source: ViewSource;
isDefault: boolean;
filters: ActiveFilter[];
columns: ViewColumn[];
tableSize: SizeType;
pageSize: number;
condition: Condition;
internalCondition?: Condition;
sorter: FieldSort[];
}packages/viewer/src/viewer/types.ts:35
ViewColumn
export interface ViewColumn extends NamedCapable, KeyCapable {
fixed: boolean;
hidden: boolean;
width?: string;
sortOrder?: SortOrder;
}packages/viewer/src/viewer/types.ts:51
Application actions and persistence
ViewMutationAction
export type ViewMutationAction = (
view: ViewState,
onSuccess?: (newView: ViewState) => void,
) => void;packages/viewer/src/viewer/types.ts:65
ViewMutationActionsCapable
export interface ViewMutationActionsCapable {
onCreateView?: ViewMutationAction;
onUpdateView?: ViewMutationAction;
onDeleteView?: ViewMutationAction;
}packages/viewer/src/viewer/types.ts:86
GetRecordCountAction
export type GetRecordCountAction = (
countUrl: string,
condition: Condition,
) => Promise<number>;packages/viewer/src/viewer/types.ts:60
GetRecordCountActionCapable
export interface GetRecordCountActionCapable {
onGetRecordCount?: GetRecordCountAction;
}packages/viewer/src/viewer/types.ts:82
TopBarActionItem
export interface TopBarActionItem<RecordType> extends ActionItem<RecordType> {}packages/viewer/src/viewer/types.ts:58
BatchActionsConfig
export interface BatchActionsConfig<RecordType> {
enabled: boolean;
title: string;
actions: TopBarActionItem<RecordType>[];
}packages/viewer/src/viewer/types.ts:70
TopbarActionsCapable
export interface TopbarActionsCapable<RecordType> {
primaryAction?: TopBarActionItem<RecordType>;
secondaryActions?: TopBarActionItem<RecordType>[];
batchActions?: BatchActionsConfig<RecordType>;
}packages/viewer/src/viewer/types.ts:76
State hooks and controlled dimensions
useActiveViewState
export function useActiveViewState(
options: UseActiveViewStateOptions,
): UseActiveViewStateReturn;Implementation defaults: defaultPage = 1; defaultPageSize = 10; defaultTableSize = 'middle'; defaultCondition = DEFAULT_CONDITION; defaultSorter = [].
packages/viewer/src/hooks/useActiveViewState.ts:43
DEFAULT_CONDITION
declare const DEFAULT_CONDITION: Condition<string>;packages/viewer/src/hooks/useActiveViewState.ts:8
UseActiveViewStateOptions
export interface UseActiveViewStateOptions {
defaultColumns: ViewColumn[];
defaultActiveFilters: ActiveFilter[];
defaultCondition?: Condition;
defaultPage?: number;
defaultPageSize?: number;
defaultSorter?: FieldSort[];
defaultTableSize?: SizeType;
}packages/viewer/src/hooks/useActiveViewState.ts:10
UseActiveViewStateReturn
export interface UseActiveViewStateReturn {
columns: ViewColumn[];
setColumns: (columns: ViewColumn[]) => void;
activeFilters: ActiveFilter[];
setActiveFilters: (filters: ActiveFilter[]) => void;
condition: Condition;
setCondition: (condition: Condition) => void;
page: number;
setPage: (page: number) => void;
pageSize: number;
setPageSize: (size: number) => void;
sorter: FieldSort[];
setSorter: (sorter: FieldSort[]) => void;
tableSize: SizeType;
setTableSize: (size: SizeType) => void;
reset: () => void;
}packages/viewer/src/hooks/useActiveViewState.ts:22
useViewState
export function useViewState(options: UseViewStateOptions): UseViewStateReturn;Implementation defaults: defaultPage = DEFAULT_PAGE; defaultPageSize = DEFAULT_PAGE_SIZE.
packages/viewer/src/view/hooks/useViewState.ts:219
ViewChangeAction
export type ViewChangeAction = (
condition: Condition,
index: number,
size: number,
sorter?: FieldSort[],
) => void;packages/viewer/src/view/hooks/useViewState.ts:32
UseViewStateOptions
Expand all fields and members
export interface UseViewStateOptions {
defaultColumns: ViewColumn[];
externalColumns?: ViewColumn[];
externalUpdateColumns?: (columns: ViewColumn[]) => void;
defaultActiveFilters?: ActiveFilter[];
externalActiveFilters?: ActiveFilter[];
externalUpdateActiveFilters?: (filters: ActiveFilter[]) => void;
defaultPage?: number;
externalPage?: number;
externalUpdatePage?: (page: number) => void;
defaultPageSize: number;
externalPageSize?: number;
externalUpdatePageSize?: (pageSize: number) => void;
defaultCondition?: Condition;
externalCondition?: Condition;
externalUpdateCondition?: (
finalCondition: Condition,
activeFilterValues: Map<Key, Condition>,
filterStates: Map<Key, FilterState>,
resetFilters?: ActiveFilter[],
) => void;
defaultSorter?: FieldSort[];
externalSorter?: FieldSort[];
externalUpdateSorter?: (sorter: FieldSort[]) => void;
defaultTableSize: SizeType;
externalTableSize?: SizeType;
externalUpdateTableSize?: (size: SizeType) => void;
onChange?: ViewChangeAction;
}packages/viewer/src/view/hooks/useViewState.ts:65
UseViewStateReturn
Expand all fields and members
export interface UseViewStateReturn {
columns: ViewColumn[];
setColumns: (columns: ViewColumn[]) => void;
activeFilters: ActiveFilter[];
setActiveFilters: (filters: ActiveFilter[]) => void;
page: number;
setPage: (page: number) => void;
pageSize: number;
setPageSize: (pageSize: number) => void;
setPagination: (page: number, pageSize: number) => void;
condition: Condition;
setCondition: (
finalCondition: Condition,
activeFilterValues: Map<Key, Condition>,
filterStates: Map<Key, FilterState>,
) => void;
sorter: FieldSort[];
setSorter: (sorter: FieldSort[]) => void;
tableSize: SizeType;
setTableSize: (size: SizeType) => void;
selectedCount: number;
updateSelectedCount: (count: number) => void;
reset: () => void;
}packages/viewer/src/view/hooks/useViewState.ts:127
useViewerState
export function useViewerState(
options: UseViewerStateOptions,
): UseViewerStateReturn;Implementation defaults: defaultShowFilter = true; defaultShowViewPanel = true.
packages/viewer/src/viewer/hooks/useViewerState.ts:77
UseViewerStateOptions
export interface UseViewerStateOptions {
views: ViewState[];
defaultView: ViewState;
definition: ViewDefinition;
defaultShowFilter?: boolean;
defaultShowViewPanel?: boolean;
}packages/viewer/src/viewer/hooks/useViewerState.ts:33
UseViewerStateReturn
Expand all fields and members
export interface UseViewerStateReturn {
activeView: ViewState;
showFilter: boolean;
setShowFilter: (showFilter: boolean) => void;
showViewPanel: boolean;
setShowViewPanel: (showViewPanel: boolean) => void;
viewChanged: boolean;
columns: ViewColumn[];
setColumns: (columns: ViewColumn[]) => void;
activeFilters: ActiveFilter[];
setActiveFilters: (filters: ActiveFilter[]) => void;
condition: Condition;
setCondition: (
finalCondition: Condition,
activeFilterValues: Map<Key, Condition>,
filterStates: Map<Key, FilterState>,
resetFilters?: ActiveFilter[],
) => void;
page: number;
setPage: (page: number) => void;
pageSize: number;
setPageSize: (size: number) => void;
sorter: FieldSort[];
setSorter: (sorter: FieldSort[]) => void;
tableSize: SizeType;
setTableSize: (size: SizeType) => void;
views: ViewState[];
setViews: (views: ViewState[]) => void;
onSwitchView: (view: ViewState) => void;
reset: () => ViewState;
}packages/viewer/src/viewer/hooks/useViewerState.ts:41
Presentation types and utilities
Optional
export type Optional<T = any> = T | undefined;packages/viewer/src/types.ts:19
DataSourceCapable
export interface DataSourceCapable<RecordType = any> {
list: RecordType[];
total: number;
}packages/viewer/src/types.ts:21
StyleCapable
export interface StyleCapable {
style?: React.CSSProperties;
className?: string;
}packages/viewer/src/types.ts:26
AttributesCapable
export interface AttributesCapable<Attributes = any> {
attributes?: Attributes;
}packages/viewer/src/types.ts:31
PrimaryKeyClickHandlerCapable
export interface PrimaryKeyClickHandlerCapable<RecordType = any> {
onClickPrimaryKey?: (id: any, record: RecordType) => void;
}packages/viewer/src/types.ts:35
ViewTableSetting
export interface ViewTableSetting {
title?: string;
}packages/viewer/src/types.ts:39
ViewTableSettingCapable
export interface ViewTableSettingCapable {
viewTableSetting?: false | ViewTableSetting;
}packages/viewer/src/types.ts:43
TableSizeCapable
export interface TableSizeCapable {
tableSize?: SizeType;
}packages/viewer/src/types.ts:47
KeyCapable
export interface KeyCapable {
key: Key;
}packages/viewer/src/types.ts:51
ReducerActionCapable
export interface ReducerActionCapable<TYPE = any> {
type: TYPE;
payload: any;
}packages/viewer/src/types.ts:55
TableRecordType
export type TableRecordType<RecordType> = RecordType & KeyCapable;packages/viewer/src/types.ts:60
ActionItem
export interface ActionItem<RecordType> extends AttributesCapable<
Omit<ButtonProps, 'onClick'>
> {
title: string;
onClick: (records: RecordType[]) => void;
render?: (records: RecordType[]) => React.ReactNode;
}packages/viewer/src/types.ts:62
SaveViewMethod
export type SaveViewMethod = 'Update' | 'SaveAs';packages/viewer/src/types.ts:70
deepEqual
export function deepEqual(left: any, right: any): boolean;packages/viewer/src/utils.ts:34
mapToTableRecord
export function mapToTableRecord<RecordType = any>(
dataSource: RecordType[] | undefined,
primaryKey?: string,
): TableRecordType<RecordType>[];packages/viewer/src/utils.ts:112
format
export function format(str: string, ...args: any[]): string;packages/viewer/src/utils.ts:137
Related topics
View and Viewer composition · Saved-view panels and persistence callbacks · FetcherViewer remote integration · Filters and editable panels · Tables, columns and cells · Registries, inputs and fullscreen button · Toolbar, refresh and locale
