feat: maintenance flows frontend foundation - types, API clients, sidebar, library filter

- Add maintenance.ts types: TargetEntry, TargetList, MaintenanceSchedule, BatchLaunch
- Add targetListsApi and maintenanceSchedulesApi/batchLaunchApi clients
- Extend TreeType union with 'maintenance' in tree.ts
- Update getTreeNavigatePath/getTreeEditorPath in routing.ts for maintenance
- Sidebar: track maintenance count and add Maintenance sub-nav item
- TreeLibraryPage: add maintenance to typeFilter state, URL sync, and tab buttons
- TreeGridView, TreeListView, TreeTableView: add amber Wrench maintenance badge

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-17 14:06:36 -05:00
parent 829b7cf5a7
commit 8441a8dbaf
12 changed files with 161 additions and 15 deletions

View File

@@ -13,3 +13,5 @@ export { default as adminApi } from './admin'
export { treeMarkdownApi } from './treeMarkdown'
export { default as pinnedFlowsApi } from './pinnedFlows'
export { default as analyticsApi } from './analytics'
export { targetListsApi } from './targetLists'
export { maintenanceSchedulesApi, batchLaunchApi } from './maintenanceSchedules'

View File

@@ -0,0 +1,24 @@
import { apiClient } from './client'
import type {
MaintenanceSchedule,
MaintenanceScheduleCreate,
MaintenanceScheduleUpdate,
BatchLaunchRequest,
BatchLaunchResponse,
} from '@/types'
export const maintenanceSchedulesApi = {
getForTree: (treeId: string): Promise<MaintenanceSchedule> =>
apiClient.get(`/maintenance-schedules/tree/${treeId}`).then(r => r.data),
create: (data: MaintenanceScheduleCreate): Promise<MaintenanceSchedule> =>
apiClient.post('/maintenance-schedules', data).then(r => r.data),
update: (id: string, data: MaintenanceScheduleUpdate): Promise<MaintenanceSchedule> =>
apiClient.patch(`/maintenance-schedules/${id}`, data).then(r => r.data),
}
export const batchLaunchApi = {
launch: (data: BatchLaunchRequest): Promise<BatchLaunchResponse> =>
apiClient.post('/sessions/batch', data).then(r => r.data),
}

View File

@@ -0,0 +1,19 @@
import { apiClient } from './client'
import type { TargetList, TargetListCreate } from '@/types'
export const targetListsApi = {
list: (): Promise<TargetList[]> =>
apiClient.get('/target-lists/').then(r => r.data),
get: (id: string): Promise<TargetList> =>
apiClient.get(`/target-lists/${id}`).then(r => r.data),
create: (data: TargetListCreate): Promise<TargetList> =>
apiClient.post('/target-lists/', data).then(r => r.data),
update: (id: string, data: Partial<TargetListCreate>): Promise<TargetList> =>
apiClient.put(`/target-lists/${id}`, data).then(r => r.data),
delete: (id: string): Promise<void> =>
apiClient.delete(`/target-lists/${id}`).then(() => undefined),
}