mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
refactor: styles batch 3 (#2821)
This commit is contained in:
parent
be1762d33f
commit
ddb9d11039
@ -137,7 +137,7 @@ const ProjectRoleForm: FC<IProjectRoleForm> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<Button onClick={onCancel} sx={{ ml: 2 }}>
|
<Button onClick={onCancel} sx={{ marginLeft: 2 }}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -264,7 +264,10 @@ export const ChangeRequestOverview: FC = () => {
|
|||||||
}
|
}
|
||||||
show={
|
show={
|
||||||
<Button
|
<Button
|
||||||
sx={{ ml: 2 }}
|
sx={{
|
||||||
|
marginLeft: theme =>
|
||||||
|
theme.spacing(2),
|
||||||
|
}}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
>
|
>
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import React, { useEffect, useState, useRef, FC } from 'react';
|
import React, { CSSProperties, useEffect, useState, useRef, FC } from 'react';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
interface IAnimateOnMountProps {
|
interface IAnimateOnMountProps {
|
||||||
mounted: boolean;
|
mounted: boolean;
|
||||||
enter: string;
|
enter: CSSProperties;
|
||||||
start: string;
|
start: CSSProperties;
|
||||||
leave?: string;
|
leave?: CSSProperties;
|
||||||
container?: string;
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
onStart?: () => void;
|
onStart?: () => void;
|
||||||
onEnd?: () => void;
|
onEnd?: () => void;
|
||||||
}
|
}
|
||||||
@ -17,14 +15,12 @@ const AnimateOnMount: FC<IAnimateOnMountProps> = ({
|
|||||||
enter,
|
enter,
|
||||||
start,
|
start,
|
||||||
leave,
|
leave,
|
||||||
container,
|
|
||||||
children,
|
children,
|
||||||
style,
|
|
||||||
onStart,
|
onStart,
|
||||||
onEnd,
|
onEnd,
|
||||||
}) => {
|
}) => {
|
||||||
const [show, setShow] = useState(mounted);
|
const [show, setShow] = useState(mounted);
|
||||||
const [styles, setStyles] = useState('');
|
const [styles, setStyles] = useState<CSSProperties>({});
|
||||||
const mountedRef = useRef<null | boolean>(null);
|
const mountedRef = useRef<null | boolean>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -39,7 +35,7 @@ const AnimateOnMount: FC<IAnimateOnMountProps> = ({
|
|||||||
if (!leave) {
|
if (!leave) {
|
||||||
setShow(false);
|
setShow(false);
|
||||||
}
|
}
|
||||||
setStyles(leave || '');
|
setStyles(leave || {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [mounted, enter, onStart, leave]);
|
}, [mounted, enter, onStart, leave]);
|
||||||
@ -56,11 +52,8 @@ const AnimateOnMount: FC<IAnimateOnMountProps> = ({
|
|||||||
condition={show}
|
condition={show}
|
||||||
show={
|
show={
|
||||||
<div
|
<div
|
||||||
className={`${start} ${styles} ${
|
|
||||||
container ? container : ''
|
|
||||||
}`}
|
|
||||||
onTransitionEnd={onTransitionEnd}
|
onTransitionEnd={onTransitionEnd}
|
||||||
style={{ ...style }}
|
style={{ ...start, ...styles }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
flexGrow: 1,
|
|
||||||
alignItems: 'center',
|
|
||||||
position: 'relative',
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
maxWidth: '400px',
|
|
||||||
[theme.breakpoints.down('md')]: {
|
|
||||||
marginTop: theme.spacing(1),
|
|
||||||
maxWidth: '100%',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
border: `1px solid ${theme.palette.grey[500]}`,
|
|
||||||
borderRadius: theme.shape.borderRadiusExtraLarge,
|
|
||||||
padding: '3px 5px 3px 12px',
|
|
||||||
width: '100%',
|
|
||||||
zIndex: 3,
|
|
||||||
'&.search-container:focus-within': {
|
|
||||||
borderColor: theme.palette.primary.light,
|
|
||||||
boxShadow: theme.boxShadows.main,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
searchIcon: {
|
|
||||||
marginRight: 8,
|
|
||||||
color: theme.palette.inactiveIcon,
|
|
||||||
},
|
|
||||||
clearContainer: {
|
|
||||||
width: '30px',
|
|
||||||
'& > button': {
|
|
||||||
padding: '7px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
clearIcon: {
|
|
||||||
color: theme.palette.grey[700],
|
|
||||||
fontSize: '18px',
|
|
||||||
},
|
|
||||||
inputRoot: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,13 +1,11 @@
|
|||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { IconButton, InputBase, Tooltip } from '@mui/material';
|
import { useAsyncDebounce } from 'react-table';
|
||||||
|
import { Box, IconButton, InputBase, styled, Tooltip } from '@mui/material';
|
||||||
import { Search as SearchIcon, Close } from '@mui/icons-material';
|
import { Search as SearchIcon, Close } from '@mui/icons-material';
|
||||||
import classnames from 'classnames';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './Search.styles';
|
|
||||||
import { SearchSuggestions } from './SearchSuggestions/SearchSuggestions';
|
import { SearchSuggestions } from './SearchSuggestions/SearchSuggestions';
|
||||||
import { IGetSearchContextOutput } from 'hooks/useSearch';
|
import { IGetSearchContextOutput } from 'hooks/useSearch';
|
||||||
import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut';
|
import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut';
|
||||||
import { useAsyncDebounce } from 'react-table';
|
|
||||||
|
|
||||||
interface ISearchProps {
|
interface ISearchProps {
|
||||||
initialValue?: string;
|
initialValue?: string;
|
||||||
@ -21,6 +19,43 @@ interface ISearchProps {
|
|||||||
debounceTime?: number;
|
debounceTime?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexGrow: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
maxWidth: '400px',
|
||||||
|
[theme.breakpoints.down('md')]: {
|
||||||
|
marginTop: theme.spacing(1),
|
||||||
|
maxWidth: '100%',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledSearch = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
border: `1px solid ${theme.palette.neutral.border}`,
|
||||||
|
borderRadius: theme.shape.borderRadiusExtraLarge,
|
||||||
|
padding: '3px 5px 3px 12px',
|
||||||
|
width: '100%',
|
||||||
|
zIndex: 3,
|
||||||
|
'&:focus-within': {
|
||||||
|
borderColor: theme.palette.primary.light,
|
||||||
|
boxShadow: theme.boxShadows.main,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledInputBase = styled(InputBase)(({ theme }) => ({
|
||||||
|
width: '100%',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledClose = styled(Close)(({ theme }) => ({
|
||||||
|
color: theme.palette.neutral.main,
|
||||||
|
fontSize: theme.typography.body1.fontSize,
|
||||||
|
}));
|
||||||
|
|
||||||
export const Search = ({
|
export const Search = ({
|
||||||
initialValue = '',
|
initialValue = '',
|
||||||
onChange,
|
onChange,
|
||||||
@ -33,7 +68,6 @@ export const Search = ({
|
|||||||
debounceTime = 200,
|
debounceTime = 200,
|
||||||
}: ISearchProps) => {
|
}: ISearchProps) => {
|
||||||
const ref = useRef<HTMLInputElement>();
|
const ref = useRef<HTMLInputElement>();
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const [showSuggestions, setShowSuggestions] = useState(false);
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||||
|
|
||||||
const [value, setValue] = useState(initialValue);
|
const [value, setValue] = useState(initialValue);
|
||||||
@ -62,23 +96,17 @@ export const Search = ({
|
|||||||
const placeholder = `${customPlaceholder ?? 'Search'} (${hotkey})`;
|
const placeholder = `${customPlaceholder ?? 'Search'} (${hotkey})`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} style={containerStyles}>
|
<StyledContainer style={containerStyles}>
|
||||||
<div
|
<StyledSearch className={className}>
|
||||||
className={classnames(
|
|
||||||
styles.search,
|
|
||||||
className,
|
|
||||||
'search-container'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<SearchIcon
|
<SearchIcon
|
||||||
className={classnames(styles.searchIcon, 'search-icon')}
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
color: theme => theme.palette.inactiveIcon,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<InputBase
|
<StyledInputBase
|
||||||
inputRef={ref}
|
inputRef={ref}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
classes={{
|
|
||||||
root: classnames(styles.inputRoot, 'input-container'),
|
|
||||||
}}
|
|
||||||
inputProps={{ 'aria-label': placeholder }}
|
inputProps={{ 'aria-label': placeholder }}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={e => onSearchChange(e.target.value)}
|
onChange={e => onSearchChange(e.target.value)}
|
||||||
@ -86,12 +114,7 @@ export const Search = ({
|
|||||||
onBlur={() => setShowSuggestions(false)}
|
onBlur={() => setShowSuggestions(false)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
<div
|
<Box sx={{ width: theme => theme.spacing(4) }}>
|
||||||
className={classnames(
|
|
||||||
styles.clearContainer,
|
|
||||||
'clear-container'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(value)}
|
condition={Boolean(value)}
|
||||||
show={
|
show={
|
||||||
@ -102,20 +125,21 @@ export const Search = ({
|
|||||||
onSearchChange('');
|
onSearchChange('');
|
||||||
ref.current?.focus();
|
ref.current?.focus();
|
||||||
}}
|
}}
|
||||||
|
sx={{ padding: theme => theme.spacing(1) }}
|
||||||
>
|
>
|
||||||
<Close className={styles.clearIcon} />
|
<StyledClose />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Box>
|
||||||
</div>
|
</StyledSearch>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(hasFilters) && showSuggestions}
|
condition={Boolean(hasFilters) && showSuggestions}
|
||||||
show={
|
show={
|
||||||
<SearchSuggestions getSearchContext={getSearchContext!} />
|
<SearchSuggestions getSearchContext={getSearchContext!} />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
import React, { useState, VFC } from 'react';
|
|
||||||
import classnames from 'classnames';
|
|
||||||
import { debounce } from 'debounce';
|
|
||||||
import { InputBase, Chip } from '@mui/material';
|
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
|
||||||
import { useStyles } from 'component/common/SearchField/styles';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
|
|
||||||
interface ISearchFieldProps {
|
|
||||||
updateValue: (value: string) => void;
|
|
||||||
initialValue?: string;
|
|
||||||
className?: string;
|
|
||||||
showValueChip?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use `Search` instead.
|
|
||||||
*/
|
|
||||||
export const SearchField: VFC<ISearchFieldProps> = ({
|
|
||||||
updateValue,
|
|
||||||
initialValue = '',
|
|
||||||
className = '',
|
|
||||||
showValueChip,
|
|
||||||
}) => {
|
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const [localValue, setLocalValue] = useState(initialValue);
|
|
||||||
const debounceUpdateValue = debounce(updateValue, 500);
|
|
||||||
|
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
event.preventDefault();
|
|
||||||
const value = event.target.value || '';
|
|
||||||
setLocalValue(value);
|
|
||||||
debounceUpdateValue(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKeyPress = (event: React.KeyboardEvent) => {
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
updateValue(localValue);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateNow = () => {
|
|
||||||
updateValue(localValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDelete = () => {
|
|
||||||
setLocalValue('');
|
|
||||||
updateValue('');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form className={styles.container} role="search">
|
|
||||||
<div className={classnames(styles.search, className)}>
|
|
||||||
<SearchIcon className={styles.searchIcon} />
|
|
||||||
<InputBase
|
|
||||||
placeholder="Search..."
|
|
||||||
classes={{ root: styles.inputRoot }}
|
|
||||||
inputProps={{ 'aria-label': 'search' }}
|
|
||||||
value={localValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
onBlur={updateNow}
|
|
||||||
onKeyPress={handleKeyPress}
|
|
||||||
type="search"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(showValueChip && localValue)}
|
|
||||||
show={
|
|
||||||
<Chip
|
|
||||||
label={localValue}
|
|
||||||
onDelete={onDelete}
|
|
||||||
title="Clear search query"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,28 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
gap: '1rem',
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
borderRadius: theme.shape.borderRadiusExtraLarge,
|
|
||||||
padding: '0.25rem 0.5rem',
|
|
||||||
maxWidth: '450px',
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
searchIcon: {
|
|
||||||
marginRight: 8,
|
|
||||||
color: theme.palette.inactiveIcon,
|
|
||||||
},
|
|
||||||
inputRoot: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,48 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
width: '100%',
|
|
||||||
padding: theme.spacing(2, 3),
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
fontSize: theme.fontSizes.smallBody,
|
|
||||||
border: `1px solid ${theme.palette.dividerAlternative}`,
|
|
||||||
position: 'relative',
|
|
||||||
borderRadius: '5px',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
textDecoration: 'none',
|
|
||||||
marginLeft: theme.spacing(1),
|
|
||||||
'&:hover': {
|
|
||||||
textDecoration: 'underline',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
accordion: {
|
|
||||||
border: `1px solid ${theme.palette.dividerAlternative}`,
|
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
boxShadow: 'none',
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
accordionRoot: {
|
|
||||||
transition: 'all 0.1s ease',
|
|
||||||
'&:before': {
|
|
||||||
opacity: '0 !important',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
accordionExpanded: {
|
|
||||||
backgroundColor: theme.palette.neutral.light,
|
|
||||||
},
|
|
||||||
previewButton: {
|
|
||||||
paddingTop: 0,
|
|
||||||
paddingBottom: 0,
|
|
||||||
marginLeft: 'auto',
|
|
||||||
fontSize: theme.fontSizes.smallBody,
|
|
||||||
},
|
|
||||||
summary: {
|
|
||||||
fontSize: theme.fontSizes.smallBody,
|
|
||||||
margin: theme.spacing(0.5, 0),
|
|
||||||
},
|
|
||||||
}));
|
|
@ -7,11 +7,11 @@ import {
|
|||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
Button,
|
Button,
|
||||||
|
styled,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { ConstraintAccordionList } from '../ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
import { ConstraintAccordionList } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
||||||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './SegmentItem.styles';
|
|
||||||
|
|
||||||
interface ISegmentItemProps {
|
interface ISegmentItemProps {
|
||||||
segment: Partial<ISegment>;
|
segment: Partial<ISegment>;
|
||||||
@ -20,36 +20,52 @@ interface ISegmentItemProps {
|
|||||||
headerContent?: JSX.Element;
|
headerContent?: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||||
|
border: `1px solid ${theme.palette.dividerAlternative}`,
|
||||||
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
boxShadow: 'none',
|
||||||
|
margin: 0,
|
||||||
|
transition: 'all 0.1s ease',
|
||||||
|
'&:before': {
|
||||||
|
opacity: '0 !important',
|
||||||
|
},
|
||||||
|
'&.Mui-expanded': { backgroundColor: theme.palette.neutral.light },
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||||
|
margin: theme.spacing(0, 0.5),
|
||||||
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
'.MuiAccordionSummary-content': {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledLink = styled(Link)(({ theme }) => ({
|
||||||
|
textDecoration: 'none',
|
||||||
|
marginLeft: theme.spacing(1),
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const SegmentItem: VFC<ISegmentItemProps> = ({
|
export const SegmentItem: VFC<ISegmentItemProps> = ({
|
||||||
segment,
|
segment,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
headerContent,
|
headerContent,
|
||||||
constraintList,
|
constraintList,
|
||||||
}) => {
|
}) => {
|
||||||
const { classes } = useStyles();
|
|
||||||
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion
|
<StyledAccordion expanded={isOpen}>
|
||||||
expanded={isOpen}
|
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
||||||
className={classes.accordion}
|
|
||||||
classes={{
|
|
||||||
root: classes.accordionRoot,
|
|
||||||
expanded: classes.accordionExpanded,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AccordionSummary
|
|
||||||
id={`segment-accordion-${segment.id}`}
|
|
||||||
className={classes.summary}
|
|
||||||
>
|
|
||||||
<DonutLarge color="secondary" sx={{ mr: 1 }} />
|
<DonutLarge color="secondary" sx={{ mr: 1 }} />
|
||||||
Segment:
|
<span>Segment:</span>
|
||||||
<Link
|
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||||
to={`/segments/edit/${segment.id}`}
|
|
||||||
className={classes.link}
|
|
||||||
>
|
|
||||||
{segment.name}
|
{segment.name}
|
||||||
</Link>
|
</StyledLink>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(headerContent)}
|
condition={Boolean(headerContent)}
|
||||||
show={headerContent}
|
show={headerContent}
|
||||||
@ -61,13 +77,18 @@ export const SegmentItem: VFC<ISegmentItemProps> = ({
|
|||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={() => setIsOpen(value => !value)}
|
onClick={() => setIsOpen(value => !value)}
|
||||||
className={classes.previewButton}
|
sx={{
|
||||||
|
my: 0,
|
||||||
|
ml: 'auto',
|
||||||
|
fontSize: theme =>
|
||||||
|
theme.typography.body2.fontSize,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{isOpen ? 'Close preview' : 'Preview'}
|
{isOpen ? 'Close preview' : 'Preview'}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</AccordionSummary>
|
</StyledAccordionSummary>
|
||||||
<AccordionDetails sx={{ pt: 0 }}>
|
<AccordionDetails sx={{ pt: 0 }}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(constraintList)}
|
condition={Boolean(constraintList)}
|
||||||
@ -90,6 +111,6 @@ export const SegmentItem: VFC<ISegmentItemProps> = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</StyledAccordion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
link: {
|
|
||||||
position: 'fixed',
|
|
||||||
overflow: 'hidden',
|
|
||||||
zIndex: 1000,
|
|
||||||
top: '1.125rem',
|
|
||||||
left: '1.125rem',
|
|
||||||
padding: '0.5rem 1rem',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
textDecoration: 'none',
|
|
||||||
background: theme.palette.primary.dark,
|
|
||||||
color: theme.palette.primary.contrastText,
|
|
||||||
borderRadius: theme.shape.borderRadius,
|
|
||||||
fontSize: theme.fontSizes.smallBody,
|
|
||||||
|
|
||||||
[theme.breakpoints.down(960)]: {
|
|
||||||
top: '0.8rem',
|
|
||||||
left: '0.8rem',
|
|
||||||
},
|
|
||||||
|
|
||||||
'&:not(:focus):not(:active)': {
|
|
||||||
clip: 'rect(0 0 0 0)',
|
|
||||||
clipPath: 'inset(50%)',
|
|
||||||
zIndex: -1,
|
|
||||||
width: 1,
|
|
||||||
height: 1,
|
|
||||||
margin: -1,
|
|
||||||
padding: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,12 +0,0 @@
|
|||||||
import { SKIP_NAV_TARGET_ID } from 'component/common/SkipNav/SkipNavTarget';
|
|
||||||
import { useStyles } from 'component/common/SkipNav/SkipNavLink.styles';
|
|
||||||
|
|
||||||
export const SkipNavLink = () => {
|
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a href={`#${SKIP_NAV_TARGET_ID}`} className={styles.link}>
|
|
||||||
Skip to content <span aria-hidden>↓</span>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
};
|
|
38
frontend/src/component/common/SkipNavLink/SkipNavLink.tsx
Normal file
38
frontend/src/component/common/SkipNavLink/SkipNavLink.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { SKIP_NAV_TARGET_ID } from 'component/common/SkipNavLink/SkipNavTarget';
|
||||||
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
|
const StyledLink = styled('a')(({ theme }) => ({
|
||||||
|
position: 'fixed',
|
||||||
|
overflow: 'hidden',
|
||||||
|
zIndex: 1000,
|
||||||
|
top: theme.spacing(2.25),
|
||||||
|
left: theme.spacing(2.25),
|
||||||
|
padding: theme.spacing(1, 2),
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textDecoration: 'none',
|
||||||
|
background: theme.palette.primary.dark,
|
||||||
|
color: theme.palette.primary.contrastText,
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
fontSize: theme.fontSizes.smallBody,
|
||||||
|
|
||||||
|
[theme.breakpoints.down(960)]: {
|
||||||
|
top: '0.8rem',
|
||||||
|
left: '0.8rem',
|
||||||
|
},
|
||||||
|
|
||||||
|
'&:not(:focus):not(:active)': {
|
||||||
|
clip: 'rect(0 0 0 0)',
|
||||||
|
clipPath: 'inset(50%)',
|
||||||
|
zIndex: -1,
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
margin: -1,
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const SkipNavLink = () => (
|
||||||
|
<StyledLink href={`#${SKIP_NAV_TARGET_ID}`}>
|
||||||
|
Skip to content <span aria-hidden>↓</span>
|
||||||
|
</StyledLink>
|
||||||
|
);
|
@ -1,7 +1,11 @@
|
|||||||
import { Typography, Button, useTheme, useMediaQuery } from '@mui/material';
|
import { Typography, Button, useTheme, useMediaQuery } from '@mui/material';
|
||||||
import EventDiff from 'component/events/EventDiff/EventDiff';
|
import EventDiff from 'component/events/EventDiff/EventDiff';
|
||||||
import { useThemeStyles } from 'themes/themeStyles';
|
import {
|
||||||
|
fadeInBottomEnter,
|
||||||
|
fadeInBottomStartWithoutFixed,
|
||||||
|
} from 'themes/themeStyles';
|
||||||
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
|
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
interface IStaleDataNotification {
|
interface IStaleDataNotification {
|
||||||
refresh: () => void;
|
refresh: () => void;
|
||||||
@ -18,12 +22,12 @@ export const StaleDataNotification = ({
|
|||||||
data,
|
data,
|
||||||
cache,
|
cache,
|
||||||
}: IStaleDataNotification) => {
|
}: IStaleDataNotification) => {
|
||||||
const { classes: themeStyles } = useThemeStyles();
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
const getStyles = () => {
|
const style = useMemo(() => {
|
||||||
const base = {
|
const base = {
|
||||||
|
...fadeInBottomStartWithoutFixed,
|
||||||
padding: `${theme.spacing(3)} ${theme.spacing(4)}`,
|
padding: `${theme.spacing(3)} ${theme.spacing(4)}`,
|
||||||
boxShadow: theme.boxShadows.elevated,
|
boxShadow: theme.boxShadows.elevated,
|
||||||
borderRadius: theme.shape.borderRadiusLarge,
|
borderRadius: theme.shape.borderRadiusLarge,
|
||||||
@ -41,15 +45,10 @@ export const StaleDataNotification = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
return base;
|
return base;
|
||||||
};
|
}, [theme, isExtraSmallScreen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimateOnMount
|
<AnimateOnMount mounted={show} start={style} enter={fadeInBottomEnter}>
|
||||||
mounted={show}
|
|
||||||
start={themeStyles.fadeInBottomStartWithoutFixed}
|
|
||||||
enter={themeStyles.fadeInBottomEnter}
|
|
||||||
style={getStyles()}
|
|
||||||
>
|
|
||||||
<Typography variant="h5" sx={{ my: 2, mb: 2 }}>
|
<Typography variant="h5" sx={{ my: 2, mb: 2 }}>
|
||||||
Your data is stale
|
Your data is stale
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
|
||||||
'& + &': {
|
|
||||||
marginTop: theme.spacing(2),
|
|
||||||
},
|
|
||||||
background: theme.palette.background.paper,
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
padding: theme.spacing(0.5, 2),
|
|
||||||
display: 'flex',
|
|
||||||
gap: theme.spacing(1),
|
|
||||||
alignItems: 'center',
|
|
||||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
||||||
fontWeight: theme.typography.fontWeightMedium,
|
|
||||||
},
|
|
||||||
headerDraggable: {
|
|
||||||
paddingLeft: theme.spacing(1),
|
|
||||||
},
|
|
||||||
icon: {
|
|
||||||
fill: theme.palette.inactiveIcon,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
marginLeft: 'auto',
|
|
||||||
display: 'flex',
|
|
||||||
minHeight: theme.spacing(6),
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
resultChip: {
|
|
||||||
marginLeft: 'auto',
|
|
||||||
},
|
|
||||||
body: {
|
|
||||||
padding: theme.spacing(2),
|
|
||||||
justifyItems: 'center',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,7 +1,6 @@
|
|||||||
import { DragEventHandler, FC, ReactNode } from 'react';
|
import { DragEventHandler, FC, ReactNode } from 'react';
|
||||||
import { DragIndicator } from '@mui/icons-material';
|
import { DragIndicator } from '@mui/icons-material';
|
||||||
import { styled, IconButton, Box } from '@mui/material';
|
import { styled, IconButton, Box } from '@mui/material';
|
||||||
import classNames from 'classnames';
|
|
||||||
import { IFeatureStrategy } from 'interfaces/strategy';
|
import { IFeatureStrategy } from 'interfaces/strategy';
|
||||||
import {
|
import {
|
||||||
getFeatureStrategyIcon,
|
getFeatureStrategyIcon,
|
||||||
@ -9,7 +8,6 @@ import {
|
|||||||
} from 'utils/strategyNames';
|
} from 'utils/strategyNames';
|
||||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './StrategyItemContainer.styles';
|
|
||||||
import { PlaygroundStrategySchema } from 'openapi';
|
import { PlaygroundStrategySchema } from 'openapi';
|
||||||
|
|
||||||
interface IStrategyItemContainerProps {
|
interface IStrategyItemContainerProps {
|
||||||
@ -40,6 +38,27 @@ const StyledIndexLabel = styled('div')(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledContainer = styled(Box)(({ theme }) => ({
|
||||||
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
'& + &': {
|
||||||
|
marginTop: theme.spacing(2),
|
||||||
|
},
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledHeader = styled('div', {
|
||||||
|
shouldForwardProp: prop => prop !== 'draggable',
|
||||||
|
})(({ theme, draggable }) => ({
|
||||||
|
padding: theme.spacing(0.5, 2),
|
||||||
|
display: 'flex',
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
alignItems: 'center',
|
||||||
|
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||||
|
fontWeight: theme.typography.fontWeightMedium,
|
||||||
|
paddingLeft: draggable ? theme.spacing(1) : theme.spacing(2),
|
||||||
|
}));
|
||||||
|
|
||||||
export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
||||||
strategy,
|
strategy,
|
||||||
onDragStart,
|
onDragStart,
|
||||||
@ -49,7 +68,6 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
|||||||
orderNumber,
|
orderNumber,
|
||||||
style = {},
|
style = {},
|
||||||
}) => {
|
}) => {
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const Icon = getFeatureStrategyIcon(strategy.name);
|
const Icon = getFeatureStrategyIcon(strategy.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -58,12 +76,8 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
|||||||
condition={orderNumber !== undefined}
|
condition={orderNumber !== undefined}
|
||||||
show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>}
|
show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>}
|
||||||
/>
|
/>
|
||||||
<Box className={styles.container} style={{ ...style }}>
|
<StyledContainer style={style}>
|
||||||
<div
|
<StyledHeader draggable={Boolean(onDragStart)}>
|
||||||
className={classNames(styles.header, {
|
|
||||||
[styles.headerDraggable]: Boolean(onDragStart),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(onDragStart)}
|
condition={Boolean(onDragStart)}
|
||||||
show={() => (
|
show={() => (
|
||||||
@ -83,16 +97,36 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
|
|||||||
</DragIcon>
|
</DragIcon>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Icon className={styles.icon} />
|
<Icon
|
||||||
|
sx={{
|
||||||
|
fill: theme => theme.palette.inactiveIcon,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<StringTruncator
|
<StringTruncator
|
||||||
maxWidth="150"
|
maxWidth="150"
|
||||||
maxLength={15}
|
maxLength={15}
|
||||||
text={formatStrategyName(strategy.name)}
|
text={formatStrategyName(strategy.name)}
|
||||||
/>
|
/>
|
||||||
<div className={styles.actions}>{actions}</div>
|
<Box
|
||||||
</div>
|
sx={{
|
||||||
<div className={styles.body}>{children}</div>
|
marginLeft: 'auto',
|
||||||
|
display: 'flex',
|
||||||
|
minHeight: theme => theme.spacing(6),
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{actions}
|
||||||
</Box>
|
</Box>
|
||||||
|
</StyledHeader>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
justifyItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
</StyledContainer>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
tabNav: {
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
borderBottom: '1px solid',
|
|
||||||
borderBottomColor: theme.palette.grey[300],
|
|
||||||
borderRadius: 0,
|
|
||||||
},
|
|
||||||
tab: {
|
|
||||||
[theme.breakpoints.up('lg')]: {
|
|
||||||
minWidth: 160,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,7 +1,5 @@
|
|||||||
import React, { useState, ReactNode } from 'react';
|
import React, { useState, ReactNode } from 'react';
|
||||||
import classnames from 'classnames';
|
|
||||||
import { Tabs, Tab, Paper } from '@mui/material';
|
import { Tabs, Tab, Paper } from '@mui/material';
|
||||||
import { useStyles } from 'component/common/TabNav/TabNav/TabNav.styles';
|
|
||||||
import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel';
|
import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel';
|
||||||
|
|
||||||
interface ITabNavProps {
|
interface ITabNavProps {
|
||||||
@ -15,13 +13,13 @@ interface ITabData {
|
|||||||
label: string;
|
label: string;
|
||||||
component: ReactNode;
|
component: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TabNav = ({
|
export const TabNav = ({
|
||||||
tabData,
|
tabData,
|
||||||
className = '',
|
className = '',
|
||||||
navClass = '',
|
navClass = '',
|
||||||
startingTab = 0,
|
startingTab = 0,
|
||||||
}: ITabNavProps) => {
|
}: ITabNavProps) => {
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const [activeTab, setActiveTab] = useState(startingTab);
|
const [activeTab, setActiveTab] = useState(startingTab);
|
||||||
const renderTabs = () =>
|
const renderTabs = () =>
|
||||||
tabData.map((tab, index) => (
|
tabData.map((tab, index) => (
|
||||||
@ -30,7 +28,11 @@ export const TabNav = ({
|
|||||||
label={tab.label}
|
label={tab.label}
|
||||||
id={`tab-${index}`}
|
id={`tab-${index}`}
|
||||||
aria-controls={`tabpanel-${index}`}
|
aria-controls={`tabpanel-${index}`}
|
||||||
className={styles.tab}
|
sx={{
|
||||||
|
minWidth: {
|
||||||
|
lg: 160,
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -44,8 +46,14 @@ export const TabNav = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Paper
|
<Paper
|
||||||
className={classnames(styles.tabNav, navClass)}
|
className={navClass}
|
||||||
elevation={0}
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
backgroundColor: theme => theme.palette.background.paper,
|
||||||
|
borderBottom: '1px solid',
|
||||||
|
borderBottomColor: theme => theme.palette.grey[300],
|
||||||
|
borderRadius: 0,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Tabs
|
<Tabs
|
||||||
value={activeTab}
|
value={activeTab}
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { styled, TableCell } from '@mui/material';
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const StyledTableCell = styled(TableCell, {
|
||||||
header: {
|
shouldForwardProp: prop =>
|
||||||
|
prop !== 'isFlex' && prop !== 'isSortable' && prop !== 'isFlexGrow',
|
||||||
|
})<{
|
||||||
|
isFlex?: boolean;
|
||||||
|
isSortable?: boolean;
|
||||||
|
isFlexGrow?: boolean;
|
||||||
|
}>(({ theme, isFlex, isSortable, isFlexGrow }) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
fontWeight: theme.fontWeight.medium,
|
fontWeight: theme.typography.fontWeightRegular,
|
||||||
},
|
...(isFlex && {
|
||||||
flex: {
|
|
||||||
justifyContent: 'stretch',
|
justifyContent: 'stretch',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -13,11 +18,8 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
'& > *': {
|
'& > *': {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
flexGrow: {
|
...(isSortable && {
|
||||||
flexGrow: 1,
|
|
||||||
},
|
|
||||||
sortable: {
|
|
||||||
padding: 0,
|
padding: 0,
|
||||||
'&:hover, &:focus': {
|
'&:hover, &:focus': {
|
||||||
backgroundColor: theme.palette.tableHeaderHover,
|
backgroundColor: theme.palette.tableHeaderHover,
|
||||||
@ -25,8 +27,15 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
sortButton: {
|
...(isFlexGrow && {
|
||||||
|
flexGrow: 1,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledButton = styled('button', {
|
||||||
|
shouldForwardProp: prop => prop !== 'isSorted',
|
||||||
|
})<{ isSorted?: boolean }>(({ theme, isSorted }) => ({
|
||||||
all: 'unset',
|
all: 'unset',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@ -41,11 +50,12 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
boxSizing: 'inherit',
|
boxSizing: 'inherit',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
...(isSorted && {
|
||||||
sortedButton: {
|
fontWeight: theme.typography.fontWeightBold,
|
||||||
fontWeight: theme.fontWeight.bold,
|
}),
|
||||||
},
|
}));
|
||||||
label: {
|
|
||||||
|
export const StyledLabel = styled('span')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
flexShrink: 1,
|
flexShrink: 1,
|
||||||
@ -58,27 +68,17 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
},
|
}));
|
||||||
alignLeft: {
|
|
||||||
justifyContent: 'flex-start',
|
export const StyledHiddenMeasurementLayer = styled('span')(({ theme }) => ({
|
||||||
textAlign: 'left',
|
|
||||||
},
|
|
||||||
alignRight: {
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
textAlign: 'right',
|
|
||||||
},
|
|
||||||
alignCenter: {
|
|
||||||
justifyContent: 'center',
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
hiddenMeasurementLayer: {
|
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
}));
|
||||||
visibleAbsoluteLayer: {
|
|
||||||
|
export const StyledVisibleAbsoluteLayer = styled('span')(({ theme }) => ({
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -95,5 +95,4 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
overflowX: 'hidden',
|
overflowX: 'hidden',
|
||||||
overflowY: 'visible',
|
overflowY: 'visible',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
@ -7,11 +7,16 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { TableCell, Tooltip } from '@mui/material';
|
import { Tooltip } from '@mui/material';
|
||||||
import classnames from 'classnames';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './CellSortable.styles';
|
|
||||||
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
||||||
|
import {
|
||||||
|
StyledButton,
|
||||||
|
StyledHiddenMeasurementLayer,
|
||||||
|
StyledLabel,
|
||||||
|
StyledTableCell,
|
||||||
|
StyledVisibleAbsoluteLayer,
|
||||||
|
} from './CellSortable.styles';
|
||||||
import { SortArrow } from './SortArrow/SortArrow';
|
import { SortArrow } from './SortArrow/SortArrow';
|
||||||
|
|
||||||
interface ICellSortableProps {
|
interface ICellSortableProps {
|
||||||
@ -45,7 +50,6 @@ export const CellSortable: FC<ICellSortableProps> = ({
|
|||||||
const { setAnnouncement } = useContext(AnnouncerContext);
|
const { setAnnouncement } = useContext(AnnouncerContext);
|
||||||
const [title, setTitle] = useState('');
|
const [title, setTitle] = useState('');
|
||||||
const ref = useRef<HTMLSpanElement>(null);
|
const ref = useRef<HTMLSpanElement>(null);
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
const ariaSort = isSorted
|
const ariaSort = isSorted
|
||||||
? isDescending
|
? isDescending
|
||||||
@ -62,18 +66,27 @@ export const CellSortable: FC<ICellSortableProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const alignClass = useMemo(() => {
|
const alignStyle = useMemo(() => {
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case 'left':
|
case 'left':
|
||||||
return styles.alignLeft;
|
return {
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
textAlign: 'left',
|
||||||
|
} as const;
|
||||||
case 'center':
|
case 'center':
|
||||||
return styles.alignCenter;
|
return {
|
||||||
|
justifyContent: 'center',
|
||||||
|
textAlign: 'center',
|
||||||
|
} as const;
|
||||||
case 'right':
|
case 'right':
|
||||||
return styles.alignRight;
|
return {
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
textAlign: 'right',
|
||||||
|
} as const;
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}, [align, styles]);
|
}, [align]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateTitle = () => {
|
const updateTitle = () => {
|
||||||
@ -93,55 +106,36 @@ export const CellSortable: FC<ICellSortableProps> = ({
|
|||||||
}, [setTitle, ariaTitle]); // eslint-disable-line react-hooks/exhaustive-deps
|
}, [setTitle, ariaTitle]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableCell
|
<StyledTableCell
|
||||||
component="th"
|
component="th"
|
||||||
aria-sort={ariaSort}
|
aria-sort={ariaSort}
|
||||||
className={classnames(
|
|
||||||
styles.header,
|
|
||||||
isSortable && styles.sortable,
|
|
||||||
isFlex && styles.flex,
|
|
||||||
isFlexGrow && styles.flexGrow
|
|
||||||
)}
|
|
||||||
style={{ width, minWidth, maxWidth }}
|
style={{ width, minWidth, maxWidth }}
|
||||||
|
isFlex={isFlex}
|
||||||
|
isFlexGrow={isFlexGrow}
|
||||||
|
isSortable={isSortable}
|
||||||
>
|
>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={isSortable}
|
condition={isSortable}
|
||||||
show={
|
show={
|
||||||
<Tooltip title={title} arrow>
|
<Tooltip title={title} arrow>
|
||||||
<button
|
<StyledButton
|
||||||
|
isSorted={isSorted}
|
||||||
type="button"
|
type="button"
|
||||||
className={classnames(
|
|
||||||
isSorted && styles.sortedButton,
|
|
||||||
styles.sortButton,
|
|
||||||
alignClass
|
|
||||||
)}
|
|
||||||
onClick={onSortClick}
|
onClick={onSortClick}
|
||||||
>
|
>
|
||||||
<span
|
<StyledHiddenMeasurementLayer
|
||||||
className={classnames(
|
style={alignStyle}
|
||||||
styles.hiddenMeasurementLayer,
|
|
||||||
alignClass
|
|
||||||
)}
|
|
||||||
aria-hidden
|
aria-hidden
|
||||||
>
|
>
|
||||||
<span
|
<StyledLabel tabIndex={-1} data-text={children}>
|
||||||
className={styles.label}
|
|
||||||
tabIndex={-1}
|
|
||||||
data-text={children}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</span>
|
</StyledLabel>
|
||||||
<SortArrow
|
<SortArrow
|
||||||
isSorted={isSorted}
|
isSorted={isSorted}
|
||||||
isDesc={isDescending}
|
isDesc={isDescending}
|
||||||
/>
|
/>
|
||||||
</span>
|
</StyledHiddenMeasurementLayer>
|
||||||
<span
|
<StyledVisibleAbsoluteLayer style={alignStyle}>
|
||||||
className={classnames(
|
|
||||||
styles.visibleAbsoluteLayer,
|
|
||||||
alignClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span ref={ref} tabIndex={-1}>
|
<span ref={ref} tabIndex={-1}>
|
||||||
<span>{children}</span>
|
<span>{children}</span>
|
||||||
</span>
|
</span>
|
||||||
@ -150,12 +144,12 @@ export const CellSortable: FC<ICellSortableProps> = ({
|
|||||||
isDesc={isDescending}
|
isDesc={isDescending}
|
||||||
className="sort-arrow"
|
className="sort-arrow"
|
||||||
/>
|
/>
|
||||||
</span>
|
</StyledVisibleAbsoluteLayer>
|
||||||
</button>
|
</StyledButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
elseShow={<div className={alignClass}>{children}</div>}
|
elseShow={<div style={alignStyle}>{children}</div>}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</StyledTableCell>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
icon: {
|
|
||||||
marginLeft: theme.spacing(0.25),
|
|
||||||
marginRight: theme.spacing(-0.5),
|
|
||||||
color: theme.palette.grey[700],
|
|
||||||
fontSize: theme.fontSizes.mainHeader,
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
},
|
|
||||||
sorted: {
|
|
||||||
color: theme.palette.grey[900],
|
|
||||||
},
|
|
||||||
}));
|
|
@ -5,8 +5,8 @@ import {
|
|||||||
UnfoldMoreOutlined,
|
UnfoldMoreOutlined,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './SortArrow.styles';
|
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import { Theme } from '@mui/material';
|
||||||
|
|
||||||
interface ISortArrowProps {
|
interface ISortArrowProps {
|
||||||
isSorted?: boolean;
|
isSorted?: boolean;
|
||||||
@ -14,14 +14,19 @@ interface ISortArrowProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const iconStyle = (theme: Theme) => ({
|
||||||
|
marginLeft: theme.spacing(0.25),
|
||||||
|
marginRight: theme.spacing(-0.5),
|
||||||
|
color: theme.palette.neutral.main,
|
||||||
|
fontSize: theme.fontSizes.mainHeader,
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
});
|
||||||
|
|
||||||
export const SortArrow: VFC<ISortArrowProps> = ({
|
export const SortArrow: VFC<ISortArrowProps> = ({
|
||||||
isSorted: sorted,
|
isSorted: sorted,
|
||||||
isDesc: desc = false,
|
isDesc: desc = false,
|
||||||
className,
|
className,
|
||||||
}) => {
|
}) => (
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(sorted)}
|
condition={Boolean(sorted)}
|
||||||
show={
|
show={
|
||||||
@ -29,21 +34,21 @@ export const SortArrow: VFC<ISortArrowProps> = ({
|
|||||||
condition={Boolean(desc)}
|
condition={Boolean(desc)}
|
||||||
show={
|
show={
|
||||||
<KeyboardArrowDown
|
<KeyboardArrowDown
|
||||||
className={classnames(
|
sx={theme => ({
|
||||||
styles.icon,
|
...iconStyle(theme),
|
||||||
styles.sorted,
|
color: theme.palette.tableHeaderColor,
|
||||||
className
|
})}
|
||||||
)}
|
className={className}
|
||||||
fontSize="inherit"
|
fontSize="inherit"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
<KeyboardArrowUp
|
<KeyboardArrowUp
|
||||||
className={classnames(
|
sx={theme => ({
|
||||||
styles.icon,
|
...iconStyle(theme),
|
||||||
styles.sorted,
|
color: theme.palette.tableHeaderColor,
|
||||||
className
|
})}
|
||||||
)}
|
className={className}
|
||||||
fontSize="inherit"
|
fontSize="inherit"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@ -51,10 +56,12 @@ export const SortArrow: VFC<ISortArrowProps> = ({
|
|||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
<UnfoldMoreOutlined
|
<UnfoldMoreOutlined
|
||||||
className={classnames(styles.icon, className, 'hover-only')}
|
sx={theme => ({
|
||||||
|
...iconStyle(theme),
|
||||||
|
})}
|
||||||
|
className={classnames(className, 'hover-only')}
|
||||||
fontSize="inherit"
|
fontSize="inherit"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
tableHeader: {
|
|
||||||
'& > th': {
|
|
||||||
height: theme.shape.tableRowHeightCompact,
|
|
||||||
border: 0,
|
|
||||||
backgroundColor: theme.palette.tableHeaderBackground,
|
|
||||||
color: theme.palette.tableHeaderColor,
|
|
||||||
'&:first-of-type': {
|
|
||||||
borderTopLeftRadius: theme.shape.borderRadiusMedium,
|
|
||||||
borderBottomLeftRadius: theme.shape.borderRadiusMedium,
|
|
||||||
},
|
|
||||||
'&:last-of-type': {
|
|
||||||
borderTopRightRadius: theme.shape.borderRadiusMedium,
|
|
||||||
borderBottomRightRadius: theme.shape.borderRadiusMedium,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,7 +1,6 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { TableHead, TableRow } from '@mui/material';
|
import { styled, TableHead, TableRow } from '@mui/material';
|
||||||
import { HeaderGroup } from 'react-table';
|
import { HeaderGroup } from 'react-table';
|
||||||
import { useStyles } from './SortableTableHeader.styles';
|
|
||||||
import { CellSortable } from './CellSortable/CellSortable';
|
import { CellSortable } from './CellSortable/CellSortable';
|
||||||
|
|
||||||
interface ISortableTableHeaderProps {
|
interface ISortableTableHeaderProps {
|
||||||
@ -10,20 +9,31 @@ interface ISortableTableHeaderProps {
|
|||||||
flex?: boolean;
|
flex?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||||
|
'& > th': {
|
||||||
|
height: theme.shape.tableRowHeightCompact,
|
||||||
|
border: 0,
|
||||||
|
backgroundColor: theme.palette.tableHeaderBackground,
|
||||||
|
color: theme.palette.tableHeaderColor,
|
||||||
|
'&:first-of-type': {
|
||||||
|
borderTopLeftRadius: theme.shape.borderRadiusMedium,
|
||||||
|
borderBottomLeftRadius: theme.shape.borderRadiusMedium,
|
||||||
|
},
|
||||||
|
'&:last-of-type': {
|
||||||
|
borderTopRightRadius: theme.shape.borderRadiusMedium,
|
||||||
|
borderBottomRightRadius: theme.shape.borderRadiusMedium,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const SortableTableHeader: VFC<ISortableTableHeaderProps> = ({
|
export const SortableTableHeader: VFC<ISortableTableHeaderProps> = ({
|
||||||
headerGroups,
|
headerGroups,
|
||||||
className,
|
className,
|
||||||
flex,
|
flex,
|
||||||
}) => {
|
}) => (
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableHead className={className}>
|
<TableHead className={className}>
|
||||||
{headerGroups.map(headerGroup => (
|
{headerGroups.map(headerGroup => (
|
||||||
<TableRow
|
<StyledTableRow {...headerGroup.getHeaderGroupProps()}>
|
||||||
{...headerGroup.getHeaderGroupProps()}
|
|
||||||
className={styles.tableHeader}
|
|
||||||
>
|
|
||||||
{headerGroup.headers.map((column: HeaderGroup) => {
|
{headerGroup.headers.map((column: HeaderGroup) => {
|
||||||
const content = column.render('Header');
|
const content = column.render('Header');
|
||||||
|
|
||||||
@ -54,8 +64,7 @@ export const SortableTableHeader: VFC<ISortableTableHeaderProps> = ({
|
|||||||
</CellSortable>
|
</CellSortable>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</TableRow>
|
</StyledTableRow>
|
||||||
))}
|
))}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles<{
|
|
||||||
rowHeight: 'auto' | 'standard' | 'dense' | 'compact' | number;
|
|
||||||
}>()((theme, { rowHeight }) => ({
|
|
||||||
table: {
|
|
||||||
position: 'relative',
|
|
||||||
|
|
||||||
'& tbody tr': {
|
|
||||||
height:
|
|
||||||
{
|
|
||||||
auto: 'auto',
|
|
||||||
standard: theme.shape.tableRowHeight,
|
|
||||||
compact: theme.shape.tableRowHeightCompact,
|
|
||||||
dense: theme.shape.tableRowHeightDense,
|
|
||||||
}[rowHeight] ?? rowHeight,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,16 +1,24 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import classnames from 'classnames';
|
|
||||||
import { Table as MUITable, TableProps } from '@mui/material';
|
import { Table as MUITable, TableProps } from '@mui/material';
|
||||||
import { useStyles } from './Table.styles';
|
|
||||||
|
|
||||||
export const Table: FC<
|
export const Table: FC<
|
||||||
TableProps & {
|
TableProps & {
|
||||||
rowHeight?: 'auto' | 'dense' | 'standard' | 'compact' | number;
|
rowHeight?: 'auto' | 'dense' | 'standard' | 'compact' | number;
|
||||||
}
|
}
|
||||||
> = ({ rowHeight = 'auto', className, ...props }) => {
|
> = ({ rowHeight = 'auto', ...props }) => (
|
||||||
const { classes } = useStyles({ rowHeight });
|
<MUITable
|
||||||
|
sx={{
|
||||||
return (
|
position: 'relative',
|
||||||
<MUITable className={classnames(classes.table, className)} {...props} />
|
'& tbody tr': {
|
||||||
);
|
height: theme =>
|
||||||
};
|
({
|
||||||
|
auto: 'auto',
|
||||||
|
standard: theme.shape.tableRowHeight,
|
||||||
|
compact: theme.shape.tableRowHeightCompact,
|
||||||
|
dense: theme.shape.tableRowHeightDense,
|
||||||
|
}[rowHeight] ?? rowHeight),
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
tableCell: {
|
|
||||||
padding: 0,
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,18 +1,16 @@
|
|||||||
import { FC, ForwardedRef, forwardRef } from 'react';
|
import { FC, ForwardedRef, forwardRef } from 'react';
|
||||||
import classnames from 'classnames';
|
import {
|
||||||
import { TableCell as MUITableCell, TableCellProps } from '@mui/material';
|
styled,
|
||||||
import { useStyles } from './TableCell.styles';
|
TableCell as MUITableCell,
|
||||||
|
TableCellProps,
|
||||||
|
} from '@mui/material';
|
||||||
|
|
||||||
|
const StyledTableCell = styled(MUITableCell)(({ theme }) => ({
|
||||||
|
padding: 0,
|
||||||
|
}));
|
||||||
|
|
||||||
export const TableCell: FC<TableCellProps> = forwardRef(
|
export const TableCell: FC<TableCellProps> = forwardRef(
|
||||||
({ className, ...props }, ref: ForwardedRef<unknown>) => {
|
({ className, ...props }, ref: ForwardedRef<unknown>) => (
|
||||||
const { classes: styles } = useStyles();
|
<StyledTableCell {...props} ref={ref} />
|
||||||
|
)
|
||||||
return (
|
|
||||||
<MUITableCell
|
|
||||||
className={classnames(styles.tableCell, className)}
|
|
||||||
{...props}
|
|
||||||
ref={ref}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
emptyStateListItem: {
|
|
||||||
border: `2px dashed ${theme.palette.neutral.light}`,
|
|
||||||
padding: '0.8rem',
|
|
||||||
textAlign: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginTop: theme.spacing(2),
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,9 +1,19 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import { useStyles } from 'component/common/Table/TablePlaceholder/TablePlaceholder.styles';
|
|
||||||
|
|
||||||
export const TablePlaceholder: FC = ({ children }) => {
|
export const TablePlaceholder: FC = ({ children }) => (
|
||||||
const { classes: styles } = useStyles();
|
<Box
|
||||||
|
sx={{
|
||||||
return <Box className={styles.emptyStateListItem}>{children}</Box>;
|
border: theme => `2px dashed ${theme.palette.neutral.light}`,
|
||||||
};
|
p: 1.6,
|
||||||
|
textAlign: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
mt: 2,
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(() => ({
|
|
||||||
row: {
|
|
||||||
position: 'absolute',
|
|
||||||
width: '100%',
|
|
||||||
'&:hover': {
|
|
||||||
'.show-row-hover': {
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
cell: {
|
|
||||||
alignItems: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
flexShrink: 0,
|
|
||||||
'& > *': {
|
|
||||||
flexGrow: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
@ -3,12 +3,11 @@ import { useTheme } from '@mui/material';
|
|||||||
import {
|
import {
|
||||||
SortableTableHeader,
|
SortableTableHeader,
|
||||||
Table,
|
Table,
|
||||||
TableCell,
|
|
||||||
TableBody,
|
TableBody,
|
||||||
TableRow,
|
TableRow,
|
||||||
|
TableCell,
|
||||||
} from 'component/common/Table';
|
} from 'component/common/Table';
|
||||||
import { useVirtualizedRange } from 'hooks/useVirtualizedRange';
|
import { useVirtualizedRange } from 'hooks/useVirtualizedRange';
|
||||||
import { useStyles } from './VirtualizedTable.styles';
|
|
||||||
import { HeaderGroup, Row } from 'react-table';
|
import { HeaderGroup, Row } from 'react-table';
|
||||||
|
|
||||||
interface IVirtualizedTableProps {
|
interface IVirtualizedTableProps {
|
||||||
@ -34,7 +33,6 @@ export const VirtualizedTable: VFC<IVirtualizedTableProps> = ({
|
|||||||
rows,
|
rows,
|
||||||
prepareRow,
|
prepareRow,
|
||||||
}) => {
|
}) => {
|
||||||
const { classes } = useStyles();
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const rowHeight = useMemo(
|
const rowHeight = useMemo(
|
||||||
() => rowHeightOverride || theme.shape.tableRowHeight,
|
() => rowHeightOverride || theme.shape.tableRowHeight,
|
||||||
@ -56,7 +54,28 @@ export const VirtualizedTable: VFC<IVirtualizedTableProps> = ({
|
|||||||
style={{ height: tableHeight }}
|
style={{ height: tableHeight }}
|
||||||
>
|
>
|
||||||
<SortableTableHeader headerGroups={headerGroups} flex />
|
<SortableTableHeader headerGroups={headerGroups} flex />
|
||||||
<TableBody role="rowgroup">
|
<TableBody
|
||||||
|
role="rowgroup"
|
||||||
|
sx={{
|
||||||
|
'& tr': {
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
'&:hover': {
|
||||||
|
'.show-row-hover': {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'& tr td': {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
flexShrink: 0,
|
||||||
|
'& > *': {
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
{rows.map((row, index) => {
|
{rows.map((row, index) => {
|
||||||
const top =
|
const top =
|
||||||
index * rowHeight + theme.shape.tableRowHeightCompact;
|
index * rowHeight + theme.shape.tableRowHeightCompact;
|
||||||
@ -73,10 +92,10 @@ export const VirtualizedTable: VFC<IVirtualizedTableProps> = ({
|
|||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
hover
|
hover
|
||||||
{...row.getRowProps()}
|
{...row.getRowProps({
|
||||||
|
style: { display: 'flex', top },
|
||||||
|
})}
|
||||||
key={row.id}
|
key={row.id}
|
||||||
className={classes.row}
|
|
||||||
style={{ display: 'flex', top }}
|
|
||||||
>
|
>
|
||||||
{row.cells.map(cell => (
|
{row.cells.map(cell => (
|
||||||
<TableCell
|
<TableCell
|
||||||
@ -87,7 +106,6 @@ export const VirtualizedTable: VFC<IVirtualizedTableProps> = ({
|
|||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
className={classes.cell}
|
|
||||||
>
|
>
|
||||||
{cell.render('Cell')}
|
{cell.render('Cell')}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: theme.spacing(0, 1.5),
|
|
||||||
},
|
|
||||||
divider: {
|
|
||||||
borderColor: theme.palette.dividerAlternative,
|
|
||||||
height: theme.spacing(3),
|
|
||||||
margin: theme.spacing(0, 2),
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,24 +1,27 @@
|
|||||||
import { Box, Divider } from '@mui/material';
|
import { Box, Divider, styled } from '@mui/material';
|
||||||
import { FC, VFC } from 'react';
|
import { FC, VFC } from 'react';
|
||||||
import { useStyles } from './ActionCell.styles';
|
|
||||||
|
|
||||||
const ActionCellDivider: VFC = () => {
|
const StyledContainer = styled(Box)(({ theme }) => ({
|
||||||
const { classes } = useStyles();
|
display: 'flex',
|
||||||
return (
|
justifyContent: 'center',
|
||||||
<Divider
|
alignItems: 'center',
|
||||||
className={classes.divider}
|
padding: theme.spacing(0, 1.5),
|
||||||
orientation="vertical"
|
}));
|
||||||
variant="middle"
|
|
||||||
/>
|
const StyledDivider = styled(Divider)(({ theme }) => ({
|
||||||
);
|
borderColor: theme.palette.dividerAlternative,
|
||||||
};
|
height: theme.spacing(3),
|
||||||
|
margin: theme.spacing(0, 2),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const ActionCellDivider: VFC = () => (
|
||||||
|
<StyledDivider orientation="vertical" variant="middle" />
|
||||||
|
);
|
||||||
|
|
||||||
const ActionCellComponent: FC & {
|
const ActionCellComponent: FC & {
|
||||||
Divider: typeof ActionCellDivider;
|
Divider: typeof ActionCellDivider;
|
||||||
} = ({ children }) => {
|
} = ({ children }) => {
|
||||||
const { classes } = useStyles();
|
return <StyledContainer>{children}</StyledContainer>;
|
||||||
|
|
||||||
return <Box className={classes.container}>{children}</Box>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ActionCellComponent.Divider = ActionCellDivider;
|
ActionCellComponent.Divider = ActionCellDivider;
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
padding: theme.spacing(1.5),
|
|
||||||
},
|
|
||||||
box: {
|
|
||||||
width: '38px',
|
|
||||||
height: '38px',
|
|
||||||
background: 'gray',
|
|
||||||
borderRadius: '4px',
|
|
||||||
textAlign: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
fontSize: theme.fontSizes.smallerBody,
|
|
||||||
margin: '0 auto',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,8 +1,7 @@
|
|||||||
import React, { FC, VFC } from 'react';
|
import React, { FC, VFC } from 'react';
|
||||||
import TimeAgo from 'react-timeago';
|
import TimeAgo from 'react-timeago';
|
||||||
import { Tooltip, useTheme } from '@mui/material';
|
import { styled, Tooltip, useTheme } from '@mui/material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './FeatureSeenCell.styles';
|
|
||||||
|
|
||||||
function shortenUnitName(unit?: string): string {
|
function shortenUnitName(unit?: string): string {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
@ -50,6 +49,24 @@ const useFeatureColor = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
padding: theme.spacing(1.5),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledBox = styled('div')(({ theme }) => ({
|
||||||
|
width: '38px',
|
||||||
|
height: '38px',
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
borderRadius: `${theme.shape.borderRadius}px`,
|
||||||
|
textAlign: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
margin: '0 auto',
|
||||||
|
}));
|
||||||
|
|
||||||
interface IFeatureSeenCellProps {
|
interface IFeatureSeenCellProps {
|
||||||
value?: string | Date | null;
|
value?: string | Date | null;
|
||||||
}
|
}
|
||||||
@ -59,21 +76,16 @@ const Wrapper: FC<{ unit?: string; tooltip: string }> = ({
|
|||||||
tooltip,
|
tooltip,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const getColor = useFeatureColor();
|
const getColor = useFeatureColor();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<StyledContainer>
|
||||||
<Tooltip title={tooltip} arrow describeChild>
|
<Tooltip title={tooltip} arrow describeChild>
|
||||||
<div
|
<StyledBox style={{ background: getColor(unit) }} data-loading>
|
||||||
className={styles.box}
|
|
||||||
style={{ background: getColor(unit) }}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</StyledBox>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { Tooltip } from '@mui/material';
|
import { styled, Tooltip } from '@mui/material';
|
||||||
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
|
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
|
||||||
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
||||||
import { useStyles } from './FeatureTypeCell.styles';
|
|
||||||
|
|
||||||
interface IFeatureTypeProps {
|
interface IFeatureTypeProps {
|
||||||
value?: string;
|
value?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
|
padding: theme.spacing(1.5),
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
color: theme.palette.text.disabled,
|
||||||
|
}));
|
||||||
|
|
||||||
export const FeatureTypeCell: VFC<IFeatureTypeProps> = ({ value }) => {
|
export const FeatureTypeCell: VFC<IFeatureTypeProps> = ({ value }) => {
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const { featureTypes } = useFeatureTypes();
|
const { featureTypes } = useFeatureTypes();
|
||||||
const IconComponent = getFeatureTypeIcons(value);
|
const IconComponent = getFeatureTypeIcons(value);
|
||||||
|
|
||||||
@ -20,10 +26,10 @@ export const FeatureTypeCell: VFC<IFeatureTypeProps> = ({ value }) => {
|
|||||||
const title = `This is a "${typeName || value}" toggle`;
|
const title = `This is a "${typeName || value}" toggle`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<StyledContainer>
|
||||||
<Tooltip arrow title={title} describeChild>
|
<Tooltip arrow title={title} describeChild>
|
||||||
<IconComponent data-loading className={styles.icon} />
|
<IconComponent data-loading />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
wordBreak: 'break-word',
|
|
||||||
padding: theme.spacing(1, 2),
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
display: '-webkit-box',
|
|
||||||
WebkitBoxOrient: 'vertical',
|
|
||||||
WebkitLineClamp: '1',
|
|
||||||
lineClamp: '1',
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
color: theme.palette.text.secondary,
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
fontSize: 'inherit',
|
|
||||||
WebkitLineClamp: '1',
|
|
||||||
lineClamp: '1',
|
|
||||||
display: '-webkit-box',
|
|
||||||
WebkitBoxOrient: 'vertical',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,8 +1,7 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
import { Box, Typography } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
import { useStyles } from './HighlightCell.styles';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
interface IHighlightCellProps {
|
interface IHighlightCellProps {
|
||||||
@ -10,17 +9,43 @@ interface IHighlightCellProps {
|
|||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledContainer = styled(Box)(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
padding: theme.spacing(1, 2),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledTitle = styled('span')(({ theme }) => ({
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
WebkitLineClamp: '1',
|
||||||
|
lineClamp: '1',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledSubtitle = styled('span')(({ theme }) => ({
|
||||||
|
color: theme.palette.text.secondary,
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
fontSize: 'inherit',
|
||||||
|
WebkitLineClamp: '1',
|
||||||
|
lineClamp: '1',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
}));
|
||||||
|
|
||||||
export const HighlightCell: VFC<IHighlightCellProps> = ({
|
export const HighlightCell: VFC<IHighlightCellProps> = ({
|
||||||
value,
|
value,
|
||||||
subtitle,
|
subtitle,
|
||||||
}) => {
|
}) => {
|
||||||
const { searchQuery } = useSearchHighlightContext();
|
const { searchQuery } = useSearchHighlightContext();
|
||||||
const { classes } = useStyles();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className={classes.container}>
|
<StyledContainer>
|
||||||
<span
|
<StyledTitle
|
||||||
className={classes.title}
|
|
||||||
style={{
|
style={{
|
||||||
WebkitLineClamp: Boolean(subtitle) ? 1 : 2,
|
WebkitLineClamp: Boolean(subtitle) ? 1 : 2,
|
||||||
lineClamp: Boolean(subtitle) ? 1 : 2,
|
lineClamp: Boolean(subtitle) ? 1 : 2,
|
||||||
@ -28,21 +53,17 @@ export const HighlightCell: VFC<IHighlightCellProps> = ({
|
|||||||
data-loading
|
data-loading
|
||||||
>
|
>
|
||||||
<Highlighter search={searchQuery}>{value}</Highlighter>
|
<Highlighter search={searchQuery}>{value}</Highlighter>
|
||||||
</span>
|
</StyledTitle>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(subtitle)}
|
condition={Boolean(subtitle)}
|
||||||
show={() => (
|
show={() => (
|
||||||
<Typography
|
<StyledSubtitle data-loading>
|
||||||
component="span"
|
|
||||||
className={classes.subtitle}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Highlighter search={searchQuery}>
|
<Highlighter search={searchQuery}>
|
||||||
{subtitle}
|
{subtitle}
|
||||||
</Highlighter>
|
</Highlighter>
|
||||||
</Typography>
|
</StyledSubtitle>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { Link, styled, Theme } from '@mui/material';
|
||||||
|
import { ComponentType } from 'react';
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const wrapperStyles = (theme: Theme) => ({
|
||||||
wrapper: {
|
|
||||||
paddingTop: theme.spacing(1.5),
|
paddingTop: theme.spacing(1.5),
|
||||||
paddingBottom: theme.spacing(1.5),
|
paddingBottom: theme.spacing(1.5),
|
||||||
paddingLeft: theme.spacing(2),
|
paddingLeft: theme.spacing(2),
|
||||||
@ -9,28 +9,38 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
minHeight: '62px',
|
minHeight: '62px',
|
||||||
},
|
});
|
||||||
link: {
|
|
||||||
|
export const StyledWrapper = styled('div')(({ theme }) => wrapperStyles(theme));
|
||||||
|
|
||||||
|
export const StyledLink = styled(Link)<{
|
||||||
|
component?: ComponentType<any>;
|
||||||
|
to?: string;
|
||||||
|
}>(({ theme }) => ({
|
||||||
|
...wrapperStyles(theme),
|
||||||
'&:hover, &:focus': {
|
'&:hover, &:focus': {
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
'& > div > span:first-of-type': {
|
'& > div > span:first-of-type': {
|
||||||
textDecoration: 'underline',
|
textDecoration: 'underline',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}));
|
||||||
container: {
|
|
||||||
|
export const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
wordBreak: 'break-all',
|
wordBreak: 'break-all',
|
||||||
},
|
}));
|
||||||
title: {
|
|
||||||
|
export const StyledTitle = styled('span')(({ theme }) => ({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
WebkitBoxOrient: 'vertical',
|
WebkitBoxOrient: 'vertical',
|
||||||
},
|
}));
|
||||||
description: {
|
|
||||||
|
export const StyledDescription = styled('span')(({ theme }) => ({
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
fontSize: 'inherit',
|
fontSize: 'inherit',
|
||||||
@ -40,5 +50,4 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
WebkitBoxOrient: 'vertical',
|
WebkitBoxOrient: 'vertical',
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { FC } from 'react';
|
import { ComponentType, FC } from 'react';
|
||||||
import { Link, Typography } from '@mui/material';
|
import { Link, styled, Typography } from '@mui/material';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useStyles } from './LinkCell.styles';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
import classnames from 'classnames';
|
import {
|
||||||
|
StyledWrapper,
|
||||||
|
StyledLink,
|
||||||
|
StyledContainer,
|
||||||
|
StyledTitle,
|
||||||
|
StyledDescription,
|
||||||
|
} from './LinkCell.styles';
|
||||||
|
|
||||||
interface ILinkCellProps {
|
interface ILinkCellProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
@ -21,14 +26,12 @@ export const LinkCell: FC<ILinkCellProps> = ({
|
|||||||
subtitle,
|
subtitle,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const { searchQuery } = useSearchHighlightContext();
|
const { searchQuery } = useSearchHighlightContext();
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<div className={styles.container}>
|
<StyledContainer>
|
||||||
<span
|
<StyledTitle
|
||||||
data-loading
|
data-loading
|
||||||
className={styles.title}
|
|
||||||
style={{
|
style={{
|
||||||
WebkitLineClamp: Boolean(subtitle) ? 1 : 2,
|
WebkitLineClamp: Boolean(subtitle) ? 1 : 2,
|
||||||
lineClamp: Boolean(subtitle) ? 1 : 2,
|
lineClamp: Boolean(subtitle) ? 1 : 2,
|
||||||
@ -36,44 +39,31 @@ export const LinkCell: FC<ILinkCellProps> = ({
|
|||||||
>
|
>
|
||||||
<Highlighter search={searchQuery}>{title}</Highlighter>
|
<Highlighter search={searchQuery}>{title}</Highlighter>
|
||||||
{children}
|
{children}
|
||||||
</span>
|
</StyledTitle>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(subtitle)}
|
condition={Boolean(subtitle)}
|
||||||
show={
|
show={
|
||||||
<>
|
<>
|
||||||
<Typography
|
<StyledDescription data-loading>
|
||||||
className={styles.description}
|
|
||||||
component="span"
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Highlighter search={searchQuery}>
|
<Highlighter search={searchQuery}>
|
||||||
{subtitle}
|
{subtitle}
|
||||||
</Highlighter>
|
</Highlighter>
|
||||||
</Typography>
|
</StyledDescription>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|
||||||
return to ? (
|
return to ? (
|
||||||
<Link
|
<StyledLink component={RouterLink} to={to} underline="hover">
|
||||||
component={RouterLink}
|
|
||||||
to={to}
|
|
||||||
underline="hover"
|
|
||||||
className={classnames(styles.wrapper, styles.link)}
|
|
||||||
>
|
|
||||||
{content}
|
{content}
|
||||||
</Link>
|
</StyledLink>
|
||||||
) : onClick ? (
|
) : onClick ? (
|
||||||
<Link
|
<StyledLink onClick={onClick} underline="hover">
|
||||||
onClick={onClick}
|
|
||||||
underline="hover"
|
|
||||||
className={classnames(styles.wrapper, styles.link)}
|
|
||||||
>
|
|
||||||
{content}
|
{content}
|
||||||
</Link>
|
</StyledLink>
|
||||||
) : (
|
) : (
|
||||||
<span className={styles.wrapper}>{content}</span>
|
<StyledWrapper>{content}</StyledWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles<{ lineClamp?: number }>()(
|
|
||||||
(theme, { lineClamp }) => ({
|
|
||||||
wrapper: {
|
|
||||||
padding: theme.spacing(1, 2),
|
|
||||||
display: '-webkit-box',
|
|
||||||
overflow: lineClamp ? 'hidden' : 'auto',
|
|
||||||
WebkitLineClamp: lineClamp ? lineClamp : 'none',
|
|
||||||
WebkitBoxOrient: 'vertical',
|
|
||||||
wordBreak: 'break-all',
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
wordBreak: 'normal',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
@ -1,6 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Box, SxProps, Theme } from '@mui/material';
|
import { Box, styled, SxProps, Theme } from '@mui/material';
|
||||||
import { useStyles } from './TextCell.styles';
|
|
||||||
|
|
||||||
interface ITextCellProps {
|
interface ITextCellProps {
|
||||||
value?: string | null;
|
value?: string | null;
|
||||||
@ -9,20 +8,30 @@ interface ITextCellProps {
|
|||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledWrapper = styled(Box, {
|
||||||
|
shouldForwardProp: prop => prop !== 'lineClamp',
|
||||||
|
})<{ lineClamp?: number }>(({ theme, lineClamp }) => ({
|
||||||
|
padding: theme.spacing(1, 2),
|
||||||
|
display: '-webkit-box',
|
||||||
|
overflow: lineClamp ? 'hidden' : 'auto',
|
||||||
|
WebkitLineClamp: lineClamp ? lineClamp : 'none',
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
[theme.breakpoints.down('sm')]: {
|
||||||
|
wordBreak: 'normal',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const TextCell: FC<ITextCellProps> = ({
|
export const TextCell: FC<ITextCellProps> = ({
|
||||||
value,
|
value,
|
||||||
children,
|
children,
|
||||||
lineClamp,
|
lineClamp,
|
||||||
sx,
|
sx,
|
||||||
'data-testid': testid,
|
'data-testid': testid,
|
||||||
}) => {
|
}) => (
|
||||||
const { classes } = useStyles({ lineClamp });
|
<StyledWrapper lineClamp={lineClamp} sx={sx}>
|
||||||
|
|
||||||
return (
|
|
||||||
<Box className={classes.wrapper} sx={sx}>
|
|
||||||
<span data-loading="true" data-testid={testid}>
|
<span data-loading="true" data-testid={testid}>
|
||||||
{children ?? value}
|
{children ?? value}
|
||||||
</span>
|
</span>
|
||||||
</Box>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
toastWrapper: {
|
|
||||||
right: 0,
|
|
||||||
left: 0,
|
|
||||||
margin: '0 auto',
|
|
||||||
maxWidth: '450px',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,16 +1,17 @@
|
|||||||
import { Portal } from '@mui/material';
|
import { Portal } from '@mui/material';
|
||||||
import { useContext, useEffect } from 'react';
|
import { useContext, useEffect, useMemo } from 'react';
|
||||||
import { useThemeStyles } from 'themes/themeStyles';
|
import {
|
||||||
|
fadeInBottomEnter,
|
||||||
|
fadeInBottomLeave,
|
||||||
|
fadeInBottomStartWithoutFixed,
|
||||||
|
} from 'themes/themeStyles';
|
||||||
import UIContext from 'contexts/UIContext';
|
import UIContext from 'contexts/UIContext';
|
||||||
import { useStyles } from './ToastRenderer.styles';
|
|
||||||
import AnimateOnMount from '../AnimateOnMount/AnimateOnMount';
|
import AnimateOnMount from '../AnimateOnMount/AnimateOnMount';
|
||||||
import Toast from './Toast/Toast';
|
import Toast from './Toast/Toast';
|
||||||
import { IToast } from 'interfaces/toast';
|
import { IToast } from 'interfaces/toast';
|
||||||
|
|
||||||
const ToastRenderer = () => {
|
const ToastRenderer = () => {
|
||||||
const { toastData, setToast } = useContext(UIContext);
|
const { toastData, setToast } = useContext(UIContext);
|
||||||
const { classes: themeStyles } = useThemeStyles();
|
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
const hide = () => {
|
const hide = () => {
|
||||||
setToast((prev: IToast) => ({ ...prev, show: false }));
|
setToast((prev: IToast) => ({ ...prev, show: false }));
|
||||||
@ -28,14 +29,28 @@ const ToastRenderer = () => {
|
|||||||
/* eslint-disable-next-line */
|
/* eslint-disable-next-line */
|
||||||
}, [toastData?.show]);
|
}, [toastData?.show]);
|
||||||
|
|
||||||
|
const animations = useMemo(
|
||||||
|
() => ({
|
||||||
|
start: {
|
||||||
|
...fadeInBottomStartWithoutFixed,
|
||||||
|
right: 0,
|
||||||
|
left: 0,
|
||||||
|
margin: '0 auto',
|
||||||
|
maxWidth: '450px',
|
||||||
|
},
|
||||||
|
enter: fadeInBottomEnter,
|
||||||
|
leave: fadeInBottomLeave,
|
||||||
|
}),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<AnimateOnMount
|
<AnimateOnMount
|
||||||
mounted={Boolean(toastData?.show)}
|
mounted={Boolean(toastData?.show)}
|
||||||
start={themeStyles.fadeInBottomStartWithoutFixed}
|
start={animations.start}
|
||||||
enter={themeStyles.fadeInBottomEnter}
|
enter={animations.enter}
|
||||||
leave={themeStyles.fadeInBottomLeave}
|
leave={animations.leave}
|
||||||
container={styles.toastWrapper}
|
|
||||||
>
|
>
|
||||||
<Toast {...toastData} />
|
<Toast {...toastData} />
|
||||||
</AnimateOnMount>
|
</AnimateOnMount>
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
|
||||||
feedback: {
|
|
||||||
borderRadius: '12.5px',
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
zIndex: 9999,
|
|
||||||
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
|
|
||||||
padding: '1.5rem',
|
|
||||||
maxWidth: '400px',
|
|
||||||
},
|
|
||||||
animateContainer: {
|
|
||||||
zIndex: 9999,
|
|
||||||
},
|
|
||||||
container: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
position: 'relative',
|
|
||||||
},
|
|
||||||
close: {
|
|
||||||
position: 'absolute',
|
|
||||||
right: '-38px',
|
|
||||||
top: '-47px',
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
|
|
||||||
['&:hover']: {
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
width: '25px',
|
|
||||||
height: '25px',
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
marginLeft: '1rem',
|
|
||||||
},
|
|
||||||
}));
|
|
@ -1,12 +1,15 @@
|
|||||||
import { useContext, useState } from 'react';
|
import { useContext, useMemo, useState } from 'react';
|
||||||
import { Button, IconButton, Tooltip } from '@mui/material';
|
import { Box, Button, IconButton, Tooltip, useTheme } from '@mui/material';
|
||||||
import classnames from 'classnames';
|
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import { ReactComponent as Logo } from 'assets/icons/logoPlain.svg';
|
import { ReactComponent as Logo } from 'assets/icons/logoPlain.svg';
|
||||||
import { useStyles } from 'component/feedback/FeedbackNPS/FeedbackNPS.styles';
|
|
||||||
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
|
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useThemeStyles } from 'themes/themeStyles';
|
import {
|
||||||
|
contentSpacingY,
|
||||||
|
fadeInTopEnter,
|
||||||
|
fadeInTopLeave,
|
||||||
|
fadeInTopStart,
|
||||||
|
} from 'themes/themeStyles';
|
||||||
import UIContext from 'contexts/UIContext';
|
import UIContext from 'contexts/UIContext';
|
||||||
import {
|
import {
|
||||||
PNPS_FEEDBACK_ID,
|
PNPS_FEEDBACK_ID,
|
||||||
@ -24,10 +27,18 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => {
|
|||||||
const { createFeedback, updateFeedback } = useAuthFeedbackApi();
|
const { createFeedback, updateFeedback } = useAuthFeedbackApi();
|
||||||
const { feedback } = useAuthFeedback();
|
const { feedback } = useAuthFeedback();
|
||||||
const [answeredNotNow, setAnsweredNotNow] = useState(false);
|
const [answeredNotNow, setAnsweredNotNow] = useState(false);
|
||||||
const { classes: styles } = useStyles();
|
const theme = useTheme();
|
||||||
const { classes: themeStyles } = useThemeStyles();
|
|
||||||
const feedbackId = PNPS_FEEDBACK_ID;
|
const feedbackId = PNPS_FEEDBACK_ID;
|
||||||
|
|
||||||
|
const animations = useMemo(
|
||||||
|
() => ({
|
||||||
|
start: { ...fadeInTopStart(theme), zIndex: theme.zIndex.tooltip },
|
||||||
|
enter: fadeInTopEnter,
|
||||||
|
leave: fadeInTopLeave,
|
||||||
|
}),
|
||||||
|
[theme]
|
||||||
|
);
|
||||||
|
|
||||||
const onConfirm = async () => {
|
const onConfirm = async () => {
|
||||||
try {
|
try {
|
||||||
await createFeedback({ feedbackId });
|
await createFeedback({ feedbackId });
|
||||||
@ -61,28 +72,53 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => {
|
|||||||
return (
|
return (
|
||||||
<AnimateOnMount
|
<AnimateOnMount
|
||||||
mounted={showFeedback}
|
mounted={showFeedback}
|
||||||
start={themeStyles.fadeInTopStart}
|
start={animations.start}
|
||||||
enter={themeStyles.fadeInTopEnter}
|
enter={animations.enter}
|
||||||
leave={themeStyles.fadeInTopLeave}
|
leave={animations.leave}
|
||||||
container={styles.animateContainer}
|
|
||||||
>
|
>
|
||||||
<div className={styles.feedback}>
|
<Box
|
||||||
<div
|
sx={{
|
||||||
className={classnames(
|
borderRadius: '12.5px',
|
||||||
styles.container,
|
backgroundColor: theme.palette.background.paper,
|
||||||
themeStyles.contentSpacingY
|
zIndex: 9999,
|
||||||
)}
|
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
|
||||||
|
padding: theme.spacing(3),
|
||||||
|
maxWidth: '400px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
position: 'relative',
|
||||||
|
...contentSpacingY(theme),
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip title="Close" arrow>
|
<Tooltip title="Close" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={styles.close}
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
right: '-38px',
|
||||||
|
top: '-47px',
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
boxShadow:
|
||||||
|
'2px 2px 4px 4px rgba(143,143,143, 0.25)',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
},
|
||||||
|
}}
|
||||||
onClick={() => setShowFeedback(false)}
|
onClick={() => setShowFeedback(false)}
|
||||||
size="large"
|
size="large"
|
||||||
>
|
>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Logo className={styles.logo} />
|
<Logo
|
||||||
|
style={{
|
||||||
|
width: '25px',
|
||||||
|
height: '25px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={answeredNotNow}
|
condition={answeredNotNow}
|
||||||
show={
|
show={
|
||||||
@ -99,7 +135,7 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<Box>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={answeredNotNow}
|
condition={answeredNotNow}
|
||||||
show={
|
show={
|
||||||
@ -120,7 +156,10 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => {
|
|||||||
Yes, no problem
|
Yes, no problem
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={styles.cancel}
|
sx={{
|
||||||
|
marginLeft: theme =>
|
||||||
|
theme.spacing(2),
|
||||||
|
}}
|
||||||
onClick={() => setAnsweredNotNow(true)}
|
onClick={() => setAnsweredNotNow(true)}
|
||||||
>
|
>
|
||||||
Not now
|
Not now
|
||||||
@ -128,9 +167,9 @@ export const FeedbackNPS = ({ openUrl }: IFeedbackNPSProps) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Box>
|
||||||
</div>
|
</Box>
|
||||||
</div>
|
</Box>
|
||||||
</AnimateOnMount>
|
</AnimateOnMount>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@ import Proclamation from 'component/common/Proclamation/Proclamation';
|
|||||||
import BreadcrumbNav from 'component/common/BreadcrumbNav/BreadcrumbNav';
|
import BreadcrumbNav from 'component/common/BreadcrumbNav/BreadcrumbNav';
|
||||||
import textureImage from 'assets/img/texture.png';
|
import textureImage from 'assets/img/texture.png';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { SkipNavLink } from 'component/common/SkipNav/SkipNavLink';
|
import { SkipNavLink } from 'component/common/SkipNavLink/SkipNavLink';
|
||||||
import { SkipNavTarget } from 'component/common/SkipNav/SkipNavTarget';
|
import { SkipNavTarget } from 'component/common/SkipNavLink/SkipNavTarget';
|
||||||
import { formatAssetPath } from 'utils/formatPath';
|
import { formatAssetPath } from 'utils/formatPath';
|
||||||
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
|
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
@ -32,14 +32,14 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
className="css-j2179i"
|
className="css-j2179i"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1oozr04-container"
|
className="css-uds21r"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1xjrf9m-search search-container"
|
className="css-19ebc6o"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium search-icon css-1kyy7n4-MuiSvgIcon-root-searchIcon"
|
className="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-1dfm5ba-MuiSvgIcon-root"
|
||||||
data-testid="SearchIcon"
|
data-testid="SearchIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -49,7 +49,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div
|
<div
|
||||||
className="MuiInputBase-root input-container MuiInputBase-colorPrimary css-tubodl-MuiInputBase-root-inputRoot"
|
className="MuiInputBase-root MuiInputBase-colorPrimary css-1vp7ju7-MuiInputBase-root"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@ -65,7 +65,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="css-llttyo-clearContainer clear-container"
|
className="MuiBox-root css-1ty7gog"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -112,7 +112,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
className="body css-ccg7sp-bodyContainer"
|
className="body css-ccg7sp-bodyContainer"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
className="MuiTable-root css-1h6dscb-MuiTable-root-table"
|
className="MuiTable-root css-1repbac-MuiTable-root"
|
||||||
role="table"
|
role="table"
|
||||||
>
|
>
|
||||||
<thead
|
<thead
|
||||||
@ -120,11 +120,11 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
role={null}
|
role={null}
|
||||||
>
|
>
|
||||||
<tr
|
<tr
|
||||||
className="MuiTableRow-root MuiTableRow-head css-1gnoged-MuiTableRow-root-tableHeader"
|
className="MuiTableRow-root MuiTableRow-head css-1b9hsk7-MuiTableRow-root"
|
||||||
role="row"
|
role="row"
|
||||||
>
|
>
|
||||||
<th
|
<th
|
||||||
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-b9leyc-MuiTableCell-root-header"
|
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-uzyimr-MuiTableCell-root"
|
||||||
scope="col"
|
scope="col"
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -140,7 +140,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
aria-sort="ascending"
|
aria-sort="ascending"
|
||||||
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-masipn-MuiTableCell-root-header-sortable"
|
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-1ts7or6-MuiTableCell-root"
|
||||||
scope="col"
|
scope="col"
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -153,7 +153,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
<button
|
<button
|
||||||
aria-label=""
|
aria-label=""
|
||||||
aria-labelledby={null}
|
aria-labelledby={null}
|
||||||
className="css-14l86a5-sortedButton css-1inbba3-sortButton"
|
className=" css-1xwc11x"
|
||||||
data-mui-internal-clone-element={true}
|
data-mui-internal-clone-element={true}
|
||||||
onBlur={[Function]}
|
onBlur={[Function]}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
@ -166,10 +166,10 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="css-r8z9jm-hiddenMeasurementLayer"
|
className="css-15yxmxx"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-1j5tskk-label"
|
className="css-1w3kvnb"
|
||||||
data-text="Name"
|
data-text="Name"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
>
|
>
|
||||||
@ -177,7 +177,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="MuiSvgIcon-root MuiSvgIcon-fontSizeInherit css-1ekkz6x-MuiSvgIcon-root-icon-sorted"
|
className="MuiSvgIcon-root MuiSvgIcon-fontSizeInherit css-57xzpo-MuiSvgIcon-root"
|
||||||
data-testid="KeyboardArrowUpIcon"
|
data-testid="KeyboardArrowUpIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -188,7 +188,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="css-bqel7i-visibleAbsoluteLayer"
|
className="css-y8b3t8"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
@ -199,7 +199,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
<svg
|
<svg
|
||||||
aria-hidden={true}
|
aria-hidden={true}
|
||||||
className="MuiSvgIcon-root MuiSvgIcon-fontSizeInherit sort-arrow css-1ekkz6x-MuiSvgIcon-root-icon-sorted"
|
className="MuiSvgIcon-root MuiSvgIcon-fontSizeInherit sort-arrow css-57xzpo-MuiSvgIcon-root"
|
||||||
data-testid="KeyboardArrowUpIcon"
|
data-testid="KeyboardArrowUpIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -212,7 +212,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-b9leyc-MuiTableCell-root-header"
|
className="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-uzyimr-MuiTableCell-root"
|
||||||
scope="col"
|
scope="col"
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -223,7 +223,12 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1x6va6g-alignCenter"
|
style={
|
||||||
|
{
|
||||||
|
"justifyContent": "center",
|
||||||
|
"textAlign": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Actions
|
Actions
|
||||||
</div>
|
</div>
|
||||||
@ -240,7 +245,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -262,17 +267,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
className="css-g3rrgy-wrapper"
|
className="css-1prhjm6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1sfnvgj-container"
|
className="css-u8cmsa"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-lcjmxf-title"
|
className="css-697v50"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -284,17 +289,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
Tag type name
|
Tag type name
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="MuiTypography-root MuiTypography-body1 css-kyf98y-MuiTypography-root-description"
|
className="css-1121jr7"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
Tag type description when loading
|
Tag type description when loading
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -410,7 +415,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -432,17 +437,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
className="css-g3rrgy-wrapper"
|
className="css-1prhjm6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1sfnvgj-container"
|
className="css-u8cmsa"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-lcjmxf-title"
|
className="css-697v50"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -454,17 +459,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
Tag type name
|
Tag type name
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="MuiTypography-root MuiTypography-body1 css-kyf98y-MuiTypography-root-description"
|
className="css-1121jr7"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
Tag type description when loading
|
Tag type description when loading
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -580,7 +585,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -602,17 +607,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
className="css-g3rrgy-wrapper"
|
className="css-1prhjm6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1sfnvgj-container"
|
className="css-u8cmsa"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-lcjmxf-title"
|
className="css-697v50"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -624,17 +629,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
Tag type name
|
Tag type name
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="MuiTypography-root MuiTypography-body1 css-kyf98y-MuiTypography-root-description"
|
className="css-1121jr7"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
Tag type description when loading
|
Tag type description when loading
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -750,7 +755,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -772,17 +777,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
className="css-g3rrgy-wrapper"
|
className="css-1prhjm6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1sfnvgj-container"
|
className="css-u8cmsa"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-lcjmxf-title"
|
className="css-697v50"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -794,17 +799,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
Tag type name
|
Tag type name
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="MuiTypography-root MuiTypography-body1 css-kyf98y-MuiTypography-root-description"
|
className="css-1121jr7"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
Tag type description when loading
|
Tag type description when loading
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -920,7 +925,7 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -942,17 +947,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
className="css-g3rrgy-wrapper"
|
className="css-1prhjm6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="css-1sfnvgj-container"
|
className="css-u8cmsa"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="css-lcjmxf-title"
|
className="css-697v50"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
@ -964,17 +969,17 @@ exports[`renders an empty list correctly 1`] = `
|
|||||||
Tag type name
|
Tag type name
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="MuiTypography-root MuiTypography-body1 css-kyf98y-MuiTypography-root-description"
|
className="css-1121jr7"
|
||||||
data-loading={true}
|
data-loading={true}
|
||||||
>
|
>
|
||||||
Tag type description when loading
|
Tag type description when loading
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
aria-sort={null}
|
aria-sort={null}
|
||||||
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-fv4mw1-MuiTableCell-root-tableCell"
|
className="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-iiibbc-MuiTableCell-root"
|
||||||
role="cell"
|
role="cell"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { makeStyles } from 'tss-react/mui';
|
||||||
import { Theme } from '@mui/material';
|
import { Theme } from '@mui/material';
|
||||||
|
import { CSSProperties } from 'react';
|
||||||
|
|
||||||
export const focusable = (theme: Theme) => ({
|
export const focusable = (theme: Theme) => ({
|
||||||
'&:focus-visible': {
|
'&:focus-visible': {
|
||||||
@ -51,6 +52,54 @@ export const defaultBorderRadius = (theme: Theme) => ({
|
|||||||
borderRadius: `${theme.shape.borderRadius}px`,
|
borderRadius: `${theme.shape.borderRadius}px`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const fadeInBottomStart = () => ({
|
||||||
|
opacity: '0',
|
||||||
|
position: 'fixed',
|
||||||
|
right: '40px',
|
||||||
|
bottom: '40px',
|
||||||
|
transform: 'translateY(400px)',
|
||||||
|
});
|
||||||
|
export const fadeInBottomStartWithoutFixed: CSSProperties = {
|
||||||
|
opacity: '0',
|
||||||
|
right: '40px',
|
||||||
|
bottom: '40px',
|
||||||
|
transform: 'translateY(400px)',
|
||||||
|
zIndex: 1400,
|
||||||
|
position: 'fixed',
|
||||||
|
};
|
||||||
|
export const fadeInBottomEnter: CSSProperties = {
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
opacity: '1',
|
||||||
|
transition: 'transform 0.6s ease, opacity 1s ease',
|
||||||
|
};
|
||||||
|
export const fadeInBottomLeave: CSSProperties = {
|
||||||
|
transform: 'translateY(400px)',
|
||||||
|
opacity: '0',
|
||||||
|
transition: 'transform 1.25s ease, opacity 1s ease',
|
||||||
|
};
|
||||||
|
export const fadeInTopStart = (theme: Theme): CSSProperties => ({
|
||||||
|
opacity: '0',
|
||||||
|
position: 'fixed',
|
||||||
|
right: '40px',
|
||||||
|
top: '40px',
|
||||||
|
transform: 'translateY(-400px)',
|
||||||
|
[theme.breakpoints.down('sm')]: {
|
||||||
|
right: 20,
|
||||||
|
left: 10,
|
||||||
|
top: 40,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const fadeInTopEnter: CSSProperties = {
|
||||||
|
transform: 'translateY(100px)',
|
||||||
|
opacity: '1',
|
||||||
|
transition: 'transform 0.6s ease, opacity 1s ease',
|
||||||
|
};
|
||||||
|
export const fadeInTopLeave: CSSProperties = {
|
||||||
|
transform: 'translateY(-400px)',
|
||||||
|
opacity: '0',
|
||||||
|
transition: 'transform 1.25s ease, opacity 1s ease',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Please extract styles below into MUI fragments as shown above
|
* Please extract styles below into MUI fragments as shown above
|
||||||
* @deprecated
|
* @deprecated
|
||||||
@ -117,53 +166,6 @@ export const useThemeStyles = makeStyles()(theme => ({
|
|||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
marginBottom: '0.5rem',
|
marginBottom: '0.5rem',
|
||||||
},
|
},
|
||||||
fadeInBottomStart: {
|
|
||||||
opacity: '0',
|
|
||||||
position: 'fixed',
|
|
||||||
right: '40px',
|
|
||||||
bottom: '40px',
|
|
||||||
transform: 'translateY(400px)',
|
|
||||||
},
|
|
||||||
fadeInBottomStartWithoutFixed: {
|
|
||||||
opacity: '0',
|
|
||||||
right: '40px',
|
|
||||||
bottom: '40px',
|
|
||||||
transform: 'translateY(400px)',
|
|
||||||
zIndex: 1400,
|
|
||||||
position: 'fixed',
|
|
||||||
},
|
|
||||||
fadeInBottomEnter: {
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
opacity: '1',
|
|
||||||
transition: 'transform 0.6s ease, opacity 1s ease',
|
|
||||||
},
|
|
||||||
fadeInBottomLeave: {
|
|
||||||
transform: 'translateY(400px)',
|
|
||||||
opacity: '0',
|
|
||||||
transition: 'transform 1.25s ease, opacity 1s ease',
|
|
||||||
},
|
|
||||||
fadeInTopStart: {
|
|
||||||
opacity: '0',
|
|
||||||
position: 'fixed',
|
|
||||||
right: '40px',
|
|
||||||
top: '40px',
|
|
||||||
transform: 'translateY(-400px)',
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
right: 20,
|
|
||||||
left: 10,
|
|
||||||
top: 40,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fadeInTopEnter: {
|
|
||||||
transform: 'translateY(100px)',
|
|
||||||
opacity: '1',
|
|
||||||
transition: 'transform 0.6s ease, opacity 1s ease',
|
|
||||||
},
|
|
||||||
fadeInTopLeave: {
|
|
||||||
transform: 'translateY(-400px)',
|
|
||||||
opacity: '0',
|
|
||||||
transition: 'transform 1.25s ease, opacity 1s ease',
|
|
||||||
},
|
|
||||||
error: {
|
error: {
|
||||||
fontSize: theme.fontSizes.smallBody,
|
fontSize: theme.fontSizes.smallBody,
|
||||||
color: theme.palette.error.main,
|
color: theme.palette.error.main,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FC, ElementType } from 'react';
|
import { FC } from 'react';
|
||||||
import { SvgIcon, useTheme } from '@mui/material';
|
import { SvgIcon, useTheme } from '@mui/material';
|
||||||
import LocationOnIcon from '@mui/icons-material/LocationOn';
|
import LocationOnIcon from '@mui/icons-material/LocationOn';
|
||||||
import PeopleIcon from '@mui/icons-material/People';
|
import PeopleIcon from '@mui/icons-material/People';
|
||||||
@ -19,7 +19,7 @@ const RolloutSvgIcon: FC = props => (
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getFeatureStrategyIcon = (strategyName: string): ElementType => {
|
export const getFeatureStrategyIcon = (strategyName: string) => {
|
||||||
switch (strategyName) {
|
switch (strategyName) {
|
||||||
case 'default':
|
case 'default':
|
||||||
return PowerSettingsNewIcon;
|
return PowerSettingsNewIcon;
|
||||||
|
Loading…
Reference in New Issue
Block a user