Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tubular object View/Read #1211

Merged
merged 2 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Src/WitsmlExplorer.Api/Models/Tubular.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;

// ReSharper disable UnusedAutoPropertyAccessor.Global

namespace WitsmlExplorer.Api.Models
{
public class Tubular
{
public string Uid { get; internal set; }
public string Name { get; internal set; }
public string WellUid { get; internal set; }
public string WellboreUid { get; internal set; }
public string TypeTubularAssy { get; internal set; }
}
}
37 changes: 37 additions & 0 deletions Src/WitsmlExplorer.Api/Query/TubularQueries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Witsml.Data;
using Witsml.Extensions;

namespace WitsmlExplorer.Api.Query
{
public static class TubularQueries
{
public static WitsmlTubulars GetWitsmlTubularByWellbore(string wellUid, string wellboreUid)
{
return new WitsmlTubulars
{
Tubulars = new WitsmlTubular
{
Uid = "",
UidWell = wellUid,
UidWellbore = wellboreUid,
Name = "",
TypeTubularAssy = "",
CommonData = new WitsmlCommonData()
}.AsSingletonList()
};
}

public static WitsmlTubulars GetWitsmlTubularById(string wellUid, string wellboreUid, string tubularUid)
{
return new WitsmlTubulars
{
Tubulars = new WitsmlTubular
{
Uid = tubularUid,
UidWell = wellUid,
UidWellbore = wellboreUid
}.AsSingletonList()
};
}
}
}
13 changes: 13 additions & 0 deletions Src/WitsmlExplorer.Api/Routes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Routes : CarterModule
private readonly IMessageObjectService messageObjectService;
private readonly IRigService rigService;
private readonly ITrajectoryService trajectoryService;
private readonly ITubularService tubularService;
private readonly IWellboreService wellboreService;
private readonly IWellService wellService;
private readonly IRiskService riskService;
Expand All @@ -36,6 +37,7 @@ public Routes(
IMessageObjectService messageObjectService,
IRigService rigService,
ITrajectoryService trajectoryService,
ITubularService tubularService,
IJobService jobService,
IRiskService riskService,
IMudLogService mudLogService,
Expand All @@ -48,6 +50,7 @@ public Routes(
this.messageObjectService = messageObjectService;
this.rigService = rigService;
this.trajectoryService = trajectoryService;
this.tubularService = tubularService;
this.jobService = jobService;
this.riskService = riskService;
this.mudLogService = mudLogService;
Expand All @@ -71,6 +74,7 @@ public Routes(
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/rigs/{rigUid}", GetRig);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/trajectories", GetTrajectories);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/trajectories/{trajectoryUid}/trajectorystations", GetTrajectoryStations);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/tubulars", GetTubulars);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/risks", GetRisksForWellbore);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/mudlogs", GetMudLogsForWellbore);
Get("/api/wells/{wellUid}/wellbores/{wellboreUid}/mudlogs/{mudlogUid}", GetMudLog);
Expand Down Expand Up @@ -260,6 +264,15 @@ private async Task GetTrajectoryStations(HttpRequest httpRequest, HttpResponse h
var trajectory = await trajectoryService.GetTrajectoryStations(wellUid, wellboreUid, trajectoryUid);
await httpResponse.AsJson(trajectory);
}

private async Task GetTubulars(HttpRequest httpRequest, HttpResponse httpResponse)
{
var wellUid = httpRequest.RouteValues.As<string>("wellUid");
var wellboreUid = httpRequest.RouteValues.As<string>("wellboreUid");
var tubulars = await tubularService.GetTubulars(wellUid, wellboreUid);
await httpResponse.AsJson(tubulars);
}

