From a516a1369050b1ed8764a6e7db88b19728684806 Mon Sep 17 00:00:00 2001 From: Adrian Nesvik Date: Wed, 19 Jun 2024 12:07:57 +0200 Subject: [PATCH] feat: Deletable Edges (#763) --- CHANGELOG.md | 12 +-- components/DeleteNodeDialog.tsx | 53 +++------- components/ScrimDelete.module.scss | 40 +++++++ components/ScrimDelete.tsx | 74 +++++++++++++ components/canvas/Canvas.tsx | 90 ++++++++++++---- .../canvas/CanvasTutorial/CanvasTutorial.tsx | 23 +++- .../CanvasTutorialButtonGroup.tsx | 2 + .../hooks/useCanvasTutorial.tsx | 6 ++ components/canvas/ChoiceEdge.module.scss | 28 ----- components/canvas/ChoiceEdge.tsx | 52 ---------- components/canvas/ChoiceNode.tsx | 4 +- components/canvas/CustomEdge.tsx | 78 ++++++++++++++ components/canvas/Edge.module.scss | 8 ++ components/canvas/EdgeElementTypes.tsx | 4 +- components/canvas/EdgeLabel.module.scss | 12 +++ .../{ChoiceEdgeLabel.tsx => EdgeLabel.tsx} | 85 ++++++++------- components/canvas/GenericNode.tsx | 8 +- components/canvas/MainActivityNode.tsx | 2 +- components/canvas/NodeCard.tsx | 2 +- components/canvas/SubActivityNode.tsx | 4 +- components/canvas/WaitingNode.tsx | 4 +- components/canvas/drawSvgPath.tsx | 58 +++++++++++ components/canvas/hooks/useEdgeDelete.tsx | 35 +++++++ components/canvas/utils/createEdges.tsx | 63 +++++++++++ components/canvas/utils/createHiddenNodes.ts | 39 +++---- package.json | 2 +- public/CanvasTutorial/delete-edge.gif | Bin 0 -> 167640 bytes public/CanvasTutorial/rename-edge.gif | Bin 0 -> 63004 bytes services/graphApi.ts | 8 ++ styles/_variables.scss | 2 + theme/colors.ts | 1 + types/EdgeTypes.tsx | 3 + types/NodeData.ts | 8 +- yarn.lock | 98 ++++++++---------- 34 files changed, 626 insertions(+), 282 deletions(-) create mode 100644 components/ScrimDelete.module.scss create mode 100644 components/ScrimDelete.tsx delete mode 100644 components/canvas/ChoiceEdge.module.scss delete mode 100644 components/canvas/ChoiceEdge.tsx create mode 100644 components/canvas/CustomEdge.tsx create mode 100644 components/canvas/Edge.module.scss create mode 100644 components/canvas/EdgeLabel.module.scss rename components/canvas/{ChoiceEdgeLabel.tsx => EdgeLabel.tsx} (50%) create mode 100644 components/canvas/drawSvgPath.tsx create mode 100644 components/canvas/hooks/useEdgeDelete.tsx create mode 100644 components/canvas/utils/createEdges.tsx create mode 100644 public/CanvasTutorial/delete-edge.gif create mode 100644 public/CanvasTutorial/rename-edge.gif create mode 100644 types/EdgeTypes.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e2cd20..38fc900e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,16 @@ ## [2.3.0](https://github.com/equinor/flyt/compare/v2.2.0...v2.3.0) (2024-06-18) - ### Features -* Click to rename project title ([#489](https://github.com/equinor/flyt/issues/489)) ([d74062f](https://github.com/equinor/flyt/commit/d74062fe1256dbdba4863e9041f0397df908ade1)) -* Edge labels ([#743](https://github.com/equinor/flyt/issues/743)) ([cae915c](https://github.com/equinor/flyt/commit/cae915ce4a9a7e69c1b894854d3997eb58c9c3ed)) - +- Click to rename project title ([#489](https://github.com/equinor/flyt/issues/489)) ([d74062f](https://github.com/equinor/flyt/commit/d74062fe1256dbdba4863e9041f0397df908ade1)) +- Edge labels ([#743](https://github.com/equinor/flyt/issues/743)) ([cae915c](https://github.com/equinor/flyt/commit/cae915ce4a9a7e69c1b894854d3997eb58c9c3ed)) ### Bug Fixes -* close scrim, fix ts errors ([#764](https://github.com/equinor/flyt/issues/764)) ([00ed2b6](https://github.com/equinor/flyt/commit/00ed2b62f2ca723335df7bf29a7c4180b228b55c)) -* edges no longer disappearing when creating hidden nodes ([#761](https://github.com/equinor/flyt/issues/761)) ([0f8ec0e](https://github.com/equinor/flyt/commit/0f8ec0ebad2f558b89c36f31a65750916d0562c4)) -* Remove duration bug ([#753](https://github.com/equinor/flyt/issues/753)) ([4edc93d](https://github.com/equinor/flyt/commit/4edc93db75872adbca7d98089487c35ac308f615)) +- close scrim, fix ts errors ([#764](https://github.com/equinor/flyt/issues/764)) ([00ed2b6](https://github.com/equinor/flyt/commit/00ed2b62f2ca723335df7bf29a7c4180b228b55c)) +- edges no longer disappearing when creating hidden nodes ([#761](https://github.com/equinor/flyt/issues/761)) ([0f8ec0e](https://github.com/equinor/flyt/commit/0f8ec0ebad2f558b89c36f31a65750916d0562c4)) +- Remove duration bug ([#753](https://github.com/equinor/flyt/issues/753)) ([4edc93d](https://github.com/equinor/flyt/commit/4edc93db75872adbca7d98089487c35ac308f615)) ## [2.2.0](https://github.com/equinor/flyt/compare/v2.1.0...v2.2.0) (2024-06-03) diff --git a/components/DeleteNodeDialog.tsx b/components/DeleteNodeDialog.tsx index 3c0f2c79..3f9ef951 100644 --- a/components/DeleteNodeDialog.tsx +++ b/components/DeleteNodeDialog.tsx @@ -1,16 +1,14 @@ -import { Button, Icon, Scrim, Typography } from "@equinor/eds-core-react"; -import { close as closeIcon, delete_forever } from "@equinor/eds-icons"; import { useAccount, useMsal } from "@azure/msal-react"; import { useMutation, useQueryClient } from "react-query"; import { getNodeTypeName } from "@/utils/getNodeTypeName"; import { notifyOthers } from "@/services/notifyOthers"; -import styles from "../layouts/default.layout.module.scss"; import { unknownErrorToString } from "@/utils/isError"; import { useStoreDispatch } from "hooks/storeHooks"; import { NodeDataApi } from "@/types/NodeDataApi"; import { NodeTypes } from "@/types/NodeTypes"; import { deleteVertice } from "services/graphApi"; import { useProjectId } from "@/hooks/useProjectId"; +import { ScrimDelete } from "./ScrimDelete"; export function DeleteNodeDialog(props: { objectToDelete: NodeDataApi; @@ -59,8 +57,8 @@ export function DeleteNodeDialog(props: { const { type } = props.objectToDelete; - const header = `Delete "${getNodeTypeName(type).toLowerCase()}"`; - let warningMessage = "This will delete the selected object."; + const header = `Delete ${getNodeTypeName(type).toLowerCase()}`; + let warningMessage = "This will delete the selected card."; if (type === mainActivity) { warningMessage = "This will delete everything under it.\nAre you sure you want to proceed?"; @@ -70,39 +68,16 @@ export function DeleteNodeDialog(props: { } const confirmMessage = "Delete"; return ( - -
- {deleteMutation.isLoading ? ( - Deleting... - ) : ( - <> -
-
{header}
- -
-
- {deleteMutation.error && ( - - {unknownErrorToString(deleteMutation.error)} - - )} - {warningMessage} -
-
- -
- - )} -
-
+ ); } diff --git a/components/ScrimDelete.module.scss b/components/ScrimDelete.module.scss new file mode 100644 index 00000000..18b920c8 --- /dev/null +++ b/components/ScrimDelete.module.scss @@ -0,0 +1,40 @@ +@import "../styles/variables"; + +.scrimHeaderWrapper { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: solid 1px #dcdcdc; +} + +.scrimTitle { + padding: 12px 18px; +} + +.scrimWrapper { + display: flex; + flex-direction: column; + justify-content: space-between; + max-width: 80vw; + max-height: 80vh; + background-color: white; + border-radius: 2px; +} + +.scrimContent { + padding: 18px; +} + +.buttonsGroup { + display: flex; + justify-content: space-between; + padding: 18px; +} + +.loaderContainer { + display: flex; + align-items: center; + flex-direction: column; + gap: 15px; + padding: 50px; +} diff --git a/components/ScrimDelete.tsx b/components/ScrimDelete.tsx new file mode 100644 index 00000000..06c6c44b --- /dev/null +++ b/components/ScrimDelete.tsx @@ -0,0 +1,74 @@ +import { Button, Icon, Scrim, Typography } from "@equinor/eds-core-react"; +import styles from "./ScrimDelete.module.scss"; +import { close as closeIcon, delete_forever } from "@equinor/eds-icons"; +import { unknownErrorToString } from "@/utils/isError"; +import { CircularProgress } from "@equinor/eds-core-react"; + +type ScrimDelete = { + id: string; + open: boolean; + onConfirm: (id: string) => void; + onClose: () => void; + header?: string; + warningMessage?: string; + confirmMessage?: string; + error?: unknown; + isLoading?: boolean; +}; + +export const ScrimDelete = ({ + id, + open, + onConfirm, + onClose, + header, + warningMessage, + confirmMessage, + error, + isLoading, +}: ScrimDelete) => { + return ( + +
+ {isLoading ? ( +
+ + Deleting... +
+ ) : ( + <> +
+
+ {header} +
+ +
+
+ {!!error && ( + + {unknownErrorToString(error)} + + )} + {warningMessage} +
+
+ + +
+ + )} +
+
+ ); +}; diff --git a/components/canvas/Canvas.tsx b/components/canvas/Canvas.tsx index e912465e..5d3a4336 100644 --- a/components/canvas/Canvas.tsx +++ b/components/canvas/Canvas.tsx @@ -33,11 +33,13 @@ import { useNodeMerge } from "./hooks/useNodeMerge"; import { useWebSocket } from "./hooks/useWebSocket"; import { getQIPRContainerWidth } from "./utils/getQIPRContainerWidth"; import { useProjectId } from "@/hooks/useProjectId"; +import { useEdgeDelete } from "./hooks/useEdgeDelete"; +import { ScrimDelete } from "../ScrimDelete"; import { MiniMapCustom } from "@/components/canvas/MiniMapCustom"; -import { EdgeDataApi } from "@/types/EdgeDataApi"; import { ZoomLevel } from "@/components/canvas/ZoomLevel"; import { edgeElementTypes } from "@/components/canvas/EdgeElementTypes"; import { createHiddenNodes } from "@/components/canvas/utils/createHiddenNodes"; +import { createEdges } from "./utils/createEdges"; type CanvasProps = { graph: Graph; @@ -60,29 +62,23 @@ const Canvas = ({ new Date("2024-04-24T00:08:00.000000Z").getTime(); let tempNodes: Node[] = []; - let tempEdges: Edge[] = []; - apiEdges.map((edge: EdgeDataApi) => { - const nodeSource = apiNodes.filter((node) => node.id === edge.source); - if (nodeSource[0] && nodeSource[0].type === NodeTypes.choice) { - tempEdges.push({ - ...edge, - type: "choice", - label: edge.edgeValue, - }); - } else { - tempEdges.push({ ...edge }); - } - }); + const tempEdges: Edge[] = apiEdges.map((e) => ({ ...e, label: e.edgeValue })); + const [isEditingEdgeText, setIsEditingEdgeText] = useState(false); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); - const [visibleDeleteScrim, setVisibleDeleteScrim] = useState(false); + const [visibleDeleteNodeScrim, setVisibleDeleteNodeScrim] = useState(false); + const [edgeToBeDeletedId, setEdgeToBeDeletedId] = useState< + string | undefined + >(undefined); const [visibleLabelScrim, setVisibleLabelScrim] = useState(false); + const isEditingEdge = isEditingEdgeText || edgeToBeDeletedId; const { onNodeDragStart, onNodeDrag, onNodeDragStop } = useNodeDrag(); const { mutate: mergeNode, merging } = useNodeMerge(); const { mutate: addNode } = useNodeAdd(); + const { deleteEdgeMutation } = useEdgeDelete(); const { socketConnected, socketReason } = useWebSocket(); @@ -145,6 +141,7 @@ const Canvas = ({ type: node.type, height: shapeSize.height, width: shapeSize.width + getQIPRContainerWidth(node.tasks), + deletable: false, }); } else { tempNodes.push({ @@ -153,11 +150,14 @@ const Canvas = ({ ...node, parents: [], columnId: node.id, + shapeHeight: shapeSize.height, + shapeWidth: shapeSize.width, }, position: { x: 0, y: 0 }, type: node.type, height: shapeSize.height, width: shapeSize.width + getQIPRContainerWidth(node.tasks), + deletable: false, }); } @@ -167,6 +167,16 @@ const Canvas = ({ }); }; + const handleSetSelectedEdge = (selectedEdge: Edge | undefined) => { + if (userCanEdit && !isEditingEdge) { + const updatedEdges = edges.map((e) => { + e.selected = e.id === selectedEdge?.id; + return e; + }); + setEdges(updatedEdges); + } + }; + const mergedNodesLooping = new Map, number]>(); let mergedNodesReady: Node[] = []; @@ -237,11 +247,23 @@ const Canvas = ({ } createNodes(root); setNodesDepth(); - const { tempNodes: tempWithHiddenNodes, tempEdges: tempWithHiddenEdges } = - createHiddenNodes(tempNodes, tempEdges, shapeSize); + const { + tempNodes: tempWithHiddenNodes, + tempEdges: tempWithHiddenEdges, + longEdges, + } = createHiddenNodes(tempNodes, tempEdges, shapeSize); const finalNodes = setLayout(tempWithHiddenNodes, tempWithHiddenEdges); + const finalEdges = createEdges( + finalNodes, + tempWithHiddenEdges, + longEdges, + shapeSize, + userCanEdit, + setIsEditingEdgeText, + setEdgeToBeDeletedId + ); setNodes(finalNodes); - setEdges(tempWithHiddenEdges); + setEdges(finalEdges); }, [apiNodes, apiEdges, userCanEdit]); useCenterCanvas(); @@ -272,16 +294,38 @@ const Canvas = ({ {selectedNode && ( { - setVisibleDeleteScrim(false); + setVisibleDeleteNodeScrim(false); setSelectedNode(undefined); }} /> )} + {edgeToBeDeletedId && ( + { + deleteEdgeMutation.mutate( + { edgeId: id }, + { + onSuccess() { + setEdgeToBeDeletedId(undefined); + }, + } + ); + }} + onClose={() => setEdgeToBeDeletedId(undefined)} + header={"Delete line"} + warningMessage={"Are you sure you want to delete this line?"} + confirmMessage={"Delete"} + isLoading={deleteEdgeMutation.isLoading} + error={deleteEdgeMutation.error} + /> + )} setSelectedNode(undefined)} - onDelete={() => setVisibleDeleteScrim(true)} + onDelete={() => setVisibleDeleteNodeScrim(true)} canEdit={userCanEdit} selectedNode={selectedNode} /> @@ -300,6 +344,10 @@ const Canvas = ({ onNodeDragStart={onNodeDragStart} onNodeDrag={onNodeDrag} onNodeDragStop={onNodeDragStop} + elevateEdgesOnSelect={true} + edgesFocusable={userCanEdit} + onEdgeMouseEnter={(event, edge) => handleSetSelectedEdge(edge)} + onEdgeMouseLeave={() => handleSetSelectedEdge(undefined)} attributionPosition="bottom-right" connectionRadius={100} > diff --git a/components/canvas/CanvasTutorial/CanvasTutorial.tsx b/components/canvas/CanvasTutorial/CanvasTutorial.tsx index 1fad93f0..70e17b6e 100644 --- a/components/canvas/CanvasTutorial/CanvasTutorial.tsx +++ b/components/canvas/CanvasTutorial/CanvasTutorial.tsx @@ -5,6 +5,8 @@ import addNewSubActivity from "../../../public/CanvasTutorial/add-new-sub-activi import addNewChoice from "../../../public/CanvasTutorial/add-new-choice.gif"; import addNewWait from "../../../public/CanvasTutorial/add-new-wait.gif"; import mergeActivities from "../../../public/CanvasTutorial/merge-activities.gif"; +import renameEdge from "../../../public/CanvasTutorial/rename-edge.gif"; +import deleteEdge from "../../../public/CanvasTutorial/delete-edge.gif"; import mainActivity from "../../../public/CanvasTutorial/main-activity.svg"; import subActivity from "../../../public/CanvasTutorial/sub-activity.svg"; import choice from "../../../public/CanvasTutorial/choice.svg"; @@ -94,12 +96,31 @@ export const CanvasTutorial = () => { containerRef={refs["merge-activities"]} title="Merge activities" image={mergeActivities} - style={{ marginBottom: "32px" }} > Hover over the merge circle of a card at the end of a choice path.{" "} Drag and drop it onto the card you wish to merge into. + + Hover over a editable line. Look for the pencil icon to appear. + Click the edit button to start writing. Once you have finished, + click outside the text area to save your changes. Editable lines + can be found directly beneath a choice card. + + + Hover over a removable line. Click the remove button to remove the + line. Removeable lines are only found above a subactivity that has + multiple parent connections. + diff --git a/components/canvas/CanvasTutorial/CanvasTutorialButtonGroup.tsx b/components/canvas/CanvasTutorial/CanvasTutorialButtonGroup.tsx index ac4a2a9e..91fad6c1 100644 --- a/components/canvas/CanvasTutorial/CanvasTutorialButtonGroup.tsx +++ b/components/canvas/CanvasTutorial/CanvasTutorialButtonGroup.tsx @@ -11,6 +11,8 @@ const buttons: Omit[] = [ { section: "add-new-wait", title: "Wait" }, { section: "add-new-choice", title: "Choice" }, { section: "merge-activities", title: "Merge" }, + { section: "rename-edge", title: "Write on lines" }, + { section: "delete-edge", title: "Remove lines" }, ]; type CanvasTutorialButtonGroupProps = { diff --git a/components/canvas/CanvasTutorial/hooks/useCanvasTutorial.tsx b/components/canvas/CanvasTutorial/hooks/useCanvasTutorial.tsx index 0a8b626b..f959952b 100644 --- a/components/canvas/CanvasTutorial/hooks/useCanvasTutorial.tsx +++ b/components/canvas/CanvasTutorial/hooks/useCanvasTutorial.tsx @@ -8,6 +8,8 @@ const sectionQueryValues = [ "add-new-wait", "add-new-choice", "merge-activities", + "rename-edge", + "delete-edge", ] as const; export type SectionQueryValue = (typeof sectionQueryValues)[number]; @@ -51,6 +53,8 @@ const useSectionRefs = () => { const addNewWaitRef = useRef(null); const addNewChoiceRef = useRef(null); const mergeActivitiesRef = useRef(null); + const renameEdgeRef = useRef(null); + const deleteEdgeRef = useRef(null); const refs: { [key in SectionQueryValue]: RefObject } = { "add-new-main-activity": addNewMainActivityRef, @@ -58,6 +62,8 @@ const useSectionRefs = () => { "add-new-wait": addNewWaitRef, "add-new-choice": addNewChoiceRef, "merge-activities": mergeActivitiesRef, + "rename-edge": renameEdgeRef, + "delete-edge": deleteEdgeRef, }; return refs; diff --git a/components/canvas/ChoiceEdge.module.scss b/components/canvas/ChoiceEdge.module.scss deleted file mode 100644 index dd35af13..00000000 --- a/components/canvas/ChoiceEdge.module.scss +++ /dev/null @@ -1,28 +0,0 @@ -@import "styles/_variables.scss"; - -.choice-edge { - path { - color: #fff; - } -} - -.editButton { - box-shadow: 0 0 8px rgba(0, 0, 0, 0.14); - background: $white !important; -} - -.editButton:hover { - background: $equinor_HOVER-ALT !important; -} - -.textarea { - background: $canvas; - outline: none; - border: none; - border-radius: 4px; - height: auto; - width: 90px; - text-align: center; - resize: none; - cursor: pointer; -} diff --git a/components/canvas/ChoiceEdge.tsx b/components/canvas/ChoiceEdge.tsx deleted file mode 100644 index 68c39d1f..00000000 --- a/components/canvas/ChoiceEdge.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { - BaseEdge, - EdgeLabelRenderer, - EdgeProps, - getBezierPath, -} from "reactflow"; -import { EdgeLabel } from "@/components/canvas/ChoiceEdgeLabel"; - -export function ChoiceEdge({ - id, - sourceX, - sourceY, - targetX, - targetY, - sourcePosition, - targetPosition, - markerEnd, - label, - selected, -}: EdgeProps) { - const [edgePath, labelX, labelY] = getBezierPath({ - sourceX, - sourceY, - sourcePosition, - targetX, - targetY, - targetPosition, - }); - - return ( - <> - - -
- -
-
- - ); -} diff --git a/components/canvas/ChoiceNode.tsx b/components/canvas/ChoiceNode.tsx index 65d472ca..20208bd4 100644 --- a/components/canvas/ChoiceNode.tsx +++ b/components/canvas/ChoiceNode.tsx @@ -48,7 +48,7 @@ export const ChoiceNode = ({ }, [dragging, connectionNodeId]); const renderNodeButtons = () => { - if (userCanEdit && hovering && !merging) { + if (userCanEdit && hovering && !merging && handleClickAddNode) { return ( <> @@ -79,7 +79,7 @@ export const ChoiceNode = ({ ) } /> - {mergeable && ( + {mergeable && handleMerge && ( handleMerge(e.source, e.target)} /> diff --git a/components/canvas/CustomEdge.tsx b/components/canvas/CustomEdge.tsx new file mode 100644 index 00000000..74e4fd9e --- /dev/null +++ b/components/canvas/CustomEdge.tsx @@ -0,0 +1,78 @@ +import { Button, Icon } from "@equinor/eds-core-react"; +import { close_circle_outlined } from "@equinor/eds-icons"; +import { BaseEdge, EdgeLabelRenderer, EdgeProps } from "reactflow"; +import styles from "./Edge.module.scss"; +import { getSvgStraightLineData } from "./drawSvgPath"; +import { EdgeLabel } from "./EdgeLabel"; +import colors from "@/theme/colors"; +import { useEffect, useState } from "react"; + +export const CustomEdge = ({ + id, + sourceX, + sourceY, + targetX, + targetY, + label, + selected, + interactionWidth, + data, +}: EdgeProps) => { + const points = [ + { x: sourceX, y: sourceY }, + { x: targetX, y: targetY }, + ]; + + data?.points && points.splice(1, 0, ...data.points); + + const [edgePath, labelX, labelY] = getSvgStraightLineData(points); + const [isEditingText, setIsEditingText] = useState(false); + + useEffect(() => { + data?.setIsEditingText(isEditingText); + }, [isEditingText]); + + return ( + <> + + +
+ + {selected && + data?.userCanEdit && + data?.onDelete && + !isEditingText && ( + + )} +
+
+ + ); +}; diff --git a/components/canvas/Edge.module.scss b/components/canvas/Edge.module.scss new file mode 100644 index 00000000..425d4773 --- /dev/null +++ b/components/canvas/Edge.module.scss @@ -0,0 +1,8 @@ +@import "styles/_variables.scss"; + +.edge-button-container { + position: absolute; + pointer-events: all; + border-radius: 50%; + background-color: $canvas; +} diff --git a/components/canvas/EdgeElementTypes.tsx b/components/canvas/EdgeElementTypes.tsx index f7e91f75..768d96a9 100644 --- a/components/canvas/EdgeElementTypes.tsx +++ b/components/canvas/EdgeElementTypes.tsx @@ -1,6 +1,6 @@ import { EdgeTypes } from "reactflow"; -import { ChoiceEdge } from "@/components/canvas/ChoiceEdge"; +import { CustomEdge } from "./CustomEdge"; export const edgeElementTypes: EdgeTypes = { - choice: ChoiceEdge, + custom: CustomEdge, }; diff --git a/components/canvas/EdgeLabel.module.scss b/components/canvas/EdgeLabel.module.scss new file mode 100644 index 00000000..b70df555 --- /dev/null +++ b/components/canvas/EdgeLabel.module.scss @@ -0,0 +1,12 @@ +@import "styles/_variables.scss"; + +.textarea { + background: $canvas; + outline: none; + border: none; + border-radius: 4px; + height: auto; + width: 90px; + text-align: center; + resize: none; +} diff --git a/components/canvas/ChoiceEdgeLabel.tsx b/components/canvas/EdgeLabel.tsx similarity index 50% rename from components/canvas/ChoiceEdgeLabel.tsx rename to components/canvas/EdgeLabel.tsx index 2b22bba3..007de58f 100644 --- a/components/canvas/ChoiceEdgeLabel.tsx +++ b/components/canvas/EdgeLabel.tsx @@ -2,7 +2,7 @@ import { useReactFlow } from "reactflow"; import { useEffect, useRef, useState } from "react"; import { Button, Icon } from "@equinor/eds-core-react"; import { edit } from "@equinor/eds-icons"; -import styles from "./ChoiceEdge.module.scss"; +import styles from "./EdgeLabel.module.scss"; import { patchEdge } from "@/services/graphApi"; import { useProjectId } from "@/hooks/useProjectId"; @@ -10,12 +10,20 @@ type EdgeLabelProps = { id: string; labelText?: string; selected: boolean; + readOnly: boolean; + setIsEditingText: (e: boolean) => void; }; -export function EdgeLabel({ id, labelText, selected }: EdgeLabelProps) { +export const EdgeLabel = ({ + id, + labelText, + selected, + readOnly, + setIsEditingText, +}: EdgeLabelProps) => { const { setEdges } = useReactFlow(); const { projectId } = useProjectId(); const [value, setValue] = useState(labelText); - const [showInput, setShowInput] = useState(!!value); + const [showInput, setShowInput] = useState(false); const inputRef = useRef(null); const numberOfRows = Math.ceil(Math.max(value?.length ?? 0, 1) / 12); @@ -31,7 +39,10 @@ export function EdgeLabel({ id, labelText, selected }: EdgeLabelProps) { useEffect(() => { const input = inputRef.current; if (!input) { - if (!value || value.length === 0) setShowInput(false); + if (!value || value.length === 0) { + setShowInput(false); + setIsEditingText(false); + } return; } @@ -44,41 +55,41 @@ export function EdgeLabel({ id, labelText, selected }: EdgeLabelProps) { }, [selected, value]); const ButtonComponent = ( - <> - - + ); const TextAreaComponent = ( - <> -