refactor: rename services to scripts and extract reusable components

This commit is contained in:
Mohamed Boudra
2026-04-09 18:54:25 +07:00
parent 5cf806dc77
commit 397d454de0
48 changed files with 1356 additions and 983 deletions
@@ -81,7 +81,7 @@ describe("openProjectDirectly", () => {
status: "done" as const,
activityAt: null,
diffStat: null,
services: [],
scripts: [],
},
})),
},
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { WorkspaceServicePayload } from "@server/shared/messages";
import type { WorkspaceScriptPayload } from "@server/shared/messages";
import {
appendMissingOrderKeys,
applyStoredOrdering,
@@ -25,7 +25,7 @@ function workspace(
| "workspaceDirectory"
| "projectKind"
| "workspaceKind"
| "services"
| "scripts"
>
>,
): WorkspaceDescriptor {
@@ -41,12 +41,12 @@ function workspace(
status: input.status,
activityAt: input.activityAt,
diffStat: null,
services: input.services ?? [],
scripts: input.scripts ?? [],
};
}
const runningService: WorkspaceServicePayload = {
serviceName: "web",
const runningScript: WorkspaceScriptPayload = {
scriptName: "web",
hostname: "main.web.localhost",
port: 3000,
url: "http://main.web.localhost:6767",
@@ -54,8 +54,8 @@ const runningService: WorkspaceServicePayload = {
health: "healthy",
};
const stoppedService: WorkspaceServicePayload = {
serviceName: "api",
const stoppedScript: WorkspaceScriptPayload = {
scriptName: "api",
hostname: "main.api.localhost",
port: 3001,
url: "http://main.api.localhost:6767",
@@ -143,7 +143,7 @@ describe("buildSidebarProjectsFromWorkspaces", () => {
expect(projects[0]?.workspaces[0]?.statusBucket).toBe("failed");
});
it("threads services into workspace rows and derives hasRunningServices", () => {
it("threads scripts into workspace rows and derives hasRunningScripts", () => {
const projects = buildSidebarProjectsFromWorkspaces({
serverId: "srv",
workspaces: [
@@ -153,15 +153,15 @@ describe("buildSidebarProjectsFromWorkspaces", () => {
name: "main",
status: "running",
activityAt: new Date("2026-01-01T00:00:00.000Z"),
services: [runningService, stoppedService],
scripts: [runningScript, stoppedScript],
}),
],
projectOrder: [],
workspaceOrderByScope: {},
});
expect(projects[0]?.workspaces[0]?.services).toEqual([runningService, stoppedService]);
expect(projects[0]?.workspaces[0]?.hasRunningServices).toBe(true);
expect(projects[0]?.workspaces[0]?.scripts).toEqual([runningScript, stoppedScript]);
expect(projects[0]?.workspaces[0]?.hasRunningScripts).toBe(true);
});
it("preserves stored project order even when activity changes", () => {
@@ -28,8 +28,8 @@ export interface SidebarWorkspaceEntry {
activityAt: Date | null;
statusBucket: SidebarStateBucket;
diffStat: { additions: number; deletions: number } | null;
services: WorkspaceDescriptor["services"];
hasRunningServices: boolean;
scripts: WorkspaceDescriptor["scripts"];
hasRunningScripts: boolean;
}
export interface SidebarProjectEntry {
@@ -148,8 +148,8 @@ export function buildSidebarProjectsFromWorkspaces(input: {
activityAt: workspace.activityAt,
statusBucket: workspace.status,
diffStat: workspace.diffStat,
services: workspace.services,
hasRunningServices: workspace.services.some((service) => service.lifecycle === "running"),
scripts: workspace.scripts,
hasRunningScripts: workspace.scripts.some((script) => script.lifecycle === "running"),
};
project.workspaces.push(row);
@@ -273,11 +273,11 @@ function toWorkspaceDescriptor(payload: {
name: string;
status: WorkspaceDescriptor["status"];
activityAt: string | null;
services?: WorkspaceDescriptorPayload["services"];
scripts?: WorkspaceDescriptorPayload["scripts"];
}): WorkspaceDescriptor {
return normalizeWorkspaceDescriptor({
...payload,
services: payload.services ?? [],
scripts: payload.scripts ?? [],
});
}