Skip to content

@ahoo-wang/fetcher-viewer

@ahoo-wang/fetcher-viewer 包提供了一个 React + Ant Design 组件库,用于构建数据查看界面。它包含带类型化注册表的过滤面板组件、带丰富单元格渲染器的表格组件、支持保存/加载的视图管理、带操作项的顶部栏,以及一个完整的 FetcherViewer 组件,通过 Wow CQRS 查询将所有功能整合在一起。

安装

bash
pnpm add @ahoo-wang/fetcher-viewer

组件架构

mermaid
graph TB
    subgraph sg_1 ["FetcherViewer"]
        direction TB
        FV["FetcherViewer<br>top-level orchestrator"]
        V["Viewer<br>view + table + filters"]
        VT["ViewTable<br>Ant Design Table wrapper"]
        FP["FilterPanel<br>filter composition"]
        TB["TopBar<br>action bar"]
    end

    subgraph sg_2 ["Filter System"]
        direction LR
        TF["TypedFilter<br>type-based dispatch"]
        FR["filterRegistry<br>type -> component map"]
        FF["FilterField<br>id, text, number, select, bool, dateTime"]
    end

    subgraph sg_3 ["Cell System"]
        direction LR
        TC["TypedCell<br>type-based dispatch"]
        CR["cellRegistry<br>type -> component map"]
        CELLS["TextCell, TagCell, ImageCell,<br>DateTimeCell, CurrencyCell, ..."]
    end

    subgraph sg_4 ["View Management"]
        direction LR
        VP["ViewPanel<br>view list sidebar"]
        SVM["SaveViewModal<br>create/edit views"]
        VMM["ViewManageModal<br>manage saved views"]
    end

    FV --> V
    V --> VT
    V --> FP
    V --> TB
    FP --> TF
    TF --> FR
    FR --> FF
    VT --> TC
    TC --> CR
    CR --> CELLS
    V --> VP
    VP --> SVM
    VP --> VMM

    style FV fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style V fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style VT fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style FP fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style TB fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style TF fill:#161b22,stroke:#30363d,color:#e6edf3
    style FR fill:#161b22,stroke:#30363d,color:#e6edf3
    style FF fill:#161b22,stroke:#30363d,color:#e6edf3
    style TC fill:#161b22,stroke:#30363d,color:#e6edf3
    style CR fill:#161b22,stroke:#30363d,color:#e6edf3
    style CELLS fill:#161b22,stroke:#30363d,color:#e6edf3
    style VP fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style SVM fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style VMM fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

FetcherViewer

顶层组件,负责协调视图定义加载、视图状态管理、通过 Wow 进行数据获取以及渲染完整的查看器 UI。

tsx
import { FetcherViewer } from '@ahoo-wang/fetcher-viewer';

function DataView() {
  return (
    <FetcherViewer
      viewerDefinitionId="order-view"
      pagination={{ pageSize: 20 }}
      enableRowSelection
      primaryAction={{
        label: 'Create Order',
        onClick: () => router.push('/orders/new'),
      }}
    />
  );
}

FetcherViewerProps

属性类型默认值描述
viewerDefinitionIdstring(必填)要加载的查看器定义 ID
ownerIdstring'(0)'数据范围的所有者 ID
tenantIdstring'(0)'数据范围的租户 ID
defaultViewIdstring--默认激活的视图
paginationfalse | PaginationProps--分页配置,设为 false 可禁用分页
actionColumnViewTableActionColumn--行操作列配置
onClickPrimaryKey(id, record) => void--主键单元格的点击处理器
enableRowSelectionbooleanfalse启用复选框行选择
enhanceDataSource(data) => data--转换/增强获取的数据
onSwitchView(view) => void--切换视图时的回调
viewTableSettingViewTableSettingCapable--表格显示设置
primaryActionaction object--顶部栏中的主要操作按钮
secondaryActionsaction array--次要操作按钮
batchActionsaction array--选中行的批量操作

来源: packages/viewer/src/fetcherviewer/FetcherViewer.tsx:48-71

FetcherViewer 数据流

mermaid
sequenceDiagram
autonumber

    participant FV as FetcherViewer
    participant VD as useViewerDefinition
    participant VV as useViewerViews
    participant FD as useFetchData
    participant API as Wow Server
    participant V as Viewer

    FV->>VD: load definition
    VD->>API: GET /viewer-definitions/{id}
    API-->>VD: ViewDefinition

    FV->>VV: load views
    VV->>API: Query viewer views
    API-->>VV: ViewState[]

    FV->>FD: fetchData(viewDefinition, defaultView)
    FD->>API: POST /snapshot/paged (with conditions)
    API-->>FD: PagedList<RecordType>

    FV->>V: Render Viewer component
    V->>V: ViewTable + FilterPanel + TopBar + ViewPanel

