Skip to content

Commit

Permalink
Improved ensemble selection dialog and added new table select component
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Oct 16, 2023
1 parent c127634 commit bd81723
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 18 deletions.
2 changes: 1 addition & 1 deletion backend/src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
SMDA_SUBSCRIPTION_KEY = os.environ["WEBVIZ_SMDA_SUBSCRIPTION_KEY"]
SMDA_RESOURCE_SCOPE = os.environ["WEBVIZ_SMDA_RESOURCE_SCOPE"]
SUMO_ENV = os.getenv("WEBVIZ_SUMO_ENV", "dev")
GRAPH_SCOPES = ["User.ReadBasic.All"]
GRAPH_SCOPES = ["User.Read", "User.ReadBasic.All"]

RESOURCE_SCOPES_DICT = {
"sumo": [f"api://{sumo_app_reg[SUMO_ENV]['RESOURCE_ID']}/access_as_user"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function useUserInfoQuery(
): UseQueryResult<GraphUserPhoto_api> {
return useQuery({
queryKey: ["getUserInfo", userId],
queryFn: () => apiService.graph.userInfo(userId),
queryFn: () => apiService.graph.userInfo(`${userId.toUpperCase()}@equinor.com`),
staleTime: STALE_TIME,
cacheTime: CACHE_TIME,
enabled: userId !== "",
Expand All @@ -42,5 +42,5 @@ export const UserAvatar: React.FC<UserAvatarProps> = (props) => {
/>
);
}
return <AccountCircle className="w-5 h-5 mr-1" />;
return <span title={props.userId}><AccountCircle className="w-5 h-5 mr-1" /></span>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";

import { CaseInfo_api, EnsembleInfo_api } from "@api";
import { apiService } from "@framework/ApiService";
import { useAuthProvider } from "@framework/internal/providers/AuthProvider";
import { ApiStateWrapper } from "@lib/components/ApiStateWrapper";
import { Button } from "@lib/components/Button";
import { CircularProgress } from "@lib/components/CircularProgress";
Expand All @@ -10,12 +11,15 @@ import { Dropdown } from "@lib/components/Dropdown";
import { IconButton } from "@lib/components/IconButton";
import { Label } from "@lib/components/Label";
import { Select } from "@lib/components/Select";
import { Switch } from "@lib/components/Switch";
import { TableSelect, TableSelectOption } from "@lib/components/TableSelect";
import { TagPicker } from "@lib/components/TagPicker";
import { useValidState } from "@lib/hooks/useValidState";
import { Add, Check, Remove } from "@mui/icons-material";
import { useQuery } from "@tanstack/react-query";

import { isEqual } from "lodash";
import { Switch } from "@lib/components/Switch";

import { UserAvatar } from "./private-components/userAvatar";

export type EnsembleItem = {
Expand Down Expand Up @@ -47,6 +51,8 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
users: [],
});

const { userInfo } = useAuthProvider();

React.useLayoutEffect(() => {
setNewlySelectedEnsembles(props.selectedEnsembles);
}, [props.selectedEnsembles]);
Expand Down Expand Up @@ -179,13 +185,23 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
filteredCases = filteredCases.filter((c) => c.status === "keep");
}
if (casesFilteringOptions.onlyMyCases) {
filteredCases = filteredCases.filter((c) => c.user === "me");
filteredCases = filteredCases.filter((c) => c.user === userInfo?.username.replace("@equinor.com", ""));
} else if (casesFilteringOptions.users.length > 0) {
filteredCases = filteredCases.filter((c) => casesFilteringOptions.users.includes(c.user));
}
return filteredCases;
}

const fieldOpts = fieldsQuery.data?.map((f) => ({ value: f.field_identifier, label: f.field_identifier })) ?? [];
const caseOpts = filterCases(casesQuery.data)?.map((c) => ({ value: c.uuid, label: c.name, icon: <UserAvatar userId={`${c.user.toUpperCase()}@equinor.com`} /> })) ?? [];
const caseOpts: TableSelectOption[] =
filterCases(casesQuery.data)?.map((el) => ({
id: el.uuid,
values: [
{ label: el.name },
{ label: el.user, adornment: <UserAvatar userId={el.user} /> },
{ label: el.status },
],
})) ?? [];
const ensembleOpts =
ensemblesQuery.data?.map((e) => ({ value: e.name, label: `${e.name} (${e.realization_count} reals)` })) ?? [];

Expand All @@ -199,6 +215,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
title="Select ensembles"
modal
width={"75%"}
minWidth={800}
actions={
<div className="flex gap-4">
<Button onClick={handleClose} color="danger" disabled={!checkIfAnyChanges()}>
Expand Down Expand Up @@ -233,18 +250,33 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
errorComponent={<div className="text-red-500">Error loading cases</div>}
loadingComponent={<CircularProgress />}
>
<div className="flex justify-end gap-4">
<Label position="right" text="Keep"><Switch checked={casesFilteringOptions.keep} onChange={handleKeepCasesSwitchChange} /></Label>
<Label position="right" text="My cases"><Switch checked={casesFilteringOptions.onlyMyCases} onChange={handleCasesByMeChange} /></Label>
</div>
<Select
<div className="flex justify-end gap-4 items-center">
<span className="flex-grow text-sm text-slate-500">
Select from {caseOpts.length} cases
</span>
<Label position="right" text="Keep" title="Show only cases marked as keep">
<Switch
checked={casesFilteringOptions.keep}
onChange={handleKeepCasesSwitchChange}
/>
</Label>
<Label position="right" text="My cases" title="Show only cases that I created">
<Switch
checked={casesFilteringOptions.onlyMyCases}
onChange={handleCasesByMeChange}
/>
</Label>
</div>
<TableSelect
headerLabels={["Name", "Author", "Status"]}
options={caseOpts}
value={[selectedCaseId]}
onChange={handleCaseChanged}
disabled={caseOpts.length === 0}
size={5}
width={400}
filter
columnSizesInPercent={[60, 20, 20]}
/>
</ApiStateWrapper>
</Label>
Expand Down Expand Up @@ -280,7 +312,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
</div>
<div className="flex flex-col flex-grow gap-4 p-4">
<Label text="Selected Ensembles">
<table className="w-full border border-collapse table-fixed">
<table className="w-full border border-collapse table-fixed text-sm">
<thead>
<tr>
<th className="min-w-1/2 text-left p-2 bg-slate-300">Case</th>
Expand Down Expand Up @@ -316,6 +348,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
handleRemoveEnsemble(item.caseUuid, item.ensembleName)
}
color="danger"
title="Remove ensemble from selection"
>
<Remove fontSize="small" />
</IconButton>{" "}
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/lib/components/Label/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { v4 } from "uuid";

export type LabelProps = {
text: string;
title?: string;
children: React.ReactElement;
wrapperClassName?: string;
labelClassName?: string;
Expand All @@ -22,8 +23,9 @@ export const Label: React.FC<LabelProps> = (props) => {
className={resolveClassNames(props.wrapperClassName ?? "", {
"flex flex-col": props.position === "above" && props.position === undefined,
"flex flex-row items-center gap-4": props.position === "left",
"flex items-center flex-row-reverse gap-4": props.position === "right"
"flex items-center flex-row-reverse gap-4": props.position === "right",
})}
title={props.title}
>
<label
className={resolveClassNames(
Expand All @@ -47,7 +49,9 @@ export const Label: React.FC<LabelProps> = (props) => {
)}
{props.text}
</label>
<div className={resolveClassNames({ "flex-grow": props.position === "left" || props.position === "right" })}>
<div
className={resolveClassNames({ "flex-grow": props.position === "left" || props.position === "right" })}
>
{props.children.props.id ? props.children : React.cloneElement(props.children, { id: id.current })}
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/lib/components/Select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const Select = withDefaults<SelectProps>()(defaultProps, (props) => {
"pl-2",
"pr-2",
"flex",
"gap-2",
"items-center",
"select-none",
{
Expand All @@ -251,11 +252,10 @@ export const Select = withDefaults<SelectProps>()(defaultProps, (props) => {
toggleValue(option, index);
}}
style={{ height: 24 }}
title={option.label}
>
<span className="min-w-0 text-ellipsis overflow-hidden whitespace-nowrap flex flex-gap-2">
{option.icon}
{option.label}
{option.icon}
<span title={option.label} className="min-w-0 text-ellipsis overflow-hidden whitespace-nowrap">
{option.label}
</span>
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lib/components/TableSelect/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { TableSelect } from "./tableSelect";
export type { TableSelectOption, TableSelectProps } from "./tableSelect";
Loading

0 comments on commit bd81723

Please sign in to comment.