From 03eff9814649bcd7e45cfef0895c53a1ede48d09 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:38:38 +0200 Subject: [PATCH 01/13] FIX-2467 Decreasing log fixes for curve data context menu options (#2468) --- .../Workers/Delete/DeleteCurveValuesWorker.cs | 24 +++++++++++++++--- .../ContentViews/CurveValuesView.tsx | 6 ++++- .../Workers/DeleteCurveValuesWorkerTest.cs | 25 ++++++++++++++++--- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Workers/Delete/DeleteCurveValuesWorker.cs b/Src/WitsmlExplorer.Api/Workers/Delete/DeleteCurveValuesWorker.cs index f3b6bd8db..022f2b98b 100644 --- a/Src/WitsmlExplorer.Api/Workers/Delete/DeleteCurveValuesWorker.cs +++ b/Src/WitsmlExplorer.Api/Workers/Delete/DeleteCurveValuesWorker.cs @@ -76,10 +76,26 @@ private async Task GetLogHeader(string wellUid, string wellboreUid, s private static ICollection CreateDeleteQueries(DeleteCurveValuesJob job, WitsmlLog witsmlLog, List logCurveInfos) { - return job.IndexRanges.ToList().Select(range => (Index.Start(witsmlLog, range.StartIndex), Index.End(witsmlLog, range.EndIndex))) - .Where(range => range.Item1 >= Index.Start(witsmlLog) && range.Item2 <= Index.End(witsmlLog)) - .Select(range => LogQueries.DeleteLogCurveContent(job.LogReference.WellUid, job.LogReference.WellboreUid, job.LogReference.Uid, witsmlLog.IndexType, - logCurveInfos, range.Item1, range.Item2)).ToList(); + var isDecreasing = witsmlLog.Direction == WitsmlLog.WITSML_DIRECTION_DECREASING; + Index logStart = Index.Start(witsmlLog); + Index logEnd = Index.End(witsmlLog); + return job.IndexRanges + .Select(range => ( + Start: Index.Start(witsmlLog, range.StartIndex), + End: Index.End(witsmlLog, range.EndIndex) + )) + .Where(range => isDecreasing + ? range.Start <= logStart && range.End >= logEnd + : range.Start >= logStart && range.End <= logEnd) + .Select(range => LogQueries.DeleteLogCurveContent( + job.LogReference.WellUid, + job.LogReference.WellboreUid, + job.LogReference.Uid, + witsmlLog.IndexType, + logCurveInfos, + range.Start, + range.End)) + .ToList(); } } } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx index 177c4f413..b90f409c3 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx @@ -658,12 +658,16 @@ const getIndexRanges = ( tableData: CurveValueRow[], selectedLog: LogObject ): IndexRange[] => { + const isDecreasing = + selectedLog.direction === WITSML_LOG_ORDERTYPE_DECREASING; const sortedItems = checkedContentItems.sort((a, b) => { const idA = selectedLog.indexType === "datetime" ? new Date(a.id) : Number(a.id); const idB = selectedLog.indexType === "datetime" ? new Date(b.id) : Number(b.id); - return idA < idB ? -1 : idA > idB ? 1 : 0; + if (idA < idB) return isDecreasing ? 1 : -1; + if (idA > idB) return isDecreasing ? -1 : 1; + return 0; }); const indexCurve = selectedLog.indexCurve; const idList = tableData.map((row) => String(row[indexCurve])); diff --git a/Tests/WitsmlExplorer.Api.Tests/Workers/DeleteCurveValuesWorkerTest.cs b/Tests/WitsmlExplorer.Api.Tests/Workers/DeleteCurveValuesWorkerTest.cs index 0cb825351..82d8b9ccd 100644 --- a/Tests/WitsmlExplorer.Api.Tests/Workers/DeleteCurveValuesWorkerTest.cs +++ b/Tests/WitsmlExplorer.Api.Tests/Workers/DeleteCurveValuesWorkerTest.cs @@ -115,6 +115,24 @@ public async Task SingleIndexRange_ShouldRunSingleDeleteQuery() Assert.True(result.IsSuccess); } + [Fact] + public async Task SingleIndexRangeDecreasing_ShouldRunSingleDeleteQuery() + { + SetupLog(WitsmlLog.WITSML_INDEX_TYPE_MD, new DepthIndex(100), new DepthIndex(10), WitsmlLog.WITSML_DIRECTION_DECREASING); + DeleteCurveValuesJob job = CreateJobTemplate() with + { + IndexRanges = new List + { + new() {StartIndex = "20", EndIndex = "10"}, + } + }; + (WorkerResult result, RefreshAction _) = await _worker.Execute(job); + + _witsmlClient.Verify(client => client.GetFromStoreAsync(It.IsAny(), It.Is((ops) => ops.ReturnElements == ReturnElements.HeaderOnly)), Times.Once); + _witsmlClient.Verify(client => client.DeleteFromStoreAsync(It.Is(logs => logs.Logs.First().StartIndex.Value == "20" && logs.Logs.First().EndIndex.Value == "10")), Times.Once()); + Assert.True(result.IsSuccess); + } + [Fact] public async Task TwoIndexRanges_ShouldRunTwoDeleteQueries_DepthIndexed() { @@ -216,11 +234,11 @@ public async Task IndexRangeOutsideLogIndex_ShouldNotRunAnyDeleteQueries_TimeInd } - private void SetupLog(string indexType, Index startIndex, Index endIndex) + private void SetupLog(string indexType, Index startIndex, Index endIndex, string direction = null) { _witsmlClient.Setup(client => client.GetFromStoreAsync(It.Is(witsmlLogs => witsmlLogs.Logs.First().Uid == LogUid), It.Is((ops) => ops.ReturnElements == ReturnElements.HeaderOnly))) - .ReturnsAsync(GetLogs(indexType, startIndex, endIndex)); + .ReturnsAsync(GetLogs(indexType, startIndex, endIndex, direction)); _witsmlClient.Setup(client => client.GetFromStoreAsync(It.Is(witsmlLogs => witsmlLogs.Logs.First().Uid != LogUid), It.Is((ops) => ops.ReturnElements == ReturnElements.HeaderOnly))) @@ -231,7 +249,7 @@ private void SetupLog(string indexType, Index startIndex, Index endIndex) .ReturnsAsync(new QueryResult(true)); } - private static WitsmlLogs GetLogs(string indexType, Index startIndex, Index endIndex) + private static WitsmlLogs GetLogs(string indexType, Index startIndex, Index endIndex, string direction) { WitsmlLog witsmlLog = new() { @@ -239,6 +257,7 @@ private static WitsmlLogs GetLogs(string indexType, Index startIndex, Index endI UidWellbore = WellboreUid, Uid = LogUid, IndexType = indexType, + Direction = direction, LogCurveInfo = new List { new() {Mnemonic = "DEPTH"}, From 3323990164b13f955ae36aa223c2ebd9933ad38c Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:43:28 +0200 Subject: [PATCH 02/13] FIX-502 Issue warning when importing overlapping data (#2466) --- .../components/Modals/LogDataImportModal.tsx | 120 +++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx index f0415571c..152f51bc0 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx @@ -1,11 +1,18 @@ import { Accordion, Icon, List } from "@equinor/eds-core-react"; import { Button, Tooltip, Typography } from "@mui/material"; +import { WITSML_INDEX_TYPE_MD } from "components/Constants"; import { StyledAccordionHeader } from "components/Modals/LogComparisonModal"; import ModalDialog from "components/Modals/ModalDialog"; +import WarningBar from "components/WarningBar"; +import { useConnectedServer } from "contexts/connectedServerContext"; import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useGetComponents } from "hooks/query/useGetComponents"; +import { ComponentType } from "models/componentType"; +import { IndexRange } from "models/jobs/deleteLogCurveValuesJob"; import ImportLogDataJob from "models/jobs/importLogDataJob"; import ObjectReference from "models/jobs/objectReference"; +import LogCurveInfo from "models/logCurveInfo"; import LogObject from "models/logObject"; import { toObjectReference } from "models/objectOnWellbore"; import React, { useCallback, useContext, useState } from "react"; @@ -31,10 +38,19 @@ const LogDataImportModal = ( props: LogDataImportModalProps ): React.ReactElement => { const { targetLog } = props; + const { connectedServer } = useConnectedServer(); const { dispatchOperation, operationState: { colors } } = useContext(OperationContext); + const { components: logCurveInfoList, isFetching: isFetchingLogCurveInfo } = + useGetComponents( + connectedServer, + targetLog.wellUid, + targetLog.wellboreUid, + targetLog.uid, + ComponentType.Mnemonic + ); const [uploadedFile, setUploadedFile] = useState(null); const [uploadedFileData, setUploadedFileData] = useState([]); const [uploadedFileColumns, setUploadedFileColumns] = useState< @@ -43,6 +59,12 @@ const LogDataImportModal = ( const [error, setError] = useState(""); const [isLoading, setIsLoading] = useState(false); const separator = ","; + const hasOverlap = checkOverlap( + targetLog, + uploadedFileColumns, + uploadedFileData, + logCurveInfoList + ); const validate = (fileColumns: ImportColumn[]) => { setError(""); @@ -157,9 +179,12 @@ const LogDataImportModal = ( + {hasOverlap && ( + + )} } - confirmDisabled={!uploadedFile || !!error} + confirmDisabled={!uploadedFile || !!error || isFetchingLogCurveInfo} confirmText={"Import"} onSubmit={() => onSubmit()} isLoading={isLoading} @@ -186,4 +211,97 @@ const Container = styled.div` gap: 1.5rem; `; +const checkOverlap = ( + targetLog: LogObject, + uploadedFileColumns: ImportColumn[], + uploadedFileData: string[], + logCurveInfoList: LogCurveInfo[] +) => { + if (!uploadedFileColumns || !uploadedFileData || !logCurveInfoList) + return false; + const importDataRanges = getDataRanges( + targetLog, + uploadedFileColumns, + uploadedFileData + ); + + for (let index = 1; index < uploadedFileColumns.length; index++) { + const mnemonic = uploadedFileColumns[index].name; + const logCurveInfo = logCurveInfoList.find( + (lci) => lci.mnemonic === mnemonic + ); + const importDataRange = importDataRanges[index]; + if (logCurveInfo && importDataRange.startIndex) { + if (targetLog.indexType === WITSML_INDEX_TYPE_MD) { + if ( + Math.max( + parseFloat(importDataRange.startIndex), + parseFloat(logCurveInfo.minDepthIndex) + ) <= + Math.min( + parseFloat(importDataRange.endIndex), + parseFloat(logCurveInfo.maxDepthIndex) + ) + ) { + return true; + } + } else { + if ( + Math.max( + new Date(importDataRange.startIndex).valueOf(), + new Date(logCurveInfo.minDateTimeIndex).valueOf() + ) <= + Math.min( + new Date(importDataRange.endIndex).valueOf(), + new Date(logCurveInfo.maxDateTimeIndex).valueOf() + ) + ) { + return true; + } + } + } + } + return false; +}; + +const getDataRanges = ( + targetLog: LogObject, + uploadedFileColumns: ImportColumn[], + uploadedFileData: string[] +): IndexRange[] => { + const dataRanges: IndexRange[] = []; + + for (let index = 0; index < uploadedFileColumns.length; index++) { + const firstRowWithData = uploadedFileData.find((dataRow) => { + const data = dataRow.split(",")[index]; + if (data) return true; + }); + + const lastRowWithData = uploadedFileData.findLast((dataRow) => { + const data = dataRow.split(",")[index]; + if (data) return true; + }); + + const firstRowWithDataIndex = firstRowWithData?.split(",")[0]; + const lastRowWithDataIndex = lastRowWithData?.split(",")[0]; + + if ( + targetLog.indexType === WITSML_INDEX_TYPE_MD && + parseFloat(firstRowWithDataIndex) > parseFloat(lastRowWithDataIndex) + ) { + dataRanges.push({ + startIndex: lastRowWithDataIndex, + endIndex: firstRowWithDataIndex + }); + } else { + dataRanges.push({ + startIndex: firstRowWithDataIndex, + endIndex: lastRowWithDataIndex + }); + } + } + + return dataRanges; +}; + export default LogDataImportModal; From c0ef02efd06940204720112685d872d3b98becf7 Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Tue, 11 Jun 2024 19:42:54 +0200 Subject: [PATCH 03/13] Confirm modal cancel job (#2469) --- .../components/ContentViews/JobsView.tsx | 49 ++++++++++++++++--- .../ContextMenus/JobInfoContextMenu.tsx | 18 ------- .../components/Modals/ConfirmModal.tsx | 2 + .../components/Modals/ModalDialog.tsx | 6 ++- .../components/Modals/ReportModal.tsx | 31 ++++++++++-- 5 files changed, 76 insertions(+), 30 deletions(-) diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx index 2bddbf1d9..81cac4dcc 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx @@ -10,6 +10,7 @@ import JobInfoContextMenu, { JobInfoContextMenuProps } from "components/ContextMenus/JobInfoContextMenu"; import formatDateString from "components/DateFormatter"; +import ConfirmModal from "components/Modals/ConfirmModal"; import { ReportModal } from "components/Modals/ReportModal"; import { generateReport } from "components/ReportCreationHelper"; import { Button } from "components/StyledComponents/Button"; @@ -20,6 +21,7 @@ import { useGetJobInfo } from "hooks/query/useGetJobInfo"; import { useGetServers } from "hooks/query/useGetServers"; import useExport from "hooks/useExport"; import JobStatus from "models/jobStatus"; +import JobInfo from "models/jobs/jobInfo"; import ReportType from "models/reportType"; import { Server } from "models/server"; import { @@ -50,6 +52,8 @@ export const JobsView = (): React.ReactElement => { const { exportData } = useExport(); + const [cancellingJobs, setCancellingJobs] = useState([]); + const onContextMenu = ( event: React.MouseEvent, selectedItem: any @@ -68,6 +72,27 @@ export const JobsView = (): React.ReactElement => { }); }; + const onClickCancel = async (jobId: string) => { + const confirmation = ( + Do you really want to cancel this job? + } + onConfirm={() => { + cancelJob(jobId); + }} + confirmColor={"danger"} + confirmText={"Yes"} + cancelText={"No"} + switchButtonPlaces={true} + /> + ); + dispatchOperation({ + type: OperationType.DisplayModal, + payload: confirmation + }); + }; const onClickReport = async (jobId: string) => { const report = await JobService.getReport(jobId); if (report.downloadImmediately === true) { @@ -89,6 +114,15 @@ export const JobsView = (): React.ReactElement => { } }; + const getJobStatus = (jobInfo: JobInfo, cancellingJobs: string[]) => { + const isCancelling = cancellingJobs.includes(jobInfo.id); + if (jobInfo.status === JobStatus.Started) { + if (isCancelling) return "Cancelling"; + if (jobInfo.progress) return `${Math.round(jobInfo.progress * 100)}%`; + } + return jobInfo.status; + }; + const columns: ContentTableColumn[] = [ { property: "startTime", label: "Start time", type: ContentType.DateTime }, { property: "jobType", label: "Job Type", type: ContentType.String }, @@ -127,7 +161,9 @@ export const JobsView = (): React.ReactElement => { const cancelJob = async (jobId: string) => { dispatchOperation({ type: OperationType.HideContextMenu }); - JobService.cancelJob(jobId); + dispatchOperation({ type: OperationType.HideModal }); + setCancellingJobs((jobs) => [...jobs, jobId]); + await JobService.cancelJob(jobId); }; const jobInfoRows = useMemo( @@ -140,17 +176,16 @@ export const JobsView = (): React.ReactElement => { wellName: jobInfo.wellName, wellboreName: jobInfo.wellboreName, objectName: jobInfo.objectName, - status: - jobInfo.progress && jobInfo.status === JobStatus.Started - ? `${Math.round(jobInfo.progress * 100)}%` - : jobInfo.status, + status: getJobStatus(jobInfo, cancellingJobs), cancel: - jobInfo.isCancelable === true && jobInfo.status === "Started" ? ( + jobInfo.isCancelable === true && + jobInfo.status === JobStatus.Started && + !cancellingJobs.includes(jobInfo.id) ? ( diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/JobInfoContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/JobInfoContextMenu.tsx index 3fb60bc3c..d20b6b7e4 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/JobInfoContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/JobInfoContextMenu.tsx @@ -10,10 +10,8 @@ import { } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { refreshJobInfoQuery } from "hooks/query/queryRefreshHelpers"; -import JobStatus from "models/jobStatus"; import JobInfo from "models/jobs/jobInfo"; import React from "react"; -import JobService from "services/jobService"; import { colors } from "styles/Colors"; export interface JobInfoContextMenuProps { @@ -38,11 +36,6 @@ const JobInfoContextMenu = ( }); }; - const onClickCancelAction = async () => { - dispatchOperation({ type: OperationType.HideContextMenu }); - JobService.cancelJob(jobInfo.id); - }; - return ( Refresh , - - - Cancel job - , , { @@ -19,6 +20,7 @@ const ConfirmModal = (props: ConfirmProps): React.ReactElement => { onSubmit={props.onConfirm} isLoading={false} confirmText={props.confirmText ?? "Yes"} + cancelText={props.cancelText} confirmColor={props.confirmColor} switchButtonPlaces={props.switchButtonPlaces} showCancelButton={props.showCancelButton} diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx index da023bf0e..87743cdb0 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx @@ -25,6 +25,7 @@ interface ModalDialogProps { showConfirmButton?: boolean; showCancelButton?: boolean; buttonPosition?: ControlButtonPosition; + cancelText?: string; } const ModalDialog = (props: ModalDialogProps): React.ReactElement => { @@ -42,7 +43,8 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { width = ModalWidth.MEDIUM, showConfirmButton = true, showCancelButton = true, - buttonPosition: ButtonPosition = ControlButtonPosition.BOTTOM + buttonPosition: ButtonPosition = ControlButtonPosition.BOTTOM, + cancelText } = props; const context = React.useContext(OperationContext); const [confirmButtonIsFocused, setConfirmButtonIsFocused] = @@ -101,7 +103,7 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { color={confirmColor ?? "primary"} variant="outlined" > - Cancel + {cancelText ?? "Cancel"} ) : ( <> diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx index 8d3253db1..41de8abb3 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx @@ -26,6 +26,7 @@ import JobService from "services/jobService"; import NotificationService from "services/notificationService"; import styled from "styled-components"; import { Colors } from "styles/Colors"; +import ConfirmModal from "./ConfirmModal"; export interface ReportModal { report?: BaseReport; @@ -85,9 +86,32 @@ export const ReportModal = (props: ReportModal): React.ReactElement => { [report] ); - const onCancelButtonClick = () => { - JobService.cancelJob(jobId); + const cancelJob = async (jobId: string) => { + dispatchOperation({ type: OperationType.HideContextMenu }); dispatchOperation({ type: OperationType.HideModal }); + await JobService.cancelJob(jobId); + }; + + const onClickCancel = async () => { + const confirmation = ( + Do you really want to cancel this job? + } + onConfirm={() => { + cancelJob(jobId); + }} + confirmColor={"danger"} + confirmText={"Yes"} + cancelText={"No"} + switchButtonPlaces={true} + /> + ); + dispatchOperation({ + type: OperationType.DisplayModal, + payload: confirmation + }); }; return ( @@ -96,6 +120,7 @@ export const ReportModal = (props: ReportModal): React.ReactElement => { heading={report ? report.title : "Loading report..."} confirmText="Ok" showCancelButton={!fetchedReport && isCancelable} + cancelText="Cancel job" content={ {report ? ( @@ -173,7 +198,7 @@ export const ReportModal = (props: ReportModal): React.ReactElement => { } onSubmit={() => dispatchOperation({ type: OperationType.HideModal })} - onCancel={() => onCancelButtonClick()} + onCancel={() => onClickCancel()} isLoading={false} /> ); From 606f97edfffd3c571dfeadd43d3d973cea3d67b1 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:47:27 +0200 Subject: [PATCH 04/13] FIX-2473 Enable search bar & command palette (#2474) --- Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx index be770372e..1faf52684 100644 --- a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx +++ b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx @@ -1,5 +1,7 @@ import "ace-builds/src-noconflict/ace"; import "ace-builds/src-noconflict/ext-language_tools"; +import "ace-builds/src-noconflict/ext-prompt"; +import "ace-builds/src-noconflict/ext-searchbox"; import "ace-builds/src-noconflict/mode-xml"; import "ace-builds/src-noconflict/theme-merbivore"; import "ace-builds/src-noconflict/theme-xcode"; From c1781ec4e849352a6e3f7a5c4194d1cf6b593541 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:16:47 +0200 Subject: [PATCH 05/13] FIX-2137 OperationContext Cleanup (#2472) --- .../components/Alerts.tsx | 6 +- .../components/ApplicationVersion.tsx | 6 +- .../components/Breadcrumbs.tsx | 6 +- .../ContentViews/BhaRunsListView.tsx | 6 +- .../ContentViews/ChangeLogsListView.tsx | 5 +- .../ContentViews/Charts/LogsGraph.tsx | 8 +- .../ContentViews/CurveValuesPlot.tsx | 4 +- .../ContentViews/CurveValuesView.tsx | 5 +- .../components/ContentViews/EditNumber.tsx | 6 +- .../ContentViews/EditSelectedLogCurveInfo.tsx | 5 +- .../components/ContentViews/ErrorView.tsx | 5 +- .../ContentViews/FluidsReportListView.tsx | 6 +- .../components/ContentViews/FluidsView.tsx | 6 +- .../ContentViews/FormationMarkersListView.tsx | 8 +- .../components/ContentViews/JobsView.tsx | 6 +- .../ContentViews/LogCurveInfoListView.tsx | 8 +- .../components/ContentViews/LogsListView.tsx | 6 +- .../ContentViews/MessagesListView.tsx | 6 +- .../components/ContentViews/MudLogView.tsx | 6 +- .../ContentViews/MudLogsListView.tsx | 6 +- .../ContentViews/MultiLogCurveValuesView.tsx | 6 +- .../MultiLogsCurveInfoListView.tsx | 8 +- .../ContentViews/ObjectSearchListView.tsx | 4 +- .../components/ContentViews/QueryView.tsx | 4 +- .../components/ContentViews/RigsListView.tsx | 6 +- .../components/ContentViews/RisksListView.tsx | 6 +- .../components/ContentViews/ServerManager.tsx | 8 +- .../ContentViews/TrajectoriesListView.tsx | 6 +- .../ContentViews/TrajectoryView.tsx | 8 +- .../components/ContentViews/TubularView.tsx | 6 +- .../ContentViews/TubularsListView.tsx | 6 +- .../components/ContentViews/ViewNotFound.tsx | 5 +- .../ContentViews/WbGeometriesListView.tsx | 6 +- .../ContentViews/WbGeometryView.tsx | 6 +- .../ContentViews/WellboreSearchListView.tsx | 4 +- .../ContentViews/WellboresListView.tsx | 6 +- .../components/ContentViews/WellsListView.tsx | 6 +- .../ContentViews/table/ColumnDef.tsx | 6 +- .../ContentViews/table/ColumnOptionsMenu.tsx | 12 +- .../ContentViews/table/ContentTable.tsx | 6 +- .../components/ContentViews/table/Panel.tsx | 6 +- .../ContentViews/table/SortableEdsTable.tsx | 6 +- .../ContextMenus/BatchModifyMenuItem.tsx | 6 +- .../ContextMenus/BhaRunContextMenu.tsx | 6 +- .../components/ContextMenus/ContextMenu.tsx | 6 +- .../ContextMenus/ContextMenuPresenter.tsx | 6 +- .../ContextMenus/CopyComponentsToServer.tsx | 5 +- .../CopyComponentsToServerUtils.tsx | 6 +- .../ContextMenus/FluidContextMenu.tsx | 6 +- .../ContextMenus/FluidsReportContextMenu.tsx | 6 +- .../FormationMarkerContextMenu.tsx | 6 +- .../GeologyIntervalContextMenu.tsx | 6 +- .../LogCurvePriorityContextMenu.tsx | 6 +- .../ContextMenus/LogObjectContextMenu.tsx | 6 +- .../ContextMenus/MessageObjectContextMenu.tsx | 6 +- .../ContextMenus/MnemonicsContextMenu.tsx | 6 +- .../ContextMenus/MudLogContextMenu.tsx | 6 +- .../ContextMenus/NestedMenuItem.tsx | 11 +- .../ObjectsSidebarContextMenu.tsx | 6 +- .../ContextMenus/RigContextMenu.tsx | 6 +- .../ContextMenus/RigsContextMenu.tsx | 6 +- .../ContextMenus/RiskContextMenu.tsx | 6 +- .../ContextMenus/TrajectoriesContextMenu.tsx | 6 +- .../ContextMenus/TrajectoryContextMenu.tsx | 6 +- .../TrajectoryStationContextMenu.tsx | 6 +- .../TubularComponentContextMenu.tsx | 6 +- .../ContextMenus/TubularContextMenu.tsx | 6 +- .../ContextMenus/TubularsContextMenu.tsx | 6 +- .../ContextMenus/WbGeometryContextMenu.tsx | 6 +- .../WbGeometrySectionContextMenu.tsx | 6 +- .../ContextMenus/WellboreContextMenu.tsx | 6 +- .../components/GlobalStyles.tsx | 10 ++ .../components/Modals/AnalyzeGapModal.tsx | 6 +- .../Modals/BatchModifyPropertiesModal.tsx | 6 +- .../Modals/BhaRunPropertiesModal.tsx | 6 +- .../components/Modals/CompareLogDataModal.tsx | 6 +- .../components/Modals/CopyMnemonicsModal.tsx | 18 +-- .../components/Modals/CopyRangeModal.tsx | 6 +- .../Modals/DeleteEmptyMnemonicsModal.tsx | 6 +- .../Modals/FormationMarkerPropertiesModal.tsx | 12 +- .../Modals/GeologyIntervalPropertiesModal.tsx | 5 +- .../components/Modals/LogComparisonModal.tsx | 6 +- .../Modals/LogCurveInfoBatchUpdateModal.tsx | 6 +- .../Modals/LogCurvePriorityModal.tsx | 6 +- .../components/Modals/LogDataImportModal.tsx | 6 +- .../Modals/LogHeaderDateTimeField.tsx | 6 +- .../components/Modals/LogPropertiesModal.tsx | 6 +- .../Modals/MessageComparisonModal.tsx | 6 +- .../Modals/MessagePropertiesModal.tsx | 6 +- .../Modals/MissingDataAgentModal.tsx | 6 +- .../components/Modals/ModalDialog.tsx | 4 +- .../components/Modals/ModalPresenter.tsx | 6 +- .../Modals/MudLogPropertiesModal.tsx | 6 +- .../components/Modals/ObjectPickerModal.tsx | 6 +- .../components/Modals/OffsetLogCurveModal.tsx | 6 +- .../components/Modals/ReportModal.tsx | 4 +- .../components/Modals/RigPropertiesModal.tsx | 6 +- .../components/Modals/RiskPropertiesModal.tsx | 6 +- .../Modals/SelectIndexToDisplayModal.tsx | 6 +- .../components/Modals/ServerModal.tsx | 5 +- .../components/Modals/SettingsModal.tsx | 6 +- .../Modals/ShowLogDataOnServerModal.tsx | 6 +- .../components/Modals/SpliceLogsModal.tsx | 5 +- .../Modals/TrajectoryPropertiesModal.tsx | 6 +- .../TrajectoryStationPropertiesModal.tsx | 6 +- .../TrimLogObject/TrimLogObjectModal.tsx | 6 +- .../Modals/UserCredentialsModal.tsx | 6 +- .../Modals/WbGeometryPropertiesModal.tsx | 6 +- .../components/Modals/WellPropertiesModal.tsx | 6 +- .../Modals/WellborePropertiesModal.tsx | 6 +- .../components/PageLayout.tsx | 5 +- .../components/PropertiesPanel.tsx | 6 +- .../components/QueryEditor.tsx | 5 +- .../components/Sidebar/FilterPanel.tsx | 4 +- .../components/Sidebar/LogItem.tsx | 6 +- .../components/Sidebar/LogTypeItem.tsx | 6 +- .../components/Sidebar/ObjectGroupItem.tsx | 4 +- .../Sidebar/ObjectOnWellboreItem.tsx | 6 +- .../components/Sidebar/SearchFilter.tsx | 6 +- .../components/Sidebar/Sidebar.tsx | 6 +- .../components/Sidebar/TreeItem.tsx | 8 +- .../components/Sidebar/WellItem.tsx | 6 +- .../components/Sidebar/WellboreItem.tsx | 8 +- .../components/StyledComponents/Button.tsx | 6 +- .../components/TopRightCornerMenu.tsx | 5 +- .../contexts/MuiThemeProvider.tsx | 18 +++ .../contexts/operationStateProvider.tsx | 108 ++++++++++++++ .../contexts/queryContext.tsx | 4 +- .../hooks/query/queryRefreshHelpers.tsx | 4 +- .../hooks/useOpenInQueryView.tsx | 4 +- .../hooks/useOperationState.tsx | 11 ++ .../routes/AuthRoute.tsx | 6 +- .../routes/ItemNotFound.tsx | 5 +- .../routes/PageNotFound.tsx | 5 +- Src/WitsmlExplorer.Frontend/routes/Root.tsx | 136 +++--------------- 135 files changed, 545 insertions(+), 527 deletions(-) create mode 100644 Src/WitsmlExplorer.Frontend/contexts/MuiThemeProvider.tsx create mode 100644 Src/WitsmlExplorer.Frontend/contexts/operationStateProvider.tsx create mode 100644 Src/WitsmlExplorer.Frontend/hooks/useOperationState.tsx diff --git a/Src/WitsmlExplorer.Frontend/components/Alerts.tsx b/Src/WitsmlExplorer.Frontend/components/Alerts.tsx index b8de98cf2..77ae16507 100644 --- a/Src/WitsmlExplorer.Frontend/components/Alerts.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Alerts.tsx @@ -2,9 +2,9 @@ import { Icon } from "@equinor/eds-core-react"; import { Alert, AlertTitle, Collapse } from "@mui/material"; import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; +import { useOperationState } from "hooks/useOperationState"; import { capitalize } from "lodash"; -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import NotificationService from "services/notificationService"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -21,7 +21,7 @@ const Alerts = (): React.ReactElement => { const { connectedServer } = useConnectedServer(); const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); useEffect(() => { const unsubscribeOnConnectionStateChanged = diff --git a/Src/WitsmlExplorer.Frontend/components/ApplicationVersion.tsx b/Src/WitsmlExplorer.Frontend/components/ApplicationVersion.tsx index 152bf378f..356f1f6be 100644 --- a/Src/WitsmlExplorer.Frontend/components/ApplicationVersion.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ApplicationVersion.tsx @@ -1,9 +1,9 @@ import { EdsProvider, Typography } from "@equinor/eds-core-react"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; +import { useOperationState } from "hooks/useOperationState"; import JobStatus from "models/jobStatus"; -import { useCallback, useContext, useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import JobService from "services/jobService"; import NotificationService from "services/notificationService"; import styled from "styled-components"; @@ -58,7 +58,7 @@ interface UpdateStatus { function DesktopUpdateStatus() { const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const [updateStatus, setUpdateStatus] = useState(null); useEffect(() => { diff --git a/Src/WitsmlExplorer.Frontend/components/Breadcrumbs.tsx b/Src/WitsmlExplorer.Frontend/components/Breadcrumbs.tsx index 635620dc8..c09036f99 100644 --- a/Src/WitsmlExplorer.Frontend/components/Breadcrumbs.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Breadcrumbs.tsx @@ -1,10 +1,10 @@ import { Breadcrumbs as EdsBreadcrumbs } from "@equinor/eds-core-react"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetObject } from "hooks/query/useGetObject"; import { useGetWell } from "hooks/query/useGetWell"; import { useGetWellbore } from "hooks/query/useGetWellbore"; import { useGetActiveRoute } from "hooks/useGetActiveRoute"; +import { useOperationState } from "hooks/useOperationState"; import { capitalize } from "lodash"; import { ObjectType, @@ -14,7 +14,7 @@ import { import { Server } from "models/server"; import Well from "models/well"; import Wellbore from "models/wellbore"; -import { useContext, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { NavLink, NavigateFunction, @@ -42,7 +42,7 @@ import { v4 as uuid } from "uuid"; export function Breadcrumbs() { const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const navigate = useNavigate(); const { isJobsView, diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/BhaRunsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/BhaRunsListView.tsx index 8456c817d..5cb846d35 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/BhaRunsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/BhaRunsListView.tsx @@ -9,13 +9,13 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import BhaRun from "models/bhaRun"; import { ObjectType } from "models/objectType"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useParams } from "react-router-dom"; export interface BhaRunRow extends ContentTableRow, BhaRun { @@ -26,7 +26,7 @@ export default function BhaRunsListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid } = useParams(); const { connectedServer } = useConnectedServer(); const { objects: bhaRuns } = useGetObjects( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/ChangeLogsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/ChangeLogsListView.tsx index 40e02906a..9b0b97f86 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/ChangeLogsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/ChangeLogsListView.tsx @@ -5,17 +5,16 @@ import { } from "components/ContentViews/table"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; -import { useContext } from "react"; import { useParams } from "react-router-dom"; export default function ChangeLogsListView() { const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid } = useParams(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/Charts/LogsGraph.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/Charts/LogsGraph.tsx index 0572d96de..79d6c7e2d 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/Charts/LogsGraph.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/Charts/LogsGraph.tsx @@ -4,6 +4,7 @@ import { CustomSeriesRenderItemAPI, CustomSeriesRenderItemParams } from "echarts"; +import { useOperationState } from "hooks/useOperationState"; import { ReactEChartsProps, @@ -11,10 +12,9 @@ import { } from "components/ContentViews/Charts/ReactLogChart"; import { ContentTableRow } from "components/ContentViews/table"; import formatDateString from "components/DateFormatter"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat } from "contexts/operationStateReducer"; import LogObject from "models/logObject"; -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; @@ -57,11 +57,11 @@ export const LogsGraph = (props: LogsGraphProps): React.ReactElement => { const categories: number[] = []; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const { logs } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const { logType } = useParams(); const isTimeIndexed = logType === RouterLogType.TIME; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx index 5b7209379..a16084d24 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx @@ -4,10 +4,10 @@ import { } from "components/ContentViews/table"; import formatDateString from "components/DateFormatter"; import { ContentViewDimensionsContext } from "components/PageLayout"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat, TimeZone } from "contexts/operationStateReducer"; import { ECharts } from "echarts"; import ReactEcharts from "echarts-for-react"; +import { useOperationState } from "hooks/useOperationState"; import { CurveSpecification } from "models/logData"; import React, { useContext, useEffect, useRef, useState } from "react"; import { useParams } from "react-router-dom"; @@ -46,7 +46,7 @@ export const CurveValuesPlot = React.memo( ); const { operationState: { colors, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const chart = useRef(null); const selectedLabels = useRef>(null); const scrollIndex = useRef(0); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx index b90f409c3..74dab7310 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx @@ -30,7 +30,6 @@ import { ShowLogDataOnServerModal } from "components/Modals/ShowLogDataOnServerM import ProgressSpinner from "components/ProgressSpinner"; import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DispatchOperation, UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -38,6 +37,7 @@ import { useGetObject } from "hooks/query/useGetObject"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; import useExport from "hooks/useExport"; import { useGetMnemonics } from "hooks/useGetMnemonics"; +import { useOperationState } from "hooks/useOperationState"; import orderBy from "lodash/orderBy"; import { ComponentType } from "models/componentType"; import { IndexRange } from "models/jobs/deleteLogCurveValuesJob"; @@ -48,7 +48,6 @@ import { ObjectType } from "models/objectType"; import React, { CSSProperties, useCallback, - useContext, useEffect, useMemo, useRef, @@ -90,7 +89,7 @@ export const CurveValuesView = (): React.ReactElement => { const { operationState: { timeZone, dateTimeFormat, colors, theme }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [searchParams, setSearchParams] = useSearchParams(); const mnemonicsSearchParams = searchParams.get("mnemonics"); const startIndex = searchParams.get("startIndex"); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/EditNumber.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/EditNumber.tsx index 552494ca4..2d8f0a4a7 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/EditNumber.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/EditNumber.tsx @@ -1,8 +1,8 @@ import { Icon, Label, TextField } from "@equinor/eds-core-react"; import { Tooltip } from "@mui/material"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; -import { ChangeEvent, ReactElement, useContext, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { ChangeEvent, ReactElement, useState } from "react"; import styled from "styled-components"; import { TooltipLayout } from "../StyledComponents/Tooltip"; @@ -24,7 +24,7 @@ const EditNumber = (props: EditNumberProps): ReactElement => { } = props; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const [isEdited, setIsEdited] = useState(false); const [value, setValue] = useState(String(defaultValue)); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/EditSelectedLogCurveInfo.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/EditSelectedLogCurveInfo.tsx index e13d320f3..b8a34e0ff 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/EditSelectedLogCurveInfo.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/EditSelectedLogCurveInfo.tsx @@ -11,17 +11,16 @@ import formatDateString, { } from "components/DateFormatter"; import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat, TimeZone } from "contexts/operationStateReducer"; import { useGetComponents } from "hooks/query/useGetComponents"; import { useGetMnemonics } from "hooks/useGetMnemonics"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { CSSProperties, ChangeEvent, Dispatch, SetStateAction, - useContext, useEffect, useState } from "react"; @@ -49,7 +48,7 @@ const EditSelectedLogCurveInfo = ( ): React.ReactElement => { const { disabled, overrideStartIndex, overrideEndIndex, onClickRefresh } = props; - const { operationState } = useContext(OperationContext); + const { operationState } = useOperationState(); const { theme, colors, timeZone } = operationState; const { wellUid, wellboreUid, logType, objectUid } = useParams(); const isTimeLog = logType === RouterLogType.TIME; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/ErrorView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/ErrorView.tsx index c0c97205a..8d2784864 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/ErrorView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/ErrorView.tsx @@ -1,6 +1,5 @@ -import { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; import styled from "styled-components"; -import OperationContext from "../../contexts/operationContext"; import { useErrorMessage } from "../../hooks/useErrorMessage"; import { Colors } from "../../styles/Colors"; import Icon from "../../styles/Icons"; @@ -9,7 +8,7 @@ export function ErrorView() { const errorMessage = useErrorMessage(); const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); return ( <> diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx index c304dace5..75be91593 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx @@ -9,14 +9,14 @@ import FluidsReportContextMenu from "components/ContextMenus/FluidsReportContext import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import FluidsReport from "models/fluidsReport"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useNavigate, useParams } from "react-router-dom"; export interface FluidsReportRow extends ContentTableRow, FluidsReport { @@ -27,7 +27,7 @@ export default function FluidsReportsListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { connectedServer } = useConnectedServer(); const { wellUid, wellboreUid } = useParams(); const navigate = useNavigate(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx index 4ebf9acce..1faddc987 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx @@ -10,16 +10,16 @@ import FluidContextMenu, { } from "components/ContextMenus/FluidContextMenu"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; import { useGetObject } from "hooks/query/useGetObject"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import Fluid from "models/fluid"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; @@ -32,7 +32,7 @@ interface FluidsRow extends ContentTableRow, FluidAsStrings { } export default function FluidsView() { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { wellUid, wellboreUid, objectUid } = useParams(); const { connectedServer } = useConnectedServer(); const { object: fluidsReport } = useGetObject( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FormationMarkersListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FormationMarkersListView.tsx index b5fc406cd..72d482a5d 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FormationMarkersListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FormationMarkersListView.tsx @@ -9,15 +9,15 @@ import FormationMarkerContextMenu from "components/ContextMenus/FormationMarkerC import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import FormationMarker from "models/formationMarker"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; import StratigraphicStruct from "models/stratigraphicStruct"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useParams } from "react-router-dom"; export interface FormationMarkerRow extends ContentTableRow { @@ -27,8 +27,8 @@ export interface FormationMarkerRow extends ContentTableRow { export default function FormationMarkersListView() { const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); - const { dispatchOperation } = useContext(OperationContext); + } = useOperationState(); + const { dispatchOperation } = useOperationState(); const { connectedServer } = useConnectedServer(); const { wellUid, wellboreUid } = useParams(); const { objects: formationMarkers } = useGetObjects( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx index 81cac4dcc..18c7fe122 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/JobsView.tsx @@ -14,12 +14,12 @@ import ConfirmModal from "components/Modals/ConfirmModal"; import { ReportModal } from "components/Modals/ReportModal"; import { generateReport } from "components/ReportCreationHelper"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { refreshJobInfoQuery } from "hooks/query/queryRefreshHelpers"; import { useGetJobInfo } from "hooks/query/useGetJobInfo"; import { useGetServers } from "hooks/query/useGetServers"; import useExport from "hooks/useExport"; +import { useOperationState } from "hooks/useOperationState"; import JobStatus from "models/jobStatus"; import JobInfo from "models/jobs/jobInfo"; import ReportType from "models/reportType"; @@ -30,7 +30,7 @@ import { getUserAppRoles, msalEnabled } from "msal/MsalAuthProvider"; -import React, { ChangeEvent, useContext, useMemo, useState } from "react"; +import React, { ChangeEvent, useMemo, useState } from "react"; import JobService from "services/jobService"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -39,7 +39,7 @@ export const JobsView = (): React.ReactElement => { const { dispatchOperation, operationState: { timeZone, colors, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const queryClient = useQueryClient(); const { servers } = useGetServers(); const [showAll, setShowAll] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx index f4aa9cdf6..1d039ed6c 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx @@ -8,17 +8,17 @@ import ProgressSpinner from "components/ProgressSpinner"; import { CommonPanelContainer } from "components/StyledComponents/Container"; import { useConnectedServer } from "contexts/connectedServerContext"; import { useCurveThreshold } from "contexts/curveThresholdContext"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; import { useGetObject } from "hooks/query/useGetObject"; import { useGetServers } from "hooks/query/useGetServers"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; import { RouterLogType } from "routes/routerConstants"; @@ -34,8 +34,8 @@ export default function LogCurveInfoListView() { const { curveThreshold } = useCurveThreshold(); const { operationState: { timeZone, dateTimeFormat, theme } - } = useContext(OperationContext); - const { dispatchOperation } = useContext(OperationContext); + } = useOperationState(); + const { dispatchOperation } = useOperationState(); const { wellUid, wellboreUid, logType, objectUid } = useParams(); const { connectedServer } = useConnectedServer(); const { servers } = useGetServers(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx index 83f6b4135..8eddec227 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx @@ -16,15 +16,15 @@ import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems" import formatDateString from "components/DateFormatter"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useGetWellbore } from "hooks/query/useGetWellbore"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import { MouseEvent, useContext, useState } from "react"; +import { MouseEvent, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; import { RouterLogType } from "routes/routerConstants"; @@ -42,7 +42,7 @@ export default function LogsListView() { const { dispatchOperation, operationState: { timeZone, dateTimeFormat, theme } - } = useContext(OperationContext); + } = useOperationState(); const [showGraph, setShowGraph] = useState(false); const [selectedRows, setSelectedRows] = useState([]); const navigate = useNavigate(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MessagesListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MessagesListView.tsx index 3527c533a..395b6936e 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MessagesListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MessagesListView.tsx @@ -9,13 +9,13 @@ import MessageObjectContextMenu from "components/ContextMenus/MessageObjectConte import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import MessageObject from "models/messageObject"; import { ObjectType } from "models/objectType"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useParams } from "react-router-dom"; export interface MessageObjectRow extends ContentTableRow { @@ -26,7 +26,7 @@ export default function MessagesListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid } = useParams(); const { connectedServer } = useConnectedServer(); const { objects: messages } = useGetObjects( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx index 3019a76c7..4a49c9113 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx @@ -10,16 +10,16 @@ import GeologyIntervalContextMenu, { } from "components/ContextMenus/GeologyIntervalContextMenu"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; import { useGetObject } from "hooks/query/useGetObject"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import GeologyInterval from "models/geologyInterval"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; @@ -43,7 +43,7 @@ export interface GeologyIntervalRow extends ContentTableRow { } export default function MudLogView() { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { wellUid, wellboreUid, objectUid } = useParams(); const { connectedServer } = useConnectedServer(); const { object: mudLog, isFetched: isFetchedMudLog } = useGetObject( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogsListView.tsx index 14721a487..ead398aa8 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogsListView.tsx @@ -9,14 +9,14 @@ import MudLogContextMenu from "components/ContextMenus/MudLogContextMenu"; import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { measureToString } from "models/measure"; import MudLog from "models/mudLog"; import { ObjectType } from "models/objectType"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useNavigate, useParams } from "react-router-dom"; export interface MudLogRow extends ContentTableRow { @@ -35,7 +35,7 @@ export default function MudLogsListView() { const { dispatchOperation, operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const navigate = useNavigate(); const { connectedServer } = useConnectedServer(); const { wellUid, wellboreUid } = useParams(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogCurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogCurveValuesView.tsx index 103a1870d..700352779 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogCurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogCurveValuesView.tsx @@ -10,14 +10,14 @@ import { import formatDateString from "components/DateFormatter"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { CurveSpecification, LogData, LogDataRow } from "models/logData"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import React, { useContext, useEffect, useRef, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useLocation, useParams, useSearchParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; import { truncateAbortHandler } from "services/apiClient"; @@ -34,7 +34,7 @@ interface CurveValueRow extends LogDataRow, ContentTableRow {} export const MultiLogCurveValuesView = (): React.ReactElement => { const { operationState: { timeZone, dateTimeFormat, theme } - } = useContext(OperationContext); + } = useOperationState(); const [searchParams] = useSearchParams(); const location = useLocation(); const mnemonicsSearchParams = searchParams.get("mnemonics"); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx index 8f3f8f18c..7e9c9bd03 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx @@ -4,13 +4,13 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import LogCurveInfoContextMenu, { LogCurveInfoContextMenuProps } from "components/ContextMenus/LogCurveInfoContextMenu"; +import { useOperationState } from "hooks/useOperationState"; import ProgressSpinner from "components/ProgressSpinner"; import { CommonPanelContainer } from "components/StyledComponents/Container"; import { useConnectedServer } from "contexts/connectedServerContext"; import { useCurveThreshold } from "contexts/curveThresholdContext"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; @@ -19,7 +19,7 @@ import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; import LogCurveInfo from "models/logCurveInfo"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { useParams, useSearchParams } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; import { truncateAbortHandler } from "services/apiClient"; @@ -35,8 +35,8 @@ export default function MultiLogsCurveInfoListView() { const { curveThreshold } = useCurveThreshold(); const { operationState: { timeZone, dateTimeFormat, theme } - } = useContext(OperationContext); - const { dispatchOperation } = useContext(OperationContext); + } = useOperationState(); + const { dispatchOperation } = useOperationState(); const { wellUid, wellboreUid, logType } = useParams(); const { connectedServer } = useConnectedServer(); const [logCurveInfoList, setLogCurveInfoList] = useState(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectSearchListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectSearchListView.tsx index 9463af73f..b2177438d 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectSearchListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectSearchListView.tsx @@ -23,10 +23,10 @@ import { ObjectFilterType, filterTypeToProperty } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import { MousePosition } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetObjectSearch } from "hooks/query/useGetObjectSearch"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; @@ -58,7 +58,7 @@ export interface ObjectSearchRow extends ContentTableRow, ObjectOnWellbore { export const ObjectSearchListView = (): ReactElement => { const { connectedServer } = useConnectedServer(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { selectedFilter, updateSelectedFilter } = useContext(FilterContext); const [searchParams] = useSearchParams(); const { filterType } = useParams<{ filterType: ObjectFilterType }>(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx index 3b82d3315..0a7c533a7 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx @@ -12,10 +12,10 @@ import { QueryEditor } from "components/QueryEditor"; import { getTag } from "components/QueryEditorUtils"; import { StyledNativeSelect } from "components/Select"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import { DispatchOperation } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { QueryActionType, QueryContext } from "contexts/queryContext"; +import { useOperationState } from "hooks/useOperationState"; import React, { ChangeEvent, useContext, useState } from "react"; import QueryService from "services/queryService"; import styled from "styled-components"; @@ -26,7 +26,7 @@ const QueryView = (): React.ReactElement => { const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { queryState: { queries, tabIndex }, dispatchQuery diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/RigsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/RigsListView.tsx index 6026412a9..9789c2bdf 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/RigsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/RigsListView.tsx @@ -9,13 +9,13 @@ import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems" import RigContextMenu from "components/ContextMenus/RigContextMenu"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import Rig from "models/rig"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useParams } from "react-router-dom"; export interface RigRow extends ContentTableRow, Rig { @@ -26,7 +26,7 @@ export default function RigsListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid } = useParams(); const { connectedServer } = useConnectedServer(); const { objects: rigs } = useGetObjects( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/RisksListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/RisksListView.tsx index 3e652fdba..215db894a 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/RisksListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/RisksListView.tsx @@ -9,13 +9,13 @@ import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems" import RiskObjectContextMenu from "components/ContextMenus/RiskContextMenu"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import RiskObject from "models/riskObject"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useParams } from "react-router-dom"; export interface RiskObjectRow extends ContentTableRow, RiskObject { @@ -26,7 +26,7 @@ export default function RisksListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid } = useParams(); const { connectedServer } = useConnectedServer(); const { objects: risks } = useGetObjects( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/ServerManager.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/ServerManager.tsx index 6eb7ddf7a..a08b91ebb 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/ServerManager.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/ServerManager.tsx @@ -18,12 +18,12 @@ import { useConnectedServer } from "contexts/connectedServerContext"; import { getSearchRegex } from "contexts/filter"; import { useLoggedInUsernames } from "contexts/loggedInUsernamesContext"; import { LoggedInUsernamesActionType } from "contexts/loggedInUsernamesReducer"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { Server, emptyServer } from "models/server"; import { adminRole, getUserAppRoles, msalEnabled } from "msal/MsalAuthProvider"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { getWellsViewPath } from "routes/utils/pathBuilder"; import AuthorizationService from "services/authorizationService"; @@ -44,7 +44,7 @@ const ServerManager = (): React.ReactElement => { const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const editDisabled = msalEnabled && !getUserAppRoles().includes(adminRole); const navigate = useNavigate(); const { connectedServer, setConnectedServer } = useConnectedServer(); @@ -269,7 +269,7 @@ const ConnectButton = ({ isConnected, ...props }: ConnectButtonProps) => { const [isHovered, setIsHovered] = React.useState(false); const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); return ( 404 Not Found diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx index 71e2cbf10..760496de9 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx @@ -9,14 +9,14 @@ import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems" import WbGeometryObjectContextMenu from "components/ContextMenus/WbGeometryContextMenu"; import formatDateString from "components/DateFormatter"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; import WbGeometryObject from "models/wbGeometry"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { useNavigate, useParams } from "react-router-dom"; export interface WbGeometryObjectRow extends ContentTableRow, WbGeometryObject { @@ -27,7 +27,7 @@ export default function WbGeometriesListView() { const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const navigate = useNavigate(); const { connectedServer } = useConnectedServer(); const { wellUid, wellboreUid } = useParams(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx index 58647fce7..0f3052703 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx @@ -10,16 +10,16 @@ import WbGeometrySectionContextMenu, { } from "components/ContextMenus/WbGeometrySectionContextMenu"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; import { useGetObject } from "hooks/query/useGetObject"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { measureToString } from "models/measure"; import { ObjectType } from "models/objectType"; import WbGeometrySection from "models/wbGeometrySection"; -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; @@ -28,7 +28,7 @@ interface WbGeometrySectionRow extends ContentTableRow { } export default function WbGeometryView() { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { wellUid, wellboreUid, objectUid } = useParams(); const { connectedServer } = useConnectedServer(); const { object: wbGeometry, isFetched: isFetchedWbGeometry } = useGetObject( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboreSearchListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboreSearchListView.tsx index 3ac4de14b..5fe3c097c 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboreSearchListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboreSearchListView.tsx @@ -17,11 +17,11 @@ import { WellboreFilterType, filterTypeToProperty } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import { MousePosition } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useGetWellboreSearch } from "hooks/query/useGetWellboreSearch"; +import { useOperationState } from "hooks/useOperationState"; import Well from "models/well"; import Wellbore from "models/wellbore"; import React, { ReactElement, useContext, useEffect } from "react"; @@ -37,7 +37,7 @@ export interface WellboreSearchRow extends ContentTableRow, Wellbore { export const WellboreSearchListView = (): ReactElement => { const { connectedServer } = useConnectedServer(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { selectedFilter, updateSelectedFilter } = useContext(FilterContext); const [searchParams] = useSearchParams(); const { filterType } = useParams<{ filterType: WellboreFilterType }>(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx index e33f3a5d8..a1a994b5d 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx @@ -11,15 +11,15 @@ import WellboreContextMenu, { import formatDateString from "components/DateFormatter"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useGetWell } from "hooks/query/useGetWell"; import { useGetWellbores } from "hooks/query/useGetWellbores"; import { useExpandSidebarNodes } from "hooks/useExpandObjectGroupNodes"; +import { useOperationState } from "hooks/useOperationState"; import EntityType from "models/entityType"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { useNavigate, useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; import { OBJECT_GROUPS_PATH } from "routes/routerConstants"; @@ -43,7 +43,7 @@ export default function WellboresListView() { const { dispatchOperation, operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const navigate = useNavigate(); useExpandSidebarNodes(wellUid); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx index 055bc9465..cdaec9146 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx @@ -12,12 +12,12 @@ import WellContextMenu, { import formatDateString from "components/DateFormatter"; import ProgressSpinner from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useGetWells } from "hooks/query/useGetWells"; +import { useOperationState } from "hooks/useOperationState"; import Well from "models/well"; -import React, { useContext } from "react"; +import React from "react"; import { useNavigate } from "react-router-dom"; import { WELLBORES_PATH } from "routes/routerConstants"; @@ -32,7 +32,7 @@ export default function WellsListView() { const { dispatchOperation, operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const navigate = useNavigate(); const columns: ContentTableColumn[] = [ diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnDef.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnDef.tsx index da2bc7516..7cfbc7593 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnDef.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnDef.tsx @@ -21,9 +21,9 @@ import { ContentType } from "components/ContentViews/table/tableParts"; import { getSearchRegex } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import { DecimalPreference, UserTheme } from "contexts/operationStateReducer"; -import { useContext, useMemo } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { useMemo } from "react"; import Icon from "styles/Icons"; import { STORAGE_CONTENTTABLE_ORDER_KEY, @@ -47,7 +47,7 @@ export const useColumnDef = ( ) => { const { operationState: { decimals, theme } - } = useContext(OperationContext); + } = useOperationState(); const isCompactMode = theme === UserTheme.Compact; return useMemo(() => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnOptionsMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnOptionsMenu.tsx index d7e599d38..0ddf32630 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnOptionsMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ColumnOptionsMenu.tsx @@ -18,17 +18,11 @@ import { ContentType } from "components/ContentViews/table/tableParts"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import { useLocalStorageState } from "hooks/useLocalStorageState"; +import { useOperationState } from "hooks/useOperationState"; import { debounce } from "lodash"; -import { - ChangeEvent, - useCallback, - useContext, - useEffect, - useState -} from "react"; +import { ChangeEvent, useCallback, useEffect, useState } from "react"; import { useSearchParams } from "react-router-dom"; import { checkIsUrlTooLong } from "routes/utils/checkIsUrlTooLong"; import styled from "styled-components"; @@ -65,7 +59,7 @@ export const ColumnOptionsMenu = (props: { } = props; const { operationState: { colors, theme } - } = useContext(OperationContext); + } = useOperationState(); const [draggedId, setDraggedId] = useState(); const [draggedOverId, setDraggedOverId] = useState(); const [isMenuOpen, setIsMenuOpen] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ContentTable.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ContentTable.tsx index fa8f498cc..859dd2589 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ContentTable.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/ContentTable.tsx @@ -45,11 +45,11 @@ import { ContentTableColumn, ContentTableProps } from "components/ContentViews/table/tableParts"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; +import { useOperationState } from "hooks/useOperationState"; import { indexToNumber } from "models/logObject"; import * as React from "react"; -import { Fragment, useContext, useEffect, useMemo, useState } from "react"; +import { Fragment, useEffect, useMemo, useState } from "react"; import { Colors } from "styles/Colors"; import Icon from "styles/Icons"; @@ -83,7 +83,7 @@ export const ContentTable = React.memo( } = contentTableProps; const { operationState: { colors, theme } - } = useContext(OperationContext); + } = useOperationState(); const [previousIndex, setPreviousIndex] = useState(null); const [rowSelection, setRowSelection] = useState( Object.assign( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/Panel.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/Panel.tsx index e09d98ef0..6ef2312bd 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/Panel.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/Panel.tsx @@ -3,7 +3,6 @@ import { useQueryClient } from "@tanstack/react-query"; import { Table } from "@tanstack/react-table"; import { ColumnOptionsMenu } from "components/ContentViews/table/ColumnOptionsMenu"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import { refreshObjectQuery, refreshObjectsQuery, @@ -11,8 +10,9 @@ import { refreshWellsQuery } from "hooks/query/queryRefreshHelpers"; import useExport, { encloseCell } from "hooks/useExport"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; -import React, { useCallback, useContext, useEffect } from "react"; +import React, { useCallback, useEffect } from "react"; import { useParams } from "react-router-dom"; import styled from "styled-components"; import Icon from "styles/Icons"; @@ -50,7 +50,7 @@ const Panel = (props: PanelProps) => { } = props; const { operationState: { theme } - } = useContext(OperationContext); + } = useOperationState(); const { exportData, exportOptions } = useExport(); const abortRefreshControllerRef = React.useRef(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/SortableEdsTable.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/SortableEdsTable.tsx index 135daf7c3..91ac4fd31 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/table/SortableEdsTable.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/table/SortableEdsTable.tsx @@ -1,6 +1,6 @@ import { CellProps, Table } from "@equinor/eds-core-react"; -import OperationContext from "contexts/operationContext"; -import { useCallback, useContext, useEffect, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { useCallback, useEffect, useState } from "react"; import styled from "styled-components"; import { Colors } from "styles/Colors"; import Icon from "styles/Icons"; @@ -37,7 +37,7 @@ const SortableEdsTable = (props: SortableEdsTableProps): React.ReactElement => { const { columns, data, caption } = props; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const initColumns = (): Column[] => columns.map((col) => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/BatchModifyMenuItem.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/BatchModifyMenuItem.tsx index 657b1c998..961c38129 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/BatchModifyMenuItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/BatchModifyMenuItem.tsx @@ -1,7 +1,7 @@ import { Typography } from "@equinor/eds-core-react"; import { MenuItem } from "@mui/material"; -import OperationContext from "contexts/operationContext"; -import { ReactElement, forwardRef, useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { ReactElement, forwardRef } from "react"; import OperationType from "../../contexts/operationType"; import ObjectOnWellbore from "../../models/objectOnWellbore"; import { ObjectType } from "../../models/objectType"; @@ -24,7 +24,7 @@ export interface BatchModifyMenuItemProps { export const BatchModifyMenuItem = forwardRef( (props: BatchModifyMenuItemProps, ref: React.Ref): ReactElement => { const { checkedObjects, objectType } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const batchModifyProperties = objectBatchModifyProperties[objectType]; const onSubmitBatchModify = async (batchUpdates: { diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/BhaRunContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/BhaRunContextMenu.tsx index 6099d5bc1..c77c4d863 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/BhaRunContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/BhaRunContextMenu.tsx @@ -12,20 +12,20 @@ import BhaRunPropertiesModal, { } from "components/Modals/BhaRunPropertiesModal"; import { PropertiesModalMode } from "components/Modals/ModalParts"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import BhaRun from "models/bhaRun"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const BhaRunContextMenu = ( props: ObjectContextMenuProps ): React.ReactElement => { const { checkedObjects } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { servers } = useGetServers(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenu.tsx index 7124fb666..8e8195335 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenu.tsx @@ -1,8 +1,8 @@ import { Menu } from "@mui/material"; -import OperationContext from "contexts/operationContext"; import { MousePosition } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; -import React, { ReactElement, useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import React, { ReactElement } from "react"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -25,7 +25,7 @@ export const getContextMenuPosition = ( }; const ContextMenu = (props: ContextMenuProps): React.ReactElement => { - const { operationState, dispatchOperation } = useContext(OperationContext); + const { operationState, dispatchOperation } = useOperationState(); const { contextMenu, colors } = operationState; const handleClose = () => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenuPresenter.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenuPresenter.tsx index 85c92bd90..532f0cab6 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenuPresenter.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ContextMenuPresenter.tsx @@ -1,8 +1,8 @@ -import React, { useContext } from "react"; -import OperationContext from "contexts/operationContext"; +import { useOperationState } from "hooks/useOperationState"; +import React from "react"; const ContextMenuPresenter = (): React.ReactElement => { - const { operationState } = useContext(OperationContext); + const { operationState } = useOperationState(); const { contextMenu } = operationState; return <>{contextMenu && contextMenu.component}; diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServer.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServer.tsx index bf097c6b8..f6f584beb 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServer.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServer.tsx @@ -6,14 +6,13 @@ import CopyRangeModal, { CopyRangeModalProps } from "components/Modals/CopyRangeModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import LogCurveInfo from "models/logCurveInfo"; import ObjectOnWellbore from "models/objectOnWellbore"; import { Server } from "models/server"; -import { useContext } from "react"; import { copyComponentsToServer } from "./CopyComponentsToServerUtils"; export interface CopyComponentsToServerMenuItemProps { @@ -38,7 +37,7 @@ export const CopyComponentsToServerMenuItem = ( } = props; const { connectedServer } = useConnectedServer(); const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const menuComponents = menuItemText("copy", componentType, componentsToCopy); const menuText = withRange === true diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServerUtils.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServerUtils.tsx index 12bf83d06..dd2ca69e2 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServerUtils.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/CopyComponentsToServerUtils.tsx @@ -21,12 +21,12 @@ import AuthorizationService from "../../services/authorizationService"; import ComponentService from "../../services/componentService"; import JobService, { JobType } from "../../services/jobService"; import ObjectService from "../../services/objectService"; -import { displayMissingObjectModal } from "../Modals/MissingObjectModals"; -import { displayReplaceModal } from "../Modals/ReplaceModal"; -import { pluralize } from "./ContextMenuUtils"; import CopyMnemonicsModal, { CopyMnemonicsModalProps } from "../Modals/CopyMnemonicsModal"; +import { displayMissingObjectModal } from "../Modals/MissingObjectModals"; +import { displayReplaceModal } from "../Modals/ReplaceModal"; +import { pluralize } from "./ContextMenuUtils"; export interface OnClickCopyComponentToServerProps { targetServer: Server; diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidContextMenu.tsx index 182f22cb9..739e86bc2 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidContextMenu.tsx @@ -15,15 +15,15 @@ import { import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import Fluid from "models/fluid"; import FluidsReport from "models/fluidsReport"; import { createComponentReferences } from "models/jobs/componentReferences"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import React, { useContext } from "react"; +import React from "react"; import { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -34,7 +34,7 @@ export interface FluidContextMenuProps { const FluidContextMenu = (props: FluidContextMenuProps): React.ReactElement => { const { checkedFluids, fluidsReport } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const fluidReferences = useClipboardComponentReferencesOfType( ComponentType.Fluid ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidsReportContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidsReportContextMenu.tsx index ebd702edf..aa1106357 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidsReportContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FluidsReportContextMenu.tsx @@ -13,12 +13,12 @@ import { } from "components/ContextMenus/ObjectMenuItems"; import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const FluidsReportContextMenu = ( @@ -26,7 +26,7 @@ const FluidsReportContextMenu = ( ): React.ReactElement => { const { checkedObjects } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const fluidReferences = useClipboardComponentReferencesOfType( ComponentType.Fluid diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FormationMarkerContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FormationMarkerContextMenu.tsx index 19bfe5e76..2a8c6eb74 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/FormationMarkerContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/FormationMarkerContextMenu.tsx @@ -11,20 +11,20 @@ import FormationMarkerPropertiesModal, { FormationMarkerPropertiesModalProps } from "components/Modals/FormationMarkerPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import FormationMarker from "models/formationMarker"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const FormationMarkerContextMenu = ( props: ObjectContextMenuProps ): React.ReactElement => { const { checkedObjects } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/GeologyIntervalContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/GeologyIntervalContextMenu.tsx index 94e34034d..ee8c768b2 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/GeologyIntervalContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/GeologyIntervalContextMenu.tsx @@ -14,14 +14,14 @@ import { import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import GeologyIntervalPropertiesModal from "components/Modals/GeologyIntervalPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import GeologyInterval from "models/geologyInterval"; import { createComponentReferences } from "models/jobs/componentReferences"; import MudLog from "models/mudLog"; -import React, { useContext } from "react"; +import React from "react"; import { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -34,7 +34,7 @@ const GeologyIntervalContextMenu = ( props: GeologyIntervalContextMenuProps ): React.ReactElement => { const { checkedGeologyIntervals, mudLog } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { servers } = useGetServers(); const { connectedServer } = useConnectedServer(); const geologyIntervalReferences = useClipboardComponentReferencesOfType( diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurvePriorityContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurvePriorityContextMenu.tsx index 1973e3d71..44f55e6ba 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurvePriorityContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurvePriorityContextMenu.tsx @@ -1,7 +1,7 @@ import { Typography } from "@equinor/eds-core-react"; import { MenuItem } from "@mui/material"; -import React, { useContext } from "react"; -import OperationContext from "../../contexts/operationContext"; +import { useOperationState } from "hooks/useOperationState"; +import React from "react"; import { MousePosition } from "../../contexts/operationStateReducer"; import { StyledMenu, preventContextMenuPropagation } from "./ContextMenu"; import { StyledIcon } from "./ContextMenuUtils"; @@ -17,7 +17,7 @@ export const LogCurvePriorityContextMenu = ( props: LogCurvePriorityContextMenuProps ): React.ReactElement => { const { onDelete, onClose, position, open } = props; - const { operationState } = useContext(OperationContext); + const { operationState } = useOperationState(); const { colors } = operationState; const onClickDelete = async () => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogObjectContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogObjectContextMenu.tsx index 068caa3ae..1fa929a2f 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogObjectContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogObjectContextMenu.tsx @@ -37,11 +37,11 @@ import { ReportModal } from "components/Modals/ReportModal"; import SpliceLogsModal from "components/Modals/SpliceLogsModal"; import TrimLogObjectModal from "components/Modals/TrimLogObject/TrimLogObjectModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DisplayModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import CheckLogHeaderJob from "models/jobs/checkLogHeaderJob"; import CompareLogDataJob from "models/jobs/compareLogData"; @@ -50,7 +50,7 @@ import LogObject from "models/logObject"; import ObjectOnWellbore, { toObjectReference } from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import React, { useContext } from "react"; +import React from "react"; import { createSearchParams, useNavigate } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; import { @@ -69,7 +69,7 @@ const LogObjectContextMenu = ( props: ObjectContextMenuProps ): React.ReactElement => { const { checkedObjects } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const logCurvesReference: CopyRangeClipboard = useClipboardComponentReferencesOfType(ComponentType.Mnemonic); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MessageObjectContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MessageObjectContextMenu.tsx index ca7e625ad..928e1ce53 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MessageObjectContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MessageObjectContextMenu.tsx @@ -21,22 +21,22 @@ import ObjectPickerModal, { ObjectPickerProps } from "components/Modals/ObjectPickerModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import MessageObject from "models/messageObject"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const MessageObjectContextMenu = ( props: ObjectContextMenuProps ): React.ReactElement => { const { checkedObjects } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MnemonicsContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MnemonicsContextMenu.tsx index b048ad90b..9d94f84e3 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MnemonicsContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MnemonicsContextMenu.tsx @@ -10,8 +10,8 @@ import { OffsetLogCurveModal, OffsetLogCurveModalProps } from "components/Modals/OffsetLogCurveModal"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { DeleteLogCurveValuesJob, @@ -19,7 +19,7 @@ import { } from "models/jobs/deleteLogCurveValuesJob"; import LogObject from "models/logObject"; import { toObjectReference } from "models/objectOnWellbore"; -import React, { useContext } from "react"; +import React from "react"; import JobService, { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -32,7 +32,7 @@ export interface MnemonicsContextMenuProps { const MnemonicsContextMenu = ( props: MnemonicsContextMenuProps ): React.ReactElement => { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { log, mnemonics, indexRanges } = props; const deleteLogCurveValues = async () => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MudLogContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MudLogContextMenu.tsx index 4ec80376b..3601d829a 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/MudLogContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/MudLogContextMenu.tsx @@ -16,14 +16,14 @@ import MudLogPropertiesModal, { MudLogPropertiesModalProps } from "components/Modals/MudLogPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import MudLog from "models/mudLog"; import { ObjectType } from "models/objectType"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const MudLogContextMenu = ( @@ -34,7 +34,7 @@ const MudLogContextMenu = ( const geologyIntervalReferences = useClipboardComponentReferencesOfType( ComponentType.GeologyInterval ); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/NestedMenuItem.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/NestedMenuItem.tsx index f4314f24e..a5bcde7a5 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/NestedMenuItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/NestedMenuItem.tsx @@ -2,13 +2,8 @@ import { Icon, Typography } from "@equinor/eds-core-react"; import MenuItem, { MenuItemProps } from "@mui/material/MenuItem"; import { StyledMenu } from "components/ContextMenus/ContextMenu"; import { StyledIcon } from "components/ContextMenus/ContextMenuUtils"; -import OperationContext from "contexts/operationContext"; -import React, { - useContext, - useImperativeHandle, - useRef, - useState -} from "react"; +import { useOperationState } from "hooks/useOperationState"; +import React, { useImperativeHandle, useRef, useState } from "react"; export interface NestedMenuItemProps extends Omit { label: string; @@ -31,7 +26,7 @@ const NestedMenuItem = React.forwardRef< } = props; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const { ref: containerRefProp, ...ContainerProps } = ContainerPropsProp; diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ObjectsSidebarContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ObjectsSidebarContextMenu.tsx index 4b4bf65e9..431f2a14f 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/ObjectsSidebarContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/ObjectsSidebarContextMenu.tsx @@ -17,14 +17,14 @@ import { pasteObjectOnWellbore } from "components/ContextMenus/CopyUtils"; import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardReferencesOfType } from "components/ContextMenus/UseClipboardReferences"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { toWellboreReference } from "models/jobs/wellboreReference"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; import { v4 as uuid } from "uuid"; @@ -37,7 +37,7 @@ const ObjectsSidebarContextMenu = ( props: ObjectsSidebarContextMenuProps ): React.ReactElement => { const { wellbore, objectType } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { servers } = useGetServers(); const objectReferences = useClipboardReferencesOfType(objectType); const openInQueryView = useOpenInQueryView(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigContextMenu.tsx index c39f0f433..940d073a0 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigContextMenu.tsx @@ -13,18 +13,18 @@ import RigPropertiesModal, { RigPropertiesModalProps } from "components/Modals/RigPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import Rig from "models/rig"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const RigContextMenu = (props: ObjectContextMenuProps): React.ReactElement => { const { checkedObjects } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigsContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigsContextMenu.tsx index 23d78a1ae..bc51ad669 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigsContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RigsContextMenu.tsx @@ -19,16 +19,16 @@ import RigPropertiesModal, { RigPropertiesModalProps } from "components/Modals/RigPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DisplayModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { toWellboreReference } from "models/jobs/wellboreReference"; import { ObjectType } from "models/objectType"; import Rig from "models/rig"; import { Server } from "models/server"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; import { v4 as uuid } from "uuid"; @@ -39,7 +39,7 @@ export interface RigsContextMenuProps { const RigsContextMenu = (props: RigsContextMenuProps): React.ReactElement => { const { wellbore, servers } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const rigReferences = useClipboardReferencesOfType(ObjectType.Rig); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RiskContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RiskContextMenu.tsx index 77abce94a..2aa72aaff 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/RiskContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/RiskContextMenu.tsx @@ -12,13 +12,13 @@ import RiskPropertiesModal, { RiskPropertiesModalProps } from "components/Modals/RiskPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import RiskObject from "models/riskObject"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const RiskObjectContextMenu = ( @@ -26,7 +26,7 @@ const RiskObjectContextMenu = ( ): React.ReactElement => { const { checkedObjects } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); const queryClient = useQueryClient(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoriesContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoriesContextMenu.tsx index f1e961aec..62aeafe0b 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoriesContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoriesContextMenu.tsx @@ -19,16 +19,16 @@ import TrajectoryPropertiesModal, { TrajectoryPropertiesModalProps } from "components/Modals/TrajectoryPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DisplayModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { toWellboreReference } from "models/jobs/wellboreReference"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Trajectory from "models/trajectory"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; import { v4 as uuid } from "uuid"; @@ -41,7 +41,7 @@ const TrajectoriesContextMenu = ( props: TrajectoriesContextMenuProps ): React.ReactElement => { const { wellbore, servers } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const trajectoryReferences = useClipboardReferencesOfType( ObjectType.Trajectory ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryContextMenu.tsx index 733840fee..e0e38edd0 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryContextMenu.tsx @@ -17,14 +17,14 @@ import TrajectoryPropertiesModal, { TrajectoryPropertiesModalProps } from "components/Modals/TrajectoryPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { ObjectType } from "models/objectType"; import Trajectory from "models/trajectory"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const TrajectoryContextMenu = ( @@ -32,7 +32,7 @@ const TrajectoryContextMenu = ( ): React.ReactElement => { const { checkedObjects } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const trajectoryStationReferences = useClipboardComponentReferencesOfType( ComponentType.TrajectoryStation ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryStationContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryStationContextMenu.tsx index c083da3b2..b2727e980 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryStationContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TrajectoryStationContextMenu.tsx @@ -17,15 +17,15 @@ import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import TrajectoryStationPropertiesModal from "components/Modals/TrajectoryStationPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { createComponentReferences } from "models/jobs/componentReferences"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Trajectory from "models/trajectory"; -import React, { useContext } from "react"; +import React from "react"; import { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -38,7 +38,7 @@ const TrajectoryStationContextMenu = ( props: TrajectoryStationContextMenuProps ): React.ReactElement => { const { checkedTrajectoryStations, trajectory } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { servers } = useGetServers(); const { connectedServer } = useConnectedServer(); const trajectoryStationReferences = useClipboardComponentReferencesOfType( diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularComponentContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularComponentContextMenu.tsx index ce59d48d1..0855bf7ca 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularComponentContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularComponentContextMenu.tsx @@ -19,15 +19,15 @@ import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import TubularComponentPropertiesModal from "components/Modals/TubularComponentPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { createComponentReferences } from "models/jobs/componentReferences"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Tubular from "models/tubular"; -import React, { useContext } from "react"; +import React from "react"; import { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -41,7 +41,7 @@ const TubularComponentContextMenu = ( ): React.ReactElement => { const { checkedTubularComponents, tubular } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const tubularComponentReferences = useClipboardComponentReferencesOfType( ComponentType.TubularComponent ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularContextMenu.tsx index 6a7846a70..17f5c1b00 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularContextMenu.tsx @@ -15,14 +15,14 @@ import { useClipboardComponentReferencesOfType } from "components/ContextMenus/U import { PropertiesModalMode } from "components/Modals/ModalParts"; import TubularPropertiesModal from "components/Modals/TubularPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { ObjectType } from "models/objectType"; import Tubular from "models/tubular"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const TubularContextMenu = ( @@ -30,7 +30,7 @@ const TubularContextMenu = ( ): React.ReactElement => { const { checkedObjects } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const tubularComponentReferences = useClipboardComponentReferencesOfType( ComponentType.TubularComponent ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularsContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularsContextMenu.tsx index f0d9b291c..2792adcca 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularsContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/TubularsContextMenu.tsx @@ -15,13 +15,13 @@ import { pasteObjectOnWellbore } from "components/ContextMenus/CopyUtils"; import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardReferencesOfType } from "components/ContextMenus/UseClipboardReferences"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { toWellboreReference } from "models/jobs/wellboreReference"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; import { v4 as uuid } from "uuid"; @@ -34,7 +34,7 @@ const TubularsContextMenu = ( props: TubularsContextMenuProps ): React.ReactElement => { const { wellbore, servers } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const tubularReferences = useClipboardReferencesOfType(ObjectType.Tubular); const openInQueryView = useOpenInQueryView(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometryContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometryContextMenu.tsx index e394dbfd2..ddc1fbdf4 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometryContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometryContextMenu.tsx @@ -17,14 +17,14 @@ import WbGeometryPropertiesModal, { WbGeometryPropertiesModalProps } from "components/Modals/WbGeometryPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { ObjectType } from "models/objectType"; import WbGeometryObject from "models/wbGeometry"; -import React, { useContext } from "react"; +import React from "react"; import { colors } from "styles/Colors"; const WbGeometryObjectContextMenu = ( @@ -32,7 +32,7 @@ const WbGeometryObjectContextMenu = ( ): React.ReactElement => { const { checkedObjects } = props; const { servers } = useGetServers(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const wbGeometrySectionReferences = useClipboardComponentReferencesOfType( ComponentType.WbGeometrySection ); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometrySectionContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometrySectionContextMenu.tsx index 0a57ca179..e73caf1c1 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometrySectionContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WbGeometrySectionContextMenu.tsx @@ -16,16 +16,16 @@ import NestedMenuItem from "components/ContextMenus/NestedMenuItem"; import { useClipboardComponentReferencesOfType } from "components/ContextMenus/UseClipboardComponentReferences"; import WbGeometrySectionPropertiesModal from "components/Modals/WbGeometrySectionPropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { createComponentReferences } from "models/jobs/componentReferences"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import WbGeometry from "models/wbGeometry"; import WbGeometrySection from "models/wbGeometrySection"; -import React, { useContext } from "react"; +import React from "react"; import { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -41,7 +41,7 @@ const WbGeometrySectionContextMenu = ( const wbGeometrySectionReferences = useClipboardComponentReferencesOfType( ComponentType.WbGeometrySection ); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { servers } = useGetServers(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WellboreContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WellboreContextMenu.tsx index 5f34d0e4a..db9b15e68 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/WellboreContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/WellboreContextMenu.tsx @@ -31,19 +31,19 @@ import WellborePropertiesModal, { WellborePropertiesModalProps } from "components/Modals/WellborePropertiesModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DisplayModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { refreshWellboreQuery } from "hooks/query/queryRefreshHelpers"; import { useGetCapObjects } from "hooks/query/useGetCapObjects"; import { useOpenInQueryView } from "hooks/useOpenInQueryView"; +import { useOperationState } from "hooks/useOperationState"; import { DeleteWellboreJob } from "models/jobs/deleteJobs"; import { toWellboreReference } from "models/jobs/wellboreReference"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; import Wellbore from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { getObjectGroupsViewPath } from "routes/utils/pathBuilder"; import JobService, { JobType } from "services/jobService"; import { colors } from "styles/Colors"; @@ -60,7 +60,7 @@ const WellboreContextMenu = ( props: WellboreContextMenuProps ): React.ReactElement => { const { wellbore, checkedWellboreRows, servers } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const openInQueryView = useOpenInQueryView(); const objectReferences = useClipboardReferences(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/GlobalStyles.tsx b/Src/WitsmlExplorer.Frontend/components/GlobalStyles.tsx index fa2cb4447..3e2976e6a 100644 --- a/Src/WitsmlExplorer.Frontend/components/GlobalStyles.tsx +++ b/Src/WitsmlExplorer.Frontend/components/GlobalStyles.tsx @@ -1,6 +1,16 @@ +import { useOperationState } from "hooks/useOperationState"; +import { ReactElement } from "react"; import { createGlobalStyle } from "styled-components"; import { Colors } from "styles/Colors"; +export const GlobalStylesWrapper = (): ReactElement => { + const { + operationState: { colors } + } = useOperationState(); + + return ; +}; + const GlobalStyles = createGlobalStyle<{ colors: Colors }>` *, *:before, diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/AnalyzeGapModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/AnalyzeGapModal.tsx index 2293086c6..d8c76e27c 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/AnalyzeGapModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/AnalyzeGapModal.tsx @@ -8,10 +8,10 @@ import ModalDialog from "components/Modals/ModalDialog"; import { ReportModal } from "components/Modals/ReportModal"; import AdjustDateTimeModal from "components/Modals/TrimLogObject/AdjustDateTimeModal"; import AdjustNumberRangeModal from "components/Modals/TrimLogObject/AdjustNumberRangeModal"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; -import React, { useContext, useState } from "react"; +import React, { useState } from "react"; import JobService, { JobType } from "services/jobService"; import { formatIndexValue, indexToNumber } from "tools/IndexHelpers"; @@ -22,7 +22,7 @@ export interface AnalyzeGapModalProps { const AnalyzeGapModal = (props: AnalyzeGapModalProps): React.ReactElement => { const { logObject, mnemonics } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const timePattern = /^([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/; const initialTime = "00:00:00"; const [log] = useState(logObject); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/BatchModifyPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/BatchModifyPropertiesModal.tsx index b93d69c9d..b0d812823 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/BatchModifyPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/BatchModifyPropertiesModal.tsx @@ -1,7 +1,7 @@ import { Autocomplete, TextField } from "@equinor/eds-core-react"; -import { ChangeEvent, ReactElement, useContext, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { ChangeEvent, ReactElement, useState } from "react"; import styled from "styled-components"; -import OperationContext from "../../contexts/operationContext"; import OperationType from "../../contexts/operationType"; import ModalDialog from "./ModalDialog"; @@ -22,7 +22,7 @@ export const BatchModifyPropertiesModal = ( props: BatchModifyModalProps ): ReactElement => { const { title, properties, onSubmit } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [batchUpdates, setBatchUpdates] = useState<{ [key: string]: string }>( properties.reduce((acc, prop) => ({ ...acc, [prop.property]: "" }), {}) ); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/BhaRunPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/BhaRunPropertiesModal.tsx index 841f29998..809f4b1d7 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/BhaRunPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/BhaRunPropertiesModal.tsx @@ -3,16 +3,16 @@ import formatDateString from "components/DateFormatter"; import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat, HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import BhaRun from "models/bhaRun"; import { itemStateTypes } from "models/itemStateTypes"; import { ObjectType } from "models/objectType"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; const typesOfBhaStatus = ["final", "progress", "plan", "unknown"]; @@ -29,7 +29,7 @@ const BhaRunPropertiesModal = ( const { mode, bhaRun, dispatchOperation } = props; const { operationState: { timeZone } - } = useContext(OperationContext); + } = useOperationState(); const [editableBhaRun, setEditableBhaRun] = useState(null); const [dTimStartValid, setDTimStartValid] = useState(true); const [dTimStopValid, setDTimStopValid] = useState(true); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/CompareLogDataModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/CompareLogDataModal.tsx index 0004b0359..f48e44251 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/CompareLogDataModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/CompareLogDataModal.tsx @@ -3,11 +3,11 @@ import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import { Checkbox } from "components/StyledComponents/Checkbox"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import ObjectOnWellbore from "models/objectOnWellbore"; import { Server } from "models/server"; -import { ChangeEvent, useContext, useState } from "react"; +import { ChangeEvent, useState } from "react"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -30,7 +30,7 @@ export default function CompareLogDataModal({ const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [checkedCompareAllLogIndexes, setCheckedCompareAllLogIndexes] = useState(false); const onSubmit = async () => { diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/CopyMnemonicsModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/CopyMnemonicsModal.tsx index 7792a1695..6a35fdc0c 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/CopyMnemonicsModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/CopyMnemonicsModal.tsx @@ -1,23 +1,23 @@ import { Radio, Typography } from "@equinor/eds-core-react"; import ModalDialog from "components/Modals/ModalDialog"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; -import { useContext, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { useState } from "react"; import styled from "styled-components"; -import ObjectReference from "../../models/jobs/objectReference"; +import { ComponentType, getParentType } from "../../models/componentType"; import ComponentReferences, { createComponentReferences } from "../../models/jobs/componentReferences"; import { CopyComponentsJob } from "../../models/jobs/copyJobs"; -import JobService, { JobType } from "../../services/jobService"; import { DeleteComponentsJob } from "../../models/jobs/deleteJobs"; +import ObjectReference from "../../models/jobs/objectReference"; import { ReplaceComponentsJob } from "../../models/jobs/replaceComponentsJob"; -import { ComponentType, getParentType } from "../../models/componentType"; -import ComponentService from "../../services/componentService"; +import LogObject from "../../models/logObject"; import { Server } from "../../models/server"; -import ObjectService from "../../services/objectService"; import AuthorizationService from "../../services/authorizationService"; -import LogObject from "../../models/logObject"; +import ComponentService from "../../services/componentService"; +import JobService, { JobType } from "../../services/jobService"; +import ObjectService from "../../services/objectService"; enum CopyMnemonicsType { DeleteInsert = "deleteInsert", @@ -45,7 +45,7 @@ const CopyMnemonicsModal = ( endIndex } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [selectedCopyMnemonicsType, setCopyMnemonicsType] = useState( CopyMnemonicsType.Paste diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/CopyRangeModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/CopyRangeModal.tsx index c31586f68..5df4156be 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/CopyRangeModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/CopyRangeModal.tsx @@ -7,15 +7,15 @@ import ModalDialog from "components/Modals/ModalDialog"; import AdjustDateTimeModal from "components/Modals/TrimLogObject/AdjustDateTimeModal"; import AdjustNumberRangeModal from "components/Modals/TrimLogObject/AdjustNumberRangeModal"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { CopyRangeClipboard, createComponentReferences } from "models/jobs/componentReferences"; import LogObject, { indexToNumber } from "models/logObject"; -import React, { useContext, useState } from "react"; +import React, { useState } from "react"; export interface CopyRangeModalProps { logObject: LogObject; @@ -26,7 +26,7 @@ export interface CopyRangeModalProps { const CopyRangeModal = (props: CopyRangeModalProps): React.ReactElement => { const { connectedServer } = useConnectedServer(); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [startIndex, setStartIndex] = useState(); const [endIndex, setEndIndex] = useState(); const [confirmDisabled, setConfirmDisabled] = useState(true); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/DeleteEmptyMnemonicsModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/DeleteEmptyMnemonicsModal.tsx index 39c7935ea..cbe96d0ab 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/DeleteEmptyMnemonicsModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/DeleteEmptyMnemonicsModal.tsx @@ -3,14 +3,14 @@ import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; import { ReportModal } from "components/Modals/ReportModal"; import { Checkbox } from "components/StyledComponents/Checkbox"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { DeleteEmptyMnemonicsJob } from "models/jobs/deleteEmptyMnemonicsJob"; import LogObject from "models/logObject"; import { toObjectReference } from "models/objectOnWellbore"; import Well from "models/well"; import Wellbore from "models/wellbore"; -import { ChangeEvent, useContext, useState } from "react"; +import { ChangeEvent, useState } from "react"; import JobService, { JobType } from "services/jobService"; import styled from "styled-components"; @@ -27,7 +27,7 @@ const DeleteEmptyMnemonicsModal = ( const { dispatchOperation, operationState: { timeZone, colors } - } = useContext(OperationContext); + } = useOperationState(); const [nullDepthValue, setNullDepthValue] = useState(-999.25); const [nullTimeValue, setNullTimeValue] = useState( "1900-01-01T00:00:00.000Z" diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/FormationMarkerPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/FormationMarkerPropertiesModal.tsx index 11d23b042..1fa9ba384 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/FormationMarkerPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/FormationMarkerPropertiesModal.tsx @@ -5,8 +5,8 @@ import { invalidStringInput, undefinedOnUnchagedEmptyString } from "components/Modals/PropertiesModalUtils"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import FormationMarker from "models/formationMarker"; import { itemStateTypes } from "models/itemStateTypes"; import MaxLength from "models/maxLength"; @@ -14,13 +14,7 @@ import Measure from "models/measure"; import MeasureWithDatum from "models/measureWithDatum"; import { ObjectType } from "models/objectType"; import StratigraphicStruct from "models/stratigraphicStruct"; -import React, { - ChangeEvent, - Dispatch, - SetStateAction, - useContext, - useState -} from "react"; +import React, { ChangeEvent, Dispatch, SetStateAction, useState } from "react"; import JobService, { JobType } from "services/jobService"; import { Layout } from "../StyledComponents/Layout"; @@ -66,7 +60,7 @@ const FormationMarkerPropertiesModal = ( props: FormationMarkerPropertiesModalProps ): React.ReactElement => { const { formationMarker } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [editable, setEditable] = useState({}); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/GeologyIntervalPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/GeologyIntervalPropertiesModal.tsx index 5d7027e2b..30390ebf9 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/GeologyIntervalPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/GeologyIntervalPropertiesModal.tsx @@ -7,8 +7,8 @@ import { invalidStringInput, undefinedOnUnchagedEmptyString } from "components/Modals/PropertiesModalUtils"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import GeologyInterval from "models/geologyInterval"; import ObjectReference from "models/jobs/objectReference"; import { lithologySources } from "models/lithologySources"; @@ -22,7 +22,6 @@ import React, { ChangeEvent, Dispatch, SetStateAction, - useContext, useEffect, useState } from "react"; @@ -75,7 +74,7 @@ const GeologyIntervalPropertiesModal = ( props: GeologyIntervalPropertiesModalInterface ): React.ReactElement => { const { geologyInterval, mudLog: selectedMudLog } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [editable, setEditable] = useState({}); const [editableLithologies, setEditableLithologies] = useState< Record diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogComparisonModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogComparisonModal.tsx index d4fa8e647..f51fa7d66 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogComparisonModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogComparisonModal.tsx @@ -19,16 +19,16 @@ import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import ProgressSpinner from "components/ProgressSpinner"; -import OperationContext from "contexts/operationContext"; import { DispatchOperation } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import LogCurveInfo from "models/logCurveInfo"; import LogObject from "models/logObject"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import { useContext, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import ComponentService from "services/componentService"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -53,7 +53,7 @@ const LogComparisonModal = ( } = props; const { operationState: { timeZone, colors, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [sourceLogCurveInfo, setSourceLogCurveInfo] = useState(null); const [targetLogCurveInfo, setTargetLogCurveInfo] = diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogCurveInfoBatchUpdateModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogCurveInfoBatchUpdateModal.tsx index 620e71cfc..d65a3b2c7 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogCurveInfoBatchUpdateModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogCurveInfoBatchUpdateModal.tsx @@ -1,8 +1,8 @@ import { Autocomplete, TextField } from "@equinor/eds-core-react"; import { Grid } from "@mui/material"; -import React, { ChangeEvent, useContext, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import React, { ChangeEvent, useState } from "react"; import styled from "styled-components"; -import OperationContext from "../../contexts/operationContext"; import OperationType from "../../contexts/operationType"; import BatchModifyLogCurveInfoJob from "../../models/jobs/batchModifyLogCurveInfoJob"; import LogCurveInfo, { EmptyLogCurveInfo } from "../../models/logCurveInfo"; @@ -26,7 +26,7 @@ const LogCurveInfoBatchUpdateModal = ( props: LogCurveInfoBatchUpdateModalProps ): React.ReactElement => { const { logCurveInfoRows, selectedLog } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [editableLogCurveInfo, setEditableLogCurveInfo] = useState(EmptyLogCurveInfo); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogCurvePriorityModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogCurvePriorityModal.tsx index dd2958693..12b5bfc56 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogCurvePriorityModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogCurvePriorityModal.tsx @@ -1,8 +1,8 @@ import { Icon, TextField } from "@equinor/eds-core-react"; import { Button } from "components/StyledComponents/Button"; -import React, { ChangeEvent, useContext, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import React, { ChangeEvent, useState } from "react"; import styled from "styled-components"; -import OperationContext from "../../contexts/operationContext"; import { MousePosition } from "../../contexts/operationStateReducer"; import OperationType from "../../contexts/operationType"; import LogCurvePriorityService from "../../services/logCurvePriorityService"; @@ -34,7 +34,7 @@ export const LogCurvePriorityModal = ( const [updatedPrioritizedCurves, setUpdatedPrioritizedCurves] = useState(prioritizedCurves); const [newCurve, setNewCurve] = useState(""); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [position, setPosition] = useState({ mouseX: null, mouseY: null diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx index 152f51bc0..acc4ab5cc 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogDataImportModal.tsx @@ -5,9 +5,9 @@ import { StyledAccordionHeader } from "components/Modals/LogComparisonModal"; import ModalDialog from "components/Modals/ModalDialog"; import WarningBar from "components/WarningBar"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { IndexRange } from "models/jobs/deleteLogCurveValuesJob"; import ImportLogDataJob from "models/jobs/importLogDataJob"; @@ -15,7 +15,7 @@ import ObjectReference from "models/jobs/objectReference"; import LogCurveInfo from "models/logCurveInfo"; import LogObject from "models/logObject"; import { toObjectReference } from "models/objectOnWellbore"; -import React, { useCallback, useContext, useState } from "react"; +import React, { useCallback, useState } from "react"; import JobService, { JobType } from "services/jobService"; import styled from "styled-components"; @@ -42,7 +42,7 @@ const LogDataImportModal = ( const { dispatchOperation, operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const { components: logCurveInfoList, isFetching: isFetchingLogCurveInfo } = useGetComponents( connectedServer, diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogHeaderDateTimeField.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogHeaderDateTimeField.tsx index 9b629bb50..85dc34a84 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogHeaderDateTimeField.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogHeaderDateTimeField.tsx @@ -3,9 +3,9 @@ import formatDateString, { getOffset, getOffsetFromTimeZone } from "components/DateFormatter"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat, TimeZone } from "contexts/operationStateReducer"; -import { ChangeEvent, useContext, useEffect, useState } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { ChangeEvent, useEffect, useState } from "react"; import styled from "styled-components"; interface DateTimeFieldProps { @@ -33,7 +33,7 @@ export const LogHeaderDateTimeField = ( const { value, label, updateObject, minValue, maxValue } = props; const { operationState: { timeZone } - } = useContext(OperationContext); + } = useOperationState(); const offset = timeZone === TimeZone.Raw ? getOffset(value) diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/LogPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/LogPropertiesModal.tsx index 1cf572bbf..da04b1035 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/LogPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/LogPropertiesModal.tsx @@ -3,12 +3,12 @@ import { WITSML_INDEX_TYPE_DATE_TIME } from "components/Constants"; import formatDateString from "components/DateFormatter"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export enum IndexCurve { @@ -28,7 +28,7 @@ const LogPropertiesModal = ( const { mode, logObject, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableLogObject, setEditableLogObject] = useState(null); const [isLoading, setIsLoading] = useState(false); const editMode = mode === PropertiesModalMode.Edit; diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/MessageComparisonModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/MessageComparisonModal.tsx index 0b2ef9636..829262e38 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/MessageComparisonModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/MessageComparisonModal.tsx @@ -16,14 +16,14 @@ import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import ProgressSpinner from "components/ProgressSpinner"; -import OperationContext from "contexts/operationContext"; import { DispatchOperation } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import MessageObject from "models/messageObject"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import { useContext, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import ObjectService from "services/objectService"; export interface MessageComparisonModalProps { @@ -46,7 +46,7 @@ const MessageComparisonModal = ( } = props; const { operationState: { timeZone, colors, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [targetMessage, setTargetMessage] = useState(null); const [differenceFound, setDifferenceFound] = useState(false); const [data, setData] = useState(null); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/MessagePropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/MessagePropertiesModal.tsx index c1043068b..6043a47f3 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/MessagePropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/MessagePropertiesModal.tsx @@ -2,12 +2,12 @@ import { TextField } from "@equinor/eds-core-react"; import formatDateString from "components/DateFormatter"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import MessageObject from "models/messageObject"; import { ObjectType } from "models/objectType"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface MessagePropertiesModalProps { @@ -22,7 +22,7 @@ const MessagePropertiesModal = ( const { mode, messageObject, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableMessageObject, setEditableMessageObject] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx index 8c71d3800..b38c10a21 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx @@ -15,15 +15,15 @@ import ModalDialog, { } from "components/Modals/ModalDialog"; import { ReportModal } from "components/Modals/ReportModal"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import useExport from "hooks/useExport"; import { useLocalStorageState } from "hooks/useLocalStorageState"; +import { useOperationState } from "hooks/useOperationState"; import MissingDataJob, { MissingDataCheck } from "models/jobs/missingDataJob"; import WellReference from "models/jobs/wellReference"; import WellboreReference from "models/jobs/wellboreReference"; import { ObjectType } from "models/objectType"; -import { useContext, useRef, useState } from "react"; +import { useRef, useState } from "react"; import JobService, { JobType } from "services/jobService"; import styled from "styled-components"; import { STORAGE_MISSING_DATA_AGENT_CHECKS_KEY } from "tools/localStorageHelpers"; @@ -47,7 +47,7 @@ const MissingDataAgentModal = ( const { dispatchOperation, operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const [missingDataChecks, setMissingDataChecks] = useLocalStorageState< MissingDataCheck[] >(STORAGE_MISSING_DATA_AGENT_CHECKS_KEY, { diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx index 87743cdb0..2cd0cf794 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ModalDialog.tsx @@ -1,7 +1,7 @@ import { Dialog, Progress, Typography } from "@equinor/eds-core-react"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import React, { ReactElement, useState } from "react"; import styled from "styled-components"; import { Colors, dark, light } from "styles/Colors"; @@ -46,7 +46,7 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { buttonPosition: ButtonPosition = ControlButtonPosition.BOTTOM, cancelText } = props; - const context = React.useContext(OperationContext); + const context = useOperationState(); const [confirmButtonIsFocused, setConfirmButtonIsFocused] = useState(false); const { operationState } = context; diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ModalPresenter.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ModalPresenter.tsx index e4d45aa8e..18ca97e54 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ModalPresenter.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ModalPresenter.tsx @@ -1,8 +1,8 @@ -import { Fragment, ReactElement, useContext } from "react"; -import OperationContext from "contexts/operationContext"; +import { useOperationState } from "hooks/useOperationState"; +import { Fragment, ReactElement } from "react"; const ModalPresenter = (): ReactElement => { - const { operationState } = useContext(OperationContext); + const { operationState } = useOperationState(); const { modals } = operationState; return ( <> diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/MudLogPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/MudLogPropertiesModal.tsx index f20c3df50..98574170b 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/MudLogPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/MudLogPropertiesModal.tsx @@ -5,14 +5,14 @@ import { invalidStringInput, undefinedOnUnchagedEmptyString } from "components/Modals/PropertiesModalUtils"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { itemStateValues } from "models/commonData"; import MaxLength from "models/maxLength"; import MudLog from "models/mudLog"; import ObjectOnWellbore, { toObjectReference } from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; import { Layout } from "../StyledComponents/Layout"; @@ -33,7 +33,7 @@ const MudLogPropertiesModal = ( const { operationState: { timeZone, dateTimeFormat }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [editableMudLog, setEditableMudLog] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ObjectPickerModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ObjectPickerModal.tsx index 214d4d54c..ffde97068 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ObjectPickerModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ObjectPickerModal.tsx @@ -7,14 +7,14 @@ import ModalDialog, { import { Banner } from "components/StyledComponents/Banner"; import { Button } from "components/StyledComponents/Button"; import { Checkbox } from "components/StyledComponents/Checkbox"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import MaxLength from "models/maxLength"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { Server } from "models/server"; -import { ChangeEvent, useContext, useState } from "react"; +import { ChangeEvent, useState } from "react"; import ObjectService from "services/objectService"; import styled from "styled-components"; import Icon from "styles/Icons"; @@ -43,7 +43,7 @@ const ObjectPickerModal = ({ const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [targetServer, setTargetServer] = useState(); const [wellUid, setWellUid] = useState(sourceObject.wellUid); const [wellboreUid, setWellboreUid] = useState( diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/OffsetLogCurveModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/OffsetLogCurveModal.tsx index d0ea9f105..c09910364 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/OffsetLogCurveModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/OffsetLogCurveModal.tsx @@ -15,15 +15,15 @@ import AdjustNumberRangeModal from "components/Modals/TrimLogObject/AdjustNumber import { Checkbox } from "components/StyledComponents/Checkbox"; import WarningBar from "components/WarningBar"; import { useConnectedServer } from "contexts/connectedServerContext"; +import { useOperationState } from "hooks/useOperationState"; import { ComponentType } from "models/componentType"; import { createComponentReferences } from "models/jobs/componentReferences"; import { OffsetLogCurveJob } from "models/jobs/offsetLogCurveJob"; import LogObject from "models/logObject"; -import React, { ChangeEvent, ReactElement, useContext, useState } from "react"; +import React, { ChangeEvent, ReactElement, useState } from "react"; import JobService, { JobType } from "services/jobService"; import styled from "styled-components"; import { indexToNumber } from "tools/IndexHelpers"; -import OperationContext from "../../contexts/operationContext"; import OperationType from "../../contexts/operationType"; import ModalDialog from "./ModalDialog"; @@ -44,7 +44,7 @@ export const OffsetLogCurveModal = ( endIndex: initialEndIndex } = props; const { connectedServer } = useConnectedServer(); - const { operationState, dispatchOperation } = useContext(OperationContext); + const { operationState, dispatchOperation } = useOperationState(); const { colors } = operationState; const isDepthLog = selectedLog.indexType === WITSML_INDEX_TYPE_MD; const [isValidInterval, setIsValidInterval] = useState(); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx index 41de8abb3..5daba5a31 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ReportModal.tsx @@ -16,10 +16,10 @@ import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import { generateReport } from "components/ReportCreationHelper"; import { Banner } from "components/StyledComponents/Banner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import useExport from "hooks/useExport"; import { useLiveJobProgress } from "hooks/useLiveJobProgress"; +import { useOperationState } from "hooks/useOperationState"; import BaseReport, { createReport } from "models/reports/BaseReport"; import React, { useEffect, useState } from "react"; import JobService from "services/jobService"; @@ -50,7 +50,7 @@ export const ReportModal = (props: ReportModal): React.ReactElement => { const { dispatchOperation, operationState: { colors } - } = React.useContext(OperationContext); + } = useOperationState(); const [report, setReport] = useState(reportProp); const fetchedReport = useGetReportOnJobFinished(jobId); const jobProgress = useLiveJobProgress(jobId); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/RigPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/RigPropertiesModal.tsx index 8a9cebce0..fe9651e53 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/RigPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/RigPropertiesModal.tsx @@ -7,14 +7,14 @@ import { validPhoneNumber, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { itemStateTypes } from "models/itemStateTypes"; import { ObjectType } from "models/objectType"; import Rig from "models/rig"; import { rigType } from "models/rigType"; -import React, { ChangeEvent, useContext, useState } from "react"; +import React, { ChangeEvent, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface RigPropertiesModalProps { @@ -29,7 +29,7 @@ const RigPropertiesModal = ( const { mode, rig, dispatchOperation } = props; const { operationState: { timeZone } - } = useContext(OperationContext); + } = useOperationState(); const [editableRig, setEditableRig] = useState({ ...rig }); const [isLoading, setIsLoading] = useState(false); const [dTimStartOpValid, setDTimStartOpValid] = useState(true); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/RiskPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/RiskPropertiesModal.tsx index 86b38975f..01d9c2d56 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/RiskPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/RiskPropertiesModal.tsx @@ -3,9 +3,9 @@ import formatDateString from "components/DateFormatter"; import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { itemStateTypes } from "models/itemStateTypes"; import { ObjectType } from "models/objectType"; import { riskAffectedPersonnel } from "models/riskAffectedPersonnel"; @@ -13,7 +13,7 @@ import { riskCategory } from "models/riskCategory"; import RiskObject from "models/riskObject"; import { riskSubCategory } from "models/riskSubCategory"; import { riskType } from "models/riskType"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface RiskPropertiesModalProps { @@ -28,7 +28,7 @@ const RiskPropertiesModal = ( const { mode, riskObject, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableRiskObject, setEditableRiskObject] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/SelectIndexToDisplayModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/SelectIndexToDisplayModal.tsx index a7f380558..1c77f785c 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/SelectIndexToDisplayModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/SelectIndexToDisplayModal.tsx @@ -8,12 +8,12 @@ import AdjustDateTimeModal from "components/Modals/TrimLogObject/AdjustDateTimeM import AdjustNumberRangeModal from "components/Modals/TrimLogObject/AdjustNumberRangeModal"; import { Banner } from "components/StyledComponents/Banner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetActiveRoute } from "hooks/useGetActiveRoute"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import { ObjectType } from "models/objectType"; -import React, { useContext, useState } from "react"; +import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; import { @@ -40,7 +40,7 @@ const SelectIndexToDisplayModal = ( const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const isTimeIndexed = log.indexType === WITSML_INDEX_TYPE_DATE_TIME; const [startIndex, setStartIndex] = useState( getStartIndex(log, logCurveInfoRows, isMultiLog) diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ServerModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ServerModal.tsx index 0777c2c24..6739b093b 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ServerModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ServerModal.tsx @@ -9,13 +9,13 @@ import UserCredentialsModal, { } from "components/Modals/UserCredentialsModal"; import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { DisplayModalAction, HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { refreshServersQuery } from "hooks/query/queryRefreshHelpers"; +import { useOperationState } from "hooks/useOperationState"; import { Server } from "models/server"; import { msalEnabled } from "msal/MsalAuthProvider"; import React, { @@ -23,7 +23,6 @@ import React, { ChangeEvent, Dispatch, SetStateAction, - useContext, useState } from "react"; import AuthorizationService from "services/authorizationService"; @@ -39,7 +38,7 @@ export interface ServerModalProps { const ServerModal = (props: ServerModalProps): React.ReactElement => { const queryClient = useQueryClient(); - const { operationState, dispatchOperation } = useContext(OperationContext); + const { operationState, dispatchOperation } = useOperationState(); const { colors } = operationState; const [server, setServer] = useState(props.server); const [connectionVerified, setConnectionVerified] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/SettingsModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/SettingsModal.tsx index 0dfd85432..d6fd59a42 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/SettingsModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/SettingsModal.tsx @@ -4,7 +4,6 @@ import ModalDialog from "components/Modals/ModalDialog"; import { StyledNativeSelect } from "components/Select"; import { Button } from "components/StyledComponents/Button"; import { Checkbox } from "components/StyledComponents/Checkbox"; -import OperationContext from "contexts/operationContext"; import { DateTimeFormat, DecimalPreference, @@ -12,8 +11,9 @@ import { UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { getAccountInfo, msalEnabled, signOut } from "msal/MsalAuthProvider"; -import React, { CSSProperties, ChangeEvent, useContext, useState } from "react"; +import React, { CSSProperties, ChangeEvent, useState } from "react"; import AuthorizationService from "services/authorizationService"; import styled from "styled-components"; import { dark, light } from "styles/Colors"; @@ -54,7 +54,7 @@ const SettingsModal = (): React.ReactElement => { hotKeysEnabled }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [checkedDecimalPreference, setCheckedDecimalPreference] = useState(() => { return decimals === DecimalPreference.Raw diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/ShowLogDataOnServerModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/ShowLogDataOnServerModal.tsx index 3551915ee..49ff03900 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/ShowLogDataOnServerModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/ShowLogDataOnServerModal.tsx @@ -7,11 +7,11 @@ import { import ModalDialog from "components/Modals/ModalDialog"; import { Banner } from "components/StyledComponents/Banner"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; +import { useOperationState } from "hooks/useOperationState"; import { Server } from "models/server"; -import { CSSProperties, ChangeEvent, useContext, useState } from "react"; +import { CSSProperties, ChangeEvent, useState } from "react"; import { useParams, useSearchParams } from "react-router-dom"; import { checkIsUrlTooLong } from "routes/utils/checkIsUrlTooLong"; import { createLogCurveValuesSearchParams } from "routes/utils/createLogCurveValuesSearchParams"; @@ -35,7 +35,7 @@ export function ShowLogDataOnServerModal() { const { operationState: { colors, theme }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const { wellUid, wellboreUid, objectGroup, objectUid, logType } = useParams(); const [isUrlTooLong, setIsUrlTooLong] = useState(false); const [searchParams] = useSearchParams(); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/SpliceLogsModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/SpliceLogsModal.tsx index 938acb09a..5fe4336a1 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/SpliceLogsModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/SpliceLogsModal.tsx @@ -2,8 +2,8 @@ import { Accordion, TextField, Typography } from "@equinor/eds-core-react"; import { StyledAccordionHeader } from "components/Modals/LogComparisonModal"; import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import { validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import SpliceLogsJob from "models/jobs/spliceLogsJob"; import LogObject from "models/logObject"; import ObjectOnWellbore, { toObjectReferences } from "models/objectOnWellbore"; @@ -12,7 +12,6 @@ import { ChangeEvent, DragEvent, ReactElement, - useContext, useEffect, useState } from "react"; @@ -32,7 +31,7 @@ const SpliceLogsModal = (props: SpliceLogsProps): ReactElement => { const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [draggedId, setDraggedId] = useState(null); const [draggedOverId, setDraggedOverId] = useState(null); const [orderedLogs, setOrderedLogs] = useState([]); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryPropertiesModal.tsx index 444548579..00ff784f7 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryPropertiesModal.tsx @@ -2,12 +2,12 @@ import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import Trajectory, { aziRefValues } from "models/trajectory"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; import { itemStateTypes } from "../../models/itemStateTypes"; export interface TrajectoryPropertiesModalProps { @@ -22,7 +22,7 @@ const TrajectoryPropertiesModal = ( const { mode, trajectory, dispatchOperation } = props; const { operationState: { timeZone } - } = useContext(OperationContext); + } = useOperationState(); const [editableTrajectory, setEditableTrajectory] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryStationPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryStationPropertiesModal.tsx index 95d148d35..e7f6178e3 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryStationPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/TrajectoryStationPropertiesModal.tsx @@ -2,15 +2,15 @@ import { TextField } from "@equinor/eds-core-react"; import formatDateString from "components/DateFormatter"; import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import ObjectReference from "models/jobs/objectReference"; import { measureToString } from "models/measure"; import { toObjectReference } from "models/objectOnWellbore"; import Trajectory from "models/trajectory"; import TrajectoryStation from "models/trajectoryStation"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface TrajectoryStationPropertiesModalInterface { @@ -25,7 +25,7 @@ const TrajectoryStationPropertiesModal = ( const { trajectoryStation, trajectory, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableTrajectoryStation, setEditableTrajectoryStation] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/TrimLogObject/TrimLogObjectModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/TrimLogObject/TrimLogObjectModal.tsx index b63e05348..29bee51e6 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/TrimLogObject/TrimLogObjectModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/TrimLogObject/TrimLogObjectModal.tsx @@ -7,11 +7,11 @@ import ModalDialog from "components/Modals/ModalDialog"; import AdjustDateTimeModal from "components/Modals/TrimLogObject/AdjustDateTimeModal"; import AdjustNumberRangeModal from "components/Modals/TrimLogObject/AdjustNumberRangeModal"; import WarningBar from "components/WarningBar"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { createTrimLogObjectJob } from "models/jobs/trimLogObjectJob"; import LogObject, { indexToNumber } from "models/logObject"; -import React, { useContext, useState } from "react"; +import React, { useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface TrimLogObjectModalProps { @@ -22,7 +22,7 @@ const TrimLogObjectModal = ( props: TrimLogObjectModalProps ): React.ReactElement => { const { logObject } = props; - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [log] = useState(logObject); const [isLoading, setIsLoading] = useState(false); const [startIndex, setStartIndex] = useState(); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/UserCredentialsModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/UserCredentialsModal.tsx index 5f601b3ff..5d5a8feea 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/UserCredentialsModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/UserCredentialsModal.tsx @@ -8,10 +8,10 @@ import ModalDialog, { ModalWidth } from "components/Modals/ModalDialog"; import { validText } from "components/Modals/ModalParts"; import { Button } from "components/StyledComponents/Button"; import { Checkbox } from "components/StyledComponents/Checkbox"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { Server } from "models/server"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import AuthorizationService, { AuthorizationStatus, BasicServerCredentials, @@ -34,7 +34,7 @@ const UserCredentialsModal = ( const { operationState: { colors }, dispatchOperation - } = useContext(OperationContext); + } = useOperationState(); const [username, setUsername] = useState(); const [password, setPassword] = useState(); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/WbGeometryPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/WbGeometryPropertiesModal.tsx index fc5dc0cba..c968f8be1 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/WbGeometryPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/WbGeometryPropertiesModal.tsx @@ -2,13 +2,13 @@ import { Autocomplete, TextField } from "@equinor/eds-core-react"; import formatDateString from "components/DateFormatter"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import { itemStateTypes } from "models/itemStateTypes"; import { ObjectType } from "models/objectType"; import WbGeometryObject from "models/wbGeometry"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface WbGeometryPropertiesModalProps { @@ -23,7 +23,7 @@ const WbGeometryPropertiesModal = ( const { mode, wbGeometryObject, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableWbGeometryObject, setEditableWbGeometryObject] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/WellPropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/WellPropertiesModal.tsx index 0bc75b037..d2eef21df 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/WellPropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/WellPropertiesModal.tsx @@ -6,11 +6,11 @@ import { validText, validTimeZone } from "components/Modals/ModalParts"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import Well from "models/well"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; export interface WellPropertiesModalProps { @@ -25,7 +25,7 @@ const WellPropertiesModal = ( const { mode, well, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableWell, setEditableWell] = useState(null); const [isLoading, setIsLoading] = useState(false); const editMode = mode === PropertiesModalMode.Edit; diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/WellborePropertiesModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/WellborePropertiesModal.tsx index 2c762e07c..3dfa79a0c 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/WellborePropertiesModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/WellborePropertiesModal.tsx @@ -4,12 +4,12 @@ import { DateTimeField } from "components/Modals/DateTimeField"; import ModalDialog from "components/Modals/ModalDialog"; import { PropertiesModalMode, validText } from "components/Modals/ModalParts"; import { invalidStringInput } from "components/Modals/PropertiesModalUtils"; -import OperationContext from "contexts/operationContext"; import { HideModalAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import MaxLength from "models/maxLength"; import Wellbore, { wellboreHasChanges } from "models/wellbore"; -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import JobService, { JobType } from "services/jobService"; import styled from "styled-components"; @@ -35,7 +35,7 @@ const WellborePropertiesModal = ( const { mode, wellbore, dispatchOperation } = props; const { operationState: { timeZone, dateTimeFormat } - } = useContext(OperationContext); + } = useOperationState(); const [editableWellbore, setEditableWellbore] = useState(null); const [pristineWellbore, setPristineWellbore] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/Src/WitsmlExplorer.Frontend/components/PageLayout.tsx b/Src/WitsmlExplorer.Frontend/components/PageLayout.tsx index 11d95d848..987174a92 100644 --- a/Src/WitsmlExplorer.Frontend/components/PageLayout.tsx +++ b/Src/WitsmlExplorer.Frontend/components/PageLayout.tsx @@ -8,14 +8,13 @@ import Nav from "components/Nav"; import PropertiesPanel from "components/PropertiesPanel"; import Sidebar from "components/Sidebar/Sidebar"; import { Button } from "components/StyledComponents/Button"; -import OperationContext from "contexts/operationContext"; import useDocumentDimensions from "hooks/useDocumentDimensions"; +import { useOperationState } from "hooks/useOperationState"; import { msalEnabled } from "msal/MsalAuthProvider"; import { ReactElement, createContext, useCallback, - useContext, useEffect, useRef, useState @@ -32,7 +31,7 @@ const PageLayout = (): ReactElement => { const [sidebarWidth, setSidebarWidth] = useState(316); const { width: documentWidth, height: documentHeight } = useDocumentDimensions(); - const { operationState } = useContext(OperationContext); + const { operationState } = useOperationState(); const { colors } = operationState; const startResizing = useCallback(() => { diff --git a/Src/WitsmlExplorer.Frontend/components/PropertiesPanel.tsx b/Src/WitsmlExplorer.Frontend/components/PropertiesPanel.tsx index 120d0108b..0eddf2e0c 100644 --- a/Src/WitsmlExplorer.Frontend/components/PropertiesPanel.tsx +++ b/Src/WitsmlExplorer.Frontend/components/PropertiesPanel.tsx @@ -1,20 +1,20 @@ import { Typography } from "@equinor/eds-core-react"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { useGetObject } from "hooks/query/useGetObject"; import { useGetWell } from "hooks/query/useGetWell"; import { useGetWellbore } from "hooks/query/useGetWellbore"; +import { useOperationState } from "hooks/useOperationState"; import { getObjectOnWellboreProperties } from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { getWellProperties } from "models/well"; import { getWellboreProperties } from "models/wellbore"; -import React, { useContext } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; const PropertiesPanel = (): React.ReactElement => { const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const { connectedServer } = useConnectedServer(); const { wellUid, wellboreUid, objectGroup, objectUid } = useParams(); const { well } = useGetWell(connectedServer, wellUid); diff --git a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx index 1faf52684..45d8aab7a 100644 --- a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx +++ b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx @@ -7,8 +7,7 @@ import "ace-builds/src-noconflict/theme-merbivore"; import "ace-builds/src-noconflict/theme-xcode"; import { customCommands, customCompleter } from "components/QueryEditorUtils"; import { updateLinesWithWidgets } from "components/QueryEditorWidgetUtils"; -import OperationContext from "contexts/operationContext"; -import { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; import AceEditor from "react-ace"; import styled from "styled-components"; import { Colors, dark } from "styles/Colors"; @@ -23,7 +22,7 @@ export const QueryEditor = (props: QueryEditorProps) => { const { value, onChange, readonly } = props; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const onLoad = (editor: any) => { editor.renderer.setPadding(10); diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx index d9dc31d4d..51e533254 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx @@ -9,8 +9,8 @@ import { Checkbox } from "components/StyledComponents/Checkbox"; import { useConnectedServer } from "contexts/connectedServerContext"; import { useCurveThreshold } from "contexts/curveThresholdContext"; import { FilterContext, VisibilityStatus } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import { useGetCapObjects } from "hooks/query/useGetCapObjects"; +import { useOperationState } from "hooks/useOperationState"; import { ObjectType } from "models/objectType"; import React, { ChangeEvent, useContext } from "react"; import styled from "styled-components"; @@ -29,7 +29,7 @@ const FilterPanel = (): React.ReactElement => { const { selectedFilter, updateSelectedFilter } = useContext(FilterContext); const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const { connectedServer } = useConnectedServer(); const { capObjects } = useGetCapObjects(connectedServer, { placeholderData: Object.entries(ObjectType) diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/LogItem.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/LogItem.tsx index dd5a5640b..6199d78e4 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/LogItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/LogItem.tsx @@ -5,10 +5,10 @@ import { import LogObjectContextMenu from "components/ContextMenus/LogObjectContextMenu"; import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import TreeItem from "components/Sidebar/TreeItem"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; -import { MouseEvent, useContext } from "react"; +import { MouseEvent } from "react"; import { getNameOccurrenceSuffix } from "tools/logSameNamesHelper"; interface LogItemProps { @@ -28,7 +28,7 @@ export default function LogItem({ objectGrowing, to }: LogItemProps) { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const onContextMenu = (event: MouseEvent, log: LogObject) => { preventContextMenuPropagation(event); diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/LogTypeItem.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/LogTypeItem.tsx index a77c7ec58..59051024e 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/LogTypeItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/LogTypeItem.tsx @@ -14,10 +14,10 @@ import { IndexCurve } from "components/Modals/LogPropertiesModal"; import LogItem from "components/Sidebar/LogItem"; import TreeItem from "components/Sidebar/TreeItem"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; import { useGetWellbore } from "hooks/query/useGetWellbore"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import { calculateObjectNodeId } from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; @@ -29,7 +29,7 @@ import Wellbore, { calculateMultipleLogsNodeItem, calculateObjectNodeId as calculateWellboreObjectNodeId } from "models/wellbore"; -import { Fragment, MouseEvent, useContext } from "react"; +import { Fragment, MouseEvent } from "react"; import { useParams, useSearchParams } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; import { @@ -48,7 +48,7 @@ export default function LogTypeItem({ wellUid, wellboreUid }: LogTypeItemProps) { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const [searchParams] = useSearchParams(); const { servers } = useGetServers(); const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectGroupItem.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectGroupItem.tsx index 1dafb2f02..f84a6f800 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectGroupItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectGroupItem.tsx @@ -20,7 +20,6 @@ import { isObjectFilterType, objectFilterTypeToObjects } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import { OperationAction } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; import { useSidebar } from "contexts/sidebarContext"; @@ -29,6 +28,7 @@ import { useGetObjectCount } from "hooks/query/useGetObjectCount"; import { useGetObjects } from "hooks/query/useGetObjects"; import { useGetWellbore } from "hooks/query/useGetWellbore"; import { useObjectFilter } from "hooks/useObjectFilter"; +import { useOperationState } from "hooks/useOperationState"; import LogObject from "models/logObject"; import ObjectOnWellbore, { calculateObjectNodeId @@ -60,7 +60,7 @@ export default function ObjectGroupItem({ ObjectContextMenu, onGroupContextMenu }: ObjectGroupItemProps) { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { selectedFilter } = useContext(FilterContext); const { expandedTreeNodes } = useSidebar(); const { diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectOnWellboreItem.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectOnWellboreItem.tsx index 90ca49490..e5d5f169a 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectOnWellboreItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/ObjectOnWellboreItem.tsx @@ -5,12 +5,12 @@ import { import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import TreeItem from "components/Sidebar/TreeItem"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import ObjectOnWellbore from "models/objectOnWellbore"; import { ObjectType } from "models/objectType"; import { calculateObjectNodeId } from "models/wellbore"; -import { ComponentType, MouseEvent, useContext } from "react"; +import { ComponentType, MouseEvent } from "react"; import { useParams } from "react-router-dom"; import { getObjectViewPath } from "routes/utils/pathBuilder"; @@ -31,7 +31,7 @@ export default function ObjectOnWellboreItem({ wellUid, wellboreUid }: ObjectOnWellboreItemProps) { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { connectedServer } = useConnectedServer(); const { wellUid: urlWellUid, diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/SearchFilter.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/SearchFilter.tsx index 183ff3784..0bf41640a 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/SearchFilter.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/SearchFilter.tsx @@ -14,8 +14,8 @@ import { isObjectFilterType, isWellboreFilterType } from "contexts/filter"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; +import { useOperationState } from "hooks/useOperationState"; import React, { useContext, useEffect, useRef, useState } from "react"; import { createSearchParams, useNavigate } from "react-router-dom"; import { getSearchViewPath } from "routes/utils/pathBuilder"; @@ -26,13 +26,13 @@ import Icons from "styles/Icons"; const searchOptions = Object.values(FilterType); const SearchFilter = (): React.ReactElement => { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { selectedFilter, updateSelectedFilter } = useContext(FilterContext); const { connectedServer } = useConnectedServer(); const selectedOption = selectedFilter?.filterType; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); const [expanded, setExpanded] = useState(false); const [nameFilter, setNameFilter] = useState(selectedFilter.name); const textFieldRef = useRef(null); diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx index 7a6699576..b0b833598 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx @@ -9,14 +9,14 @@ import ProgressSpinner from "components/ProgressSpinner"; import SearchFilter from "components/Sidebar/SearchFilter"; import WellItem from "components/Sidebar/WellItem"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; import { useSidebar } from "contexts/sidebarContext"; import { SidebarActionType } from "contexts/sidebarReducer"; import { useGetWells } from "hooks/query/useGetWells"; +import { useOperationState } from "hooks/useOperationState"; import { useWellFilter } from "hooks/useWellFilter"; import Well from "models/well"; -import { Fragment, useContext, useEffect, useRef } from "react"; +import { Fragment, useEffect, useRef } from "react"; import { useParams } from "react-router-dom"; import styled from "styled-components"; import Icon from "styles/Icons"; @@ -30,7 +30,7 @@ export default function Sidebar() { const isDeepLink = useRef(!!wellUid); const { operationState: { colors, theme } - } = useContext(OperationContext); + } = useOperationState(); const isCompactMode = theme === UserTheme.Compact; const filteredWells = useWellFilter(wells); const containerRef = useRef(null); diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/TreeItem.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/TreeItem.tsx index a2f4c520b..d0355195e 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/TreeItem.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/TreeItem.tsx @@ -1,9 +1,9 @@ import { DotProgress } from "@equinor/eds-core-react"; import { Tooltip } from "@mui/material"; import { TreeItem, TreeItemProps } from "@mui/x-tree-view"; -import OperationContext from "contexts/operationContext"; import { UserTheme } from "contexts/operationStateReducer"; -import React, { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import React from "react"; import { NavLink } from "react-router-dom"; import styled from "styled-components"; import { Colors } from "styles/Colors"; @@ -22,12 +22,12 @@ const StyledTreeItem = (props: StyledTreeItemProps): React.ReactElement => { props; const { operationState: { theme } - } = useContext(OperationContext); + } = useOperationState(); const isCompactMode = theme === UserTheme.Compact; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); return ( ((props, ref) => { const { operationState: { colors, theme } - } = useContext(OperationContext); + } = useOperationState(); if (!props.variant || props.variant === "contained") { return ; diff --git a/Src/WitsmlExplorer.Frontend/components/TopRightCornerMenu.tsx b/Src/WitsmlExplorer.Frontend/components/TopRightCornerMenu.tsx index ddcfdd432..39c41fe3d 100644 --- a/Src/WitsmlExplorer.Frontend/components/TopRightCornerMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/TopRightCornerMenu.tsx @@ -6,10 +6,9 @@ import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; import { useLoggedInUsernames } from "contexts/loggedInUsernamesContext"; import { LoggedInUsernamesActionType } from "contexts/loggedInUsernamesReducer"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import useDocumentDimensions from "hooks/useDocumentDimensions"; -import { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; import { useNavigate } from "react-router-dom"; import { getJobsViewPath, getQueryViewPath } from "routes/utils/pathBuilder"; import AuthorizationService from "services/authorizationService"; @@ -17,7 +16,7 @@ import styled from "styled-components"; import Icon from "styles/Icons"; export default function TopRightCornerMenu() { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { width: documentWidth } = useDocumentDimensions(); const showLabels = documentWidth > 1180; const { connectedServer } = useConnectedServer(); diff --git a/Src/WitsmlExplorer.Frontend/contexts/MuiThemeProvider.tsx b/Src/WitsmlExplorer.Frontend/contexts/MuiThemeProvider.tsx new file mode 100644 index 000000000..ad3b4a721 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/contexts/MuiThemeProvider.tsx @@ -0,0 +1,18 @@ +import { ThemeProvider } from "@mui/material"; +import { useOperationState } from "hooks/useOperationState"; +import { ReactElement, ReactNode } from "react"; +import { getTheme } from "styles/material-eds"; + +interface MuiThemeProviderProps { + children: ReactNode; +} + +export const MuiThemeProvider = ({ + children +}: MuiThemeProviderProps): ReactElement => { + const { + operationState: { theme } + } = useOperationState(); + + return {children}; +}; diff --git a/Src/WitsmlExplorer.Frontend/contexts/operationStateProvider.tsx b/Src/WitsmlExplorer.Frontend/contexts/operationStateProvider.tsx new file mode 100644 index 000000000..d94a16507 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/contexts/operationStateProvider.tsx @@ -0,0 +1,108 @@ +import OperationContext from "contexts/operationContext"; +import { + DateTimeFormat, + DecimalPreference, + SetDateTimeFormatAction, + SetDecimalAction, + SetHotKeysEnabledAction, + SetModeAction, + SetThemeAction, + SetTimeZoneAction, + TimeZone, + UserTheme, + initOperationStateReducer +} from "contexts/operationStateReducer"; +import OperationType from "contexts/operationType"; +import { enableDarkModeDebug } from "debugUtils/darkModeDebug"; +import { ReactNode, useEffect } from "react"; +import { dark, light } from "styles/Colors"; +import { + STORAGE_DATETIMEFORMAT_KEY, + STORAGE_DECIMAL_KEY, + STORAGE_HOTKEYS_ENABLED_KEY, + STORAGE_MODE_KEY, + STORAGE_THEME_KEY, + STORAGE_TIMEZONE_KEY, + getLocalStorageItem +} from "tools/localStorageHelpers"; + +interface OperationStateProviderProps { + children: ReactNode; +} + +export const OperationStateProvider = ({ + children +}: OperationStateProviderProps) => { + const [operationState, dispatchOperation] = initOperationStateReducer(); + + useEffect(() => { + if (typeof localStorage != "undefined") { + const localStorageTheme = + getLocalStorageItem(STORAGE_THEME_KEY); + if (localStorageTheme) { + const action: SetThemeAction = { + type: OperationType.SetTheme, + payload: localStorageTheme + }; + dispatchOperation(action); + } + const storedTimeZone = + getLocalStorageItem(STORAGE_TIMEZONE_KEY); + if (storedTimeZone) { + const action: SetTimeZoneAction = { + type: OperationType.SetTimeZone, + payload: storedTimeZone + }; + dispatchOperation(action); + } + const storedMode = getLocalStorageItem<"light" | "dark">( + STORAGE_MODE_KEY + ); + if (storedMode) { + const action: SetModeAction = { + type: OperationType.SetMode, + payload: storedMode == "light" ? light : dark + }; + dispatchOperation(action); + } + const storedDateTimeFormat = getLocalStorageItem( + STORAGE_DATETIMEFORMAT_KEY + ); + if (storedDateTimeFormat) { + const action: SetDateTimeFormatAction = { + type: OperationType.SetDateTimeFormat, + payload: storedDateTimeFormat + }; + dispatchOperation(action); + } + const storedDecimals = + getLocalStorageItem(STORAGE_DECIMAL_KEY); + if (storedDecimals) { + const action: SetDecimalAction = { + type: OperationType.SetDecimal, + payload: storedDecimals + }; + dispatchOperation(action); + } + const storedHotKeysEnabled = getLocalStorageItem( + STORAGE_HOTKEYS_ENABLED_KEY + ); + if (storedHotKeysEnabled != null) { + const action: SetHotKeysEnabledAction = { + type: OperationType.SetHotKeysEnabled, + payload: storedHotKeysEnabled + }; + dispatchOperation(action); + } + } + if (import.meta.env.VITE_DARK_MODE_DEBUG) { + return enableDarkModeDebug(dispatchOperation); + } + }, []); + + return ( + + {children} + + ); +}; diff --git a/Src/WitsmlExplorer.Frontend/contexts/queryContext.tsx b/Src/WitsmlExplorer.Frontend/contexts/queryContext.tsx index 10a421890..72dbea9a2 100644 --- a/Src/WitsmlExplorer.Frontend/contexts/queryContext.tsx +++ b/Src/WitsmlExplorer.Frontend/contexts/queryContext.tsx @@ -1,5 +1,3 @@ -import React, { Dispatch, useEffect } from "react"; -import { v4 as uuid } from "uuid"; import { QueryTemplatePreset, ReturnElements, @@ -7,10 +5,12 @@ import { getQueryTemplateWithPreset } from "components/ContentViews/QueryViewUtils"; import { useLocalStorageState } from "hooks/useLocalStorageState"; +import React, { Dispatch, useEffect } from "react"; import { STORAGE_QUERYVIEW_DATA, getLocalStorageItem } from "tools/localStorageHelpers"; +import { v4 as uuid } from "uuid"; export interface QueryElement { query: string; diff --git a/Src/WitsmlExplorer.Frontend/hooks/query/queryRefreshHelpers.tsx b/Src/WitsmlExplorer.Frontend/hooks/query/queryRefreshHelpers.tsx index beb3f5867..ae6464ce4 100644 --- a/Src/WitsmlExplorer.Frontend/hooks/query/queryRefreshHelpers.tsx +++ b/Src/WitsmlExplorer.Frontend/hooks/query/queryRefreshHelpers.tsx @@ -1,19 +1,19 @@ import { QueryClient } from "@tanstack/react-query"; +import { ObjectFilterType } from "../../contexts/filter"; import { ComponentType, getParentType } from "../../models/componentType"; import { ObjectType } from "../../models/objectType"; import { QUERY_KEY_COMPONENTS, QUERY_KEY_JOB_INFO, QUERY_KEY_OBJECT, - QUERY_KEY_OBJECT_SEARCH, QUERY_KEY_OBJECTS, + QUERY_KEY_OBJECT_SEARCH, QUERY_KEY_SERVERS, QUERY_KEY_WELL, QUERY_KEY_WELLBORE, QUERY_KEY_WELLBORES, QUERY_KEY_WELLS } from "./queryKeys"; -import { ObjectFilterType } from "../../contexts/filter"; export const refreshServersQuery = (queryClient: QueryClient) => { queryClient.invalidateQueries({ diff --git a/Src/WitsmlExplorer.Frontend/hooks/useOpenInQueryView.tsx b/Src/WitsmlExplorer.Frontend/hooks/useOpenInQueryView.tsx index 99c572c03..51c552c13 100644 --- a/Src/WitsmlExplorer.Frontend/hooks/useOpenInQueryView.tsx +++ b/Src/WitsmlExplorer.Frontend/hooks/useOpenInQueryView.tsx @@ -1,8 +1,8 @@ import { QueryTemplatePreset } from "components/ContentViews/QueryViewUtils"; import { useConnectedServer } from "contexts/connectedServerContext"; -import OperationContext from "contexts/operationContext"; import OperationType from "contexts/operationType"; import { QueryActionType, QueryContext } from "contexts/queryContext"; +import { useOperationState } from "hooks/useOperationState"; import { useCallback, useContext } from "react"; import { useNavigate } from "react-router-dom"; import { getQueryViewPath } from "routes/utils/pathBuilder"; @@ -11,7 +11,7 @@ export type OpenInQueryView = (templatePreset: QueryTemplatePreset) => void; export const useOpenInQueryView = () => { const { dispatchQuery } = useContext(QueryContext); - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const { connectedServer } = useConnectedServer(); const navigate = useNavigate(); diff --git a/Src/WitsmlExplorer.Frontend/hooks/useOperationState.tsx b/Src/WitsmlExplorer.Frontend/hooks/useOperationState.tsx new file mode 100644 index 000000000..363d72979 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/hooks/useOperationState.tsx @@ -0,0 +1,11 @@ +import OperationContext from "contexts/operationContext"; +import { useContext } from "react"; + +export function useOperationState() { + const context = useContext(OperationContext); + if (!context) + throw new Error( + `useOperationState() has to be used within ` + ); + return context; +} diff --git a/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx b/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx index 9236b67a0..3039168c1 100644 --- a/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx +++ b/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx @@ -1,14 +1,14 @@ import { useIsAuthenticated } from "@azure/msal-react"; import { useLoggedInUsernames } from "contexts/loggedInUsernamesContext"; import { LoggedInUsernamesActionType } from "contexts/loggedInUsernamesReducer"; -import { useContext, useEffect } from "react"; +import { useOperationState } from "hooks/useOperationState"; +import { useEffect } from "react"; import { Outlet, useNavigate, useParams } from "react-router-dom"; import { ItemNotFound } from "routes/ItemNotFound"; import UserCredentialsModal, { UserCredentialsModalProps } from "../components/Modals/UserCredentialsModal"; import { useConnectedServer } from "../contexts/connectedServerContext"; -import OperationContext from "../contexts/operationContext"; import OperationType from "../contexts/operationType"; import { useGetServers } from "../hooks/query/useGetServers"; import { Server } from "../models/server"; @@ -19,7 +19,7 @@ import AuthorizationService, { } from "../services/authorizationService"; export default function AuthRoute() { - const { dispatchOperation } = useContext(OperationContext); + const { dispatchOperation } = useOperationState(); const isAuthenticated = !msalEnabled || useIsAuthenticated(); const { servers } = useGetServers({ enabled: isAuthenticated }); const { serverUrl } = useParams(); diff --git a/Src/WitsmlExplorer.Frontend/routes/ItemNotFound.tsx b/Src/WitsmlExplorer.Frontend/routes/ItemNotFound.tsx index 031d74b99..80cd0b75f 100644 --- a/Src/WitsmlExplorer.Frontend/routes/ItemNotFound.tsx +++ b/Src/WitsmlExplorer.Frontend/routes/ItemNotFound.tsx @@ -1,7 +1,6 @@ import { Typography } from "@equinor/eds-core-react"; -import { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; import styled from "styled-components"; -import OperationContext from "../contexts/operationContext"; import { Colors } from "../styles/Colors"; export interface ItemNotFoundProps { @@ -12,7 +11,7 @@ export function ItemNotFound(props: ItemNotFoundProps) { const { itemType } = props; const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); return ( <> {`${itemType} Not Found`} diff --git a/Src/WitsmlExplorer.Frontend/routes/PageNotFound.tsx b/Src/WitsmlExplorer.Frontend/routes/PageNotFound.tsx index 11f6f9918..d62dea244 100644 --- a/Src/WitsmlExplorer.Frontend/routes/PageNotFound.tsx +++ b/Src/WitsmlExplorer.Frontend/routes/PageNotFound.tsx @@ -1,12 +1,11 @@ -import { useContext } from "react"; +import { useOperationState } from "hooks/useOperationState"; import styled from "styled-components"; -import OperationContext from "../contexts/operationContext"; import { Colors } from "../styles/Colors"; export function PageNotFound() { const { operationState: { colors } - } = useContext(OperationContext); + } = useOperationState(); return ( <> 404 Not Found diff --git a/Src/WitsmlExplorer.Frontend/routes/Root.tsx b/Src/WitsmlExplorer.Frontend/routes/Root.tsx index 7c380b59c..89839c83e 100644 --- a/Src/WitsmlExplorer.Frontend/routes/Root.tsx +++ b/Src/WitsmlExplorer.Frontend/routes/Root.tsx @@ -1,124 +1,26 @@ import { InteractionType } from "@azure/msal-browser"; import { MsalAuthenticationTemplate, MsalProvider } from "@azure/msal-react"; -import { ThemeProvider } from "@mui/material"; +import ContextMenuPresenter from "components/ContextMenus/ContextMenuPresenter"; import { DesktopAppEventHandler } from "components/DesktopAppEventHandler"; +import { GlobalStylesWrapper } from "components/GlobalStyles"; import { HotKeyHandler } from "components/HotKeyHandler"; +import ModalPresenter from "components/Modals/ModalPresenter"; +import PageLayout from "components/PageLayout"; +import RefreshHandler from "components/RefreshHandler"; +import { Snackbar } from "components/Snackbar"; +import { MuiThemeProvider } from "contexts/MuiThemeProvider"; +import { ConnectedServerProvider } from "contexts/connectedServerContext"; +import { CurveThresholdProvider } from "contexts/curveThresholdContext"; +import { FilterContextProvider } from "contexts/filter"; import { LoggedInUsernamesProvider } from "contexts/loggedInUsernamesContext"; +import { OperationStateProvider } from "contexts/operationStateProvider"; +import { QueryContextProvider } from "contexts/queryContext"; +import { SidebarProvider } from "contexts/sidebarContext"; +import { authRequest, msalEnabled, msalInstance } from "msal/MsalAuthProvider"; import { SnackbarProvider } from "notistack"; -import { useEffect } from "react"; import { isDesktopApp } from "tools/desktopAppHelpers"; -import ContextMenuPresenter from "../components/ContextMenus/ContextMenuPresenter"; -import GlobalStyles from "../components/GlobalStyles"; -import ModalPresenter from "../components/Modals/ModalPresenter"; -import PageLayout from "../components/PageLayout"; -import RefreshHandler from "../components/RefreshHandler"; -import { Snackbar } from "../components/Snackbar"; -import { ConnectedServerProvider } from "../contexts/connectedServerContext"; -import { CurveThresholdProvider } from "../contexts/curveThresholdContext"; -import { FilterContextProvider } from "../contexts/filter"; -import OperationContext from "../contexts/operationContext"; -import { - DateTimeFormat, - DecimalPreference, - SetDateTimeFormatAction, - SetDecimalAction, - SetHotKeysEnabledAction, - SetModeAction, - SetThemeAction, - SetTimeZoneAction, - TimeZone, - UserTheme, - initOperationStateReducer -} from "../contexts/operationStateReducer"; -import OperationType from "../contexts/operationType"; -import { QueryContextProvider } from "../contexts/queryContext"; -import { SidebarProvider } from "../contexts/sidebarContext"; -import { enableDarkModeDebug } from "../debugUtils/darkModeDebug"; -import { - authRequest, - msalEnabled, - msalInstance -} from "../msal/MsalAuthProvider"; -import { dark, light } from "../styles/Colors"; -import { getTheme } from "../styles/material-eds"; -import { - STORAGE_DATETIMEFORMAT_KEY, - STORAGE_DECIMAL_KEY, - STORAGE_HOTKEYS_ENABLED_KEY, - STORAGE_MODE_KEY, - STORAGE_THEME_KEY, - STORAGE_TIMEZONE_KEY, - getLocalStorageItem -} from "../tools/localStorageHelpers"; export default function Root() { - const [operationState, dispatchOperation] = initOperationStateReducer(); - - useEffect(() => { - if (typeof localStorage != "undefined") { - const localStorageTheme = - getLocalStorageItem(STORAGE_THEME_KEY); - if (localStorageTheme) { - const action: SetThemeAction = { - type: OperationType.SetTheme, - payload: localStorageTheme - }; - dispatchOperation(action); - } - const storedTimeZone = - getLocalStorageItem(STORAGE_TIMEZONE_KEY); - if (storedTimeZone) { - const action: SetTimeZoneAction = { - type: OperationType.SetTimeZone, - payload: storedTimeZone - }; - dispatchOperation(action); - } - const storedMode = getLocalStorageItem<"light" | "dark">( - STORAGE_MODE_KEY - ); - if (storedMode) { - const action: SetModeAction = { - type: OperationType.SetMode, - payload: storedMode == "light" ? light : dark - }; - dispatchOperation(action); - } - const storedDateTimeFormat = getLocalStorageItem( - STORAGE_DATETIMEFORMAT_KEY - ); - if (storedDateTimeFormat) { - const action: SetDateTimeFormatAction = { - type: OperationType.SetDateTimeFormat, - payload: storedDateTimeFormat - }; - dispatchOperation(action); - } - const storedDecimals = - getLocalStorageItem(STORAGE_DECIMAL_KEY); - if (storedDecimals) { - const action: SetDecimalAction = { - type: OperationType.SetDecimal, - payload: storedDecimals - }; - dispatchOperation(action); - } - const storedHotKeysEnabled = getLocalStorageItem( - STORAGE_HOTKEYS_ENABLED_KEY - ); - if (storedHotKeysEnabled != null) { - const action: SetHotKeysEnabledAction = { - type: OperationType.SetHotKeysEnabled, - payload: storedHotKeysEnabled - }; - dispatchOperation(action); - } - } - if (import.meta.env.VITE_DARK_MODE_DEBUG) { - return enableDarkModeDebug(dispatchOperation); - } - }, []); - return ( {msalEnabled && ( @@ -127,9 +29,9 @@ export default function Root() { authenticationRequest={authRequest} /> )} - - - + + + @@ -151,8 +53,8 @@ export default function Root() { - - + + ); } From d9565cf3d1e1e25d2b63e1d177c758f5b257d0dc Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Fri, 14 Jun 2024 07:52:31 +0200 Subject: [PATCH 06/13] FIX-2259 Overlay loading status (#2477) --- .../components/ContentView.tsx | 1 + .../ContentViews/CurveValuesView.tsx | 11 +-- .../components/ContentViews/FluidsView.tsx | 31 ++++---- .../ContentViews/LogCurveInfoListView.tsx | 73 +++++++++--------- .../LogCurveInfoListViewUtils.tsx | 2 + .../components/ContentViews/LogsListView.tsx | 71 +++++++++--------- .../components/ContentViews/MudLogView.tsx | 29 ++++---- .../MultiLogsCurveInfoListView.tsx | 74 +++++++++---------- .../ContentViews/ObjectsListView.tsx | 21 +++--- .../ContentViews/TrajectoriesListView.tsx | 2 +- .../ContentViews/TrajectoryView.tsx | 27 ++++--- .../components/ContentViews/TubularView.tsx | 27 ++++--- .../ContentViews/TubularsListView.tsx | 2 +- .../ContentViews/WbGeometriesListView.tsx | 2 +- .../ContentViews/WbGeometryView.tsx | 27 ++++--- .../ContentViews/WellboresListView.tsx | 29 ++++---- .../components/ContentViews/WellsListView.tsx | 41 +++++----- .../components/ProgressSpinner.tsx | 42 ++++++++++- 18 files changed, 273 insertions(+), 239 deletions(-) diff --git a/Src/WitsmlExplorer.Frontend/components/ContentView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentView.tsx index 90085322c..19d5a8b24 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentView.tsx @@ -10,5 +10,6 @@ export default function ContentView() { } const ContentPanel = styled.div` + position: relative; height: 100%; `; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx index 74dab7310..6483bdcca 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesView.tsx @@ -27,7 +27,7 @@ import formatDateString from "components/DateFormatter"; import ConfirmModal from "components/Modals/ConfirmModal"; import { ReportModal } from "components/Modals/ReportModal"; import { ShowLogDataOnServerModal } from "components/Modals/ShowLogDataOnServerModal"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { Button } from "components/StyledComponents/Button"; import { useConnectedServer } from "contexts/connectedServerContext"; import { DispatchOperation, UserTheme } from "contexts/operationStateReducer"; @@ -340,7 +340,6 @@ export const CurveValuesView = (): React.ReactElement => { }, [startIndex, endIndex, mnemonics, log]); const refreshData = () => { - setTableData([]); setIsLoading(true); setAutoRefresh(false); @@ -566,16 +565,15 @@ export const CurveValuesView = (): React.ReactElement => { ] ); - if (isFetching) { - return ; - } - if (isFetchedLog && !log) { return ; } return ( <> + {(isFetching || isLoading) && ( + + )} { )} - {isLoading && } {!isLoading && !tableData.length && ( No data diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx index 1faddc987..b6edd7044 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx @@ -8,7 +8,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import FluidContextMenu, { FluidContextMenuProps } from "components/ContextMenus/FluidContextMenu"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -270,24 +270,25 @@ export default function FluidsView() { { property: "vis600Rpm", label: "vis600Rpm", type: ContentType.String } ]; - if (isFetching) { - return ; - } - if (isFetched && !fluidsReport) { return ; } return ( - + <> + {isFetching && ( + + )} + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx index 1d039ed6c..511a4f8d8 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx @@ -4,7 +4,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import LogCurveInfoContextMenu, { LogCurveInfoContextMenuProps } from "components/ContextMenus/LogCurveInfoContextMenu"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { CommonPanelContainer } from "components/StyledComponents/Container"; import { useConnectedServer } from "contexts/connectedServerContext"; import { useCurveThreshold } from "contexts/curveThresholdContext"; @@ -114,10 +114,6 @@ export default function LogCurveInfoListView() { }); }; - if (isFetching) { - return ; - } - if (isFetchedLog && !logObject) { return ; } @@ -145,37 +141,40 @@ export default function LogCurveInfoListView() { ]; return ( - logObjects && ( - - ) + <> + {isFetching && } + {logObject && ( + + )} + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListViewUtils.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListViewUtils.tsx index 1c36f9cc6..4145c0045 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListViewUtils.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListViewUtils.tsx @@ -118,6 +118,8 @@ export const getTableData = ( isDepthIndex: boolean, logUid: string = null ) => { + if (!logCurveInfoList) return []; + const isVisibleFunction = (isActive: boolean): (() => boolean) => { return () => { if (isDepthIndex) return true; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx index 8eddec227..c5652f06c 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogsListView.tsx @@ -14,7 +14,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import LogObjectContextMenu from "components/ContextMenus/LogObjectContextMenu"; import { ObjectContextMenuProps } from "components/ContextMenus/ObjectMenuItems"; import formatDateString from "components/DateFormatter"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import { UserTheme } from "contexts/operationStateReducer"; import OperationType from "contexts/operationType"; @@ -151,47 +151,46 @@ export default function LogsListView() { navigate(encodeURIComponent(log.uid)); }; - if (isFetching) { - return ; - } - if (isFetchedWellbore && !wellbore) { return ; } return ( - - - - setShowGraph(!showGraph)} - size={theme === UserTheme.Compact ? "small" : "default"} + <> + {isFetching && } + + + + setShowGraph(!showGraph)} + size={theme === UserTheme.Compact ? "small" : "default"} + /> + + Gantt view{selectedRows.length > 0 && " (selected logs only)"} + + + + {showGraph ? ( + 0 ? selectedRows : logs} /> + ) : ( + + setSelectedRows(rows as LogObjectRow[]) + } + checkableRows + showRefresh + initiallySelectedRows={selectedRows} + downloadToCsvFileName={isTimeIndexed ? "TimeLogs" : "DepthLogs"} /> - - Gantt view{selectedRows.length > 0 && " (selected logs only)"} - - - - {showGraph ? ( - 0 ? selectedRows : logs} /> - ) : ( - - setSelectedRows(rows as LogObjectRow[]) - } - checkableRows - showRefresh - initiallySelectedRows={selectedRows} - downloadToCsvFileName={isTimeIndexed ? "TimeLogs" : "DepthLogs"} - /> - )} - + )} + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx index 4a49c9113..964465af8 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MudLogView.tsx @@ -8,7 +8,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import GeologyIntervalContextMenu, { GeologyIntervalContextMenuProps } from "components/ContextMenus/GeologyIntervalContextMenu"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -138,25 +138,24 @@ export default function MudLogView() { } ); - if (isFetching) { - return ; - } - if (isFetchedMudLog && !mudLog) { return ; } return ( - + <> + {isFetching && } + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx index 7e9c9bd03..05f0ad019 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx @@ -6,7 +6,7 @@ import LogCurveInfoContextMenu, { } from "components/ContextMenus/LogCurveInfoContextMenu"; import { useOperationState } from "hooks/useOperationState"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { CommonPanelContainer } from "components/StyledComponents/Container"; import { useConnectedServer } from "contexts/connectedServerContext"; @@ -128,10 +128,6 @@ export default function MultiLogsCurveInfoListView() { }); }; - if (isFetching) { - return ; - } - const panelElements = [ - ) + <> + {isFetching && } + {logObjects && logCurveInfoList && ( + + )} + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectsListView.tsx index f05a25f8b..68255afc3 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/ObjectsListView.tsx @@ -5,7 +5,7 @@ import { useGetObjects } from "../../hooks/query/useGetObjects"; import { useGetWellbore } from "../../hooks/query/useGetWellbore"; import { ObjectType, pluralizeObjectType } from "../../models/objectType"; import { ItemNotFound } from "../../routes/ItemNotFound"; -import ProgressSpinner from "../ProgressSpinner"; +import { ProgressSpinnerOverlay } from "../ProgressSpinner"; import BhaRunsListView from "./BhaRunsListView"; import ChangeLogsListView from "./ChangeLogsListView"; import FluidsReportsListView from "./FluidsReportListView"; @@ -61,21 +61,22 @@ export function ObjectsListView() { objectGroup as ObjectType ); - if (isFetching) { - return ( - - ); - } - if (isFetchedWellbore && !wellbore) { return ( ); } - return getObjectListView(objectGroup); + return ( + <> + {isFetching && ( + + )} + {getObjectListView(objectGroup)} + + ); } const getObjectListView = (objectType: string) => { diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoriesListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoriesListView.tsx index 16c271836..54cffee01 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoriesListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoriesListView.tsx @@ -105,7 +105,7 @@ export default function TrajectoriesListView() { navigate(encodeURIComponent(trajectory.uid)); }; - const trajectoryRows = trajectories.map((trajectory) => { + const trajectoryRows = trajectories?.map((trajectory) => { return { ...trajectory, ...trajectory.commonData, diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoryView.tsx index b9f4fce21..b36573bef 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoryView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/TrajectoryView.tsx @@ -9,7 +9,7 @@ import TrajectoryStationContextMenu, { TrajectoryStationContextMenuProps } from "components/ContextMenus/TrajectoryStationContextMenu"; import formatDateString from "components/DateFormatter"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -124,23 +124,22 @@ export default function TrajectoryView() { }; }); - if (isFetching) { - return ; - } - if (isFetchedTrajectory && !trajectory) { return ; } return ( - + <> + {isFetching && } + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularView.tsx index ae1c8d619..11e543a9b 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularView.tsx @@ -8,7 +8,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import TubularComponentContextMenu, { TubularComponentContextMenuProps } from "components/ContextMenus/TubularComponentContextMenu"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -138,23 +138,22 @@ export default function TubularView() { }; }); - if (isFetching) { - return ; - } - if (isFetchedTubular && !tubular) { return ; } return ( - + <> + {isFetching && } + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularsListView.tsx index 57d7168f5..c01b587b4 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/TubularsListView.tsx @@ -73,7 +73,7 @@ export default function TubularsListView() { navigate(encodeURIComponent(tubular.uid)); }; - const tubularRows = tubulars.map((tubular) => { + const tubularRows = tubulars?.map((tubular) => { return { ...tubular, dTimCreation: formatDateString( diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx index 760496de9..67f9f0c82 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometriesListView.tsx @@ -41,7 +41,7 @@ export default function WbGeometriesListView() { useExpandSidebarNodes(wellUid, wellboreUid, ObjectType.WbGeometry); const getTableData = () => { - return wbGeometries.map((wbGeometry) => { + return wbGeometries?.map((wbGeometry) => { return { ...wbGeometry, mdBottom: measureToString(wbGeometry.mdBottom), diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx index 0f3052703..e6d6b5387 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WbGeometryView.tsx @@ -8,7 +8,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import WbGeometrySectionContextMenu, { WbGeometrySectionContextMenuProps } from "components/ContextMenus/WbGeometrySectionContextMenu"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetComponents } from "hooks/query/useGetComponents"; @@ -120,23 +120,22 @@ export default function WbGeometryView() { }; }); - if (isFetching) { - return ; - } - if (isFetchedWbGeometry && !wbGeometry) { return ; } return ( - + <> + {isFetching && } + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx index a1a994b5d..34f63e763 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellboresListView.tsx @@ -9,7 +9,7 @@ import WellboreContextMenu, { WellboreContextMenuProps } from "components/ContextMenus/WellboreContextMenu"; import formatDateString from "components/DateFormatter"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; @@ -117,24 +117,23 @@ export default function WellboresListView() { ); }; - if (isFetching) { - return ; - } - if (isFetchedWell && !well) { return ; } return ( - + <> + {isFetching && } + + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx index cdaec9146..8fdbfc5b9 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/WellsListView.tsx @@ -10,7 +10,7 @@ import WellContextMenu, { WellContextMenuProps } from "components/ContextMenus/WellContextMenu"; import formatDateString from "components/DateFormatter"; -import ProgressSpinner from "components/ProgressSpinner"; +import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; import { useGetServers } from "hooks/query/useGetServers"; @@ -94,24 +94,25 @@ export default function WellsListView() { }); }; - if (isFetching) { - return ( - - ); - } - - return wells?.length === 0 ? ( - No wells found. - ) : ( - + return ( + <> + {isFetching && ( + + )} + {!isFetching && wells?.length === 0 ? ( + No wells found. + ) : ( + + )} + ); } diff --git a/Src/WitsmlExplorer.Frontend/components/ProgressSpinner.tsx b/Src/WitsmlExplorer.Frontend/components/ProgressSpinner.tsx index 4200bd3fd..c9ff09ced 100644 --- a/Src/WitsmlExplorer.Frontend/components/ProgressSpinner.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ProgressSpinner.tsx @@ -1,6 +1,8 @@ import { CircularProgress, Typography } from "@equinor/eds-core-react"; -import React from "react"; +import OperationContext from "contexts/operationContext"; +import React, { useContext } from "react"; import styled from "styled-components"; +import { Colors, dark } from "styles/Colors"; type Props = { message?: string; @@ -21,6 +23,44 @@ const ProgressSpinner = ({ message }: Props): React.ReactElement => { ); }; +export const ProgressSpinnerOverlay = ({ + message +}: Props): React.ReactElement => { + const { + operationState: { colors } + } = useContext(OperationContext); + return ( + + + + + + ); +}; + +const Overlay = styled.div<{ colors: Colors }>` + position: absolute; + width: 100%; + height: 100%; + background: ${(props) => + props.colors === dark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)"}; + z-index: 999; + display: flex; + justify-content: center; + align-items: center; +`; + +const InnerOverlay = styled.div<{ colors: Colors }>` + background-color: ${(props) => props.colors.ui.backgroundDefault}; + color: ${(props) => props.colors.text.staticIconsDefault}; + display: flex; + flex-direction: column; + align-items: center; + padding: 64px; + box-shadow: 1px 4px 5px rgba(0, 0, 0, 0.1); + border-radius: 4px; +`; + const ProgressLayout = styled.div` display: flex; flex-direction: column; From 0483a27189830751b2d8a07d23c5fb9f2b5b484d Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Fri, 14 Jun 2024 09:51:47 +0200 Subject: [PATCH 07/13] FIX-2444 Open credential modal when navigating back to another server (#2478) --- .../contexts/operationStateReducer.tsx | 10 +++++++++- Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Src/WitsmlExplorer.Frontend/contexts/operationStateReducer.tsx b/Src/WitsmlExplorer.Frontend/contexts/operationStateReducer.tsx index 4da0ec316..ba1357d21 100644 --- a/Src/WitsmlExplorer.Frontend/contexts/operationStateReducer.tsx +++ b/Src/WitsmlExplorer.Frontend/contexts/operationStateReducer.tsx @@ -1,3 +1,4 @@ +import UserCredentialsModal from "components/Modals/UserCredentialsModal"; import OperationType from "contexts/operationType"; import { Dispatch, ReactElement, useReducer } from "react"; import { Colors, light } from "styles/Colors"; @@ -179,7 +180,14 @@ const displayModal = ( state: OperationState, { payload }: DisplayModalAction ) => { - const modals = state.modals.concat(payload); + const isUserCredentialsModal = payload.type === UserCredentialsModal; + + const modals = isUserCredentialsModal // We don't want to stack login modals + ? state.modals + .filter((modal) => modal.type !== UserCredentialsModal) + .concat(payload) + : state.modals.concat(payload); + return { ...state, contextMenu: EMPTY_CONTEXT_MENU, diff --git a/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx b/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx index 3039168c1..19bf483b1 100644 --- a/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx +++ b/Src/WitsmlExplorer.Frontend/routes/AuthRoute.tsx @@ -59,11 +59,12 @@ export default function AuthRoute() { }, []); useEffect(() => { - if (servers && !connectedServer) { + if (servers && (!connectedServer || connectedServer.url != serverUrl)) { + setConnectedServer(null); const server = servers.find((server) => server.url === serverUrl); if (server) showCredentialsModal(server, true); } - }, [servers]); + }, [servers, serverUrl]); const showCredentialsModal = (server: Server, initialLogin: boolean) => { const userCredentialsModalProps: UserCredentialsModalProps = { From 0fada9db78aa5407f5cbf7569d4eef7610ae11bb Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Mon, 17 Jun 2024 14:54:24 +0200 Subject: [PATCH 08/13] =?UTF-8?q?Missing=20Data=20Agent=20-=20can't=20alwa?= =?UTF-8?q?ys=20see=20the=20whole=20"select=20object"=20and=20=E2=80=9Csel?= =?UTF-8?q?ect=20properties=E2=80=9D=20list=20#2267=20(#2479)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Modals/MissingDataAgentModal.tsx | 4 ++++ .../components/Modals/ModalDialog.tsx | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx b/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx index b38c10a21..0c0f04c88 100644 --- a/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Modals/MissingDataAgentModal.tsx @@ -236,6 +236,8 @@ const MissingDataAgentModal = ( confirmText={`OK`} showCancelButton={true} width={ModalWidth.MEDIUM} + height="800px" + minHeight="650px" isLoading={false} content={ @@ -261,6 +263,7 @@ const MissingDataAgentModal = ( {missingDataChecks.map((missingDataCheck) => ( { @@ -41,10 +43,12 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { errorMessage, switchButtonPlaces, width = ModalWidth.MEDIUM, + height, showConfirmButton = true, showCancelButton = true, buttonPosition: ButtonPosition = ControlButtonPosition.BOTTOM, - cancelText + cancelText, + minHeight } = props; const context = useOperationState(); const [confirmButtonIsFocused, setConfirmButtonIsFocused] = @@ -158,6 +162,7 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { ); const dialogStyle = { width: width, + height: height, background: colors.ui.backgroundDefault, color: colors.text.staticIconsDefault }; @@ -165,7 +170,7 @@ const ModalDialog = (props: ModalDialogProps): React.ReactElement => { return ( {ButtonPosition == ControlButtonPosition.TOP ? top : header} - + {content} {errorMessage && {errorMessage}} @@ -196,9 +201,13 @@ export enum ControlButtonPosition { BOTTOM = "bottom" } -const Content = styled(Dialog.CustomContent)<{ colors: Colors }>` +const Content = styled(Dialog.CustomContent)<{ + colors: Colors; + minHeight: string; +}>` margin-top: 0.5em; max-height: 75vh; + min-height: ${(props) => (props.minHeight ? props.minHeight : "")}; overflow-y: auto; background-color: ${(props) => props.colors.ui.backgroundDefault}; color: ${(props) => props.colors.text.staticIconsDefault}; From 1a343922e3824274c6b14986f9abfc08c8491c01 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:58:35 +0200 Subject: [PATCH 09/13] FIX-2234 Update server setup documentation (#2471) --- Docker/README.md | 2 +- Docker/Server/README.md | 38 +++++++++++++++++++++++++------- Docker/Server/docker-compose.yml | 20 +++++++++++++++++ Docs/AUTH.md | 2 +- Docs/OAUTH.md | 2 +- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Docker/README.md b/Docker/README.md index aa52ed4c9..5bb69ee2c 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -10,7 +10,7 @@ See [setting up a database in Azure](../Scripts/Azure) Build dockerfiles for frontend and backend (see [build_docker_images.sh](../build_docker_images.sh), [Dockerfile-api](../Dockerfile-api) and [Dockerfile-frontend](../Dockerfile-frontend)). -### **Build api and backend images** +### **Build api and frontend images** ```sh ❯ docker build -t witsmlexplorer-api:latest -f Dockerfile-api . Building witsmlexplorer-api... diff --git a/Docker/Server/README.md b/Docker/Server/README.md index 635c1dcd3..782ec8f7a 100644 --- a/Docker/Server/README.md +++ b/Docker/Server/README.md @@ -1,19 +1,41 @@ # Deploy on server +## Configure application + +Configure your application according to [this guide](../README.md#deploy-and-run-witsml-explorer) + +## OAUTH + +If you are planning on using OAUTH with Azure, see [OAUTH.md](../../Docs/OAUTH.md) + +## Configure docker-compose.yml + +You will find a [docker-compose-yml](./docker-compose.yml) that is similar to the one used for running docker-compose locally. The difference is that `web` and `api` containers do not expose their ports outside of docker, and that an nginx instance is running in front forwarding the requests. + +In `docker-compose.yml` ensure that the volumes that are mapped into the containers for nginx from the host OS have the correct host path. + +## Configure nginx Running on a server requires running an nginx in front of the api and the web containers. This is needed for configuring SSL. -You will find a [docker-compose-yml](./docker-compose-yml) that is similar to the one used for running docker-compose locally. +The volume `/etc/nginx` requires both an [`nginx.conf`](nginx.conf) file, and a `certs` directory. Here you need to place the certificate and key files. Ensure that the naming corresponds to what you configure in the `nginx.conf` file. + +## Build docker images -The difference is that `web` and `api` containers do not expose their ports outside of docker, and that an nginx instance is running in front forwarding the requests. +Follow [Run locally with docker](../README.md#build-api-and-frontend-images) to build the docker images. You can either clone the application and build the images locally on the server, or create a workflow to build the images and then push them to a container registry. Make sure you use the same name in the building process and in docker-compose.yml. -## docker-compose.yml and nginx.conf -You might need to do some changes to make this run on a server. -* In `docker-compose.yml` ensure that the volumes that are mapped into the containers for nginx from the host OS have the correct host path. -* The volume `/etc/nginx` requires both an `nginx.conf` file which you can find next to the `docker-compose.yml` file, and also a `certs` directory. Here you need to place the certificate and key files. Ensure that the naming corresponds to what you configure in the `nginx.conf` file. +## Start docker containers When the configuration is in place, run the following to pull fresh images and run them: -* `docker-compose pull` -* `docker-compose up`. Add `-d` if you want to run the application in the background +* `docker-compose pull`. +* `docker-compose up -d`. `-d` makes the application run in the background. * Go to `https://yourserver` to open the application * Use `docker-compose down` to stop the application + +## Update your application + +Before you update your application, make sure that no jobs are running. + +To update your application, build and pull your new containers, and re-run `docker-compose up -d`. + +Run `docker image prune --force --filter dangling=true` to remove dangling images. diff --git a/Docker/Server/docker-compose.yml b/Docker/Server/docker-compose.yml index ccfb5521a..952adef1f 100644 --- a/Docker/Server/docker-compose.yml +++ b/Docker/Server/docker-compose.yml @@ -1,17 +1,37 @@ version: '3.7' services: + + mongo: # Remove this if you are not using mongodb. + image: mongo:4.4.1 + container_name: witsmlexplorer-mongodb + restart: unless-stopped + ports: + - 27017:27017 + volumes: + - ./data:/data/db + environment: + - MONGO_INITDB_ROOT_USERNAME= # Configure this + - MONGO_INITDB_ROOT_PASSWORD= # Configure this + api: image: witsmlexplorer-api:latest + restart: unless-stopped container_name: witsmlexplorer-api volumes: - ./config.json:/app/config.json:ro #May be changed + depends_on: # Remove this if you are not using mongodb. + - mongo + links: # Remove this if you are not using mongodb. + - mongo:mongo web: image: witsmlexplorer-frontend:latest + restart: unless-stopped container_name: witsmlexplorer-frontend nginx: image: nginx:1.21-alpine + restart: unless-stopped container_name: witsmlexplorer-nginx ports: - 80:80 diff --git a/Docs/AUTH.md b/Docs/AUTH.md index d0fffc4c3..c140cfdb9 100644 --- a/Docs/AUTH.md +++ b/Docs/AUTH.md @@ -18,4 +18,4 @@ Accessing the API without a frontend is explained at the end of each of the docu Basic mode uses a session cookie to keep track of the user. This mode is used by setting `"OAuth2Enabled": false` in the API configuration and empty `VITE_MSALENABLED=` in the frontend environment. Basic flow is explained in [BASIC_AUTH.md](./BASIC_AUTH.md). -OAuth mode uses JWT authentication to keep track of the user. This mode is used by setting `"OAuth2Enabled": true` in the API configuration and `VITE_MSALENABLED=true` in the frontend environment. OAUTH flow is explained in [OAUTH.md](./OAUTH.md). +OAuth mode uses JWT authentication to keep track of the user. This mode is used by setting `"OAuth2Enabled": true` in the API configuration and `VITE_MSALENABLED=true` in the frontend environment. Current OAUTH implementation only supports Azure Entra ID. OAUTH flow is explained in [OAUTH.md](./OAUTH.md). diff --git a/Docs/OAUTH.md b/Docs/OAUTH.md index 123ac6110..c6126467b 100644 --- a/Docs/OAUTH.md +++ b/Docs/OAUTH.md @@ -30,7 +30,7 @@ Example `mysettings.json` file for API: } ``` -Required environment variables in frontend: +Required environment variables in frontend [Dockerfile](../Dockerfile-frontend). ```bash # To disable MSAL, leave VITE_MSALENABLED empty From a9aa7bb9b26b7057ef4cc14f83fd701a5fc4d513 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:36:40 +0200 Subject: [PATCH 10/13] FIX-2482 Format dTim for fluidsReports (#2483) --- .../components/ContentViews/FluidsReportListView.tsx | 3 ++- .../components/ContentViews/FluidsView.tsx | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx index 75be91593..407266f8b 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsReportListView.tsx @@ -49,6 +49,7 @@ export default function FluidsReportsListView() { fluidsReport: fluidsReport, md: measureToString(fluidsReport.md), tvd: measureToString(fluidsReport.tvd), + dTim: formatDateString(fluidsReport.dTim, timeZone, dateTimeFormat), dTimCreation: formatDateString( fluidsReport.commonData.dTimCreation, timeZone, @@ -65,7 +66,7 @@ export default function FluidsReportsListView() { const columns: ContentTableColumn[] = [ { property: "name", label: "name", type: ContentType.String }, - { property: "dTim", label: "dTim", type: ContentType.String }, + { property: "dTim", label: "dTim", type: ContentType.DateTime }, { property: "md", label: "md", type: ContentType.Measure }, { property: "tvd", label: "tvd", type: ContentType.Measure }, { property: "numReport", label: "numReport", type: ContentType.String }, diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx index b6edd7044..813849d58 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/FluidsView.tsx @@ -8,6 +8,7 @@ import { getContextMenuPosition } from "components/ContextMenus/ContextMenu"; import FluidContextMenu, { FluidContextMenuProps } from "components/ContextMenus/FluidContextMenu"; +import formatDateString from "components/DateFormatter"; import { ProgressSpinnerOverlay } from "components/ProgressSpinner"; import { useConnectedServer } from "contexts/connectedServerContext"; import OperationType from "contexts/operationType"; @@ -32,7 +33,10 @@ interface FluidsRow extends ContentTableRow, FluidAsStrings { } export default function FluidsView() { - const { dispatchOperation } = useOperationState(); + const { + operationState: { timeZone, dateTimeFormat }, + dispatchOperation + } = useOperationState(); const { wellUid, wellboreUid, objectUid } = useParams(); const { connectedServer } = useConnectedServer(); const { object: fluidsReport } = useGetObject( @@ -85,7 +89,7 @@ export default function FluidsView() { label: "locationSample", type: ContentType.String }, - { property: "dTim", label: "dTim", type: ContentType.String }, + { property: "dTim", label: "dTim", type: ContentType.DateTime }, { property: "md", label: "md", type: ContentType.Measure }, { property: "tvd", label: "tvd", type: ContentType.Measure }, { @@ -189,7 +193,7 @@ export default function FluidsView() { uid: fluid.uid, type: fluid.type, locationSample: fluid.locationSample, - dTim: fluid.dTim, + dTim: formatDateString(fluid.dTim, timeZone, dateTimeFormat), md: measureToString(fluid.md), tvd: measureToString(fluid.tvd), presBopRating: measureToString(fluid.presBopRating), From d665570d53280225f664a5b6f9c0e7bd4bafb590 Mon Sep 17 00:00:00 2001 From: Elias Kristoffer Bruvik <70512270+eliasbruvik@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:02:16 +0200 Subject: [PATCH 11/13] FIX-2094 Plot Improvements (#2480) --- .../ContentViews/CurveDataTransformation.ts | 126 +++++++++ .../ContentViews/CurveValuesPlot.tsx | 242 ++++++++++++++---- 2 files changed, 319 insertions(+), 49 deletions(-) create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/CurveDataTransformation.ts diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveDataTransformation.ts b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveDataTransformation.ts new file mode 100644 index 000000000..ada046c29 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveDataTransformation.ts @@ -0,0 +1,126 @@ +import { ExportableContentTableColumn } from "components/ContentViews/table"; +import { CurveSpecification } from "models/logData"; + +const calculateMean = (arr: number[]): number => + arr.reduce((a, b) => a + b, 0) / arr.length; + +const calculateStdDev = (arr: number[], mean: number): number => { + const variance = + arr.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / arr.length; + return Math.sqrt(variance); +}; + +const calculateZScore = (value: number, mean: number, stdDev: number): number => + (value - mean) / stdDev; + +interface ZScoreThreshold { + global: number; + local: number; + windowSize: number; +} + +export enum ThresholdLevel { + Low = "low", + Medium = "medium", + High = "high" +} + +const zScoreThresholds: Record = { + [ThresholdLevel.Low]: { + global: 2, + local: 2.5, + windowSize: 12 + }, + [ThresholdLevel.Medium]: { + global: 1.5, + local: 1.5, + windowSize: 20 + }, + [ThresholdLevel.High]: { + global: 0.7, + local: 0.5, + windowSize: 28 + } +}; + +/** + * Removes outliers from the provided data based on Z-score thresholds applied globally and locally within a moving window. + * + * @param {any[]} data - The dataset to process, where each element is an object containing various numeric properties. + * @param {ExportableContentTableColumn[]} columns - The columns specification, where the first column represents the index curve. + * @param {ZScoreThreshold} zScoreThreshold - An object containing `global` and `local` thresholds and 'windowSize' size for Z-score calculations. + * - `global`: The Z-score threshold to identify potential outliers globally across the entire dataset. + * - `local`: The Z-score threshold to identify outliers within the moving window. + * - `windowSize`: The size of the moving window. + * @returns {any[]} The transformed dataset with outliers removed. + */ +export const removeCurveDataOutliers = ( + data: any[], + columns: ExportableContentTableColumn[], + thresholdLevel: ThresholdLevel +): any[] => { + const transformedData = data.map((dataRow) => ({ ...dataRow })); + const indexCurve = columns[0].columnOf.mnemonic; + const zScoreThreshold = zScoreThresholds[thresholdLevel]; + + columns + .filter((col) => col.columnOf.mnemonic !== indexCurve) + .forEach((col) => { + const mnemonic = col.columnOf.mnemonic; + const originalIndices = data + .map((dataRow, index) => ({ value: dataRow[mnemonic], index })) + .filter( + (dataRow) => dataRow.value !== undefined && dataRow.value !== null + ); + const columnData = originalIndices.map((dataRow) => dataRow.value); + const mean = calculateMean(columnData); + const stdDev = calculateStdDev(columnData, mean); + if (stdDev) { + for (let i = 0; i < columnData.length; i++) { + const originalIndex = originalIndices[i].index; + const zScoreValue = calculateZScore(columnData[i], mean, stdDev); + if (Math.abs(zScoreValue) > zScoreThreshold.global) { + const start = Math.max( + 0, + i - Math.floor(zScoreThreshold.windowSize / 2) + ); + const end = Math.min( + columnData.length, + i + Math.ceil(zScoreThreshold.windowSize / 2) + ); + const window = columnData.slice(start, end); + const windowMean = calculateMean(window); + const windowStdDev = calculateStdDev(window, windowMean); + if (windowStdDev) { + const windowZScoreValue = calculateZScore( + columnData[i], + windowMean, + windowStdDev + ); + if (Math.abs(windowZScoreValue) > zScoreThreshold.local) { + delete transformedData[originalIndex][mnemonic]; + } + } + } + } + } + }); + + return transformedData; +}; + +export const transformCurveData = ( + data: any[], + columns: ExportableContentTableColumn[], + thresholdLevel: ThresholdLevel, + removeOutliers: boolean +) => { + let transformedData = data; + + if (removeOutliers) { + transformedData = removeCurveDataOutliers(data, columns, thresholdLevel); + } + // Other potential transformations should be added here. + + return transformedData; +}; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx index a16084d24..ceedce8b3 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/CurveValuesPlot.tsx @@ -1,15 +1,33 @@ +import { EdsProvider, Switch, Typography } from "@equinor/eds-core-react"; +import { + ThresholdLevel, + transformCurveData +} from "components/ContentViews/CurveDataTransformation"; import { ContentType, ExportableContentTableColumn } from "components/ContentViews/table"; import formatDateString from "components/DateFormatter"; import { ContentViewDimensionsContext } from "components/PageLayout"; -import { DateTimeFormat, TimeZone } from "contexts/operationStateReducer"; +import { StyledNativeSelect } from "components/Select"; +import { CommonPanelContainer } from "components/StyledComponents/Container"; +import { + DateTimeFormat, + TimeZone, + UserTheme +} from "contexts/operationStateReducer"; import { ECharts } from "echarts"; import ReactEcharts from "echarts-for-react"; import { useOperationState } from "hooks/useOperationState"; import { CurveSpecification } from "models/logData"; -import React, { useContext, useEffect, useRef, useState } from "react"; +import React, { + ChangeEvent, + useContext, + useEffect, + useMemo, + useRef, + useState +} from "react"; import { useParams } from "react-router-dom"; import { RouterLogType } from "routes/routerConstants"; import { Colors } from "styles/Colors"; @@ -17,6 +35,7 @@ import { Colors } from "styles/Colors"; const COLUMN_WIDTH = 135; const MNEMONIC_LABEL_WIDTH = COLUMN_WIDTH - 10; const TOOLTIP_OFFSET_Y = 30; +const GAP_DISTANCE = 3; interface ControlledTooltipProps { visible: boolean; @@ -45,8 +64,12 @@ export const CurveValuesPlot = React.memo( (col, index) => col.type === ContentType.Number || index === 0 ); const { - operationState: { colors, dateTimeFormat } + operationState: { colors, dateTimeFormat, theme } } = useOperationState(); + const [enableScatter, setEnableScatter] = useState(false); + const [removeOutliers, setRemoveOutliers] = useState(false); + const [outliersThresholdLevel, setOutliersThresholdLevel] = + useState(ThresholdLevel.Medium); const chart = useRef(null); const selectedLabels = useRef>(null); const scrollIndex = useRef(0); @@ -65,6 +88,16 @@ export const CurveValuesPlot = React.memo( useState({ visible: false } as ControlledTooltipProps); + const transformedData = useMemo( + () => + transformCurveData( + data, + columns, + outliersThresholdLevel, + !autoRefresh && removeOutliers + ), + [data, columns, outliersThresholdLevel, removeOutliers, autoRefresh] + ); useEffect(() => { if (contentViewWidth) { @@ -78,7 +111,7 @@ export const CurveValuesPlot = React.memo( }, [contentViewWidth]); const chartOption = getChartOption( - data, + transformedData, columns, name, colors, @@ -90,7 +123,8 @@ export const CurveValuesPlot = React.memo( scrollIndex.current, horizontalZoom.current, verticalZoom.current, - isTimeLog + isTimeLog, + enableScatter ); const onMouseOver = (e: any) => { @@ -183,44 +217,99 @@ export const CurveValuesPlot = React.memo( }; return ( -
- (chart.current = c)} - style={{ - height: "100%", - minWidth: `${width}px`, - maxWidth: `${width}px` - }} - /> +
+ + + setEnableScatter(!enableScatter)} + size={theme === UserTheme.Compact ? "small" : "default"} + /> + + Scatter Plot + + {!autoRefresh && ( + <> + setRemoveOutliers(!removeOutliers)} + size={theme === UserTheme.Compact ? "small" : "default"} + /> + + Hide Outliers + + {removeOutliers && ( + <> + + Sensitivity: + + ) => + setOutliersThresholdLevel( + event.target.value as ThresholdLevel + ) + } + value={outliersThresholdLevel} + colors={colors} + > + {Object.values(ThresholdLevel).map((value) => { + return ( + + ); + })} + + + )} + + )} + +
- {controlledTooltip.content} + (chart.current = c)} + style={{ + height: "100%", + minWidth: `${width}px`, + maxWidth: `${width}px` + }} + /> +
+ {controlledTooltip.content} +
); @@ -241,7 +330,8 @@ const getChartOption = ( scrollIndex: number, horizontalZoom: [number, number], verticalZoom: [number, number], - isTimeLog: boolean + isTimeLog: boolean, + enableScatter: boolean ) => { const VALUE_OFFSET_FROM_COLUMN = 0.01; const AUTO_REFRESH_SIZE = 300; @@ -405,7 +495,7 @@ const getChartOption = ( start: verticalZoom[0], end: verticalZoom[1], orient: "vertical", - filterMode: "empty", + filterMode: enableScatter ? "empty" : "none", type: "slider", labelFormatter: () => "" }, @@ -437,14 +527,23 @@ const getChartOption = ( const minMaxValue = minMaxValues.find( (v) => v.curve == col.columnOf.mnemonic ); - return { - large: true, - symbolSize: data.length > 200 ? 2 : 5, - name: col.label, - type: "scatter", - data: data.map((row) => { + + const offsetData = data + .map((row, rowIndex) => { const index = row[indexCurve]; const value = row[col.columnOf.mnemonic]; + const isSmallGap = + !enableScatter && + value === undefined && + hasDataWithinRange( + data, + rowIndex, + col.columnOf.mnemonic, + GAP_DISTANCE + ); + if (isSmallGap) { + return null; // Return null and filter it away later to draw lines over small gaps. + } const normalizedValue = (value - minMaxValue.minValue) / (minMaxValue.maxValue - minMaxValue.minValue || 1); @@ -454,11 +553,56 @@ const getChartOption = ( i; return [offsetNormalizedValue, index]; }) + .filter((r) => r !== null); + + return { + large: true, + connectNulls: false, + symbolSize: enableScatter + ? data.length > 200 + ? 2 + : 5 + : (value: any, params: any) => { + const isIsolated = + value !== undefined && + isNaN(offsetData[Math.max(0, params.dataIndex - 1)][0]) && + isNaN( + offsetData[ + Math.min(offsetData.length - 1, params.dataIndex + 1) + ][0] + ); + return isIsolated ? 1 : 0; // Only isolated data points should have a symbol for the line plot + }, + emphasis: { + disabled: true + }, + name: col.label, + type: enableScatter ? "scatter" : "line", + showSymbol: true, + data: offsetData }; }) }; }; +const hasDataWithinRange = ( + data: any[], + valueIndex: number, + mnemonic: string, + distanceFromIndex: number +): boolean => { + const start = Math.max(0, valueIndex - distanceFromIndex); + const end = Math.min(data.length, valueIndex + distanceFromIndex); + const window = [ + ...data.slice(start, valueIndex), + ...data.slice(valueIndex + 1, end + 1) + ]; + if (window.some((d) => d[mnemonic] !== undefined)) { + return true; + } + return false; +}; + const timeFormatter = (params: number, dateTimeFormat: DateTimeFormat) => { const dateTime = new Date(Math.round(params)); return formatDateString( From edce3f62d449070e8e5e7befa3520a49d828c36c Mon Sep 17 00:00:00 2001 From: matusmlichsk <61700762+matusmlichsk@users.noreply.github.com> Date: Mon, 24 Jun 2024 08:28:33 +0200 Subject: [PATCH 12/13] FIX-2476 Inform user when no active wells are available and inactive are hidden (#2484) --- .../components/Sidebar/FilterPanel.tsx | 5 ++- .../InactiveWellsHiddenFilterHelper.tsx | 26 ++++++++++++ .../InactiveWellsHiddenFilterHelper/index.ts | 1 + .../components/Sidebar/Sidebar.tsx | 41 +++++++++++++------ .../components/StyledComponents/Chip/Chip.tsx | 38 +++++++++++++++++ .../components/StyledComponents/Chip/index.ts | 1 + 6 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/InactiveWellsHiddenFilterHelper.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/index.ts create mode 100644 Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/index.ts diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx index 51e533254..e6b30be61 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/FilterPanel.tsx @@ -16,12 +16,12 @@ import React, { ChangeEvent, useContext } from "react"; import styled from "styled-components"; import { Colors } from "styles/Colors"; import { + setLocalStorageItem, STORAGE_FILTER_HIDDENOBJECTS_KEY, STORAGE_FILTER_INACTIVE_TIME_CURVES_KEY, STORAGE_FILTER_INACTIVE_TIME_CURVES_VALUE_KEY, STORAGE_FILTER_ISACTIVE_KEY, - STORAGE_FILTER_OBJECTGROWING_KEY, - setLocalStorageItem + STORAGE_FILTER_OBJECTGROWING_KEY } from "tools/localStorageHelpers"; const FilterPanel = (): React.ReactElement => { @@ -242,6 +242,7 @@ const StyledTextField = styled(TextField)<{ colors: Colors }>` label { color: ${(props) => props.colors.text.staticTextLabel}; } + div { background: ${(props) => props.colors.text.staticTextFieldDefault}; } diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/InactiveWellsHiddenFilterHelper.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/InactiveWellsHiddenFilterHelper.tsx new file mode 100644 index 000000000..d48f620a2 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/InactiveWellsHiddenFilterHelper.tsx @@ -0,0 +1,26 @@ +import React, { FC, useContext } from "react"; +import { FilterContext } from "../../../contexts/filter.tsx"; +import { + setLocalStorageItem, + STORAGE_FILTER_ISACTIVE_KEY +} from "../../../tools/localStorageHelpers.tsx"; +import { Icon } from "@equinor/eds-core-react"; +import { Chip } from "../../StyledComponents/Chip"; + +export const InactiveWellsHiddenFilterHelper: FC = () => { + const { selectedFilter, updateSelectedFilter } = useContext(FilterContext); + + const handleClearFilterProperty = () => { + setLocalStorageItem(STORAGE_FILTER_ISACTIVE_KEY, false); + updateSelectedFilter({ isActive: false }); + }; + + if (!selectedFilter.isActive) return null; + + return ( + + + Inactive Wells are hidden + + ); +}; diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/index.ts b/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/index.ts new file mode 100644 index 000000000..d5c3dc490 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/InactiveWellsHiddenFilterHelper/index.ts @@ -0,0 +1 @@ +export * from "./InactiveWellsHiddenFilterHelper"; diff --git a/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx b/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx index b0b833598..fe64e8e4c 100644 --- a/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx +++ b/Src/WitsmlExplorer.Frontend/components/Sidebar/Sidebar.tsx @@ -1,9 +1,9 @@ import { Divider, Typography } from "@equinor/eds-core-react"; import { TreeView } from "@mui/x-tree-view"; import { + useVirtualizer, VirtualItem, - Virtualizer, - useVirtualizer + Virtualizer } from "@tanstack/react-virtual"; import ProgressSpinner from "components/ProgressSpinner"; import SearchFilter from "components/Sidebar/SearchFilter"; @@ -16,11 +16,13 @@ import { useGetWells } from "hooks/query/useGetWells"; import { useOperationState } from "hooks/useOperationState"; import { useWellFilter } from "hooks/useWellFilter"; import Well from "models/well"; -import { Fragment, useEffect, useRef } from "react"; +import { Fragment, SyntheticEvent, useEffect, useRef } from "react"; import { useParams } from "react-router-dom"; import styled from "styled-components"; import Icon from "styles/Icons"; import { WellIndicator } from "../StyledComponents/WellIndicator"; +import { InactiveWellsHiddenFilterHelper } from "./InactiveWellsHiddenFilterHelper"; +import { Stack } from "@mui/material"; export default function Sidebar() { const { connectedServer } = useConnectedServer(); @@ -55,7 +57,7 @@ export default function Sidebar() { } }, [filteredWells]); - const onNodeToggle = (_: React.SyntheticEvent, nodeIds: string[]) => { + const onNodeToggle = (_: SyntheticEvent, nodeIds: string[]) => { if (nodeIds !== expandedTreeNodes) { dispatchSidebar({ type: SidebarActionType.SetTreeNodes, @@ -64,19 +66,29 @@ export default function Sidebar() { } }; + if (isFetching) + return ( + <> + + {!!connectedServer && ( + + + + )} + + ); + return ( {!!connectedServer && ( - {isFetching ? ( - - ) : ( - filteredWells && + {filteredWells && (filteredWells.length === 0 ? ( - - No wells match the current filter - + + No wells match the current filter + + ) : ( - )) - )} + ))} )} @@ -144,13 +155,17 @@ const SidebarTreeView = styled.div` height: 70%; padding-left: 1em; padding-right: 0.3em; + .MuiTreeItem-root { min-width: 0; + .MuiTreeItem-iconContainer { flex: none; } + .MuiTreeItem-label { min-width: 0; + p { white-space: nowrap; overflow: hidden; diff --git a/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx new file mode 100644 index 000000000..cb32ddbe4 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx @@ -0,0 +1,38 @@ +import React, { forwardRef } from "react"; +import { Chip as EquinorChip, ChipProps } from "@equinor/eds-core-react"; +import styled, { css } from "styled-components"; +import { Colors } from "../../../styles/Colors.tsx"; +import { useOperationState } from "../../../hooks/useOperationState.tsx"; + +type WithTheme = T & { colors: Colors }; + +export const Chip = forwardRef( + ({ variant = "default", ...props }, ref) => { + const { + operationState: { colors } + } = useOperationState(); + + const commonProps = { ref, variant, ...props }; + + switch (variant) { + case "default": + return ; + default: + return ; + } + } +); + +Chip.displayName = "WitsmlExplorerChip"; + +const WitsmlDefaultChip = styled(EquinorChip)` + ${({ colors: { ui, mode, interactive } }) => { + if (mode === "light") return; + + return css` + --eds_ui_background__light: ${ui.backgroundLight}; + --eds_interactive_primary__resting: ${interactive.primaryResting}; + --eds_interactive_primary__hover_alt: ${ui.backgroundDefault}; + `; + }} +`; diff --git a/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/index.ts b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/index.ts new file mode 100644 index 000000000..ecfadf0ca --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/index.ts @@ -0,0 +1 @@ +export * from "./Chip.tsx"; From d2b6fdf714dbbe2b935939eaad528932fe6c83af Mon Sep 17 00:00:00 2001 From: Robert Basti Date: Tue, 25 Jun 2024 10:26:50 +0200 Subject: [PATCH 13/13] New bump desktop version (#2491) --- Src/WitsmlExplorer.Desktop/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/WitsmlExplorer.Desktop/package.json b/Src/WitsmlExplorer.Desktop/package.json index 76b965bdb..54379940e 100644 --- a/Src/WitsmlExplorer.Desktop/package.json +++ b/Src/WitsmlExplorer.Desktop/package.json @@ -1,7 +1,7 @@ { "name": "WEx-Desktop", "description": "Witsml Explorer Desktop Edition", - "version": "0.2.0", + "version": "0.3.0", "private": true, "author": "Witsml Explorer Team", "repository": "https://github.com/equinor/witsml-explorer",