来源: packages/viewer/src/fetcherviewer/FetcherViewer.tsx:75-377

过滤系统

类型化过滤器注册表

过滤器通过类型使用注册表模式进行分发。TypedFilter 组件从注册表中查找对应的过滤器组件:

mermaid
graph LR
    subgraph sg_1 ["filterRegistry"]
        direction TB
        id["id -> IdFilter"]
        text["text -> TextFilter"]
        number["number -> NumberFilter"]
        select["select -> SelectFilter"]
        bool["bool -> BoolFilter"]
        dateTime["dateTime -> DateTimeFilter"]
    end

    TF["TypedFilter<br>type-based dispatch"] --> filterRegistry

    style TF fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style id fill:#161b22,stroke:#30363d,color:#e6edf3
    style text fill:#161b22,stroke:#30363d,color:#e6edf3
    style number fill:#161b22,stroke:#30363d,color:#e6edf3
    style select fill:#161b22,stroke:#30363d,color:#e6edf3
    style bool fill:#161b22,stroke:#30363d,color:#e6edf3
    style dateTime fill:#161b22,stroke:#30363d,color:#e6edf3
过滤器类型组件描述
idIdFilter聚合 ID 输入
textTextFilter带运算符选择的文本输入
numberNumberFilter支持范围的数值输入
selectSelectFilter带选项的下拉选择
boolBoolFilter布尔值开关/复选框
dateTimeDateTimeFilter支持范围的日期/时间选择器

来源: packages/viewer/src/filter/filterRegistry.ts:73-83

FilterPanel 组件

组件描述
FilterPanel显示一组活跃过滤器
EditableFilterPanel动态添加/移除过滤器
AvailableFilterSelect下拉选择要添加的过滤字段
AvailableFilterSelectModal过滤字段选择的弹窗版本
RemovableTypedFilter带移除按钮的单个过滤器

来源: packages/viewer/src/filter/panel/

过滤器 Props

每个过滤器组件接收标准化的 props:

typescript
interface FilterProps {
  field: FilterField;           // { name, label, type, format }
  label?: FilterLabelProps;     // Label display configuration
  operator?: FilterOperatorProps; // Operator selection (null to hide)
  value?: FilterValueProps;     // Value input configuration
  onChange?: (value?: FilterValue) => void; // Change callback
  conditionOptions?: ConditionOptions; // Condition building options
}

来源: packages/viewer/src/filter/types.ts:59-69

表格单元格系统

类型化单元格注册表

表格单元格通过类型使用与过滤器相同的注册表模式进行分发:

单元格类型组件描述
textTextCell支持省略号的纯文本显示
tagTagCell单个 Ant Design 标签
tagsTagsCell多个 Ant Design 标签
dateTimeDateTimeCell格式化的日期/时间显示
calendarCalendarTimeCell基于日历的时间显示
imageImageCell带缩略图的图片预览
imageGroupImageGroupCell图片预览组
linkLinkCell可点击链接
currencyCurrencyCell格式化的货币显示
avatarAvatarCell用户头像显示
primaryKeyPrimaryKeyCell可点击的主键单元格
actionActionCell单个操作按钮
actionsActionsCell多个操作按钮

来源: packages/viewer/src/table/cell/cellRegistry.ts:67-82

CellProps 接口

所有单元格组件接收标准化的 props:

typescript
interface CellProps<ValueType, RecordType, Attributes> {
  data: {
    value: ValueType;     // The cell value to display
    record: RecordType;   // The full row record
    index: number;        // Row index
  };
  attributes?: Attributes; // Component-specific attributes
}

来源: packages/viewer/src/table/cell/types.ts:100-106

ViewTable

ViewTable 组件封装了 Ant Design 的 Table,并与查看器定义集成,从视图字段配置自动生成列。支持:

  • 通过 TypedCell 自动分发单元格类型
  • 可排序列
  • 列可见性配置
  • 表格设置面板,用于字段排序和可见性管理
  • 行选择
  • 操作列

来源: packages/viewer/src/table/ViewTable.tsx

视图管理

