diff --git a/Src/WitsmlExplorer.Api/HttpHandlers/LogCurvePriorityHandler.cs b/Src/WitsmlExplorer.Api/HttpHandlers/LogCurvePriorityHandler.cs index 12b9ccf03..ad1e0e3b3 100644 --- a/Src/WitsmlExplorer.Api/HttpHandlers/LogCurvePriorityHandler.cs +++ b/Src/WitsmlExplorer.Api/HttpHandlers/LogCurvePriorityHandler.cs @@ -10,17 +10,31 @@ namespace WitsmlExplorer.Api.HttpHandlers { public static class LogCurvePriorityHandler { - [Produces(typeof(List))] - public static async Task GetPrioritizedCurves(string wellUid, string wellboreUid, ILogCurvePriorityService logCurvePriorityService) + [Produces(typeof(string[]))] + public static async Task GetPrioritizedLocalCurves(string wellUid, string wellboreUid, ILogCurvePriorityService logCurvePriorityService) + { + var prioritizedCurves = await logCurvePriorityService.GetPrioritizedLocalCurves(wellUid, wellboreUid) ?? new List(); + return TypedResults.Ok(prioritizedCurves); + } + + [Produces(typeof(string[]))] + public static async Task GetPrioritizedUniversalCurves(ILogCurvePriorityService logCurvePriorityService) { - var prioritizedCurves = await logCurvePriorityService.GetPrioritizedCurves(wellUid, wellboreUid) ?? new List(); + var prioritizedCurves = await logCurvePriorityService.GetPrioritizedUniversalCurves() ?? new List(); return TypedResults.Ok(prioritizedCurves); } - [Produces(typeof(IList))] - public static async Task SetPrioritizedCurves(string wellUid, string wellboreUid, IList prioritizedCurves, ILogCurvePriorityService logCurvePriorityService) + [Produces(typeof(List))] + public static async Task SetPrioritizedLocalCurves(string wellUid, string wellboreUid, IList prioritizedCurves, ILogCurvePriorityService logCurvePriorityService) + { + var createdPrioritizedCurves = await logCurvePriorityService.SetPrioritizedLocalCurves(wellUid, wellboreUid, prioritizedCurves) ?? new List(); + return TypedResults.Ok(createdPrioritizedCurves); + } + + [Produces(typeof(List))] + public static async Task SetPrioritizedUniversalCurves(List prioritizedCurves, ILogCurvePriorityService logCurvePriorityService) { - var createdPrioritizedCurves = await logCurvePriorityService.SetPrioritizedCurves(wellUid, wellboreUid, prioritizedCurves) ?? new List(); + var createdPrioritizedCurves = await logCurvePriorityService.SetPrioritizedUniversalCurves(prioritizedCurves) ?? new List(); return TypedResults.Ok(createdPrioritizedCurves); } } diff --git a/Src/WitsmlExplorer.Api/Routes.cs b/Src/WitsmlExplorer.Api/Routes.cs index 6e84bb55d..69acd7fa3 100644 --- a/Src/WitsmlExplorer.Api/Routes.cs +++ b/Src/WitsmlExplorer.Api/Routes.cs @@ -39,8 +39,10 @@ public static void ConfigureApi(this WebApplication app, IConfiguration configur app.MapGet("/wells/{wellUid}/wellbores/{wellboreUid}/idonly/{objectType}/{objectUid}", ObjectHandler.GetObjectIdOnly, useOAuth2); app.MapGet("/wells/{wellUid}/wellbores/{wellboreUid}/countexpandable", ObjectHandler.GetExpandableObjectsCount, useOAuth2); - app.MapGet("/wells/{wellUid}/wellbores/{wellboreUid}/logCurvePriority", LogCurvePriorityHandler.GetPrioritizedCurves, useOAuth2); - app.MapPost("/wells/{wellUid}/wellbores/{wellboreUid}/logCurvePriority", LogCurvePriorityHandler.SetPrioritizedCurves, useOAuth2); + app.MapGet("/wells/{wellUid}/wellbores/{wellboreUid}/logCurvePriority", LogCurvePriorityHandler.GetPrioritizedLocalCurves, useOAuth2); + app.MapGet("/universal/logCurvePriority", LogCurvePriorityHandler.GetPrioritizedUniversalCurves, useOAuth2); + app.MapPost("/universal/logCurvePriority", LogCurvePriorityHandler.SetPrioritizedUniversalCurves, useOAuth2); + app.MapPost("/wells/{wellUid}/wellbores/{wellboreUid}/logCurvePriority", LogCurvePriorityHandler.SetPrioritizedLocalCurves, useOAuth2); Dictionary types = EntityTypeHelper.ToPluralLowercase(); Dictionary routes = types.ToDictionary(entry => entry.Key, entry => "/wells/{wellUid}/wellbores/{wellboreUid}/" + entry.Value); diff --git a/Src/WitsmlExplorer.Api/Services/LogCurvePriorityService.cs b/Src/WitsmlExplorer.Api/Services/LogCurvePriorityService.cs index 7337d1aca..04492085c 100644 --- a/Src/WitsmlExplorer.Api/Services/LogCurvePriorityService.cs +++ b/Src/WitsmlExplorer.Api/Services/LogCurvePriorityService.cs @@ -1,7 +1,4 @@ - -using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Microsoft.IdentityModel.Tokens; @@ -13,27 +10,26 @@ namespace WitsmlExplorer.Api.Services { public interface ILogCurvePriorityService { - Task> GetPrioritizedCurves(string wellUid, string wellboreUid); - Task> SetPrioritizedCurves(string wellUid, string wellboreUid, IList prioritizedCurves); + Task> GetPrioritizedLocalCurves(string wellUid, string wellboreUid); + Task> SetPrioritizedLocalCurves(string wellUid, string wellboreUid, IList prioritizedCurves); + Task> SetPrioritizedUniversalCurves(List prioritizedCurves); + Task> GetPrioritizedUniversalCurves(); } - public class LogCurvePriorityService : ILogCurvePriorityService + public class LogCurvePriorityService( + IDocumentRepository + logCurvePriorityRepository) + : ILogCurvePriorityService { - private readonly IDocumentRepository logCurvePriorityRepository; - - public LogCurvePriorityService(IDocumentRepository logCurvePriorityRepository) - { - this.logCurvePriorityRepository = logCurvePriorityRepository; - } - - public async Task> GetPrioritizedCurves(string wellUid, string wellboreUid) + private const string UniversalDbId = "universal"; + public async Task> GetPrioritizedLocalCurves(string wellUid, string wellboreUid) { string logCurvePriorityId = GetLogCurvePriorityId(wellUid, wellboreUid); LogCurvePriority logCurvePriority = await logCurvePriorityRepository.GetDocumentAsync(logCurvePriorityId); return logCurvePriority?.PrioritizedCurves; } - public async Task> SetPrioritizedCurves(string wellUid, string wellboreUid, IList prioritizedCurves) + public async Task> SetPrioritizedLocalCurves(string wellUid, string wellboreUid, IList prioritizedCurves) { if (prioritizedCurves.IsNullOrEmpty()) { @@ -41,34 +37,50 @@ public async Task> SetPrioritizedCurves(string wellUid, string wel return null; } - IList currentPrioritizedCurves = await GetPrioritizedCurves(wellUid, wellboreUid); - if (currentPrioritizedCurves == null) + string logCurvePriorityId = GetLogCurvePriorityId(wellUid, wellboreUid); + LogCurvePriority logCurvePriority = await logCurvePriorityRepository.GetDocumentAsync(logCurvePriorityId); + if (logCurvePriority == null) { return await CreatePrioritizedCurves(wellUid, wellboreUid, prioritizedCurves); } - string logCurvePriorityId = GetLogCurvePriorityId(wellUid, wellboreUid); - LogCurvePriority logCurvePriorityToUpdate = CreateLogCurvePriorityObject(wellUid, wellboreUid, prioritizedCurves); + LogCurvePriority logCurvePriorityToUpdate = CreateLogCurvePriorityLocalObject(wellUid, wellboreUid, prioritizedCurves); LogCurvePriority updatedLogCurvePriority = await logCurvePriorityRepository.UpdateDocumentAsync(logCurvePriorityId, logCurvePriorityToUpdate); return updatedLogCurvePriority.PrioritizedCurves; } + public async Task> GetPrioritizedUniversalCurves() + { + LogCurvePriority logCurvePriorityGlobal = await logCurvePriorityRepository.GetDocumentAsync(UniversalDbId); + return logCurvePriorityGlobal?.PrioritizedCurves; + } + + public async Task> SetPrioritizedUniversalCurves(List prioritizedCurves) + { + var globalDocument = await logCurvePriorityRepository.GetDocumentAsync(UniversalDbId); + if (globalDocument == null) + { + return await CreatePrioritizedUniversalCurves(prioritizedCurves); + } + return await UpdatePrioritizedUniversalCurves(prioritizedCurves); + } + + private async Task> CreatePrioritizedCurves(string wellUid, string wellboreUid, IList prioritizedCurves) { - LogCurvePriority logCurvePriorityToCreate = CreateLogCurvePriorityObject(wellUid, wellboreUid, prioritizedCurves); + LogCurvePriority logCurvePriorityToCreate = CreateLogCurvePriorityLocalObject(wellUid, wellboreUid, prioritizedCurves); LogCurvePriority inserted = await logCurvePriorityRepository.CreateDocumentAsync(logCurvePriorityToCreate); return inserted.PrioritizedCurves; } private async Task DeleteLogCurvePriorityObject(string wellUid, string wellboreUid) { - IList currentPrioritizedCurves = await GetPrioritizedCurves(wellUid, wellboreUid); + IList currentPrioritizedCurves = await GetPrioritizedLocalCurves(wellUid, wellboreUid); if (currentPrioritizedCurves != null) { string logCurvePriorityId = GetLogCurvePriorityId(wellUid, wellboreUid); await logCurvePriorityRepository.DeleteDocumentAsync(logCurvePriorityId); } - return; } private string GetLogCurvePriorityId(string wellUid, string wellboreUid) @@ -76,7 +88,7 @@ private string GetLogCurvePriorityId(string wellUid, string wellboreUid) return $"{wellUid}-{wellboreUid}"; } - private LogCurvePriority CreateLogCurvePriorityObject(string wellUid, string wellboreUid, IList prioritizedCurves) + private LogCurvePriority CreateLogCurvePriorityLocalObject(string wellUid, string wellboreUid, IList prioritizedCurves) { string logCurvePriorityId = GetLogCurvePriorityId(wellUid, wellboreUid); LogCurvePriority logCurvePriorityObject = new(logCurvePriorityId) @@ -85,5 +97,28 @@ private LogCurvePriority CreateLogCurvePriorityObject(string wellUid, string wel }; return logCurvePriorityObject; } + + private async Task> CreatePrioritizedUniversalCurves(List logCurvePriorities) + { + LogCurvePriority logCurvePriorityToCreate = CreateLogCurveUniversalPriorityObject(logCurvePriorities); + LogCurvePriority inserted = await logCurvePriorityRepository.CreateDocumentAsync(logCurvePriorityToCreate); + return inserted.PrioritizedCurves; + } + + private async Task> UpdatePrioritizedUniversalCurves(List logCurvePriorities) + { + LogCurvePriority logCurvePriorityToCreate = CreateLogCurveUniversalPriorityObject(logCurvePriorities); + LogCurvePriority updated = await logCurvePriorityRepository.UpdateDocumentAsync(UniversalDbId, logCurvePriorityToCreate); + return updated.PrioritizedCurves; + } + + private LogCurvePriority CreateLogCurveUniversalPriorityObject(List prioritizedCurves) + { + LogCurvePriority logCurvePriorityObject = new(UniversalDbId) + { + PrioritizedCurves = prioritizedCurves + }; + return logCurvePriorityObject; + } } } diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx index 511a4f8d8..24aee8012 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/LogCurveInfoListView.tsx @@ -61,10 +61,19 @@ export default function LogCurveInfoListView() { const [hideEmptyMnemonics, setHideEmptyMnemonics] = useState(false); const [showOnlyPrioritizedCurves, setShowOnlyPrioritizedCurves] = useState(false); - const [prioritizedCurves, setPrioritizedCurves] = useState([]); + const [prioritizedLocalCurves, setPrioritizedLocalCurves] = useState< + string[] + >([]); + const [prioritizedUniversalCurves, setPrioritizedUniversalCurves] = useState< + string[] + >([]); const logObjects = new Map([[objectUid, logObject]]); const isDepthIndex = logType === RouterLogType.DEPTH; const isFetching = isFetchingLog || isFetchingLogCurveInfo; + const allPrioritizedCurves = [ + ...prioritizedLocalCurves, + ...prioritizedUniversalCurves + ].filter((value, index, self) => self.indexOf(value) === index); useExpandSidebarNodes( wellUid, @@ -76,16 +85,24 @@ export default function LogCurveInfoListView() { useEffect(() => { if (logObject) { - const getLogCurvePriority = async () => { + const getLogCurveLocalPriority = async () => { const prioritizedCurves = await LogCurvePriorityService.getPrioritizedCurves( + false, wellUid, wellboreUid ); - setPrioritizedCurves(prioritizedCurves); + setPrioritizedLocalCurves(prioritizedCurves); }; - getLogCurvePriority().catch(truncateAbortHandler); + const getLogCurveUniversalPriority = async () => { + const prioritizedCurves = + await LogCurvePriorityService.getPrioritizedCurves(true); + setPrioritizedUniversalCurves(prioritizedCurves); + }; + + getLogCurveLocalPriority().catch(truncateAbortHandler); + getLogCurveUniversalPriority().catch(truncateAbortHandler); setShowOnlyPrioritizedCurves(false); } }, [logObject]); @@ -101,8 +118,10 @@ export default function LogCurveInfoListView() { selectedLog: logObject, selectedServer: connectedServer, servers, - prioritizedCurves, - setPrioritizedCurves + prioritizedLocalCurves, + setPrioritizedLocalCurves, + prioritizedUniversalCurves, + setPrioritizedUniversalCurves }; const position = getContextMenuPosition(event); dispatchOperation({ @@ -130,7 +149,9 @@ export default function LogCurveInfoListView() { setShowOnlyPrioritizedCurves(!showOnlyPrioritizedCurves) } @@ -154,7 +175,7 @@ export default function LogCurveInfoListView() { columns={getColumns( isDepthIndex, showOnlyPrioritizedCurves, - prioritizedCurves, + allPrioritizedCurves, logObjects, hideEmptyMnemonics, true diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx index 05f0ad019..70db3f5d1 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/MultiLogsCurveInfoListView.tsx @@ -48,7 +48,16 @@ export default function MultiLogsCurveInfoListView() { const [hideEmptyMnemonics, setHideEmptyMnemonics] = useState(false); const [showOnlyPrioritizedCurves, setShowOnlyPrioritizedCurves] = useState(false); - const [prioritizedCurves, setPrioritizedCurves] = useState([]); + const [prioritizedLocalCurves, setPrioritizedLocalCurves] = useState< + string[] + >([]); + const [prioritizedUniversalCurves, setPrioritizedUniversalCurves] = useState< + string[] + >([]); + const allPrioritizedCurves = [ + ...prioritizedLocalCurves, + ...prioritizedUniversalCurves + ].filter((value, index, self) => self.indexOf(value) === index); const { objects: allLogs, isFetching: isFetchingLogs } = useGetObjects( connectedServer, wellUid, @@ -87,16 +96,24 @@ export default function MultiLogsCurveInfoListView() { }; getMnemonics(); - const getLogCurvePriority = async () => { + const getLogCurveLocalPriority = async () => { const prioritizedCurves = await LogCurvePriorityService.getPrioritizedCurves( + false, wellUid, wellboreUid ); - setPrioritizedCurves(prioritizedCurves); + setPrioritizedLocalCurves(prioritizedCurves); }; - getLogCurvePriority().catch(truncateAbortHandler); + const getLogCurveUniversalPriority = async () => { + const prioritizedCurves = + await LogCurvePriorityService.getPrioritizedCurves(true); + setPrioritizedUniversalCurves(prioritizedCurves); + }; + + getLogCurveLocalPriority().catch(truncateAbortHandler); + getLogCurveUniversalPriority().catch(truncateAbortHandler); setShowOnlyPrioritizedCurves(false); } }, [allLogs]); @@ -114,8 +131,10 @@ export default function MultiLogsCurveInfoListView() { selectedLog: selectedLog, selectedServer: connectedServer, servers, - prioritizedCurves, - setPrioritizedCurves, + prioritizedLocalCurves, + setPrioritizedLocalCurves, + prioritizedUniversalCurves, + setPrioritizedUniversalCurves, isMultiLog }; const position = getContextMenuPosition(event); @@ -140,7 +159,9 @@ export default function MultiLogsCurveInfoListView() { setShowOnlyPrioritizedCurves(!showOnlyPrioritizedCurves) } @@ -164,7 +185,7 @@ export default function MultiLogsCurveInfoListView() { columns={getColumns( isDepthIndex, showOnlyPrioritizedCurves, - prioritizedCurves, + allPrioritizedCurves, logObjects, hideEmptyMnemonics )} diff --git a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurveInfoContextMenu.tsx b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurveInfoContextMenu.tsx index acaaf7bf4..6bcc33487 100644 --- a/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurveInfoContextMenu.tsx +++ b/Src/WitsmlExplorer.Frontend/components/ContextMenus/LogCurveInfoContextMenu.tsx @@ -59,8 +59,10 @@ export interface LogCurveInfoContextMenuProps { selectedLog: LogObject; selectedServer: Server; servers: Server[]; - prioritizedCurves: string[]; - setPrioritizedCurves: (prioritizedCurves: string[]) => void; + prioritizedLocalCurves: string[]; + setPrioritizedLocalCurves: (prioritizedLocalCurves: string[]) => void; + prioritizedUniversalCurves: string[]; + setPrioritizedUniversalCurves: (prioritizedUniversalCurves: string[]) => void; isMultiLog?: boolean; } @@ -73,17 +75,26 @@ const LogCurveInfoContextMenu = ( selectedLog, selectedServer, servers, - prioritizedCurves, - setPrioritizedCurves, + prioritizedLocalCurves, + setPrioritizedLocalCurves, + prioritizedUniversalCurves, + setPrioritizedUniversalCurves, isMultiLog = false } = props; const onlyPrioritizedCurvesAreChecked = checkedLogCurveInfoRows.every( (row, index) => - prioritizedCurves.includes(row.mnemonic) || + prioritizedLocalCurves.includes(row.mnemonic) || (checkedLogCurveInfoRows.length > 1 && index === 0) ); + const onlyPrioritizedUniversalCurvesAreChecked = + checkedLogCurveInfoRows.every( + (row, index) => + prioritizedUniversalCurves.includes(row.mnemonic) || + (checkedLogCurveInfoRows.length > 1 && index === 0) + ); + const checkedLogCurveInfoRowsWithoutIndexCurve = checkedLogCurveInfoRows.filter( (lc) => lc.mnemonic !== selectedLog.indexCurve @@ -174,8 +185,22 @@ const LogCurveInfoContextMenu = ( const logCurvePriorityModalProps: LogCurvePriorityModalProps = { wellUid: selectedLog.wellUid, wellboreUid: selectedLog.wellboreUid, - prioritizedCurves, - setPrioritizedCurves + prioritizedCurves: prioritizedLocalCurves, + setPrioritizedCurves: setPrioritizedLocalCurves, + isUniversal: false + }; + dispatchOperation({ + type: OperationType.DisplayModal, + payload: + }); + }; + + const onClickEditUniversalPriority = () => { + dispatchOperation({ type: OperationType.HideContextMenu }); + const logCurvePriorityModalProps: LogCurvePriorityModalProps = { + prioritizedCurves: prioritizedUniversalCurves, + setPrioritizedCurves: setPrioritizedUniversalCurves, + isUniversal: true }; dispatchOperation({ type: OperationType.DisplayModal, @@ -199,36 +224,52 @@ const LogCurveInfoContextMenu = ( }); }; - const onClickSetPriority = async () => { + const onClickSetPriority = async (isUniversal: boolean) => { dispatchOperation({ type: OperationType.HideContextMenu }); const newCurvesToPrioritize = checkedLogCurveInfoRows.map( (lc) => lc.mnemonic ); - const curvesToPrioritize = Array.from( - new Set(prioritizedCurves.concat(newCurvesToPrioritize)) - ); + const curvesToPrioritize = isUniversal + ? Array.from( + new Set(prioritizedUniversalCurves.concat(newCurvesToPrioritize)) + ) + : Array.from( + new Set(prioritizedLocalCurves.concat(newCurvesToPrioritize)) + ); const newPrioritizedCurves = await LogCurvePriorityService.setPrioritizedCurves( + curvesToPrioritize, + isUniversal, selectedLog.wellUid, selectedLog.wellboreUid, - curvesToPrioritize + null ); - setPrioritizedCurves(newPrioritizedCurves); + isUniversal + ? setPrioritizedUniversalCurves(newPrioritizedCurves) + : setPrioritizedLocalCurves(newPrioritizedCurves); }; - const onClickRemovePriority = async () => { + const onClickRemovePriority = async (isUniversal: boolean) => { dispatchOperation({ type: OperationType.HideContextMenu }); const curvesToDelete = checkedLogCurveInfoRows.map((lc) => lc.mnemonic); - const curvesToPrioritize = prioritizedCurves.filter( - (curve) => !curvesToDelete.includes(curve) - ); + const curvesToPrioritize = isUniversal + ? prioritizedUniversalCurves.filter( + (curve) => !curvesToDelete.includes(curve) + ) + : prioritizedLocalCurves.filter( + (curve) => !curvesToDelete.includes(curve) + ); const newPrioritizedCurves = await LogCurvePriorityService.setPrioritizedCurves( + curvesToPrioritize, + isUniversal, selectedLog.wellUid, selectedLog.wellboreUid, - curvesToPrioritize + null ); - setPrioritizedCurves(newPrioritizedCurves); + isUniversal + ? setPrioritizedUniversalCurves(newPrioritizedCurves) + : setPrioritizedLocalCurves(newPrioritizedCurves); }; const toDelete = createComponentReferences( @@ -379,35 +420,73 @@ const LogCurveInfoContextMenu = ( )} , - - onlyPrioritizedCurvesAreChecked - ? onClickRemovePriority() - : onClickSetPriority() - } + - onlyPrioritizedCurvesAreChecked - ? "favoriteFilled" - : "favoriteOutlined" + ? onClickRemovePriority(false) + : onClickSetPriority(false) } - color={colors.interactive.primaryResting} - /> - - {onlyPrioritizedCurvesAreChecked - ? "Remove Priority" - : "Set Priority"} - - , - - - Edit Priority - , + > + + + {onlyPrioritizedCurvesAreChecked + ? "Remove Local Priority" + : "Set Local Priority"} + + + + onlyPrioritizedUniversalCurvesAreChecked + ? onClickRemovePriority(true) + : onClickSetPriority(true) + } + > + + + {onlyPrioritizedUniversalCurvesAreChecked + ? "Remove Universal Priority" + : "Set Universal Priority"} + + + + + Edit Local Priority + + + + Edit Universal Priority + + , , void; + isUniversal: boolean; } export interface LogCurvePriorityRow { @@ -41,12 +43,13 @@ export const LogCurvePriorityModal = ( }); const [checkedCurves, setCheckedCurves] = useState([]); + const [uploadedFile, setUploadedFile] = useState(null); const columns = [ { property: "mnemonic", label: "mnemonic", type: ContentType.String, - width: 500 + width: 440 } ]; @@ -78,14 +81,30 @@ export const LogCurvePriorityModal = ( const onSubmit = async () => { await LogCurvePriorityService.setPrioritizedCurves( + updatedPrioritizedCurves, + props.isUniversal, wellUid, - wellboreUid, - updatedPrioritizedCurves + wellboreUid ); dispatchOperation({ type: OperationType.HideModal }); setPrioritizedCurves(updatedPrioritizedCurves); }; + const handleFileChange = async ( + e: React.ChangeEvent + ): Promise => { + const file = e.target.files.item(0); + if (!file) return; + const text = (await file.text()).replace(/(\r)/gm, "").trim(); + const data = text.split("\n").slice(1); + const mergedArray = [...data, ...updatedPrioritizedCurves]; + const uniqueArray = mergedArray.filter( + (value, index, self) => self.indexOf(value) === index && value !== "" + ); + setUpdatedPrioritizedCurves(uniqueArray); + setUploadedFile(file); + }; + const addCurve = () => { setUpdatedPrioritizedCurves([...updatedPrioritizedCurves, newCurve]); setNewCurve(""); @@ -93,7 +112,11 @@ export const LogCurvePriorityModal = ( return ( @@ -101,13 +124,18 @@ export const LogCurvePriorityModal = ( ) => - setNewCurve(e.target.value) - } + onKeyDown={(e: KeyboardEvent) => { + if (e.key === "Enter") { + e.stopPropagation(); + addCurve(); + } + }} + onChange={(e: ChangeEvent) => { + setNewCurve(e.target.value); + }} value={newCurve} /> + + + + + {uploadedFile?.name ?? "No file chosen"} + + + @@ -143,7 +196,7 @@ const Layout = styled.div` display: grid; grid-template-rows: 1fr auto; max-height: 100%; - gap: 20px; + gap: 40px; `; const AddItemLayout = styled.div` @@ -152,3 +205,13 @@ const AddItemLayout = styled.div` gap: 10px; align-items: end; `; + +const FileContainer = styled.div` + display: flex; + flex-direction: row; + gap: 1rem; + align-items: center; + .MuiButton-root { + min-width: 160px; + } +`; diff --git a/Src/WitsmlExplorer.Frontend/services/logCurvePriorityService.tsx b/Src/WitsmlExplorer.Frontend/services/logCurvePriorityService.tsx index 32fa17bbc..b03ef16ca 100644 --- a/Src/WitsmlExplorer.Frontend/services/logCurvePriorityService.tsx +++ b/Src/WitsmlExplorer.Frontend/services/logCurvePriorityService.tsx @@ -2,40 +2,45 @@ import { ApiClient } from "./apiClient"; export default class LogCurvePriorityService { public static async getPrioritizedCurves( - wellUid: string, - wellboreUid: string, + isUniversal: boolean, + wellUid?: string, + wellboreUid?: string, abortSignal?: AbortSignal ): Promise { - const response = await ApiClient.get( - `/api/wells/${encodeURIComponent(wellUid)}/wellbores/${encodeURIComponent( - wellboreUid - )}/logCurvePriority`, - abortSignal - ); + const path = isUniversal + ? `/api/universal/logCurvePriority` + : `/api/wells/${encodeURIComponent( + wellUid + )}/wellbores/${encodeURIComponent(wellboreUid)}/logCurvePriority`; + const response = await ApiClient.get(path, abortSignal); if (response.ok) { return response.json(); } else { - return []; + return null; } } public static async setPrioritizedCurves( - wellUid: string, - wellboreUid: string, prioritizedCurves: string[], + isUniversal: boolean, + wellUid?: string, + wellboreUid?: string, abortSignal?: AbortSignal ): Promise { + const path = isUniversal + ? `/api/universal/logCurvePriority` + : `/api/wells/${encodeURIComponent( + wellUid + )}/wellbores/${encodeURIComponent(wellboreUid)}/logCurvePriority`; const response = await ApiClient.post( - `/api/wells/${encodeURIComponent(wellUid)}/wellbores/${encodeURIComponent( - wellboreUid - )}/logCurvePriority`, + path, JSON.stringify(prioritizedCurves), abortSignal ); if (response.ok) { return response.json(); } else { - return []; + return null; } } } diff --git a/Tests/WitsmlExplorer.Api.Tests/Services/LogCurvePriorityServiceTests.cs b/Tests/WitsmlExplorer.Api.Tests/Services/LogCurvePriorityServiceTests.cs index 3f7d54aab..6ea4559ea 100644 --- a/Tests/WitsmlExplorer.Api.Tests/Services/LogCurvePriorityServiceTests.cs +++ b/Tests/WitsmlExplorer.Api.Tests/Services/LogCurvePriorityServiceTests.cs @@ -52,31 +52,31 @@ public LogCurvePriorityServiceTests() } [Fact] - public async Task GetPrioritizedCurves_CorrectIds_ReturnsExpectedCurves() + public async Task GetPrioritizedLocalCurves_CorrectIds_ReturnsExpectedCurves() { var wellUid = "well1"; var wellboreUid = "wellbore1"; - var result = await _logCurvePriorityService.GetPrioritizedCurves(wellUid, wellboreUid); + var result = await _logCurvePriorityService.GetPrioritizedLocalCurves(wellUid, wellboreUid); Assert.Equal(_prioritizedCurvesWell1Wellbore1, result); _repository.Verify(repo => repo.GetDocumentAsync(It.Is(id => id == $"{wellUid}-{wellboreUid}")), Times.Once); } [Fact] - public async Task GetPrioritizedCurves_IncorrectId_ReturnsNull() + public async Task GetPrioritizedLocalCurves_IncorrectId_ReturnsNull() { var wellUid = "well"; var wellboreUid = "wellbore"; - var result = await _logCurvePriorityService.GetPrioritizedCurves(wellUid, wellboreUid); + var result = await _logCurvePriorityService.GetPrioritizedLocalCurves(wellUid, wellboreUid); Assert.Null(result); _repository.Verify(repo => repo.GetDocumentAsync(It.Is(id => id == $"{wellUid}-{wellboreUid}")), Times.Once); } [Fact] - public async Task SetPrioritizedCurves_NoExistingPriority_CreatesNewPriority() + public async Task SetPrioritizedLocalCurves_NoExistingPriority_CreatesNewPriority() { var wellUid = "well3"; var wellboreUid = "wellbore3"; @@ -86,7 +86,7 @@ public async Task SetPrioritizedCurves_NoExistingPriority_CreatesNewPriority() PrioritizedCurves = curves }; - var result = await _logCurvePriorityService.SetPrioritizedCurves(wellUid, wellboreUid, curves); + var result = await _logCurvePriorityService.SetPrioritizedLocalCurves(wellUid, wellboreUid, curves); Assert.Equal(curves, result); _repository.Verify(repo => repo.UpdateDocumentAsync(It.IsAny(), It.IsAny()), Times.Never); @@ -94,7 +94,7 @@ public async Task SetPrioritizedCurves_NoExistingPriority_CreatesNewPriority() } [Fact] - public async Task SetPrioritizedCurves_ExistingPriority_ReplacesPriority() + public async Task SetPrioritizedLocalCurves_ExistingPriority_ReplacesPriority() { var wellUid = "well1"; var wellboreUid = "wellbore2"; @@ -104,20 +104,20 @@ public async Task SetPrioritizedCurves_ExistingPriority_ReplacesPriority() PrioritizedCurves = curves }; - var result = await _logCurvePriorityService.SetPrioritizedCurves(wellUid, wellboreUid, curves); + var result = await _logCurvePriorityService.SetPrioritizedLocalCurves(wellUid, wellboreUid, curves); Assert.Equal(curves, result); _repository.Verify(repo => repo.UpdateDocumentAsync($"{wellUid}-{wellboreUid}", It.Is(lcp => lcp.PrioritizedCurves.SequenceEqual(curves))), Times.Once); } [Fact] - public async Task SetPrioritizedCurves_EmptyInput_RemovesPriorityObject() + public async Task SetPrioritizedLocalCurves_EmptyInput_RemovesPriorityObject() { var wellUid = "well2"; var wellboreUid = "wellbore1"; var curves = new List(); - var result = await _logCurvePriorityService.SetPrioritizedCurves(wellUid, wellboreUid, curves); + var result = await _logCurvePriorityService.SetPrioritizedLocalCurves(wellUid, wellboreUid, curves); Assert.Null(result); _repository.Verify(repo => repo.UpdateDocumentAsync(It.IsAny(), It.IsAny()), Times.Never);