Skip to content

Commit

Permalink
Ensemble selector initially visible, added notification to modules list
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Jun 13, 2024
1 parent c67869c commit 5f80fbc
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 31 deletions.
10 changes: 7 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,13 @@ function App() {
"opacity-100": !isInitializingApp,
})}
>
<LeftNavBar workbench={WORKBENCH} />
<SettingsContentPanels workbench={WORKBENCH} />
<RightNavBar workbench={WORKBENCH} />
{!isInitializingApp && (
<>
<LeftNavBar workbench={WORKBENCH} />
<SettingsContentPanels workbench={WORKBENCH} />
<RightNavBar workbench={WORKBENCH} />
</>
)}
</div>
<ToggleDevToolsButton guiMessageBroker={WORKBENCH.getGuiMessageBroker()} />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ModuleRegistry } from "@framework/ModuleRegistry";
import { DrawPreviewFunc } from "@framework/Preview";
import { Workbench } from "@framework/Workbench";
import { Drawer } from "@framework/internal/components/Drawer";
import { useModuleInstances } from "@framework/internal/hooks/workbenchHooks";
import { Checkbox } from "@lib/components/Checkbox";
import { useElementBoundingRect } from "@lib/hooks/useElementBoundingRect";
import { createPortal } from "@lib/utils/createPortal";
Expand Down Expand Up @@ -460,6 +461,7 @@ if (isDevMode()) {

export const ModulesList: React.FC<ModulesListProps> = (props) => {
const drawerContent = useGuiValue(props.workbench.getGuiMessageBroker(), GuiState.DrawerContent);
const moduleInstances = useModuleInstances(props.workbench);

const ref = React.useRef<HTMLDivElement>(null);
const boundingClientRect = useElementBoundingRect(ref);
Expand Down Expand Up @@ -500,6 +502,10 @@ export const ModulesList: React.FC<ModulesListProps> = (props) => {
setDetailsPosY(yPos);
}

function handleNotificationClick() {
props.workbench.getGuiMessageBroker().setState(GuiState.DrawerContent, DrawerContent.ModuleSettings);
}

const handleDraggingStart = React.useCallback(function handleDraggingStart() {
setShowDetailsForModule(null);
}, []);
Expand All @@ -524,7 +530,12 @@ export const ModulesList: React.FC<ModulesListProps> = (props) => {
showFilter
filterPlaceholder="Filter modules..."
onFilterChange={handleSearchQueryChange}
headerChildren={<DevStatesFilter onFilterChange={handleDevStatesChange} initialDevStates={devStates} />}
headerChildren={
<>
<Notification onClick={handleNotificationClick} visible={moduleInstances.length > 0} />
<DevStatesFilter onFilterChange={handleDevStatesChange} initialDevStates={devStates} />
</>
}
>
<>
{MODULE_CATEGORIES.map((el) => (
Expand Down Expand Up @@ -563,3 +574,23 @@ export const ModulesList: React.FC<ModulesListProps> = (props) => {
</div>
);
};

type NotificationProps = {
visible: boolean;
onClick: () => void;
};

function Notification(props: NotificationProps): React.ReactNode {
if (!props.visible) {
return null;
}
return (
<div
className="bg-green-600 hover:bg-green-500 p-2 mb-4 text-sm cursor-pointer text-white"
onClick={props.onClick}
>
<p className="font-bold mb-1">Done editing?</p>
Click here or on a module header to start using your dashboard.
</div>
);
}
34 changes: 18 additions & 16 deletions frontend/src/framework/internal/components/NavBar/leftNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ const NavBarDivider: React.FC = () => {
};

export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
const [ensembleDialogOpen, setEnsembleDialogOpen] = React.useState<boolean>(false);
const ensembleSet = useEnsembleSet(props.workbench.getWorkbenchSession());
const [ensembleDialogOpen, setEnsembleDialogOpen] = React.useState<boolean>(
ensembleSet.getEnsembleArr().length === 0
);
const [newSelectedEnsembles, setNewSelectedEnsembles] = React.useState<EnsembleItem[]>([]);
const [layoutEmpty, setLayoutEmpty] = React.useState<boolean>(props.workbench.getLayout().length === 0);
const [expanded, setExpanded] = React.useState<boolean>(localStorage.getItem("navBarExpanded") === "true");
const [collapsed, setCollapsed] = React.useState<boolean>(localStorage.getItem("navBarCollapsed") === "true");
const loadingEnsembleSet = useIsEnsembleSetLoading(props.workbench.getWorkbenchSession());
const [drawerContent, setDrawerContent] = useGuiState(
props.workbench.getGuiMessageBroker(),
Expand All @@ -40,7 +43,6 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
props.workbench.getGuiMessageBroker(),
GuiState.LeftSettingsPanelWidthInPercent
);
const ensembleSet = useEnsembleSet(props.workbench.getWorkbenchSession());

const queryClient = useQueryClient();
const colorSet = props.workbench.getWorkbenchSettings().useColorSet();
Expand Down Expand Up @@ -106,8 +108,8 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
}

function handleCollapseOrExpand() {
setExpanded(!expanded);
localStorage.setItem("navBarExpanded", (!expanded).toString());
setCollapsed(!collapsed);
localStorage.setItem("navBarCollapsed", (!collapsed).toString());
}

const selectedEnsembles: EnsembleItem[] = ensembleSet.getEnsembleArr().map((ens) => ({
Expand Down Expand Up @@ -137,7 +139,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
<div
className={resolveClassNames(
"bg-white p-2 border-r-2 border-slate-200 z-50 shadow-lg flex flex-col",
expanded ? "w-64" : "w-[4.5rem]"
collapsed ? "w-[4.5rem]" : "w-64"
)}
>
<div className="flex flex-col gap-2 flex-grow">
Expand All @@ -154,9 +156,9 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
<Button
onClick={handleCollapseOrExpand}
className="!text-slate-800"
title={expanded ? "Collapse menu" : "Expand menu"}
title={collapsed ? "Expand menu" : "Collapse menu"}
>
{expanded ? <ChevronLeft fontSize="small" /> : <ChevronRight fontSize="small" />}
{collapsed ? <ChevronRight fontSize="small" /> : <ChevronLeft fontSize="small" />}
</Button>
</div>
<NavBarDivider />
Expand Down Expand Up @@ -184,7 +186,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
)
}
>
{expanded ? "Ensembles" : ""}
{!collapsed ? "Ensembles" : ""}
</Button>
<NavBarDivider />
<Button
Expand All @@ -198,7 +200,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
)}
disabled={layoutEmpty}
>
{expanded ? "Module settings" : ""}
{!collapsed ? "Module settings" : ""}
</Button>
<Button
title="Show sync settings"
Expand All @@ -211,7 +213,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
)}
disabled={layoutEmpty}
>
{expanded ? "Sync settings" : ""}
{!collapsed ? "Sync settings" : ""}
</Button>
<NavBarDivider />
<Button
Expand All @@ -224,7 +226,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
drawerContent === DrawerContent.ModulesList ? "text-cyan-600" : "!text-slate-800"
)}
>
{expanded ? "Add modules" : ""}
{!collapsed ? "Add modules" : ""}
</Button>
<Button
title="Show templates list"
Expand All @@ -236,7 +238,7 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
drawerContent === DrawerContent.TemplatesList ? "text-cyan-600" : "!text-slate-800"
)}
>
{expanded ? "Use templates" : ""}
{!collapsed ? "Use templates" : ""}
</Button>
<NavBarDivider />
<Button
Expand All @@ -249,14 +251,14 @@ export const LeftNavBar: React.FC<LeftNavBarProps> = (props) => {
drawerContent === DrawerContent.ColorPaletteSettings ? "text-cyan-600" : "!text-slate-800"
)}
>
{expanded ? "Color settings" : ""}
{!collapsed ? "Color settings" : ""}
</Button>
<NavBarDivider />
<LoginButton className="w-full !text-slate-800 h-10" showText={expanded} />
<LoginButton className="w-full !text-slate-800 h-10" showText={!collapsed} />
<div className="flex-grow h-5" />
<div className={isDevMode() ? "mb-16" : ""}>
<NavBarDivider />
<UserSessionState expanded={expanded} />
<UserSessionState expanded={!collapsed} />
</div>
</div>
{ensembleDialogOpen && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ interface CaseFilterSettings {
users: string[];
}

function readInitialStateFromLocalStorage(stateName: string): string {
const storedState = localStorage.getItem(stateName);
if (storedState && typeof storedState === "string") {
return storedState;
}
return "";
}

function storeStateInLocalStorage(stateName: string, value: string) {
localStorage.setItem(stateName, value);
}

export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (props) => {
const [isLoadingEnsembles, setIsLoadingEnsembles] = React.useState<boolean>(false);
const [confirmCancel, setConfirmCancel] = React.useState<boolean>(false);
Expand All @@ -74,7 +86,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
});

