@ahoo-wang/wow-view-engine 9.2.0-rc.0
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/LICENSE +201 -0
- package/README.md +1182 -0
- package/README.zh-CN.md +1171 -0
- package/THIRD_PARTY_NOTICES.md +196 -0
- package/dist/actions-DK1yfiI8.js +9986 -0
- package/dist/actions-DK1yfiI8.js.map +1 -0
- package/dist/analysis/boxplot.d.ts +80 -0
- package/dist/analysis/boxplot.d.ts.map +1 -0
- package/dist/analysis/bucketChange.d.ts +25 -0
- package/dist/analysis/bucketChange.d.ts.map +1 -0
- package/dist/analysis/budget.d.ts +37 -0
- package/dist/analysis/budget.d.ts.map +1 -0
- package/dist/analysis/candidates.d.ts +96 -0
- package/dist/analysis/candidates.d.ts.map +1 -0
- package/dist/analysis/candlestick.d.ts +73 -0
- package/dist/analysis/candlestick.d.ts.map +1 -0
- package/dist/analysis/capability.d.ts +129 -0
- package/dist/analysis/capability.d.ts.map +1 -0
- package/dist/analysis/cartesian.d.ts +102 -0
- package/dist/analysis/cartesian.d.ts.map +1 -0
- package/dist/analysis/chart.d.ts +108 -0
- package/dist/analysis/chart.d.ts.map +1 -0
- package/dist/analysis/chartFamilies.d.ts +175 -0
- package/dist/analysis/chartFamilies.d.ts.map +1 -0
- package/dist/analysis/chartOptions.d.ts +113 -0
- package/dist/analysis/chartOptions.d.ts.map +1 -0
- package/dist/analysis/chartRefs.d.ts +31 -0
- package/dist/analysis/chartRefs.d.ts.map +1 -0
- package/dist/analysis/chartRows.d.ts +39 -0
- package/dist/analysis/chartRows.d.ts.map +1 -0
- package/dist/analysis/chartSlots.d.ts +73 -0
- package/dist/analysis/chartSlots.d.ts.map +1 -0
- package/dist/analysis/chartSwitch.d.ts +34 -0
- package/dist/analysis/chartSwitch.d.ts.map +1 -0
- package/dist/analysis/compile.d.ts +55 -0
- package/dist/analysis/compile.d.ts.map +1 -0
- package/dist/analysis/currency.d.ts +68 -0
- package/dist/analysis/currency.d.ts.map +1 -0
- package/dist/analysis/dangling.d.ts +52 -0
- package/dist/analysis/dangling.d.ts.map +1 -0
- package/dist/analysis/defaults.d.ts +168 -0
- package/dist/analysis/defaults.d.ts.map +1 -0
- package/dist/analysis/derived.d.ts +81 -0
- package/dist/analysis/derived.d.ts.map +1 -0
- package/dist/analysis/drill.d.ts +142 -0
- package/dist/analysis/drill.d.ts.map +1 -0
- package/dist/analysis/drillFilter.d.ts +34 -0
- package/dist/analysis/drillFilter.d.ts.map +1 -0
- package/dist/analysis/expand.d.ts +51 -0
- package/dist/analysis/expand.d.ts.map +1 -0
- package/dist/analysis/expressions.d.ts +12 -0
- package/dist/analysis/expressions.d.ts.map +1 -0
- package/dist/analysis/fitCharts.d.ts +93 -0
- package/dist/analysis/fitCharts.d.ts.map +1 -0
- package/dist/analysis/formula.d.ts +65 -0
- package/dist/analysis/formula.d.ts.map +1 -0
- package/dist/analysis/funnel.d.ts +48 -0
- package/dist/analysis/funnel.d.ts.map +1 -0
- package/dist/analysis/gauge.d.ts +34 -0
- package/dist/analysis/gauge.d.ts.map +1 -0
- package/dist/analysis/granularity.d.ts +22 -0
- package/dist/analysis/granularity.d.ts.map +1 -0
- package/dist/analysis/having.d.ts +38 -0
- package/dist/analysis/having.d.ts.map +1 -0
- package/dist/analysis/hierarchy.d.ts +73 -0
- package/dist/analysis/hierarchy.d.ts.map +1 -0
- package/dist/analysis/index.d.ts +29 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/logScale.d.ts +20 -0
- package/dist/analysis/logScale.d.ts.map +1 -0
- package/dist/analysis/map.d.ts +28 -0
- package/dist/analysis/map.d.ts.map +1 -0
- package/dist/analysis/metricCard.d.ts +155 -0
- package/dist/analysis/metricCard.d.ts.map +1 -0
- package/dist/analysis/metricCondition.d.ts +41 -0
- package/dist/analysis/metricCondition.d.ts.map +1 -0
- package/dist/analysis/metricFormat.d.ts +136 -0
- package/dist/analysis/metricFormat.d.ts.map +1 -0
- package/dist/analysis/metricOrder.d.ts +47 -0
- package/dist/analysis/metricOrder.d.ts.map +1 -0
- package/dist/analysis/metricWindow.d.ts +28 -0
- package/dist/analysis/metricWindow.d.ts.map +1 -0
- package/dist/analysis/profiles.d.ts +53 -0
- package/dist/analysis/profiles.d.ts.map +1 -0
- package/dist/analysis/project.d.ts +242 -0
- package/dist/analysis/project.d.ts.map +1 -0
- package/dist/analysis/queryFilter.d.ts +32 -0
- package/dist/analysis/queryFilter.d.ts.map +1 -0
- package/dist/analysis/references.d.ts +41 -0
- package/dist/analysis/references.d.ts.map +1 -0
- package/dist/analysis/splitOther.d.ts +80 -0
- package/dist/analysis/splitOther.d.ts.map +1 -0
- package/dist/analysis/timeAxis.d.ts +173 -0
- package/dist/analysis/timeAxis.d.ts.map +1 -0
- package/dist/analysis/timeCharts.d.ts +76 -0
- package/dist/analysis/timeCharts.d.ts.map +1 -0
- package/dist/analysis/treemap.d.ts +36 -0
- package/dist/analysis/treemap.d.ts.map +1 -0
- package/dist/analysis/validate.d.ts +19 -0
- package/dist/analysis/validate.d.ts.map +1 -0
- package/dist/analysis/validateAliases.d.ts +16 -0
- package/dist/analysis/validateAliases.d.ts.map +1 -0
- package/dist/analysis/validateChart.d.ts +60 -0
- package/dist/analysis/validateChart.d.ts.map +1 -0
- package/dist/analysis/validateElements.d.ts +20 -0
- package/dist/analysis/validateElements.d.ts.map +1 -0
- package/dist/analysis/validateGroups.d.ts +5 -0
- package/dist/analysis/validateGroups.d.ts.map +1 -0
- package/dist/analysis/validateHaving.d.ts +9 -0
- package/dist/analysis/validateHaving.d.ts.map +1 -0
- package/dist/analysis/validateLevels.d.ts +33 -0
- package/dist/analysis/validateLevels.d.ts.map +1 -0
- package/dist/analysis/validateLimits.d.ts +3 -0
- package/dist/analysis/validateLimits.d.ts.map +1 -0
- package/dist/analysis/validateMetrics.d.ts +5 -0
- package/dist/analysis/validateMetrics.d.ts.map +1 -0
- package/dist/analysis/validateOffers.d.ts +12 -0
- package/dist/analysis/validateOffers.d.ts.map +1 -0
- package/dist/analysis/validateReferences.d.ts +16 -0
- package/dist/analysis/validateReferences.d.ts.map +1 -0
- package/dist/analysis/validateShape.d.ts +14 -0
- package/dist/analysis/validateShape.d.ts.map +1 -0
- package/dist/analysis/validateSort.d.ts +3 -0
- package/dist/analysis/validateSort.d.ts.map +1 -0
- package/dist/analysis/waterfall.d.ts +33 -0
- package/dist/analysis/waterfall.d.ts.map +1 -0
- package/dist/capabilities/aliases.d.ts +36 -0
- package/dist/capabilities/aliases.d.ts.map +1 -0
- package/dist/capabilities/analysis.d.ts +19 -0
- package/dist/capabilities/analysis.d.ts.map +1 -0
- package/dist/capabilities/cache.d.ts +69 -0
- package/dist/capabilities/cache.d.ts.map +1 -0
- package/dist/capabilities/fields.d.ts +50 -0
- package/dist/capabilities/fields.d.ts.map +1 -0
- package/dist/capabilities/index.d.ts +13 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/limits.d.ts +24 -0
- package/dist/capabilities/limits.d.ts.map +1 -0
- package/dist/capabilities/match.d.ts +52 -0
- package/dist/capabilities/match.d.ts.map +1 -0
- package/dist/capabilities/narrow.d.ts +27 -0
- package/dist/capabilities/narrow.d.ts.map +1 -0
- package/dist/capabilities/open.d.ts +25 -0
- package/dist/capabilities/open.d.ts.map +1 -0
- package/dist/capabilities/record.d.ts +13 -0
- package/dist/capabilities/record.d.ts.map +1 -0
- package/dist/capabilities/violations.d.ts +19 -0
- package/dist/capabilities/violations.d.ts.map +1 -0
- package/dist/cartesianBrush-HLU12ig5.js +122 -0
- package/dist/cartesianBrush-HLU12ig5.js.map +1 -0
- package/dist/clickDraft-DQDQn4x-.js +184 -0
- package/dist/clickDraft-DQDQn4x-.js.map +1 -0
- package/dist/dashboard/boardFields.d.ts +11 -0
- package/dist/dashboard/boardFields.d.ts.map +1 -0
- package/dist/dashboard/click.d.ts +105 -0
- package/dist/dashboard/click.d.ts.map +1 -0
- package/dist/dashboard/clickDraft.d.ts +84 -0
- package/dist/dashboard/clickDraft.d.ts.map +1 -0
- package/dist/dashboard/declared.d.ts +29 -0
- package/dist/dashboard/declared.d.ts.map +1 -0
- package/dist/dashboard/defaults.d.ts +14 -0
- package/dist/dashboard/defaults.d.ts.map +1 -0
- package/dist/dashboard/edit.d.ts +118 -0
- package/dist/dashboard/edit.d.ts.map +1 -0
- package/dist/dashboard/filterEdit.d.ts +60 -0
- package/dist/dashboard/filterEdit.d.ts.map +1 -0
- package/dist/dashboard/filters.d.ts +104 -0
- package/dist/dashboard/filters.d.ts.map +1 -0
- package/dist/dashboard/index.d.ts +26 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/layout.d.ts +184 -0
- package/dist/dashboard/layout.d.ts.map +1 -0
- package/dist/dashboard/merge.d.ts +32 -0
- package/dist/dashboard/merge.d.ts.map +1 -0
- package/dist/dashboard/migrate.d.ts +33 -0
- package/dist/dashboard/migrate.d.ts.map +1 -0
- package/dist/dashboard/panelFieldNames.d.ts +20 -0
- package/dist/dashboard/panelFieldNames.d.ts.map +1 -0
- package/dist/dashboard/panelLook.d.ts +18 -0
- package/dist/dashboard/panelLook.d.ts.map +1 -0
- package/dist/dashboard/panels.d.ts +78 -0
- package/dist/dashboard/panels.d.ts.map +1 -0
- package/dist/dashboard/placeholders.d.ts +3 -0
- package/dist/dashboard/placeholders.d.ts.map +1 -0
- package/dist/dashboard/tabs.d.ts +28 -0
- package/dist/dashboard/tabs.d.ts.map +1 -0
- package/dist/dashboard/timeBindings.d.ts +42 -0
- package/dist/dashboard/timeBindings.d.ts.map +1 -0
- package/dist/dashboard/validate.d.ts +80 -0
- package/dist/dashboard/validate.d.ts.map +1 -0
- package/dist/dashboard/validateFilters.d.ts +15 -0
- package/dist/dashboard/validateFilters.d.ts.map +1 -0
- package/dist/dashboard/wiring.d.ts +103 -0
- package/dist/dashboard/wiring.d.ts.map +1 -0
- package/dist/echarts-HUGzxow7.js +35 -0
- package/dist/echarts-HUGzxow7.js.map +1 -0
- package/dist/echartsGeo-BWbXo9ef.js +14 -0
- package/dist/echartsGeo-BWbXo9ef.js.map +1 -0
- package/dist/echartsHierarchy-Cm-9-LN9.js +14 -0
- package/dist/echartsHierarchy-Cm-9-LN9.js.map +1 -0
- package/dist/echartsStatistics-Lq-BjHez.js +20 -0
- package/dist/echartsStatistics-Lq-BjHez.js.map +1 -0
- package/dist/echartsTime-gMH0oF0x.js +15 -0
- package/dist/echartsTime-gMH0oF0x.js.map +1 -0
- package/dist/filter/compile.d.ts +23 -0
- package/dist/filter/compile.d.ts.map +1 -0
- package/dist/filter/configBase.d.ts +23 -0
- package/dist/filter/configBase.d.ts.map +1 -0
- package/dist/filter/describe.d.ts +234 -0
- package/dist/filter/describe.d.ts.map +1 -0
- package/dist/filter/fieldGroups.d.ts +17 -0
- package/dist/filter/fieldGroups.d.ts.map +1 -0
- package/dist/filter/fieldKind.d.ts +244 -0
- package/dist/filter/fieldKind.d.ts.map +1 -0
- package/dist/filter/index.d.ts +21 -0
- package/dist/filter/index.d.ts.map +1 -0
- package/dist/filter/issuePath.d.ts +21 -0
- package/dist/filter/issuePath.d.ts.map +1 -0
- package/dist/filter/kinds/array.d.ts +18 -0
- package/dist/filter/kinds/array.d.ts.map +1 -0
- package/dist/filter/kinds/boolean.d.ts +3 -0
- package/dist/filter/kinds/boolean.d.ts.map +1 -0
- package/dist/filter/kinds/dateTime.d.ts +39 -0
- package/dist/filter/kinds/dateTime.d.ts.map +1 -0
- package/dist/filter/kinds/deletion.d.ts +42 -0
- package/dist/filter/kinds/deletion.d.ts.map +1 -0
- package/dist/filter/kinds/duration.d.ts +27 -0
- package/dist/filter/kinds/duration.d.ts.map +1 -0
- package/dist/filter/kinds/elementMatch.d.ts +34 -0
- package/dist/filter/kinds/elementMatch.d.ts.map +1 -0
- package/dist/filter/kinds/entries.d.ts +20 -0
- package/dist/filter/kinds/entries.d.ts.map +1 -0
- package/dist/filter/kinds/enum.d.ts +7 -0
- package/dist/filter/kinds/enum.d.ts.map +1 -0
- package/dist/filter/kinds/index.d.ts +18 -0
- package/dist/filter/kinds/index.d.ts.map +1 -0
- package/dist/filter/kinds/metadata.d.ts +3 -0
- package/dist/filter/kinds/metadata.d.ts.map +1 -0
- package/dist/filter/kinds/number.d.ts +3 -0
- package/dist/filter/kinds/number.d.ts.map +1 -0
- package/dist/filter/kinds/options.d.ts +44 -0
- package/dist/filter/kinds/options.d.ts.map +1 -0
- package/dist/filter/kinds/presence.d.ts +18 -0
- package/dist/filter/kinds/presence.d.ts.map +1 -0
- package/dist/filter/kinds/reference.d.ts +8 -0
- package/dist/filter/kinds/reference.d.ts.map +1 -0
- package/dist/filter/kinds/search.d.ts +15 -0
- package/dist/filter/kinds/search.d.ts.map +1 -0
- package/dist/filter/kinds/string.d.ts +3 -0
- package/dist/filter/kinds/string.d.ts.map +1 -0
- package/dist/filter/marks.d.ts +28 -0
- package/dist/filter/marks.d.ts.map +1 -0
- package/dist/filter/search.d.ts +28 -0
- package/dist/filter/search.d.ts.map +1 -0
- package/dist/filter/time.d.ts +57 -0
- package/dist/filter/time.d.ts.map +1 -0
- package/dist/filter/tree.d.ts +186 -0
- package/dist/filter/tree.d.ts.map +1 -0
- package/dist/filter/validate.d.ts +42 -0
- package/dist/filter/validate.d.ts.map +1 -0
- package/dist/filter/values.d.ts +111 -0
- package/dist/filter/values.d.ts.map +1 -0
- package/dist/index.d.ts +138 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +478 -0
- package/dist/index.js.map +1 -0
- package/dist/model/analysis.d.ts +327 -0
- package/dist/model/analysis.d.ts.map +1 -0
- package/dist/model/chart.d.ts +503 -0
- package/dist/model/chart.d.ts.map +1 -0
- package/dist/model/config.d.ts +68 -0
- package/dist/model/config.d.ts.map +1 -0
- package/dist/model/currency.d.ts +55 -0
- package/dist/model/currency.d.ts.map +1 -0
- package/dist/model/dashboard.d.ts +454 -0
- package/dist/model/dashboard.d.ts.map +1 -0
- package/dist/model/definition.d.ts +373 -0
- package/dist/model/definition.d.ts.map +1 -0
- package/dist/model/field.d.ts +432 -0
- package/dist/model/field.d.ts.map +1 -0
- package/dist/model/filter.d.ts +54 -0
- package/dist/model/filter.d.ts.map +1 -0
- package/dist/model/index.d.ts +21 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/instance.d.ts +118 -0
- package/dist/model/instance.d.ts.map +1 -0
- package/dist/model/issue.d.ts +33 -0
- package/dist/model/issue.d.ts.map +1 -0
- package/dist/model/json.d.ts +34 -0
- package/dist/model/json.d.ts.map +1 -0
- package/dist/model/limits.d.ts +133 -0
- package/dist/model/limits.d.ts.map +1 -0
- package/dist/model/record.d.ts +114 -0
- package/dist/model/record.d.ts.map +1 -0
- package/dist/model/storeError.d.ts +105 -0
- package/dist/model/storeError.d.ts.map +1 -0
- package/dist/model/text.d.ts +58 -0
- package/dist/model/text.d.ts.map +1 -0
- package/dist/react/actionRunner.d.ts +161 -0
- package/dist/react/actionRunner.d.ts.map +1 -0
- package/dist/react/actions.d.ts +112 -0
- package/dist/react/actions.d.ts.map +1 -0
- package/dist/react/analysisEditing.d.ts +122 -0
- package/dist/react/analysisEditing.d.ts.map +1 -0
- package/dist/react/analysisFields.d.ts +38 -0
- package/dist/react/analysisFields.d.ts.map +1 -0
- package/dist/react/environment.d.ts +10 -0
- package/dist/react/environment.d.ts.map +1 -0
- package/dist/react/index.d.ts +41 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/issues.d.ts +14 -0
- package/dist/react/issues.d.ts.map +1 -0
- package/dist/react/manager/abilities.d.ts +38 -0
- package/dist/react/manager/abilities.d.ts.map +1 -0
- package/dist/react/manager/order.d.ts +60 -0
- package/dist/react/manager/order.d.ts.map +1 -0
- package/dist/react/manager/outcomes.d.ts +55 -0
- package/dist/react/manager/outcomes.d.ts.map +1 -0
- package/dist/react/manager/queue.d.ts +56 -0
- package/dist/react/manager/queue.d.ts.map +1 -0
- package/dist/react/manager/useCommandRunner.d.ts +74 -0
- package/dist/react/manager/useCommandRunner.d.ts.map +1 -0
- package/dist/react/recordColumns.d.ts +68 -0
- package/dist/react/recordColumns.d.ts.map +1 -0
- package/dist/react/recordDraft.d.ts +31 -0
- package/dist/react/recordDraft.d.ts.map +1 -0
- package/dist/react/recordEdits.d.ts +58 -0
- package/dist/react/recordEdits.d.ts.map +1 -0
- package/dist/react/recordSelection.d.ts +46 -0
- package/dist/react/recordSelection.d.ts.map +1 -0
- package/dist/react/useAnalysisEditor.d.ts +183 -0
- package/dist/react/useAnalysisEditor.d.ts.map +1 -0
- package/dist/react/useAnalysisResult.d.ts +168 -0
- package/dist/react/useAnalysisResult.d.ts.map +1 -0
- package/dist/react/useAutoRefresh.d.ts +115 -0
- package/dist/react/useAutoRefresh.d.ts.map +1 -0
- package/dist/react/useDashboard.d.ts +204 -0
- package/dist/react/useDashboard.d.ts.map +1 -0
- package/dist/react/useFilterEditor.d.ts +255 -0
- package/dist/react/useFilterEditor.d.ts.map +1 -0
- package/dist/react/usePanelFollowUps.d.ts +31 -0
- package/dist/react/usePanelFollowUps.d.ts.map +1 -0
- package/dist/react/useRecordActions.d.ts +126 -0
- package/dist/react/useRecordActions.d.ts.map +1 -0
- package/dist/react/useRecordDetail.d.ts +76 -0
- package/dist/react/useRecordDetail.d.ts.map +1 -0
- package/dist/react/useRecordExport.d.ts +104 -0
- package/dist/react/useRecordExport.d.ts.map +1 -0
- package/dist/react/useRecordTable.d.ts +309 -0
- package/dist/react/useRecordTable.d.ts.map +1 -0
- package/dist/react/useReshape.d.ts +54 -0
- package/dist/react/useReshape.d.ts.map +1 -0
- package/dist/react/useSaveCommands.d.ts +119 -0
- package/dist/react/useSaveCommands.d.ts.map +1 -0
- package/dist/react/useSearchBox.d.ts +34 -0
- package/dist/react/useSearchBox.d.ts.map +1 -0
- package/dist/react/useUnavailable.d.ts +19 -0
- package/dist/react/useUnavailable.d.ts.map +1 -0
- package/dist/react/useValueCandidates.d.ts +41 -0
- package/dist/react/useValueCandidates.d.ts.map +1 -0
- package/dist/react/useViewEngine.d.ts +93 -0
- package/dist/react/useViewEngine.d.ts.map +1 -0
- package/dist/react/useViewList.d.ts +75 -0
- package/dist/react/useViewList.d.ts.map +1 -0
- package/dist/react/useViewManager.d.ts +92 -0
- package/dist/react/useViewManager.d.ts.map +1 -0
- package/dist/react/useWorkbench.d.ts +334 -0
- package/dist/react/useWorkbench.d.ts.map +1 -0
- package/dist/react/workbench/handOver.d.ts +73 -0
- package/dist/react/workbench/handOver.d.ts.map +1 -0
- package/dist/react/workbench/instanceSync.d.ts +55 -0
- package/dist/react/workbench/instanceSync.d.ts.map +1 -0
- package/dist/react/workbench/leaveGuard.d.ts +65 -0
- package/dist/react/workbench/leaveGuard.d.ts.map +1 -0
- package/dist/react/workbench/newView.d.ts +35 -0
- package/dist/react/workbench/newView.d.ts.map +1 -0
- package/dist/react/workbench/releaseDeleted.d.ts +19 -0
- package/dist/react/workbench/releaseDeleted.d.ts.map +1 -0
- package/dist/react/writes.d.ts +134 -0
- package/dist/react/writes.d.ts.map +1 -0
- package/dist/react-DzstAsWB.js +3648 -0
- package/dist/react-DzstAsWB.js.map +1 -0
- package/dist/react-router/index.d.ts +12 -0
- package/dist/react-router/index.d.ts.map +1 -0
- package/dist/react-router.js +27 -0
- package/dist/react-router.js.map +1 -0
- package/dist/react.js +3 -0
- package/dist/record/compile.d.ts +56 -0
- package/dist/record/compile.d.ts.map +1 -0
- package/dist/record/defaults.d.ts +9 -0
- package/dist/record/defaults.d.ts.map +1 -0
- package/dist/record/detail.d.ts +27 -0
- package/dist/record/detail.d.ts.map +1 -0
- package/dist/record/export.d.ts +78 -0
- package/dist/record/export.d.ts.map +1 -0
- package/dist/record/index.d.ts +12 -0
- package/dist/record/index.d.ts.map +1 -0
- package/dist/record/paging.d.ts +89 -0
- package/dist/record/paging.d.ts.map +1 -0
- package/dist/record/path.d.ts +13 -0
- package/dist/record/path.d.ts.map +1 -0
- package/dist/record/project.d.ts +245 -0
- package/dist/record/project.d.ts.map +1 -0
- package/dist/record/summaryCurrency.d.ts +18 -0
- package/dist/record/summaryCurrency.d.ts.map +1 -0
- package/dist/record/validate.d.ts +30 -0
- package/dist/record/validate.d.ts.map +1 -0
- package/dist/routes-DvPNPlQP.js +23 -0
- package/dist/routes-DvPNPlQP.js.map +1 -0
- package/dist/runtime/abort.d.ts +3 -0
- package/dist/runtime/abort.d.ts.map +1 -0
- package/dist/runtime/actions.d.ts +241 -0
- package/dist/runtime/actions.d.ts.map +1 -0
- package/dist/runtime/admission.d.ts +35 -0
- package/dist/runtime/admission.d.ts.map +1 -0
- package/dist/runtime/autoApply.d.ts +51 -0
- package/dist/runtime/autoApply.d.ts.map +1 -0
- package/dist/runtime/capabilities.d.ts +98 -0
- package/dist/runtime/capabilities.d.ts.map +1 -0
- package/dist/runtime/commandChecks.d.ts +22 -0
- package/dist/runtime/commandChecks.d.ts.map +1 -0
- package/dist/runtime/dashboard/anchor.d.ts +46 -0
- package/dist/runtime/dashboard/anchor.d.ts.map +1 -0
- package/dist/runtime/dashboard/canonical.d.ts +31 -0
- package/dist/runtime/dashboard/canonical.d.ts.map +1 -0
- package/dist/runtime/dashboard/children.d.ts +127 -0
- package/dist/runtime/dashboard/children.d.ts.map +1 -0
- package/dist/runtime/dashboard/commands.d.ts +172 -0
- package/dist/runtime/dashboard/commands.d.ts.map +1 -0
- package/dist/runtime/dashboard/contract.d.ts +250 -0
- package/dist/runtime/dashboard/contract.d.ts.map +1 -0
- package/dist/runtime/dashboard/editing.d.ts +197 -0
- package/dist/runtime/dashboard/editing.d.ts.map +1 -0
- package/dist/runtime/dashboard/filterCandidates.d.ts +38 -0
- package/dist/runtime/dashboard/filterCandidates.d.ts.map +1 -0
- package/dist/runtime/dashboard/filterValues.d.ts +117 -0
- package/dist/runtime/dashboard/filterValues.d.ts.map +1 -0
- package/dist/runtime/dashboard/grouping.d.ts +26 -0
- package/dist/runtime/dashboard/grouping.d.ts.map +1 -0
- package/dist/runtime/dashboard/history.d.ts +78 -0
- package/dist/runtime/dashboard/history.d.ts.map +1 -0
- package/dist/runtime/dashboard/opening.d.ts +17 -0
- package/dist/runtime/dashboard/opening.d.ts.map +1 -0
- package/dist/runtime/dashboard/owned.d.ts +38 -0
- package/dist/runtime/dashboard/owned.d.ts.map +1 -0
- package/dist/runtime/dashboard/panelRun.d.ts +101 -0
- package/dist/runtime/dashboard/panelRun.d.ts.map +1 -0
- package/dist/runtime/dashboard/panels.d.ts +155 -0
- package/dist/runtime/dashboard/panels.d.ts.map +1 -0
- package/dist/runtime/dashboard/presentation.d.ts +25 -0
- package/dist/runtime/dashboard/presentation.d.ts.map +1 -0
- package/dist/runtime/dashboard/press.d.ts +150 -0
- package/dist/runtime/dashboard/press.d.ts.map +1 -0
- package/dist/runtime/dashboard/references.d.ts +97 -0
- package/dist/runtime/dashboard/references.d.ts.map +1 -0
- package/dist/runtime/dashboardRuntime.d.ts +235 -0
- package/dist/runtime/dashboardRuntime.d.ts.map +1 -0
- package/dist/runtime/define/analysis.d.ts +8 -0
- package/dist/runtime/define/analysis.d.ts.map +1 -0
- package/dist/runtime/define/defineView.d.ts +42 -0
- package/dist/runtime/define/defineView.d.ts.map +1 -0
- package/dist/runtime/define/fields.d.ts +23 -0
- package/dist/runtime/define/fields.d.ts.map +1 -0
- package/dist/runtime/define/spec.d.ts +88 -0
- package/dist/runtime/define/spec.d.ts.map +1 -0
- package/dist/runtime/definitions.d.ts +35 -0
- package/dist/runtime/definitions.d.ts.map +1 -0
- package/dist/runtime/deprecated.d.ts +3 -0
- package/dist/runtime/deprecated.d.ts.map +1 -0
- package/dist/runtime/environment.d.ts +95 -0
- package/dist/runtime/environment.d.ts.map +1 -0
- package/dist/runtime/execute.d.ts +70 -0
- package/dist/runtime/execute.d.ts.map +1 -0
- package/dist/runtime/exportRows.d.ts +67 -0
- package/dist/runtime/exportRows.d.ts.map +1 -0
- package/dist/runtime/failures.d.ts +57 -0
- package/dist/runtime/failures.d.ts.map +1 -0
- package/dist/runtime/fetchRecord.d.ts +20 -0
- package/dist/runtime/fetchRecord.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +35 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/issueReport.d.ts +25 -0
- package/dist/runtime/issueReport.d.ts.map +1 -0
- package/dist/runtime/issues.d.ts +35 -0
- package/dist/runtime/issues.d.ts.map +1 -0
- package/dist/runtime/listeners.d.ts +36 -0
- package/dist/runtime/listeners.d.ts.map +1 -0
- package/dist/runtime/navigation.d.ts +139 -0
- package/dist/runtime/navigation.d.ts.map +1 -0
- package/dist/runtime/openRuntimes.d.ts +34 -0
- package/dist/runtime/openRuntimes.d.ts.map +1 -0
- package/dist/runtime/panelViews.d.ts +42 -0
- package/dist/runtime/panelViews.d.ts.map +1 -0
- package/dist/runtime/pending.d.ts +75 -0
- package/dist/runtime/pending.d.ts.map +1 -0
- package/dist/runtime/permissions.d.ts +80 -0
- package/dist/runtime/permissions.d.ts.map +1 -0
- package/dist/runtime/preferences.d.ts +37 -0
- package/dist/runtime/preferences.d.ts.map +1 -0
- package/dist/runtime/publish.d.ts +38 -0
- package/dist/runtime/publish.d.ts.map +1 -0
- package/dist/runtime/queryFailure.d.ts +59 -0
- package/dist/runtime/queryFailure.d.ts.map +1 -0
- package/dist/runtime/queryWeight.d.ts +29 -0
- package/dist/runtime/queryWeight.d.ts.map +1 -0
- package/dist/runtime/recordRuntime.d.ts +88 -0
- package/dist/runtime/recordRuntime.d.ts.map +1 -0
- package/dist/runtime/refreshTimer.d.ts +72 -0
- package/dist/runtime/refreshTimer.d.ts.map +1 -0
- package/dist/runtime/requestId.d.ts +11 -0
- package/dist/runtime/requestId.d.ts.map +1 -0
- package/dist/runtime/requestRunner.d.ts +58 -0
- package/dist/runtime/requestRunner.d.ts.map +1 -0
- package/dist/runtime/resources.d.ts +73 -0
- package/dist/runtime/resources.d.ts.map +1 -0
- package/dist/runtime/restyle.d.ts +21 -0
- package/dist/runtime/restyle.d.ts.map +1 -0
- package/dist/runtime/routes.d.ts +99 -0
- package/dist/runtime/routes.d.ts.map +1 -0
- package/dist/runtime/runtimeFactory.d.ts +80 -0
- package/dist/runtime/runtimeFactory.d.ts.map +1 -0
- package/dist/runtime/runtimeStore.d.ts +187 -0
- package/dist/runtime/runtimeStore.d.ts.map +1 -0
- package/dist/runtime/savedConditions.d.ts +11 -0
- package/dist/runtime/savedConditions.d.ts.map +1 -0
- package/dist/runtime/scope.d.ts +50 -0
- package/dist/runtime/scope.d.ts.map +1 -0
- package/dist/runtime/source.d.ts +108 -0
- package/dist/runtime/source.d.ts.map +1 -0
- package/dist/runtime/sourceReason.d.ts +65 -0
- package/dist/runtime/sourceReason.d.ts.map +1 -0
- package/dist/runtime/storedViews.d.ts +17 -0
- package/dist/runtime/storedViews.d.ts.map +1 -0
- package/dist/runtime/summaries.d.ts +25 -0
- package/dist/runtime/summaries.d.ts.map +1 -0
- package/dist/runtime/tabMemory.d.ts +39 -0
- package/dist/runtime/tabMemory.d.ts.map +1 -0
- package/dist/runtime/text.d.ts +20 -0
- package/dist/runtime/text.d.ts.map +1 -0
- package/dist/runtime/unavailable.d.ts +13 -0
- package/dist/runtime/unavailable.d.ts.map +1 -0
- package/dist/runtime/validateDefinition.d.ts +43 -0
- package/dist/runtime/validateDefinition.d.ts.map +1 -0
- package/dist/runtime/validateFields.d.ts +9 -0
- package/dist/runtime/validateFields.d.ts.map +1 -0
- package/dist/runtime/valueCandidates.d.ts +58 -0
- package/dist/runtime/valueCandidates.d.ts.map +1 -0
- package/dist/runtime/viewChanges.d.ts +39 -0
- package/dist/runtime/viewChanges.d.ts.map +1 -0
- package/dist/runtime/viewEngine.d.ts +292 -0
- package/dist/runtime/viewEngine.d.ts.map +1 -0
- package/dist/runtime/viewRuntime.d.ts +199 -0
- package/dist/runtime/viewRuntime.d.ts.map +1 -0
- package/dist/runtime/viewRuntimeTypes.d.ts +445 -0
- package/dist/runtime/viewRuntimeTypes.d.ts.map +1 -0
- package/dist/runtime/write.d.ts +96 -0
- package/dist/runtime/write.d.ts.map +1 -0
- package/dist/runtime/writeLedger.d.ts +134 -0
- package/dist/runtime/writeLedger.d.ts.map +1 -0
- package/dist/shadcn-bridge.css +107 -0
- package/dist/store/MemoryViewStore.d.ts +134 -0
- package/dist/store/MemoryViewStore.d.ts.map +1 -0
- package/dist/store/ViewStore.d.ts +116 -0
- package/dist/store/ViewStore.d.ts.map +1 -0
- package/dist/store/index.d.ts +10 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/localStorageSnapshot.d.ts +65 -0
- package/dist/store/localStorageSnapshot.d.ts.map +1 -0
- package/dist/styles.css +3 -0
- package/dist/styles.d.ts +1 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +0 -0
- package/dist/testing/actions.d.ts +78 -0
- package/dist/testing/actions.d.ts.map +1 -0
- package/dist/testing/aggregate.d.ts +24 -0
- package/dist/testing/aggregate.d.ts.map +1 -0
- package/dist/testing/calendar.d.ts +41 -0
- package/dist/testing/calendar.d.ts.map +1 -0
- package/dist/testing/expression.d.ts +17 -0
- package/dist/testing/expression.d.ts.map +1 -0
- package/dist/testing/filter.d.ts +48 -0
- package/dist/testing/filter.d.ts.map +1 -0
- package/dist/testing/index.d.ts +13 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/source.d.ts +52 -0
- package/dist/testing/source.d.ts.map +1 -0
- package/dist/testing/values.d.ts +14 -0
- package/dist/testing/values.d.ts.map +1 -0
- package/dist/testing.js +725 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme-check.mjs +6972 -0
- package/dist/theme-source.css +1393 -0
- package/dist/theme-tokens.json +5335 -0
- package/dist/themes/azure.css +126 -0
- package/dist/themes/contrast.css +122 -0
- package/dist/themes/neutral.css +2 -0
- package/dist/themes/porcelain.css +136 -0
- package/dist/themes.css +389 -0
- package/dist/ui/DashboardWorkbench.d.ts +133 -0
- package/dist/ui/DashboardWorkbench.d.ts.map +1 -0
- package/dist/ui/DataWorkbench.d.ts +155 -0
- package/dist/ui/DataWorkbench.d.ts.map +1 -0
- package/dist/ui/EmbeddedDashboard.d.ts +103 -0
- package/dist/ui/EmbeddedDashboard.d.ts.map +1 -0
- package/dist/ui/EmbeddedView.d.ts +76 -0
- package/dist/ui/EmbeddedView.d.ts.map +1 -0
- package/dist/ui/ViewHost.d.ts +94 -0
- package/dist/ui/ViewHost.d.ts.map +1 -0
- package/dist/ui/actions/ActionButtons.d.ts +49 -0
- package/dist/ui/actions/ActionButtons.d.ts.map +1 -0
- package/dist/ui/actions/ActionDialog.d.ts +35 -0
- package/dist/ui/actions/ActionDialog.d.ts.map +1 -0
- package/dist/ui/actions/ActionSurface.d.ts +60 -0
- package/dist/ui/actions/ActionSurface.d.ts.map +1 -0
- package/dist/ui/actions/BulkStatus.d.ts +41 -0
- package/dist/ui/actions/BulkStatus.d.ts.map +1 -0
- package/dist/ui/analysis/AnalysisChart.d.ts +71 -0
- package/dist/ui/analysis/AnalysisChart.d.ts.map +1 -0
- package/dist/ui/analysis/AnalysisTable.d.ts +54 -0
- package/dist/ui/analysis/AnalysisTable.d.ts.map +1 -0
- package/dist/ui/analysis/AnalysisToolbar.d.ts +68 -0
- package/dist/ui/analysis/AnalysisToolbar.d.ts.map +1 -0
- package/dist/ui/analysis/AxesTab.d.ts +11 -0
- package/dist/ui/analysis/AxesTab.d.ts.map +1 -0
- package/dist/ui/analysis/CardMenu.d.ts +41 -0
- package/dist/ui/analysis/CardMenu.d.ts.map +1 -0
- package/dist/ui/analysis/ChartOptions.d.ts +38 -0
- package/dist/ui/analysis/ChartOptions.d.ts.map +1 -0
- package/dist/ui/analysis/ChartPicker.d.ts +86 -0
- package/dist/ui/analysis/ChartPicker.d.ts.map +1 -0
- package/dist/ui/analysis/CompactSelect.d.ts +28 -0
- package/dist/ui/analysis/CompactSelect.d.ts.map +1 -0
- package/dist/ui/analysis/CompositionOptions.d.ts +18 -0
- package/dist/ui/analysis/CompositionOptions.d.ts.map +1 -0
- package/dist/ui/analysis/CurrencyStrip.d.ts +19 -0
- package/dist/ui/analysis/CurrencyStrip.d.ts.map +1 -0
- package/dist/ui/analysis/DataTab.d.ts +10 -0
- package/dist/ui/analysis/DataTab.d.ts.map +1 -0
- package/dist/ui/analysis/DimensionCard.d.ts +13 -0
- package/dist/ui/analysis/DimensionCard.d.ts.map +1 -0
- package/dist/ui/analysis/DisplayTab.d.ts +26 -0
- package/dist/ui/analysis/DisplayTab.d.ts.map +1 -0
- package/dist/ui/analysis/DrillMenu.d.ts +73 -0
- package/dist/ui/analysis/DrillMenu.d.ts.map +1 -0
- package/dist/ui/analysis/DroppedNotice.d.ts +28 -0
- package/dist/ui/analysis/DroppedNotice.d.ts.map +1 -0
- package/dist/ui/analysis/ElementsSlot.d.ts +22 -0
- package/dist/ui/analysis/ElementsSlot.d.ts.map +1 -0
- package/dist/ui/analysis/EmptyResult.d.ts +50 -0
- package/dist/ui/analysis/EmptyResult.d.ts.map +1 -0
- package/dist/ui/analysis/ExportMenu.d.ts +35 -0
- package/dist/ui/analysis/ExportMenu.d.ts.map +1 -0
- package/dist/ui/analysis/FormulaCard.d.ts +46 -0
- package/dist/ui/analysis/FormulaCard.d.ts.map +1 -0
- package/dist/ui/analysis/HavingRows.d.ts +50 -0
- package/dist/ui/analysis/HavingRows.d.ts.map +1 -0
- package/dist/ui/analysis/LevelOptions.d.ts +21 -0
- package/dist/ui/analysis/LevelOptions.d.ts.map +1 -0
- package/dist/ui/analysis/MapOptions.d.ts +8 -0
- package/dist/ui/analysis/MapOptions.d.ts.map +1 -0
- package/dist/ui/analysis/MetricCard.d.ts +29 -0
- package/dist/ui/analysis/MetricCard.d.ts.map +1 -0
- package/dist/ui/analysis/MetricCondition.d.ts +73 -0
- package/dist/ui/analysis/MetricCondition.d.ts.map +1 -0
- package/dist/ui/analysis/MetricSlot.d.ts +35 -0
- package/dist/ui/analysis/MetricSlot.d.ts.map +1 -0
- package/dist/ui/analysis/OrderedCards.d.ts +39 -0
- package/dist/ui/analysis/OrderedCards.d.ts.map +1 -0
- package/dist/ui/analysis/RangeSlot.d.ts +26 -0
- package/dist/ui/analysis/RangeSlot.d.ts.map +1 -0
- package/dist/ui/analysis/ReferenceOptions.d.ts +12 -0
- package/dist/ui/analysis/ReferenceOptions.d.ts.map +1 -0
- package/dist/ui/analysis/ResultSlot.d.ts +31 -0
- package/dist/ui/analysis/ResultSlot.d.ts.map +1 -0
- package/dist/ui/analysis/SeriesList.d.ts +35 -0
- package/dist/ui/analysis/SeriesList.d.ts.map +1 -0
- package/dist/ui/analysis/SkeletonResult.d.ts +36 -0
- package/dist/ui/analysis/SkeletonResult.d.ts.map +1 -0
- package/dist/ui/analysis/StatisticalOptions.d.ts +31 -0
- package/dist/ui/analysis/StatisticalOptions.d.ts.map +1 -0
- package/dist/ui/analysis/TermTip.d.ts +32 -0
- package/dist/ui/analysis/TermTip.d.ts.map +1 -0
- package/dist/ui/analysis/Tray.d.ts +45 -0
- package/dist/ui/analysis/Tray.d.ts.map +1 -0
- package/dist/ui/analysis/VisualizationPanel.d.ts +68 -0
- package/dist/ui/analysis/VisualizationPanel.d.ts.map +1 -0
- package/dist/ui/analysis/chartIcons.d.ts +19 -0
- package/dist/ui/analysis/chartIcons.d.ts.map +1 -0
- package/dist/ui/analysis/drag.d.ts +39 -0
- package/dist/ui/analysis/drag.d.ts.map +1 -0
- package/dist/ui/analysis/editing.d.ts +69 -0
- package/dist/ui/analysis/editing.d.ts.map +1 -0
- package/dist/ui/analysis/exportOffer.d.ts +60 -0
- package/dist/ui/analysis/exportOffer.d.ts.map +1 -0
- package/dist/ui/analysis/headerSort.d.ts +66 -0
- package/dist/ui/analysis/headerSort.d.ts.map +1 -0
- package/dist/ui/analysis/imageExport.d.ts +40 -0
- package/dist/ui/analysis/imageExport.d.ts.map +1 -0
- package/dist/ui/analysis/issueNames.d.ts +39 -0
- package/dist/ui/analysis/issueNames.d.ts.map +1 -0
- package/dist/ui/analysis/listFocus.d.ts +42 -0
- package/dist/ui/analysis/listFocus.d.ts.map +1 -0
- package/dist/ui/analysis/optionControls.d.ts +200 -0
- package/dist/ui/analysis/optionControls.d.ts.map +1 -0
- package/dist/ui/analysis/tableColumns.d.ts +79 -0
- package/dist/ui/analysis/tableColumns.d.ts.map +1 -0
- package/dist/ui/analysis/virtualRows.d.ts +66 -0
- package/dist/ui/analysis/virtualRows.d.ts.map +1 -0
- package/dist/ui/charts/Boxplot.d.ts +10 -0
- package/dist/ui/charts/Boxplot.d.ts.map +1 -0
- package/dist/ui/charts/Candlestick.d.ts +9 -0
- package/dist/ui/charts/Candlestick.d.ts.map +1 -0
- package/dist/ui/charts/Cartesian.d.ts +9 -0
- package/dist/ui/charts/Cartesian.d.ts.map +1 -0
- package/dist/ui/charts/ChartLegend.d.ts +47 -0
- package/dist/ui/charts/ChartLegend.d.ts.map +1 -0
- package/dist/ui/charts/ChartNotes.d.ts +14 -0
- package/dist/ui/charts/ChartNotes.d.ts.map +1 -0
- package/dist/ui/charts/ChartReading.d.ts +15 -0
- package/dist/ui/charts/ChartReading.d.ts.map +1 -0
- package/dist/ui/charts/EChart.d.ts +177 -0
- package/dist/ui/charts/EChart.d.ts.map +1 -0
- package/dist/ui/charts/Funnel.d.ts +27 -0
- package/dist/ui/charts/Funnel.d.ts.map +1 -0
- package/dist/ui/charts/Gauge.d.ts +9 -0
- package/dist/ui/charts/Gauge.d.ts.map +1 -0
- package/dist/ui/charts/GeoMap.d.ts +11 -0
- package/dist/ui/charts/GeoMap.d.ts.map +1 -0
- package/dist/ui/charts/Heatmap.d.ts +9 -0
- package/dist/ui/charts/Heatmap.d.ts.map +1 -0
- package/dist/ui/charts/Hierarchy.d.ts +12 -0
- package/dist/ui/charts/Hierarchy.d.ts.map +1 -0
- package/dist/ui/charts/MetricCard.d.ts +4 -0
- package/dist/ui/charts/MetricCard.d.ts.map +1 -0
- package/dist/ui/charts/PieSlices.d.ts +26 -0
- package/dist/ui/charts/PieSlices.d.ts.map +1 -0
- package/dist/ui/charts/Profiles.d.ts +11 -0
- package/dist/ui/charts/Profiles.d.ts.map +1 -0
- package/dist/ui/charts/ScatterPoints.d.ts +5 -0
- package/dist/ui/charts/ScatterPoints.d.ts.map +1 -0
- package/dist/ui/charts/TimeCharts.d.ts +10 -0
- package/dist/ui/charts/TimeCharts.d.ts.map +1 -0
- package/dist/ui/charts/Treemap.d.ts +12 -0
- package/dist/ui/charts/Treemap.d.ts.map +1 -0
- package/dist/ui/charts/Waterfall.d.ts +11 -0
- package/dist/ui/charts/Waterfall.d.ts.map +1 -0
- package/dist/ui/charts/axis.d.ts +101 -0
- package/dist/ui/charts/axis.d.ts.map +1 -0
- package/dist/ui/charts/boxplotOption.d.ts +33 -0
- package/dist/ui/charts/boxplotOption.d.ts.map +1 -0
- package/dist/ui/charts/candlestickOption.d.ts +42 -0
- package/dist/ui/charts/candlestickOption.d.ts.map +1 -0
- package/dist/ui/charts/cartesianBrush.d.ts +84 -0
- package/dist/ui/charts/cartesianBrush.d.ts.map +1 -0
- package/dist/ui/charts/cartesianFit.d.ts +72 -0
- package/dist/ui/charts/cartesianFit.d.ts.map +1 -0
- package/dist/ui/charts/cartesianMarks.d.ts +116 -0
- package/dist/ui/charts/cartesianMarks.d.ts.map +1 -0
- package/dist/ui/charts/cartesianOption.d.ts +32 -0
- package/dist/ui/charts/cartesianOption.d.ts.map +1 -0
- package/dist/ui/charts/cartesianPlan.d.ts +263 -0
- package/dist/ui/charts/cartesianPlan.d.ts.map +1 -0
- package/dist/ui/charts/cartesianSeries.d.ts +41 -0
- package/dist/ui/charts/cartesianSeries.d.ts.map +1 -0
- package/dist/ui/charts/cartesianTooltip.d.ts +14 -0
- package/dist/ui/charts/cartesianTooltip.d.ts.map +1 -0
- package/dist/ui/charts/cartesianZoom.d.ts +60 -0
- package/dist/ui/charts/cartesianZoom.d.ts.map +1 -0
- package/dist/ui/charts/categoryFrame.d.ts +106 -0
- package/dist/ui/charts/categoryFrame.d.ts.map +1 -0
- package/dist/ui/charts/dateTicks.d.ts +36 -0
- package/dist/ui/charts/dateTicks.d.ts.map +1 -0
- package/dist/ui/charts/echarts.d.ts +16 -0
- package/dist/ui/charts/echarts.d.ts.map +1 -0
- package/dist/ui/charts/echartsGeo.d.ts +5 -0
- package/dist/ui/charts/echartsGeo.d.ts.map +1 -0
- package/dist/ui/charts/echartsHierarchy.d.ts +2 -0
- package/dist/ui/charts/echartsHierarchy.d.ts.map +1 -0
- package/dist/ui/charts/echartsStatistics.d.ts +2 -0
- package/dist/ui/charts/echartsStatistics.d.ts.map +1 -0
- package/dist/ui/charts/echartsTime.d.ts +2 -0
- package/dist/ui/charts/echartsTime.d.ts.map +1 -0
- package/dist/ui/charts/family.d.ts +176 -0
- package/dist/ui/charts/family.d.ts.map +1 -0
- package/dist/ui/charts/frameClass.d.ts +18 -0
- package/dist/ui/charts/frameClass.d.ts.map +1 -0
- package/dist/ui/charts/funnelFit.d.ts +67 -0
- package/dist/ui/charts/funnelFit.d.ts.map +1 -0
- package/dist/ui/charts/funnelOption.d.ts +94 -0
- package/dist/ui/charts/funnelOption.d.ts.map +1 -0
- package/dist/ui/charts/gaugeOption.d.ts +32 -0
- package/dist/ui/charts/gaugeOption.d.ts.map +1 -0
- package/dist/ui/charts/heatmapOption.d.ts +38 -0
- package/dist/ui/charts/heatmapOption.d.ts.map +1 -0
- package/dist/ui/charts/hierarchyOption.d.ts +85 -0
- package/dist/ui/charts/hierarchyOption.d.ts.map +1 -0
- package/dist/ui/charts/highlight.d.ts +26 -0
- package/dist/ui/charts/highlight.d.ts.map +1 -0
- package/dist/ui/charts/image.d.ts +96 -0
- package/dist/ui/charts/image.d.ts.map +1 -0
- package/dist/ui/charts/legend.d.ts +11 -0
- package/dist/ui/charts/legend.d.ts.map +1 -0
- package/dist/ui/charts/load.d.ts +29 -0
- package/dist/ui/charts/load.d.ts.map +1 -0
- package/dist/ui/charts/mapOption.d.ts +39 -0
- package/dist/ui/charts/mapOption.d.ts.map +1 -0
- package/dist/ui/charts/maps.d.ts +53 -0
- package/dist/ui/charts/maps.d.ts.map +1 -0
- package/dist/ui/charts/markWords.d.ts +38 -0
- package/dist/ui/charts/markWords.d.ts.map +1 -0
- package/dist/ui/charts/measure.d.ts +2 -0
- package/dist/ui/charts/measure.d.ts.map +1 -0
- package/dist/ui/charts/motion.d.ts +15 -0
- package/dist/ui/charts/motion.d.ts.map +1 -0
- package/dist/ui/charts/optionMerge.d.ts +10 -0
- package/dist/ui/charts/optionMerge.d.ts.map +1 -0
- package/dist/ui/charts/palette.d.ts +43 -0
- package/dist/ui/charts/palette.d.ts.map +1 -0
- package/dist/ui/charts/patterns.d.ts +29 -0
- package/dist/ui/charts/patterns.d.ts.map +1 -0
- package/dist/ui/charts/periodSpan.d.ts +11 -0
- package/dist/ui/charts/periodSpan.d.ts.map +1 -0
- package/dist/ui/charts/pieOption.d.ts +107 -0
- package/dist/ui/charts/pieOption.d.ts.map +1 -0
- package/dist/ui/charts/print.d.ts +16 -0
- package/dist/ui/charts/print.d.ts.map +1 -0
- package/dist/ui/charts/profileOption.d.ts +47 -0
- package/dist/ui/charts/profileOption.d.ts.map +1 -0
- package/dist/ui/charts/reading.d.ts +66 -0
- package/dist/ui/charts/reading.d.ts.map +1 -0
- package/dist/ui/charts/readingStatistics.d.ts +58 -0
- package/dist/ui/charts/readingStatistics.d.ts.map +1 -0
- package/dist/ui/charts/scale.d.ts +42 -0
- package/dist/ui/charts/scale.d.ts.map +1 -0
- package/dist/ui/charts/scatterOption.d.ts +44 -0
- package/dist/ui/charts/scatterOption.d.ts.map +1 -0
- package/dist/ui/charts/sentence.d.ts +19 -0
- package/dist/ui/charts/sentence.d.ts.map +1 -0
- package/dist/ui/charts/sentenceParts.d.ts +36 -0
- package/dist/ui/charts/sentenceParts.d.ts.map +1 -0
- package/dist/ui/charts/sizes.d.ts +25 -0
- package/dist/ui/charts/sizes.d.ts.map +1 -0
- package/dist/ui/charts/sparklineOption.d.ts +19 -0
- package/dist/ui/charts/sparklineOption.d.ts.map +1 -0
- package/dist/ui/charts/theme.d.ts +179 -0
- package/dist/ui/charts/theme.d.ts.map +1 -0
- package/dist/ui/charts/timeOption.d.ts +54 -0
- package/dist/ui/charts/timeOption.d.ts.map +1 -0
- package/dist/ui/charts/tooltip.d.ts +51 -0
- package/dist/ui/charts/tooltip.d.ts.map +1 -0
- package/dist/ui/charts/treemapOption.d.ts +56 -0
- package/dist/ui/charts/treemapOption.d.ts.map +1 -0
- package/dist/ui/charts/waterfallOption.d.ts +58 -0
- package/dist/ui/charts/waterfallOption.d.ts.map +1 -0
- package/dist/ui/colorMode.d.ts +39 -0
- package/dist/ui/colorMode.d.ts.map +1 -0
- package/dist/ui/columns/ColumnRow.d.ts +79 -0
- package/dist/ui/columns/ColumnRow.d.ts.map +1 -0
- package/dist/ui/columns/ColumnSettings.d.ts +51 -0
- package/dist/ui/columns/ColumnSettings.d.ts.map +1 -0
- package/dist/ui/columns/WidthInput.d.ts +39 -0
- package/dist/ui/columns/WidthInput.d.ts.map +1 -0
- package/dist/ui/columns/drag.d.ts +34 -0
- package/dist/ui/columns/drag.d.ts.map +1 -0
- package/dist/ui/columns/rows.d.ts +155 -0
- package/dist/ui/columns/rows.d.ts.map +1 -0
- package/dist/ui/columns/sections.d.ts +55 -0
- package/dist/ui/columns/sections.d.ts.map +1 -0
- package/dist/ui/components/alert-dialog.d.ts +19 -0
- package/dist/ui/components/alert-dialog.d.ts.map +1 -0
- package/dist/ui/components/alert.d.ts +11 -0
- package/dist/ui/components/alert.d.ts.map +1 -0
- package/dist/ui/components/badge.d.ts +8 -0
- package/dist/ui/components/badge.d.ts.map +1 -0
- package/dist/ui/components/button-group.d.ts +11 -0
- package/dist/ui/components/button-group.d.ts.map +1 -0
- package/dist/ui/components/button.d.ts +9 -0
- package/dist/ui/components/button.d.ts.map +1 -0
- package/dist/ui/components/calendar.d.ts +11 -0
- package/dist/ui/components/calendar.d.ts.map +1 -0
- package/dist/ui/components/card.d.ts +12 -0
- package/dist/ui/components/card.d.ts.map +1 -0
- package/dist/ui/components/checkbox.d.ts +4 -0
- package/dist/ui/components/checkbox.d.ts.map +1 -0
- package/dist/ui/components/collapsible.d.ts +6 -0
- package/dist/ui/components/collapsible.d.ts.map +1 -0
- package/dist/ui/components/combobox.d.ts +25 -0
- package/dist/ui/components/combobox.d.ts.map +1 -0
- package/dist/ui/components/dialog.d.ts +18 -0
- package/dist/ui/components/dialog.d.ts.map +1 -0
- package/dist/ui/components/dropdown-menu.d.ts +30 -0
- package/dist/ui/components/dropdown-menu.d.ts.map +1 -0
- package/dist/ui/components/empty.d.ts +12 -0
- package/dist/ui/components/empty.d.ts.map +1 -0
- package/dist/ui/components/field.d.ts +25 -0
- package/dist/ui/components/field.d.ts.map +1 -0
- package/dist/ui/components/input-group.d.ts +19 -0
- package/dist/ui/components/input-group.d.ts.map +1 -0
- package/dist/ui/components/input.d.ts +4 -0
- package/dist/ui/components/input.d.ts.map +1 -0
- package/dist/ui/components/item.d.ts +23 -0
- package/dist/ui/components/item.d.ts.map +1 -0
- package/dist/ui/components/label.d.ts +4 -0
- package/dist/ui/components/label.d.ts.map +1 -0
- package/dist/ui/components/pagination.d.ts +18 -0
- package/dist/ui/components/pagination.d.ts.map +1 -0
- package/dist/ui/components/popover.d.ts +10 -0
- package/dist/ui/components/popover.d.ts.map +1 -0
- package/dist/ui/components/progress.d.ts +8 -0
- package/dist/ui/components/progress.d.ts.map +1 -0
- package/dist/ui/components/radio-group.d.ts +6 -0
- package/dist/ui/components/radio-group.d.ts.map +1 -0
- package/dist/ui/components/select.d.ts +16 -0
- package/dist/ui/components/select.d.ts.map +1 -0
- package/dist/ui/components/separator.d.ts +4 -0
- package/dist/ui/components/separator.d.ts.map +1 -0
- package/dist/ui/components/sheet.d.ts +15 -0
- package/dist/ui/components/sheet.d.ts.map +1 -0
- package/dist/ui/components/skeleton.d.ts +3 -0
- package/dist/ui/components/skeleton.d.ts.map +1 -0
- package/dist/ui/components/spinner.d.ts +3 -0
- package/dist/ui/components/spinner.d.ts.map +1 -0
- package/dist/ui/components/table.d.ts +11 -0
- package/dist/ui/components/table.d.ts.map +1 -0
- package/dist/ui/components/tabs.d.ts +11 -0
- package/dist/ui/components/tabs.d.ts.map +1 -0
- package/dist/ui/components/textarea.d.ts +4 -0
- package/dist/ui/components/textarea.d.ts.map +1 -0
- package/dist/ui/components/toast.d.ts +17 -0
- package/dist/ui/components/toast.d.ts.map +1 -0
- package/dist/ui/components/toggle-group.d.ts +12 -0
- package/dist/ui/components/toggle-group.d.ts.map +1 -0
- package/dist/ui/components/toggle.d.ts +9 -0
- package/dist/ui/components/toggle.d.ts.map +1 -0
- package/dist/ui/components/tooltip.d.ts +7 -0
- package/dist/ui/components/tooltip.d.ts.map +1 -0
- package/dist/ui/dashboard/AddMenu.d.ts +28 -0
- package/dist/ui/dashboard/AddMenu.d.ts.map +1 -0
- package/dist/ui/dashboard/Board.d.ts +49 -0
- package/dist/ui/dashboard/Board.d.ts.map +1 -0
- package/dist/ui/dashboard/BoardDestination.d.ts +48 -0
- package/dist/ui/dashboard/BoardDestination.d.ts.map +1 -0
- package/dist/ui/dashboard/BoardFilters.d.ts +58 -0
- package/dist/ui/dashboard/BoardFilters.d.ts.map +1 -0
- package/dist/ui/dashboard/BoardWidth.d.ts +15 -0
- package/dist/ui/dashboard/BoardWidth.d.ts.map +1 -0
- package/dist/ui/dashboard/ClickSettings.d.ts +30 -0
- package/dist/ui/dashboard/ClickSettings.d.ts.map +1 -0
- package/dist/ui/dashboard/ContentEditor.d.ts +40 -0
- package/dist/ui/dashboard/ContentEditor.d.ts.map +1 -0
- package/dist/ui/dashboard/DashboardArrange.d.ts +101 -0
- package/dist/ui/dashboard/DashboardArrange.d.ts.map +1 -0
- package/dist/ui/dashboard/DashboardGrid.d.ts +96 -0
- package/dist/ui/dashboard/DashboardGrid.d.ts.map +1 -0
- package/dist/ui/dashboard/DashboardPanel.d.ts +143 -0
- package/dist/ui/dashboard/DashboardPanel.d.ts.map +1 -0
- package/dist/ui/dashboard/DashboardPanels.d.ts +93 -0
- package/dist/ui/dashboard/DashboardPanels.d.ts.map +1 -0
- package/dist/ui/dashboard/DashboardTabs.d.ts +43 -0
- package/dist/ui/dashboard/DashboardTabs.d.ts.map +1 -0
- package/dist/ui/dashboard/EditBar.d.ts +55 -0
- package/dist/ui/dashboard/EditBar.d.ts.map +1 -0
- package/dist/ui/dashboard/EditableTabs.d.ts +32 -0
- package/dist/ui/dashboard/EditableTabs.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterBar.d.ts +82 -0
- package/dist/ui/dashboard/FilterBar.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterOrder.d.ts +40 -0
- package/dist/ui/dashboard/FilterOrder.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterReadings.d.ts +41 -0
- package/dist/ui/dashboard/FilterReadings.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterSettings.d.ts +32 -0
- package/dist/ui/dashboard/FilterSettings.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterSheet.d.ts +24 -0
- package/dist/ui/dashboard/FilterSheet.d.ts.map +1 -0
- package/dist/ui/dashboard/FilterWiring.d.ts +47 -0
- package/dist/ui/dashboard/FilterWiring.d.ts.map +1 -0
- package/dist/ui/dashboard/GridBlocksLayer.d.ts +17 -0
- package/dist/ui/dashboard/GridBlocksLayer.d.ts.map +1 -0
- package/dist/ui/dashboard/GroupingControl.d.ts +10 -0
- package/dist/ui/dashboard/GroupingControl.d.ts.map +1 -0
- package/dist/ui/dashboard/NewAnalysisDialog.d.ts +41 -0
- package/dist/ui/dashboard/NewAnalysisDialog.d.ts.map +1 -0
- package/dist/ui/dashboard/PanelBodies.d.ts +101 -0
- package/dist/ui/dashboard/PanelBodies.d.ts.map +1 -0
- package/dist/ui/dashboard/PanelExport.d.ts +35 -0
- package/dist/ui/dashboard/PanelExport.d.ts.map +1 -0
- package/dist/ui/dashboard/PanelMarks.d.ts +43 -0
- package/dist/ui/dashboard/PanelMarks.d.ts.map +1 -0
- package/dist/ui/dashboard/PanelMenu.d.ts +56 -0
- package/dist/ui/dashboard/PanelMenu.d.ts.map +1 -0
- package/dist/ui/dashboard/PanelUnavailable.d.ts +45 -0
- package/dist/ui/dashboard/PanelUnavailable.d.ts.map +1 -0
- package/dist/ui/dashboard/PresentationDialog.d.ts +36 -0
- package/dist/ui/dashboard/PresentationDialog.d.ts.map +1 -0
- package/dist/ui/dashboard/ScrollCue.d.ts +21 -0
- package/dist/ui/dashboard/ScrollCue.d.ts.map +1 -0
- package/dist/ui/dashboard/ViewPicker.d.ts +59 -0
- package/dist/ui/dashboard/ViewPicker.d.ts.map +1 -0
- package/dist/ui/dashboard/buildShell.d.ts +44 -0
- package/dist/ui/dashboard/buildShell.d.ts.map +1 -0
- package/dist/ui/dashboard/building.d.ts +44 -0
- package/dist/ui/dashboard/building.d.ts.map +1 -0
- package/dist/ui/dashboard/commands.d.ts +131 -0
- package/dist/ui/dashboard/commands.d.ts.map +1 -0
- package/dist/ui/dashboard/extensions.d.ts +66 -0
- package/dist/ui/dashboard/extensions.d.ts.map +1 -0
- package/dist/ui/dashboard/filterModes.d.ts +60 -0
- package/dist/ui/dashboard/filterModes.d.ts.map +1 -0
- package/dist/ui/dashboard/filterOutcome.d.ts +24 -0
- package/dist/ui/dashboard/filterOutcome.d.ts.map +1 -0
- package/dist/ui/dashboard/findings.d.ts +24 -0
- package/dist/ui/dashboard/findings.d.ts.map +1 -0
- package/dist/ui/dashboard/gridBlocks.d.ts +55 -0
- package/dist/ui/dashboard/gridBlocks.d.ts.map +1 -0
- package/dist/ui/dashboard/gridPlacement.d.ts +38 -0
- package/dist/ui/dashboard/gridPlacement.d.ts.map +1 -0
- package/dist/ui/dashboard/gridWidth.d.ts +33 -0
- package/dist/ui/dashboard/gridWidth.d.ts.map +1 -0
- package/dist/ui/dashboard/history.d.ts +56 -0
- package/dist/ui/dashboard/history.d.ts.map +1 -0
- package/dist/ui/dashboard/landing.d.ts +13 -0
- package/dist/ui/dashboard/landing.d.ts.map +1 -0
- package/dist/ui/dashboard/panelFit.d.ts +43 -0
- package/dist/ui/dashboard/panelFit.d.ts.map +1 -0
- package/dist/ui/dashboard/press.d.ts +50 -0
- package/dist/ui/dashboard/press.d.ts.map +1 -0
- package/dist/ui/dashboard/reveal.d.ts +21 -0
- package/dist/ui/dashboard/reveal.d.ts.map +1 -0
- package/dist/ui/dashboard/scrollMore.d.ts +92 -0
- package/dist/ui/dashboard/scrollMore.d.ts.map +1 -0
- package/dist/ui/dashboard/touchGate.d.ts +30 -0
- package/dist/ui/dashboard/touchGate.d.ts.map +1 -0
- package/dist/ui/embed/EmbedFrame.d.ts +29 -0
- package/dist/ui/embed/EmbedFrame.d.ts.map +1 -0
- package/dist/ui/embed/EmbedHead.d.ts +81 -0
- package/dist/ui/embed/EmbedHead.d.ts.map +1 -0
- package/dist/ui/embed/EmbeddedAnalysis.d.ts +20 -0
- package/dist/ui/embed/EmbeddedAnalysis.d.ts.map +1 -0
- package/dist/ui/embed/EmbeddedRecord.d.ts +33 -0
- package/dist/ui/embed/EmbeddedRecord.d.ts.map +1 -0
- package/dist/ui/embed/options.d.ts +118 -0
- package/dist/ui/embed/options.d.ts.map +1 -0
- package/dist/ui/filter/AddEntry.d.ts +25 -0
- package/dist/ui/filter/AddEntry.d.ts.map +1 -0
- package/dist/ui/filter/AppliedBar.d.ts +39 -0
- package/dist/ui/filter/AppliedBar.d.ts.map +1 -0
- package/dist/ui/filter/ConditionPill.d.ts +38 -0
- package/dist/ui/filter/ConditionPill.d.ts.map +1 -0
- package/dist/ui/filter/FieldChecklist.d.ts +56 -0
- package/dist/ui/filter/FieldChecklist.d.ts.map +1 -0
- package/dist/ui/filter/FilterActions.d.ts +49 -0
- package/dist/ui/filter/FilterActions.d.ts.map +1 -0
- package/dist/ui/filter/FilterModes.d.ts +39 -0
- package/dist/ui/filter/FilterModes.d.ts.map +1 -0
- package/dist/ui/filter/FilterPanel.d.ts +76 -0
- package/dist/ui/filter/FilterPanel.d.ts.map +1 -0
- package/dist/ui/filter/FilterValueEditor.d.ts +103 -0
- package/dist/ui/filter/FilterValueEditor.d.ts.map +1 -0
- package/dist/ui/filter/GroupBlock.d.ts +49 -0
- package/dist/ui/filter/GroupBlock.d.ts.map +1 -0
- package/dist/ui/filter/conditionFocus.d.ts +39 -0
- package/dist/ui/filter/conditionFocus.d.ts.map +1 -0
- package/dist/ui/filter/enter.d.ts +20 -0
- package/dist/ui/filter/enter.d.ts.map +1 -0
- package/dist/ui/filter/groupOperators.d.ts +12 -0
- package/dist/ui/filter/groupOperators.d.ts.map +1 -0
- package/dist/ui/filter/inputs/calendar.d.ts +26 -0
- package/dist/ui/filter/inputs/calendar.d.ts.map +1 -0
- package/dist/ui/filter/inputs/candidates.d.ts +27 -0
- package/dist/ui/filter/inputs/candidates.d.ts.map +1 -0
- package/dist/ui/filter/inputs/chips.d.ts +56 -0
- package/dist/ui/filter/inputs/chips.d.ts.map +1 -0
- package/dist/ui/filter/inputs/date.d.ts +35 -0
- package/dist/ui/filter/inputs/date.d.ts.map +1 -0
- package/dist/ui/filter/inputs/daterange.d.ts +28 -0
- package/dist/ui/filter/inputs/daterange.d.ts.map +1 -0
- package/dist/ui/filter/inputs/duration.d.ts +16 -0
- package/dist/ui/filter/inputs/duration.d.ts.map +1 -0
- package/dist/ui/filter/inputs/number.d.ts +47 -0
- package/dist/ui/filter/inputs/number.d.ts.map +1 -0
- package/dist/ui/filter/inputs/relative.d.ts +23 -0
- package/dist/ui/filter/inputs/relative.d.ts.map +1 -0
- package/dist/ui/filter/inputs/remote.d.ts +20 -0
- package/dist/ui/filter/inputs/remote.d.ts.map +1 -0
- package/dist/ui/filter/inputs/select.d.ts +26 -0
- package/dist/ui/filter/inputs/select.d.ts.map +1 -0
- package/dist/ui/filter/inputs/shared.d.ts +79 -0
- package/dist/ui/filter/inputs/shared.d.ts.map +1 -0
- package/dist/ui/filter/inputs/suggested.d.ts +29 -0
- package/dist/ui/filter/inputs/suggested.d.ts.map +1 -0
- package/dist/ui/filter/inputs/text.d.ts +8 -0
- package/dist/ui/filter/inputs/text.d.ts.map +1 -0
- package/dist/ui/filter/inputs/time.d.ts +29 -0
- package/dist/ui/filter/inputs/time.d.ts.map +1 -0
- package/dist/ui/filter/inputs/timeOfDay.d.ts +38 -0
- package/dist/ui/filter/inputs/timeOfDay.d.ts.map +1 -0
- package/dist/ui/filter/inputs/unsupported.d.ts +33 -0
- package/dist/ui/filter/inputs/unsupported.d.ts.map +1 -0
- package/dist/ui/index.d.ts +123 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/kit/Announcer.d.ts +75 -0
- package/dist/ui/kit/Announcer.d.ts.map +1 -0
- package/dist/ui/kit/CopyButton.d.ts +31 -0
- package/dist/ui/kit/CopyButton.d.ts.map +1 -0
- package/dist/ui/kit/DragHandle.d.ts +84 -0
- package/dist/ui/kit/DragHandle.d.ts.map +1 -0
- package/dist/ui/kit/ExportDialog.d.ts +111 -0
- package/dist/ui/kit/ExportDialog.d.ts.map +1 -0
- package/dist/ui/kit/ExportSteps.d.ts +38 -0
- package/dist/ui/kit/ExportSteps.d.ts.map +1 -0
- package/dist/ui/kit/FieldMenu.d.ts +22 -0
- package/dist/ui/kit/FieldMenu.d.ts.map +1 -0
- package/dist/ui/kit/HandOffMenu.d.ts +29 -0
- package/dist/ui/kit/HandOffMenu.d.ts.map +1 -0
- package/dist/ui/kit/IconButton.d.ts +74 -0
- package/dist/ui/kit/IconButton.d.ts.map +1 -0
- package/dist/ui/kit/MessagesProvider.d.ts +135 -0
- package/dist/ui/kit/MessagesProvider.d.ts.map +1 -0
- package/dist/ui/kit/MixedCheckbox.d.ts +16 -0
- package/dist/ui/kit/MixedCheckbox.d.ts.map +1 -0
- package/dist/ui/kit/OutcomeActions.d.ts +78 -0
- package/dist/ui/kit/OutcomeActions.d.ts.map +1 -0
- package/dist/ui/kit/PendingDot.d.ts +39 -0
- package/dist/ui/kit/PendingDot.d.ts.map +1 -0
- package/dist/ui/kit/RenameInput.d.ts +63 -0
- package/dist/ui/kit/RenameInput.d.ts.map +1 -0
- package/dist/ui/kit/RenderBoundary.d.ts +68 -0
- package/dist/ui/kit/RenderBoundary.d.ts.map +1 -0
- package/dist/ui/kit/RowItem.d.ts +31 -0
- package/dist/ui/kit/RowItem.d.ts.map +1 -0
- package/dist/ui/kit/StatusStrip.d.ts +114 -0
- package/dist/ui/kit/StatusStrip.d.ts.map +1 -0
- package/dist/ui/kit/SystemMark.d.ts +32 -0
- package/dist/ui/kit/SystemMark.d.ts.map +1 -0
- package/dist/ui/kit/Truncated.d.ts +25 -0
- package/dist/ui/kit/Truncated.d.ts.map +1 -0
- package/dist/ui/kit/ViewExpansion.d.ts +89 -0
- package/dist/ui/kit/ViewExpansion.d.ts.map +1 -0
- package/dist/ui/kit/ViewSurface.d.ts +100 -0
- package/dist/ui/kit/ViewSurface.d.ts.map +1 -0
- package/dist/ui/kit/alerts.d.ts +60 -0
- package/dist/ui/kit/alerts.d.ts.map +1 -0
- package/dist/ui/kit/anchor.d.ts +16 -0
- package/dist/ui/kit/anchor.d.ts.map +1 -0
- package/dist/ui/kit/badges.d.ts +34 -0
- package/dist/ui/kit/badges.d.ts.map +1 -0
- package/dist/ui/kit/band.d.ts +49 -0
- package/dist/ui/kit/band.d.ts.map +1 -0
- package/dist/ui/kit/chartFailure.d.ts +19 -0
- package/dist/ui/kit/chartFailure.d.ts.map +1 -0
- package/dist/ui/kit/copyText.d.ts +13 -0
- package/dist/ui/kit/copyText.d.ts.map +1 -0
- package/dist/ui/kit/cspNonce.d.ts +19 -0
- package/dist/ui/kit/cspNonce.d.ts.map +1 -0
- package/dist/ui/kit/currency.d.ts +26 -0
- package/dist/ui/kit/currency.d.ts.map +1 -0
- package/dist/ui/kit/datePart.d.ts +11 -0
- package/dist/ui/kit/datePart.d.ts.map +1 -0
- package/dist/ui/kit/display.d.ts +293 -0
- package/dist/ui/kit/display.d.ts.map +1 -0
- package/dist/ui/kit/download.d.ts +29 -0
- package/dist/ui/kit/download.d.ts.map +1 -0
- package/dist/ui/kit/dragAnnounce.d.ts +51 -0
- package/dist/ui/kit/dragAnnounce.d.ts.map +1 -0
- package/dist/ui/kit/dragDrop.d.ts +36 -0
- package/dist/ui/kit/dragDrop.d.ts.map +1 -0
- package/dist/ui/kit/dragPlugins.d.ts +35 -0
- package/dist/ui/kit/dragPlugins.d.ts.map +1 -0
- package/dist/ui/kit/dragWording.d.ts +15 -0
- package/dist/ui/kit/dragWording.d.ts.map +1 -0
- package/dist/ui/kit/failureSink.d.ts +19 -0
- package/dist/ui/kit/failureSink.d.ts.map +1 -0
- package/dist/ui/kit/features.d.ts +38 -0
- package/dist/ui/kit/features.d.ts.map +1 -0
- package/dist/ui/kit/focus.d.ts +54 -0
- package/dist/ui/kit/focus.d.ts.map +1 -0
- package/dist/ui/kit/kinds.d.ts +54 -0
- package/dist/ui/kit/kinds.d.ts.map +1 -0
- package/dist/ui/kit/layout.d.ts +77 -0
- package/dist/ui/kit/layout.d.ts.map +1 -0
- package/dist/ui/kit/messages.d.ts +56 -0
- package/dist/ui/kit/messages.d.ts.map +1 -0
- package/dist/ui/kit/numbers.d.ts +53 -0
- package/dist/ui/kit/numbers.d.ts.map +1 -0
- package/dist/ui/kit/popups.d.ts +83 -0
- package/dist/ui/kit/popups.d.ts.map +1 -0
- package/dist/ui/kit/presets.d.ts +42 -0
- package/dist/ui/kit/presets.d.ts.map +1 -0
- package/dist/ui/kit/roving.d.ts +32 -0
- package/dist/ui/kit/roving.d.ts.map +1 -0
- package/dist/ui/kit/summary.d.ts +45 -0
- package/dist/ui/kit/summary.d.ts.map +1 -0
- package/dist/ui/kit/toolbar.d.ts +92 -0
- package/dist/ui/kit/toolbar.d.ts.map +1 -0
- package/dist/ui/kit/variants.d.ts +464 -0
- package/dist/ui/kit/variants.d.ts.map +1 -0
- package/dist/ui/lib/utils.d.ts +2 -0
- package/dist/ui/lib/utils.d.ts.map +1 -0
- package/dist/ui/manage/DeleteDialog.d.ts +32 -0
- package/dist/ui/manage/DeleteDialog.d.ts.map +1 -0
- package/dist/ui/manage/ViewManager.d.ts +24 -0
- package/dist/ui/manage/ViewManager.d.ts.map +1 -0
- package/dist/ui/manage/ViewManagerRow.d.ts +96 -0
- package/dist/ui/manage/ViewManagerRow.d.ts.map +1 -0
- package/dist/ui/manage/drag.d.ts +33 -0
- package/dist/ui/manage/drag.d.ts.map +1 -0
- package/dist/ui/messages/actions.d.ts +32 -0
- package/dist/ui/messages/actions.d.ts.map +1 -0
- package/dist/ui/messages/analysis.d.ts +684 -0
- package/dist/ui/messages/analysis.d.ts.map +1 -0
- package/dist/ui/messages/building.d.ts +62 -0
- package/dist/ui/messages/building.d.ts.map +1 -0
- package/dist/ui/messages/bulk.d.ts +27 -0
- package/dist/ui/messages/bulk.d.ts.map +1 -0
- package/dist/ui/messages/capabilities.d.ts +38 -0
- package/dist/ui/messages/capabilities.d.ts.map +1 -0
- package/dist/ui/messages/clicks.d.ts +84 -0
- package/dist/ui/messages/clicks.d.ts.map +1 -0
- package/dist/ui/messages/config.d.ts +12 -0
- package/dist/ui/messages/config.d.ts.map +1 -0
- package/dist/ui/messages/dashboard.d.ts +310 -0
- package/dist/ui/messages/dashboard.d.ts.map +1 -0
- package/dist/ui/messages/definition.d.ts +71 -0
- package/dist/ui/messages/definition.d.ts.map +1 -0
- package/dist/ui/messages/embed.d.ts +11 -0
- package/dist/ui/messages/embed.d.ts.map +1 -0
- package/dist/ui/messages/en.d.ts +2098 -0
- package/dist/ui/messages/en.d.ts.map +1 -0
- package/dist/ui/messages/export.d.ts +50 -0
- package/dist/ui/messages/export.d.ts.map +1 -0
- package/dist/ui/messages/filter.d.ts +263 -0
- package/dist/ui/messages/filter.d.ts.map +1 -0
- package/dist/ui/messages/filters.d.ts +78 -0
- package/dist/ui/messages/filters.d.ts.map +1 -0
- package/dist/ui/messages/header.d.ts +14 -0
- package/dist/ui/messages/header.d.ts.map +1 -0
- package/dist/ui/messages/manage.d.ts +35 -0
- package/dist/ui/messages/manage.d.ts.map +1 -0
- package/dist/ui/messages/record.d.ts +172 -0
- package/dist/ui/messages/record.d.ts.map +1 -0
- package/dist/ui/messages/refresh.d.ts +19 -0
- package/dist/ui/messages/refresh.d.ts.map +1 -0
- package/dist/ui/messages/render.d.ts +11 -0
- package/dist/ui/messages/render.d.ts.map +1 -0
- package/dist/ui/messages/reorder.d.ts +19 -0
- package/dist/ui/messages/reorder.d.ts.map +1 -0
- package/dist/ui/messages/save.d.ts +59 -0
- package/dist/ui/messages/save.d.ts.map +1 -0
- package/dist/ui/messages/scope.d.ts +28 -0
- package/dist/ui/messages/scope.d.ts.map +1 -0
- package/dist/ui/messages/status.d.ts +28 -0
- package/dist/ui/messages/status.d.ts.map +1 -0
- package/dist/ui/messages/view.d.ts +160 -0
- package/dist/ui/messages/view.d.ts.map +1 -0
- package/dist/ui/messages/workbench.d.ts +21 -0
- package/dist/ui/messages/workbench.d.ts.map +1 -0
- package/dist/ui/messages/zh-CN.d.ts +12 -0
- package/dist/ui/messages/zh-CN.d.ts.map +1 -0
- package/dist/ui/record/CardSettings.d.ts +34 -0
- package/dist/ui/record/CardSettings.d.ts.map +1 -0
- package/dist/ui/record/CardSummaries.d.ts +15 -0
- package/dist/ui/record/CardSummaries.d.ts.map +1 -0
- package/dist/ui/record/ColumnResizer.d.ts +67 -0
- package/dist/ui/record/ColumnResizer.d.ts.map +1 -0
- package/dist/ui/record/DetailStructure.d.ts +51 -0
- package/dist/ui/record/DetailStructure.d.ts.map +1 -0
- package/dist/ui/record/EmptyResult.d.ts +41 -0
- package/dist/ui/record/EmptyResult.d.ts.map +1 -0
- package/dist/ui/record/Filler.d.ts +47 -0
- package/dist/ui/record/Filler.d.ts.map +1 -0
- package/dist/ui/record/OffscreenSummary.d.ts +46 -0
- package/dist/ui/record/OffscreenSummary.d.ts.map +1 -0
- package/dist/ui/record/RecordCards.d.ts +53 -0
- package/dist/ui/record/RecordCards.d.ts.map +1 -0
- package/dist/ui/record/RecordDetail.d.ts +45 -0
- package/dist/ui/record/RecordDetail.d.ts.map +1 -0
- package/dist/ui/record/RecordPagination.d.ts +32 -0
- package/dist/ui/record/RecordPagination.d.ts.map +1 -0
- package/dist/ui/record/RecordTable.d.ts +118 -0
- package/dist/ui/record/RecordTable.d.ts.map +1 -0
- package/dist/ui/record/RowActions.d.ts +14 -0
- package/dist/ui/record/RowActions.d.ts.map +1 -0
- package/dist/ui/record/RowCheckbox.d.ts +30 -0
- package/dist/ui/record/RowCheckbox.d.ts.map +1 -0
- package/dist/ui/record/SelectionBar.d.ts +26 -0
- package/dist/ui/record/SelectionBar.d.ts.map +1 -0
- package/dist/ui/record/SkeletonCards.d.ts +11 -0
- package/dist/ui/record/SkeletonCards.d.ts.map +1 -0
- package/dist/ui/record/SkeletonRows.d.ts +33 -0
- package/dist/ui/record/SkeletonRows.d.ts.map +1 -0
- package/dist/ui/record/SortableHeader.d.ts +75 -0
- package/dist/ui/record/SortableHeader.d.ts.map +1 -0
- package/dist/ui/record/SummaryRows.d.ts +43 -0
- package/dist/ui/record/SummaryRows.d.ts.map +1 -0
- package/dist/ui/record/cells.d.ts +41 -0
- package/dist/ui/record/cells.d.ts.map +1 -0
- package/dist/ui/record/columns.d.ts +190 -0
- package/dist/ui/record/columns.d.ts.map +1 -0
- package/dist/ui/record/detailPlacement.d.ts +24 -0
- package/dist/ui/record/detailPlacement.d.ts.map +1 -0
- package/dist/ui/record/emptyWayOut.d.ts +59 -0
- package/dist/ui/record/emptyWayOut.d.ts.map +1 -0
- package/dist/ui/record/exportOffer.d.ts +47 -0
- package/dist/ui/record/exportOffer.d.ts.map +1 -0
- package/dist/ui/record/headerRoving.d.ts +57 -0
- package/dist/ui/record/headerRoving.d.ts.map +1 -0
- package/dist/ui/record/issueNames.d.ts +25 -0
- package/dist/ui/record/issueNames.d.ts.map +1 -0
- package/dist/ui/record/offscreenSummaries.d.ts +81 -0
- package/dist/ui/record/offscreenSummaries.d.ts.map +1 -0
- package/dist/ui/record/openRows.d.ts +43 -0
- package/dist/ui/record/openRows.d.ts.map +1 -0
- package/dist/ui/record/overflow.d.ts +39 -0
- package/dist/ui/record/overflow.d.ts.map +1 -0
- package/dist/ui/record/pinCap.d.ts +68 -0
- package/dist/ui/record/pinCap.d.ts.map +1 -0
- package/dist/ui/record/queryAnnouncement.d.ts +47 -0
- package/dist/ui/record/queryAnnouncement.d.ts.map +1 -0
- package/dist/ui/record/roomBelowRows.d.ts +24 -0
- package/dist/ui/record/roomBelowRows.d.ts.map +1 -0
- package/dist/ui/record/sticky.d.ts +227 -0
- package/dist/ui/record/sticky.d.ts.map +1 -0
- package/dist/ui/record/summaryText.d.ts +10 -0
- package/dist/ui/record/summaryText.d.ts.map +1 -0
- package/dist/ui/record/useOffscreenColumns.d.ts +36 -0
- package/dist/ui/record/useOffscreenColumns.d.ts.map +1 -0
- package/dist/ui/record/useSummaries.d.ts +31 -0
- package/dist/ui/record/useSummaries.d.ts.map +1 -0
- package/dist/ui/sort/SortSettings.d.ts +47 -0
- package/dist/ui/sort/SortSettings.d.ts.map +1 -0
- package/dist/ui/sort/drag.d.ts +53 -0
- package/dist/ui/sort/drag.d.ts.map +1 -0
- package/dist/ui/theme/brandDocs.d.ts +15 -0
- package/dist/ui/theme/brandDocs.d.ts.map +1 -0
- package/dist/ui/theme/densityDocs.d.ts +9 -0
- package/dist/ui/theme/densityDocs.d.ts.map +1 -0
- package/dist/ui/theme/pairs.d.ts +138 -0
- package/dist/ui/theme/pairs.d.ts.map +1 -0
- package/dist/ui/theme/stateDocs.d.ts +149 -0
- package/dist/ui/theme/stateDocs.d.ts.map +1 -0
- package/dist/ui/theme/tokenDocs.d.ts +25 -0
- package/dist/ui/theme/tokenDocs.d.ts.map +1 -0
- package/dist/ui/theme/tokens.d.ts +1526 -0
- package/dist/ui/theme/tokens.d.ts.map +1 -0
- package/dist/ui/viewNavigation.d.ts +39 -0
- package/dist/ui/viewNavigation.d.ts.map +1 -0
- package/dist/ui/workbench/AnalysisParts.d.ts +57 -0
- package/dist/ui/workbench/AnalysisParts.d.ts.map +1 -0
- package/dist/ui/workbench/ConditionBlock.d.ts +20 -0
- package/dist/ui/workbench/ConditionBlock.d.ts.map +1 -0
- package/dist/ui/workbench/ConflictConfirm.d.ts +21 -0
- package/dist/ui/workbench/ConflictConfirm.d.ts.map +1 -0
- package/dist/ui/workbench/EditorBand.d.ts +73 -0
- package/dist/ui/workbench/EditorBand.d.ts.map +1 -0
- package/dist/ui/workbench/LeaveGuard.d.ts +27 -0
- package/dist/ui/workbench/LeaveGuard.d.ts.map +1 -0
- package/dist/ui/workbench/NewView.d.ts +40 -0
- package/dist/ui/workbench/NewView.d.ts.map +1 -0
- package/dist/ui/workbench/NoViews.d.ts +22 -0
- package/dist/ui/workbench/NoViews.d.ts.map +1 -0
- package/dist/ui/workbench/OpeningSkeleton.d.ts +35 -0
- package/dist/ui/workbench/OpeningSkeleton.d.ts.map +1 -0
- package/dist/ui/workbench/OriginBar.d.ts +20 -0
- package/dist/ui/workbench/OriginBar.d.ts.map +1 -0
- package/dist/ui/workbench/RecordParts.d.ts +135 -0
- package/dist/ui/workbench/RecordParts.d.ts.map +1 -0
- package/dist/ui/workbench/RefreshControl.d.ts +70 -0
- package/dist/ui/workbench/RefreshControl.d.ts.map +1 -0
- package/dist/ui/workbench/ResultBlock.d.ts +88 -0
- package/dist/ui/workbench/ResultBlock.d.ts.map +1 -0
- package/dist/ui/workbench/ResultToolbar.d.ts +109 -0
- package/dist/ui/workbench/ResultToolbar.d.ts.map +1 -0
- package/dist/ui/workbench/SaveActions.d.ts +76 -0
- package/dist/ui/workbench/SaveActions.d.ts.map +1 -0
- package/dist/ui/workbench/SaveAsDialog.d.ts +66 -0
- package/dist/ui/workbench/SaveAsDialog.d.ts.map +1 -0
- package/dist/ui/workbench/SearchBox.d.ts +18 -0
- package/dist/ui/workbench/SearchBox.d.ts.map +1 -0
- package/dist/ui/workbench/Sidebar.d.ts +50 -0
- package/dist/ui/workbench/Sidebar.d.ts.map +1 -0
- package/dist/ui/workbench/StatusLine.d.ts +31 -0
- package/dist/ui/workbench/StatusLine.d.ts.map +1 -0
- package/dist/ui/workbench/TitleBar.d.ts +39 -0
- package/dist/ui/workbench/TitleBar.d.ts.map +1 -0
- package/dist/ui/workbench/Unopenable.d.ts +19 -0
- package/dist/ui/workbench/Unopenable.d.ts.map +1 -0
- package/dist/ui/workbench/ViewEngineProvider.d.ts +93 -0
- package/dist/ui/workbench/ViewEngineProvider.d.ts.map +1 -0
- package/dist/ui/workbench/ViewHeader.d.ts +123 -0
- package/dist/ui/workbench/ViewHeader.d.ts.map +1 -0
- package/dist/ui/workbench/ViewList.d.ts +71 -0
- package/dist/ui/workbench/ViewList.d.ts.map +1 -0
- package/dist/ui/workbench/ViewSwitcher.d.ts +49 -0
- package/dist/ui/workbench/ViewSwitcher.d.ts.map +1 -0
- package/dist/ui/workbench/WorkbenchShell.d.ts +291 -0
- package/dist/ui/workbench/WorkbenchShell.d.ts.map +1 -0
- package/dist/ui/workbench/WriteOutcome.d.ts +51 -0
- package/dist/ui/workbench/WriteOutcome.d.ts.map +1 -0
- package/dist/ui/workbench/address.d.ts +84 -0
- package/dist/ui/workbench/address.d.ts.map +1 -0
- package/dist/ui/workbench/bindings.d.ts +45 -0
- package/dist/ui/workbench/bindings.d.ts.map +1 -0
- package/dist/ui/workbench/configRemedy.d.ts +28 -0
- package/dist/ui/workbench/configRemedy.d.ts.map +1 -0
- package/dist/ui/workbench/describeConfig.d.ts +23 -0
- package/dist/ui/workbench/describeConfig.d.ts.map +1 -0
- package/dist/ui/workbench/panelsToFix.d.ts +43 -0
- package/dist/ui/workbench/panelsToFix.d.ts.map +1 -0
- package/dist/ui/workbench/parts.d.ts +33 -0
- package/dist/ui/workbench/parts.d.ts.map +1 -0
- package/dist/ui/workbench/useEditorFold.d.ts +26 -0
- package/dist/ui/workbench/useEditorFold.d.ts.map +1 -0
- package/dist/ui/workbench/useSidebarFold.d.ts +57 -0
- package/dist/ui/workbench/useSidebarFold.d.ts.map +1 -0
- package/dist/ui/workbench/useWorkbenchFolds.d.ts +44 -0
- package/dist/ui/workbench/useWorkbenchFolds.d.ts.map +1 -0
- package/dist/ui.js +43488 -0
- package/dist/ui.js.map +1 -0
- package/dist/viewRuntimeTypes-yK2rlUjK.js +5482 -0
- package/dist/viewRuntimeTypes-yK2rlUjK.js.map +1 -0
- package/package.json +168 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
# Wow View Engine
|
|
2
|
+
|
|
3
|
+
随 Wow 9.2.0 发布,与 Wow 同一个 tag、同一个版本号。
|
|
4
|
+
|
|
5
|
+
> **兼容性。** 从 9.2.0 起,补丁版本(`9.2.x`)不破坏公开面:每个入口的导出,包括后端实现的 `ViewStore` 端口;CSS 合同([什么是公开的](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#什么是公开的));消息键与 issue code;以及 `wow-view-engine` 命令。次版本可以破坏,它的发布说明逐条列出每个破坏与迁移步骤;Wow 包请停在同一个次版本上,见[版本范围](https://wow.ahoo.me/zh/guide/typescript/compatibility#版本范围)。破坏就是干净的改动,从不带兼容层。用户以旧形状保存的视图照常打开:引擎在读取时迁移存储的配置。[docs/design/](https://github.com/Ahoo-Wang/Wow/tree/main/typescript/wow-view-engine/docs/design/) 是模型的唯一依据,本页只说现在的 API。
|
|
6
|
+
|
|
7
|
+
**Wow View Engine 是面向 Wow 业务应用的数据视图引擎。** 业务应用用代码声明一份数据"能被怎样观察":字段、类型、操作符、可用的维度与指标。用户在界面上决定"这一次怎样观察":筛选、列、排序、维度与指标、图表、面板组合。引擎把这种观察方式编译成 Wow 查询、执行、渲染,并把有价值的观察方式保存下来供下次直接打开。
|
|
8
|
+
|
|
9
|
+
它是 `@ahoo-wang/wow-client` 之上的展示层,也是 `@ahoo-wang/fetcher-viewer` 的继任者。
|
|
10
|
+
|
|
11
|
+
## 解决什么问题
|
|
12
|
+
|
|
13
|
+
业务系统里的大多数页面是同一种页面:一张列表,带筛选、排序、分页,偶尔加一张统计图。每个业务对象(订单、库存、客户、工单)都要写一套。运营每提一次"再加一个筛选条件""按仓库拆开看一下""把这几张表放到一个概览页",都要改代码、排期、发版。
|
|
14
|
+
|
|
15
|
+
数据没有变,变的只是观察方式。问题在于观察方式被写死在页面代码里:用户不能自己调整,研发被重复劳动占满,产品把展示层的每次调整都当成需求。
|
|
16
|
+
|
|
17
|
+
## 目标
|
|
18
|
+
|
|
19
|
+
- **用户目标。** 在已声明的能力范围内自己调整数据范围、组织方式与呈现方式,把常用的观察方式保存下来,下次一键重开。
|
|
20
|
+
- **研发目标。** 一个业务对象接入一次,即一份定义加一个查询客户端,之后记录视图、分析视图、仪表盘三类视图不再需要写页面;筛选编辑、查询协调、结果呈现、保存恢复与冲突处理由引擎统一提供。
|
|
21
|
+
- **演进目标。** 新增业务对象只增加定义,不在引擎里加业务分支;自定义布局通过无样式钩子复用同一套行为,不复制一份逻辑。
|
|
22
|
+
|
|
23
|
+
## 价值
|
|
24
|
+
|
|
25
|
+
| 对象 | 得到什么 |
|
|
26
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
27
|
+
| 业务用户 | 不等排期就能得到需要的视图;常用视图保存后直接打开;同一份数据既能看记录,也能按维度看指标,还能看概览 |
|
|
28
|
+
| 研发 | 列表类页面从"每个对象一套"变为"每个对象一份定义";筛选、分页、排序、保存、冲突只实现一次;定义可由 generator 从 Wow 元数据生成 |
|
|
29
|
+
| 产品 | 支持范围内的展示调整不再是需求而是配置;"保存与共享视图"可以作为产品能力交付给客户 |
|
|
30
|
+
|
|
31
|
+
## 场景
|
|
32
|
+
|
|
33
|
+
| 场景 | 视图 | 用户做什么 |
|
|
34
|
+
| -------------------------- | ------------------------------- | -------------------------------------------------------------------------------------- |
|
|
35
|
+
| 仓管每天找待出库订单 | Record | 筛选状态为待出库,按创建时间排序,只显示需要的列,保存为"今日待出库" |
|
|
36
|
+
| 主管比较各仓库积压 | Analysis | 按仓库分组、计数并合计金额,切换为柱状图 |
|
|
37
|
+
| 运营周会看整体情况 | Dashboard | 把上面两个视图放进一个面板页,用全局时间范围同时约束两者 |
|
|
38
|
+
| 业务页面里嵌一块数据 | EmbeddedView、EmbeddedDashboard | 开发者把已保存视图嵌入订单详情页,或把一块仪表盘锁定在这位客户上嵌进客户页,不带工作台 |
|
|
39
|
+
| 运维为新业务对象配基础视图 | 系统视图 | 在定义中声明"全部""待处理""本周新增"三个视图,用户打开即有可用视角,再按需另存 |
|
|
40
|
+
| 客户在租户内自定义报表 | 全部 | 客户保存并共享自己的视图,供应商无需为此发版 |
|
|
41
|
+
|
|
42
|
+
## 不是什么
|
|
43
|
+
|
|
44
|
+
不是数据库或计算后端,不是权限系统,不是通用低代码页面搭建器,也不是 BI 建模工具。数据、聚合能力与授权由业务服务提供,引擎只负责让观察方式可靠地运行。
|
|
45
|
+
|
|
46
|
+
## 安装
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm add @ahoo-wang/fetcher @ahoo-wang/fetcher-decorator \
|
|
50
|
+
@ahoo-wang/fetcher-eventstream @ahoo-wang/wow-client @ahoo-wang/wow-view-engine
|
|
51
|
+
# /react 与 /ui 入口
|
|
52
|
+
pnpm add react react-dom
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
版本号跟随 Wow,次版本可能带有破坏性改动:用 `save-prefix=~` 或 `--save-exact` 让 Wow 包停在同一个次版本上,见[版本范围](https://wow.ahoo.me/zh/guide/typescript/compatibility#版本范围)。
|
|
56
|
+
|
|
57
|
+
Peer 依赖:`@ahoo-wang/wow-client`(以及它需要的 fetcher 包);`react` 与 `react-dom` 只用于 `/react` 和 `/ui` 入口,`react-router` 只用于 `/react-router`,`mingo` 只用于 `/testing`。根入口可在 Node 中运行。要把保存的视图放在 Wow 服务端,再加 [`@ahoo-wang/wow-view-store`](../wow-view-store/README.zh-CN.md)。只提供 ES 模块;Node `>=22.12.0` 或当前的浏览器;TypeScript 6 及以上。
|
|
58
|
+
|
|
59
|
+
## 设计原则
|
|
60
|
+
|
|
61
|
+
| 事实 | 推论 |
|
|
62
|
+
| ---------------------- | ---------------------------------------------------------------------------------------- |
|
|
63
|
+
| **定义是代码。** | 没有定义服务与定义版本。定义变更就是一次发版;保存的视图在打开时按当前定义校验。 |
|
|
64
|
+
| **配置是数据。** | 持久化对象只有 `ViewInstance` 与个人偏好。一致性策略是乐观 revision 加幂等 `requestId`。 |
|
|
65
|
+
| **运行状态是临时的。** | 草稿、结果、分页与选择只活在一个打开的 `ViewRuntime` 中,不持久化。 |
|
|
66
|
+
|
|
67
|
+
## 快速开始
|
|
68
|
+
|
|
69
|
+
### 1. 声明定义
|
|
70
|
+
|
|
71
|
+
<!-- typecheck: file=orders.ts -->
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import type { ViewDefinition } from '@ahoo-wang/wow-view-engine';
|
|
75
|
+
|
|
76
|
+
export const orders: ViewDefinition = {
|
|
77
|
+
id: 'orders',
|
|
78
|
+
title: 'Orders',
|
|
79
|
+
kind: 'data',
|
|
80
|
+
source: 'orders',
|
|
81
|
+
fields: [
|
|
82
|
+
{ name: 'id', label: 'Order', kind: 'string', sortable: true },
|
|
83
|
+
{
|
|
84
|
+
name: 'status',
|
|
85
|
+
label: 'Status',
|
|
86
|
+
kind: 'enum',
|
|
87
|
+
options: [
|
|
88
|
+
{ value: 'PENDING', label: '待出库' },
|
|
89
|
+
{ value: 'SHIPPED', label: '已出库' },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{ name: 'warehouse', label: 'Warehouse', kind: 'string' },
|
|
93
|
+
{
|
|
94
|
+
name: 'amount',
|
|
95
|
+
label: 'Amount',
|
|
96
|
+
kind: 'number',
|
|
97
|
+
summary: ['SUM', 'AVG'],
|
|
98
|
+
},
|
|
99
|
+
{ name: 'createdAt', label: 'Created', kind: 'datetime', sortable: true },
|
|
100
|
+
],
|
|
101
|
+
// 行键必须可排序:每条记录查询的排序都以它收尾,排序值相同的行翻页时才不重不漏
|
|
102
|
+
record: { rowKey: 'id', paging: 'paged', layouts: ['table', 'card'] },
|
|
103
|
+
// 系统视图:开发或运维配置的基础视图,随定义部署,所有用户可见,只读,可另存
|
|
104
|
+
views: [
|
|
105
|
+
{
|
|
106
|
+
id: 'pending',
|
|
107
|
+
title: 'Pending',
|
|
108
|
+
config: {
|
|
109
|
+
kind: 'record',
|
|
110
|
+
filter: {
|
|
111
|
+
op: 'and',
|
|
112
|
+
// enum 是封闭集合,因此提供 IN 与 NOT_IN 而不是 EQ:
|
|
113
|
+
// 一个条件即表达“取其中之一”,两者互换时保留已选项。
|
|
114
|
+
children: [{ field: 'status', operator: 'IN', value: ['PENDING'] }],
|
|
115
|
+
},
|
|
116
|
+
filterMode: 'simple',
|
|
117
|
+
refresh: { interval: null },
|
|
118
|
+
sort: [{ field: 'createdAt', direction: 'DESC' }],
|
|
119
|
+
pageSize: 20,
|
|
120
|
+
summaries: [{ field: 'amount', fn: 'SUM' }],
|
|
121
|
+
layout: 'table',
|
|
122
|
+
table: {
|
|
123
|
+
columns: [
|
|
124
|
+
{ field: 'id' },
|
|
125
|
+
{ field: 'warehouse' },
|
|
126
|
+
{ field: 'amount' },
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
card: { title: 'id', fields: ['status', 'warehouse', 'amount'] },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 从描述符定义视图
|
|
137
|
+
|
|
138
|
+
手写的定义要把服务的查询描述符已经说过的再说一遍:有哪些路径、各存什么、能按什么排序、筛选与聚合。`defineView(descriptor, spec)` 从随定义一起提交的描述符快照里取这些事实,`spec` 只写选择:读者看到哪些字段、什么次序、叫什么,类别的措辞与语气色,单元格,以及收窄什么。结果仍是一份普通的 `DataViewDefinition`,引擎的其余部分不知道它是怎么写的。
|
|
139
|
+
|
|
140
|
+
<!-- typecheck-context
|
|
141
|
+
import type { QueryModelDescriptor } from '@ahoo-wang/wow-client';
|
|
142
|
+
declare const ordersDescriptor: QueryModelDescriptor;
|
|
143
|
+
-->
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { defineView, text } from '@ahoo-wang/wow-view-engine';
|
|
147
|
+
|
|
148
|
+
export const orders = defineView(ordersDescriptor, {
|
|
149
|
+
id: 'orders',
|
|
150
|
+
source: 'orders',
|
|
151
|
+
title: text('orders.title'),
|
|
152
|
+
// 看板的时间筛选经它接到面板上。
|
|
153
|
+
timeField: 'createdAt',
|
|
154
|
+
fields: {
|
|
155
|
+
id: { label: text('orders.id'), cell: 'copyable', analysis: false },
|
|
156
|
+
status: {
|
|
157
|
+
label: text('orders.status'),
|
|
158
|
+
cell: 'status',
|
|
159
|
+
options: {
|
|
160
|
+
PENDING: { label: text('orders.pending'), tone: 'warning' },
|
|
161
|
+
SHIPPED: { label: text('orders.shipped'), tone: 'success' },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
amount: { label: text('orders.amount'), summary: ['SUM'] },
|
|
165
|
+
createdAt: text('orders.createdAt'),
|
|
166
|
+
},
|
|
167
|
+
record: { layouts: ['table', 'card'] },
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- **事实取快照,能力取数据源。** 没列出的字段不出现。种类、枚举值、敏感级别与数组的条目是模型的事实,取自快照;快照没有的路径或值是准入错误(`validateDefinition`、`onIssue`)——定义照样加载,并说出错在哪。路径能怎么排序、筛选、聚合是存储的能力:你没收窄的,定义取它所运行的数据源给的一切(Elasticsearch 上有数组条目里的搜索,MongoDB 上没有);你收窄的——`operators`、`sortable: false`、`summary`、`analysis` 或 `analysis: false`——取你的子集与之相交。收窄超出快照是警告,因为换一个存储可能就有。已弃用的路径在写明理由前一直警告;敏感字段退出分析,机密字段不做任何比较;时刻按日历分组,只有最早与最晚。
|
|
172
|
+
- **快照随代码提交。** 定义在模块加载时就建好,测试里一样。运行时给出描述符的数据源,用它填上你留开的能力、收窄其余,与任何定义一样;不给描述符的数据源按快照的能力跑。
|
|
173
|
+
- **措辞写键。** `text(key)` 占着标签的位置,一份定义服务所有语言。引擎存着的、交出去的都留着键:定义、每个视图的状态与快照、`list()`、编辑器拿到的与交回的,以及存储——从系统视图另存的视图连键一起存,所以换到哪种语言都仍是未修改、还原也对。键只在显示或离开引擎的地方说成话——单元格、表头、图表的 option、导出、无障碍名称、标题——按最近的 `ViewHost` 的 `messages`,缺的退回 `ViewEngineOptions.text`;所以换语言只重画已打开的视图,不重开、不重查、不变脏。自己写的组件用 `/ui` 的 `useSay()` 说,React 之外的代码用 `say(label, words)`;`cellText`、`displayValue` 经上下文的 `say` 说选项标签,`renderCell` 拿到的是原值,键也在内。自己写的编辑器显示成话、交回键:原样留着的话交回原来的键——提交草稿时用 `keptKey(typed, original, say, shown)`(`shown` 是打开时显示的话,打开期间换了语言,没动过的标签也不会变成话),每敲一键就写回的输入框用 `useSaidText(value)`。起始措辞只传到 `ViewHost`、工作台和嵌入画的东西里;自己用 `ViewSurface` 包部件、上面又没有 `ViewHost` 的,给它 `engine={engine}`。界面自己起的名字——「…的副本」、新标签页、新分析的默认标题——是起名时所用语言的话,此后不变。措辞缺的键按键本身显示;写了这个引擎的最外层 `ViewHost` 每种语言报一次(`definition.text.unknown`,起始措辞补上了的报 `definition.text.fallback`)。字面字符串仍可当标签。
|
|
174
|
+
- **时间。** `timeField`——或系统视图自己的,`null` 表示整体读——是看板唯一的日期筛选接到没有接线的面板上所经的字段;手写的接线优先,面板上的 `ignoresTime: true` 让时间范围不作用于它。
|
|
175
|
+
- `/testing` 的 `admit` 在宿主的测试里把这些一并核对([测试宿主](#测试宿主内存数据源))。
|
|
176
|
+
|
|
177
|
+
### 2. 创建引擎
|
|
178
|
+
|
|
179
|
+
<!-- typecheck-context
|
|
180
|
+
import { orders } from './orders';
|
|
181
|
+
import type { QueryApi } from '@ahoo-wang/wow-client';
|
|
182
|
+
declare const queryClients: Record<string, Pick<QueryApi<any>, 'paged' | 'cursor' | 'aggregate'>>;
|
|
183
|
+
-->
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { MemoryViewStore, ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
187
|
+
|
|
188
|
+
const engine = new ViewEngine({
|
|
189
|
+
store: new MemoryViewStore(),
|
|
190
|
+
// 来自 @ahoo-wang/wow-client 的 Pick<QueryApi, 'paged' | 'cursor' | 'aggregate'>
|
|
191
|
+
resources: [{ definition: orders, source: queryClients.orders }],
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
每项**资源**把一份定义与它的数据从哪来配成一对。看板的定义没有数据源——它自己不查数据。数据源按数据定义写的键(`definition.source`)找,所以同一查询模型上的两份定义共用一个;哪里都没有登记数据源的数据定义在注册时就被拒绝(`definition.source.unregistered`):它的工作台说明原因,看板上只有用它的面板熄掉。资源在应用启动时注册一次:**一个应用一个引擎**,各页面共享它的查询、偏好与描述。查询队列按看板规模自己留位——打开的看板在 `maxQueuedQueries` 之外为它的面板留出位置——所以大看板不用调高上限也能整块打开。
|
|
196
|
+
|
|
197
|
+
没有抛出物的发现——定义的准入、描述收窄去掉了什么——交给 `onIssue`。不传时,开发构建(`NODE_ENV` 为 `development`)按资源分组、折叠打印到控制台,每条带改法;生产与测试运行不出声。
|
|
198
|
+
|
|
199
|
+
**服务端收什么:`describe`。** 定义是代码,写的时候不知道部署在哪种存储上:在 Elasticsearch 上能用的短语检索,在没有文本索引的 MongoDB 上会被拒绝;调高了查询守卫的服务端,收的也比引擎的缺省多。给数据源一个 `describe`——wow-client 的 `describeSnapshot`(或 `describeEventStream`)可以直接充当——引擎就在这个源上的第一个视图运行之前读服务端的能力描述,把每份定义收窄到描述允许的范围(描述没有列出的算子、排序、检索、分组或指标不再提供:隐藏,不置灰),并从它读源预算(`maxPageSize`、`maxPageWindow`、`maxAnalysisRows`、`maxQueryFilterNodes`、`maxFilterValues`);超出后两项的查询——按服务端守卫的口径在编译后的查询上数——在发出之前就被拒绝。刷新时、页面切回来时,引擎带着持有的版本重新验证描述,至多每五分钟一次。收窄去掉了什么,按描述版本经 `onIssue` 报一次;描述与定义冲突时——源没有这种分页方式、行键不可排序、时间按另一种单位保存——这份定义像准入不过一样被拒绝。不给 `describe`,视图照旧按定义与缺省上限运行。
|
|
200
|
+
|
|
201
|
+
<!-- typecheck-context
|
|
202
|
+
import { orders } from './orders';
|
|
203
|
+
import type { QueryApi, QueryDescriptorApi } from '@ahoo-wang/wow-client';
|
|
204
|
+
declare const snapshots: Pick<QueryApi<any>, 'paged' | 'cursor' | 'aggregate'>;
|
|
205
|
+
declare const descriptors: QueryDescriptorApi;
|
|
206
|
+
-->
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
import { MemoryViewStore, ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
210
|
+
|
|
211
|
+
// factory.createSnapshotQueryClient() 与 factory.createQueryDescriptorClient():
|
|
212
|
+
// schema 路由没有租户、所有者段,所以是两个客户端。
|
|
213
|
+
const engine = new ViewEngine({
|
|
214
|
+
store: new MemoryViewStore(),
|
|
215
|
+
resources: [
|
|
216
|
+
{
|
|
217
|
+
definition: orders,
|
|
218
|
+
source: {
|
|
219
|
+
paged: snapshots.paged,
|
|
220
|
+
cursor: snapshots.cursor,
|
|
221
|
+
aggregate: snapshots.aggregate,
|
|
222
|
+
describe: descriptors.describeSnapshot,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`limits` 叠在 `DEFAULT_RUNTIME_LIMITS` 之上:只传你要改的。传了的源预算只会压低描述给的值;把 `DEFAULT_RUNTIME_LIMITS` 整个展开进去,就又把它们钉回了缺省。
|
|
230
|
+
|
|
231
|
+
**给 fetcher 设超时。** `@ahoo-wang/fetcher` 缺省不设,引擎也不给查询设:服务端接了连接却不应答时,视图一直停在打开中;几条这样的查询就占满引擎队列的全部并发(`maxConcurrentQueries`),看板上其余面板永远发不出去。在源与存储用的 fetcher 上设一个——`fetcher.timeout = 60_000`,或 `new Fetcher({ timeout })`——超时的查询与别的失败一样报出、可以重试。引擎自己只限一处等待:首次读一个源的能力描述,过了十秒就照声明的定义打开(与读取失败时一样),描述到了再收窄。
|
|
232
|
+
|
|
233
|
+
**导出的文件缺省中和公式。** CSV 会离开页面,在表格软件里被打开,打开的人常常不是导出的人;所以每一处导出——记录视图的行、分析的「导出数据…」——都把文本以 `=`、`+`、`-`、`@`、制表符或回车开头的格子写成前面带一个 `'`(OWASP CSV Injection),表头也算。值是数的格子、以及文本就是一个纯数的格子(如 `-12.5`)照写:表格软件把它读成数,从不求值。文件不进表格软件时可以关掉:`limits: { exportNeutralizeFormulas: false }`;自己调用 `serializeCsv` 时传 `{ neutralizeFormulas: false }`。
|
|
234
|
+
|
|
235
|
+
**失败交给你的监控。** 查询、存储调用、导出、渲染、图表或声明式操作的命令失败时,界面在出事的地方照旧说明;要记日志或送监控,就给环境一个 `onError`。每次失败它被告知一次,带着抛出来的原物和出事的位置;它抛什么都会被吞掉,不给它就什么也不记。
|
|
236
|
+
|
|
237
|
+
<!-- typecheck-context
|
|
238
|
+
import { orders } from './orders';
|
|
239
|
+
import type { QueryApi } from '@ahoo-wang/wow-client';
|
|
240
|
+
declare const queryClients: Record<string, Pick<QueryApi<any>, 'paged' | 'cursor' | 'aggregate'>>;
|
|
241
|
+
declare function sendToMonitoring(record: Record<string, unknown>): void;
|
|
242
|
+
-->
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import { MemoryViewStore, ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
246
|
+
import { browserRuntimeEnvironment } from '@ahoo-wang/wow-view-engine/react';
|
|
247
|
+
|
|
248
|
+
const engine = new ViewEngine({
|
|
249
|
+
store: new MemoryViewStore(),
|
|
250
|
+
resources: [{ definition: orders, source: queryClients.orders }],
|
|
251
|
+
// 不用 React 时写 `defaultRuntimeEnvironment({ onError })`。
|
|
252
|
+
environment: browserRuntimeEnvironment({
|
|
253
|
+
onError: ({ kind, error, context }) =>
|
|
254
|
+
sendToMonitoring({ kind, error, ...context }),
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
| `kind` | 何时告知 | `context.operation` |
|
|
260
|
+
| -------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
261
|
+
| `query` | 视图的查询失败,或它旁边的查询:汇总行、分析的合计、条件的取值 | `query`、`summaries`、`totals`、`split`、`record`、`candidates` |
|
|
262
|
+
| `store` | 一次 `ViewStore` 调用被拒:列表、打开、写入(每次重试各一次,同一个 `requestId`) | 端口的方法名:`list`、`get`、`create`、`save`…… |
|
|
263
|
+
| `export` | 导出的行拉不下来,或文件做不出来、交不出去 | `fetch`、`deliver`、`image` |
|
|
264
|
+
| `render` | 工作台或嵌入里的某一块画的时候抛错——常常是你的动作槽位 | `render` |
|
|
265
|
+
| `chart` | 图表库没加载到,或绘制时抛错 | `load`、`draw` |
|
|
266
|
+
| `action` | 声明式操作的 `run`(或插槽的命令)在某条记录上抛错或超时——动作自己的拒绝不算 | 动作的 `id`;`context.recordKey` 是那条记录 |
|
|
267
|
+
|
|
268
|
+
`context` 在知道时还写明是哪个视图——`definitionId`、`instanceId`、`runtimeId`——`render` 与 `chart` 另有 `boundary`、`panelId` 与 React 的 `componentStack`。被叫停的请求(被下一个顶掉、被取消)不算失败,不告知。工作台、网格与嵌入上的 `onRenderFailure` 照旧:它是那一块界面自己的回调,拿到的是同一个 `error`;`onError` 是整个引擎的。引擎的 `onIssue` 只管没有抛出物的发现,比如定义准入。
|
|
269
|
+
|
|
270
|
+
### 3. 把引擎放在页面之上:`ViewHost`
|
|
271
|
+
|
|
272
|
+
`ViewHost` 是宿主在页面外面要写的唯一一样东西。它由几个端口组成,每个都只是一座桥,通到宿主已经有的东西——**数据**(引擎,连同它的 `resources` 与 `store`)、**路由**、**语言**、**主题**,以及每项资源上的**命令**(`bind`)——路由库、i18n 与主题系统仍是宿主自己的:
|
|
273
|
+
|
|
274
|
+
<!-- typecheck-context
|
|
275
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
276
|
+
import type { ReactNode } from 'react';
|
|
277
|
+
declare const engine: ViewEngine;
|
|
278
|
+
declare const locale: string;
|
|
279
|
+
declare const ordersWords: Record<string, string>;
|
|
280
|
+
declare const orderActions: import('@ahoo-wang/wow-view-engine').RecordActions;
|
|
281
|
+
-->
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
import '@ahoo-wang/wow-view-engine/styles.css';
|
|
285
|
+
import '@ahoo-wang/wow-view-engine/themes/porcelain.css';
|
|
286
|
+
import { useReactRouter } from '@ahoo-wang/wow-view-engine/react-router';
|
|
287
|
+
import { bind, ViewHost } from '@ahoo-wang/wow-view-engine/ui';
|
|
288
|
+
|
|
289
|
+
const bindings = [
|
|
290
|
+
bind('orders', {
|
|
291
|
+
route: view => (view ? `/orders?view=${view}` : '/orders'),
|
|
292
|
+
reading: { title: row => `订单 ${String(row.key)}` },
|
|
293
|
+
actions: orderActions,
|
|
294
|
+
}),
|
|
295
|
+
bind('overview', {
|
|
296
|
+
route: board => (board ? `/boards?view=${board}` : '/boards'),
|
|
297
|
+
}),
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
export function Host({ children }: { children: ReactNode }) {
|
|
301
|
+
return (
|
|
302
|
+
<ViewHost
|
|
303
|
+
engine={engine}
|
|
304
|
+
router={useReactRouter()}
|
|
305
|
+
locale={locale}
|
|
306
|
+
messages={ordersWords}
|
|
307
|
+
bindings={bindings}
|
|
308
|
+
preset="porcelain"
|
|
309
|
+
rememberColorMode="my-app.color-mode"
|
|
310
|
+
>
|
|
311
|
+
{children}
|
|
312
|
+
</ViewHost>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
| 属性 | 端口 | 做什么 |
|
|
318
|
+
| -------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
319
|
+
| `engine` | 数据 | 应用的引擎,建一次。写了它的那层用自己的 `messages` 说出引擎定义里的键 |
|
|
320
|
+
| `router` | 路由 | 宿主的路由:`/react-router` 的 `useReactRouter()`(React Router 是可选 peer,只有这个入口加载它),或在别的路由库上写 `ViewRouter` 的两个成员 |
|
|
321
|
+
| `locale`、`messages` | 语言 | 值按哪种语言显示,以及合并在已生效措辞之上的措辞——引擎自己的(`zhCN`、宿主的改写)与定义的键一样放在这里;一换,所有打开的视图就地重画,还是那些运行时,不重发查询 |
|
|
322
|
+
| `bindings` | 命令 | `bind(definitionId, { route, reading, actions, slots })`:`route(instanceId, target?)` 是打开它的页面路径(没人保存的视图 `instanceId` 为 `null`;引擎要一条链接而不是一条去处时——`useViewNavigation`——不给 `target`);`reading` 是记录详情的选项(`render`、`title`、`sections`);`actions` 是宿主对它的记录的命令,写成声明([接入宿主](#接入宿主声明式操作)),`slots` 是旁边宿主自己的标记——它的工作台、记录详情与所有看板上它的记录面板都挂 |
|
|
323
|
+
| `theme`、`preset`、`brand` | 主题 | [两条路](#主题先选一条路)选其一 |
|
|
324
|
+
| `colorMode`、`rememberColorMode` | 主题 | `<html>` 上的明暗:缺省 `system`,跟随系统;`light`/`dark` 从钉住开始;宿主自己画明暗时写 `host`。`useColorMode()` 给宿主的开关 `{ mode, setMode }`,读者的选择按给的 `localStorage` 键记住 |
|
|
325
|
+
| `navigate` | 路由 | 每一条去处由宿主自己接,不走路由端口:按目标的 `route` 解析好交来——`{ kind: 'route', path, state }`——网址与没有 `route` 的资源原样交来 |
|
|
326
|
+
|
|
327
|
+
**有了路由端口,地址由引擎管。** 离开看板或视图的每一条路——「在工作台中打开」、一组上的追问、面板的去处、回到看板——都去目标资源的 `route`,页面要打开的东西作为这条历史的 state(`ViewRouteState`:交接来的视图、看板的 `filters` 与 `tab`);宿主自己的路径也经路由,别的站点另开。没传 `instanceId` 的 `DataWorkbench`、`DashboardWorkbench` 打开地址的 `?view=`——只认自己定义的视图,一页上两个工作台互不干扰——读者换视图就写回去,每换一个一条历史;没传 `handOver` 的,打开这条历史里交接的视图;没传筛选那一对(`initialFilters`、`onFiltersChange`)或标签页那一对的看板——工作台的,或 `EmbeddedDashboard`——从这条历史读,读者一改就记回去,每块板各记各的,一页上几块板各自找回自己的。绑定了的资源,记录详情跟着 `?id=`,除非它的 `reading` 自己握着 `open`。宿主自己的 props 仍然优先,每一对各算各的。别的路由库只要两个成员:
|
|
328
|
+
|
|
329
|
+
<!-- typecheck-context
|
|
330
|
+
type ViewRouter = import('@ahoo-wang/wow-view-engine/ui').ViewRouter;
|
|
331
|
+
declare const pathname: string;
|
|
332
|
+
declare const search: string;
|
|
333
|
+
declare const state: unknown;
|
|
334
|
+
declare function push(path: string, state: unknown, replace: boolean): void;
|
|
335
|
+
-->
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
const router: ViewRouter = {
|
|
339
|
+
location: { pathname, search, state },
|
|
340
|
+
go: (path, options) => push(path, options?.state, options?.replace ?? false),
|
|
341
|
+
};
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
地址一变就给一个新的路由对象,不变就给同一个——像 `useReactRouter` 那样按地址的几个部分 `useMemo`:读地址的一切只在路由对象换了时重读。
|
|
345
|
+
|
|
346
|
+
**导航是数据。** 引擎画视图、页面归宿主,所以没有整页外壳;`useViewNavigation()` 给宿主的外壳它的去处——每一项绑了 `route` 的资源,按注册的次序:`{ id, kind, title, path, current, views }`,`views` 是它的系统视图(看板定义的就是系统看板),各带 `{ id, title, path, current }`。标题按生效的措辞说,`current` 读路由端口的地址。用宿主自己的组件画——shadcn 的 `Sidebar`、顶栏都行——名字也可以是宿主自己起的:
|
|
347
|
+
|
|
348
|
+
<!-- typecheck: skip — Sidebar、SidebarMenu 与 Link 是宿主自己的组件 -->
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
function AppSidebar() {
|
|
352
|
+
const places = useViewNavigation();
|
|
353
|
+
return (
|
|
354
|
+
<Sidebar>
|
|
355
|
+
<SidebarMenu>
|
|
356
|
+
{places.map(place => (
|
|
357
|
+
<SidebarMenuItem key={place.id}>
|
|
358
|
+
<SidebarMenuButton
|
|
359
|
+
isActive={place.current}
|
|
360
|
+
render={<Link to={place.path} />}
|
|
361
|
+
>
|
|
362
|
+
{place.title}
|
|
363
|
+
</SidebarMenuButton>
|
|
364
|
+
</SidebarMenuItem>
|
|
365
|
+
))}
|
|
366
|
+
</SidebarMenu>
|
|
367
|
+
</Sidebar>
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
它下面的外壳只写这一处与别处不同的:`<DataWorkbench definitionId="orders" />`、`<EmbeddedDashboard instanceId="…" />`。外壳自己的 `engine`、`messages`、`locale`、`onNavigate`、`record` 仍然优先;**ViewHost** 可以嵌套,内层的绑定按 id 覆盖外层——一页两个引擎照样写得出。引擎的定义说的是写了这个引擎的最外层 `ViewHost` 的 `messages`——一个引擎同时只说一种语言——所以内层换一种语言的 `ViewHost`——无论隔几层再写一次这个引擎,还是不写——只改写它之下引擎自己的措辞,不改定义的键;两个并列的 `ViewHost` 写同一个引擎时,须给它同样的措辞。`EmbeddedView` 的 `detail` 按绑定的读法读记录(`render`、`title`、`sections`),但开着哪一条是它自己的:同一定义的两个嵌入不会打开同一条,也不写绑定的 `open`。
|
|
373
|
+
|
|
374
|
+
#### 接入宿主:声明式操作
|
|
375
|
+
|
|
376
|
+
记录上的命令写成声明,不画出来。宿主说**做什么**——记录接哪些命令、什么时候能做、不能做时怎么说、要不要先确认、要什么输入;引擎负责**放在哪、怎样做**:
|
|
377
|
+
|
|
378
|
+
| 宿主声明 | 引擎做 |
|
|
379
|
+
| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
380
|
+
| 有哪些命令,每条的 `run` 调生成的命令客户端 | 放在哪:主操作是行内(与卡片上)的按钮,其余在这条记录的「⋯」菜单里,全部都在多选条与详情里 |
|
|
381
|
+
| 何时可用(`available` 返回 `true` 或理由),何时自己翻转(`changesAt`) | 不可用时置灰并写明理由(提示、按钮的描述、菜单顶端);到点重算,宿主不开定时器 |
|
|
382
|
+
| 口径、语气(`tone`)、要不要先确认(`confirm`)、要什么输入(`form`) | 确认框与表单(条件编辑器的值控件),焦点留在框内,键盘可达,开始与结局都播报 |
|
|
383
|
+
| 命令何时算完成:`run` 在读模型反映之后才 resolve | 多选时:「5 条里 3 条能做」,列出被拒的记录与理由,一键只选能做的;几条一起跑、进度、停止、结局、跑完刷新 |
|
|
384
|
+
|
|
385
|
+
<!-- typecheck-context
|
|
386
|
+
declare const commands: {
|
|
387
|
+
ship(id: string): Promise<void>;
|
|
388
|
+
cancel(id: string): Promise<void>;
|
|
389
|
+
prioritize(id: string, priority: string): Promise<void>;
|
|
390
|
+
};
|
|
391
|
+
declare function holdOf(row: import('@ahoo-wang/wow-view-engine').RecordRow): number;
|
|
392
|
+
-->
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
import { actions, text } from '@ahoo-wang/wow-view-engine';
|
|
396
|
+
|
|
397
|
+
export const orderActions = actions([
|
|
398
|
+
{
|
|
399
|
+
id: 'ship',
|
|
400
|
+
label: text('orders.ship'),
|
|
401
|
+
primary: true,
|
|
402
|
+
// `true`,或者为什么不行——一个键,按读者的语言说。
|
|
403
|
+
available: (row, { now }) =>
|
|
404
|
+
holdOf(row) > now ? text('orders.onHold') : true,
|
|
405
|
+
// 什么时候自己翻转;到点引擎再问一次。
|
|
406
|
+
changesAt: (row, { now }) => (holdOf(row) > now ? holdOf(row) + 1 : null),
|
|
407
|
+
// 一张单按了就发;多选时先数清楚。
|
|
408
|
+
confirm: { title: text('orders.shipTitle'), ask: 'bulk' },
|
|
409
|
+
run: row => commands.ship(String(row.key)),
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
id: 'cancel',
|
|
413
|
+
label: text('orders.cancel'),
|
|
414
|
+
tone: 'danger',
|
|
415
|
+
// `{count}` 是多少条;语言把「一条」说得不同时另写 `-one` 键。
|
|
416
|
+
confirm: {
|
|
417
|
+
title: text('orders.cancelTitle'),
|
|
418
|
+
body: text('orders.cancelBody'),
|
|
419
|
+
},
|
|
420
|
+
run: row => commands.cancel(String(row.key)),
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
id: 'priority',
|
|
424
|
+
label: text('orders.priority'),
|
|
425
|
+
// 只有一个带选项的字段就是选择:选项直接是菜单项。
|
|
426
|
+
form: {
|
|
427
|
+
priority: {
|
|
428
|
+
label: text('orders.priorityField'),
|
|
429
|
+
options: [
|
|
430
|
+
{ value: 'HIGH', label: text('orders.high') },
|
|
431
|
+
{ value: 'NORMAL', label: text('orders.normal') },
|
|
432
|
+
],
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
// 带着选项问:订单已经是的那一项不再提供。
|
|
436
|
+
available: (row, { input }) =>
|
|
437
|
+
input?.priority === row.data.priority
|
|
438
|
+
? text('orders.samePriority')
|
|
439
|
+
: true,
|
|
440
|
+
run: (row, { priority }) =>
|
|
441
|
+
commands.prioritize(String(row.key), String(priority)),
|
|
442
|
+
},
|
|
443
|
+
]);
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
- **`run` 要等读模型反映了命令再 resolve。** 引擎紧接着重读视图,跑在命令前头的刷新读到的是旧状态。Wow 命令等 `CommandStage.SNAPSHOT`(请求头写 `waitStrategy({ stage: CommandStage.SNAPSHOT })`),或宿主投影需要的阶段。它抛出的错误按服务端自己的原因读。
|
|
447
|
+
- `run` 只写一条记录;多选由引擎几条一起跑,停止在两条之间生效。命令有批量版本之前不加 **runMany**。
|
|
448
|
+
- **每条命令都要幂等**——带上这一行显示的聚合版本(`commandHeaders({ aggregateVersion })`,第一次已经生效时第二次按版本冲突被拒,而不是再做一遍),以及服务端据以去重同一次发送的重试的请求 id(`requestId`)。发出之后超时、被中止或断网的 `run`,结局谁也不知道:引擎报「结果未知,先刷新核对」,并取消这些行的选择,不留着诱导一次盲目的重跑;但读者核对后再按一次,也不能退两次款。动作上的 `timeout: ms` 给每条记录一个截止时间(过了就是结果未知);没有它时,「停止」再按一次就不再等待。轮到时被动作拒绝的记录报「未执行」而不是「失败」,并留在选中里。
|
|
449
|
+
- `on: ['row', 'bulk', 'detail']` 收窄出现的位置(缺省处处都有);`hidden: row => …` 让读者不能做的记录干脆不出现这项,`available` 则是出现但置灰并说明。
|
|
450
|
+
- 多个字段(或一个不带选项的字段)的 `form` 在确认框里给出表单:文字、数字或是否,每个字段缺省必填(`required: false` 例外),`initial` 是打开时的值;`run` 按字段名拿到输入。
|
|
451
|
+
- 每个字都是键或文字,在显示处说出(`text(key)`,[措辞与语言](#措辞与语言))。
|
|
452
|
+
- **插槽是逃生口**,画在声明的操作之后:`slots: { row, bulk, global }` 渲染宿主自己的标记——一条链出去的链接、声明说不了的控件。插槽里仍要发命令的,调上下文里的 `run`,结局就报在这个面的那一行上:`row: ({ row, run, busy }) => …`,`run({ title, each: key => … })`。
|
|
453
|
+
|
|
454
|
+
宿主的测试按引擎的读法读这些声明,不画界面——`/testing` 的 `actionHarness`([测试宿主](#测试宿主内存数据源))。
|
|
455
|
+
|
|
456
|
+
### 3a. 渲染默认工作台
|
|
457
|
+
|
|
458
|
+
<!-- typecheck-context
|
|
459
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
460
|
+
declare const engine: ViewEngine;
|
|
461
|
+
-->
|
|
462
|
+
|
|
463
|
+
```tsx
|
|
464
|
+
import '@ahoo-wang/wow-view-engine/styles.css';
|
|
465
|
+
import { DataWorkbench } from '@ahoo-wang/wow-view-engine/ui';
|
|
466
|
+
|
|
467
|
+
export function OrdersPage() {
|
|
468
|
+
return <DataWorkbench engine={engine} definitionId="orders" />;
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
主题跟随宿主:祖先上带 `.dark` class 即为暗色;给 `ViewSurface`(或工作台、嵌入组件)传 `theme="light"` 或 `theme="dark"` 可以把某一处视图钉住,传 `theme="system"` 则跟随读者系统的 `prefers-color-scheme` 并随它实时切换,适合自己没有明暗开关的页面。弹层 portal 到 `<body>` 时带着面从级联里解析出的模式,`.dark` 不必放在 `<html>` 上。预设也是这样选的,见[预设](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#预设)。
|
|
473
|
+
|
|
474
|
+
**导入次序无关,宿主的类在面里照样生效。** `styles.css` 放在宿主自己的 Tailwind 样式之前或之后都行。它的工具类带前缀 `fve:`(`fve:flex`、`fve:md:w-64`),与宿主的不同名:我们的 `fve:md:w-64` 与宿主全局的 `.w-full` 不管次序都是两条规则;宿主写在面里、自己标记上的断点类(`sm:grid-cols-3`)只与宿主自己的规则比。样式表其余部分——preflight、base 与 token——仍收在两个边界里,不加权重(`scripts/verify-package.mjs` 核对每个被样式化的类都带前缀、其余每条规则都在作用域里)。`fve:` 工具类是引擎自己的,不给宿主的标记用:样式表只在引擎某个组件写着它时才有这一条。公开的是 token——见[什么是公开的](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#什么是公开的)。
|
|
475
|
+
|
|
476
|
+
#### 页面自己已有 `main`
|
|
477
|
+
|
|
478
|
+
工作台的主列是页面的 `main` 地标,以开着的视图命名:工作台通常就是页面的主体。宿主页面自己已有 `<main>`、工作台放在它里面时,两个 `main` 就多了一个(axe `landmark-no-duplicate-main`、`landmark-main-is-top-level`),这时给 `DataWorkbench` 或 `DashboardWorkbench` 传 `landmark="region"`:
|
|
479
|
+
|
|
480
|
+
| 属性 | 缺省 | 画成 |
|
|
481
|
+
| ---------- | -------- | --------------------------------------------------------------------------------------------- |
|
|
482
|
+
| `landmark` | `'main'` | `'main'`:以开着的视图命名的 `<main>`。`'region'`:同名的 `<section>`,没开视图时以定义名命名 |
|
|
483
|
+
|
|
484
|
+
两种画法布局一样:样式表按主列自己的一个属性找它,从不按标签。这个属性和所有 `data-slot` 一样是引擎自己的,不是给宿主样式表用的选择器。嵌入本来就不画 `main`,没有这个属性。
|
|
485
|
+
|
|
486
|
+
<!-- typecheck-context
|
|
487
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
488
|
+
declare const engine: ViewEngine;
|
|
489
|
+
import { DataWorkbench } from '@ahoo-wang/wow-view-engine/ui';
|
|
490
|
+
-->
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
export function OrdersPage() {
|
|
494
|
+
return (
|
|
495
|
+
<main>
|
|
496
|
+
<h1>订单</h1>
|
|
497
|
+
<DataWorkbench engine={engine} definitionId="orders" landmark="region" />
|
|
498
|
+
</main>
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
#### 开着哪个视图,与宿主的路由
|
|
504
|
+
|
|
505
|
+
一个数据定义同时装着它的记录视图与分析视图,`DataWorkbench` 把它们列在一张列表里:用户在一张订单表与一张订单图之间切换,就像在任意两个视图之间切换一样,「新建视图」会先问要建哪一种。宿主要一页只有一种,就收窄——`viewKinds={['record']}`——另一种在这一页既不列出也打不开。
|
|
506
|
+
|
|
507
|
+
一个人打开的视图,就是他可以发出去的一条链接。两个工作台因此都收 `instanceId` 与 `onInstanceChange`——进出你的路由的两个方向,`DataWorkbench` 与 `DashboardWorkbench` 契约完全一致。`ViewHost` 带了 `router` 时这两个都不用写:工作台自己把开着的视图记在地址的 `?view=` 里。它们留给把视图记在别处的宿主,或者要决定的不止是视图的页面(控制台的失败执行按链接的 `?cluster=` 收窄视图)。
|
|
508
|
+
|
|
509
|
+
<!-- typecheck-context
|
|
510
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
511
|
+
declare const engine: ViewEngine;
|
|
512
|
+
import { DataWorkbench } from '@ahoo-wang/wow-view-engine/ui';
|
|
513
|
+
declare function useSearchParam(key: string): [string | null, (value: string | null) => void];
|
|
514
|
+
-->
|
|
515
|
+
|
|
516
|
+
```tsx
|
|
517
|
+
export function OrdersPage() {
|
|
518
|
+
// 你的路由给什么都行:path 参数、query、hash。
|
|
519
|
+
const [view, setView] = useSearchParam('view');
|
|
520
|
+
return (
|
|
521
|
+
<DataWorkbench
|
|
522
|
+
engine={engine}
|
|
523
|
+
definitionId="orders"
|
|
524
|
+
instanceId={view}
|
|
525
|
+
onInstanceChange={setView}
|
|
526
|
+
/>
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
`instanceId` 是受控的,语义照 input 的 `value`:
|
|
532
|
+
|
|
533
|
+
- **不传**——非受控形态:开着哪个由工作台自己拿着,从用户的有效默认开始;
|
|
534
|
+
- **传了**——一个视图 id,或 `null` 表示那个有效默认:由你说开哪个,此后每一次变化都打开它所指的视图。`null` 是一个值,不是"没有值";
|
|
535
|
+
- `onInstanceChange(id)` 报的是此刻开着的那个,用同一套说法——`null` 在这里同样指有效默认——所以出来的值可以原样传回去。
|
|
536
|
+
|
|
537
|
+
它**收敛**而不是**渲染**。视图里装着未保存的草稿,所以推进来的值与侧栏上的一次点击走同一道离开守卫:后动的那一方说话,另一方跟上。若守卫问过而用户选择留下,工作台会把**留下的那个**报回来,你的路由不会停在一个没开着的视图上。完整参照见 `examples/PlainRecordWorkbench.tsx`,连浏览器后退一并覆盖。
|
|
538
|
+
|
|
539
|
+
#### 搭仪表盘,以及打开面板背后的视图
|
|
540
|
+
|
|
541
|
+
仪表盘平时是读的:能保存它的人按「编辑」之前,板上什么都不动。编辑中顶上一条编辑条,有「撤销」「重做」、「添加」(数据:已保存的视图,或只属于这块板的新分析;内容:标题、文字、图片、链接)、「添加筛选」(加一个仪表盘筛选,再接到面板上)、「取消」与「保存」,其下的标签栏可以加、改名、排序、删除标签页——面板随改随跑,只有「保存」才存下,走的就是标题栏那次保存。系统仪表盘只读,只有「另存为」。
|
|
542
|
+
|
|
543
|
+
离开这块板的每一条路都经过你给的一个路由 `onNavigate(to)`——包本身从不碰地址。不给,就一条都没有:
|
|
544
|
+
|
|
545
|
+
- 面板「⋯」里的「在工作台中打开」:`{ kind: 'view', definitionId, instanceId, scopeFilter, filter, from }`,面板显示的已保存视图,已经换成那个视图自己的字段名。不归读者的——板子的固定范围,以及页面持有的锁定或隐藏的筛选——是 `scopeFilter`:视图在它之下跑,是作用域,到了工作台谁也拿不掉。读者在板上设的是 `filter`:成为视图自己的条件,于是视图开着就是「已修改」,每一条都能拿掉——全拿掉就回到保存时的样子,不再「已修改」——「还原」一次全拿掉。板内自建的分析交的是 `{ kind: 'unsaved', … }`,读者的值在它的条件里,页面持有的是它的 `scopeFilter`。
|
|
546
|
+
- **点一组**(柱、扇区、表格的一行)打开分析视图的追问菜单(查看这些记录、按其他维度细分、只显示这一组)。每一项都是一个没保存的视图:`{ kind: 'unsaved', definitionId, title, config, scopeFilter, named, from }`,读者的值与这一组已经在它的条件里,页面持有的是作用域;`named` 是标题里那一组,读者把它拿掉后工作台的名字就不再带它。
|
|
547
|
+
- 每一条路交法相同,`from` 是回去的路:把目标交给 `DataWorkbench` 的 `handOver` 属性(每个新对象打开一次),再给同一个 `onNavigate`,工作台就在标题栏下画「返回〈仪表盘〉」,按下交出 `{ kind: 'dashboard', definitionId, instanceId, filters, tab }`——离开时的那块板;只有读者在板子交来的之外又改过,才先问一句。宿主不必自己画返回键。
|
|
548
|
+
- **「点击时…」**(编辑中):面板也可以改为用点中的一组设置仪表盘筛选(交叉筛选——不需要路由;其余接线的面板跟着筛,被点的面板只标出这一组,再点一次撤销),或者去另一个已保存的视图(`{ kind: 'view' }`,交法同上,这一组在它自己的条件里)、另一块仪表盘,或你的一个页面(`{ kind: 'url', url }`,`{{字段}}` 换成点中的值并编码)。
|
|
549
|
+
- **另一块仪表盘**:作者逐个列出目的板的筛选,每个映射到这块面板的一个维度、这块板上一个同类型的筛选,或者不带——不按名字猜。点一组时交给你 `{ kind: 'dashboard', definitionId, instanceId, filters }`:`filters` 就是那块板的 `DashboardFilters`,映射了的筛选是这一组的值或这块板那个筛选点的那一刻的值,其余是它们的默认值。把它交给 `DashboardWorkbench` 的 `initialFilters`(或 `ViewEngine.open` 的 `filters`)——它是读者的,不写进任何一块板的配置。映射失效(筛选或维度被删、那块板被删)时面板上挂 warning,点一组改为打开追问菜单。
|
|
550
|
+
|
|
551
|
+
<!-- typecheck: skip — 并列的两个 JSX 元素,各自是一个示例 -->
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
<DashboardWorkbench
|
|
555
|
+
engine={engine}
|
|
556
|
+
definitionId="overview"
|
|
557
|
+
onNavigate={to => router.push(routeFor(to))}
|
|
558
|
+
/>
|
|
559
|
+
|
|
560
|
+
<DataWorkbench
|
|
561
|
+
engine={engine}
|
|
562
|
+
definitionId={fromRoute.definitionId}
|
|
563
|
+
handOver={fromRoute}
|
|
564
|
+
onNavigate={to => router.push(routeFor(to))}
|
|
565
|
+
/>
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
`DashboardWorkbench`、`EmbeddedDashboard` 与 `EmbeddedView` 收同一个属性。
|
|
569
|
+
|
|
570
|
+
#### 嵌入一个视图或一块仪表盘
|
|
571
|
+
|
|
572
|
+
业务页面要摆出别人已经定好的观察,就嵌入它:只有结果——没有视图列表、没有条件编辑器、没有保存。**嵌入一律不写**:不存视图、不存板子、也不写偏好,读者在上面做的只影响这一次观看。定义视图、搭板子、保存都在工作台里;要让读者在页面上搭板子,就嵌 `DashboardWorkbench`。入口按资源分两个,与工作台的拆法一样:记录或分析视图用 `EmbeddedView`,仪表盘用 `EmbeddedDashboard`。各自只画自己那一种,给错了会直说。
|
|
573
|
+
|
|
574
|
+
<!-- typecheck: skip — 并列的两个 JSX 元素,各自是一个示例 -->
|
|
575
|
+
|
|
576
|
+
```tsx
|
|
577
|
+
import {
|
|
578
|
+
EmbeddedDashboard,
|
|
579
|
+
EmbeddedView,
|
|
580
|
+
} from '@ahoo-wang/wow-view-engine/ui';
|
|
581
|
+
|
|
582
|
+
// 订单页:这位客户最近的运单,照存下的样子读。
|
|
583
|
+
<EmbeddedView
|
|
584
|
+
engine={engine}
|
|
585
|
+
instanceId="orders-pending"
|
|
586
|
+
scopeFilter={{
|
|
587
|
+
op: 'and',
|
|
588
|
+
children: [{ field: 'customer', operator: 'IN', value: [customerId] }],
|
|
589
|
+
}}
|
|
590
|
+
/>
|
|
591
|
+
|
|
592
|
+
// 客户页:客户的那块板,锁定在这位客户上;时间归读者。
|
|
593
|
+
<EmbeddedDashboard
|
|
594
|
+
engine={engine}
|
|
595
|
+
instanceId="customer-board"
|
|
596
|
+
interaction="interactive"
|
|
597
|
+
filterModes={{ customer: 'locked' }}
|
|
598
|
+
pageValues={{
|
|
599
|
+
values: { customer: { items: [{ id: customerId, label: customerName }] } },
|
|
600
|
+
}}
|
|
601
|
+
initialFilters={readFromAddress()}
|
|
602
|
+
onFiltersChange={writeToAddress}
|
|
603
|
+
onNavigate={to => router.push(routeFor(to))}
|
|
604
|
+
/>
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
**读者能走多远是明确的一档**:`interaction`,缺省 `static`。两档都不存任何东西:
|
|
608
|
+
|
|
609
|
+
| 档 | `EmbeddedView`(记录、分析) | `EmbeddedDashboard` |
|
|
610
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
611
|
+
| `static` | 结果与它是在什么条件下取来的;表头不能排序、不能拖宽、没有分页、哪儿也去不了 | 面板照画、什么都不回应:没有追问菜单、没有联动、没有「⋯」;每个筛选读作它的值,没有控件 |
|
|
612
|
+
| `interactive` | 表头排序、拖宽、翻页;分析的表格|图表切换、按一组追问;「在工作台中打开」;开了 `expandable` 时「铺满屏幕」 | 改筛选(搜索类的筛选也是)、追问菜单、交叉筛选、自定义目的地、「在工作台中打开」;开了 `expandable` 时「铺满屏幕」 |
|
|
613
|
+
|
|
614
|
+
离开嵌入的每一条路都经宿主的**一个**路由 `onNavigate(to)`——与仪表盘工作台交出的同一个 `ViewNavigation`;不给就一条也没有。
|
|
615
|
+
|
|
616
|
+
**开关**——关掉就是不存在,不是置灰。档位是上限,开关在档位之内:搜索、导出、记录详情、铺满屏幕是读者的控件,`static` 一档里开了也不起作用:
|
|
617
|
+
|
|
618
|
+
| 属性 | 缺省 | 做什么 |
|
|
619
|
+
| --------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
620
|
+
| `withTitle` | 关 | 画出视图或仪表盘的标题 |
|
|
621
|
+
| `headingLevel` | `2` | 嵌入所标的标题级别:自己的标题在这一级,仪表盘的面板在它下一级(没有标题时就在这一级)。`h1` 归宿主页面 |
|
|
622
|
+
| `withPanelTitles`(仪表盘) | 开 | 关掉时面板标题只留给读屏 |
|
|
623
|
+
| `withSearch`(记录) | 关 | 视图的搜索框,定义声明了搜索字段才有;只在 `interactive` 一档 |
|
|
624
|
+
| `withExport`(记录) | 关 | 导出按钮与窗口,行可以勾选;只在 `interactive` 一档 |
|
|
625
|
+
| `detail`(记录) | 关 | 按一行打开这条记录的详情,读全、只读——没有行命令、什么也不写;`true`(有定义的绑定时按它的 `reading` 读),或与工作台 `record.detail` 同一份选项(`open`/`onOpenChange`、宿主的 `sections`)。在抽屉里打开时是叠在上面的第二层,Esc 只关它,焦点回到那一行。只在 `interactive` 一档 |
|
|
626
|
+
| `withExport`(仪表盘) | 关 | 面板「⋯」里的「导出数据…」,同一个导出窗口;只在 `interactive` 一档 |
|
|
627
|
+
| `autoRefresh` | 开 | 按作者存的间隔自己刷新;关掉就从不自己刷新 |
|
|
628
|
+
| `withRefresh`(仪表盘) | 关 | 首行的「更新于 10:32」——屏幕上的面板何时读的,取最早的那块——`interactive` 一档旁边还有刷新按钮(不带间隔菜单);刷新什么也不写 |
|
|
629
|
+
| `caption`(仪表盘) | 无 | 板子的口径说明(`ReactNode`,如「指标卡读 9 月 21 日(昨日),较前一日」):常态下不画——宿主在自己的标题旁画——铺满屏幕时画在标题下;铺满时 `withTitle` 关着也会用板子自己的标题补一行(D70) |
|
|
630
|
+
| `openInWorkbench` | 开 | `interactive` 一档里给不给「在工作台中打开」 |
|
|
631
|
+
| `expandable` | 关 | `interactive` 一档首行最后的「铺满屏幕」:与工作台一样就地铺开,Esc 收起 |
|
|
632
|
+
| `size` | `content` | `content` 按内容定高、有上限(记录表格与分析表格在 `--fve-record-table-max-h` 里滚);`fill` 填满容器——整页嵌入、大屏 |
|
|
633
|
+
|
|
634
|
+
**仪表盘的筛选逐个三态**(`filterModes` 按筛选名,时间粒度用 `groupingMode`):`adjustable`——在筛选条上、归读者,这一次看时可调,与工作台一样,也是缺省;`locked`——在筛选条上读作它的值,带一把锁、没有控件;`hidden`——不在筛选条上,照样收窄接上的面板。锁定与隐藏由 runtime 持有,读者做什么——改值、「清空」、点一组交叉筛选——都改不了它们。它们的值是页面自己的 `pageValues`(没写就是默认值):从第一次查询起就在,并**跟着这个属性变**——客户页换到下一位客户,板子跟着换。读者的筛选是宿主地址里的那一份:`initialFilters` 与 `onFiltersChange`,读法、报法与 `DashboardWorkbench` 相同。**锁定与隐藏的值从不走地址**:`initialFilters` 里写到它们的条目不算,`onFiltersChange` 只报读者能设的筛选——否则读者改一下地址就换了客户,与「锁定」正相反。板子不收条件树(`EmbeddedDashboard` 没有 `scopeFilter`):要收窄它,在板上声明那个筛选,再锁定或隐藏它。
|
|
635
|
+
|
|
636
|
+
**记录面板上的宿主命令**来自宿主给面板视图所在定义的绑定(`ViewHost` 上的 `bind(definitionId, { actions, slots })`,`EmbeddedDashboard` 与 `DashboardWorkbench` 都一样):记录工作台同一套声明的 `actions`——一条记录的两档都画,选中的只在能勾选的一档(`interactive`)——面板在行上方说执行的进度与结局;命令之后整块板重读。它们是宿主对自己服务的命令,嵌入照旧什么也不写。记录面板也说一共多少条,`interactive` 一档能翻页。
|
|
637
|
+
|
|
638
|
+
**锁定不是安全边界。** 页面锁定的条件是在浏览器里拼进查询的,只保证读者在界面上改不了、在这里看不到别的。改一下页面脚本、直接调接口,就能问到别的客户。租户、归属与权限必须由 Wow 后端强制——对外的页面尤其如此。本包是宿主进程里的库,不照搬 Metabase 的 iframe、签名令牌或 SSO:身份与权限属于宿主与后端。
|
|
639
|
+
|
|
640
|
+
铺满屏幕:开了 `expandable`,可交互的嵌入自己画这颗开关。想把它放在宿主自己的 chrome 里,或让一块 `static` 的大屏铺满,就传一个 `ref`,用 `useViewExpansion` 指向它。
|
|
641
|
+
|
|
642
|
+
#### 主题:先选一条路
|
|
643
|
+
|
|
644
|
+
> **宿主已经在切明暗**(next-themes、自己的 `.dark` 开关)?在 `ViewHost` 上写 **`colorMode="host"`**。不写时引擎也会写 `<html>` 的 `.dark`,两边会互相覆盖。
|
|
645
|
+
|
|
646
|
+
引入 `styles.css`,再在 `ViewHost` 上做一个选择:
|
|
647
|
+
|
|
648
|
+
| 路 | 适合 | 写法 | 引擎做 |
|
|
649
|
+
| ---------- | ------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
650
|
+
| 引擎跟宿主 | 已有 shadcn 主题(Tailwind v4)的宿主 | `theme="host"`,并引入 `shadcn-bridge.css` | 把宿主的 shadcn 变量读进自己的;`input`、`ring`、状态色与图表色仍用本包的,为了对比度 |
|
|
651
|
+
| 宿主跟引擎 | 没有主题、或愿意穿引擎主题的宿主 | `preset="porcelain"`(引入 `themes/porcelain.css`),可加 `brand="#1d4ed8"` | 在 `<html>` 上点名预设与品牌色;宿主自己的外壳挂 `fve-tokens`,拿到同一套 shadcn 名 |
|
|
652
|
+
|
|
653
|
+
```ts
|
|
654
|
+
import '@ahoo-wang/wow-view-engine/styles.css';
|
|
655
|
+
// 引擎跟宿主:
|
|
656
|
+
import '@ahoo-wang/wow-view-engine/shadcn-bridge.css';
|
|
657
|
+
// ……或宿主跟引擎:
|
|
658
|
+
// import '@ahoo-wang/wow-view-engine/themes/porcelain.css';
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**明暗归 `ViewHost`。** 缺省的 `colorMode="system"` 在第一次绘制前写 `<html>` 的 `.dark` 与 `color-scheme`,跟随系统;`light`/`dark` 从钉住开始;读者经 `useColorMode()` 选的,按 `rememberColorMode` 记在本机;`host` 如上,跟宿主的 `.dark`。面上的 `theme="light"`、`"dark"`、`"system"` 仍可钉住某一个视图。宿主自己的暗色值写 `--fve-dark-*`,不写 `.dark` 下的 `--fve-*`:钉在浅色的视图会继承到它。
|
|
662
|
+
|
|
663
|
+
**宿主自己的外壳**挂 `className="fve-tokens"` 穿上主题——挂在用到它的外壳上,不挂 `<body>`:边界里有 preflight——宿主自己的每个弹层离开外壳到了 `<body>`,它的 portal 也挂上(`<Menu.Portal className="fve-tokens">`)。边界里,你自己的类按 shadcn 的名字读主题的 token(`bg-card` 映射到 `var(--card)`);引擎的 `fve:` 工具类不公开([什么是公开的](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#什么是公开的))。
|
|
664
|
+
|
|
665
|
+
其余的——逐个 `--fve-*` 覆盖与完整的 token 表、只给一块面的 `tokens`、逐套预设、品牌色的边界、角色与链接、密度、涨跌色、桥接的细则、覆盖变量要守的线、给 CI 用的 `theme-check`——都在文档站的[视图引擎的主题](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming)。
|
|
666
|
+
|
|
667
|
+
#### 工作台确实交出来的东西:一个值的读法
|
|
668
|
+
|
|
669
|
+
`/ui` 不把自己的 chrome 组件交出去,但它把**读一个值的那套东西**交出去了——改一个单元格,因此不必赔上整个工作台。`renderCell` 只盖住你在意的那一列,其余的交给 `cellValue`,照默认那样画:枚举取定义里的 option 标签、时间走这块面的时区与语言、数字按字段的 `numberFormat`:
|
|
670
|
+
|
|
671
|
+
<!-- typecheck-context
|
|
672
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
673
|
+
declare const engine: ViewEngine;
|
|
674
|
+
declare function OrderStatusLamp(props: { status: string }): React.ReactNode;
|
|
675
|
+
-->
|
|
676
|
+
|
|
677
|
+
```tsx
|
|
678
|
+
import {
|
|
679
|
+
DataWorkbench,
|
|
680
|
+
cellValue,
|
|
681
|
+
useSurfaceDisplay,
|
|
682
|
+
useViewMessages,
|
|
683
|
+
} from '@ahoo-wang/wow-view-engine/ui';
|
|
684
|
+
import type { RecordCell } from '@ahoo-wang/wow-view-engine/ui';
|
|
685
|
+
|
|
686
|
+
function OrderCell({ cell }: { cell: RecordCell }) {
|
|
687
|
+
// 从这个单元格所在的那块面上读:正在生效的措辞,以及值所用的语言与时区。
|
|
688
|
+
const messages = useViewMessages();
|
|
689
|
+
const display = useSurfaceDisplay();
|
|
690
|
+
if (cell.column.field !== 'status') {
|
|
691
|
+
return cellValue(cell.value, cell.column, messages, display, 'table');
|
|
692
|
+
}
|
|
693
|
+
return <OrderStatusLamp status={String(cell.value)} />;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
<DataWorkbench
|
|
697
|
+
engine={engine}
|
|
698
|
+
definitionId="orders"
|
|
699
|
+
// 关于记录视图的话——单元格怎么读、能不能勾选行、空结果说什么——是一个
|
|
700
|
+
// 对象,因为它们对分析视图都没有意义。
|
|
701
|
+
record={{
|
|
702
|
+
renderCell: cell => <OrderCell cell={cell} />,
|
|
703
|
+
selectable: false,
|
|
704
|
+
emptyTitle: '没有待发货的订单',
|
|
705
|
+
}}
|
|
706
|
+
/>;
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
`cellText` 是同一套读法的单行文本版——写 CSV、复制选区、`title` 属性都用它;`displayValue` 只给字段种类自己的那一层,种类没话可说时返回 `undefined`,剩下的交给你自己的渲染。
|
|
710
|
+
|
|
711
|
+
#### 记录详情:你的节,和地址里的那一条
|
|
712
|
+
|
|
713
|
+
按一行(或在行上按 Enter)会在侧边抽屉里把这条记录读全,按定义的字段分组排。`record.detail` 让你往里加东西、并由你来握住开着哪一条:
|
|
714
|
+
|
|
715
|
+
- **`sections(context)`** 按开着的记录返回你自己的节——每节一个 `id`、一个 `title`、一个 `render()`——与引擎的节并排。`placement` 放在 `'start'`、`'end'`(缺省)或 `{ after: '<字段分组 id>' }`。`render` 只在这条记录上屏时才调用,所以节里的 `EmbeddedView` 在读者打开记录时才去读数据;每节是一个有名字的区域,各自包在一道渲染边界里(`'detail'`)。上下文带 `row`(整条读到之前是页上的那一行,读到之后 `complete` 为真)、`runtime` 与 `refresh`,与行动作的上下文一样。节若按自己的读法画定义里的某个字段,就在 `fields` 里点名(`fields: ['state.error.stackTrace']`):引擎的分组不再列它,记录里不会读两遍,被拿空的分组不画。
|
|
716
|
+
- **`render(context)`** 换成你自己的读法:它返回的就是整个正文,替掉定义的分组与你的 `sections`——适合一条记录只回答一个问题(为什么失败、再试有没有用),按自己的版式说比按字段排清楚的时候。面板仍是引擎的:从行上立即打开、读全这条、说它不在/被拒/读不到、头部的行命令、焦点与返回。上下文与渲染边界同 `sections`。**`title(row)`** 在头部用你的名字代替键作标题,键移到名字上方。
|
|
717
|
+
- **`open`/`onOpenChange`** 握住开着的是哪一条,与 `instanceId`/`onInstanceChange` 握住开着的视图同一个做法——`ViewHost` 带了 `router` 时,绑定了的资源的详情已经记在地址的 `?id=` 里,这一对留给记在别处的宿主:不传 `open` 由工作台自己管;传一个键(或 `null`),每个值都打开它说的那一条——不在当前页上的也行,单独读(`runtime.fetchRecord`,只叠注入的作用域),有自己的「正在读」「已不在」「没有权限」(HTTP 401/403)与「读不到、可重试」几种状态。按一行、关掉抽屉都只是经 `onOpenChange` 请求,两种模式下它都会被告知。
|
|
718
|
+
|
|
719
|
+
<!-- typecheck-context
|
|
720
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
721
|
+
import { DataWorkbench, EmbeddedView } from '@ahoo-wang/wow-view-engine/ui';
|
|
722
|
+
declare const engine: ViewEngine;
|
|
723
|
+
declare const params: URLSearchParams;
|
|
724
|
+
declare function setId(id: string | null): void;
|
|
725
|
+
declare function RetryForm(props: { id: string }): React.ReactNode;
|
|
726
|
+
-->
|
|
727
|
+
|
|
728
|
+
```tsx
|
|
729
|
+
<DataWorkbench
|
|
730
|
+
engine={engine}
|
|
731
|
+
definitionId="failures"
|
|
732
|
+
record={{
|
|
733
|
+
detail: {
|
|
734
|
+
// `?id=` 打开那一条,打开或关掉一条都写回地址。
|
|
735
|
+
open: params.get('id'),
|
|
736
|
+
onOpenChange: key => setId(key === null ? null : String(key)),
|
|
737
|
+
sections: ({ row }) => [
|
|
738
|
+
{
|
|
739
|
+
id: 'retry',
|
|
740
|
+
title: '执行上下文',
|
|
741
|
+
placement: 'start',
|
|
742
|
+
render: () => <RetryForm id={String(row.key)} />,
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
id: 'history',
|
|
746
|
+
title: '执行历史',
|
|
747
|
+
render: () => (
|
|
748
|
+
<EmbeddedView
|
|
749
|
+
engine={engine}
|
|
750
|
+
instanceId="execution-history"
|
|
751
|
+
interaction="interactive"
|
|
752
|
+
scopeFilter={{
|
|
753
|
+
op: 'and',
|
|
754
|
+
children: [
|
|
755
|
+
{ field: 'aggregateId', operator: 'EQ', value: row.key },
|
|
756
|
+
],
|
|
757
|
+
}}
|
|
758
|
+
/>
|
|
759
|
+
),
|
|
760
|
+
},
|
|
761
|
+
],
|
|
762
|
+
},
|
|
763
|
+
}}
|
|
764
|
+
/>
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
**面不嵌套。** 根套根不受支持:CSS 没有「最近祖先」选择器,内层面把 token 重新声明在自己身上,`dark:` 工具类认的却仍是外层那个根——钉成相反模式时就是浅色 token 配深色 utility,屏幕上画不出来。需要第二层的时候,戴 `fve-tokens`,不要再套一块面。
|
|
768
|
+
|
|
769
|
+
### 3b. 或者自行组合 UI
|
|
770
|
+
|
|
771
|
+
<!-- typecheck-context
|
|
772
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
773
|
+
declare const engine: ViewEngine;
|
|
774
|
+
declare function Spinner(): React.ReactNode;
|
|
775
|
+
declare function NotFound(): React.ReactNode;
|
|
776
|
+
declare function OrdersLayout(props: Record<string, unknown>): React.ReactNode;
|
|
777
|
+
-->
|
|
778
|
+
|
|
779
|
+
```tsx
|
|
780
|
+
import { isRecordRuntime } from '@ahoo-wang/wow-view-engine';
|
|
781
|
+
import type { RecordViewRuntime } from '@ahoo-wang/wow-view-engine';
|
|
782
|
+
import {
|
|
783
|
+
useOpenView,
|
|
784
|
+
useViewRuntime,
|
|
785
|
+
useFilterEditor,
|
|
786
|
+
useRecordTable,
|
|
787
|
+
} from '@ahoo-wang/wow-view-engine/react';
|
|
788
|
+
|
|
789
|
+
export function OrdersPage({ instanceId }: { instanceId: string }) {
|
|
790
|
+
const { runtime, loading } = useOpenView(engine, instanceId);
|
|
791
|
+
if (!runtime) return loading ? <Spinner /> : <NotFound />;
|
|
792
|
+
// 这个 id 也可能是分析视图或仪表盘;本页只画记录。
|
|
793
|
+
if (runtime.kind !== 'record' || !isRecordRuntime(runtime))
|
|
794
|
+
return <NotFound />;
|
|
795
|
+
return <OrdersView runtime={runtime} />;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
function OrdersView({ runtime }: { runtime: RecordViewRuntime }) {
|
|
799
|
+
const state = useViewRuntime(runtime); // draft、applied、result、issues、dirty
|
|
800
|
+
const filter = useFilterEditor(runtime); // 节点增删改、提交
|
|
801
|
+
const table = useRecordTable(runtime); // 列、排序、选择、分页
|
|
802
|
+
// 用这些控制器渲染任意布局,无需触及引擎内部。
|
|
803
|
+
return <OrdersLayout state={state} filter={filter} table={table} />;
|
|
804
|
+
}
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### 只用内核,不用 React
|
|
808
|
+
|
|
809
|
+
<!-- typecheck-context
|
|
810
|
+
import { orders } from './orders';
|
|
811
|
+
import type { QueryApi } from '@ahoo-wang/wow-client';
|
|
812
|
+
import type { RecordViewConfig } from '@ahoo-wang/wow-view-engine';
|
|
813
|
+
declare const config: RecordViewConfig;
|
|
814
|
+
declare const source: QueryApi<any>;
|
|
815
|
+
-->
|
|
816
|
+
|
|
817
|
+
```ts
|
|
818
|
+
import {
|
|
819
|
+
builtinFieldKinds,
|
|
820
|
+
compileRecord,
|
|
821
|
+
projectRecord,
|
|
822
|
+
validateRecord,
|
|
823
|
+
} from '@ahoo-wang/wow-view-engine';
|
|
824
|
+
|
|
825
|
+
// 内核只接受数据定义;`orders` 就是一个。
|
|
826
|
+
if (orders.kind !== 'data') throw new Error('orders is a data definition');
|
|
827
|
+
const issues = validateRecord(orders, config, builtinFieldKinds);
|
|
828
|
+
if (issues.some(i => i.severity === 'error')) throw new Error('配置无效');
|
|
829
|
+
|
|
830
|
+
const query = compileRecord(
|
|
831
|
+
orders,
|
|
832
|
+
config,
|
|
833
|
+
builtinFieldKinds,
|
|
834
|
+
{ now: new Date(), timeZone: 'Asia/Shanghai' },
|
|
835
|
+
{ index: 1 }, // Wow 页码从 1 开始
|
|
836
|
+
);
|
|
837
|
+
const page = await source.paged(query);
|
|
838
|
+
const view = projectRecord(orders, config, page);
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
## 测试宿主:内存数据源
|
|
842
|
+
|
|
843
|
+
宿主自己的测试——打开一个视图或一块板的页面、没有后端的演示——需要一个按引擎实际发出的查询作答的数据源。`@ahoo-wang/wow-view-engine/testing` 提供了它:`memorySource(documents, options?)` 是一个 `ViewSource`,对内存里的 JSON 文档像 MongoDB 上的 Wow 服务那样筛选、排序、分页、投影与聚合。它的答案由本包的测试对照服务端自己的语义——`wow-tck` 的 `FilterSemantics` 语义矩阵与查询 TCK 的聚合用例——逐条守着,所以测试看到的是引擎的查询按生产环境的方式得到的回答,而不是一份把被筛掉的行也显示出来的罐头结果。
|
|
844
|
+
|
|
845
|
+
<!-- typecheck-context
|
|
846
|
+
import { orders } from './orders';
|
|
847
|
+
-->
|
|
848
|
+
|
|
849
|
+
```ts
|
|
850
|
+
import { FilterOperator } from '@ahoo-wang/wow-client';
|
|
851
|
+
import { MemoryViewStore, ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
852
|
+
import { matches, memorySource } from '@ahoo-wang/wow-view-engine/testing';
|
|
853
|
+
|
|
854
|
+
// 服务返回的快照:信封字段、`state`、以纪元毫秒存的时间。
|
|
855
|
+
const documents = [
|
|
856
|
+
{
|
|
857
|
+
aggregateId: 'O-1',
|
|
858
|
+
eventTime: 1_790_000_000_000,
|
|
859
|
+
state: { status: 'PAID', total: 120 },
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
aggregateId: 'O-2',
|
|
863
|
+
eventTime: 1_790_000_060_000,
|
|
864
|
+
state: { status: 'CANCELLED', total: 80 },
|
|
865
|
+
},
|
|
866
|
+
];
|
|
867
|
+
const source = memorySource(documents, {
|
|
868
|
+
// BEFORE_NOW / AFTER_NOW 比较的钟:与页面的钟钉在同一时刻。
|
|
869
|
+
now: () => Date.parse('2026-09-27T00:00:00Z'),
|
|
870
|
+
});
|
|
871
|
+
const engine = new ViewEngine({
|
|
872
|
+
resources: [{ definition: orders, source }],
|
|
873
|
+
store: new MemoryViewStore(),
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
// 测试自己的条件,按同样的读法问一条文档。
|
|
877
|
+
const paid = matches(documents[0], {
|
|
878
|
+
op: FilterOperator.EQ,
|
|
879
|
+
field: 'state.status',
|
|
880
|
+
value: 'PAID',
|
|
881
|
+
});
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
它承诺的:引擎会编出的每个筛选算子,缺失字段、显式 `null`、空字符串或空数组、数组元素与大小写都按 MongoDB 的读法;`DELETION` 读 `deleted` 标记(`deleted: true` 的文档除非筛选问到,否则不答);分页、游标(一个偏移量)与排序;投影;聚合——`elements`(路径与门槛条件都相对于元素)、`TERMS`、`HISTOGRAM`、按时区的 `DATE_HISTOGRAM` 与 `DATE_PART`(缺省 UTC)、`dense`、带自身条件的每种指标、`DERIVED`、`having`、Wow 给分组的次序(先按排序,再按每个分组别名升序)与缺省 `limit` 100。`PERCENTILE` 是精确值,服务端是落在同样两个秩之间的估计值。没有读法的——`ID`、`TENANT_ID`、`SPACE_ID`、引擎从不发出的日历筛选——直接报错,测试开始发出的新查询会失败,而不是得到一个看似合理的错误答案。`timeField` 让大数据集按一个纪元毫秒列排好、对它的范围二分切片;`remember` 让同一个聚合从记忆里作答,只用于从不改变的文档。这个入口是无头的——没有 React、DOM 与样式表。它用 `mingo`(MongoDB 查询语言的 JavaScript 实现)求值筛选,`mingo` 是可选的对等依赖:安装本包不会带上它,导入 `/testing` 的宿主要自己把它加进开发依赖——`pnpm add -D mingo`(或 `npm install -D mingo`)。别的入口都不加载它。
|
|
885
|
+
|
|
886
|
+
`admit(definitions, descriptors, { text })` 按引擎的方式准入宿主声明的一切——说出每份定义的键、它自己的规则、它的看板对照其余定义、每份数据定义按提交的描述符(按 `source`)收窄——返回每条发现连同它所属的定义,全部成立时是 `[]`。它收定义,也收装着定义的资源(`{ definition }`),与注册时的写法一样:
|
|
887
|
+
|
|
888
|
+
<!-- typecheck-context
|
|
889
|
+
import type { QueryModelDescriptor } from '@ahoo-wang/wow-client';
|
|
890
|
+
import type { DataViewDefinition, DashboardDefinition, TextResolver } from '@ahoo-wang/wow-view-engine';
|
|
891
|
+
declare const orders: DataViewDefinition;
|
|
892
|
+
declare const overview: DashboardDefinition;
|
|
893
|
+
declare const ordersDescriptor: QueryModelDescriptor;
|
|
894
|
+
declare const chinese: TextResolver;
|
|
895
|
+
declare function expect(value: unknown): { toEqual(expected: unknown): void };
|
|
896
|
+
-->
|
|
897
|
+
|
|
898
|
+
```ts
|
|
899
|
+
import { admit } from '@ahoo-wang/wow-view-engine/testing';
|
|
900
|
+
|
|
901
|
+
expect(
|
|
902
|
+
admit([orders, overview], { orders: ordersDescriptor }, { text: chinese }),
|
|
903
|
+
).toEqual([]);
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
`actionHarness(actions, rows, { now })` 按引擎自己的规则读宿主声明的操作,不渲染:每项出现在哪(`at`)、某条记录能不能做、为什么不能(`state`)、一组选中怎么分(`bulk`)、按下会问什么(`asks`)、它的表单或选择(`form`、`choice`、`missing`)、记录什么时候自己翻转(`changesAt`),以及照引擎那样发出的 `run`——记录不接时带着理由拒绝(`ActionRefusedError`):
|
|
907
|
+
|
|
908
|
+
<!-- typecheck-context
|
|
909
|
+
import { text } from '@ahoo-wang/wow-view-engine';
|
|
910
|
+
import type { RecordActions, RecordRow } from '@ahoo-wang/wow-view-engine';
|
|
911
|
+
declare const orderActions: RecordActions;
|
|
912
|
+
declare const rows: RecordRow[];
|
|
913
|
+
declare function expect(value: unknown): { toEqual(expected: unknown): void; toBe(expected: unknown): void };
|
|
914
|
+
-->
|
|
915
|
+
|
|
916
|
+
```ts
|
|
917
|
+
import { actionHarness } from '@ahoo-wang/wow-view-engine/testing';
|
|
918
|
+
|
|
919
|
+
const orders = actionHarness(orderActions, rows, {
|
|
920
|
+
now: Date.parse('2026-09-28'),
|
|
921
|
+
});
|
|
922
|
+
expect(orders.state('ship', 'O-2').reason).toBe(text('orders.onHold'));
|
|
923
|
+
expect(orders.bulk('ship').able).toEqual(['O-1']);
|
|
924
|
+
expect(orders.asks('cancel', 'row').asks).toBe(true);
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
## 概念
|
|
928
|
+
|
|
929
|
+
| 类型 | 职责 | 所在 |
|
|
930
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
|
|
931
|
+
| `ViewDefinition` | 字段、类型、操作符、记录与分析能力。由代码声明或生成,运行时不可编辑。 | 代码 |
|
|
932
|
+
| `ViewConfig` | `RecordViewConfig` / `AnalysisViewConfig` / `DashboardViewConfig` 判别联合,共享的 `FilterTree` 描述数据范围。它是意图模型:保存"最近 7 天"这样的语义而不是编译结果,也不含任何 UI 组件名。Analysis 覆盖 Wow 聚合协议全部能力;Dashboard 面板分数据面板(引用已保存的视图,或板子自己的分析)与标题、Markdown 文字、图片、链接四种内容面板。 | 数据 |
|
|
933
|
+
| `ViewInstance` | 一份保存的 `ViewConfig`,加 id、标题、范围与不透明 `revision`。范围为系统、共享或个人。 | 存储 |
|
|
934
|
+
| `ViewRuntime` | 一个打开的视图:草稿、已应用配置、结果、状态、选择。提供 `subscribe` / `getSnapshot`。 | 内存 |
|
|
935
|
+
| `ViewEngine` | 定义、存储与已打开运行时的注册表;打开、保存、列表等命令的入口。 | 内存 |
|
|
936
|
+
| `ViewStore` | 八个方法(外加可选的 `changeAudience`)的持久化端口。Wow 服务端用 `@ahoo-wang/wow-view-store` 的 `WowViewStore`;别的后端自己实现。 | 应用 |
|
|
937
|
+
| `FieldKind` | 一种字段类型的操作符、校验、编译与编辑器描述。 | 注册表 |
|
|
938
|
+
|
|
939
|
+
有三个名字各有两种读法,这里说清哪个是哪个:
|
|
940
|
+
|
|
941
|
+
- **`*Spec`** 要么是宿主提供的,要么是视图存下的。`DefineViewSpec`、`FieldSpec`、`FieldAnalysisSpec` 与 `AnalysisSpec` 是宿主交给 `defineView` 的输入——它提供的字段、操作符与分析;`ChartSpec`、`RecordTableSpec`、`AnalysisTableSpec` 与各图型的 `*Spec` 是存下的 `ViewConfig` 的部件。
|
|
942
|
+
- **`RecordProjection` / `AnalysisProjection`** 是 `projectRecord` / `projectAnalysis` 从结果投影出来的东西:界面画的列、行与系列。「视图」指保存的 `ViewInstance`;`/ui` 的 `RecordViewProps` 是工作台的 `record` 属性,不是投影的。
|
|
943
|
+
- **`kinds`** 在 `ViewEngineOptions` 与 `ViewEngine` 上是字段类型注册表;`DataWorkbench` 的 `viewKinds` 是它列出哪几种视图(`'record'`、`'analysis'`)。
|
|
944
|
+
|
|
945
|
+
## 视图管理
|
|
946
|
+
|
|
947
|
+
- **生命周期。** 新建、保存、另存、改名、删除全部是 `ViewEngine` 命令,默认 UI 与自定义组合走同一路径。保存的只有配置,不含选择、页码与结果。
|
|
948
|
+
- **三种范围。** `system` 由开发或运维配置,是定义的基础视图与常用视图,所有用户可见、只读、可另存,可在 `definition.views` 中用代码声明,也可由服务端返回;`shared` 由有许可的业务用户创建并对同定义用户可见;`personal` 仅本人可见。
|
|
949
|
+
- **两个问题,一个值。** 三种范围是"给谁看"与"是不是用户配置的"两件事的合法组合:系统视图一定是共享视图,"个人的系统视图"写都写不出来。`audienceOf(scope)` 回答前者,`isSystemScope(scope)` 回答后者,从 Dashboard 的引用约束到侧栏分组都经由它们提问;用户创建时给的是 `ViewAudience` 而不是范围。
|
|
950
|
+
- **侧栏。** 视图按受众分组——个人在前、共享在后,系统视图落在共享组里并带 `system` 标签——每项以种类图标作前缀,因为一个 data 定义同时承载记录与分析视图;标题取自定义本身。`ViewInstanceSummary` 为此带上 `kind`:它是配置判别标签的投影,store 回答 `list` 时从自己存的配置里读出来。
|
|
951
|
+
- **许可。** `store.permissions()` 同步提供许可,只决定按钮可用性,服务端才是权威。无权修改的共享视图与系统视图都可另存到个人范围。
|
|
952
|
+
- **列表与偏好。** 列表、偏好、许可独立加载,互不阻塞;个人排序与默认视图存于 `ViewPreferences`,删除实例不改写偏好。
|
|
953
|
+
- **冲突与未知结果。** 版本冲突时二选一:重新加载或覆盖,另加"另存";请求已发出但结果未知时可用同一 `requestId` 重试,草稿始终保留。
|
|
954
|
+
- **离开保护。** 有未保存草稿或未知写入的视图关闭前确认;导航不取消在途写入。
|
|
955
|
+
|
|
956
|
+
细节见 [docs/design/management.md](https://github.com/Ahoo-Wang/Wow/blob/main/typescript/wow-view-engine/docs/design/management.md)。
|
|
957
|
+
|
|
958
|
+
## 入口
|
|
959
|
+
|
|
960
|
+
| 入口 | 导出 |
|
|
961
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
962
|
+
| `@ahoo-wang/wow-view-engine` | 模型类型与常量;四个纯内核(`validate*` / `compile*` / `project*` 及其旁边的读法);运行时只导出宿主要握的,不导出它由什么搭成——`ViewEngine`、`validateDefinition`、运行时合同 `ViewRuntime`、`RecordViewRuntime`、`DashboardRuntime`、`AnyViewRuntime` 连同它们签名里出现的每一个类型、`hasResult`、`hasAsked`、`isRecordRuntime`、`actions` 连同声明式操作的类型、写入错误 `ViewWriteError` 与 `ViewCommandError`、`ExportCancelledError`、`RuntimeEnvironment`、`defaultRuntimeEnvironment`、`ViewSource`、`OptionSource`;`ViewStore` 端口、`MemoryViewStore` 与 `localStorageSnapshot` |
|
|
963
|
+
| `/react` | 钩子与无样式控制器,连同它们交出的类型:`useViewEngine`、`useOpenView`、`useViewRuntime`、`useViewList`、`useViewManager`、`useWorkbench`、`useLeaveGuard`、`useFilterEditor`、`useRecordTable`、`useAnalysisEditor`、`useAnalysisResult`、`useDashboard`、`useSaveCommands`、`useRecordActions`(一个记录面上的声明式操作:每条记录与选中的能做什么、等读者回答的确认或表单、唯一的执行器)、`RecordActionSlots`,以及保存命令报告的两个写入结局类型(`SettledWrite`、`RecoveredWrite`) |
|
|
964
|
+
| `/ui` | 默认组件、视图与工作台,连同它们的 props:`DataWorkbench`、`DashboardWorkbench`、`DashboardEditExtensions`、`useDashboardExtensions`、`EmbeddedView`、`EmbeddedDashboard`、`ViewHost`、`bind`、`useEngine`、`useViewNavigation`、`useColorMode`、`ViewHeader`、`SaveActions`、`ViewManager`、`LeaveDialog`、`EditorBand`、`FilterPanel`、`StatusStrip`、`AppliedBar`、`ResultToolbar`、`RowActions`、`RecordTable`、`RecordCards`、`RecordPagination`、`AnalysisTable`、`AnalysisChart`、`DashboardGrid`、`HeadingPanel`、`MarkdownPanel`、`ImagePanel`、`LinksPanel`、`MessagesProvider`;措辞目录 `en` 与 `zhCN`;一个值的读法 `cellValue`、`cellText`、`displayValue` |
|
|
965
|
+
| `/testing` | `memorySource` 与 `matches`:带 Wow 查询语义的内存 `ViewSource`;`resolveNavigation`:引擎自己按宿主绑定解析离开的路,供宿主测路由;`admit`:按提交的描述符准入宿主的声明;`actionHarness`:按引擎的规则读宿主声明的操作,不画界面——供宿主测试使用([测试宿主](#测试宿主内存数据源)) |
|
|
966
|
+
| `/react-router` | `useReactRouter`:把 React Router 接成视图宿主的路由端口。React Router 是可选 peer,只有这个入口加载它 |
|
|
967
|
+
| `/styles.css` | 主题。显式导入;任何 JS 入口都不会引入 CSS,产物也不会在 `.fve-root`/`.fve-tokens` 两个样式边界之外绘制任何东西(preflight 与 base 在构建时收进边界内、不加权重,工具类一律带 `fve:` 前缀、与宿主的不同名,所以宿主的导入次序无关)——预设的复位规则除外,它只在挂了预设的元素上清空 `--fvp-*` 层——`scripts/verify-package.mjs` 在每次构建时逐条核对。 |
|
|
968
|
+
| `/themes.css` | 预设,可选:只有按 `data-fve-preset` 选中的 `--fvp-*` 赋值([预设](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#预设)),由同一个脚本核对。 |
|
|
969
|
+
| `/themes/<名>.css` | 单独一套预设,给只用一套的宿主:就是 `themes.css` 里它那一块([预设](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#预设))。 |
|
|
970
|
+
| `/shadcn-bridge.css` | 可选:把宿主的 shadcn token 读进 `--fvp-*` 变量,`input`、`ring`、状态色、图表色与阴影除外,且只在没挂预设时生效([桥接](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#shadcn-桥接)),由同一个脚本核对。 |
|
|
971
|
+
|
|
972
|
+
这就是公开面,而且逐个名字守着。每个入口把它导出的名字逐个写出,按声明它的文件分组,不整模块转出(`test/architecture.test.ts`),所以文件为包内邻居写的 `export` 不会意外变成公开的。每个代码入口的完整清单——每一个名字,以及它是类型还是值——在 `test/surface/`(`root.txt`、`react.txt`、`ui.txt`、`testing.txt`、`react-router.txt`):入口多导出了清单上没有的名字、或不再导出清单上有的名字,`test/publicSurface.test.ts` 就失败;`scripts/verify-package.mjs` 再拿同一份清单核对构建出的每个 JS 入口。往清单里加一个名字或拿掉一个,就是改公开面,按改公开面来审。命令也是公开面:`test/surface/bin.txt` 列出 `bin`(`wow-view-engine`)与它认的每个子命令([`theme-check`](https://wow.ahoo.me/zh/guide/typescript/view-engine-theming#检查一套主题))。
|
|
973
|
+
|
|
974
|
+
运行时自己的部件不导出:请求调度器、两种运行时共用的那个 store、刷新计时器、监听者集合、运行时的类与它们的构造函数。运行时经 `ViewEngine` 打开或新建、按合同持有,从不手搭;`/react` 与 `/ui` 在包内直接取这些部件,不经入口。
|
|
975
|
+
|
|
976
|
+
## 持久化
|
|
977
|
+
|
|
978
|
+
后端只需满足 `ViewStore` 这一个端口:
|
|
979
|
+
|
|
980
|
+
```ts
|
|
981
|
+
interface ViewStore {
|
|
982
|
+
list(
|
|
983
|
+
definitionId: string,
|
|
984
|
+
signal?: AbortSignal,
|
|
985
|
+
): Promise<ViewInstanceSummary[]>;
|
|
986
|
+
get(id: string, signal?: AbortSignal): Promise<ViewInstance>;
|
|
987
|
+
create(
|
|
988
|
+
input: Omit<ViewInstance, 'id' | 'revision'>,
|
|
989
|
+
ctx: WriteContext,
|
|
990
|
+
): Promise<ViewInstance>;
|
|
991
|
+
save(
|
|
992
|
+
id: string,
|
|
993
|
+
config: ViewConfig,
|
|
994
|
+
revision: string,
|
|
995
|
+
ctx: WriteContext,
|
|
996
|
+
): Promise<ViewInstance>;
|
|
997
|
+
rename(
|
|
998
|
+
id: string,
|
|
999
|
+
title: string,
|
|
1000
|
+
revision: string,
|
|
1001
|
+
ctx: WriteContext,
|
|
1002
|
+
): Promise<ViewInstance>;
|
|
1003
|
+
delete(id: string, revision: string, ctx: WriteContext): Promise<void>;
|
|
1004
|
+
// 可选:没有它,视图管理里就没有「设为共享/设为个人」。
|
|
1005
|
+
changeAudience?(
|
|
1006
|
+
id: string,
|
|
1007
|
+
audience: ViewAudience,
|
|
1008
|
+
revision: string,
|
|
1009
|
+
ctx: WriteContext,
|
|
1010
|
+
): Promise<ViewInstance>;
|
|
1011
|
+
getPreferences(
|
|
1012
|
+
definitionId: string,
|
|
1013
|
+
signal?: AbortSignal,
|
|
1014
|
+
): Promise<ViewPreferences>;
|
|
1015
|
+
setPreferences(
|
|
1016
|
+
definitionId: string,
|
|
1017
|
+
prefs: ViewPreferences,
|
|
1018
|
+
ctx: WriteContext,
|
|
1019
|
+
): Promise<ViewPreferences>;
|
|
1020
|
+
permissions?(definitionId: string): ViewPermissions;
|
|
1021
|
+
}
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
两条规则保证一致性:
|
|
1025
|
+
|
|
1026
|
+
1. **乐观 revision。** 写入携带期望 `revision`,不匹配时抛出 code 为 `CONFLICT` 的 `ViewStoreError`,UI 提供"重新加载后覆盖"或"另存"。
|
|
1027
|
+
2. **幂等 `requestId`。** 每个逻辑写入在 `WriteContext` 中携带一次 `requestId`,超时后的重试复用它,服务端去重。
|
|
1028
|
+
|
|
1029
|
+
`changeAudience` 把已保存的视图就地在个人与共享之间移动——id 不变,显示它的仪表盘照常显示。它守同样两条规则;要求改成视图已有的受众时原样答回、不花 revision;共享仪表盘还在显示它时拒绝改成个人(`INVALID`,`boards` 带上那些仪表盘的标题,由引擎用自己的话说出来)。没有这个方法的 store,视图管理里就没有这颗按钮;有的,每一行按 store 的 `permissions` 给「设为共享」或「设为个人」——`instance(id).changeAudience`(缺省读作允许)加上去往那个受众的创建许可。
|
|
1030
|
+
|
|
1031
|
+
实现 store 时可以跑端口一致性测试 `test/conformance/viewStoreConformance.ts`(在本包的仓库里,不随包发布):`describeViewStoreConformance({ name, capabilities, connect })` 登记每个 store 都要通过的用例——列表、可见性、各种写入、过期 revision、系统视图、重放、偏好——声明不具备的能力对应的用例跳过。
|
|
1032
|
+
|
|
1033
|
+
本包提供 `MemoryViewStore`,用于测试、示例与只查询不持久化的场景。Wow 应用把视图存在 Wow 的视图存储服务端上,用 `@ahoo-wang/wow-view-store` 的 [`WowViewStore`](../wow-view-store/README.zh-CN.md);不要为 Wow 后端自己写 store。别的后端用自己的 fetcher 针对自己的 API 实现 `ViewStore`,HTTP 状态码到 `ViewStoreError.code` 的映射在那里完成。授权、可见性过滤与去重是服务端职责,`permissions` 只决定按钮可用性。
|
|
1034
|
+
|
|
1035
|
+
### 本地存储:在后端接手之前
|
|
1036
|
+
|
|
1037
|
+
开发与单用户宿主可以用 `localStorageSnapshot(key)` 把 `MemoryViewStore` 存进浏览器的 `localStorage`,整份作为一个 JSON 文档放在 `key` 下。它只是这一个浏览器的视图,不是共享的;大家共享的视图存在服务端、`ViewStore` 背后——Wow 服务端上就是 `WowViewStore`。
|
|
1038
|
+
|
|
1039
|
+
```ts
|
|
1040
|
+
import {
|
|
1041
|
+
localStorageSnapshot,
|
|
1042
|
+
MemoryViewStore,
|
|
1043
|
+
} from '@ahoo-wang/wow-view-engine';
|
|
1044
|
+
|
|
1045
|
+
const store = new MemoryViewStore({
|
|
1046
|
+
snapshot: localStorageSnapshot('my-app:views'),
|
|
1047
|
+
});
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
- **存储拒收的写入就是失败。** 配额满或存储被禁用时,写入在内存中撤回,并以 code 为 `UNAVAILABLE` 的 `ViewStoreError` 拒绝:环境的 `onError` 收到一次 `store` 失败,界面显示这次保存没有落地并可重试。
|
|
1051
|
+
- **标签页之间不互相覆盖。** 每次写入前 store 重读文档,按实例、按每个定义的偏好核对这次写入的 `revision`:写入合并进另一个标签页存下的内容——一个标签页保存的看板,不会被另一个标签页的排序抹掉;另一个标签页已经越过的写入是 `CONFLICT`,与任何过期写入一样。另一个标签页的改动也会经 `storage` 事件让 store 重新载入。
|
|
1052
|
+
- 文档缺失或读不懂时从空开始,页面不会因此出错,下一次写入会替换它。
|
|
1053
|
+
|
|
1054
|
+
### 措辞与语言
|
|
1055
|
+
|
|
1056
|
+
模型只带 `code` 与 `params`,措辞归 `/ui`。`en`(英文目录)给每个 issue 一句英文,`ViewSurface` 与每个工作台的 `messages` 按 key 合并在已生效的措辞之上——改写与本地化是同一个入口;在应用外层放一个 `ViewHost`(或单独的 `MessagesProvider`),就能对其中所有视图一次设定,连同值显示的语言(`locale`)。包里另带一份逐键对应的简体中文 `zhCN`:整份交给 `messages` 即可,要改其中几句就铺开再覆盖(`{ ...zhCN, 'label.filter.apply': '确定' }`)。
|
|
1057
|
+
|
|
1058
|
+
值按字段显示:枚举显示选项的标签,`datetime`/`date` 经 `Intl.DateTimeFormat` 格式化,日期直方图的键显示为它起始的年、季度、月或日。表格单元格里的 `datetime` 写得短——到分,今年之内不写年(`09-17 21:19`,英文 `Sep 17, 9:19 PM`),整份时刻在单元格的 `title` 与记录详情里;秒要紧的字段(事件流的时间)声明 `timePrecision: 'second'`。`locale` 决定这些值用什么语言显示,缺省为运行环境的语言;它和 `messages` 是同一个选择,一个管文字,一个管值:
|
|
1059
|
+
|
|
1060
|
+
<!-- typecheck-context
|
|
1061
|
+
import { ViewEngine } from '@ahoo-wang/wow-view-engine';
|
|
1062
|
+
declare const engine: ViewEngine;
|
|
1063
|
+
-->
|
|
1064
|
+
|
|
1065
|
+
```tsx
|
|
1066
|
+
import { DataWorkbench, zhCN } from '@ahoo-wang/wow-view-engine/ui';
|
|
1067
|
+
|
|
1068
|
+
<DataWorkbench
|
|
1069
|
+
engine={engine}
|
|
1070
|
+
definitionId="orders"
|
|
1071
|
+
messages={{ ...zhCN, 'label.filter.apply': '确定' }}
|
|
1072
|
+
locale="zh-CN"
|
|
1073
|
+
/>;
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
时间按引擎的时钟 `environment.timeZone` 显示:相对日期"今天"按它解析,未声明 `timeZone` 的日期直方图也按它切桶,所以一行按什么时钟被筛选、被分组,就按什么时钟显示。
|
|
1077
|
+
|
|
1078
|
+
找不到的 key 会沿点号回退到最长的已知前缀,再退回 key 本身,因此不会渲染空白。新增 issue code 却没有对应措辞时,测试会失败。组件能取的 key 是 `MessageKey` 这个联合类型,删掉一个键就是编译错误;宿主自己的 `messages` 仍是开放的字符串映射。
|
|
1079
|
+
|
|
1080
|
+
消息键与 issue code 都是公开面,列在 `test/surface/messages.txt` 与 `test/surface/issues.txt`:改名或删掉一个,和删掉一个导出一样是破坏性变更。改写引擎自己的措辞时用 `satisfies MessageOverrides`,引擎改了名的键会让你的构建失败,而不是悄悄回落到引擎自己的句子;你自己的键(定义里的 `text(key)`)另放在普通的 `ViewMessages` 里:
|
|
1081
|
+
|
|
1082
|
+
```ts
|
|
1083
|
+
import type { MessageOverrides } from '@ahoo-wang/wow-view-engine/ui';
|
|
1084
|
+
|
|
1085
|
+
const wording = {
|
|
1086
|
+
'label.filter.apply': '确定',
|
|
1087
|
+
} satisfies MessageOverrides;
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
## 扩展点
|
|
1091
|
+
|
|
1092
|
+
| 变化轴 | 机制 |
|
|
1093
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1094
|
+
| 字段类型 | 注册 `FieldKind`(操作符、校验、编译到 `FilterExpression`、编辑器描述)。编辑器从 `/ui` 已有的值控件里选一种(`EDITOR_INPUTS`):没有渲染器注册表,要别的控件的类型会被拒绝而不是猜着画 |
|
|
1095
|
+
| 数据来源 | `resources` 的每一项把一份定义与它的数据源(Wow 查询客户端)配成对 |
|
|
1096
|
+
| 持久化 | Wow 服务端用 `WowViewStore`(`@ahoo-wang/wow-view-store`);别的后端实现 `ViewStore` |
|
|
1097
|
+
| 动作 | 写成声明(`actions()`)并绑到定义上(`bind(id, { actions })`),或向工作台传 `record.actions`;`slots`——`global`、`bulk`、`row` 三个渲染函数——是旁边的逃生口。动作是代码,由宿主交出来,不进配置、不入库。一页只取视图显示的字段,动作要读的其他字段写在定义的 `record.rowFields` 里 |
|
|
1098
|
+
| 外观 | CSS 变量与主题文件;通过组合 `/react` 钩子替换组件 |
|
|
1099
|
+
| 地图 | `/ui` 的 `registerChartMap` 给地图图型提供地理数据,见[地图](#地图) |
|
|
1100
|
+
|
|
1101
|
+
内置字段类型:`string`、`number`、`boolean`、`date`、`datetime`、`enum`、`reference`、`array`、`elementMatch`、`search`,以及由 Wow 元数据筛选支撑的 `documentId`、`aggregateId`、`tenantId`、`ownerId`、`spaceId`、`deletion`。
|
|
1102
|
+
|
|
1103
|
+
## 地图
|
|
1104
|
+
|
|
1105
|
+
地图图型画的是宿主注册的地图。**本包不带任何地图数据**:地图画哪些边界、能不能发布,由发布地的法规决定——例如在中国发布中国地图,须有标准地图服务给出的审图号。地理数据归宿主选、归宿主负责。
|
|
1106
|
+
|
|
1107
|
+
```ts
|
|
1108
|
+
import { registerChartMap } from '@ahoo-wang/wow-view-engine/ui';
|
|
1109
|
+
|
|
1110
|
+
// 应用启动时注册一次。`load` 在地图图型第一次画这张地图时才调用,结果留着;
|
|
1111
|
+
// 失败了下次再要。
|
|
1112
|
+
const unregister = registerChartMap({
|
|
1113
|
+
name: 'world',
|
|
1114
|
+
label: '世界',
|
|
1115
|
+
load: () => fetch('/maps/world.geo.json').then(response => response.json()),
|
|
1116
|
+
});
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
- `load` 返回 GeoJSON 的 `FeatureCollection`,每个要素的 `properties.name` 是地区名。
|
|
1120
|
+
- 地区维度的取值**按它的列显示的文字**与这些名字对上,枚举字段就是标签;地图上没有的地区在图上方计数说出来,不猜。
|
|
1121
|
+
- 注册了多张地图时,图型的数据页可以选;图没指定时画第一张。一张都没注册时,图型网格里的地图置灰。
|
|
1122
|
+
- 同名再注册替换前一个;返回的函数把地图取回。
|
|
1123
|
+
|
|
1124
|
+
## 分层
|
|
1125
|
+
|
|
1126
|
+
```text
|
|
1127
|
+
model → filter → record | analysis | dashboard → runtime → react → ui
|
|
1128
|
+
store → model
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
`validateDefinition` 在引擎注册定义时校验一次:字段名是否符合 Wow 查询语法、id 是否唯一且不含 `:`、能力是否足以让 `default*Config` 构造出合法配置、每个系统视图是否通过它自己的内核。含 error 的定义仍留在注册表里,但在使用处被拒绝——代码里的错误因此表现为一条可读的 issue,而不是用户打开视图时的 `TypeError`。
|
|
1132
|
+
|
|
1133
|
+
六条依赖规则由架构测试强制:`model` 不引入任何目录;`filter` 只引入 `model`;`record`、`analysis`、`dashboard` 只引入 `model` 与 `filter`;`runtime` 不引入 `react` 与 `ui`;`store` 只引入 `model`;`react` 不引入 `ui`。`store` 及以下不含 React 与 DOM。只使用 Wow 未弃用的、基于 `FilterExpression` 的查询 API。
|
|
1134
|
+
|
|
1135
|
+
## 不做
|
|
1136
|
+
|
|
1137
|
+
视图种类插件、定义 CRUD 后端、写入回执核对与读屏障、并发与页大小以外的资源预算、SSR 预载、通用 region 或事件总线、跨页全选、单元格编辑、Dashboard 嵌套。
|
|
1138
|
+
|
|
1139
|
+
## 内容安全策略(CSP)
|
|
1140
|
+
|
|
1141
|
+
本包可以在严格的策略下运行——`script-src 'self'`、`style-src 'self'`,不开 `'unsafe-inline'` 与 `'unsafe-eval'`——要放行的只有三件事:
|
|
1142
|
+
|
|
1143
|
+
- **样式表**是文件(`styles.css`,用预设时还有 `themes.css`):从允许的来源加载,不要内联。组件画出来的标记里没有 `style` 属性:内联样式都经 DOM 的 style 对象写入,策略不拦;图表提示框的色块是 SVG 的 `fill`(有单测守着提示框的 HTML 里没有 `style=`)。也不载入 `data:` 图片:搭看板时显示的格子画在页面里。
|
|
1144
|
+
- **打包进来的库干活时加的样式**,都是 `<head>` 里的一个 `<style>`:拖放库在拖动排序时加(列设置、排序、视图列表、看板的筛选与标签页——拖动时的光标、不选中文字),栅格的拖动库在移动或缩放看板面板时加(不选中文字),Base UI 在下拉选择的列表打开时加(出现滚动箭头时藏起滚动条)。`style-src` 只放行 `'self'` 时它们会被拦,所以页面要把本次响应的 nonce 按 Vite 的约定写出来:`<meta property="csp-nonce" nonce="…">`(Vite 的 `html.cspNonce` 就是这样写的;写在 `content` 里也认),策略里加上 `'nonce-…'`。引擎把它交给这三个库。没有这个 meta 时一切照样能用,只是这几条规则被拦掉,各报一次违规。
|
|
1145
|
+
- **把图导出为 PNG** 时,图的 SVG 从一个 `blob:` 地址作为图片载入、再画到画布上,所以 `img-src` 要包含 `blob:`。不放行时 PNG 做不出来,工具栏会说明;导出 SVG 不需要任何放行。两种导出都不执行代码、不写内联脚本。
|
|
1146
|
+
|
|
1147
|
+
```
|
|
1148
|
+
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'nonce-<每次响应不同>'; img-src 'self' blob:
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
```html
|
|
1152
|
+
<meta property="csp-nonce" nonce="<同一个 nonce>" />
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
有两处在这条策略下跑,都一次违规也不许有。Storybook 在这条策略下走一遍引擎本身(`typescript/storybook/stories/view-engine/StrictCsp.test.stories.tsx`,进 CI):记录工作台里拖一列、从下拉选一个汇总、拉宽一列、打开一条记录的详情;每种图型连同它的提示框;SVG、PNG 与 CSV 三种导出;一块看板先读、从图上筛选,再搭——移动与缩放面板、拖动标签页、加一个分析——然后保存。补偿控制台按它跑端到端(`compensation/dashboard/e2e/csp.spec.ts`):走遍每个去处、真的拖动一次。
|
|
1156
|
+
|
|
1157
|
+
## 开发
|
|
1158
|
+
|
|
1159
|
+
```bash
|
|
1160
|
+
pnpm --filter @ahoo-wang/wow-view-engine test # 单元测试、覆盖率与三个 tsc 工程
|
|
1161
|
+
pnpm --filter @ahoo-wang/wow-view-engine build # 构建,并核对发布出去的入口
|
|
1162
|
+
pnpm --filter @ahoo-wang/wow-view-engine test:package # 入口可导入、核心入口无 DOM 类型、JS 不引入 CSS
|
|
1163
|
+
pnpm storybook # 每个界面的每种状态,见导航「View Engine」
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
本仓库的 `examples/`(不在 npm 包里)是三个只依赖公开合同、不依赖内部实现的消费者:
|
|
1167
|
+
`quickstart.ts` 是快速上手里那份定义的代码,由测试准入;
|
|
1168
|
+
`PlainRecordWorkbench.tsx` 用无样式 HTML 跑通整个闭环;
|
|
1169
|
+
`FetcherViewStore.ts` 用 `@ahoo-wang/fetcher` 为一个不是 Wow 的后端(带 `If-Match` revision 的 REST API)实现 `ViewStore` 端口——Wow 服务端的 store 是 `WowViewStore`。
|
|
1170
|
+
|
|
1171
|
+
`@ahoo-wang/fetcher-viewer` 已弃用,新项目使用本包。两者模型与 API 不同。
|