Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete commissioning packages #53

Merged
merged 14 commits into from
Jan 2, 2025
87 changes: 87 additions & 0 deletions www/src/components/editor/CommissioningPackageDeletionDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Button, Checkbox, Dialog, Table } from "@equinor/eds-core-react";
import React, { useEffect, useState } from "react";
import { useCommissioningPackageContext } from "../../hooks/useCommissioningPackageContext.tsx";

interface DeleteDialogProps {
isOpen: boolean;
onClose: () => void;
}

const DeleteCommissioningPackageDialog: React.FC<DeleteDialogProps> = ({ isOpen, onClose }) => {
const context = useCommissioningPackageContext();
const [selectedPackages, setSelectedPackages] = useState<Set<string>>(new Set());

const handleCheckboxChange = (packageId: string) => {
setSelectedPackages((prevSelected) => {
const newSelected = new Set(prevSelected);
if (newSelected.has(packageId)) {
newSelected.delete(packageId);
} else {
newSelected.add(packageId);
}
return newSelected;
});
};

const handleDelete = () => {
selectedPackages.forEach((packageId) => {
context?.deleteCommissioningPackage(packageId);
});
onClose();
setSelectedPackages(new Set());

if (context?.commissioningPackages.length === 0) {
context?.createInitialPackage();
}
};

useEffect(() => {
if (isOpen && context?.activePackage) {
setSelectedPackages(new Set([context.activePackage.id]));
}
}, [isOpen, context?.activePackage]);

return (
<Dialog open={isOpen} onClose={onClose}>
<Dialog.Header>
<Dialog.Title>Delete Commissioning Packages</Dialog.Title>
</Dialog.Header>
<Dialog.CustomContent>
Choose which commissioning packages to delete:
<Table>
<Table.Body>
{context?.commissioningPackages.map((commpckg) => (
<Table.Row key={commpckg.id}>
<Table.Cell>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div
style={{
width: '16px',
height: '16px',
backgroundColor: commpckg.color,
borderRadius: '50%',
marginRight: '8px',
}}
></div>
<Checkbox
label={commpckg.name}
name="multiple"
checked={selectedPackages.has(commpckg.id)}
onChange={() => handleCheckboxChange(commpckg.id)}
/>
</div>
</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table>
</Dialog.CustomContent>
<Dialog.Actions>
<Button onClick={handleDelete}>Delete</Button>
<Button variant="ghost" onClick={onClose}>Cancel</Button>
</Dialog.Actions>
</Dialog>
);
};

export default DeleteCommissioningPackageDialog;
16 changes: 15 additions & 1 deletion www/src/components/editor/EditorSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SideBar, SidebarLinkProps } from "@equinor/eds-core-react";
import { add, boundaries, category, texture } from "@equinor/eds-icons";
import { add, boundaries, category, texture, delete_to_trash } from "@equinor/eds-icons";
import styled from "styled-components";
import { useContext, useState } from "react";
import Tools from "../../enums/Tools.ts";
import { useCommissioningPackageContext } from "../../hooks/useCommissioningPackageContext.tsx";
import ToolContext from "../../context/ToolContext.ts";
import CommissioningPackageCreationDialog from "./CommissioningPackageCreationDialog.tsx";
import CommissioningPackageDeletionDialog from "./CommissioningPackageDeletionDialog.tsx";

const StyledSideBar = styled.div`
height: 100%;
Expand All @@ -15,6 +16,7 @@ export default function EditorSidebar() {
const context = useCommissioningPackageContext();
const { activeTool, setActiveTool } = useContext(ToolContext);
const [isCreationOpen, setIsCreationOpen] = useState<boolean>(false);
const [isDeleteOpen, setIsDeleteOpen] = useState<boolean>(false);

const menuItemsInitial: SidebarLinkProps[] = [
{
Expand All @@ -33,13 +35,25 @@ export default function EditorSidebar() {
},
active: activeTool === Tools.INSIDEBOUNDARY,
},
{
label: "Delete commissioning packages",
icon: delete_to_trash,
onClick: () => {
setIsDeleteOpen(true);
},
},
];

return (
<>
<CommissioningPackageCreationDialog
open={isCreationOpen}
setOpen={setIsCreationOpen}
/>
<CommissioningPackageDeletionDialog
isOpen={isDeleteOpen}
onClose={() => setIsDeleteOpen(false)}
/>
<StyledSideBar>
<SideBar>
<SideBar.Content>
Expand Down
63 changes: 52 additions & 11 deletions www/src/context/CommissioningPackageContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { createContext, useEffect, useState } from "react";
import CommissioningPackage from "../types/CommissioningPackage.ts";
import HighlightColors from "../enums/HighlightColors.ts";
import { deletePackageFromTripleStore } from "../utils/Triplestore.ts";

export interface CommissioningPackageContextProps {
activePackage: CommissioningPackage;
Expand All @@ -9,40 +10,80 @@ export interface CommissioningPackageContextProps {
setCommissioningPackages: React.Dispatch<
React.SetStateAction<CommissioningPackage[]>
>;
deleteCommissioningPackage: (packageId: string) => void;
createInitialPackage: () => CommissioningPackage;
}

const CommissioningPackageContext = createContext<
CommissioningPackageContextProps | undefined
>(undefined);

export const createInitialPackage = (): CommissioningPackage => ({
id: "asset:Package1",
name: "Initial Package",
color: HighlightColors.LASER_LEMON,
boundaryIds: [],
internalIds: [],
nodeIds: [],
});

export const CommissioningPackageContextProvider: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
const [activePackage, setActivePackage] = useState<CommissioningPackage>({
id: "asset:Package1",
name: "Initial Package",
color: HighlightColors.LASER_LEMON,
boundaryIds: [],
internalIds: [],
nodeIds: [],
});
const [commissioningPackages, setCommissioningPackages] = useState<
CommissioningPackage[]
>([]);
const [activePackage, setActivePackage] = useState<CommissioningPackage>(createInitialPackage());
const [commissioningPackages, setCommissioningPackages] = useState<CommissioningPackage[]>([]);

useEffect(() => {
if (activePackage && commissioningPackages.length === 0) {
setCommissioningPackages([activePackage]);
}
}, [activePackage, commissioningPackages]);

const deleteCommissioningPackage = async (packageId: string) => {
await deletePackageFromTripleStore(packageId);

if (commissioningPackages.length === 1) {
const initialPackage = createInitialPackage();
setCommissioningPackages([initialPackage]);
setActivePackage(initialPackage);
} else {
setCommissioningPackages((prevPackages) => {
const updatedPackages = prevPackages.filter((pkg) => pkg.id !== packageId);
if (activePackage.id === packageId) {
setActivePackage(updatedPackages[0]);
}
return updatedPackages;
});
}

setCommissioningPackages((prevPackages) =>
prevPackages.map((pkg) => ({
...pkg,
boundaryIds: pkg.boundaryIds.filter((id) => id !== packageId),
internalIds: pkg.internalIds.filter((id) => id !== packageId),
nodeIds: pkg.nodeIds.filter((id) => id !== packageId),
}))
);

if (activePackage.id === packageId) {
setActivePackage((prevPackage) => ({
...prevPackage,
boundaryIds: [],
internalIds: [],
nodeIds: [],
}));
}
};

return (
<CommissioningPackageContext.Provider
value={{
activePackage,
setActivePackage,
commissioningPackages,
setCommissioningPackages,
deleteCommissioningPackage,
createInitialPackage,
}}
>
{children}
Expand Down
7 changes: 7 additions & 0 deletions www/src/utils/Triplestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export async function cleanTripleStore() {
await queryTripleStore(deleteInternal, Method.Post);
}

export async function deletePackageFromTripleStore(packageId: string) {
const deleteBoundary = "DELETE WHERE { ?boundary comp:isBoundaryOf " + packageId + " . }";
const deleteInternal = "DELETE WHERE { ?internal comp:isInPackage " + packageId + " . }";
await queryTripleStore(deleteBoundary, Method.Post);
await queryTripleStore(deleteInternal, Method.Post);
}

export async function getNodeIdsInCommissioningPackage(packageIri: string) {
const query =
"SELECT ?node WHERE{?node comp:isInPackage " + packageIri + " .}";
Expand Down
Loading