From 2631e278b4687e50e4eb55a025b13600f4034079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98rjan=20Aare=20J=C3=B8rgensen?= Date: Thu, 3 Oct 2024 08:44:33 +0200 Subject: [PATCH] chore: refactor model page styles and micro copy (#324) * chore: refactor model page styles and microcopy * Fix heading levels and nesting * Add custom styles for loading and error state on the model page * Add conditional rendering of metadata tables * Clean up model upload page * Fix alignment on upload page * Backtrack previously deleted validation rules in upload form * Remove unused heading * Remove uploading status from snackbar (replaced by static message) and reset to default duration * chore: Small pr changes. --------- Co-authored-by: mheggelund --- .../AreaCoordinates.styled.tsx | 32 ++--- .../AreaCoordinates/AreaCoordinates.tsx | 4 +- .../hooks/AreaCoordinates.hooks.ts | 24 ++-- .../ErrorBanner/ErrorBanner.styled.tsx | 17 --- src/components/ErrorBanner/ErrorBanner.tsx | 12 -- src/components/ErrorMessage/ErrorMessage.tsx | 39 ++++-- .../GrossDepositionEnviromentGroup.styled.ts | 14 +-- .../GrossDepositionEnviromentGroup.tsx | 94 +++++++------- .../OutcropAnalogueGroup.tsx | 22 ++-- .../StratigrapicGroups.styled.ts | 11 +- .../StratigrapicGroups/StratigrapicGroups.tsx | 119 +++++++++--------- .../SettingSelect.styled.tsx | 3 +- src/features/Footer/Footer.styled.tsx | 1 + .../HandleModelComponent.hooks.ts | 6 +- .../HandleModelComponent.styled.ts | 28 ++++- .../HandleModelComponent.tsx | 55 ++++---- .../ModelMetadata/ModelMetadata.styled.ts | 11 +- .../ModelMetadata/ModelMetadata.tsx | 9 +- .../ModelMetadataComponent.test.tsx | 8 +- .../HandleModel/SidePane/SidePane.styled.ts | 3 - .../ModelView/DeleteButton/DeleteModel.tsx | 4 +- .../EditNameDescription.styled.ts | 3 +- .../EditNameDescription.tsx | 36 +----- .../ModelAreaCoordinates.tsx | 6 +- .../ModelFilesView/ModelFilesView.styled.tsx | 5 +- .../ModelFilesView/ModelFilesView.tsx | 12 +- .../ModelMetadataView.styled.tsx | 23 ++-- .../ModelMetadataView/ModelMetadataView.tsx | 115 +++++++++-------- .../ModelNameFrame/ModelNameFrame.styled.tsx | 10 +- .../ModelNameFrame/ModelNameFrame.tsx | 11 +- src/features/ModelView/ModelView.styled.tsx | 18 +-- src/features/ModelView/ModelView.tsx | 17 +-- src/pages/AddModel/AddModel.styled.tsx | 23 ++-- src/pages/AddModel/AddModel.tsx | 52 ++++---- src/pages/ModelPages/Model/Model.styled.tsx | 33 +++-- src/pages/ModelPages/Model/Model.tsx | 40 +++++- src/tokens/theme.ts | 11 ++ 37 files changed, 466 insertions(+), 465 deletions(-) delete mode 100644 src/components/ErrorBanner/ErrorBanner.styled.tsx delete mode 100644 src/components/ErrorBanner/ErrorBanner.tsx diff --git a/src/components/AreaCoordinates/AreaCoordinates.styled.tsx b/src/components/AreaCoordinates/AreaCoordinates.styled.tsx index eb8c1e20..e580d550 100644 --- a/src/components/AreaCoordinates/AreaCoordinates.styled.tsx +++ b/src/components/AreaCoordinates/AreaCoordinates.styled.tsx @@ -5,13 +5,7 @@ import { theme } from '../../tokens/theme'; export const StyledDialog = styled(Dialog)` width: fit-content; - max-width: 90vw; max-height: 90vh; - - @media (min-width: 700px) { - max-height: 90vh; - overflow-x: scroll; - } `; export const ContentSplitter = styled.div` @@ -23,18 +17,13 @@ export const ContentSplitter = styled.div` export const Selects = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.XXX_LARGE}; - - @media (min-width: 750px) { - min-width: 450px; - } + width: 28rem; `; export const CoordinateFields = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.LARGE}; `; @@ -42,13 +31,27 @@ export const Content = styled(Dialog.CustomContent)` display: flex; flex-direction: column; justify-content: start; - row-gap: ${spacings.SMALL}; + + .coordinate-errors { + padding: 0; + margin: 0 0 0 ${spacings.LARGE}; + + p, + li { + color: ${theme.light.danger.text}; + } + + li:has(p:empty) { + display: none; + } + } `; export const CoordinateGroup = styled.div` display: flex; flex-direction: column; + row-gap: 1rem; `; export const CoordinateInputs = styled.div` @@ -60,14 +63,13 @@ export const CoordinateInputs = styled.div` export const Warning = styled(Banner)` div { background-color: ${theme.light.info.warning}; - max-width: 450px; } `; export const Buttons = styled.div` display: flex; flex-direction: row; - column-gap: ${spacings.MEDIUM}; + column-gap: ${spacings.SMALL}; `; export { StyledDialog as Dialog }; diff --git a/src/components/AreaCoordinates/AreaCoordinates.tsx b/src/components/AreaCoordinates/AreaCoordinates.tsx index bc241b29..e1dcad20 100644 --- a/src/components/AreaCoordinates/AreaCoordinates.tsx +++ b/src/components/AreaCoordinates/AreaCoordinates.tsx @@ -313,7 +313,7 @@ export const AreaCoordinates = ({ - Bottom Right Corner + Bottom Right Corner 0 && edit && ( - + IMPORTANT - this model area has one or more results in object or variogram cases. Changing the coordinates will diff --git a/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts b/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts index 0118310a..71039b4a 100644 --- a/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts +++ b/src/components/AreaCoordinates/hooks/AreaCoordinates.hooks.ts @@ -19,29 +19,29 @@ export const validateCoordinates = async ( ) => { const errors: CoordinateErrorType = {}; if (!activeArea || activeArea.modelAreaTypeId === '') { - errors.area = 'Model area needs to be selected'; + errors.area = 'You must select a model area'; } if (area && area.coordinates[0].x === area.coordinates[1].x) { - errors.x0 = 'X coordinates can´t be equal.'; + errors.x0 = "X start/end coordinates can't be equal."; } if (area && area.coordinates[0].y === area.coordinates[1].y) { - errors.y0 = 'Y coordinates can´t be equal.'; + errors.y0 = "Y start/end coordinates can't be equal."; } if (area && NotANumber(area.coordinates[0].x)) { - errors.x0 = 'Coordinates can´t be string, just numbers are allowed.'; + errors.x0 = 'Coordinates must be a number'; } if (area && NotANumber(area.coordinates[0].y)) { - errors.y0 = 'Coordinates can´t be string, just numbers are allowed.'; + errors.y0 = 'Coordinates must be a number'; } if (area && NotANumber(area.coordinates[1].x)) { - errors.x1 = 'Coordinates can´t be string, just numbers are allowed.'; + errors.x1 = 'Coordinates must be a number'; } if (area && NotANumber(area.coordinates[1].y)) { - errors.y1 = 'Coordinates can´t be string, just numbers are allowed.'; + errors.y1 = 'Coordinates must be a number'; } if (area && area.coordinates[1].x === 0) { - errors.x1 = 'Bottom right corner can not be 0.'; + errors.x1 = 'Bottom right corner must be greater than 0'; } if ( @@ -51,7 +51,7 @@ export const validateCoordinates = async ( // @ts-expect-error Autocomplete area.coordinates[0].x === '') ) { - errors.x0 = 'All fields must be filled in'; + errors.x0 = 'You must enter all four coordinates'; } if ( @@ -61,7 +61,7 @@ export const validateCoordinates = async ( // @ts-expect-error Autocomplete area.coordinates[0].y === '') ) { - errors.y0 = 'All fields must be filled in'; + errors.y0 = 'You must enter all four coordinates'; } if ( @@ -71,7 +71,7 @@ export const validateCoordinates = async ( // @ts-expect-error Autocomplete area.coordinates[1].x === '') ) { - errors.x1 = 'All fields must be filled in'; + errors.x1 = 'You must enter all four coordinates'; } if ( @@ -81,7 +81,7 @@ export const validateCoordinates = async ( // @ts-expect-error Autocomplete area.coordinates[1].y === '') ) { - errors.y1 = 'All fields must be filled in'; + errors.y1 = 'You must enter all four coordinates'; } return errors; diff --git a/src/components/ErrorBanner/ErrorBanner.styled.tsx b/src/components/ErrorBanner/ErrorBanner.styled.tsx deleted file mode 100644 index bfaf06e2..00000000 --- a/src/components/ErrorBanner/ErrorBanner.styled.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Banner } from '@equinor/eds-core-react'; -import styled from 'styled-components'; -import { spacings } from '../../tokens/spacings'; - -export const Error = styled(Banner)` - max-width: 650px; - box-shadow: none; - hr { - height: 0px; - } - - div { - background-color: #ffaebf; - border: solid 1px #c7264c; - border-radius: ${spacings.BORDER_ROUNDED}; - } -`; diff --git a/src/components/ErrorBanner/ErrorBanner.tsx b/src/components/ErrorBanner/ErrorBanner.tsx deleted file mode 100644 index 7a19de3e..00000000 --- a/src/components/ErrorBanner/ErrorBanner.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Banner } from '@equinor/eds-core-react'; -import * as Styled from './ErrorBanner.styled'; - -export const ErrorBanner = ({ text }: { text: string | undefined }) => { - return ( - - - {text !== undefined ? text : ''} - - - ); -}; diff --git a/src/components/ErrorMessage/ErrorMessage.tsx b/src/components/ErrorMessage/ErrorMessage.tsx index c87e39c1..61693990 100644 --- a/src/components/ErrorMessage/ErrorMessage.tsx +++ b/src/components/ErrorMessage/ErrorMessage.tsx @@ -1,17 +1,38 @@ +import { Typography } from '@equinor/eds-core-react'; import { CoordinateErrorType } from '../AreaCoordinates/hooks/AreaCoordinates.hooks'; export const ErrorMessage = ({ errors }: { errors: CoordinateErrorType }) => { return ( <> - {errors && ( -
- {' '} -

{errors.area}

-

{errors.x0}

-

{errors.y0}

-

{errors.x1}

-

{errors.y1}

-
+ {/* Only render the
    wrapper if there are one or more errors */} + {Object.values(errors).some((error) => !!error) && ( +
      +
    • + + {errors.area} + +
    • +
    • + + {errors.x0} + +
    • +
    • + + {errors.y0} + +
    • +
    • + + {errors.x1} + +
    • +
    • + + {errors.y1} + +
    • +
    )} ); diff --git a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.styled.ts b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.styled.ts index 484f1c6b..fb97ddd8 100644 --- a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.styled.ts +++ b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.styled.ts @@ -3,16 +3,14 @@ import { spacings } from '../../../tokens/spacings'; export const Wrapper = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.MEDIUM}; -`; -export const ArcElCell = styled.div` - display: flex; - flex-direction: row; - white-space: nowrap; + th, + td { + white-space: nowrap; + } - > p { - padding-right: ${spacings.X_SMALL}; + ul { + padding-inline: ${spacings.MEDIUM} 0; } `; diff --git a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx index 16a8ab24..48447eb7 100644 --- a/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx +++ b/src/components/GrossDepositionEnviroment/GrossDepositionEnviromentGroup/GrossDepositionEnviromentGroup.tsx @@ -106,57 +106,55 @@ export const GrossDepositionEnviromentGroup = ({ return ( <> - Gross Depositional Environment - - - - - Gross Depositional Environment (GDE) - Depositional Environment - Subenvironment - Architectural Element - - - - - {gdeGroups.map((row) => ( - - - - - - - {row.grossDepEnv.identifier} - - - - {row.depEnv.identifier} - - - {row.subenv.identifier} - - - - {row.architecturalElements.map((a) => ( -

    {a.identifier},

    - ))} -
    -
    + + Gross Depositional Environment (GDE) + + {gdeGroups.length > 0 && ( +
    + + + + GDE + Depositional environment + Subenvironment + Architectural element - ))} - -
    + + + + {gdeGroups.map((row) => ( + + + + + {row.grossDepEnv.identifier} + {row.depEnv.identifier} + {row.subenv.identifier} + + {row.architecturalElements.length > 0 && ( +
      + {row.architecturalElements.map((a) => ( +
    • {a.identifier}
    • + ))} +
    + )} +
    +
    + ))} +
    + + )}
    diff --git a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx index 7c73941a..5e37b0f5 100644 --- a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx +++ b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx @@ -78,9 +78,11 @@ export const OutcropAnalogueGroup = ({ }; return ( - <> - - Outcrop Analogue + + + Outcrop Analogue + + {outcropGroup.length > 0 && ( @@ -124,12 +126,12 @@ export const OutcropAnalogueGroup = ({ ))}
    -
    - -
    -
    + )} +
    + +
    Add Outcrop Analogue @@ -146,6 +148,6 @@ export const OutcropAnalogueGroup = ({ - +
    ); }; diff --git a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.styled.ts b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.styled.ts index bf95f702..513a75bc 100644 --- a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.styled.ts +++ b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.styled.ts @@ -4,16 +4,15 @@ import { spacings } from '../../../tokens/spacings'; export const Wrapper = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.MEDIUM}; + + th, + td { + white-space: nowrap; + } `; export const StratColCell = styled.div` display: flex; flex-direction: row; - white-space: nowrap; - - > p { - padding-right: ${spacings.X_SMALL}; - } `; diff --git a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx index 50ec3fbe..986e5772 100644 --- a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx +++ b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx @@ -28,77 +28,82 @@ export const StratigrapicGroups = ({ return ( - Stratigraphic column + + Stratigraphic column + - - - - - Country - Field - Stratigraphic column - Level 1 (group) - Level 2 (formation) - Level 3 (formation/subzone) - - + {stratColumnGroups.length > 0 && ( +
    + + + + Country + Field + Stratigraphic column + Level 1 (group) + Level 2 (formation) + Level 3 (formation/subzone) + + - - {stratColumnGroups.map((row) => ( - - - - - {row.country.identifier} - - - {row.field.identifier} - - - - - {row.stratColumn.identifier} - - - {filterUnitLevel(row, 1).length > 0 ? ( + + {stratColumnGroups.map((row) => ( + - - {filterUnitLevel(row, 1)[0].identifier} - + - ) : ( - --- - )} - {filterUnitLevel(row, 2).length > 0 ? ( + {row.country.identifier} - {filterUnitLevel(row, 2)[0].identifier} + {row.field.identifier} - ) : ( - --- - )} - {filterUnitLevel(row, 3).length > 0 ? ( - {filterUnitLevel(row, 3)[0].identifier} + {row.stratColumn.identifier} - ) : ( - --- - )} - - ))} - -
    + {filterUnitLevel(row, 1).length > 0 ? ( + + + {filterUnitLevel(row, 1)[0].identifier} + + + ) : ( + - + )} + {filterUnitLevel(row, 2).length > 0 ? ( + + + {filterUnitLevel(row, 2)[0].identifier} + + + ) : ( + - + )} + {filterUnitLevel(row, 3).length > 0 ? ( + + + {filterUnitLevel(row, 3)[0].identifier} + + + ) : ( + - + )} + + ))} + + + )} +
    diff --git a/src/features/Compute/CaseGroup/CaseSettingSelects/SettingSelect.styled.tsx b/src/features/Compute/CaseGroup/CaseSettingSelects/SettingSelect.styled.tsx index 809ff1da..879bfada 100644 --- a/src/features/Compute/CaseGroup/CaseSettingSelects/SettingSelect.styled.tsx +++ b/src/features/Compute/CaseGroup/CaseSettingSelects/SettingSelect.styled.tsx @@ -1,5 +1,6 @@ import styled from 'styled-components'; import { spacings } from '../../../../tokens/spacings'; +import { theme } from '../../../../tokens/theme'; export const AutocompleteWrapper = styled.div` display: flex; @@ -12,7 +13,7 @@ export const AutocompleteWrapper = styled.div` export const Required = styled.div` > label { - color: red; + color: ${theme.light.danger.text}; } `; diff --git a/src/features/Footer/Footer.styled.tsx b/src/features/Footer/Footer.styled.tsx index 4ba229ce..6ee471ff 100644 --- a/src/features/Footer/Footer.styled.tsx +++ b/src/features/Footer/Footer.styled.tsx @@ -4,6 +4,7 @@ import { theme } from '../../tokens/theme'; const StyledFooter = styled.footer` height: ${spacings.XXXX_LARGE}; + background-color: ${theme.light.ui.background.default}; display: flex; justify-content: space-between; diff --git a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.hooks.ts b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.hooks.ts index 916eb83e..a0a8db56 100644 --- a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.hooks.ts +++ b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.hooks.ts @@ -30,19 +30,19 @@ export const validateValues = ( const errors: ErrorType = {}; if (inputValues?.name === undefined || inputValues?.name === '') { - errors.name = 'Name not provided'; + errors.name = 'You must name your model'; } if ( inputValues?.description === undefined || inputValues?.description === '' ) { - errors.description = 'Description not provided'; + errors.description = 'You must add a description'; } if (files && !isEdit) { if (!files.NC) { - errors.file = 'NC file missing'; + errors.file = 'You must select an NC file to upload'; } } diff --git a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.styled.ts b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.styled.ts index 059c9286..36842143 100644 --- a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.styled.ts +++ b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.styled.ts @@ -1,5 +1,6 @@ import styled from 'styled-components'; import { spacings } from '../../../tokens/spacings'; +import { theme } from '../../../tokens/theme'; export const Wrapper = styled.div` display: flex; @@ -9,23 +10,40 @@ export const Wrapper = styled.div` `; export const CustomContent = styled.div` + max-width: 40rem; display: flex; flex-direction: column; row-gap: ${spacings.X_LARGE}; `; export const UploadDiv = styled.div` + max-width: 40rem; display: flex; flex-direction: column; - row-gap: ${spacings.LARGE}; + + .warning-message { + margin: 0; + display: flex; + flex-direction: row; + align-items: center; + column-gap: ${spacings.SMALL}; + padding: ${spacings.MEDIUM_SMALL} ${spacings.MEDIUM}; + border-radius: ${spacings.X_SMALL}; + background-color: ${theme.light.warning.highlight}; + color: ${theme.light.text.staticIconsDefault}; + + .icon { + fill: ${theme.light.warning.text}; + } + } `; export const ErrorDiv = styled.div` - display: flex; - flex-direction: column; - - row-gap: ${spacings.SMALL}; + color: ${theme.light.danger.text}; + font-size: 0.75rem; + font-weight: 500; + line-height: 1.333em; `; export const InfoNavigation = styled.div` diff --git a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.tsx b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.tsx index 13fdcc97..c69f5f1f 100644 --- a/src/features/HandleModel/HandleModelComponent/HandleModelComponent.tsx +++ b/src/features/HandleModel/HandleModelComponent/HandleModelComponent.tsx @@ -1,7 +1,13 @@ +/* eslint-disable camelcase */ /* eslint-disable max-lines */ /* eslint-disable max-lines-per-function */ -import { Button, LinearProgress, Typography } from '@equinor/eds-core-react'; -import _ from 'lodash'; +import { + Button, + Icon, + LinearProgress, + Typography, +} from '@equinor/eds-core-react'; +import { error_outlined } from '@equinor/eds-icons'; import { useEffect, useState } from 'react'; import { generatePath, useNavigate } from 'react-router-dom'; import { @@ -11,7 +17,6 @@ import { StratColumnDto, StratUnitDto, } from '../../../api/generated'; -import { ErrorBanner } from '../../../components/ErrorBanner/ErrorBanner'; import { ModelInputFilesTable } from '../ModelInputFilesTable/ModelInputFilesTable'; import { ModelMetadata } from '../ModelMetadata/ModelMetadata'; import { @@ -19,6 +24,7 @@ import { validateValues, } from './HandleModelComponent.hooks'; import * as Styled from './HandleModelComponent.styled'; +Icon.add({ error_outlined }); interface AddModelDialogProps { confirm?: (file: File, metadata: AnalogueModelDetail) => Promise; @@ -81,7 +87,7 @@ export const HandleModelComponent = ({ const [fileSize, setFileSize] = useState(0); const [rawFile, setrawFile] = useState(); - const [errors, setErrors] = useState({}); + const [errors, setErrors] = useState({}); const navigate = useNavigate(); useHandleModelComponent( @@ -130,23 +136,6 @@ export const HandleModelComponent = ({ } const INIFileContent = () =>

    Not implemented yet...

    ; - const getErroMessageList = () => { - if (_.isEmpty(errors)) return; - - const errorList: string[] = []; - - Object.keys(errors).forEach(function (key) { - // TODO: Fix the TS error for errors[key] - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const message = errors[key]; - errorList.push(message); - }); - return errorList; - }; - - const ErrorList = getErroMessageList(); - return ( {progress !== undefined && progress <= 0 && ( @@ -173,15 +162,7 @@ export const HandleModelComponent = ({ metadata={metadata} setMetadata={setMetadata} /> - {!_.isEmpty(errors) && - ErrorList !== undefined && - ErrorList.map((e, i) => { - return ( - - - - ); - })} + {errors.file && errors.file} )} @@ -197,16 +178,22 @@ export const HandleModelComponent = ({ {uploading && ( - +

    + + Remember to keep this browser tab open until the upload has finished +

    + Upload progress: {progress !== undefined && progress.toFixed(0)}% - {} + {}
    )} {progress === 100 && modelId && ( - Model finish uploaded! + + Upload complete +
    diff --git a/src/features/HandleModel/ModelMetadata/ModelMetadata.styled.ts b/src/features/HandleModel/ModelMetadata/ModelMetadata.styled.ts index dc9f5b40..9aa9f8d0 100644 --- a/src/features/HandleModel/ModelMetadata/ModelMetadata.styled.ts +++ b/src/features/HandleModel/ModelMetadata/ModelMetadata.styled.ts @@ -1,10 +1,10 @@ import { TextField } from '@equinor/eds-core-react'; import styled from 'styled-components'; import { spacings } from '../../../tokens/spacings'; +import { theme } from '../../../tokens/theme'; export const ModelMetadata = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.MEDIUM}; min-height: 200px; `; @@ -15,12 +15,11 @@ export const Form = styled.div` row-gap: ${spacings.MEDIUM}; `; -export const TextInput = styled(TextField)` - display: flex; - flex-direction: column; -`; +export const TextInput = styled(TextField)``; + export const InputfieldRequired = styled.div` > label { - color: red; + color: ${theme.light.danger.text}; + margin-block-start: ${spacings.X_SMALL}; } `; diff --git a/src/features/HandleModel/ModelMetadata/ModelMetadata.tsx b/src/features/HandleModel/ModelMetadata/ModelMetadata.tsx index fab64e77..ed111f2d 100644 --- a/src/features/HandleModel/ModelMetadata/ModelMetadata.tsx +++ b/src/features/HandleModel/ModelMetadata/ModelMetadata.tsx @@ -16,25 +16,24 @@ export const ModelMetadata = ({ }) => { return ( - {/* Description and metadata */} ) => setMetadata({ ...metadata, name: e.currentTarget.value }) } /> - {errors.name && } + {errors.name && } ) => setMetadata({ ...metadata, description: e.currentTarget.value }) @@ -43,7 +42,7 @@ export const ModelMetadata = ({ rows={4} rowsMax={8} /> - {errors.description && } + {errors.description && } diff --git a/src/features/HandleModel/ModelMetadata/ModelMetadataComponent.test.tsx b/src/features/HandleModel/ModelMetadata/ModelMetadataComponent.test.tsx index 67a3341b..c86d1ebe 100644 --- a/src/features/HandleModel/ModelMetadata/ModelMetadataComponent.test.tsx +++ b/src/features/HandleModel/ModelMetadata/ModelMetadataComponent.test.tsx @@ -81,7 +81,7 @@ const Render = () => { test('renders modelMetadata after loading', () => { render(); - const nameLable = screen.getByLabelText('Model Name'); + const nameLable = screen.getByLabelText('Model name (required)'); expect(nameLable).toBeInTheDocument(); expect(nameLable).toHaveValue(''); }); @@ -89,7 +89,7 @@ test('renders modelMetadata after loading', () => { test('Name field to be present and empty after render', async () => { render(); - const nameLable = screen.getByLabelText('Model Name'); + const nameLable = screen.getByLabelText('Model name (required)'); expect(nameLable).toBeInTheDocument(); expect(nameLable).toHaveValue(''); }); @@ -97,6 +97,8 @@ test('Name field to be present and empty after render', async () => { test('Description field to be present after render', async () => { render(); - const descriptionLable = screen.getByLabelText('Model description'); + const descriptionLable = screen.getByLabelText( + 'Model description (required)', + ); expect(descriptionLable).toBeInTheDocument(); }); diff --git a/src/features/HandleModel/SidePane/SidePane.styled.ts b/src/features/HandleModel/SidePane/SidePane.styled.ts index 4bf58f4b..204b37f4 100644 --- a/src/features/HandleModel/SidePane/SidePane.styled.ts +++ b/src/features/HandleModel/SidePane/SidePane.styled.ts @@ -6,9 +6,6 @@ import { theme } from '../../../tokens/theme'; export const SidebarWrapper = styled.div` heigth: 100%; max-width: 256px; - > div { - border-color: ${theme.light.ui.background.medium}; - } `; export const StyledSidebarContent = styled(SideBar.Content)` diff --git a/src/features/ModelView/DeleteButton/DeleteModel.tsx b/src/features/ModelView/DeleteButton/DeleteModel.tsx index cf04141c..ea942e35 100644 --- a/src/features/ModelView/DeleteButton/DeleteModel.tsx +++ b/src/features/ModelView/DeleteButton/DeleteModel.tsx @@ -32,7 +32,9 @@ export const DeleteModel = () => { return ( - Delete model + + Delete model + This will delete the model along with all related cases and results. diff --git a/src/features/ModelView/EditNameDescription/EditNameDescription.styled.ts b/src/features/ModelView/EditNameDescription/EditNameDescription.styled.ts index fec9567f..60f54ae8 100644 --- a/src/features/ModelView/EditNameDescription/EditNameDescription.styled.ts +++ b/src/features/ModelView/EditNameDescription/EditNameDescription.styled.ts @@ -3,12 +3,11 @@ import styled from 'styled-components'; import { spacings } from '../../../tokens/spacings'; export const DialogWrapper = styled(Dialog)` - min-width: 300px; + min-width: 336px; `; export const Buttons = styled(Dialog.Actions)` display: flex; flex-direction: row; - column-gap: ${spacings.SMALL}; `; diff --git a/src/features/ModelView/EditNameDescription/EditNameDescription.tsx b/src/features/ModelView/EditNameDescription/EditNameDescription.tsx index 3a1cc28e..1c4e2727 100644 --- a/src/features/ModelView/EditNameDescription/EditNameDescription.tsx +++ b/src/features/ModelView/EditNameDescription/EditNameDescription.tsx @@ -1,11 +1,8 @@ /* eslint-disable max-lines-per-function */ -import { Button, Dialog, Typography } from '@equinor/eds-core-react'; -import _ from 'lodash'; +import { Button, Dialog } from '@equinor/eds-core-react'; import { useEffect, useState } from 'react'; import { AnalogueModelDetail } from '../../../api/generated'; -import { ErrorBanner } from '../../../components/ErrorBanner/ErrorBanner'; import { validateValues } from '../../HandleModel/HandleModelComponent/HandleModelComponent.hooks'; -import * as Styled2 from '../../HandleModel/HandleModelComponent/HandleModelComponent.styled'; import { ModelMetadata } from '../../HandleModel/ModelMetadata/ModelMetadata'; import * as Styled from './EditNameDescription.styled'; export const EditNameDescription = ({ @@ -42,22 +39,6 @@ export const EditNameDescription = ({ } }, [defaultMetadata, edit, errors, isEdit, metadata, submitting]); - const getErroMessageList = () => { - if (_.isEmpty(errors)) return; - - const errorList: string[] = []; - - Object.keys(errors).forEach(function (key) { - // TODO: Fix the TS error for errors[key] - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const message = errors[key]; - errorList.push(message); - }); - return errorList; - }; - const ErrorList = getErroMessageList(); - const handleSubmit = () => { setErrors(validateValues(metadata, undefined, isEdit)); setSubmitting(true); @@ -71,8 +52,8 @@ export const EditNameDescription = ({ return ( <> + Edit name and description - Edit name description {isEdit && ( <> - {!_.isEmpty(errors) && - ErrorList !== undefined && - ErrorList.map((e, i) => { - return ( - - - - ); - })} )} - - diff --git a/src/features/ModelView/ModelAreaCoordinates/ModelAreaCoordinates.tsx b/src/features/ModelView/ModelAreaCoordinates/ModelAreaCoordinates.tsx index ede2a4a6..cf67f7cd 100644 --- a/src/features/ModelView/ModelAreaCoordinates/ModelAreaCoordinates.tsx +++ b/src/features/ModelView/ModelAreaCoordinates/ModelAreaCoordinates.tsx @@ -8,13 +8,15 @@ export const ModelAreaCoordinates = ({ }) => { return ( - Model areas + + Model areas + You can define multiple areas for calculation in your model by entering coordinates. ); diff --git a/src/features/ModelView/ModelFilesView/ModelFilesView.styled.tsx b/src/features/ModelView/ModelFilesView/ModelFilesView.styled.tsx index 6c165f01..3a1d1968 100644 --- a/src/features/ModelView/ModelFilesView/ModelFilesView.styled.tsx +++ b/src/features/ModelView/ModelFilesView/ModelFilesView.styled.tsx @@ -5,17 +5,14 @@ import { spacings } from '../../../tokens/spacings'; export const TableWrapper = styled.div` display: flex; flex-direction: column; + align-items: flex-start; row-gap: ${spacings.LARGE}; - - width: 85%; `; export const FileTable = styled(Table)` - width: 100%; min-width: 256px; `; export const TableCell = styled(Table.Cell)` - width: 80%; padding-right: ${spacings.X_LARGE}; `; diff --git a/src/features/ModelView/ModelFilesView/ModelFilesView.tsx b/src/features/ModelView/ModelFilesView/ModelFilesView.tsx index 4ab42ae4..acdf06b5 100644 --- a/src/features/ModelView/ModelFilesView/ModelFilesView.tsx +++ b/src/features/ModelView/ModelFilesView/ModelFilesView.tsx @@ -10,11 +10,13 @@ export const ModelFilesView = () => { return ( - Files + + Files + - Model input files + Model input files Size @@ -24,14 +26,14 @@ export const ModelFilesView = () => { data.data.fileUploads?.length > 0) ? ( data.data.fileUploads?.map((file: UploadList) => ( - {file.originalFileName} - **Size** + {file.originalFileName} + - )) ) : ( No files uploaded - -- + - )} diff --git a/src/features/ModelView/ModelMetadataView/ModelMetadataView.styled.tsx b/src/features/ModelView/ModelMetadataView/ModelMetadataView.styled.tsx index a595a3ac..0bbc5fed 100644 --- a/src/features/ModelView/ModelMetadataView/ModelMetadataView.styled.tsx +++ b/src/features/ModelView/ModelMetadataView/ModelMetadataView.styled.tsx @@ -1,27 +1,30 @@ import styled from 'styled-components'; import { spacings } from '../../../tokens/spacings'; +import { theme } from '../../../tokens/theme'; export const Wrapper = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.XXX_LARGE}; - > button { - width: fit-content; + table { + border: 1px solid ${theme.light.ui.background.medium}; + border-collapse: collapse; } -`; -export const Metadata = styled.div` - display: flex; - flex-direction: column; - row-gap: ${spacings.LARGE}; + /* Equal widths of the icon column in each of the metadata tables */ + td:first-child { + width: ${spacings.XXX_LARGE}; + } `; -export const MetadataInfo = styled.div` +export const DescriptionMeta = styled.div` display: flex; flex-direction: column; + align-items: flex-start; row-gap: ${spacings.MEDIUM}; +`; - max-width: 60%; +export const UploadingMeta = styled.div` + max-width: 40rem; `; diff --git a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx index c45a3667..494ac4c7 100644 --- a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx +++ b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx @@ -37,10 +37,10 @@ export const defaultStratColumnData: StratColumnType = { export const ModelMetadataView = ({ modelIdParent, - isAddUploading, + uploadingProgress, }: { modelIdParent?: string; - isAddUploading?: boolean; + uploadingProgress?: number; }) => { const { isLoading, data } = useFetchModel( modelIdParent ? modelIdParent : undefined, @@ -272,66 +272,71 @@ export const ModelMetadataView = ({ return ( - - {!isAddUploading && ( + {uploadingProgress === undefined && ( + <> - Description and metadata + {data.data.description && ( + + {data.data.description} + + )} + - <>{data.data.description &&
    {data.data.description}
    } + - -
    - {!isAddModelDialog && ( - - )} -
    - - )} - {isAddUploading && ( - - Add model metadata + +
    + )} + {uploadingProgress !== undefined && + uploadingProgress >= 0 && + uploadingProgress < 100 && ( + - At least one type of metadata (outcrop analogue, stratigraphic - column, or deposition environment) is required when adding a new - model. + While your model is being uploaded, you can add some metadata like + outcrop analogue, stratigraphic column, or gross depositional + environment. Please note that at least one type of metadata is + required for PEPM models before they can be approved later on. - + )} -
    - -
    -
    - -
    -
    - -
    -
    + + Model metadata + + +
    + +
    +
    + +
    +
    + +
    Add stratigraphic column diff --git a/src/features/ModelView/ModelNameFrame/ModelNameFrame.styled.tsx b/src/features/ModelView/ModelNameFrame/ModelNameFrame.styled.tsx index 9f35b5e7..47af001a 100644 --- a/src/features/ModelView/ModelNameFrame/ModelNameFrame.styled.tsx +++ b/src/features/ModelView/ModelNameFrame/ModelNameFrame.styled.tsx @@ -3,15 +3,7 @@ import { spacings } from '../../../tokens/spacings'; import { theme } from '../../../tokens/theme'; export const NameFrame = styled.div` - width: 100%; - min-height: ${spacings.NAME_FRAME}; - padding: ${spacings.LARGE} 0; background-color: ${theme.light.ui.background.light}; - border-left: solid ${spacings.XX_SMALL} ${theme.light.ui.background.medium}; - - > h1 { - margin: 0; - padding: 0 ${spacings.X_LARGE}; - font-weight: normal; + padding: ${spacings.LARGE} ${spacings.X_LARGE}; } `; diff --git a/src/features/ModelView/ModelNameFrame/ModelNameFrame.tsx b/src/features/ModelView/ModelNameFrame/ModelNameFrame.tsx index ff0ae7bf..13af2e84 100644 --- a/src/features/ModelView/ModelNameFrame/ModelNameFrame.tsx +++ b/src/features/ModelView/ModelNameFrame/ModelNameFrame.tsx @@ -1,10 +1,19 @@ +import { Typography } from '@equinor/eds-core-react'; import { AnalogueModelDetail } from '../../../api/generated'; import * as Styled from './ModelNameFrame.styled'; export const ModelNameFrame = ({ model }: { model?: AnalogueModelDetail }) => { return ( - {model ?

    {model.name}

    :

    Loading ....

    } + {model ? ( + + {model.name} + + ) : ( + + Loading .... + + )}
    ); }; diff --git a/src/features/ModelView/ModelView.styled.tsx b/src/features/ModelView/ModelView.styled.tsx index 13469d51..8a2a6ebc 100644 --- a/src/features/ModelView/ModelView.styled.tsx +++ b/src/features/ModelView/ModelView.styled.tsx @@ -2,22 +2,10 @@ import styled from 'styled-components'; import { spacings } from '../../tokens/spacings'; export const MetadataWrapper = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - height: calc(100% - 75.5px); - width: 100%; - padding: ${spacings.X_LARGE}; - row-gap: ${spacings.XXX_LARGE}; - column-gap: ${spacings.X_LARGE}; - - @media (max-width: 1350px) { - flex-direction: column; - } -`; -export const InnerMetadataWrapper = styled.div` display: flex; flex-direction: column; + align-items: flex-start; row-gap: ${spacings.XXX_LARGE}; - width: 50vw; + padding: ${spacings.X_LARGE} ${spacings.X_LARGE} + calc(${spacings.XXXX_LARGE} + ${spacings.X_LARGE}); `; diff --git a/src/features/ModelView/ModelView.tsx b/src/features/ModelView/ModelView.tsx index 7e209013..4282d89f 100644 --- a/src/features/ModelView/ModelView.tsx +++ b/src/features/ModelView/ModelView.tsx @@ -1,12 +1,10 @@ import { useState } from 'react'; import { CoordinatesDialog } from '../../components/AreaCoordinates/CoordinatesDialog/CoordinatesDialog'; -import { ImageView } from '../../components/ImageView/ImageView'; import { ModelMetadataView } from '../../features/ModelView/ModelMetadataView/ModelMetadataView'; import { DeleteModel } from './DeleteButton/DeleteModel'; import { ModelAreaCoordinates } from './ModelAreaCoordinates/ModelAreaCoordinates'; import { ModelFilesView } from './ModelFilesView/ModelFilesView'; import * as Styled from './ModelView.styled'; -import Img from './image.png'; export const ModelView = () => { const [open, setOpen] = useState(false); @@ -18,17 +16,10 @@ export const ModelView = () => { return ( <> - - - - - - - + + + + diff --git a/src/pages/AddModel/AddModel.styled.tsx b/src/pages/AddModel/AddModel.styled.tsx index 2173f8eb..018bad4e 100644 --- a/src/pages/AddModel/AddModel.styled.tsx +++ b/src/pages/AddModel/AddModel.styled.tsx @@ -2,26 +2,17 @@ import styled from 'styled-components'; import { spacings } from '../../tokens/spacings'; export const PageLayout = styled.div` - display: flex; - fled-direction: row; - flex: auto; - position: relative; - width: 100%; + display: grid; + grid-template-areas: 'sidebar content'; + grid-template-columns: 16rem 1fr; height: 100%; `; export const Content = styled.div` - display: flex; - fled-direction: column; - - width: 100%; - overflow: scroll; - - padding: ${spacings.XX_LARGE} ${spacings.X_LARGE}; -`; - -export const InnerContent = styled.div` display: flex; flex-direction: column; - row-gap: ${spacings.X_LARGE}; + align-items: flex-start; + row-gap: ${spacings.XXX_LARGE}; + padding: ${spacings.X_LARGE} ${spacings.X_LARGE} + calc(${spacings.XXXX_LARGE} + ${spacings.X_LARGE}); `; diff --git a/src/pages/AddModel/AddModel.tsx b/src/pages/AddModel/AddModel.tsx index 17d8cfa8..3c0bbc36 100644 --- a/src/pages/AddModel/AddModel.tsx +++ b/src/pages/AddModel/AddModel.tsx @@ -1,6 +1,7 @@ +/* eslint-disable sort-imports */ /* eslint-disable max-lines */ /* eslint-disable max-lines-per-function */ -import { Snackbar } from '@equinor/eds-core-react'; +import { Snackbar, Typography } from '@equinor/eds-core-react'; import { useMutation } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; import { @@ -12,8 +13,8 @@ import { AnalogueModelsService, ConvertAnalogueModelCommand, CreateAnalogueModelCommand, - JobsService, JobStatus, + JobsService, MetadataDto, UploadFileType, UploadsService, @@ -25,8 +26,7 @@ import { ModelMetadataView } from '../../features/ModelView/ModelMetadataView/Mo import * as Styled from './AddModel.styled'; enum UploadProcess { - STARTED = 'We are uploading your new model. Please keep this browser tab open.', - SUCCESS = 'Model successfully uploaded and is now beeing processed. You may close this browser tab now.', + SUCCESS = 'Model successfully uploaded and is now beeing processed.', FAILED = 'File upload failed.', } @@ -174,7 +174,6 @@ export const AddModel = () => { } async function uploadModel(file: File, metadata: AnalogueModelDetail) { - setUploadStatus(UploadProcess.STARTED); setUploading(true); const ModelBody: CreateAnalogueModelCommand = { name: metadata.name ? metadata.name : '', @@ -300,33 +299,28 @@ export const AddModel = () => { -
    - - 0} - modelId={modelId} + + New model + + 0} + modelId={modelId} + /> + {modelId !== '' && ( + <> + - {modelId !== '' && ( - <> - 0} - /> - - )} - -
    + + )}
    - + {uploadStatus} diff --git a/src/pages/ModelPages/Model/Model.styled.tsx b/src/pages/ModelPages/Model/Model.styled.tsx index c2ec1147..af084160 100644 --- a/src/pages/ModelPages/Model/Model.styled.tsx +++ b/src/pages/ModelPages/Model/Model.styled.tsx @@ -1,24 +1,31 @@ import styled from 'styled-components'; +import { spacings } from '../../../tokens/spacings'; import { theme } from '../../../tokens/theme'; -export const Wrapper = styled.div` - display: flex; - flex: auto; - flex-direction: row; - position: relative; - width: 100%; +export const EmptyPage = styled.div` + background-color: ${theme.light.ui.background.light}; + display: grid; + place-items: center; height: 100%; + + .loading { + display: flex; + align-items: center; + flex-direction: row; + column-gap: ${spacings.MEDIUM}; + } +`; + +export const Wrapper = styled.div` + display: grid; + grid-template-areas: 'sidebar content'; + grid-template-columns: 16rem 1fr; `; export const ContentWrapper = styled.div` - width: 100%; - overflow: scroll; + grid-area: content; `; export const SidebarWrapper = styled.div` - heigth: 100%; - max-width: 256px; - > div { - border-color: ${theme.light.ui.background.medium}; - } + grid-area: sidebar; `; diff --git a/src/pages/ModelPages/Model/Model.tsx b/src/pages/ModelPages/Model/Model.tsx index a901fa8f..54134bc0 100644 --- a/src/pages/ModelPages/Model/Model.tsx +++ b/src/pages/ModelPages/Model/Model.tsx @@ -3,12 +3,48 @@ import { ModelNameFrame } from '../../../features/ModelView/ModelNameFrame/Model import { ModelNavigationBar } from '../../../features/ModelView/ModelNavigationBar/ModelNavigationBar'; import { useFetchModel } from '../../../hooks/useFetchModel'; import * as Styled from './Model.styled'; +import { + Banner, + CircularProgress, + Icon, + Typography, +} from '@equinor/eds-core-react'; +import { mood_sad } from '@equinor/eds-icons'; + +// eslint-disable-next-line camelcase +Icon.add({ mood_sad }); export const Model = () => { const { data, isLoading, failureReason } = useFetchModel(); - if (failureReason) return <>An error occured; - if (isLoading) return <>Loading ...; + if (failureReason) + return ( + + + + + + + An error occured. Please try refreshing this page. + + + + ); + + if (isLoading) + return ( + +
    + {' '} + Loading, please wait… +
    +
    + ); return ( diff --git a/src/tokens/theme.ts b/src/tokens/theme.ts index 28fb16d2..6c5e1b00 100644 --- a/src/tokens/theme.ts +++ b/src/tokens/theme.ts @@ -21,6 +21,7 @@ export const theme = { highlight: interactive.secondary__highlight.hex, }, text: { + staticIconsDefault: text.static_icons__default.hex, staticIconsTertiary: text.static_icons__tertiary.hex, }, ui: { @@ -36,5 +37,15 @@ export const theme = { info: { warning: infographic.primary__spruce_wood.hex, }, + danger: { + text: interactive.danger__text.hex, + highlight: interactive.danger__highlight.hex, + resting: interactive.danger__resting.hex, + }, + warning: { + text: interactive.warning__text.hex, + highlight: interactive.warning__highlight.hex, + resting: interactive.warning__resting.hex, + }, }, };