mermaid
stateDiagram-v2
    [*] --> LoadingDef: FetcherViewer mounts
    LoadingDef --> LoadingViews: Definition loaded
    LoadingViews --> Active: Views loaded, default selected
    Active --> Active: Switch view
    Active --> Active: Create view
    Active --> Active: Edit view
    Active --> Active: Delete view
    Active --> Active: Update filters
    Active --> Active: Change page

    state Active {
        [*] --> Viewing
        Viewing --> FilterEditing: Open filter panel
        FilterEditing --> Viewing: Apply filters
        Viewing --> SaveModal: Save as new view
        SaveModal --> Viewing: View saved
    }

视图状态

每个视图(ViewState)持久化保存:

  • 活跃的过滤条件
  • 排序配置
  • 列可见性和排序
  • 视图名称和类型(PRIVATE/SHARED)
  • 默认视图标志

视图通过 Wow 命令操作进行管理,使用 ViewCommandClient

  • createView -- 创建新视图
  • editView -- 更新已有视图
  • deleteAggregate -- 删除视图

来源: packages/viewer/src/fetcherviewer/client/view/commandClient.ts

TopBar 组件

顶部栏在数据表格上方提供操作项:

组件描述
TopBar栏项容器
BarItem基础栏项组件
RefreshDataBarItem手动数据刷新按钮
AutoRefreshBarItem带间隔的自动刷新开关
FilterBarItem切换过滤面板可见性
FullscreenBarItem切换全屏模式
ColumnHeightBarItem调整表格行密度
DataMonitorBarItem数据监控指示器
ShareLinkBarItem复制可分享的视图链接

来源: packages/viewer/src/topbar/

独立组件

viewer 包还导出了可复用的 UI 组件:

组件描述
NumberRange用于范围过滤的双数值输入
RemoteSelect带远程数据获取的选择器
TagInput用于管理标签集合的输入框
Fullscreen全屏容器封装

来源: packages/viewer/src/components/

注册表模式

过滤器和单元格都使用共享的 TypedComponentRegistry<T, P> 模式:

typescript
import { TypedComponentRegistry } from '@ahoo-wang/fetcher-viewer';

// Create a custom registry
const myRegistry = TypedComponentRegistry.create<string, MyProps>([
  ['type1', MyComponent1],
  ['type2', MyComponent2],
]);

// Register additional types
myRegistry.register('type3', MyComponent3);

// Look up
const Component = myRegistry.get('type1');

来源: packages/viewer/src/registry/componentRegistry.ts

Storybook 集成

viewer 包包含全面的 Storybook stories,用于可视化开发和测试:

bash
pnpm storybook

Stories 与组件并列组织在 stories/ 目录中:

  • 过滤器组件: filter/stories/filter/panel/stories/
  • 单元格组件: table/cell/stories/
  • 表格组件: table/stories/table/setting/stories/
  • 顶部栏组件: topbar/stories/
  • 查看器组件: viewer/stories/view/stories/
  • FetcherViewer: fetcherviewer/stories/
  • 独立组件: components/stories/

主要导出

导出模块描述
FetcherViewerfetcherviewer/顶层查看器协调器
Viewerviewer/视图 + 表格 + 过滤器组合
Viewview/单个视图容器
ViewTabletable/带类型化单元格的 Ant Design 表格
TypedFilterfilter/按类型分发的过滤器组件
filterRegistryfilter/过滤器组件注册表
TypedCelltable/cell/按类型分发的单元格组件
cellRegistrytable/cell/单元格组件注册表
TopBartopbar/操作栏容器
FilterPanelfilter/panel/活跃过滤器显示
EditableFilterPanelfilter/panel/动态过滤器编辑器
ViewPanelviewer/panel/视图列表侧边栏
SaveViewModalviewer/panel/保存/编辑视图弹窗
TypedComponentRegistryregistry/通用类型化组件注册表
NumberRangecomponents/双数值范围输入
RemoteSelectcomponents/远程数据选择器
TagInputcomponents/标签管理输入框

交叉引用

  • Wow -- FetcherViewer 使用 Wow SnapshotQueryClient 进行数据获取,使用 CommandClient 进行视图管理
  • React -- 使用 React 包中的 useFetcheruseKeyStorageuseEventSubscription Hooks
  • Fetcher -- 用于所有 API 通信的核心 HTTP 客户端
  • Storage -- KeyStorage 用于持久化本地默认视图 ID
  • CoSec -- 通过 owner/tenant ID 支持多租户数据范围

基于 Apache License 2.0 发布。