Skip to content

Commit 22cc4a1

Browse files
authored
Merge pull request #244 from ProverCoderAI/issue-239
feat(app): add container task manager
2 parents 0acfd65 + 513fcc3 commit 22cc4a1

29 files changed

Lines changed: 848 additions & 186 deletions
18 KB
Loading
44 KB
Loading
71.9 KB
Loading
84.1 KB
Loading

packages/app/src/web/actions-shared.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export type BrowserActionContext = {
5454
readonly addTerminalSession: (session: ActiveTerminalSession) => void
5555
readonly githubStatus: GithubAuthStatus | null
5656
readonly portForwardInput: string
57+
readonly projectTasksIncludeDefault: boolean
5758
readonly reloadDashboard: () => void
5859
readonly selectedProjectId: string | null
5960
readonly selectedProjectKey: string | null
@@ -76,6 +77,7 @@ export type BrowserActionContext = {
7677
readonly setProjectBrowser: Setter<ProjectBrowserSession | null>
7778
readonly setProjectTaskLogs: Setter<string>
7879
readonly setProjectTasks: Setter<ContainerTaskSnapshot | null>
80+
readonly setProjectTasksIncludeDefault: Setter<boolean>
7981
readonly setSelectedMenuIndex: Setter<number>
8082
readonly setSelectedProject: Setter<ProjectDetails | null>
8183
readonly setSelectedProjectId: Setter<string | null>

packages/app/src/web/actions-tasks.ts

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import type { Effect } from "effect"
1+
import { Effect } from "effect"
22

3-
import { type BrowserActionContext, requireSelectedProjectId, withBusy } from "./actions-shared.js"
3+
import { type BrowserActionContext, confirmAction, requireSelectedProjectId, withBusy } from "./actions-shared.js"
44
import { loadProjectTaskLogs, loadProjectTasks, stopProjectTask } from "./api.js"
55
import type { ContainerTaskSnapshot } from "./api.js"
66

7+
type LoadSelectedProjectTasksOptions = {
8+
readonly includeDefault?: boolean
9+
readonly silent?: boolean
10+
}
11+
712
const requireProjectIdForTasks = (context: BrowserActionContext): string | null => {
813
const projectId = requireSelectedProjectId(context)
914
if (projectId === null) {
@@ -66,16 +71,20 @@ const removeTaskFromSnapshot = (
6671

6772
const stopSelectedProjectTaskEffect = (
6873
selected: SelectedProjectTaskAction
69-
): Effect.Effect<void, string> => stopProjectTask(selected.projectId, selected.pid)
74+
): Effect.Effect<ContainerTaskSnapshot, string> =>
75+
stopProjectTask(selected.projectId, selected.pid).pipe(
76+
Effect.flatMap(() => loadProjectTasks(selected.projectId, selected.context.projectTasksIncludeDefault))
77+
)
7078

7179
const loadSelectedProjectTaskLogsEffect = (
7280
selected: SelectedProjectTaskAction
7381
): Effect.Effect<string, string> => loadProjectTaskLogs(selected.projectId, selected.pid, 200)
7482

7583
const applyStoppedProjectTask = (
76-
selected: SelectedProjectTaskAction
84+
selected: SelectedProjectTaskAction,
85+
snapshot: ContainerTaskSnapshot
7786
): void => {
78-
selected.context.setProjectTasks((snapshot) => removeTaskFromSnapshot(snapshot, selected.pid))
87+
selected.context.setProjectTasks(removeTaskFromSnapshot(snapshot, selected.pid))
7988
selected.context.setMessage(`Sent SIGTERM to PID ${selected.pid}.`)
8089
}
8190

@@ -87,18 +96,16 @@ const applyLoadedProjectTaskLogs = (
8796
selected.context.setMessage(`Loaded logs for PID ${selected.pid}.`)
8897
}
8998

90-
export const loadSelectedProjectTasks = (
99+
export const loadProjectTasksById = (
91100
context: BrowserActionContext,
92-
options?: { readonly silent?: boolean }
101+
projectId: string,
102+
options?: LoadSelectedProjectTasksOptions
93103
) => {
94-
const projectId = requireProjectIdForTasks(context)
95-
if (projectId === null) {
96-
return
97-
}
104+
const includeDefault = options?.includeDefault ?? context.projectTasksIncludeDefault
98105
withBusy({
99106
context,
100-
effect: loadProjectTasks(projectId),
101-
label: "Loading container tasks",
107+
effect: loadProjectTasks(projectId, includeDefault),
108+
label: includeDefault ? "Loading all container tasks" : "Loading container tasks",
102109
onSuccess: (snapshot) => {
103110
context.setProjectTasks(snapshot)
104111
if (options?.silent !== true) {
@@ -108,16 +115,46 @@ export const loadSelectedProjectTasks = (
108115
})
109116
}
110117

118+
export const loadSelectedProjectTasks = (
119+
context: BrowserActionContext,
120+
options?: LoadSelectedProjectTasksOptions
121+
) => {
122+
const projectId = requireProjectIdForTasks(context)
123+
if (projectId === null) {
124+
return
125+
}
126+
loadProjectTasksById(context, projectId, options)
127+
}
128+
129+
export const setSelectedProjectTasksIncludeDefault = (
130+
context: BrowserActionContext,
131+
includeDefault: boolean
132+
) => {
133+
context.setProjectTasksIncludeDefault(includeDefault)
134+
context.setProjectTaskLogs("")
135+
const projectId = requireProjectIdForTasks(context)
136+
if (projectId === null) {
137+
return
138+
}
139+
loadProjectTasksById(context, projectId, { includeDefault })
140+
}
141+
111142
export const stopSelectedProjectTask = (
112143
context: BrowserActionContext,
113144
pid: number
114145
) => {
115-
withSelectedProjectTaskBusy({
116-
context,
117-
effect: stopSelectedProjectTaskEffect,
118-
label: "Stopping container task",
119-
onSuccess: applyStoppedProjectTask,
120-
pid
146+
withSelectedProjectTask(context, pid, (selected) => {
147+
if (!confirmAction(`Stop PID ${selected.pid}?`)) {
148+
return
149+
}
150+
withBusy({
151+
context: selected.context,
152+
effect: stopSelectedProjectTaskEffect(selected),
153+
label: "Stopping container task",
154+
onSuccess: (snapshot) => {
155+
applyStoppedProjectTask(selected, snapshot)
156+
}
157+
})
121158
})
122159
}
123160

packages/app/src/web/actions.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ export {
3838
loadSelectedProjectInfo,
3939
runApplyAllProjects
4040
} from "./actions-projects.js"
41-
export { loadSelectedProjectTaskLogs, loadSelectedProjectTasks, stopSelectedProjectTask } from "./actions-tasks.js"
41+
export {
42+
loadProjectTasksById,
43+
loadSelectedProjectTaskLogs,
44+
loadSelectedProjectTasks,
45+
setSelectedProjectTasksIncludeDefault,
46+
stopSelectedProjectTask
47+
} from "./actions-tasks.js"
4248

4349
export const runBrowserMenuAction = (
4450
currentMenu: BrowserMenuTag,

packages/app/src/web/api-tasks.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ import { Effect } from "effect"
33
import { requestJson, requestText } from "./api-http.js"
44
import { ContainerTaskSnapshotResponseSchema, OutputResponseSchema } from "./api-schema.js"
55

6-
export const loadProjectTasks = (projectId: string) =>
6+
const projectTasksPath = (projectId: string, includeDefault: boolean): string =>
7+
`/projects/${encodeURIComponent(projectId)}/tasks${includeDefault ? "?includeDefault=true" : ""}`
8+
9+
export const loadProjectTasks = (projectId: string, includeDefault = false) =>
710
requestJson(
811
"GET",
9-
`/projects/${encodeURIComponent(projectId)}/tasks`,
12+
projectTasksPath(projectId, includeDefault),
1013
ContainerTaskSnapshotResponseSchema
1114
).pipe(
1215
Effect.map((response) => response.snapshot)

packages/app/src/web/app-ready-actions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type ActionContextArgs = {
1111
readonly addTerminalSession: BrowserActionContext["addTerminalSession"]
1212
readonly githubStatus: BrowserActionContext["githubStatus"]
1313
readonly portForwardInput: BrowserActionContext["portForwardInput"]
14+
readonly projectTasksIncludeDefault: BrowserActionContext["projectTasksIncludeDefault"]
1415
readonly refreshDashboard: () => void
1516
readonly selectedProjectId: string | null
1617
readonly selectedProjectKey: string | null
@@ -33,6 +34,7 @@ type ActionContextArgs = {
3334
readonly setProjectBrowser: BrowserActionContext["setProjectBrowser"]
3435
readonly setProjectTaskLogs: BrowserActionContext["setProjectTaskLogs"]
3536
readonly setProjectTasks: BrowserActionContext["setProjectTasks"]
37+
readonly setProjectTasksIncludeDefault: BrowserActionContext["setProjectTasksIncludeDefault"]
3638
readonly setSelectedMenuIndex: BrowserActionContext["setSelectedMenuIndex"]
3739
readonly setSelectedProject: BrowserActionContext["setSelectedProject"]
3840
readonly setSelectedProjectId: BrowserActionContext["setSelectedProjectId"]
@@ -47,6 +49,7 @@ export const createActionContext = (args: ActionContextArgs): BrowserActionConte
4749
databaseLabelInput: args.databaseLabelInput,
4850
githubStatus: args.githubStatus,
4951
portForwardInput: args.portForwardInput,
52+
projectTasksIncludeDefault: args.projectTasksIncludeDefault,
5053
reloadDashboard: args.refreshDashboard,
5154
selectedProjectId: args.selectedProjectId,
5255
selectedProjectKey: args.selectedProjectKey,
@@ -69,6 +72,7 @@ export const createActionContext = (args: ActionContextArgs): BrowserActionConte
6972
setProjectBrowser: args.setProjectBrowser,
7073
setProjectTaskLogs: args.setProjectTaskLogs,
7174
setProjectTasks: args.setProjectTasks,
75+
setProjectTasksIncludeDefault: args.setProjectTasksIncludeDefault,
7276
setSelectedMenuIndex: args.setSelectedMenuIndex,
7377
setSelectedProject: args.setSelectedProject,
7478
setSelectedProjectId: args.setSelectedProjectId

packages/app/src/web/app-ready-controller-context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const createReadyActionContext = (
1717
databaseLabelInput: state.databaseLabelInput,
1818
githubStatus: state.githubStatus,
1919
portForwardInput: state.portForwardInput,
20+
projectTasksIncludeDefault: state.projectTasksIncludeDefault,
2021
refreshDashboard,
2122
selectedProjectId: state.selectedProjectId,
2223
selectedProjectKey: selectedProjectSummary?.projectKey ?? null,
@@ -39,6 +40,7 @@ export const createReadyActionContext = (
3940
setProjectBrowser: state.setProjectBrowser,
4041
setProjectTaskLogs: state.setProjectTaskLogs,
4142
setProjectTasks: state.setProjectTasks,
43+
setProjectTasksIncludeDefault: state.setProjectTasksIncludeDefault,
4244
setSelectedMenuIndex: state.setSelectedMenuIndex,
4345
setSelectedProject: state.setSelectedProject,
4446
setSelectedProjectId: state.setSelectedProjectId

0 commit comments

Comments
 (0)