Skip to content

Commit

Permalink
typescript migration of components/diagrams (#2273)
Browse files Browse the repository at this point in the history
* typescript migration of components/diagrams

---------

Signed-off-by: jamal-khey <myjamal89@gmail.com>
Co-authored-by: souissimai <133104748+souissimai@users.noreply.github.com>
  • Loading branch information
jamal-khey and souissimai authored Oct 14, 2024
1 parent a7c02e5 commit 00198dc
Show file tree
Hide file tree
Showing 17 changed files with 742 additions and 583 deletions.
24 changes: 21 additions & 3 deletions src/components/diagrams/diagram-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { FEEDER_TYPES, FeederTypes } from 'components/utils/feederType';
import { EQUIPMENT_TYPES } from 'components/utils/equipment-types';
import { Theme } from '@mui/material';
import { AppDispatch } from '../../redux/store';
import { SLDMetadata } from '@powsybl/diagram-viewer';
import { UUID } from 'crypto';

export const LOADING_WIDTH = 300;
export const LOADING_HEIGHT = 300;
Expand Down Expand Up @@ -138,7 +140,7 @@ export enum DiagramType {
}

// be careful when using this method because there are treatments made on purpose
export function getEquipmentTypeFromFeederType(feederType: FeederTypes) {
export function getEquipmentTypeFromFeederType(feederType: FeederTypes | null): EQUIPMENT_TYPES | null {
switch (feederType) {
case FEEDER_TYPES.LINE:
return EQUIPMENT_TYPES.LINE;
Expand Down Expand Up @@ -260,9 +262,25 @@ export const useDiagram = () => {
};
};

export const NoSvg = {
export interface Svg {
svg: string | null;
metadata: SLDMetadata | null;
additionalMetadata:
| (SLDMetadata & {
country: string;
substationId?: string;
voltageLevels: { name: string; substationId: UUID }[];
nbVoltageLevels?: number;
})
| null;
error?: string | null;
svgUrl?: string | null;
}

export const NoSvg: Svg = {
svg: null,
metadata: null,
additionalMetadata: null,
error: null,
error: undefined,
svgUrl: undefined,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,104 +12,112 @@ import RemoveCircleIcon from '@mui/icons-material/RemoveCircle';
import IconButton from '@mui/material/IconButton';
import FullscreenExitIcon from '@mui/icons-material/FullscreenExit';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import PropTypes from 'prop-types';
import { Theme } from '@mui/material';

const styles = {
counterText: (theme) => ({
counterText: (theme: Theme) => ({
bottom: theme.spacing(4),
left: theme.spacing(1),
position: 'absolute',
}),
incrementCounterIcon: (theme) => ({
incrementCounterIcon: (theme: Theme) => ({
padding: 0,
bottom: theme.spacing(1),
left: theme.spacing(5.5),
position: 'absolute',
cursor: 'pointer',
}),
decrementCounterIcon: (theme) => ({
decrementCounterIcon: (theme: Theme) => ({
padding: 0,
bottom: theme.spacing(1),
left: theme.spacing(2),
position: 'absolute',
cursor: 'pointer',
}),
fullScreenIcon: (theme) => ({
fullScreenIcon: (theme: Theme) => ({
bottom: theme.spacing(1),
right: theme.spacing(2),
position: 'absolute',
cursor: 'pointer',
}),
};

const DiagramFooter = (props) => {
const { onStopFullScreen, onStartFullScreen, onIncrementCounter, onDecrementCounter } = props;
interface DiagramFooterProps {
showCounterControls?: boolean;
showCounterValue?: boolean;
showFullscreenControl?: boolean;
counterText: string;
counterValue: number;
fullScreenActive?: boolean;
decrementCounterDisabled?: boolean;
incrementCounterDisabled?: boolean;
onIncrementCounter?: () => void;
onDecrementCounter?: () => void;
onStopFullScreen?: () => void;
onStartFullScreen?: () => void;
}

const defaultProps: DiagramFooterProps = {
showCounterControls: false,
showCounterValue: true,
showFullscreenControl: false,
counterText: '',
counterValue: 0,
fullScreenActive: false,
decrementCounterDisabled: true,
incrementCounterDisabled: false,
};

const DiagramFooter: React.FC<DiagramFooterProps> = ({
showCounterControls = defaultProps.showCounterControls,
showCounterValue = defaultProps.showCounterValue,
showFullscreenControl = defaultProps.showFullscreenControl,
counterText = defaultProps.counterText,
counterValue = defaultProps.counterValue,
fullScreenActive = defaultProps.fullScreenActive,
decrementCounterDisabled = defaultProps.decrementCounterDisabled,
incrementCounterDisabled = defaultProps.incrementCounterDisabled,
onIncrementCounter,
onDecrementCounter,
onStopFullScreen,
onStartFullScreen,
}) => {
const handleStopFullScreen = useCallback(() => onStopFullScreen && onStopFullScreen(), [onStopFullScreen]);
const handleStartFullScreen = useCallback(() => onStartFullScreen && onStartFullScreen(), [onStartFullScreen]);
const handleIncrementCounter = useCallback(() => onIncrementCounter && onIncrementCounter(), [onIncrementCounter]);
const handleDecrementCounter = useCallback(() => onDecrementCounter && onDecrementCounter(), [onDecrementCounter]);

return (
<div style={{ display: 'flex' }}>
{props.showCounterControls && (
{showCounterControls && (
<>
{props.showCounterValue && (
<Typography sx={styles.counterText}>{props.counterText + props.counterValue}</Typography>
)}
{showCounterValue && <Typography sx={styles.counterText}>{counterText + counterValue}</Typography>}
<IconButton
onClick={handleIncrementCounter}
disabled={props.incrementCounterDisabled}
disabled={incrementCounterDisabled}
sx={styles.incrementCounterIcon}
>
<AddCircleIcon />
</IconButton>
<IconButton
onClick={handleDecrementCounter}
disabled={props.decrementCounterDisabled}
disabled={decrementCounterDisabled}
sx={styles.decrementCounterIcon}
>
<RemoveCircleIcon />
</IconButton>
</>
)}
{props.showFullscreenControl && (
{showFullscreenControl && (
<>
{props.fullScreenActive && (
{fullScreenActive && (
<FullscreenExitIcon onClick={handleStopFullScreen} sx={styles.fullScreenIcon} />
)}
{!props.fullScreenActive && (
<FullscreenIcon onClick={handleStartFullScreen} sx={styles.fullScreenIcon} />
)}
{!fullScreenActive && <FullscreenIcon onClick={handleStartFullScreen} sx={styles.fullScreenIcon} />}
</>
)}
</div>
);
};

DiagramFooter.defaultProps = {
showCounterControls: false,
showCounterValue: true,
showFullscreenControl: false,
counterText: '',
counterValue: 0,
fullscreenActive: false,
decrementCounterDisabled: true,
incrementCounterDisabled: false,
};

DiagramFooter.propTypes = {
showCounterControls: PropTypes.bool,
showCounterValue: PropTypes.bool,
counterText: PropTypes.string,
counterValue: PropTypes.number,
onIncrementCounter: PropTypes.func,
onDecrementCounter: PropTypes.func,
showFullscreenControl: PropTypes.bool,
fullScreenActive: PropTypes.any,
onStopFullScreen: PropTypes.func,
onStartFullScreen: PropTypes.func,
decrementCounterDisabled: PropTypes.bool,
incrementCounterDisabled: PropTypes.bool,
};

export default DiagramFooter;
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import MinimizeIcon from '@mui/icons-material/Minimize';
import PushPinIcon from '@mui/icons-material/PushPin';
import PushPinOutlinedIcon from '@mui/icons-material/PushPinOutlined';
import CloseIcon from '@mui/icons-material/Close';
import PropTypes from 'prop-types';
import { stopDiagramBlink } from '../../redux/actions';
import { mergeSx } from '../utils/functions';
import { Theme } from '@mui/material';
import { AppState } from 'redux/reducer';

const BLINK_LENGTH_MS = 1800;

const styles = {
header: (theme) => ({
header: (theme: Theme) => ({
// prevent header from making the window wider, prevent bugs when displaying a lot of different voltage levels
position: 'absolute',
width: '100%',
Expand All @@ -34,20 +35,20 @@ const styles = {
borderBottom: 'solid 1px',
borderBottomColor: theme.palette.mode === 'light' ? theme.palette.action.selected : 'transparent',
}),
actionIcon: (theme) => ({
actionIcon: (theme: Theme) => ({
padding: 0,
borderRight: theme.spacing(1),
}),
pinRotate: (theme) => ({
pinRotate: (theme: Theme) => ({
padding: 0,
borderRight: theme.spacing(1),
transform: 'rotate(45deg)',
}),
close: (theme) => ({
close: (theme: Theme) => ({
padding: 0,
borderRight: theme.spacing(1),
}),
blink: (theme) => ({
blink: (theme: Theme) => ({
animation: 'diagramHeaderBlinkAnimation ' + BLINK_LENGTH_MS + 'ms',
'@keyframes diagramHeaderBlinkAnimation': {
// This adds a global css rule, so we keep the rule's name specific.
Expand All @@ -62,10 +63,33 @@ const styles = {
}),
};

const DiagramHeader = (props) => {
interface DiagramHeaderProps {
diagramTitle?: string;
showMinimizeControl?: boolean;
onMinimize?: () => void;
showTogglePinControl?: boolean;
onTogglePin?: () => void;
pinned?: boolean;
showCloseControl?: boolean;
onClose?: () => void;
diagramId?: string;
svgType?: string;
}

const DiagramHeader: React.FC<DiagramHeaderProps> = ({
diagramTitle,
showMinimizeControl = false,
onMinimize,
showTogglePinControl = false,
onTogglePin,
pinned,
showCloseControl = false,
onClose,
diagramId,
svgType,
}) => {
const dispatch = useDispatch();

const { onMinimize, onTogglePin, onClose } = props;
const handleMinimize = useCallback(() => onMinimize && onMinimize(), [onMinimize]);
const handleTogglePin = useCallback(() => onTogglePin && onTogglePin(), [onTogglePin]);
const handleClose = useCallback(() => onClose && onClose(), [onClose]);
Expand All @@ -76,9 +100,8 @@ const DiagramHeader = (props) => {

const [blinking, setBlinking] = useState(false);
const needsToBlink = useSelector(
(state) =>
state.diagramStates.find((diagram) => diagram.svgType === props?.svgType && diagram.id === props?.diagramId)
?.needsToBlink
(state: AppState) =>
state.diagramStates.find((diagram) => diagram.svgType === svgType && diagram.id === diagramId)?.needsToBlink
);

useEffect(() => {
Expand All @@ -99,25 +122,25 @@ const DiagramHeader = (props) => {

return (
<Box sx={mergeSx(styles.header, blinking && styles.blink)}>
<OverflowableText sx={{ flexGrow: '1' }} text={props.diagramTitle} />
<OverflowableText sx={{ flexGrow: '1' }} text={diagramTitle} />
<Box>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
}}
>
{props.showMinimizeControl && (
{showMinimizeControl && (
<IconButton sx={styles.actionIcon} onClick={handleMinimize}>
<MinimizeIcon />
</IconButton>
)}
{props.showTogglePinControl && (
<IconButton sx={props.pinned ? styles.actionIcon : styles.pinRotate} onClick={handleTogglePin}>
{props.pinned ? <PushPinIcon /> : <PushPinOutlinedIcon />}
{showTogglePinControl && (
<IconButton sx={pinned ? styles.actionIcon : styles.pinRotate} onClick={handleTogglePin}>
{pinned ? <PushPinIcon /> : <PushPinOutlinedIcon />}
</IconButton>
)}
{props.showCloseControl && (
{showCloseControl && (
<IconButton sx={styles.close} onClick={handleClose}>
<CloseIcon />
</IconButton>
Expand All @@ -128,23 +151,4 @@ const DiagramHeader = (props) => {
);
};

DiagramHeader.defaultProps = {
showMinimizeControl: false,
showTogglePinControl: false,
showCloseControl: false,
};

DiagramHeader.propTypes = {
diagramTitle: PropTypes.string,
showMinimizeControl: PropTypes.bool,
onMinimize: PropTypes.func,
showTogglePinControl: PropTypes.bool,
onTogglePin: PropTypes.func,
pinned: PropTypes.bool,
showCloseControl: PropTypes.bool,
onClose: PropTypes.func,
diagramId: PropTypes.string,
svgType: PropTypes.string.isRequired,
};

export default DiagramHeader;
Loading

0 comments on commit 00198dc

Please sign in to comment.