Files
leistungsbilanz-ts/src/frontend/utils/api.ts
T
2026-07-25 21:09:02 +02:00

483 lines
12 KiB
TypeScript

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<T>(url: string, init?: RequestInit): Promise<T> {
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<T>;
}
export function listProjects() {
return request<ProjectDto[]>("/api/projects");
}
export function getProject(projectId: string) {
return request<ProjectDto>(`/api/projects/${projectId}`);
}
export function getProjectHistory(projectId: string) {
return request<ProjectHistoryStateDto>(
`/api/projects/${projectId}/history`
);
}
export function executeProjectCommand(
projectId: string,
expectedRevision: number,
command: ProjectCommandDto,
description?: string
) {
return request<ProjectCommandResultDto>(
`/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<ProjectCommandResultDto>(
`/api/projects/${projectId}/history/${direction}`,
{
method: "POST",
body: JSON.stringify({ expectedRevision }),
}
);
}
export function createProject(name: string) {
return request<ProjectDto>("/api/projects", {
method: "POST",
body: JSON.stringify({ name }),
});
}
export function updateProjectSettings(
projectId: string,
input: { singlePhaseVoltageV: number; threePhaseVoltageV: number }
) {
return request<ProjectDto>(`/api/projects/${projectId}`, {
method: "PUT",
body: JSON.stringify(input),
});
}
export function listDistributionBoards(projectId: string) {
return request<DistributionBoardDto[]>(`/api/projects/${projectId}/distribution-boards`);
}
export function createDistributionBoard(projectId: string, name: string) {
return request<DistributionBoardDto>(`/api/projects/${projectId}/distribution-boards`, {
method: "POST",
body: JSON.stringify({ name }),
});
}
export function listCircuitLists(projectId: string) {
return request<CircuitListDto[]>(`/api/projects/${projectId}/circuit-lists`);
}
export function getCircuitTree(projectId: string, circuitListId: string) {
return request<CircuitTreeResponseDto>(`/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<FloorDto[]>(`/api/projects/${projectId}/floors`);
}
export function createFloor(projectId: string, input: CreateFloorInput) {
return request<FloorDto>(`/api/projects/${projectId}/floors`, {
method: "POST",
body: JSON.stringify(input),
});
}
export function listRooms(projectId: string) {
return request<RoomDto[]>(`/api/projects/${projectId}/rooms`);
}
export function createRoom(projectId: string, input: CreateRoomInput) {
return request<RoomDto>(`/api/projects/${projectId}/rooms`, {
method: "POST",
body: JSON.stringify(input),
});
}
export function listGlobalDevices() {
return request<GlobalDeviceDto[]>("/api/global-devices");
}
export function createGlobalDevice(input: CreateGlobalDeviceInput) {
return request<GlobalDeviceDto>("/api/global-devices", {
method: "POST",
body: JSON.stringify(input),
});
}
export function updateGlobalDevice(globalDeviceId: string, input: CreateGlobalDeviceInput) {
return request<GlobalDeviceDto>(`/api/global-devices/${globalDeviceId}`, {
method: "PUT",
body: JSON.stringify(input),
});
}
export function deleteGlobalDevice(globalDeviceId: string) {
return request<void>(`/api/global-devices/${globalDeviceId}`, { method: "DELETE" });
}
export function copyProjectDeviceToGlobal(projectId: string, projectDeviceId: string) {
return request<GlobalDeviceDto>(`/api/global-devices/import-project/${projectId}/${projectDeviceId}`, {
method: "POST",
});
}
export function listProjectDevices(projectId: string) {
return request<ProjectDeviceDto[]>(`/api/project-devices/projects/${projectId}`);
}
export function createProjectDevice(
projectId: string,
input: CreateProjectDeviceInput,
expectedRevision: number
) {
return request<ProjectDeviceCommandResultDto>(`/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<ProjectDeviceCommandResultDto>(
`/api/project-devices/projects/${projectId}/${projectDeviceId}`,
{
method: "PUT",
body: JSON.stringify({ ...input, expectedRevision }),
}
);
}
export function deleteProjectDevice(
projectId: string,
projectDeviceId: string,
expectedRevision: number
) {
return request<ProjectCommandResultDto>(
`/api/project-devices/projects/${projectId}/${projectDeviceId}`,
{
method: "DELETE",
body: JSON.stringify({ expectedRevision }),
}
);
}
export function copyGlobalDeviceToProject(
projectId: string,
globalDeviceId: string,
expectedRevision: number
) {
return request<ProjectDeviceCommandResultDto>(
`/api/project-devices/projects/${projectId}/import-global/${globalDeviceId}`,
{
method: "POST",
body: JSON.stringify({ expectedRevision }),
}
);
}
export function getProjectDeviceSyncPreview(projectId: string, projectDeviceId: string) {
return request<ProjectDeviceSyncPreviewDto>(
`/api/project-devices/projects/${projectId}/${projectDeviceId}/links`
);
}
export function synchronizeProjectDeviceRows(
projectId: string,
projectDeviceId: string,
rowIds: string[],
fields: ProjectDeviceSyncField[],
expectedRevision: number
) {
return request<ProjectDeviceSyncCommandResultDto>(
`/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<ProjectDeviceSyncCommandResultDto>(
`/api/project-devices/projects/${projectId}/${projectDeviceId}/disconnect`,
{
method: "POST",
body: JSON.stringify({ rowIds, expectedRevision }),
}
);
}