forked from jappel/leistungsbilanz-ts
Create feeder circuits while linking boards
This commit is contained in:
parent
552362bad1
commit
ade21fe386
11 changed files with 960 additions and 40 deletions
|
|
@ -47,6 +47,7 @@ import {
|
|||
import {
|
||||
copyGlobalDeviceToProject,
|
||||
copyDistributionBoard,
|
||||
createFeederCircuitAndUpdateDistributionBoard,
|
||||
copyProjectDeviceToGlobal,
|
||||
createDistributionBoard,
|
||||
createProjectDevice,
|
||||
|
|
@ -71,6 +72,12 @@ import {
|
|||
updateProjectDevice,
|
||||
updateProjectSettings,
|
||||
} from "../../../frontend/utils/api";
|
||||
import { createClientId } from "../../../frontend/utils/client-id";
|
||||
import {
|
||||
buildFeederCircuitSnapshot,
|
||||
getDefaultFeederCircuitSection,
|
||||
getNextFeederCircuitIdentifier,
|
||||
} from "../../../frontend/utils/distribution-board-feeder-circuit";
|
||||
import type {
|
||||
BuildingDto,
|
||||
CircuitListDto,
|
||||
|
|
@ -146,6 +153,7 @@ const boardFilterCollapsedStorageKey =
|
|||
"leistungsbilanz:overview-filter-collapsed:distribution-boards";
|
||||
const projectDeviceFilterCollapsedStorageKey =
|
||||
"leistungsbilanz:overview-filter-collapsed:project-devices";
|
||||
const createFeederCircuitSelectValue = "__create_feeder_circuit__";
|
||||
|
||||
export default function ProjectDetailPage() {
|
||||
const params = useParams<{ projectId: string }>();
|
||||
|
|
@ -175,6 +183,12 @@ export default function ProjectDetailPage() {
|
|||
const [editingBoardCopyName, setEditingBoardCopyName] = useState("");
|
||||
const [editingFeedingBoardId, setEditingFeedingBoardId] = useState("");
|
||||
const [editingFeedingCircuitId, setEditingFeedingCircuitId] = useState("");
|
||||
const [isCreatingFeederCircuit, setIsCreatingFeederCircuit] =
|
||||
useState(false);
|
||||
const [editingFeederCircuitSectionId, setEditingFeederCircuitSectionId] =
|
||||
useState("");
|
||||
const [editingFeederCircuitDisplayName, setEditingFeederCircuitDisplayName] =
|
||||
useState("");
|
||||
const [editingBoardInfo, setEditingBoardInfo] =
|
||||
useState<DistributionBoardInfoDraft>(
|
||||
toDistributionBoardInfoDraft({
|
||||
|
|
@ -350,6 +364,21 @@ export default function ProjectDetailPage() {
|
|||
const selectedFeedingCircuit = selectedFeedingCircuits.find(
|
||||
({ circuit }) => circuit.id === editingFeedingCircuitId
|
||||
);
|
||||
const feederCircuitSections =
|
||||
selectedFeedingTree?.sections.filter(
|
||||
(section) => section.category !== undefined
|
||||
) ?? [];
|
||||
const selectedNewFeederCircuitSection = feederCircuitSections.find(
|
||||
(section) => section.id === editingFeederCircuitSectionId
|
||||
);
|
||||
const newFeederCircuitIdentifier = selectedNewFeederCircuitSection
|
||||
? getNextFeederCircuitIdentifier(selectedNewFeederCircuitSection)
|
||||
: null;
|
||||
const selectedFeedingCircuitCategory =
|
||||
selectedFeedingCircuit?.section.category ??
|
||||
(isCreatingFeederCircuit
|
||||
? selectedNewFeederCircuitSection?.category
|
||||
: undefined);
|
||||
const selectedFeedingBoard = boards.find(
|
||||
(board) => board.id === editingFeedingBoardId
|
||||
);
|
||||
|
|
@ -556,6 +585,9 @@ export default function ProjectDetailPage() {
|
|||
setEditingBoardInfo(toDistributionBoardInfoDraft(board));
|
||||
setEditingFeedingBoardId(board.feedingDistributionBoardId ?? "");
|
||||
setEditingFeedingCircuitId(board.feedingCircuitId ?? "");
|
||||
setIsCreatingFeederCircuit(false);
|
||||
setEditingFeederCircuitSectionId("");
|
||||
setEditingFeederCircuitDisplayName("");
|
||||
}
|
||||
|
||||
function openBoardCreator() {
|
||||
|
|
@ -584,28 +616,56 @@ export default function ProjectDetailPage() {
|
|||
setIsSaving(true);
|
||||
setError(null);
|
||||
try {
|
||||
const result = await updateDistributionBoard(
|
||||
projectId,
|
||||
editingBoard.id,
|
||||
{
|
||||
floorId: editingBoardFloorId || null,
|
||||
supplyType: editingBoardSupplyType,
|
||||
simultaneityFactor,
|
||||
feedingDistributionBoardId: editingFeedingBoardId || null,
|
||||
feedingCircuitId: editingFeedingCircuitId || null,
|
||||
...fromDistributionBoardInfoDraft(editingBoardInfo),
|
||||
},
|
||||
project.currentRevision
|
||||
);
|
||||
setBoards((current) =>
|
||||
current.map((board) =>
|
||||
board.id === result.distributionBoard.id
|
||||
? result.distributionBoard
|
||||
: board
|
||||
)
|
||||
);
|
||||
const boardInput = {
|
||||
floorId: editingBoardFloorId || null,
|
||||
supplyType: editingBoardSupplyType,
|
||||
simultaneityFactor,
|
||||
feedingDistributionBoardId: editingFeedingBoardId || null,
|
||||
feedingCircuitId: editingFeedingCircuitId || null,
|
||||
...fromDistributionBoardInfoDraft(editingBoardInfo),
|
||||
};
|
||||
let result;
|
||||
if (isCreatingFeederCircuit) {
|
||||
if (!editingFeedingBoardId || !selectedFeedingTree) {
|
||||
throw new Error("Bitte eine speisende Verteilung wählen.");
|
||||
}
|
||||
if (!selectedNewFeederCircuitSection) {
|
||||
throw new Error(
|
||||
"Bitte eine Stromkreisgruppe für den neuen Abgang wählen."
|
||||
);
|
||||
}
|
||||
const circuit = buildFeederCircuitSnapshot({
|
||||
id: createClientId(),
|
||||
tree: selectedFeedingTree,
|
||||
sectionId: selectedNewFeederCircuitSection.id,
|
||||
displayName: editingFeederCircuitDisplayName,
|
||||
});
|
||||
result = await createFeederCircuitAndUpdateDistributionBoard(
|
||||
projectId,
|
||||
editingBoard.id,
|
||||
{
|
||||
...boardInput,
|
||||
feedingDistributionBoardId: editingFeedingBoardId,
|
||||
feedingCircuitId: circuit.id,
|
||||
},
|
||||
circuit,
|
||||
project.currentRevision
|
||||
);
|
||||
} else {
|
||||
result = await updateDistributionBoard(
|
||||
projectId,
|
||||
editingBoard.id,
|
||||
boardInput,
|
||||
project.currentRevision
|
||||
);
|
||||
}
|
||||
applyProjectRevision(result.history.currentRevision);
|
||||
setCircuitTrees((await getProjectCircuitTrees(projectId)).trees);
|
||||
const [updatedBoards, updatedTrees] = await Promise.all([
|
||||
listDistributionBoards(projectId),
|
||||
getProjectCircuitTrees(projectId),
|
||||
]);
|
||||
setBoards(updatedBoards);
|
||||
setCircuitTrees(updatedTrees.trees);
|
||||
setEditingBoard(null);
|
||||
} catch (err) {
|
||||
setError(
|
||||
|
|
@ -1567,8 +1627,16 @@ export default function ProjectDetailPage() {
|
|||
className="form-select"
|
||||
id="feeding-distribution-board"
|
||||
onChange={(event) => {
|
||||
setEditingFeedingBoardId(event.target.value);
|
||||
const boardId = event.target.value;
|
||||
setEditingFeedingBoardId(boardId);
|
||||
setEditingFeedingCircuitId("");
|
||||
setIsCreatingFeederCircuit(false);
|
||||
setEditingFeederCircuitSectionId(
|
||||
getDefaultFeederCircuitSection(
|
||||
circuitTreeByBoardId.get(boardId)
|
||||
)?.id ?? ""
|
||||
);
|
||||
setEditingFeederCircuitDisplayName("");
|
||||
}}
|
||||
value={editingFeedingBoardId}
|
||||
>
|
||||
|
|
@ -1588,10 +1656,31 @@ export default function ProjectDetailPage() {
|
|||
className="form-select"
|
||||
disabled={!editingFeedingBoardId}
|
||||
id="feeding-circuit"
|
||||
onChange={(event) => setEditingFeedingCircuitId(event.target.value)}
|
||||
value={editingFeedingCircuitId}
|
||||
onChange={(event) => {
|
||||
if (event.target.value === createFeederCircuitSelectValue) {
|
||||
setEditingFeedingCircuitId("");
|
||||
setIsCreatingFeederCircuit(true);
|
||||
setEditingFeederCircuitSectionId(
|
||||
(current) =>
|
||||
current ||
|
||||
getDefaultFeederCircuitSection(selectedFeedingTree)?.id ||
|
||||
""
|
||||
);
|
||||
return;
|
||||
}
|
||||
setIsCreatingFeederCircuit(false);
|
||||
setEditingFeedingCircuitId(event.target.value);
|
||||
}}
|
||||
value={
|
||||
isCreatingFeederCircuit
|
||||
? createFeederCircuitSelectValue
|
||||
: editingFeedingCircuitId
|
||||
}
|
||||
>
|
||||
<option value="">Nur Verteilung bekannt</option>
|
||||
<option value={createFeederCircuitSelectValue}>
|
||||
+ Neuen Einspeiseabgang anlegen …
|
||||
</option>
|
||||
{selectedFeedingCircuits.map(({ circuit }) => (
|
||||
<option key={circuit.id} value={circuit.id}>
|
||||
{circuit.equipmentIdentifier}
|
||||
|
|
@ -1600,7 +1689,62 @@ export default function ProjectDetailPage() {
|
|||
))}
|
||||
</select>
|
||||
</div>
|
||||
{editingFeedingBoardId && !editingFeedingCircuitId ? (
|
||||
{isCreatingFeederCircuit ? (
|
||||
<div className="col-12">
|
||||
<div className="border rounded p-3">
|
||||
<div className="row g-3">
|
||||
<div className="col-12 col-md-6">
|
||||
<label className="form-label" htmlFor="new-feeder-circuit-section">
|
||||
Stromkreisgruppe
|
||||
</label>
|
||||
<select
|
||||
className="form-select"
|
||||
id="new-feeder-circuit-section"
|
||||
onChange={(event) =>
|
||||
setEditingFeederCircuitSectionId(event.target.value)
|
||||
}
|
||||
required
|
||||
value={editingFeederCircuitSectionId}
|
||||
>
|
||||
{feederCircuitSections.map((section) => (
|
||||
<option key={section.id} value={section.id}>
|
||||
{section.displayName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="form-text">
|
||||
Vorgesehenes BMK: {newFeederCircuitIdentifier ?? "–"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-6">
|
||||
<label className="form-label" htmlFor="new-feeder-circuit-name">
|
||||
Abgangsbezeichnung (optional)
|
||||
</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="new-feeder-circuit-name"
|
||||
onChange={(event) =>
|
||||
setEditingFeederCircuitDisplayName(event.target.value)
|
||||
}
|
||||
placeholder="z. B. Steigetrasse Ost"
|
||||
value={editingFeederCircuitDisplayName}
|
||||
/>
|
||||
<div className="form-text">
|
||||
Ohne Zusatzbezeichnung wird der Name der gespeisten
|
||||
Verteilung angezeigt.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-text mt-2">
|
||||
Der Abgang wird erst beim Speichern angelegt und gemeinsam
|
||||
mit dieser Verteilung verknüpft. Es entsteht keine Gerätezeile.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{editingFeedingBoardId &&
|
||||
!editingFeedingCircuitId &&
|
||||
!isCreatingFeederCircuit ? (
|
||||
<div className="col-12">
|
||||
<div className="alert alert-warning mb-0 py-2">
|
||||
Ohne speisenden Abgang wird die Hierarchie angezeigt, die
|
||||
|
|
@ -1618,8 +1762,8 @@ export default function ProjectDetailPage() {
|
|||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{selectedFeedingCircuit &&
|
||||
selectedFeedingCircuit.section.category !== "three_phase" ? (
|
||||
{selectedFeedingCircuitCategory !== undefined &&
|
||||
selectedFeedingCircuitCategory !== "three_phase" ? (
|
||||
<div className="col-12">
|
||||
<div className="alert alert-warning mb-0 py-2">
|
||||
Der gewählte Abgang ist 1-phasig. Bitte prüfen, ob diese
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue