- Add BatchStatusPage (/flows/:id/batches/:batchId): per-target Start/Resume/View cards, progress bar, 5s polling while in-progress, completion outcome summary - Add BatchStatusCard: handles not-started/in-progress/complete states with step progress for in-progress targets - Add ActiveBatchBanner: amber banner on detail page when a batch is running, links to BatchStatusPage - Add MaintenanceContextStrip: amber strip in ProceduralNavigationPage for maintenance flows showing target name, batch progress (X/Y complete), and Back to Batch nav - Update MaintenanceFlowDetailPage: active batch banner, clickable run history rows with mini progress dots and outcome summaries, Run button loading state, post-launch navigates to BatchStatusPage - Update ProceduralNavigationPage: renders MaintenanceContextStrip between top bar and content when tree_type === 'maintenance'; fetches batch progress once on mount - Add batch_id filter to GET /sessions backend endpoint and SessionListParams frontend type - Add /flows/:id/batches/:batchId route to router Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
104 lines
3.4 KiB
TypeScript
104 lines
3.4 KiB
TypeScript
import apiClient from './client'
|
|
import type { Session, SessionCreate, SessionUpdate, SessionExport, SaveAsTreeRequest, SaveAsTreeResponse, SessionComplete, RedactionSummary, SessionShareCreate, SessionShare, SharedSessionView } from '@/types'
|
|
|
|
export interface SessionListParams {
|
|
page?: number
|
|
size?: number
|
|
tree_id?: string
|
|
batch_id?: string
|
|
completed?: boolean
|
|
ticket_number?: string
|
|
client_name?: string
|
|
tree_name?: string
|
|
started_after?: string // ISO datetime string
|
|
started_before?: string
|
|
completed_after?: string
|
|
completed_before?: string
|
|
}
|
|
|
|
export const sessionsApi = {
|
|
async list(params?: SessionListParams): Promise<Session[]> {
|
|
const response = await apiClient.get<Session[]>('/sessions', { params })
|
|
return response.data
|
|
},
|
|
|
|
async get(id: string): Promise<Session> {
|
|
const response = await apiClient.get<Session>(`/sessions/${id}`)
|
|
return response.data
|
|
},
|
|
|
|
async create(data: SessionCreate): Promise<Session> {
|
|
const response = await apiClient.post<Session>('/sessions', data)
|
|
return response.data
|
|
},
|
|
|
|
async update(id: string, data: SessionUpdate): Promise<Session> {
|
|
const response = await apiClient.put<Session>(`/sessions/${id}`, data)
|
|
return response.data
|
|
},
|
|
|
|
async complete(id: string, data: SessionComplete): Promise<Session> {
|
|
const response = await apiClient.post<Session>(`/sessions/${id}/complete`, data)
|
|
return response.data
|
|
},
|
|
|
|
async export(id: string, options: SessionExport): Promise<string> {
|
|
const response = await apiClient.post<string>(`/sessions/${id}/export`, options)
|
|
return response.data
|
|
},
|
|
|
|
async exportWithMeta(
|
|
id: string,
|
|
options: SessionExport
|
|
): Promise<{
|
|
content: string
|
|
redactionMode: 'none' | 'mask'
|
|
redactionSummary: RedactionSummary | null
|
|
}> {
|
|
const response = await apiClient.post<string>(`/sessions/${id}/export`, options)
|
|
const redactionMode = (response.headers['x-redaction-mode'] as 'none' | 'mask') || 'none'
|
|
let redactionSummary: RedactionSummary | null = null
|
|
const summaryHeader = response.headers['x-redaction-summary']
|
|
if (summaryHeader) {
|
|
try {
|
|
redactionSummary = JSON.parse(summaryHeader)
|
|
} catch {
|
|
// Ignore malformed header
|
|
}
|
|
}
|
|
return { content: response.data, redactionMode, redactionSummary }
|
|
},
|
|
|
|
async updateScratchpad(id: string, content: string): Promise<Session> {
|
|
const response = await apiClient.patch<Session>(`/sessions/${id}/scratchpad`, { scratchpad: content })
|
|
return response.data
|
|
},
|
|
|
|
async saveAsTree(id: string, data: SaveAsTreeRequest): Promise<SaveAsTreeResponse> {
|
|
const response = await apiClient.post<SaveAsTreeResponse>(`/sessions/${id}/save-as-tree`, data)
|
|
return response.data
|
|
},
|
|
|
|
// Session Sharing
|
|
async createShare(sessionId: string, data: SessionShareCreate): Promise<SessionShare> {
|
|
const response = await apiClient.post<SessionShare>(`/sessions/${sessionId}/shares`, data)
|
|
return response.data
|
|
},
|
|
|
|
async listMyShares(): Promise<SessionShare[]> {
|
|
const response = await apiClient.get<SessionShare[]>('/shares/my-shares')
|
|
return response.data
|
|
},
|
|
|
|
async revokeShare(shareId: string): Promise<void> {
|
|
await apiClient.delete(`/shares/${shareId}`)
|
|
},
|
|
|
|
async getSharedSession(shareToken: string): Promise<SharedSessionView> {
|
|
const response = await apiClient.get<SharedSessionView>(`/share/${shareToken}`)
|
|
return response.data
|
|
},
|
|
}
|
|
|
|
export default sessionsApi
|