private async Task GetRisksForWellbore(HttpRequest httpRequest, HttpResponse httpResponse)
{
var wellUid = httpRequest.RouteValues.As<string>("wellUid");
Expand Down
39 changes: 39 additions & 0 deletions Src/WitsmlExplorer.Api/Services/TubularService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WitsmlExplorer.Api.Query;
using Witsml.ServiceReference;
using WitsmlExplorer.Api.Models;

namespace WitsmlExplorer.Api.Services
{
public interface ITubularService
{
Task<IEnumerable<Tubular>> GetTubulars(string wellUid, string wellboreUid);
}

// ReSharper disable once UnusedMember.Global
public class TubularService : WitsmlService, ITubularService
{
public TubularService(IWitsmlClientProvider witsmlClientProvider) : base(witsmlClientProvider)
{
}

public async Task<IEnumerable<Tubular>> GetTubulars(string wellUid, string wellboreUid)
{
var witsmlTubular = TubularQueries.GetWitsmlTubularByWellbore(wellUid, wellboreUid);
var result = await WitsmlClient.GetFromStoreAsync(witsmlTubular, new OptionsIn(ReturnElements.Requested));

return result.Tubulars.Select(tubular =>
new Tubular
{
Uid = tubular.Uid,
WellUid = tubular.UidWell,
WellboreUid = tubular.UidWellbore,
Name = tubular.Name,
TypeTubularAssy = tubular.TypeTubularAssy
}).OrderBy(tubular => tubular.Name);
}

}
}
4 changes: 4 additions & 0 deletions Src/WitsmlExplorer.Frontend/components/ContentView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RigsListView } from "./ContentViews/RigsListView";
import { MessagesListView } from "./ContentViews/MessagesListView";
import WellboreObjectTypesListView from "./ContentViews/WellboreObjectTypesListView";
import TrajectoriesListView from "./ContentViews/TrajectoriesListView";
import TubularsListView from "./ContentViews/TubularsListView";
import LogCurveInfoListView from "./ContentViews/LogCurveInfoListView";
import TrajectoryView from "./ContentViews/TrajectoryView";
import NavigationContext from "../contexts/navigationContext";
Expand All @@ -26,6 +27,7 @@ const ContentView = (): React.ReactElement => {
selectedMessageGroup,
selectedTrajectoryGroup,
selectedTrajectory,
selectedTubularGroup,
selectedServer,
currentSelected
} = navigationState;
Expand Down Expand Up @@ -57,6 +59,8 @@ const ContentView = (): React.ReactElement => {
setView(<TrajectoriesListView />);
} else if (currentSelected === selectedTrajectory) {
setView(<TrajectoryView />);
} else if (currentSelected === selectedTubularGroup) {
setView(<TubularsListView />);
} else {
// eslint-disable-next-line no-console
console.error(`Don't know how to render this item: ${JSON.stringify(currentSelected)}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useContext, useEffect, useState } from "react";
import { ContentTable, ContentTableColumn, ContentType } from "./table";
import Tubular from "../../models/tubular";
import NavigationContext from "../../contexts/navigationContext";

export const TubularsListView = (): React.ReactElement => {
const { navigationState } = useContext(NavigationContext);
const { selectedWellbore } = navigationState;
const [tubulars, setTubulars] = useState<Tubular[]>([]);

useEffect(() => {
if (selectedWellbore?.tubulars) {
setTubulars(selectedWellbore.tubulars);
}
}, [selectedWellbore?.tubulars]);

const columns: ContentTableColumn[] = [
{ property: "name", label: "Tubular name", type: ContentType.String },
{ property: "typeTubularAssy", label: "typeTubularAssy", type: ContentType.String },
{ property: "uid", label: "UID", type: ContentType.String }
];

return selectedWellbore ? <ContentTable columns={columns} data={tubulars} /> : <></>;
};

export default TubularsListView;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useContext } from "react";
import { ContentTable, ContentTableColumn, ContentType } from "./table";
import NavigationContext from "../../contexts/navigationContext";
import NavigationType from "../../contexts/navigationType";
import { calculateLogGroupId, calculateMessageGroupId, calculateRigGroupId, calculateTrajectoryGroupId } from "../../models/wellbore";
import { calculateLogGroupId, calculateMessageGroupId, calculateRigGroupId, calculateTrajectoryGroupId, calculateTubularGroupId } from "../../models/wellbore";

export const WellboreObjectTypesListView = (): React.ReactElement => {
const { navigationState, dispatchNavigation } = useContext(NavigationContext);
Expand Down Expand Up @@ -35,6 +35,12 @@ export const WellboreObjectTypesListView = (): React.ReactElement => {
name: "Messages",
action: NavigationType.SelectMessageGroup,
actionPayload: { well: selectedWell, wellbore: selectedWellbore, messageGroup: calculateMessageGroupId(selectedWellbore) }
},
{
uid: 5,
name: "Tubulars",
action: NavigationType.SelectTubularGroup,
actionPayload: { well: selectedWell, wellbore: selectedWellbore, tubularGroup: calculateTubularGroupId(selectedWellbore) }
}
];
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import OperationContext from "../../contexts/operationContext";
import Wellbore from "../../models/wellbore";
import { getContextMenuPosition } from "../ContextMenus/ContextMenu";
import MessageObjectService from "../../services/messageObjectService";
import TubularService from "../../services/tubularService";

export const WellboresListView = (): React.ReactElement => {
const { navigationState, dispatchNavigation } = useContext(NavigationContext);
Expand Down Expand Up @@ -39,8 +40,9 @@ export const WellboresListView = (): React.ReactElement => {
const logs = await LogObjectService.getLogs(wellbore.wellUid, uid, controller.signal);
const rigs = await RigService.getRigs(wellUid, uid, controller.signal);
const trajectories = await TrajectoryService.getTrajectories(wellUid, uid, controller.signal);
const tubulars = await TubularService.getTubulars(wellUid, uid, controller.signal);
const messages = await MessageObjectService.getMessages(wellUid, uid, controller.signal);
dispatchNavigation({ type: NavigationType.SelectWellbore, payload: { well: selectedWell, wellbore, logs, rigs, trajectories, messages } });
dispatchNavigation({ type: NavigationType.SelectWellbore, payload: { well: selectedWell, wellbore, logs, rigs, trajectories, messages, tubulars } });
};

return selectedWell && <ContentTable columns={columns} data={[...selectedWell.wellbores]} onSelect={onSelect} onContextMenu={onContextMenu} />;
Expand Down
21 changes: 19 additions & 2 deletions Src/WitsmlExplorer.Frontend/components/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
SelectServerAction,
SelectTrajectoryAction,
SelectTrajectoryGroupAction,
SelectTubularGroupAction,
SelectWellAction,
SelectWellboreAction
} from "../contexts/navigationStateReducer";
Expand All @@ -38,6 +39,7 @@ const Nav = (): React.ReactElement => {
selectedRigGroup,
selectedTrajectoryGroup,
selectedTrajectory,
selectedTubularGroup,
currentSelected
} = navigationState;

Expand All @@ -54,7 +56,8 @@ const Nav = (): React.ReactElement => {
getMessageCrumbs(selectedMessage, selectedWell, selectedWellbore, dispatchNavigation),
getRigGroupCrumb(selectedRigGroup, selectedWell, selectedWellbore, dispatchNavigation),
getTrajectoryGroupCrumb(selectedTrajectoryGroup, selectedWell, selectedWellbore, dispatchNavigation),
getTrajectoryCrumb(selectedTrajectory, selectedWell, selectedWellbore, dispatchNavigation)
getTrajectoryCrumb(selectedTrajectory, selectedWell, selectedWellbore, dispatchNavigation),
getTubularGroupCrumb(selectedTubularGroup, selectedWell, selectedWellbore, dispatchNavigation)
].filter((item) => item.name);
};

Expand Down Expand Up @@ -110,7 +113,8 @@ const getWellboreCrumb = (selectedWellbore: Wellbore, selectedWell: Well, dispat
logs: selectedWellbore.logs,
rigs: selectedWellbore.rigs,
trajectories: selectedWellbore.trajectories,
messages: selectedWellbore.messages
messages: selectedWellbore.messages,
tubulars: selectedWellbore.tubulars
}
})
}
Expand Down Expand Up @@ -228,6 +232,19 @@ const getTrajectoryCrumb = (selectedTrajectory: Trajectory, selectedWell: Well,
: {};
};

const getTubularGroupCrumb = (selectedTubularGroup: string, selectedWell: Well, selectedWellbore: Wellbore, dispatch: (action: SelectTubularGroupAction) => void) => {
return selectedTubularGroup
? {
name: "Tubulars",
onClick: () =>
dispatch({
type: NavigationType.SelectTubularGroup,
payload: { well: selectedWell, wellbore: selectedWellbore, tubularGroup: selectedTubularGroup }
})
}
: {};
};

const Link = styled(MuiLink)`
cursor: pointer;
`;
Expand Down
6 changes: 4 additions & 2 deletions Src/WitsmlExplorer.Frontend/components/Routing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Wellbore from "../models/wellbore";
import LogObject from "../models/logObject";
import { NavigationState, SelectLogObjectAction, SelectServerAction, SelectWellAction, SelectWellboreAction, SetFilterAction } from "../contexts/navigationStateReducer";
import MessageObjectService from "../services/messageObjectService";
import TubularService from "../services/tubularService";

const Routing = (): React.ReactElement => {
const { dispatchNavigation, navigationState } = useContext(NavigationContext);
Expand Down Expand Up @@ -87,13 +88,14 @@ const Routing = (): React.ReactElement => {
const getLogs = LogObjectService.getLogs(selectedWell.uid, wellboreUid, controller.signal);
const getRigs = RigService.getRigs(selectedWell.uid, wellboreUid, controller.signal);
const getTrajectories = TrajectoryService.getTrajectories(selectedWell.uid, wellboreUid, controller.signal);
const getTubulars = TubularService.getTubulars(selectedWell.uid, wellboreUid, controller.signal);
const getMessages = MessageObjectService.getMessages(selectedWell.uid, wellboreUid, controller.signal);
const [logs, rigs, trajectories, messages] = await Promise.all([getLogs, getRigs, getTrajectories, getMessages]);
const [logs, rigs, trajectories, messages, tubulars] = await Promise.all([getLogs, getRigs, getTrajectories, getMessages, getTubulars]);
const wellbore: Wellbore = selectedWell.wellbores.find((wb: Wellbore) => wb.uid === wellboreUid);
if (wellbore) {
const selectWellbore: SelectWellboreAction = {
type: NavigationType.SelectWellbore,
payload: { well: selectedWell, wellbore, logs, rigs, trajectories, messages }
payload: { well: selectedWell, wellbore, logs, rigs, trajectories, messages, tubulars }
} as SelectWellboreAction;
dispatchNavigation(selectWellbore);
} else {
Expand Down
21 changes: 17 additions & 4 deletions Src/WitsmlExplorer.Frontend/components/Sidebar/WellboreItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TreeItem from "./TreeItem";
import LogObjectService from "../../services/logObjectService";
import MessageObjectService from "../../services/messageObjectService";
import Well from "../../models/well";
import Wellbore, { calculateLogGroupId, calculateMessageGroupId, calculateRigGroupId, calculateTrajectoryGroupId } from "../../models/wellbore";
import Wellbore, { calculateLogGroupId, calculateMessageGroupId, calculateRigGroupId, calculateTrajectoryGroupId, calculateTubularGroupId } from "../../models/wellbore";
import LogTypeItem from "./LogTypeItem";
import RigService from "../../services/rigService";
import TrajectoryService from "../../services/trajectoryService";
Expand All @@ -19,6 +19,7 @@ import { calculateTrajectoryId } from "../../models/trajectory";
import { SelectWellboreAction, ToggleTreeNodeAction } from "../../contexts/navigationStateReducer";
import LogsContextMenu, { LogsContextMenuProps } from "../ContextMenus/LogsContextMenu";
import { IndexCurve } from "../Modals/LogPropertiesModal";
import TubularService from "../../services/tubularService";

interface WellboreItemProps {
well: Well;
Expand Down Expand Up @@ -60,8 +61,9 @@ const WellboreItem = (props: WellboreItemProps): React.ReactElement => {
const getRigs = RigService.getRigs(well.uid, wellbore.uid, controller.signal);
const getTrajectories = TrajectoryService.getTrajectories(well.uid, wellbore.uid, controller.signal);
const getMessages = MessageObjectService.getMessages(well.uid, wellbore.uid, controller.signal);
const [logs, rigs, trajectories, messages] = await Promise.all([getLogs, getRigs, getTrajectories, getMessages]);
const selectWellbore: SelectWellboreAction = { type: NavigationType.SelectWellbore, payload: { well, wellbore, logs, rigs, trajectories, messages } };
const getTubulars = TubularService.getTubulars(well.uid, wellbore.uid, controller.signal);
const [logs, rigs, trajectories, messages, tubulars] = await Promise.all([getLogs, getRigs, getTrajectories, getMessages, getTubulars]);
const selectWellbore: SelectWellboreAction = { type: NavigationType.SelectWellbore, payload: { well, wellbore, logs, rigs, trajectories, messages, tubulars } };
dispatchNavigation(selectWellbore);
setIsFetchingData(false);
}
Expand Down Expand Up @@ -89,10 +91,14 @@ const WellboreItem = (props: WellboreItemProps): React.ReactElement => {
dispatchNavigation({ type: NavigationType.SelectTrajectoryGroup, payload: { well, wellbore, trajectoryGroup } });
};

const onSelectTubularGroup = async (well: Well, wellbore: Wellbore, tubularGroup: string) => {
dispatchNavigation({ type: NavigationType.SelectTubularGroup, payload: { well, wellbore, tubularGroup } });
};

const onLabelClick = () => {
const wellboreHasData = wellbore.logs?.length > 0;
if (wellboreHasData) {
const payload = { well, wellbore, logs: wellbore.logs, rigs: wellbore.rigs, trajectories: wellbore.trajectories, messages: wellbore.messages };
const payload = { well, wellbore, logs: wellbore.logs, rigs: wellbore.rigs, trajectories: wellbore.trajectories, messages: wellbore.messages, tubulars: wellbore.tubulars };
const selectWellbore: SelectWellboreAction = { type: NavigationType.SelectWellbore, payload };
dispatchNavigation(selectWellbore);
} else {
Expand All @@ -114,6 +120,7 @@ const WellboreItem = (props: WellboreItemProps): React.ReactElement => {
const messageGroupId = calculateMessageGroupId(wellbore);
const trajectoryGroupId = calculateTrajectoryGroupId(wellbore);
const rigGroupId = calculateRigGroupId(wellbore);
const tubularsGroupId = calculateTubularGroupId(wellbore);

return (
<TreeItem
Expand Down Expand Up @@ -164,6 +171,12 @@ const WellboreItem = (props: WellboreItemProps): React.ReactElement => {
/>
))}
</TreeItem>
<TreeItem
nodeId={tubularsGroupId}
labelText={"Tubulars"}
onLabelClick={() => onSelectTubularGroup(well, wellbore, tubularsGroupId)}
onContextMenu={preventContextMenuPropagation}
/>
</TreeItem>
);
};
Expand Down
Loading