Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
150 lines
3.9 KiB
TypeScript
150 lines
3.9 KiB
TypeScript
/**
|
|
* `useTemplates` — view-model hook for the templates feature (L7).
|
|
*
|
|
* Owns the templates list and CRUD actions. Consumes {@link TemplateGateway}
|
|
* exclusively; never touches `invoke()` or `@tauri-apps/api`, keeping the
|
|
* component layer testable with mock gateways (ARCHITECTURE §1.3).
|
|
*/
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
|
|
import type { GatewayError, Template } from "@/domain";
|
|
import type { CreateTemplateInput } from "@/ports";
|
|
import { useGateways } from "@/app/di";
|
|
|
|
/** What the templates UI needs from this hook. */
|
|
export interface TemplatesViewModel {
|
|
/** All templates. */
|
|
templates: Template[];
|
|
/** Last error message, or `null`. */
|
|
error: string | null;
|
|
/** Whether a request is in flight. */
|
|
busy: boolean;
|
|
/** Reloads the template list. */
|
|
refresh: () => Promise<void>;
|
|
/** Creates a new template and refreshes the list. */
|
|
createTemplate: (input: CreateTemplateInput) => Promise<void>;
|
|
/** Updates the content of an existing template. */
|
|
updateTemplate: (templateId: string, content: string) => Promise<void>;
|
|
/** Deletes a template by id. */
|
|
deleteTemplate: (templateId: string) => Promise<void>;
|
|
/** Creates an agent from a template in the given project. */
|
|
createAgentFromTemplate: (
|
|
projectId: string,
|
|
templateId: string,
|
|
opts?: { name?: string; synchronized?: boolean },
|
|
) => Promise<void>;
|
|
}
|
|
|
|
function describe(e: unknown): string {
|
|
if (e && typeof e === "object" && "message" in e) {
|
|
return String((e as GatewayError).message);
|
|
}
|
|
return String(e);
|
|
}
|
|
|
|
export function useTemplates(): TemplatesViewModel {
|
|
const { template } = useGateways();
|
|
|
|
const [templates, setTemplates] = useState<Template[]>([]);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [busy, setBusy] = useState(false);
|
|
|
|
const refresh = useCallback(async () => {
|
|
setBusy(true);
|
|
setError(null);
|
|
try {
|
|
const list = await template.listTemplates();
|
|
setTemplates(list);
|
|
} catch (e) {
|
|
setError(describe(e));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
}, [template]);
|
|
|
|
useEffect(() => {
|
|
void refresh();
|
|
}, [refresh]);
|
|
|
|
const createTemplate = useCallback(
|
|
async (input: CreateTemplateInput) => {
|
|
setBusy(true);
|
|
setError(null);
|
|
try {
|
|
const created = await template.createTemplate(input);
|
|
setTemplates((prev) => [...prev, created]);
|
|
} catch (e) {
|
|
setError(describe(e));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
},
|
|
[template],
|
|
);
|
|
|
|
const updateTemplate = useCallback(
|
|
async (templateId: string, content: string) => {
|
|
setBusy(true);
|
|
setError(null);
|
|
try {
|
|
const updated = await template.updateTemplate(templateId, content);
|
|
setTemplates((prev) =>
|
|
prev.map((t) => (t.id === templateId ? updated : t)),
|
|
);
|
|
} catch (e) {
|
|
setError(describe(e));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
},
|
|
[template],
|
|
);
|
|
|
|
const deleteTemplate = useCallback(
|
|
async (templateId: string) => {
|
|
setBusy(true);
|
|
setError(null);
|
|
try {
|
|
await template.deleteTemplate(templateId);
|
|
setTemplates((prev) => prev.filter((t) => t.id !== templateId));
|
|
} catch (e) {
|
|
setError(describe(e));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
},
|
|
[template],
|
|
);
|
|
|
|
const createAgentFromTemplate = useCallback(
|
|
async (
|
|
projectId: string,
|
|
templateId: string,
|
|
opts?: { name?: string; synchronized?: boolean },
|
|
) => {
|
|
setBusy(true);
|
|
setError(null);
|
|
try {
|
|
await template.createAgentFromTemplate(projectId, templateId, opts);
|
|
} catch (e) {
|
|
setError(describe(e));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
},
|
|
[template],
|
|
);
|
|
|
|
return {
|
|
templates,
|
|
error,
|
|
busy,
|
|
refresh,
|
|
createTemplate,
|
|
updateTemplate,
|
|
deleteTemplate,
|
|
createAgentFromTemplate,
|
|
};
|
|
}
|