import type { CircuitListDto, CreateFloorInput, CreateProjectDeviceInput, CreateRoomInput, CreateGlobalDeviceInput, DistributionBoardDto, FloorDto, GlobalDeviceDto, ProjectCommandDto, ProjectCommandResultDto, ProjectDeviceCommandResultDto, ProjectDeviceDto, ProjectHistoryStateDto, ProjectDeviceSyncCommandResultDto, ProjectDeviceSyncPreviewDto, ProjectDto, RoomDto, CircuitTreeResponseDto, } from "../types"; import type { ProjectDeviceSyncField } from "../../shared/constants/project-device-sync-fields"; import { createCircuitUpdateProjectCommand, type CircuitUpdatePatch, } from "../../domain/models/circuit-project-command.model"; import { createCircuitDeviceRowUpdateProjectCommand, type CircuitDeviceRowUpdatePatch, } from "../../domain/models/circuit-device-row-project-command.model"; import type { CircuitDeviceRowSnapshot, } from "../../domain/models/circuit-device-row-structure-project-command.model"; import type { CircuitSnapshot, } from "../../domain/models/circuit-structure-project-command.model"; import type { CircuitDeviceRowMoveAssignment, } from "../../domain/models/circuit-device-row-move-project-command.model"; async function request(url: string, init?: RequestInit): Promise { const response = await fetch(url, { ...init, headers: { "Content-Type": "application/json", ...init?.headers, }, cache: "no-store", }); if (!response.ok) { const details = await response.text(); throw new Error(details || `Anfrage fehlgeschlagen (Status ${response.status})`); } if (response.status === 204) { return undefined as T; } return response.json() as Promise; } export function listProjects() { return request("/api/projects"); } export function getProject(projectId: string) { return request(`/api/projects/${projectId}`); } export function getProjectHistory(projectId: string) { return request( `/api/projects/${projectId}/history` ); } export function executeProjectCommand( projectId: string, expectedRevision: number, command: ProjectCommandDto, description?: string ) { return request( `/api/projects/${projectId}/commands`, { method: "POST", body: JSON.stringify({ expectedRevision, command, ...(description ? { description } : {}), }), } ); } export function undoProjectCommand( projectId: string, expectedRevision: number ) { return executeProjectHistoryCommand( projectId, expectedRevision, "undo" ); } export function redoProjectCommand( projectId: string, expectedRevision: number ) { return executeProjectHistoryCommand( projectId, expectedRevision, "redo" ); } function executeProjectHistoryCommand( projectId: string, expectedRevision: number, direction: "undo" | "redo" ) { return request( `/api/projects/${projectId}/history/${direction}`, { method: "POST", body: JSON.stringify({ expectedRevision }), } ); } export function createProject(name: string) { return request("/api/projects", { method: "POST", body: JSON.stringify({ name }), }); } export function updateProjectSettings( projectId: string, input: { singlePhaseVoltageV: number; threePhaseVoltageV: number } ) { return request(`/api/projects/${projectId}`, { method: "PUT", body: JSON.stringify(input), }); } export function listDistributionBoards(projectId: string) { return request(`/api/projects/${projectId}/distribution-boards`); } export function createDistributionBoard(projectId: string, name: string) { return request(`/api/projects/${projectId}/distribution-boards`, { method: "POST", body: JSON.stringify({ name }), }); } export function listCircuitLists(projectId: string) { return request(`/api/projects/${projectId}/circuit-lists`); } export function getCircuitTree(projectId: string, circuitListId: string) { return request(`/api/projects/${projectId}/circuit-lists/${circuitListId}/tree`); } export function updateCircuitById( projectId: string, expectedRevision: number, circuitId: string, input: CircuitUpdatePatch ) { return executeProjectCommand( projectId, expectedRevision, createCircuitUpdateProjectCommand(circuitId, input), "Stromkreisfeld bearbeiten" ); } export function insertCircuitCommand( projectId: string, expectedRevision: number, circuit: CircuitSnapshot, description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit.insert", payload: { circuit }, }, description ); } export function deleteCircuitCommand( projectId: string, expectedRevision: number, circuitId: string, expectedCircuitListId: string, description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit.delete", payload: { circuitId, expectedCircuitListId }, }, description ); } export function getNextCircuitIdentifier(sectionId: string) { return request<{ sectionId: string; nextIdentifier: string }>( `/api/circuit-sections/${sectionId}/next-identifier` ); } export function updateCircuitDeviceRowById( projectId: string, expectedRevision: number, rowId: string, input: CircuitDeviceRowUpdatePatch ) { return executeProjectCommand( projectId, expectedRevision, createCircuitDeviceRowUpdateProjectCommand(rowId, input), "Gerätezeilenfeld bearbeiten" ); } export function insertCircuitDeviceRowCommand( projectId: string, expectedRevision: number, row: CircuitDeviceRowSnapshot, description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit-device-row.insert", payload: { row }, }, description ); } export function deleteCircuitDeviceRowCommand( projectId: string, expectedRevision: number, rowId: string, expectedCircuitId: string, description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit-device-row.delete", payload: { rowId, expectedCircuitId }, }, description ); } export function moveCircuitDeviceRowsCommand( projectId: string, expectedRevision: number, moves: CircuitDeviceRowMoveAssignment[], description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit-device-row.move", payload: { moves }, }, description ); } export function moveCircuitDeviceRowsToNewCircuitCommand( projectId: string, expectedRevision: number, targetCircuit: CircuitSnapshot, moves: CircuitDeviceRowMoveAssignment[], description: string ) { return executeProjectCommand( projectId, expectedRevision, { schemaVersion: 1, type: "circuit-device-row.move-with-new-circuit", payload: { targetCircuitAction: "create", targetCircuit, moves, }, }, description ); } export function renumberCircuitSection(sectionId: string) { return request(`/api/circuit-sections/${sectionId}/renumber`, { method: "POST", }); } export function reorderSectionCircuits(sectionId: string, orderedCircuitIds: string[]) { return request(`/api/circuit-sections/${sectionId}/circuits/reorder`, { method: "PATCH", body: JSON.stringify({ orderedCircuitIds }), }); } export function updateSectionEquipmentIdentifiers( sectionId: string, identifiers: Array<{ circuitId: string; equipmentIdentifier: string }> ) { return request(`/api/circuit-sections/${sectionId}/equipment-identifiers`, { method: "PATCH", body: JSON.stringify({ identifiers }), }); } export function listFloors(projectId: string) { return request(`/api/projects/${projectId}/floors`); } export function createFloor(projectId: string, input: CreateFloorInput) { return request(`/api/projects/${projectId}/floors`, { method: "POST", body: JSON.stringify(input), }); } export function listRooms(projectId: string) { return request(`/api/projects/${projectId}/rooms`); } export function createRoom(projectId: string, input: CreateRoomInput) { return request(`/api/projects/${projectId}/rooms`, { method: "POST", body: JSON.stringify(input), }); } export function listGlobalDevices() { return request("/api/global-devices"); } export function createGlobalDevice(input: CreateGlobalDeviceInput) { return request("/api/global-devices", { method: "POST", body: JSON.stringify(input), }); } export function updateGlobalDevice(globalDeviceId: string, input: CreateGlobalDeviceInput) { return request(`/api/global-devices/${globalDeviceId}`, { method: "PUT", body: JSON.stringify(input), }); } export function deleteGlobalDevice(globalDeviceId: string) { return request(`/api/global-devices/${globalDeviceId}`, { method: "DELETE" }); } export function copyProjectDeviceToGlobal(projectId: string, projectDeviceId: string) { return request(`/api/global-devices/import-project/${projectId}/${projectDeviceId}`, { method: "POST", }); } export function listProjectDevices(projectId: string) { return request(`/api/project-devices/projects/${projectId}`); } export function createProjectDevice( projectId: string, input: CreateProjectDeviceInput, expectedRevision: number ) { return request(`/api/project-devices/projects/${projectId}`, { method: "POST", body: JSON.stringify({ ...input, expectedRevision }), }); } export function updateProjectDevice( projectId: string, projectDeviceId: string, input: CreateProjectDeviceInput, expectedRevision: number ) { return request( `/api/project-devices/projects/${projectId}/${projectDeviceId}`, { method: "PUT", body: JSON.stringify({ ...input, expectedRevision }), } ); } export function deleteProjectDevice( projectId: string, projectDeviceId: string, expectedRevision: number ) { return request( `/api/project-devices/projects/${projectId}/${projectDeviceId}`, { method: "DELETE", body: JSON.stringify({ expectedRevision }), } ); } export function copyGlobalDeviceToProject( projectId: string, globalDeviceId: string, expectedRevision: number ) { return request( `/api/project-devices/projects/${projectId}/import-global/${globalDeviceId}`, { method: "POST", body: JSON.stringify({ expectedRevision }), } ); } export function getProjectDeviceSyncPreview(projectId: string, projectDeviceId: string) { return request( `/api/project-devices/projects/${projectId}/${projectDeviceId}/links` ); } export function synchronizeProjectDeviceRows( projectId: string, projectDeviceId: string, rowIds: string[], fields: ProjectDeviceSyncField[], expectedRevision: number ) { return request( `/api/project-devices/projects/${projectId}/${projectDeviceId}/synchronize`, { method: "POST", body: JSON.stringify({ rowIds, fields, expectedRevision }), } ); } export function disconnectProjectDeviceRows( projectId: string, projectDeviceId: string, rowIds: string[], expectedRevision: number ) { return request( `/api/project-devices/projects/${projectId}/${projectDeviceId}/disconnect`, { method: "POST", body: JSON.stringify({ rowIds, expectedRevision }), } ); }