Skip to content

Commit

Permalink
#2568 UID Mapping Overview (#2625)
Browse files Browse the repository at this point in the history
  • Loading branch information
vaclavbasniar authored Dec 18, 2024
1 parent 5339e5e commit f12593d
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ import WellWellboreTree, {
export interface WellboreUidMappingModalProps {
wellbore: Wellbore;
targetServer: Server;
onModalClose?: () => void;
}

const WellboreUidMappingModal = (
props: WellboreUidMappingModalProps
): React.ReactElement => {
const { wellbore, targetServer } = props;
const { wellbore, targetServer, onModalClose } = props;

const {
dispatchOperation,
Expand Down Expand Up @@ -201,6 +202,10 @@ const WellboreUidMappingModal = (
} else {
await UidMappingService.addUidMapping(uidMapping);
}

if (onModalClose) {
onModalClose();
}
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,346 @@
import { Server } from "../../models/server.ts";
import React, { useEffect, useMemo, useState } from "react";
import { useGetServers } from "../../hooks/query/useGetServers.tsx";
import { useGetWellbores } from "../../hooks/query/useGetWellbores.tsx";
import { UidMapping, UidMappingDbQuery } from "../../models/uidMapping.tsx";
import UidMappingService from "../../services/uidMappingService.tsx";
import {
ContentTable,
ContentTableColumn,
ContentTableRow,
ContentType
} from "../ContentViews/table";
import { Colors } from "../../styles/Colors.tsx";
import styled from "styled-components";
import { Autocomplete, Dialog } from "@equinor/eds-core-react";
import { useOperationState } from "../../hooks/useOperationState.tsx";
import OperationType from "../../contexts/operationType.ts";
import { ProgressSpinnerOverlay } from "../ProgressSpinner.tsx";
import { Button } from "../StyledComponents/Button.tsx";
import WellboreUidMappingModal, {
WellboreUidMappingModalProps
} from "./WellboreUidMappingModal.tsx";
import { DisplayModalAction } from "../../contexts/operationStateReducer.tsx";
import { calculateWellboreNodeId } from "../../models/wellbore.tsx";

interface UidMappingRow extends ContentTableRow {
sourceWellId: string;
sourceWellName: string;
sourceWellboreId: string;
sourceWellboreName: string;
targetWellId: string;
targetWellName: string;
targetWellboreId: string;
targetWellboreName: string;
username: string;
timestamp: string;
}

const WellboreUidMappingOverviewModal = (): React.ReactElement => {
const { servers } = useGetServers();
const {
dispatchOperation,
operationState: { colors }
} = useOperationState();

const [sourceServerValue, setSourceServerValue] = useState<Server>(undefined);
const [targetServerValue, setTargetServerValue] = useState<Server>(undefined);

const [isFetchingUidMapping, setIsFetchingUidMapping] =
useState<boolean>(false);
const [mappings, setMappings] = useState<UidMapping[]>([]);

const [selectedRows, setSelectedRows] = useState<UidMappingRow[]>([]);

const { wellbores: sourceWellbores, isFetching: isFetchingSourceWellbores } =
useGetWellbores(sourceServerValue, "", { placeholderData: [] });

const { wellbores: targetWellbores, isFetching: isFetchingTargetWellbores } =
useGetWellbores(targetServerValue, "", { placeholderData: [] });

useEffect(() => {
if (
!!sourceServerValue &&
!!targetServerValue &&
!isFetchingSourceWellbores &&
!isFetchingTargetWellbores
) {
loadMappings();
}
}, [sourceServerValue, targetServerValue, sourceWellbores, targetWellbores]);

const loadMappings = () => {
const dbQuery: UidMappingDbQuery = {
sourceServerId: sourceServerValue.id,
targetServerId: targetServerValue.id
};

setSelectedRows([]);

setIsFetchingUidMapping(true);

UidMappingService.queryUidMapping(dbQuery)
.then((mappings) => {
if (mappings.length > 0) {
setMappings(mappings);
} else {
setMappings([]);
}
})
.finally(() => setIsFetchingUidMapping(false));
};

const tableData = useMemo((): UidMappingRow[] => {
const mappingRows: UidMappingRow[] = [];

if (!!sourceServerValue && !!targetServerValue) {
for (const mapping of mappings) {
const sourceWellbore = sourceWellbores.find(
(wb) => wb.uid === mapping.sourceWellboreId
);

const targetWellbore = targetWellbores.find(
(wb) => wb.uid === mapping.targetWellboreId
);

const row: UidMappingRow = {
id:
calculateWellboreNodeId(sourceWellbore) +
calculateWellboreNodeId(targetWellbore),
sourceWellId: sourceWellbore.wellUid,
sourceWellName: sourceWellbore.wellName,
sourceWellboreId: sourceWellbore.uid,
sourceWellboreName: sourceWellbore.name,
targetWellId: targetWellbore.wellUid,
targetWellName: targetWellbore.wellName,
targetWellboreId: targetWellbore.uid,
targetWellboreName: targetWellbore.name,
username: mapping.username,
timestamp: mapping.timestamp
};

mappingRows.push(row);
}
}

return mappingRows;
}, [
isFetchingUidMapping,
mappings,
sourceWellbores,
targetWellbores,
sourceServerValue,
targetServerValue
]);

const columns: ContentTableColumn[] = [
{
property: "sourceWellboreName",
label: "Source Wellbore Name",
type: ContentType.String
},
{
property: "sourceWellboreId",
label: "Source Wellbore Id",
type: ContentType.String
},
{
property: "sourceWellName",
label: "Source Well Name",
type: ContentType.String
},
{
property: "sourceWellId",
label: "Source Well Id",
type: ContentType.String
},
{
property: "targetWellboreName",
label: "Target Wellbore Name",
type: ContentType.String
},
{
property: "targetWellboreId",
label: "Target Wellbore Id",
type: ContentType.String
},
{
property: "targetWellName",
label: "Target Well Name",
type: ContentType.String
},
{
property: "targetWellId",
label: "Target Well Id",
type: ContentType.String
},
{ property: "username", label: "User Name", type: ContentType.String },
{ property: "timestamp", label: "Timestamp", type: ContentType.String }
];

const onDelete = async () => {
if (selectedRows.length > 0) {
for (const row of selectedRows) {
const deleteQuery: UidMappingDbQuery = {
sourceServerId: sourceServerValue.id,
sourceWellId: row.sourceWellId,
sourceWellboreId: row.sourceWellboreId,
targetServerId: targetServerValue.id,
targetWellId: row.targetWellId,
targetWellboreId: row.targetWellboreId
};

await UidMappingService.removeUidMapping(deleteQuery);
}
loadMappings();
}
};

const onEdit = () => {
if (selectedRows.length == 1) {
const wellboreUidMappingModalProps: WellboreUidMappingModalProps = {
wellbore: sourceWellbores.find(
(wb) => wb.uid === selectedRows[0].sourceWellboreId
),
targetServer: targetServerValue,
onModalClose: () => loadMappings()
};
const action: DisplayModalAction = {
type: OperationType.DisplayModal,
payload: <WellboreUidMappingModal {...wellboreUidMappingModalProps} />
};
dispatchOperation(action);
}
};

const onClose = () => {
dispatchOperation({ type: OperationType.HideModal });
};

const dialogStyle = {
width: "960px",
height: "75vh",
background: colors.ui.backgroundDefault,
color: colors.text.staticIconsDefault
};

return (
<>
<Dialog open={true} style={dialogStyle}>
<Dialog.Header>
<Dialog.Title>Wellbore UID Mapping Overview</Dialog.Title>
</Dialog.Header>
<Dialog.CustomContent>
<ContentLayout>
<HeaderLayout>
<ServerItemLayout>
<StyledAutocomplete
id={"sourceServer"}
label={"Source server:"}
optionLabel={(s: Server) => `${s.name}`}
options={servers}
onOptionsChange={(changes) => {
setMappings([]);
setSourceServerValue(changes.selectedItems[0] as Server);
}}
colors={colors}
/>
</ServerItemLayout>
<ServerItemLayout>
<StyledAutocomplete
id={"targetServer"}
label={"Target server:"}
optionLabel={(s: Server) => `${s.name}`}
options={servers}
onOptionsChange={(changes) => {
setMappings([]);
setTargetServerValue(changes.selectedItems[0] as Server);
}}
colors={colors}
/>
</ServerItemLayout>
</HeaderLayout>
<BodyLayout>
{isFetchingUidMapping ||
isFetchingSourceWellbores ||
isFetchingTargetWellbores ? (
<StyledProgressSpinner message="Fetching data" />
) : (
<ContentTable
viewId={"uidMappingView"}
columns={columns}
data={tableData}
checkableRows
onRowSelectionChange={(rows) =>
setSelectedRows(rows as UidMappingRow[])
}
/>
)}
</BodyLayout>
</ContentLayout>
</Dialog.CustomContent>
<Dialog.Actions>
<FooterLayout>
<Button onClick={onDelete} disabled={selectedRows.length == 0}>
Delete
</Button>
<Button onClick={onEdit} disabled={selectedRows.length != 1}>
Edit
</Button>
<Button onClick={onClose}>Close</Button>
</FooterLayout>
</Dialog.Actions>
</Dialog>
</>
);
};

const StyledAutocomplete = styled(Autocomplete)<{ colors: Colors }>`
button {
color: ${(props) => props.colors.infographic.primaryMossGreen};
}
`;

const ContentLayout = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
height: 82%;
gap: 0.75rem;
`;

const HeaderLayout = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
gap: 0.75rem;
`;

const ServerItemLayout = styled.div`
display: flex;
flex-direction: row;
gap: 0.75rem;
`;

const BodyLayout = styled.div`
display: flex;
flex-direction: column;
gap: 0.75rem;
min-height: 49vh;
`;

const FooterLayout = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 0.75rem;
`;

const StyledProgressSpinner = styled(ProgressSpinnerOverlay)`
Overlay {
width: 96%;
height: 65%;
}
`;

export default WellboreUidMappingOverviewModal;
Loading

0 comments on commit f12593d

Please sign in to comment.