Skip to content

Commit

Permalink
800 fix minor realization filter issues (#801)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgenherje authored Nov 8, 2024
1 parent fab6727 commit 09109b0
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 146 deletions.
10 changes: 10 additions & 0 deletions frontend/src/framework/GuiMessageBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { isDevMode } from "@lib/utils/devMode";
import { Size2D } from "@lib/utils/geometry";
import { Vec2 } from "@lib/utils/vec2";

import { UnsavedChangesAction } from "./types/unsavedChangesAction";

export enum LeftDrawerContent {
ModuleSettings = "ModuleSettings",
ModulesList = "ModulesList",
Expand All @@ -27,6 +29,7 @@ export enum GuiState {
EditDataChannelConnections = "editDataChannelConnections",
RightSettingsPanelWidthInPercent = "rightSettingsPanelWidthInPercent",
AppInitialized = "appInitialized",
NumberOfUnsavedRealizationFilters = "numberOfUnsavedRealizationFilters",
}

export enum GuiEvent {
Expand All @@ -43,6 +46,7 @@ export enum GuiEvent {
DataChannelConnectionsChange = "dataChannelConnectionsChange",
DataChannelNodeHover = "dataChannelNodeHover",
DataChannelNodeUnhover = "dataChannelNodeUnhover",
UnsavedRealizationFilterSettingsAction = "unsavedRealizationFilterSettingsAction",
}

export type GuiEventPayloads = {
Expand Down Expand Up @@ -75,6 +79,9 @@ export type GuiEventPayloads = {
[GuiEvent.DataChannelNodeHover]: {
connectionAllowed: boolean;
};
[GuiEvent.UnsavedRealizationFilterSettingsAction]: {
action: UnsavedChangesAction;
};
};

type GuiStateValueTypes = {
Expand All @@ -87,6 +94,7 @@ type GuiStateValueTypes = {
[GuiState.EditDataChannelConnections]: boolean;
[GuiState.RightSettingsPanelWidthInPercent]: number;
[GuiState.AppInitialized]: boolean;
[GuiState.NumberOfUnsavedRealizationFilters]: number;
};

const defaultStates: Map<GuiState, any> = new Map();
Expand All @@ -98,12 +106,14 @@ defaultStates.set(GuiState.DataChannelConnectionLayerVisible, false);
defaultStates.set(GuiState.DevToolsVisible, isDevMode());
defaultStates.set(GuiState.RightSettingsPanelWidthInPercent, 0);
defaultStates.set(GuiState.AppInitialized, false);
defaultStates.set(GuiState.NumberOfUnsavedRealizationFilters, 0);

const persistentStates: GuiState[] = [
GuiState.LeftSettingsPanelWidthInPercent,
GuiState.DevToolsVisible,
GuiState.RightSettingsPanelWidthInPercent,
GuiState.RightDrawerContent,
GuiState.NumberOfUnsavedRealizationFilters,
];

export class GuiMessageBroker {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,33 +211,45 @@ export const EnsembleRealizationFilter: React.FC<EnsembleRealizationFilterProps>
}
}

const activeStyleClasses = {
"ring ring-opacity-100 shadow-lg": true,
"ring-blue-400 shadow-blue-400": !props.hasUnsavedSelections,
"ring-orange-400 shadow-orange-400": props.hasUnsavedSelections,
};
const inactiveStyleClasses = {
"cursor-pointer ring-2": true,
"ring-opacity-100": !props.isAnotherFilterActive,
"ring-opacity-50 group hover:shadow-md hover:ring-opacity-75 transition-opacity": props.isAnotherFilterActive,
"ring-gray-300 shadow-gray-300 ": !props.hasUnsavedSelections,
"ring-orange-400 shadow-orange-400": props.hasUnsavedSelections,
"hover:shadow-blue-400 hover:shadow-lg shadow-md": !props.isAnotherFilterActive && props.hasUnsavedSelections,
"hover:ring-blue-400 hover:shadow-blue-400 hover:shadow-md":
!props.isAnotherFilterActive && !props.hasUnsavedSelections,
};
const mainDivStyleClasses = props.isActive ? activeStyleClasses : inactiveStyleClasses;

return (
<div
className={resolveClassNames("outline mb-4 rounded-md", {
"cursor-pointer": !props.isActive,
"hover:opacity-75 transition-opacity duration-100": !props.isActive && props.isAnotherFilterActive,
"hover:outline-blue-400 hover:shadow-blue-400 hover:shadow-md":
!props.isActive && !props.isAnotherFilterActive,
"outline-orange-400 shadow-orange-400 shadow-lg": props.isActive && props.hasUnsavedSelections,
"outline-blue-400 shadow-blue-400 shadow-lg": props.isActive && !props.hasUnsavedSelections,
"opacity-100": props.isActive || !props.isAnotherFilterActive,
"opacity-60 ": !props.isActive && props.isAnotherFilterActive && props.hasUnsavedSelections,
"opacity-30": !props.isActive && props.isAnotherFilterActive && !props.hasUnsavedSelections,
"outline-2 outline-orange-400 shadow-orange-400 shadow-lg":
!props.isActive && props.hasUnsavedSelections,
"outline-2 outline-gray-300 shadow-gray-300 shadow-md": !props.isActive && !props.hasUnsavedSelections,
})}
className={resolveClassNames("rounded-md", mainDivStyleClasses)}
title={!props.isActive ? "Click to open filter" : undefined}
>
<div className={`flex justify-center items-center p-2 rounded-md bg-slate-100 h-12 cursor-pointer`}>
<div className="flex justify-center items-center bg-slate-100 h-12 rounded-tl-md rounded-tr-md">
<div
className="font-bold flex-grow text-sm overflow-ellipsis overflow-hidden whitespace-nowrap"
title={`Ensemble: ${props.ensembleName}`}
className={resolveClassNames(
"flex-grow h-full pl-2 flex items-center cursor-pointer font-bold text-sm overflow-ellipsis overflow-hidden whitespace-nowrap",
{
"pr-2": !props.hasUnsavedSelections,
"opacity-20 group-hover:opacity-75 transition-opacity duration-100":
!props.isActive && props.isAnotherFilterActive,
}
)}
title={props.isActive ? `Ensemble: ${props.ensembleName}` : undefined}
onClick={handleHeaderOnClick}
>
{props.ensembleName}
</div>
<div
className={resolveClassNames("flex items-center gap-1", {
className={resolveClassNames("flex h-full items-center gap-1 pr-2", {
hidden: !props.hasUnsavedSelections,
})}
>
Expand All @@ -260,7 +272,13 @@ export const EnsembleRealizationFilter: React.FC<EnsembleRealizationFilterProps>
/>
</div>
</div>
<div onClickCapture={handleBodyOnClickCapture}>
<div
className={resolveClassNames({
"opacity-20 group-hover:opacity-75 transition-opacity duration-100":
!props.isActive && props.isAnotherFilterActive,
})}
onClickCapture={handleBodyOnClickCapture}
>
<div className="flex flex-col gap-2 p-2">
<div className="border border-lightgrey p-2 rounded-md">
<RealizationNumberDisplay
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ export const RealizationNumberDisplay: React.FC<RealizationNumberDisplayProps> =
const nonCompactWidthAndHeightPx = 12;

// Find the number of realizations that can fit in a row based on non-compact size, as factor of 5
const candidateNumberOfRealizationsPerRow = Math.floor(
divSize.width / (nonCompactWidthAndHeightPx + nonCompactGapPx)
const candidateNumberOfRealizationsPerRow = Math.max(
5,
Math.floor(divSize.width / (nonCompactWidthAndHeightPx + nonCompactGapPx))
);
const remainder = candidateNumberOfRealizationsPerRow % 5;
const newNumberOfRealizationsPerRow =
Expand Down
38 changes: 23 additions & 15 deletions frontend/src/framework/internal/components/NavBar/rightNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";

import { GuiState, RightDrawerContent, useGuiState } from "@framework/GuiMessageBroker";
import { Workbench } from "@framework/Workbench";
import { Badge } from "@lib/components/Badge";
import { Button } from "@lib/components/Button";
import { resolveClassNames } from "@lib/utils/resolveClassNames";
import { FilterAlt, History } from "@mui/icons-material";
Expand All @@ -11,27 +12,24 @@ type RightNavBarProps = {
};

export const RightNavBar: React.FC<RightNavBarProps> = (props) => {
const [drawerContent, setDrawerContent] = useGuiState(
props.workbench.getGuiMessageBroker(),
GuiState.RightDrawerContent
const guiMessageBroker = props.workbench.getGuiMessageBroker();
const [drawerContent, setDrawerContent] = useGuiState(guiMessageBroker, GuiState.RightDrawerContent);
const [numberOfUnsavedRealizationFilters] = useGuiState(
guiMessageBroker,
GuiState.NumberOfUnsavedRealizationFilters
);

const [rightSettingsPanelWidth, setRightSettingsPanelWidth] = useGuiState(
props.workbench.getGuiMessageBroker(),
guiMessageBroker,
GuiState.RightSettingsPanelWidthInPercent
);

function ensureSettingsPanelIsVisible() {
if (rightSettingsPanelWidth <= 5) {
setRightSettingsPanelWidth(15);
setRightSettingsPanelWidth(30);
}
}

function handleRealizationFilterClick() {
if (rightSettingsPanelWidth > 0 && drawerContent === RightDrawerContent.RealizationFilterSettings) {
setRightSettingsPanelWidth(0);
return;
}
ensureSettingsPanelIsVisible();
setDrawerContent(RightDrawerContent.RealizationFilterSettings);
}
Expand All @@ -49,7 +47,9 @@ export const RightNavBar: React.FC<RightNavBarProps> = (props) => {
>
<div className="flex flex-col gap-2 flex-grow">
<Button
title="Open realization filter panel"
title={`Open realization filter panel${
numberOfUnsavedRealizationFilters === 0 ? "" : " (unsaved changes)"
}`}
onClick={handleRealizationFilterClick}
className={resolveClassNames(
"w-full",
Expand All @@ -58,8 +58,15 @@ export const RightNavBar: React.FC<RightNavBarProps> = (props) => {
? "text-cyan-600"
: "!text-slate-800"
)}
startIcon={<FilterAlt fontSize="small" className="w-5 h-5 mr-2" />}
/>
>
{numberOfUnsavedRealizationFilters !== 0 ? (
<Badge badgeContent="!" color="bg-orange-500">
<FilterAlt fontSize="small" className="w-5 h-5 mr-2" />
</Badge>
) : (
<FilterAlt fontSize="small" className="w-5 h-5 mr-2" />
)}
</Button>
<Button
title="Open realization filter panel"
onClick={handleModuleInstanceLogClick}
Expand All @@ -70,8 +77,9 @@ export const RightNavBar: React.FC<RightNavBarProps> = (props) => {
? "text-cyan-600"
: "!text-slate-800"
)}
startIcon={<History fontSize="small" className="w-5 h-5 mr-2" />}
/>
>
<History fontSize="small" className="w-5 h-5 mr-2" />
</Button>
</div>
</div>
);
Expand Down
Loading

0 comments on commit 09109b0

Please sign in to comment.