Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move search button in top-bar next to tabs #1778

Merged
merged 5 commits into from
Dec 20, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 138 additions & 66 deletions src/components/app-top-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,33 @@

import { useCallback, useEffect, useState } from 'react';
import {
ElementSearchDialog,
EquipmentItem,
equipmentStyles,
LIGHT_THEME,
logout,
EquipmentItem,
OverflowableText,
TagRenderer,
TopBar,
OverflowableText,
} from '@gridsuite/commons-ui';
import { ReactComponent as GridStudyLogoLight } from '../images/GridStudy_logo_light.svg';
import { ReactComponent as GridStudyLogoDark } from '../images/GridStudy_logo_dark.svg';
import Tabs from '@mui/material/Tabs';
import { StudyView } from './study-pane';
import { Badge, Box } from '@mui/material';
import {
Badge,
Box,
Button,
IconButton,
Tab,
Tabs,
Tooltip,
} from '@mui/material';
import {
GpsFixed as GpsFixedIcon,
Search,
Timeline as TimelineIcon,
} from '@mui/icons-material';
import { FormattedMessage, useIntl } from 'react-intl';
import Tab from '@mui/material/Tab';
import {
PARAM_LANGUAGE,
PARAM_THEME,
Expand All @@ -36,13 +48,10 @@ import {
STUDY_DISPLAY_MODE,
STUDY_INDEXATION_STATUS,
} from '../redux/actions';
import IconButton from '@mui/material/IconButton';
import GpsFixedIcon from '@mui/icons-material/GpsFixed';
import TimelineIcon from '@mui/icons-material/Timeline';
import {
DiagramType,
useDiagram,
NETWORK_AREA_DIAGRAM_NB_MAX_VOLTAGE_LEVELS,
useDiagram,
} from './diagrams/diagram-common';
import { isNodeBuilt, isNodeReadOnly } from './graph/util/model-functions';
import Parameters, { useParameterState } from './dialogs/parameters/parameters';
Expand All @@ -59,20 +68,33 @@ import { useComputationNotificationCount } from '../hooks/use-computation-notifi
import { useComputationNotification } from '../hooks/use-computation-notification';

const styles = {
tabs: {
flexGrow: 1,
currentNodeBox: {
width: '15%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderColor: '#123456',
},
label: (theme) => ({
currentNodeLabel: (theme) => ({
color: theme.palette.primary.main,
margin: theme.spacing(1.5),
fontWeight: 'bold',
}),
boxContent: { display: 'flex', width: '100%' },
tabs: {},
searchButton: {
marginTop: 'auto',
marginBottom: 'auto',
marginLeft: 1,
marginRight: 1,
},
runButtonContainer: {
marginTop: 'auto',
marginBottom: 'auto',
marginRight: '10%',
marginTop: '4px',
marginLeft: 'auto',
flexShrink: 0,
},
boxContent: { display: 'flex', width: '100%' },
};

const STUDY_VIEWS = [
Expand Down Expand Up @@ -161,11 +183,15 @@ const CustomSuffixRenderer = ({ props, element }) => {
</IconButton>
</>
);
} else {
return (
<TagRenderer
styles={equipmentStyles}
props={props}
element={element}
/>
);
}

return (
<TagRenderer styles={equipmentStyles} props={props} element={element} />
);
};

const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {
Expand All @@ -191,6 +217,8 @@ const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {

const currentNode = useSelector((state) => state.currentTreeNode);

const [isDialogSearchOpen, setDialogSearchOpen] = useState(false);

const [isParametersOpen, setParametersOpen] = useState(false);

const { openDiagramView } = useDiagram();
Expand Down Expand Up @@ -230,26 +258,39 @@ const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {
}
}, [user]);

useEffect(() => {
if (user) {
const openSearch = (e) => {
if (
e.ctrlKey &&
e.shiftKey &&
(e.key === 'F' || e.key === 'f')
) {
e.preventDefault();
setDialogSearchOpen(true);
}
};
document.addEventListener('keydown', openSearch);
return () => document.removeEventListener('keydown', openSearch);
}
}, [user]);

function getDisableReason() {
if (studyDisplayMode === STUDY_DISPLAY_MODE.TREE) {
return intl.formatMessage({
id: 'UnsupportedView',
});
}

if (!isNodeBuilt(currentNode)) {
} else if (!isNodeBuilt(currentNode)) {
return intl.formatMessage({
id: 'InvalidNode',
});
}

if (studyIndexationStatus !== STUDY_INDEXATION_STATUS.INDEXED) {
} else if (studyIndexationStatus !== STUDY_INDEXATION_STATUS.INDEXED) {
return intl.formatMessage({
id: 'waitingStudyIndexation',
});
} else {
return '';
}

return '';
}

return (
Expand Down Expand Up @@ -311,48 +352,25 @@ const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {
theme={themeLocal}
onEquipmentLabellingClick={handleChangeUseName}
equipmentLabelling={useNameLocal}
withElementsSearch={true}
searchingLabel={intl.formatMessage({
id: 'equipment_search/label',
})}
onSearchTermChange={searchMatchingEquipments}
onSelectionChange={showVoltageLevelDiagram}
elementsFound={equipmentsFound}
renderElement={(props) => (
<EquipmentItem
styles={equipmentStyles}
{...props}
key={'ei' + props.element.key}
suffixRenderer={CustomSuffixRenderer}
/>
)}
onLanguageClick={handleChangeLanguage}
language={languageLocal}
searchTermDisabled={getDisableReason() !== ''}
searchTermDisableReason={getDisableReason()}
>
{/* Add current Node name between Logo and Tabs */}
<Box
width="15%"
display="flex"
alignItems="center"
justifyContent="center"
borderColor={'#123456'}
>
{/* TODO : temporary fix (remove user and manage disconnection in a hook?) */}
{currentNode && user && (
{user && currentNode && (
<Box sx={styles.currentNodeBox}>
{/* TODO : temporary fix (remove user and manage disconnection in a hook?) */}
<OverflowableText
sx={styles.label}
sx={styles.currentNodeLabel}
text={
currentNode?.data?.label === 'Root'
? intl.formatMessage({ id: 'root' })
: currentNode?.data?.label
}
/>
)}
</Box>
<Box sx={styles.boxContent}>
{studyUuid && (
</Box>
)}
{user && studyUuid && (
<Box sx={styles.boxContent}>
<Tabs
value={tabIndex}
variant="scrollable"
Expand Down Expand Up @@ -382,8 +400,37 @@ const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {
return <Tab key={tabName} label={label} />;
})}
</Tabs>
)}
{studyUuid && (
<Box sx={styles.searchButton}>
<Tooltip
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tooltip was not here before.
Maybe you should ask a PO to confirm ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirmed with a PO, it's OK.

title={
<FormattedMessage id="equipment_search/label" />
}
>
<Button
color="inherit"
size="large"
onClick={() => setDialogSearchOpen(true)}
>
<Search />
</Button>
</Tooltip>
</Box>
<Box sx={styles.searchButton}>
<Tooltip
title={
<FormattedMessage id="equipment_search/label" />
}
>
<IconButton
color="inherit"
aria-label="search"
size="large"
onClick={() => setDialogSearchOpen(true)}
>
<Search />
</IconButton>
</Tooltip>
</Box>
Copy link
Contributor

@lilian-houdelet lilian-houdelet Dec 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any difference between the two search buttons ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oups, I forget to remove it!

Yes they don't have the same apparence (mainly one is sqaure retangle and the other is round.

<Box sx={styles.runButtonContainer}>
<RunButtonContainer
studyUuid={studyUuid}
Expand All @@ -394,16 +441,41 @@ const AppTopBar = ({ user, tabIndex, onChangeTab, userManager }) => {
}
/>
</Box>
)}
</Box>
</Box>
)}
</TopBar>

{studyUuid && (
<Parameters
isParametersOpen={isParametersOpen}
hideParameters={() => setParametersOpen(false)}
user={user}
/>
<>
<ElementSearchDialog
open={isDialogSearchOpen}
onClose={() => setDialogSearchOpen(false)}
searchingLabel={intl.formatMessage({
id: 'equipment_search/label',
})}
onSearchTermChange={searchMatchingEquipments}
onSelectionChange={(element) => {
setDialogSearchOpen(false);
showVoltageLevelDiagram(element);
}}
elementsFound={equipmentsFound}
renderElement={(props) => (
<EquipmentItem
styles={equipmentStyles}
{...props}
key={'ei-' + props.element.key}
suffixRenderer={CustomSuffixRenderer}
/>
)}
searchTermDisabled={getDisableReason() !== ''}
searchTermDisableReason={getDisableReason()}
/>
<Parameters
isParametersOpen={isParametersOpen}
hideParameters={() => setParametersOpen(false)}
user={user}
/>
</>
)}
</>
);
Expand Down