Skip to content

Commit

Permalink
FIX-2594 Priority servers (#2599)
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasbruvik authored Nov 19, 2024
1 parent 3ff43f1 commit 340b341
Show file tree
Hide file tree
Showing 34 changed files with 281 additions and 34 deletions.
1 change: 1 addition & 0 deletions Src/WitsmlExplorer.Api/Models/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public Connection(Server server)
CredentialIds = server.CredentialIds;
Id = server.Id;
DepthLogDecimals = server.DepthLogDecimals;
IsPriority = server.IsPriority;
}

[JsonPropertyName("usernames")]
Expand Down
2 changes: 2 additions & 0 deletions Src/WitsmlExplorer.Api/Models/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public Server() : base(Guid.NewGuid())
public IList<string> CredentialIds { get; init; }
[JsonPropertyName("depthLogDecimals")]
public int DepthLogDecimals { get; init; }
[JsonPropertyName("isPriority")]
public bool IsPriority { get; init; }

public override string ToString()
{
Expand Down
1 change: 1 addition & 0 deletions Src/WitsmlExplorer.Frontend/__testUtils__/testUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export function getServer(overrides?: Partial<Server>): Server {
roles: [],
credentialIds: [],
depthLogDecimals: 0,
isPriority: false,
...overrides
};
}
Expand Down
104 changes: 91 additions & 13 deletions Src/WitsmlExplorer.Frontend/components/ContentViews/ServerManager.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useIsAuthenticated } from "@azure/msal-react";
import {
ButtonProps,
Switch,
Table,
TextField,
Typography
Expand All @@ -14,23 +15,31 @@ import UserCredentialsModal, {
} from "components/Modals/UserCredentialsModal";
import ProgressSpinner from "components/ProgressSpinner";
import { Button } from "components/StyledComponents/Button";
import { CommonPanelContainer } from "components/StyledComponents/Container";
import { useConnectedServer } from "contexts/connectedServerContext";
import { getSearchRegex } from "contexts/filter";
import { FilterContext } from "contexts/filter";
import { useLoggedInUsernames } from "contexts/loggedInUsernamesContext";
import { LoggedInUsernamesActionType } from "contexts/loggedInUsernamesReducer";
import { UserTheme } from "contexts/operationStateReducer";
import OperationType from "contexts/operationType";
import { useGetServers } from "hooks/query/useGetServers";
import { getServersQueryKey, useGetServers } from "hooks/query/useGetServers";
import { useOperationState } from "hooks/useOperationState";
import { Server, emptyServer } from "models/server";
import { useServerFilter } from "hooks/useServerFilter";
import { emptyServer, Server } from "models/server";
import { adminRole, getUserAppRoles, msalEnabled } from "msal/MsalAuthProvider";
import React, { ChangeEvent, useEffect, useState } from "react";
import React, { ChangeEvent, useContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { getWellsViewPath } from "routes/utils/pathBuilder";
import AuthorizationService from "services/authorizationService";
import NotificationService from "services/notificationService";
import ServerService from "services/serverService";
import styled from "styled-components";
import { Colors } from "styles/Colors";
import Icon from "styles/Icons";
import {
setLocalStorageItem,
STORAGE_FILTER_PRIORITYSERVERS_KEY
} from "tools/localStorageHelpers";

const NEW_SERVER_ID = "1";

Expand All @@ -42,18 +51,16 @@ const ServerManager = (): React.ReactElement => {
placeholderData: []
});
const {
operationState: { colors },
operationState: { colors, theme },
dispatchOperation
} = useOperationState();
const editDisabled = msalEnabled && !getUserAppRoles().includes(adminRole);
const navigate = useNavigate();
const { connectedServer, setConnectedServer } = useConnectedServer();
const { dispatchLoggedInUsernames } = useLoggedInUsernames();
const [filter, setFilter] = useState<string>("");
const searchRegex = getSearchRegex(filter);
const filteredServers = servers?.filter(
(s) => !filter || searchRegex.test(s.name) || searchRegex.test(s.url)
);
const [filterByName, setFilterByName] = useState<string>("");
const { selectedFilter, updateSelectedFilter } = useContext(FilterContext);
const filteredServers = useServerFilter(servers, filterByName);

useEffect(() => {
if (isError) {
Expand Down Expand Up @@ -100,6 +107,36 @@ const ServerManager = (): React.ReactElement => {
});
};

const togglePriority = async (server: Server) => {
try {
// Optimistically update the query cache to avoid full rerenders and to keep the scroll position.
queryClient.setQueryData(getServersQueryKey(), (oldServers: Server[]) =>
oldServers?.map((s) =>
s.id === server.id ? { ...s, isPriority: !s.isPriority } : s
)
);

const freshServer = await ServerService.updateServer({
...server,
isPriority: !server.isPriority
});
if (freshServer) {
AuthorizationService.onServerStateChange(freshServer);
}
} catch (error) {
// Roll back on failure
queryClient.setQueryData(getServersQueryKey(), (oldServers: Server[]) =>
oldServers?.map((s) => (s.id === server.id ? server : s))
);

NotificationService.Instance.alertDispatcher.dispatch({
serverUrl: null,
message: `Unable to update priority: ${error.message}`,
isSuccess: false
});
}
};

const CellStyle = {
color: colors.interactive.primaryResting,
padding: "0.3rem",
Expand Down Expand Up @@ -144,11 +181,34 @@ const ServerManager = (): React.ReactElement => {
</Typography>
<StyledTextField
id="serverSearch"
value={filter}
value={filterByName}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setFilter(e.target.value)
setFilterByName(e.target.value)
}
/>
<CommonPanelContainer>
<Switch
checked={selectedFilter.filterPriorityServers}
onChange={() => {
setLocalStorageItem<boolean>(
STORAGE_FILTER_PRIORITYSERVERS_KEY,
!selectedFilter.filterPriorityServers
);
updateSelectedFilter({
filterPriorityServers: !selectedFilter.filterPriorityServers
});
}}
size={theme === UserTheme.Compact ? "small" : "default"}
/>
<Typography
style={{
color: colors.infographic.primaryMossGreen,
whiteSpace: "nowrap"
}}
>
Only show priority servers
</Typography>
</CommonPanelContainer>
</div>
<Button
variant="outlined"
Expand All @@ -169,6 +229,7 @@ const ServerManager = (): React.ReactElement => {
<Table.Cell style={CellHeaderStyle}>Username</Table.Cell>
<Table.Cell style={CellHeaderStyle} />
<Table.Cell style={CellHeaderStyle}>Status</Table.Cell>
<Table.Cell style={CellHeaderStyle}>Priority</Table.Cell>
<Table.Cell style={CellHeaderStyle}></Table.Cell>
<Table.Cell style={CellHeaderStyle}></Table.Cell>
</Table.Row>
Expand Down Expand Up @@ -214,6 +275,23 @@ const ServerManager = (): React.ReactElement => {
}
/>
</Table.Cell>
<Table.Cell style={CellStyle}>
<Button
variant="ghost"
disabled={editDisabled || isError}
onClick={() => togglePriority(server)}
>
<Icon
name={
server.isPriority
? "favoriteFilled"
: "favoriteOutlined"
}
size={24}
color={colors.text.staticIconsTertiary}
/>
</Button>
</Table.Cell>
<Table.Cell style={CellStyle}>
<Button variant="ghost" onClick={() => onEditItem(server)}>
<Icon
Expand All @@ -226,7 +304,7 @@ const ServerManager = (): React.ReactElement => {
<Table.Cell style={CellStyle}>
<Button
data-testid="deleteServerButton"
disabled={editDisabled}
disabled={editDisabled || isError}
variant="ghost"
onClick={() =>
showDeleteServerModal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useConnectedServer } from "contexts/connectedServerContext";
import { useGetServers } from "hooks/query/useGetServers";
import { useOpenInQueryView } from "hooks/useOpenInQueryView";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import BhaRun from "models/bhaRun";
import { ObjectType } from "models/objectType";
import React from "react";
Expand All @@ -24,6 +25,7 @@ const BhaRunContextMenu = (
const { dispatchOperation } = useOperationState();
const openInQueryView = useOpenInQueryView();
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);
const { connectedServer } = useConnectedServer();
const queryClient = useQueryClient();

Expand All @@ -35,6 +37,7 @@ const BhaRunContextMenu = (
ObjectType.BhaRun,
connectedServer,
servers,
filteredServers,
dispatchOperation,
queryClient,
openInQueryView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useConnectedServer } from "contexts/connectedServerContext";
import OperationType from "contexts/operationType";
import { useGetServers } from "hooks/query/useGetServers";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import { ComponentType } from "models/componentType";
import LogCurveInfo from "models/logCurveInfo";
import ObjectOnWellbore from "models/objectOnWellbore";
Expand Down Expand Up @@ -37,6 +38,7 @@ export const CopyComponentsToServerMenuItem = (
} = props;
const { connectedServer } = useConnectedServer();
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);
const { dispatchOperation } = useOperationState();
const menuComponents = menuItemText("copy", componentType, componentsToCopy);
const menuText =
Expand Down Expand Up @@ -87,7 +89,7 @@ export const CopyComponentsToServerMenuItem = (
label={menuText}
disabled={componentsToCopy.length < 1 || disableMenuItem}
>
{servers?.map(
{filteredServers?.map(
(server: Server) =>
server.id !== connectedServer?.id && (
<MenuItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useClipboardComponentReferencesOfType } from "components/ContextMenus/U
import { useConnectedServer } from "contexts/connectedServerContext";
import { useGetServers } from "hooks/query/useGetServers";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import { ComponentType } from "models/componentType";
import Fluid from "models/fluid";
import FluidsReport from "models/fluidsReport";
Expand All @@ -40,6 +41,7 @@ const FluidContextMenu = (props: FluidContextMenuProps): React.ReactElement => {
);
const { connectedServer } = useConnectedServer();
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);

const toDelete = createComponentReferences(
checkedFluids.map((fluid) => fluid.uid),
Expand Down Expand Up @@ -111,7 +113,7 @@ const FluidContextMenu = (props: FluidContextMenuProps): React.ReactElement => {
</Typography>
</MenuItem>,
<NestedMenuItem key={"showOnServer"} label={"Show on server"}>
{servers.map((server: Server) => (
{filteredServers.map((server: Server) => (
<MenuItem
key={server.name}
onClick={() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useConnectedServer } from "contexts/connectedServerContext";
import { useGetServers } from "hooks/query/useGetServers";
import { useOpenInQueryView } from "hooks/useOpenInQueryView";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import { ComponentType } from "models/componentType";
import FluidsReport from "models/fluidsReport";
import { ObjectType } from "models/objectType";
Expand All @@ -28,6 +29,7 @@ const FluidsReportContextMenu = (
): React.ReactElement => {
const { checkedObjects } = props;
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);
const { dispatchOperation } = useOperationState();
const openInQueryView = useOpenInQueryView();
const fluidReferences = useClipboardComponentReferencesOfType(
Expand Down Expand Up @@ -66,6 +68,7 @@ const FluidsReportContextMenu = (
ObjectType.FluidsReport,
connectedServer,
servers,
filteredServers,
dispatchOperation,
queryClient,
openInQueryView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useConnectedServer } from "contexts/connectedServerContext";
import { useGetServers } from "hooks/query/useGetServers";
import { useOpenInQueryView } from "hooks/useOpenInQueryView";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import FormationMarker from "models/formationMarker";
import { ObjectType } from "models/objectType";
import React from "react";
Expand All @@ -26,6 +27,7 @@ const FormationMarkerContextMenu = (
const { connectedServer } = useConnectedServer();
const queryClient = useQueryClient();
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);

const extraMenuItems = (): React.ReactElement[] => {
return [
Expand Down Expand Up @@ -55,6 +57,7 @@ const FormationMarkerContextMenu = (
ObjectType.FormationMarker,
connectedServer,
servers,
filteredServers,
dispatchOperation,
queryClient,
openInQueryView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
HideModalAction
} from "contexts/operationStateReducer";
import OperationType from "contexts/operationType";
import { useServerFilter } from "hooks/useServerFilter";
import { ComponentType } from "models/componentType";
import { IndexCurve } from "models/indexCurve";
import { createComponentReferences } from "models/jobs/componentReferences";
Expand Down Expand Up @@ -82,6 +83,8 @@ const LogCurveInfoContextMenu = (
isMultiLog = false
} = props;

const filteredServers = useServerFilter(servers);

const onlyPrioritizedCurvesAreChecked = checkedLogCurveInfoRows.every(
(row, index) =>
prioritizedLocalCurves.includes(row.mnemonic) ||
Expand Down Expand Up @@ -374,7 +377,7 @@ const LogCurveInfoContextMenu = (
label={"Show on server"}
disabled={isMultiLog}
>
{servers.map((server: Server) => (
{filteredServers.map((server: Server) => (
<MenuItem
key={server.name}
onClick={() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import OperationType from "contexts/operationType";
import { useGetServers } from "hooks/query/useGetServers";
import { useOpenInQueryView } from "hooks/useOpenInQueryView";
import { useOperationState } from "hooks/useOperationState";
import { useServerFilter } from "hooks/useServerFilter";
import { ComponentType } from "models/componentType";
import CheckLogHeaderJob from "models/jobs/checkLogHeaderJob";
import CompareLogDataJob from "models/jobs/compareLogData";
Expand Down Expand Up @@ -74,6 +75,7 @@ const LogObjectContextMenu = (
useClipboardComponentReferencesOfType(ComponentType.Mnemonic);
const { connectedServer } = useConnectedServer();
const { servers } = useGetServers();
const filteredServers = useServerFilter(servers);
const queryClient = useQueryClient();
const navigate = useNavigate();

Expand Down Expand Up @@ -479,6 +481,7 @@ const LogObjectContextMenu = (
ObjectType.Log,
connectedServer,
servers,
filteredServers,
dispatchOperation,
queryClient,
openInQueryView,
Expand Down
Loading

0 comments on commit 340b341

Please sign in to comment.