From eb6d0f7c879abd64b3da1134959d91f73df96074 Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:04:07 -0700 Subject: [PATCH] Extract automations list panel and worktree map logic Split AutomationsPageSurface into smaller, focused modules for better maintainability and reusability. Move list panel UI rendering to AutomationsPageListPanel component and worktree map selection logic to a standalone utility function. --- .../automations/AutomationsPageListPanel.tsx | 125 ++++++++++++++++++ .../automations/AutomationsPageSurface.tsx | 91 +------------ 2 files changed, 129 insertions(+), 87 deletions(-) create mode 100644 src/renderer/src/components/automations/AutomationsPageListPanel.tsx diff --git a/src/renderer/src/components/automations/AutomationsPageListPanel.tsx b/src/renderer/src/components/automations/AutomationsPageListPanel.tsx new file mode 100644 index 00000000000..25c7ff7b88c --- /dev/null +++ b/src/renderer/src/components/automations/AutomationsPageListPanel.tsx @@ -0,0 +1,125 @@ +import React from 'react' +import type { AutomationsPageController } from './use-automations-page-controller' +import { AutomationsListPanel } from './AutomationsListPanel' + +export function AutomationsPageListPanel({ + controller, + onOpenDetail +}: { + controller: AutomationsPageController + onOpenDetail: () => void +}): React.JSX.Element { + const { + store, + local, + list, + destination, + sourceAvailability, + pageRefresh, + runActions, + editorActions, + managementActions, + externalActions, + presentation + } = controller + const { + projectHostSetups, + repoMap, + worktreeMap, + sshConnectionStates, + runtimeStatusByEnvironmentId + } = store + const { + listSearchQuery, + setListSearchQuery, + listFilter, + setListFilter, + relativeNow, + externalActionKey, + setActivePaneTab, + isLoading, + setPageView + } = local + const { + hostCatalog, + hasListItems, + hasFilteredListItems, + isListSearchQueryTooLarge, + filteredRows, + filteredExternalAutomationEntries, + selectedRow, + selectedExternal, + searchCounts + } = list + const onListFilterChange = (next: typeof listFilter): void => { + setListFilter(next) + if ((next.hostStableKeys?.length ?? 0) > 0 && hostCatalog.resolution.effective.kind !== 'all') { + hostCatalog.selectHost({ kind: 'all' }) + } + } + return ( + { + hostCatalog.recover(action, entry) + if (action === 'retry') { + void pageRefresh.refresh() + } + }} + filteredRows={filteredRows} + filteredExternalAutomationEntries={filteredExternalAutomationEntries} + selectedRowKey={selectedRow?.key ?? null} + selectedExternalKey={local.selectedExternalKey} + selectedExternal={selectedExternal} + relativeNow={relativeNow} + repoMap={repoMap} + worktreeMap={worktreeMap} + repoForRow={store.repoForRow} + worktreeForRow={store.worktreeForRow} + projectHostSetups={projectHostSetups} + sshConnectionStates={sshConnectionStates} + runtimeStatusByEnvironmentId={runtimeStatusByEnvironmentId} + hostTargetFor={destination.automationHostTargetFor} + automationSourceHostAvailabilityByRowKey={ + sourceAvailability.automationSourceHostAvailabilityByRowKey + } + hostLabelById={presentation.hostLabelById} + isActionEnabled={destination.isAutomationRowActionEnabled} + externalActionKey={externalActionKey} + selectAutomationRow={list.selectAutomationRow} + selectExternalKey={local.selectExternalKey} + setActivePaneTab={setActivePaneTab} + runNow={(row) => void runActions.runNow(row)} + openEditDialog={(row) => void editorActions.openEditDialog(row)} + toggleAutomation={(row) => void managementActions.toggleAutomation(row)} + requestDeleteAutomation={managementActions.requestDeleteAutomation} + requestExternalAction={externalActions.requestExternalAction} + openEditExternalDialog={editorActions.openEditExternalDialog} + openCreateDialog={editorActions.openCreateDialog} + canCreateAutomation={destination.canCreateAutomation} + onOpenDetail={onOpenDetail} + onRefresh={() => { + hostCatalog.refreshHosts() + void pageRefresh.refresh() + }} + isRefreshing={isLoading} + onOpenRuns={() => { + hostCatalog.selectHost({ kind: 'all' }) + setPageView('runs') + }} + /> + ) +} diff --git a/src/renderer/src/components/automations/AutomationsPageSurface.tsx b/src/renderer/src/components/automations/AutomationsPageSurface.tsx index 04afae8c786..1e46b5f0283 100644 --- a/src/renderer/src/components/automations/AutomationsPageSurface.tsx +++ b/src/renderer/src/components/automations/AutomationsPageSurface.tsx @@ -2,7 +2,6 @@ import React, { useMemo } from 'react' import { translate } from '@/i18n/i18n' import { AutomationEditorDialog } from './AutomationEditorDialog' import { AutomationsDetailPane } from './AutomationsDetailPane' -import { AutomationsListPanel } from './AutomationsListPanel' import { AutomationsPageSkeleton } from './AutomationsPageSkeleton' import { getAutomationAuthorityTarget } from './automation-host-client' import type { AutomationListRow } from './automation-list-row-identity' @@ -12,6 +11,7 @@ import type { AutomationsPageController } from './use-automations-page-controlle import { AutomationRunsDashboardSurface } from './AutomationRunsDashboardSurface' import { AutomationRunDetailsPage } from './AutomationRunDetailsPage' import { AutomationsPageDeleteDialogs } from './AutomationsPageDeleteDialogs' +import { AutomationsPageListPanel } from './AutomationsPageListPanel' export function AutomationsPageSurface({ controller }: { @@ -26,7 +26,6 @@ export function AutomationsPageSurface({ destinationForm, setup, runPage, - sourceAvailability, presentation, pageRefresh, draftEffects, @@ -42,8 +41,6 @@ export function AutomationsPageSurface({ repoMap, worktreeMap, settings, - sshConnectionStates, - runtimeStatusByEnvironmentId, repoForRow, worktreeForRow, setPendingAutomationRunNavigation @@ -65,10 +62,6 @@ export function AutomationsPageSurface({ externalDeleteTarget, externalDeleteConfirmButtonRef, setExternalDeleteTarget, - listSearchQuery, - setListSearchQuery, - listFilter, - setListFilter, relativeNow, externalActionKey, activePaneTab, @@ -92,18 +85,7 @@ export function AutomationsPageSurface({ runPageOrigin, setRunPageOrigin } = local - const { - hostCatalog, - hasListItems, - hasFilteredListItems, - isListSearchQueryTooLarge, - filteredRows, - filteredExternalAutomationEntries, - selected, - selectedRow, - selectedExternal, - searchCounts - } = list + const { hostCatalog, hasListItems, selected, selectedRow, selectedExternal } = list const selectedAutomationRunPage = setup.selectedAutomationRunPage const selectedRunWorktreeMap = useMemo(() => { if (!selectedRow) { @@ -132,12 +114,6 @@ export function AutomationsPageSurface({ void pageRefresh.refresh() } } - const onListFilterChange = (next: typeof listFilter): void => { - setListFilter(next) - if ((next.hostStableKeys?.length ?? 0) > 0 && hostCatalog.resolution.effective.kind !== 'all') { - hostCatalog.selectHost({ kind: 'all' }) - } - } const openAutomationRunPage = (run: (typeof setup.selectedRuns)[number]): void => { externalActions.openAutomationRunPage(run) setRunPageOrigin('automation') @@ -340,68 +316,9 @@ export function AutomationsPageSurface({ }} /> ) : ( - { - hostCatalog.recover(action, entry) - if (action === 'retry') { - void pageRefresh.refresh() - } - }} - filteredRows={filteredRows} - filteredExternalAutomationEntries={filteredExternalAutomationEntries} - selectedRowKey={selectedRow?.key ?? null} - selectedExternalKey={local.selectedExternalKey} - selectedExternal={selectedExternal} - relativeNow={relativeNow} - repoMap={repoMap} - worktreeMap={worktreeMap} - repoForRow={repoForRow} - worktreeForRow={worktreeForRow} - projectHostSetups={projectHostSetups} - sshConnectionStates={sshConnectionStates} - runtimeStatusByEnvironmentId={runtimeStatusByEnvironmentId} - hostTargetFor={destination.automationHostTargetFor} - automationSourceHostAvailabilityByRowKey={ - sourceAvailability.automationSourceHostAvailabilityByRowKey - } - hostLabelById={presentation.hostLabelById} - isActionEnabled={destination.isAutomationRowActionEnabled} - externalActionKey={externalActionKey} - selectAutomationRow={list.selectAutomationRow} - selectExternalKey={local.selectExternalKey} - setActivePaneTab={setActivePaneTab} - runNow={(row) => void runActions.runNow(row)} - openEditDialog={(row) => void editorActions.openEditDialog(row)} - toggleAutomation={(row) => void managementActions.toggleAutomation(row)} - requestDeleteAutomation={managementActions.requestDeleteAutomation} - requestExternalAction={externalActions.requestExternalAction} - openEditExternalDialog={editorActions.openEditExternalDialog} - openCreateDialog={editorActions.openCreateDialog} - canCreateAutomation={destination.canCreateAutomation} + setIsDetailOpen(true)} - onRefresh={() => { - hostCatalog.refreshHosts() - void pageRefresh.refresh() - }} - isRefreshing={isLoading} - onOpenRuns={() => { - hostCatalog.selectHost({ kind: 'all' }) - setPageView('runs') - }} /> )}