From 1b8443ff567e7006a38d272f83cf9a88d075e87b Mon Sep 17 00:00:00 2001 From: mheggelund Date: Mon, 9 Oct 2023 15:15:31 +0200 Subject: [PATCH 1/2] chore: merge inn upload-form-valitation functionallity --- .../AddModelDialog/AddModelDialog.tsx | 56 ++++++++++- .../ModelMetadata/ModelMetadata.styled.ts | 19 ++++ .../AddModel/ModelMetadata/ModelMetadata.tsx | 94 +++++++++++++++++-- 3 files changed, 158 insertions(+), 11 deletions(-) diff --git a/src/features/AddModel/AddModelDialog/AddModelDialog.tsx b/src/features/AddModel/AddModelDialog/AddModelDialog.tsx index 7a1020d6..59afba91 100644 --- a/src/features/AddModel/AddModelDialog/AddModelDialog.tsx +++ b/src/features/AddModel/AddModelDialog/AddModelDialog.tsx @@ -1,3 +1,4 @@ +/* eslint-disable max-lines-per-function */ import { Button } from '@equinor/eds-core-react' import { useState } from 'react' import { ModelInputFilesTable } from '../ModelInputFilesTable/ModelInputFilesTable' @@ -10,6 +11,14 @@ interface AddModelDialogProps { cancel: () => void } +export default interface MetadataProps { + description?: string + field: string[] + zone?: string[] + formation: string[] + analogue?: string[] +} + export const AddModelDialog = ({ isOpen, confirm, @@ -20,6 +29,12 @@ export const AddModelDialog = ({ NC: undefined, INI: undefined, }) + const [metadata, setMetadata] = useState>() + + const [fieldValidationError, setFieldValidationError] = + useState(false) + const [formationValidationError, setFormationValidationError] = + useState(false) function toggleINIFileContent() { setFileDisplay(!isFileDisplay) @@ -27,6 +42,36 @@ export const AddModelDialog = ({ const INIFileContent = () =>

Not implemented yet...

+ const validateFieldInput = () => { + if (metadata?.field === undefined) { + setFieldValidationError(true) + } else if (metadata?.field.length === 0) { + setFieldValidationError(true) + } else { + setFieldValidationError(false) + } + } + const validateFormationInput = () => { + if (metadata?.formation === undefined) { + setFormationValidationError(true) + } else if (metadata?.formation.length === 0) { + setFormationValidationError(true) + } else { + setFormationValidationError(false) + } + } + + const uploadFile = () => { + if (files.NC) confirm(files.NC) + } + + const submit = () => { + validateFieldInput() + validateFormationInput() + + if (!fieldValidationError || !formationValidationError) uploadFile() + } + return ( @@ -42,12 +87,15 @@ export const AddModelDialog = ({ }} /> {isFileDisplay && } - + - + diff --git a/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts b/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts index d7d11a96..6aae8916 100644 --- a/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts +++ b/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts @@ -11,5 +11,24 @@ export const ModelMetadata = styled.div` > .model-description { grid-column: 1 / span 2; } + + > .model-required { + border-style: solid; + border-width: 2px; + border-color: red; + } + + > .required-div { + > label { + color: red !important; + } + > .model-required2 { + > div { + border-style: solid !important; + border-width: 2px !important; + border-color: red !important; + } + } + } } ` diff --git a/src/features/AddModel/ModelMetadata/ModelMetadata.tsx b/src/features/AddModel/ModelMetadata/ModelMetadata.tsx index d9a827ed..3056bd86 100644 --- a/src/features/AddModel/ModelMetadata/ModelMetadata.tsx +++ b/src/features/AddModel/ModelMetadata/ModelMetadata.tsx @@ -1,8 +1,37 @@ -import { Autocomplete, TextField, Typography } from '@equinor/eds-core-react' +/* eslint-disable max-lines-per-function */ +import { + Autocomplete, + AutocompleteChanges, + Label, + TextField, + Typography, +} from '@equinor/eds-core-react' +import MetadataProps from '../AddModelDialog/AddModelDialog' + import * as Styled from './ModelMetadata.styled' -export const ModelMetadata = () => { - const fields = [{ name: 'Tor' }] +export const ModelMetadata = ({ + fieldValidationError, + formationValidationError, + metadata, + setMetadata, +}: { + fieldValidationError: boolean + formationValidationError: boolean + metadata: Partial | undefined + setMetadata: (metadata: Partial) => void +}) => { + const fields = { + description: 'Description string', + field: ['Tor', 'Pål'], + zone: ['Zone 1', 'Zone 2', 'Zone 3'], + formation: ['Rocky', 'Hilly', 'Flat'], + analogue: ['Analouge1', 'Analouge2'], + } + + const handleInput = (e: AutocompleteChanges, target: string) => { + setMetadata({ ...metadata, [target]: e.selectedItems }) + } return ( Description and metadata @@ -10,12 +39,63 @@ export const ModelMetadata = () => { id="model-description" className="model-description" label="Model description (optional)" + value={metadata?.description} + onChange={(e: React.ChangeEvent) => + setMetadata({ ...metadata, description: e.currentTarget.value }) + } multiline /> - - - - +
+ ) => + handleInput(e, 'field') + } + > + {fieldValidationError && ( + + )} +
+
+ ) => + handleInput(e, 'formation') + } + > + {formationValidationError && ( + + )} +
+ ) => + setMetadata({ ...metadata, analogue: e.selectedItems }) + } + > + ) => + setMetadata({ ...metadata, zone: e.selectedItems }) + } + >{' '}
) } From 1b7fc8a0e6af6d48ac15394a425770d15a4682f8 Mon Sep 17 00:00:00 2001 From: mheggelund Date: Tue, 10 Oct 2023 13:56:26 +0200 Subject: [PATCH 2/2] chore: uppdated add model validation --- .../AddModelDialog/AddModelDialog.styled.ts | 6 + .../AddModelDialog/AddModelDialog.tsx | 73 +++++----- .../ModelMetadata/ModelMetadata.styled.ts | 64 +++++---- .../AddModel/ModelMetadata/ModelMetadata.tsx | 128 +++++++++--------- 4 files changed, 148 insertions(+), 123 deletions(-) diff --git a/src/features/AddModel/AddModelDialog/AddModelDialog.styled.ts b/src/features/AddModel/AddModelDialog/AddModelDialog.styled.ts index faf3a32c..d652a49a 100644 --- a/src/features/AddModel/AddModelDialog/AddModelDialog.styled.ts +++ b/src/features/AddModel/AddModelDialog/AddModelDialog.styled.ts @@ -12,6 +12,12 @@ const StyledDialogCustomContent = styled(Dialog.CustomContent)` flex-direction: column; row-gap: ${spacings.X_LARGE}; height: 740px; + + > p { + &.error { + color: red; + } + } ` const StyledDialogActions = styled(Dialog.Actions)` diff --git a/src/features/AddModel/AddModelDialog/AddModelDialog.tsx b/src/features/AddModel/AddModelDialog/AddModelDialog.tsx index 59afba91..9d87f2c1 100644 --- a/src/features/AddModel/AddModelDialog/AddModelDialog.tsx +++ b/src/features/AddModel/AddModelDialog/AddModelDialog.tsx @@ -1,6 +1,6 @@ /* eslint-disable max-lines-per-function */ -import { Button } from '@equinor/eds-core-react' -import { useState } from 'react' +import { Button, Typography } from '@equinor/eds-core-react' +import { useEffect, useState } from 'react' import { ModelInputFilesTable } from '../ModelInputFilesTable/ModelInputFilesTable' import { ModelMetadata } from '../ModelMetadata/ModelMetadata' import * as Styled from './AddModelDialog.styled' @@ -19,6 +19,11 @@ export default interface MetadataProps { analogue?: string[] } +export type ErrorType = { + field?: string + formation?: string + file?: string +} export const AddModelDialog = ({ isOpen, confirm, @@ -30,11 +35,8 @@ export const AddModelDialog = ({ INI: undefined, }) const [metadata, setMetadata] = useState>() - - const [fieldValidationError, setFieldValidationError] = - useState(false) - const [formationValidationError, setFormationValidationError] = - useState(false) + const [errors, setErrors] = useState({}) + const [submitting, setSubmitting] = useState(false) function toggleINIFileContent() { setFileDisplay(!isFileDisplay) @@ -42,36 +44,41 @@ export const AddModelDialog = ({ const INIFileContent = () =>

Not implemented yet...

- const validateFieldInput = () => { - if (metadata?.field === undefined) { - setFieldValidationError(true) - } else if (metadata?.field.length === 0) { - setFieldValidationError(true) - } else { - setFieldValidationError(false) + const validateValues = (inputValues: Partial | undefined) => { + const errors: ErrorType = {} + if (inputValues?.field === undefined || inputValues?.field?.length === 0) { + errors.field = 'Field not selected' } - } - const validateFormationInput = () => { - if (metadata?.formation === undefined) { - setFormationValidationError(true) - } else if (metadata?.formation.length === 0) { - setFormationValidationError(true) - } else { - setFormationValidationError(false) + + if ( + inputValues?.formation === undefined || + inputValues?.formation?.length === 0 + ) { + errors.formation = 'Formation not selected' } - } - const uploadFile = () => { - if (files.NC) confirm(files.NC) + if (!files.NC) { + errors.file = 'NC file missing' + } + return errors } - const submit = () => { - validateFieldInput() - validateFormationInput() + const handleSubmit = () => { + setErrors(validateValues(metadata)) + setSubmitting(true) + } - if (!fieldValidationError || !formationValidationError) uploadFile() + const finishSubmit = () => { + if (files.NC) confirm(files.NC) } + useEffect(() => { + if (Object.keys(errors).length === 0 && submitting) { + finishSubmit() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [errors, submitting]) + return ( @@ -88,14 +95,16 @@ export const AddModelDialog = ({ /> {isFileDisplay && } + {Object.keys(errors).includes('file') && ( + NC file missing + )} - + diff --git a/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts b/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts index 6aae8916..98f45a19 100644 --- a/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts +++ b/src/features/AddModel/ModelMetadata/ModelMetadata.styled.ts @@ -1,33 +1,47 @@ +import { TextField } from '@equinor/eds-core-react' import styled from 'styled-components' import { spacings } from '../../../tokens/spacings' - export const ModelMetadata = styled.div` - &.model-metadata { - display: grid; - grid-template-columns: auto auto; - column-gap: ${spacings.MEDIUM}}; - row-gap: ${spacings.MEDIUM}; + display: flex; + flex-direction: column; - > .model-description { - grid-column: 1 / span 2; - } + row-gap: ${spacings.MEDIUM}; +` - > .model-required { - border-style: solid; - border-width: 2px; - border-color: red; - } - - > .required-div { - > label { - color: red !important; - } - > .model-required2 { - > div { - border-style: solid !important; - border-width: 2px !important; - border-color: red !important; - } +export const Form = styled.form` + display: flex; + flex-direction: column; + row-gap: ${spacings.MEDIUM}; +` + +export const AutocompleteWrapper = styled.div` + display: flex; + flex-direction: column; + row-gap: ${spacings.MEDIUM}; +` +export const AutocompleteRow = styled.div` + display: flex; + flex-direction: row; + flex: end; + column-gap: ${spacings.MEDIUM}; + + > div { + flex-grow: 1; + } +` + +export const TextInput = styled(TextField)` + display: flex; + flex-direction: column; +` +export const Required = styled.div` + > label { + color: red; + } + > .model-required { + > div { + > div { + border: solid 2px red; } } } diff --git a/src/features/AddModel/ModelMetadata/ModelMetadata.tsx b/src/features/AddModel/ModelMetadata/ModelMetadata.tsx index 3056bd86..3dc3e09f 100644 --- a/src/features/AddModel/ModelMetadata/ModelMetadata.tsx +++ b/src/features/AddModel/ModelMetadata/ModelMetadata.tsx @@ -3,21 +3,18 @@ import { Autocomplete, AutocompleteChanges, Label, - TextField, Typography, } from '@equinor/eds-core-react' -import MetadataProps from '../AddModelDialog/AddModelDialog' +import MetadataProps, { ErrorType } from '../AddModelDialog/AddModelDialog' import * as Styled from './ModelMetadata.styled' export const ModelMetadata = ({ - fieldValidationError, - formationValidationError, + errors, metadata, setMetadata, }: { - fieldValidationError: boolean - formationValidationError: boolean + errors: ErrorType metadata: Partial | undefined setMetadata: (metadata: Partial) => void }) => { @@ -32,70 +29,69 @@ export const ModelMetadata = ({ const handleInput = (e: AutocompleteChanges, target: string) => { setMetadata({ ...metadata, [target]: e.selectedItems }) } + return ( Description and metadata - ) => - setMetadata({ ...metadata, description: e.currentTarget.value }) - } - multiline - /> -
- ) => - handleInput(e, 'field') - } - > - {fieldValidationError && ( - - )} -
-
- ) => - handleInput(e, 'formation') + + ) => + setMetadata({ ...metadata, description: e.currentTarget.value }) } - > - {formationValidationError && ( - - )} -
- ) => - setMetadata({ ...metadata, analogue: e.selectedItems }) - } - > - ) => - setMetadata({ ...metadata, zone: e.selectedItems }) - } - >{' '} + multiline + rows={4} + rowsMax={8} + /> + + + + ) => + handleInput(e, 'field') + } + > + {errors.field && } + + + ) => + handleInput(e, 'formation') + } + > + {errors.formation && ( + + )} + + + + ) => + setMetadata({ ...metadata, analogue: e.selectedItems }) + } + > + ) => + setMetadata({ ...metadata, zone: e.selectedItems }) + } + > + + +
) }