diff --git a/backend/api/Controllers/Models/AreaResponse.cs b/backend/api/Controllers/Models/AreaResponse.cs index 600121c01..498602ff7 100644 --- a/backend/api/Controllers/Models/AreaResponse.cs +++ b/backend/api/Controllers/Models/AreaResponse.cs @@ -10,6 +10,8 @@ public class AreaResponse public string PlantCode { get; set; } + public string PlantName { get; set; } + public string InstallationCode { get; set; } public string AreaName { get; set; } @@ -25,6 +27,7 @@ public AreaResponse(Area area) Id = area.Id; DeckName = area.Deck!.Name; PlantCode = area.Plant.PlantCode; + PlantName = area.Plant.Name; InstallationCode = area.Installation.InstallationCode; AreaName = area.Name; MapMetadata = area.MapMetadata; diff --git a/frontend/src/components/Pages/MissionDefinitionPage/MissionDefinitionPage.tsx b/frontend/src/components/Pages/MissionDefinitionPage/MissionDefinitionPage.tsx index c49579d1c..59e77ecf0 100644 --- a/frontend/src/components/Pages/MissionDefinitionPage/MissionDefinitionPage.tsx +++ b/frontend/src/components/Pages/MissionDefinitionPage/MissionDefinitionPage.tsx @@ -7,17 +7,14 @@ import { BackendAPICaller } from 'api/ApiCaller' import { tokens } from '@equinor/eds-tokens' import { Header } from 'components/Header/Header' import { CondensedMissionDefinition, SourceType } from 'models/MissionDefinition' -import { Button, Typography, Card, Dialog, TextField } from '@equinor/eds-core-react' +import { Button, Typography, Card, Dialog, TextField, Icon } from '@equinor/eds-core-react' import { useLanguageContext } from 'components/Contexts/LanguageContext' import { MissionDefinitionUpdateForm } from 'models/MissionDefinitionUpdateForm' import { config } from 'config' import { SignalREventLabels, useSignalRContext } from 'components/Contexts/SignalRContext' +import { Icons } from 'utils/icons' -const StyledFormDialog = styled.div` - display: flex; - justify-content: space-between; -` -const StyledAutoComplete = styled(Card)` +const StyledFormCard = styled(Card)` display: flex; justify-content: center; padding: 8px; @@ -29,18 +26,31 @@ const StyledButtonSection = styled.div` margin-right: 0; gap: 10px; ` -const StyledFormSection = styled.div` - display: flex; - margin-left: auto; - margin-right: 0; - gap: 10px; +const StyledFormContainer = styled.div` + display: grid; + grid-template-columns: [c1] 1fr [c2] 1fr [c3] 1fr; + grid-template-rows: [r1] auto [r1] auto [r1] auto; + align: left; + align-items: flex-start; + align-content: flex-start; + max-width: 1200px; + min-width: 600px; + gap: 10px 20px; +` +const StyledFormItem = styled.div` + width: 100%; + height: auto; + padding: 5px; + word-break: break-word; + hyphens: auto; + min-height: 60px; ` const StyledDialog = styled(Dialog)` display: flex; + justify-content: space-between; padding: 1rem; width: 620px; ` - const StyledMissionDefinitionPage = styled.div` display: flex; flex-wrap: wrap; @@ -49,99 +59,154 @@ const StyledMissionDefinitionPage = styled.div` gap: 1rem; margin: 2rem; ` +const StyledButton = styled(Button)` + width: 260px; +` +const StyledInspectionFrequencyDiv = styled.div` + > * { + padding: 10px; + } +` +const StyledTitleComponent = styled.div` + display: flex; + align-items: center; + height: 37px; +` +const StyledEditButton = styled(Button)` + padding-left: 5px; + padding-top: 0px; + margin-top: 0px; +` +const StyledCard = styled(Card)` + display: flex; + padding: 8px; + height: 110px; +` -interface IProps { - missionDefinition: CondensedMissionDefinition - updateMissionDefinition: (missionDefinition: CondensedMissionDefinition) => void -} - -function KeyValuePairDisplay({ left, right }: { left: string; right: any }) { +function MetadataItem({ title, content, onEdit }: { title: string; content: any; onEdit?: () => void }) { return ( - <> - - {left} - - - {right} - - + + + + + {title} + + {onEdit && ( + + + + )} + + + {content} + + + ) } -function MissionDefinitionPageBody({ missionDefinition, updateMissionDefinition }: IProps) { +interface IMissionDefinitionPageBodyProps { + missionDefinition: CondensedMissionDefinition + updateMissionDefinition: (missionDefinition: CondensedMissionDefinition) => void +} + +function MissionDefinitionPageBody({ missionDefinition, updateMissionDefinition }: IMissionDefinitionPageBodyProps) { const { TranslateText } = useLanguageContext() + const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) + const [selectedField, setSelectedField] = useState('') let navigate = useNavigate() const displayInspectionFrequency = (inspectionFrequency: string | undefined | null) => { if (!inspectionFrequency) return TranslateText('No inspection frequency set') const timeArray = inspectionFrequency.split(':') - const days: number = +timeArray[0] - const hours: number = +timeArray[1] - const minutes: number = +timeArray[2] + const days: number = +timeArray[0] // [1] is hours and [2] is minutes let returnStringArray: string[] = [] if (days > 0) returnStringArray.push(days + ' ' + TranslateText('days')) - if (hours > 0) returnStringArray.push(hours + ' ' + TranslateText('hours')) - if (minutes > 0) returnStringArray.push(minutes + ' ' + TranslateText('minutes')) if (returnStringArray.length === 0) return TranslateText('No inspection frequency set') return TranslateText('Inspection required every') + ' ' + returnStringArray.join(', ') } + const onEdit = (editType: string) => { + return () => { + setIsEditDialogOpen(true) + setSelectedField(editType) + } + } + return ( <> - - - - - - - - - + + {isEditDialogOpen && ( + setIsEditDialogOpen(false)} + updateMissionDefinition={updateMissionDefinition} + /> + )} ) } -function MissionDefinitionEditButtons({ missionDefinition, updateMissionDefinition }: IProps) { +interface IMissionDefinitionEditDialogProps { + missionDefinition: CondensedMissionDefinition + fieldName: string + closeEditDialog: () => void + updateMissionDefinition: (missionDefinition: CondensedMissionDefinition) => void +} + +function MissionDefinitionEditDialog({ + missionDefinition, + updateMissionDefinition, + fieldName, + closeEditDialog, +}: IMissionDefinitionEditDialogProps) { const defaultMissionDefinitionForm: MissionDefinitionUpdateForm = { comment: missionDefinition.comment, inspectionFrequency: missionDefinition.inspectionFrequency, @@ -149,7 +214,6 @@ function MissionDefinitionEditButtons({ missionDefinition, updateMissionDefiniti isDeprecated: false, } const { TranslateText } = useLanguageContext() - const [isEditDialogOpen, setIsEditDialogOpen] = useState(false) const [form, setForm] = useState(defaultMissionDefinitionForm) const updateInspectionFrequencyFormDays = (newDay: string) => { @@ -161,15 +225,6 @@ function MissionDefinitionEditButtons({ missionDefinition, updateMissionDefiniti setForm({ ...form, inspectionFrequency: newDay + '.00:' + inspectionArray[1] + ':00' }) } - const updateInspectionFrequencyFormHours = (newHour: string) => { - if (!Number(newHour) && newHour !== '') return - newHour = newHour === '' ? '0' : newHour - if (!form.inspectionFrequency) return '00:' + newHour + ':00' - const inspectionArray = form.inspectionFrequency.split(':') - if (!inspectionArray || inspectionArray.length < 2) return '00:' + newHour + ':00' - setForm({ ...form, inspectionFrequency: inspectionArray[0] + ':' + newHour + ':00' }) - } - const getDayAndHoursFromInspectionFrequency = (inspectionFrequency: string | undefined): [number, number] => { if (!inspectionFrequency) return [0, 0] const inspectionParts = form.inspectionFrequency?.split(':') @@ -181,7 +236,8 @@ function MissionDefinitionEditButtons({ missionDefinition, updateMissionDefiniti const daysAndHours = getDayAndHoursFromInspectionFrequency(form.inspectionFrequency) if (daysAndHours[0] === 0 && daysAndHours[1] === 0) form.inspectionFrequency = undefined BackendAPICaller.updateMissionDefinition(missionDefinition.id, form).then((missionDefinition) => { - setIsEditDialogOpen(false) + closeEditDialog() + // When we integrate signalR, we will no longer need this function call as it will update regardless if (missionDefinition.isDeprecated) updateMissionDefinition(missionDefinition) }) } @@ -189,71 +245,71 @@ function MissionDefinitionEditButtons({ missionDefinition, updateMissionDefiniti const inspectionFrequency = getDayAndHoursFromInspectionFrequency(form.inspectionFrequency) const inspectionFrequencyDays = !inspectionFrequency[0] || inspectionFrequency[0] === 0 ? '' : String(inspectionFrequency[0]) - const inspectionFrequencyHours = - !inspectionFrequency[1] || inspectionFrequency[1] === 0 ? '' : String(inspectionFrequency[1]) + + const getFormItem = () => { + switch (fieldName) { + case 'inspectionFrequency': + return ( + + ) => { + if (!isNaN(+changes.target.value)) + updateInspectionFrequencyFormDays(changes.target.value) + }} + /> + + ) + case 'comment': + return ( + ) => + setForm({ ...form, comment: changes.target.value }) + } + /> + ) + case 'name': + return ( + ) => + setForm({ ...form, name: changes.target.value }) + } + /> + ) + default: + console.error('Invalid field name: ', fieldName) + break + } + } return ( - <> - - {isEditDialogOpen && ( - - - - - ) => - setForm({ ...form, name: changes.target.value }) - } - /> - ) => - setForm({ ...form, comment: changes.target.value }) - } - /> -
- ) => - updateInspectionFrequencyFormDays(changes.target.value) - } - /> - ) => - updateInspectionFrequencyFormHours(changes.target.value) - } - /> -
-
- - - - -
-
-
- )} - + + + {TranslateText('Edit') + ' ' + TranslateText(fieldName)} + {getFormItem()} + + + + + + ) } diff --git a/frontend/src/language/en.json b/frontend/src/language/en.json index 4db4db00f..af1918217 100644 --- a/frontend/src/language/en.json +++ b/frontend/src/language/en.json @@ -150,7 +150,7 @@ "for": "for", "Already scheduled": "Already scheduled", "Edit": "Edit", - "Update mission definition": "Update mission definition", + "Update": "Update", "Delete": "Delete", "Installation": "Installation", "Area": "Area", @@ -158,6 +158,9 @@ "Plant": "Plant", "Inspection frequency": "Inspection frequency", "Comment": "Comment", + "inspectionFrequency": "inspection frequency", + "name": "name", + "comment": "comment", "View last run": "View last run", "Mission source": "Mission source", "Inspection required every": "Inspection required every", @@ -197,5 +200,6 @@ "Dismiss robots from safe zone long text": "Normal operation can resume by continuing the missions present on the queue or remove them all.", "Dismiss robots from safe zone": "Dismiss robots from safe zone", "Continue missions": "Continue missions", - "Safe Zone": "Safe Zone" + "Safe Zone": "Safe Zone", + "Edit mission definition": "Edit mission definition" } diff --git a/frontend/src/language/no.json b/frontend/src/language/no.json index 53dbe5495..ced56af03 100644 --- a/frontend/src/language/no.json +++ b/frontend/src/language/no.json @@ -150,7 +150,7 @@ "for": "for", "Already scheduled": "Allerede i køen", "Edit": "Rediger", - "Update mission definition": "Oppdater oppdragsdefinisjon", + "Update": "Oppdater", "Delete": "Slett", "Installation": "Installasjon", "Area": "Område", @@ -158,6 +158,9 @@ "Plant": "Anlegg", "Inspection frequency": "Inspeksjonsfrekvens", "Comment": "Kommentar", + "inspectionFrequency": "inspeksjonsfrekvens", + "name": "navn", + "comment": "kommentar", "View last run": "Se siste kjøring", "Mission source": "Oppdragskilde", "Echo": "Echo", @@ -197,5 +200,6 @@ "Dismiss robots from safe zone long text": "Vanlig drift kan fortsette ved å starte oppdragene i køen eller ved å slette dem.", "Dismiss robots from safe zone": "Slipp robotene ut av trygg sone", "Continue missions": "Fortsett oppdragene", - "Safe Zone": "Trygg Sone" + "Safe Zone": "Trygg Sone", + "Edit mission definition": "Rediger oppdragsdefinisjon" } diff --git a/frontend/src/models/Area.ts b/frontend/src/models/Area.ts index 7899da138..362f0ba72 100644 --- a/frontend/src/models/Area.ts +++ b/frontend/src/models/Area.ts @@ -4,6 +4,7 @@ export interface Area { id: string areaName: string plantCode: string + plantName: string installationCode: string deckName: string defaultLocalizationPose: Pose diff --git a/frontend/src/utils/icons.tsx b/frontend/src/utils/icons.tsx index 5933f671e..ef10515db 100644 --- a/frontend/src/utils/icons.tsx +++ b/frontend/src/utils/icons.tsx @@ -38,6 +38,7 @@ import { platform, library_add, play, + edit, } from '@equinor/eds-icons' Icon.add({ @@ -79,6 +80,7 @@ Icon.add({ platform, library_add, play, + edit, }) export enum Icons { @@ -120,4 +122,5 @@ export enum Icons { Platform = 'platform', LibraryAdd = 'library_add', PlayTriangle = 'play', + Edit = 'edit', }