const [selectedField, setSelectedField] = useValidState<string>({
initialState: "",
initialState: readInitialStateFromLocalStorage("selectedField"),
validStates: fieldsQuery.data?.map((item) => item.field_identifier) ?? [],
keepStateWhenInvalid: true,
});
Expand All @@ -94,7 +106,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop

const [selectedCaseId, setSelectedCaseId] = useValidState<string>({
initialState: "",
validStates: casesQuery.data?.map((item) => item.uuid) ?? [],
validStates: filterCases(casesQuery.data)?.map((item) => item.uuid) ?? [],
keepStateWhenInvalid: true,
});

Expand All @@ -118,6 +130,7 @@ export const SelectEnsemblesDialog: React.FC<SelectEnsemblesDialogProps> = (prop
});

function handleFieldChanged(fieldIdentifier: string) {
storeStateInLocalStorage("selectedField", fieldIdentifier);
setSelectedField(fieldIdentifier);
}

Expand Down
22 changes: 13 additions & 9 deletions frontend/src/lib/components/TableSelect/tableSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const TableSelect = withDefaults<TableSelectProps>()(defaultProps, (props
const [lastShiftIndex, setLastShiftIndex] = React.useState<number>(-1);
const [currentIndex, setCurrentIndex] = React.useState<number>(0);
const [prevFilteredOptions, setPrevFilteredOptions] = React.useState<TableSelectOption[]>([]);
const [prevValue, setPrevValue] = React.useState<string[] | undefined>(props.value);

if (!isEqual(prevHeaderLabels, props.headerLabels)) {
setPrevHeaderLabels(props.headerLabels);
Expand Down Expand Up @@ -92,6 +93,18 @@ export const TableSelect = withDefaults<TableSelectProps>()(defaultProps, (props
[props.options, filters, props.filter]
);

if (!isEqual(prevValue, props.value)) {
setPrevValue(props.value);
setSelected(props.value ?? []);
if (props.value?.length === 1) {
const newIndex = filteredOptions.findIndex((option) => option.id === props.value[0]);
if (newIndex !== -1) {
setCurrentIndex(newIndex);
setStartIndex(newIndex);
}
}
}

if (!checkForEqualityWithoutAdornment(filteredOptions, prevFilteredOptions)) {
let newCurrentIndex = 0;
let newStartIndex = 0;
Expand Down Expand Up @@ -212,15 +225,6 @@ export const TableSelect = withDefaults<TableSelectProps>()(defaultProps, (props
[currentIndex, selected, filteredOptions, props.size, hasFocus, startIndex, toggleValue]
);

React.useLayoutEffect(
function handleInitialSelection() {
if (props.value) {
setSelected(props.value);
}
},
[props.value]
);

function handleFilterChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, index: number) {
setFilters((prev) => {
const newFilters = [...prev];
Expand Down

0 comments on commit 5f80fbc

Please sign in to comment.