Move circuits between groups
This commit is contained in:
@@ -13,6 +13,9 @@ import type {
|
||||
import type {
|
||||
CircuitGroupRenumberPlan,
|
||||
} from "../../domain/services/circuit-group-renumbering";
|
||||
import type {
|
||||
CircuitGroupMovePlan,
|
||||
} from "../../domain/services/circuit-group-move-planning";
|
||||
|
||||
export function toCircuitGroupSnapshot(
|
||||
section: CircuitTreeSectionDto,
|
||||
@@ -187,6 +190,92 @@ export function canRenumberCircuitGroups(
|
||||
);
|
||||
}
|
||||
|
||||
export function canMoveCircuitToGroup(
|
||||
sections: readonly CircuitTreeSectionDto[],
|
||||
circuitId: string,
|
||||
targetSectionId: string
|
||||
) {
|
||||
const source = sections.find((section) =>
|
||||
section.circuits.some((circuit) => circuit.id === circuitId)
|
||||
);
|
||||
const target = sections.find(
|
||||
(section) => section.id === targetSectionId
|
||||
);
|
||||
return Boolean(
|
||||
source?.category &&
|
||||
target?.category &&
|
||||
source.id !== target.id &&
|
||||
source.category === target.category
|
||||
);
|
||||
}
|
||||
|
||||
export function buildCircuitGroupMovePlan(input: {
|
||||
sections: readonly CircuitTreeSectionDto[];
|
||||
circuitId: string;
|
||||
targetSectionId: string;
|
||||
placement:
|
||||
| { kind: "end" }
|
||||
| {
|
||||
kind: "before" | "after";
|
||||
targetCircuitId: string;
|
||||
};
|
||||
}): CircuitGroupMovePlan {
|
||||
const sourceGroup = input.sections.find((section) =>
|
||||
section.circuits.some(
|
||||
(circuit) => circuit.id === input.circuitId
|
||||
)
|
||||
);
|
||||
const targetGroup = input.sections.find(
|
||||
(section) => section.id === input.targetSectionId
|
||||
);
|
||||
const circuit = sourceGroup?.circuits.find(
|
||||
(entry) => entry.id === input.circuitId
|
||||
);
|
||||
if (
|
||||
!sourceGroup?.category ||
|
||||
!sourceGroup.groupNumber ||
|
||||
!targetGroup?.category ||
|
||||
!targetGroup.groupNumber ||
|
||||
!circuit ||
|
||||
sourceGroup.id === targetGroup.id ||
|
||||
sourceGroup.category !== targetGroup.category
|
||||
) {
|
||||
throw new Error(
|
||||
"Stromkreise können nur zwischen verschiedenen Gruppen derselben Kategorie verschoben werden."
|
||||
);
|
||||
}
|
||||
parseCircuitNumber(
|
||||
circuit.equipmentIdentifier,
|
||||
sourceGroup.category,
|
||||
sourceGroup.groupNumber
|
||||
);
|
||||
const targetCircuitNumbers = targetGroup.circuits.map((entry) =>
|
||||
parseCircuitNumber(
|
||||
entry.equipmentIdentifier,
|
||||
targetGroup.category!,
|
||||
targetGroup.groupNumber!
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
circuitId: circuit.id,
|
||||
circuitListId: circuit.circuitListId,
|
||||
expectedSectionId: sourceGroup.id,
|
||||
targetSectionId: targetGroup.id,
|
||||
expectedEquipmentIdentifier: circuit.equipmentIdentifier,
|
||||
targetEquipmentIdentifier: formatCircuitIdentifier(
|
||||
targetGroup.category,
|
||||
targetGroup.groupNumber,
|
||||
Math.max(0, ...targetCircuitNumbers) + 1
|
||||
),
|
||||
expectedSortOrder: circuit.sortOrder,
|
||||
targetSortOrder: getCircuitMoveSortOrder(
|
||||
targetGroup.circuits,
|
||||
input.placement
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function getNewGroupSortOrder(
|
||||
category: CircuitGroupCategory,
|
||||
sections: readonly (CircuitTreeSectionDto & {
|
||||
@@ -287,3 +376,41 @@ function formatGroupComponentIdentifier(
|
||||
"Die Stromkreisgruppe enthält eine nicht unterstützte Verteilerkomponente."
|
||||
);
|
||||
}
|
||||
|
||||
function getCircuitMoveSortOrder(
|
||||
circuits: CircuitTreeSectionDto["circuits"],
|
||||
placement:
|
||||
| { kind: "end" }
|
||||
| {
|
||||
kind: "before" | "after";
|
||||
targetCircuitId: string;
|
||||
}
|
||||
) {
|
||||
const ordered = [...circuits].sort(
|
||||
(left, right) =>
|
||||
left.sortOrder - right.sortOrder ||
|
||||
left.id.localeCompare(right.id)
|
||||
);
|
||||
if (placement.kind === "end") {
|
||||
return ordered.length === 0
|
||||
? 10
|
||||
: ordered[ordered.length - 1].sortOrder + 10;
|
||||
}
|
||||
const index = ordered.findIndex(
|
||||
(circuit) => circuit.id === placement.targetCircuitId
|
||||
);
|
||||
if (index < 0) {
|
||||
throw new Error("Der Zielstromkreis wurde nicht gefunden.");
|
||||
}
|
||||
const current = ordered[index].sortOrder;
|
||||
if (placement.kind === "before") {
|
||||
const previous = ordered[index - 1]?.sortOrder;
|
||||
return previous === undefined
|
||||
? current - 10
|
||||
: previous + (current - previous) / 2;
|
||||
}
|
||||
const next = ordered[index + 1]?.sortOrder;
|
||||
return next === undefined
|
||||
? current + 10
|
||||
: current + (next - current) / 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user