From 6cf4cb723e88254a63fd942279fab4558a1bf753 Mon Sep 17 00:00:00 2001 From: kslazykv Date: Wed, 12 Feb 2025 10:03:41 +0100 Subject: [PATCH 1/3] added styles --- src/components/TreeView/TreeView.tsx | 34 +++- src/components/TreeView/style.ts | 3 + .../PlantConfig/views/Library/Library.tsx | 83 ++++---- .../LibraryTreeview/LibraryTreeview.style.ts | 1 + .../LibraryTreeview/LibraryTreeview.tsx | 38 +++- .../PreservationJourney.tsx | 188 ++++++++++-------- 6 files changed, 224 insertions(+), 123 deletions(-) diff --git a/src/components/TreeView/TreeView.tsx b/src/components/TreeView/TreeView.tsx index aceb49228..668bfcbe3 100644 --- a/src/components/TreeView/TreeView.tsx +++ b/src/components/TreeView/TreeView.tsx @@ -8,7 +8,8 @@ import { } from './style'; import Spinner from '../Spinner'; import { KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material'; -import { Link, useLocation } from 'react-router-dom'; +import { Link, useLocation, useNavigate } from 'react-router-dom'; +import { useLibraryContext } from '@procosys/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview'; /** * @param id Unique identifier across all nodes in the tree (number or string). @@ -56,6 +57,29 @@ const TreeView = ({ const [isNodeExpanded, setIsNodeExpanded] = useState(false); const [executionCount, setExecutionCount] = useState(0); const { pathname } = useLocation(); + const navigate = useNavigate(); + + const { newJourney } = useLibraryContext(); + + // useEffect(() => { + // const getBasePath = (pathname: string): string => { + // const segments = pathname.split('/').filter(Boolean); + // if (segments.length < 2) return ''; + // return `/${segments[0]}/${segments[1]}`; + // }; + + // const baseLibraryPath = getBasePath(pathname); + + // if (newJourney?.project?.description && newJourney?.title) { + // const updatedPath = `${baseLibraryPath}/Preservation%20journeys/${encodeURIComponent( + // newJourney.project.description + // )}/${encodeURIComponent(newJourney.title)}`; + + // if (pathname !== updatedPath) { + // navigate(updatedPath, { replace: true }); + // } + // } + // }, [newJourney, pathname, navigate]); const getNodeChildCountAndCollapse = ( parentNodeId: string | number @@ -307,6 +331,7 @@ const TreeView = ({ handleOnClick(node); }} isSelected={node.isSelected ? true : false} + title={node.name} > {node.name} @@ -319,7 +344,12 @@ const TreeView = ({ return ( {linkContent} diff --git a/src/components/TreeView/style.ts b/src/components/TreeView/style.ts index ad2b493f0..a80bfee7c 100644 --- a/src/components/TreeView/style.ts +++ b/src/components/TreeView/style.ts @@ -4,6 +4,7 @@ import { tokens } from '@equinor/eds-tokens'; export const TreeContainer = styled.div` display: flex; flex-direction: column; + max-width: 100%; `; interface NodeContainerProps { @@ -17,6 +18,8 @@ export const NodeContainer = styled.div` margin-left: ${(props): string => `calc(var(--grid-unit) * ${props.indentMultiplier} - 4px)`}; + margin-left: ${(props): string => + `calc(var(--grid-unit) * ${props.indentMultiplier} - 4px)`}; `; interface ExpandCollapseIconProps { diff --git a/src/modules/PlantConfig/views/Library/Library.tsx b/src/modules/PlantConfig/views/Library/Library.tsx index 6e3952b5a..d495ef5ea 100644 --- a/src/modules/PlantConfig/views/Library/Library.tsx +++ b/src/modules/PlantConfig/views/Library/Library.tsx @@ -4,7 +4,9 @@ import React, { useEffect, useReducer, useState } from 'react'; import { Helmet } from 'react-helmet'; //import withAccessControl from '../../../../core/security/withAccessControl'; import LibraryItemDetails from './LibraryItemDetails'; -import LibraryTreeview from './LibraryTreeview/LibraryTreeview'; +import LibraryTreeview, { + LibraryProvider, +} from './LibraryTreeview/LibraryTreeview'; import { hot } from 'react-hot-loader'; import { Route, Routes } from 'react-router-dom'; @@ -111,43 +113,50 @@ const Library = (): JSX.Element => { }; return ( - - {selectedLibraryType && ( - - {` - ${selectedLibraryType}`} - - )} - setDirtyLibraryType('')} - /> - - - - - - - } + + + {selectedLibraryType && ( + + {` - ${selectedLibraryType}`} + + )} + setDirtyLibraryType('')} /> - - + + + + + + + } + /> + + + ); }; diff --git a/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.style.ts b/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.style.ts index b9467b8b3..2ef506aed 100644 --- a/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.style.ts +++ b/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.style.ts @@ -7,4 +7,5 @@ export const Container = styled.div` padding-top: var(--margin-module--top); padding-right: calc(var(--grid-unit) * 5); padding-left: calc(var(--grid-unit) * 5); + width: 20vw; `; diff --git a/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.tsx b/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.tsx index 4decc7838..d71e4aebe 100644 --- a/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.tsx +++ b/src/modules/PlantConfig/views/Library/LibraryTreeview/LibraryTreeview.tsx @@ -4,7 +4,7 @@ import TreeView, { import { Container } from './LibraryTreeview.style'; import { LibraryType } from '../Library'; -import React from 'react'; +import React, { createContext, useContext, useState } from 'react'; import { showSnackbarNotification } from '../../../../../core/services/NotificationService'; import { usePlantConfigContext } from '../../../context/PlantConfigContext'; import { @@ -282,3 +282,39 @@ const LibraryTreeview = (props: LibraryTreeviewProps): JSX.Element => { }; export default LibraryTreeview; + +interface LibraryContextType { + newJourney: Journey; + setNewJourney: (journey: Journey) => void; +} + +const LibraryContext = createContext(undefined); + +export const LibraryProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const [newJourney, setNewJourney] = useState({ + id: -1, + title: '', + isVoided: false, + isInUse: false, + steps: [], + rowVersion: '', + }); + + return ( + + {children} + + ); +}; + +export const useLibraryContext = (): LibraryContextType => { + const context = useContext(LibraryContext); + if (!context) { + throw new Error( + 'useLibraryContext must be used within a LibraryProvider' + ); + } + return context; +}; diff --git a/src/modules/PlantConfig/views/Library/PreservationJourney/PreservationJourney.tsx b/src/modules/PlantConfig/views/Library/PreservationJourney/PreservationJourney.tsx index 6e45eb5d9..c31427c77 100644 --- a/src/modules/PlantConfig/views/Library/PreservationJourney/PreservationJourney.tsx +++ b/src/modules/PlantConfig/views/Library/PreservationJourney/PreservationJourney.tsx @@ -30,6 +30,16 @@ import { ButtonContainerLeft, ButtonContainerRight, } from '../Library.style'; +import { + AutoTransferMethod, + Journey, + Mode, + PreservationJourneyProps, + Step, +} from './types'; +import { ProjectDetails } from '@procosys/modules/Preservation/types'; +import { Autocomplete } from '@equinor/eds-core-react'; +import { useLibraryContext } from '../LibraryTreeview/LibraryTreeview'; const addIcon = ; const upIcon = ; @@ -48,50 +58,7 @@ const WAIT_INTERVAL = 300; const checkboxHeightInGridUnits = 4; -enum AutoTransferMethod { - NONE = 'None', - RFCC = 'OnRfccSign', - RFOC = 'OnRfocSign', -} - -interface Journey { - id: number; - title: string; - isVoided: boolean; - isInUse: boolean; - steps: Step[]; - rowVersion: string; -} - -interface Step { - id: number; - title: string; - autoTransferMethod: string; - isVoided: boolean; - isInUse: boolean; - mode: Mode; - responsible: { - code: string; - title: string; - rowVersion: string; - description?: string; - }; - rowVersion: string; -} - -interface Mode { - id: number; - title: string; - forSupplier: boolean; - isVoided: boolean; - rowVersion: string; -} - -type PreservationJourneyProps = { - forceUpdate: number; - journeyId: number; - setDirtyLibraryType: () => void; -}; +const sharedJourneyBreadcrumb = 'All projects'; const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { const getInitialJourney = (): Journey => { @@ -108,7 +75,13 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { const [isEditMode, setIsEditMode] = useState(false); const [isLoading, setIsLoading] = useState(false); const [journey, setJourney] = useState(null); - const [newJourney, setNewJourney] = useState(getInitialJourney); + const [selectedProject, setSelectedProject] = useState< + ProjectDetails | undefined + >(); + const [breadcrumbs, setBreadcrumbs] = useState( + `${baseBreadcrumb} / ${sharedJourneyBreadcrumb}` + ); + const { newJourney, setNewJourney } = useLibraryContext(); const [mappedModes, setMappedModes] = useState([]); const [modes, setModes] = useState([]); const [mappedResponsibles, setMappedResponsibles] = useState( @@ -130,22 +103,31 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { return JSON.stringify(journey) != JSON.stringify(newJourney); }, [journey, newJourney]); - const { preservationApiClient, libraryApiClient } = usePlantConfigContext(); + const { preservationApiClient, libraryApiClient, projects } = + usePlantConfigContext(); const cloneJourney = (journey: Journey): Journey => { return JSON.parse(JSON.stringify(journey)); }; + useEffect(() => { + setBreadcrumbs( + `${baseBreadcrumb} / ${ + selectedProject?.description ?? sharedJourneyBreadcrumb + }` + ); + }, [selectedProject]); + /** * Get Modes */ useEffect(() => { - let requestCancellor: Canceler | null = null; + let requestCanceler: Canceler | null = null; (async (): Promise => { try { const modes = await preservationApiClient.getModes( false, - (cancel: Canceler) => (requestCancellor = cancel) + (cancel: Canceler) => (requestCanceler = cancel) ); const mappedModes: SelectItem[] = []; modes.forEach((mode) => @@ -183,7 +165,7 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { })(); return (): void => { - requestCancellor && requestCancellor(); + requestCanceler && requestCanceler(); }; }, [journey]); @@ -231,21 +213,17 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { const getJourney = async (journeyId: number): Promise => { setIsLoading(true); try { - await preservationApiClient - .getJourney(journeyId, true) - .then((response) => { - setJourney(response); - setNewJourney(cloneJourney(response)); - }); + const response = await preservationApiClient.getJourney( + journeyId, + true + ); + setNewJourney(response); } catch (error) { console.error( 'Get preservation journey failed: ', error.message, error.data ); - if (error instanceof ProCoSysApiError) { - if (error.isCancel) return; - } showSnackbarNotification(error.message); } setIsLoading(false); @@ -261,6 +239,14 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { } }, [props.journeyId]); + useEffect(() => { + if (journey || newJourney) { + setSelectedProject(newJourney.project ?? journey?.project); + } else { + setSelectedProject(undefined); + } + }, [journey?.project?.id, newJourney.project?.id]); + const saveNewStep = async ( journeyId: number, step: Step @@ -312,7 +298,8 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { await preservationApiClient.updateJourney( newJourney.id, newJourney.title, - newJourney.rowVersion + newJourney.rowVersion, + newJourney.project?.name ); props.setDirtyLibraryType(); return true; @@ -356,7 +343,10 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { setIsLoading(true); let saveOk = true; let noChangesToSave = true; - if (journey && journey.title != newJourney.title) { + if ( + journey?.title != newJourney.title || + journey?.project?.id != newJourney.project?.id + ) { saveOk = await updateJourney(); noChangesToSave = false; } @@ -445,7 +435,7 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { }; const confirmDiscardingChangesIfExist = (): boolean => { - return !isDirty || confirm(unsavedChangesConfirmationMessage); + return !isDirty ?? confirm(unsavedChangesConfirmationMessage); }; const cancel = (): void => { @@ -564,6 +554,11 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { setNewJourney(cloneJourney(newJourney)); }; + const setProjectIdValue = (value: ProjectDetails): void => { + newJourney.project = value; + setNewJourney(cloneJourney(newJourney)); + }; + const setResponsibleValue = ( event: React.MouseEvent, stepIndex: number, @@ -798,7 +793,7 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { if (isLoading) { return ( - {baseBreadcrumb} / + {breadcrumbs} / ); @@ -807,7 +802,7 @@ const PreservationJourney = (props: PreservationJourneyProps): JSX.Element => { if (!isEditMode) { return ( - {baseBreadcrumb} + {breadcrumbs}