P2-2 前端巨型组件拆分:DataStudioNew 6108→3568,F1–F11 完成(composables + 冒烟/单测/真机 E2E)#375
Open
blankmeadow wants to merge 25 commits into
Open
P2-2 前端巨型组件拆分:DataStudioNew 6108→3568,F1–F11 完成(composables + 冒烟/单测/真机 E2E)#375blankmeadow wants to merge 25 commits into
blankmeadow wants to merge 25 commits into
Conversation
Design + execution plan to decompose DataStudioNew.vue (6108 lines, 3797
in script) into Vue 3 composables + pure utils, keeping the page behavior,
routing, and the provide('dataStudioCtx') contract unchanged. Verifiable
pure-util slices (formatters/chart-column-select/sql-split/tab-serialize)
go first with Vitest tests; stateful composable slices follow with
component tests or local smoke, honestly scoped given the near-zero
existing component-test coverage.
Refs docs/reports/2026-06-16-main-full-code-review.md (frontend 4.3).
…w (P2-2 F1)
First verifiable slice of the DataStudioNew.vue megacomponent split: move
the pure formatting/predicate helpers (formatNumber/formatRowCount/
formatStorageSize/formatDuration/formatDateTime/abbreviateSql/
isAggregateTable) verbatim into datastudio/tableFormat.js with Vitest
coverage. The component imports them; template/state and the
provide('dataStudioCtx') contract are unchanged.
Verified: npm run lint (0 errors), npm run test (61 passed, +7 new),
npm run build. Behavior preserved by construction (verbatim move; one
test assertion was corrected to match the existing >=10 toFixed(0) rule).
Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F1).
…ils (P2-2 F2,F3)
F2: move pure chart column scoring/numeric detection into
datastudio/chartColumnSelect.js (scoreColumnName/scoreDimensionColumn/
scoreMetricColumn/detectNumericColumns). The component's getNumericColumns
now delegates to detectNumericColumns; applyDefaultChartSelection keeps its
state mutation and uses the imported scorers. Behavior identical.
F3: move the SQL statement splitter (quote/comment-aware) into
datastudio/sqlStatements.js verbatim.
Both with Vitest coverage (scoring/suffix boosts, numeric detection &
sampling, quote/comment-aware splitting & escapes). provide('dataStudioCtx')
and template unchanged.
Verified: npm run lint (0 errors), npm run test (73 passed, +12), build.
Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F2,F3).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…y net) shallowMount-based smoke that executes the full script setup, composables, computed and onMounted with APIs/router/element-plus message boxes mocked and IntersectionObserver/ResizeObserver stubbed. It fails if a composable extraction breaks a reference or reactive wiring at runtime — the verification layer build/lint cannot provide. Used as the gate for the upcoming stateful composable slices (F4-F11). Verified: npm run test green; smoke catches setup/render errors (seen during development).
Move the workspace-tab localStorage persistence cluster (snapshot computed, debounced persist, restore + the persist watch) out of DataStudioNew.vue into composables/useTabPersistence.js, injecting shared reactive state and createTabState so refs stay identical. Composable is assembled after createTabState (before onMounted), preserving the original runtime order. Verified: focused composable unit test (persist/flush/restore/version-guard/ debounce, 5 cases) + DataStudioNew mount smoke green; npm run lint (0 errors), npm run build. Behavior preserved (verbatim move; storageKey passes the same isDemoMode-derived key).
Move the three-pane layout cluster (sidebar/right width ratios + clamps + computed styles, left-pane heights/refs, the three mouse drag handlers, and the window-resize listener lifecycle) out of DataStudioNew.vue into composables/useResizablePanes.js. The composable owns its mousemove/mouseup handler vars and registers its own onMounted/onBeforeUnmount for the resize listener + drag cleanup; activeTab is injected and syncResultPaneLayout is passed as a lazy wrapper (forward ref). Returned refs (leftPaneHeights/ leftPaneRefs) stay shared with disposeTabResources. Verified: DataStudioNew mount smoke green, npm run build (refs resolve), npm run lint (0 errors); orphan check shows all moved symbols gone from the component. Drag/resize logic is verbatim-moved (behavior preserved by construction); interactive drag itself is not exercised by the smoke. Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F5).
Move the SQL-editor completion data source (schema/table/column getters, loaders, remote search, per-tab completion context) out of DataStudioNew.vue into composables/useSqlCompletion.js. The shared catalog caches (schemaStore/tableStore/columnStore) and loaders (loadTables/ activateDatasource) stay component-owned and are injected (loaders as lazy wrappers), to be unified when the catalog tree is extracted (F7). Verified: mount smoke green, npm run build (refs resolve), npm run lint (0 errors); orphan check clean. Functions are verbatim-moved. Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F6).
Move the tab<->URL route sync functions (syncRouteWithTab, clearRouteTabQuery, clearCreateQuery, syncFromRoute) out of DataStudioNew.vue into composables/useTabRouting.js. The composable resolves its own useRoute/useRouter and injects shared tab/catalog state, lazy-wrapping the forward refs (loadSchemas/loadTables/openTableTab). Tab-lifecycle handlers that border on the catalog/open-tab core (F7) are intentionally left in the component for now. Verified: mount smoke green, npm run build, npm run lint (0 errors); orphan check clean; route/router still used by remaining component code. Functions are verbatim-moved. Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F8).
Move the pure field-diff helpers (buildFieldPayload, isFieldChanged, isOnlyCommentChanged) out of DataStudioNew.vue into datastudio/fieldEdit.js with Vitest coverage. The stateful metadata/field edit flow (drafts, save, API calls) — which has a large injected-dependency surface — is intentionally left in the component for a focused follow-up. Verified: fieldEdit unit tests (8) + mount smoke green; npm run build, npm run lint (0 errors); orphan check clean. Verbatim move. Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F10).
…nup) The useSqlCompletion destructure pulled five functions only used internally by getSqlCompletionContext; keep just the entries the component uses (getSchemaOptions, getSqlCompletionContext). Removes 5 unused-var warnings. Pre-existing dead code unrelated to the P2-2 extraction is left untouched. Verified: npm run build, npm run test (87 passed), npm run lint (0 errors, 270 warnings). Refs docs/plans/2026-06-18-frontend-megacomponent-split-plan.md (F11).
…-2 regression net) Harden the regression net for the four largest stateful composables that previously relied only on the mount smoke + Playwright browser E2E: - useTableMetaEditing: field draft ops (getFieldRows/start/add/remove/cancel, aggregate-table guard) - useQueryExecution: pure helpers (parseResultTabIndex/isResultSetType/ getResultSetCountText/getResultSetByIndex) + resetQuery state effect - useResultChart: getNumericColumns/applyDefaultChartSelection/canRenderChart - useCatalogTree: getDatasourceById/filterCatalogNode + shared-cache exposure Lifecycle-bound composables are exercised via a withSetup(createApp) harness; externals (element-plus/api/echarts/demo) are mocked. Verified: npm run test (23 files / 103 passed, +16), npm run lint (0 errors), npm run build.
…ew coupling) TaskEditDrawer was a view imported by other views (DataStudioNew, LineageView) — the 'views importing views' coupling flagged in the review. Move it (and its sole helper taskEditForm + its test) from views/tasks/ to components/, and point the 3 importers (TaskTable, DataStudioNew, LineageView) at @/components/TaskEditDrawer.vue. The ./taskEditForm sibling import and the test's ../taskEditForm import stay valid (moved together). Verified: npm run build, npm run lint (0 errors), npm run test (103 passed); no dangling references to the old path.
…proach as P2-2) Apply the DataStudio composables/pure-utils playbook to WorkflowDetail.vue. W1 (verifiable pure slice): move the status/text mappers (getWorkflowStatusType/Text, getInstanceStateType/Text, getTriggerText, getOperationText, getPublishRecordStatusType/Text) and the formatters (formatDateTime/formatDuration/formatLog) into views/workflows/workflowDisplay.js with Vitest coverage. Verbatim move; the component imports them. Verified: workflowDisplay unit tests + full suite green; npm run build, npm run lint (0 errors). WorkflowDetail.vue 2792 -> 2688.
Move the pure global-param row transforms (cloneGlobalParamCore, createGlobalParamRow, normalizeGlobalParams, isGlobalParamEmpty, formatGlobalParamDisplay) into views/workflows/globalParams.js with Vitest coverage. serializeGlobalParams stays in the component (reads component state) and now delegates to the imported cloneGlobalParamCore. Verbatim move. Verified: globalParams unit tests + full suite (25 files / 112 passed); npm run build, npm run lint (0 errors). WorkflowDetail.vue 2688 -> 2662.
… (W3) Extract the pure cores of the version/Dolphin display predicates into views/workflows/workflowVersion.js (formatDolphinConfigOption, rollbackDisabledReason, versionDeleteDisabledReason) with Vitest coverage. The two version predicates read component refs, so the component keeps same-named one-line wrappers that inject currentVersionId / lastSuccessfulPublishedVersionId — call sites (incl. template) unchanged. Verified: workflowVersion unit tests + full suite green; npm run build, npm run lint (0 errors). WorkflowDetail.vue 2662 -> 2631. (one test assertion corrected to match the existing missing-isActive -> 停用 rule.)
…e safety net) shallowMount smoke that runs WorkflowDetail's full setup/computed/onMounted with router/api/element-plus mocked and child components stubbed. Gates the upcoming stateful composable extractions (schedule form, version compare, inline field editing) the same way DataStudioNew.smoke does. Verified: smoke green (1 test); full suite unaffected.
First stateful WorkflowDetail slice, gated by the new mount smoke. Move the name/task-group/description inline-edit state machines (editing flags/values, savingField, task-group options + the 11 start/cancel/save functions) into composables/useInlineFieldEditing.js. workflow/workflowTaskIds are injected; loadWorkflowDetail/buildDolphinConfigParams passed as lazy forward refs. Returned refs/functions keep the same names so template bindings are unchanged. Verified: WorkflowDetail mount smoke + full suite (27 files / 116 passed); npm run build, npm run lint (0 errors). Verbatim move; WorkflowDetail.vue 2631 -> 2523.
Largest WorkflowDetail slice, smoke-gated: move the entire schedule tab (form state + reactive scheduleForm + option lists + computeds isScheduleOnline/timezoneOptions/environmentFilteredOptions + scheduleRules + loadScheduleOptions/handleWorkerGroupChange/previewScheduleTimes/ syncScheduleForm/saveScheduleConfig/handleToggleSchedule + the activeTab watch) into composables/useScheduleForm.js. workflow/activeTab injected; buildDolphinConfigParams/loadWorkflowDetail/getErrorMessage lazy-wrapped (stay component-owned, shared). scheduleOptionsLoaded returned so the engine-switch/detail-load reset paths keep working. Verified: WorkflowDetail mount smoke + full suite (27 files / 116 passed); npm run build, npm run lint (0 errors). Verbatim move; WorkflowDetail.vue 2523 -> 2240.
Move the version-compare interaction (compare state + selectedHistoryVersionIds/ canCompareSelected computeds + handleVersionSelectionChange/loadVersionCompare/ compareSelectedVersions/stepVersionCompare/clearVersionHistorySelection) into composables/useVersionCompare.js, smoke-gated. workflow/versionList/changeMode injected; selectedHistoryVersionIds returned for isVersionSelectable. Version mutations (rollback/delete) and publish-record dialog stay in the component. Also drops the dead resolveLeftVersionId (0 callers). Verified: WorkflowDetail mount smoke + full suite (27 files / 116 passed); npm run build, npm run lint (0 errors). WorkflowDetail.vue 2240 -> 2131.
Move version rollback/delete + per-version publish-records dialog (rollback/ delete loading refs, dialog state, versionPublishRecordDialogTitle computed, rollbackToVersion/deleteVersion/openVersionPublishRecords) into composables/useVersionMutations.js, smoke-gated. workflow/versionById/ publishRecordsByVersionId injected; the W3 disabled-reason wrappers, loadWorkflowDetail and backToPublishRecords passed as lazy forward refs. Verified: WorkflowDetail mount smoke + full suite (27 files / 116 passed); npm run build, npm run lint (0 errors). WorkflowDetail.vue 2131 -> 2047.
Move the shared getErrorMessage(error) helper (used 9+ times across publish/ schedule/version flows) into the pure views/workflows/workflowDisplay.js util with Vitest coverage; the component and the W5/W7 lazy wrappers import it. Zero call-site churn. Verified: npm run build, npm run lint (0 errors), npm run test (full suite green).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
承接已合并的全量评审 PR #374,本 PR 完成 P2-2 前端巨型组件拆分(
DataStudioNew.vue)。F1–F11 全部完成:纯逻辑抽成可单测工具,9 个职责簇抽成 Vue 3 composables;全程行为按构造保持,provide('dataStudioCtx')契约逐字不变(31 键),模板与路由未改动。DataStudioNew.vue:6108 → 3568 行(script 3797 → 1257)。交付物
文档
docs/design/2026-06-18-frontend-megacomponent-split-design.md+docs/plans/2026-06-18-frontend-megacomponent-split-plan.md(含各切片的真实验证记录)纯工具(配 Vitest 单测)
tableFormat.js(F1) ·chartColumnSelect.js(F2) ·sqlStatements.js(F3) ·fieldEdit.js(F10)Composables(逐字搬迁、依赖注入、前向引用惰性包装)
useTabPersistence(F4) ·useResizablePanes(F5) ·useSqlCompletion(F6) ·useTabRouting(F8)useCatalogTree(F7) ·useQueryExecution(F9) ·useResultChart(F10a) ·useTableMetaEditing(F10b)schemaStore/tableStore/columnStore由useCatalogTree拥有并 return,作为同一引用共享给补全/路由/查询 composable。测试网
DataStudioNew.smoke.spec.js挂载冒烟(执行全部 8 个 composable 的 setup)useCatalogTree/useQueryExecution/useResultChart/useTableMetaEditing):有生命周期钩子的用withSetup(createApp)在真实组件实例内运行;externals mock 掉。验证
npm run test— 103 passed(23 文件,含冒烟 + 16 条新 composable 单测)npm run lint— 0 error(warnings 270 → 259)npm run build— 通过SELECT返回行 / CSV 导出 / 历史回填;F10a 图表按像素采样校验渲染与默认选列;F10b 字段编辑触发真实ALTER TABLE ... MODIFY COLUMN ... COMMENT,MySQLdata_field/SHOW FULL COLUMNS校验通过。详见计划文档验证记录。附带改动
vite.config.js:dev 代理 target 改为VITE_BACKEND_PROXY_TARGET可配(默认http://localhost:8080不变),便于本地连不同后端做冒烟。未包含(同类技术债,另行设计)
WorkflowDetail.vue(2792) 同法 composables 化;TaskEditDrawer从views/迁入components/消除跨视图耦合。useCatalogTree.js(905 行) 后续可再按「树构建 vs 加载器」二次细分(当前内聚,不强求)。🤖 Generated with Claude Code
https://claude.ai/code/session_01GFj62aMr88VieUECFbvakJ