mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Refactored feature toggles table (#951)
* refactor: simplify table toolbar * refactor: table links and padding * fix: header icons colors * fix: minor table style changes
This commit is contained in:
parent
7785e2c717
commit
5ecc83f1b4
@ -4,6 +4,9 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
tableCellHeaderSortable: {
|
tableCellHeaderSortable: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
'&:hover, &:focus': {
|
||||||
|
backgroundColor: theme.palette.grey[400],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
sortButton: {
|
sortButton: {
|
||||||
all: 'unset',
|
all: 'unset',
|
||||||
@ -15,9 +18,6 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
},
|
},
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: theme.palette.grey[400],
|
|
||||||
},
|
|
||||||
boxSizing: 'inherit',
|
boxSizing: 'inherit',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
},
|
||||||
|
@ -14,8 +14,4 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
icon: {
|
|
||||||
marginLeft: theme.spacing(0.5),
|
|
||||||
fontSize: 18,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
8
frontend/src/component/common/Table/Table.tsx
Normal file
8
frontend/src/component/common/Table/Table.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { Box, Table as MUITable } from '@mui/material';
|
||||||
|
|
||||||
|
export const Table: FC = ({ children }) => (
|
||||||
|
<Box sx={{ p: 4, pb: 0 }}>
|
||||||
|
<MUITable>{children}</MUITable>
|
||||||
|
</Box>
|
||||||
|
);
|
@ -14,6 +14,9 @@ interface ITableActionsProps {
|
|||||||
isSeparated?: boolean;
|
isSeparated?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
export const TableActions: FC<ITableActionsProps> = ({
|
export const TableActions: FC<ITableActionsProps> = ({
|
||||||
initialSearchValue: search,
|
initialSearchValue: search,
|
||||||
onSearch = () => {},
|
onSearch = () => {},
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
import { makeStyles } from 'tss-react/mui';
|
||||||
|
|
||||||
|
export const useStyles = makeStyles()(theme => ({
|
||||||
|
tableCell: {
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
}));
|
@ -0,0 +1,9 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { TableCell as MUITableCell, TableCellProps } from '@mui/material';
|
||||||
|
import { useStyles } from './TableCell.styles';
|
||||||
|
|
||||||
|
export const TableCell: FC<TableCellProps> = ({ ...props }) => {
|
||||||
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
|
return <MUITableCell className={styles.tableCell} {...props} />;
|
||||||
|
};
|
@ -7,8 +7,4 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
borderRadius: theme.spacing(1.5),
|
borderRadius: theme.spacing(1.5),
|
||||||
paddingBottom: theme.spacing(4),
|
paddingBottom: theme.spacing(4),
|
||||||
},
|
},
|
||||||
content: {
|
|
||||||
padding: theme.spacing(4),
|
|
||||||
paddingBottom: 0,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
@ -0,0 +1,15 @@
|
|||||||
|
import { forwardRef } from 'react';
|
||||||
|
import { Paper, PaperProps } from '@mui/material';
|
||||||
|
import { useStyles } from './TableContainer.styles';
|
||||||
|
|
||||||
|
export const TableContainer = forwardRef<HTMLDivElement, PaperProps>(
|
||||||
|
({ children, ...props }, ref) => {
|
||||||
|
const { classes } = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper ref={ref} className={classes.panel} {...props}>
|
||||||
|
{children}
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
@ -1,18 +0,0 @@
|
|||||||
import { forwardRef, ReactNode } from 'react';
|
|
||||||
import { Paper } from '@mui/material';
|
|
||||||
import { Box } from '@mui/material';
|
|
||||||
import { useStyles } from './TablePanel.styles';
|
|
||||||
|
|
||||||
export const TablePanel = forwardRef<
|
|
||||||
HTMLDivElement,
|
|
||||||
{ children: ReactNode; header?: ReactNode }
|
|
||||||
>(({ header, children, ...props }, ref) => {
|
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Paper ref={ref} className={styles.panel} {...props}>
|
|
||||||
{header}
|
|
||||||
<Box className={styles.content}>{children}</Box>
|
|
||||||
</Paper>
|
|
||||||
);
|
|
||||||
});
|
|
@ -8,7 +8,6 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginTop: theme.spacing(4),
|
margin: theme.spacing(4),
|
||||||
marginBottom: theme.spacing(4),
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -2,10 +2,8 @@ import { FC } from 'react';
|
|||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import { useStyles } from 'component/common/Table/TablePlaceholder/TablePlaceholder.styles';
|
import { useStyles } from 'component/common/Table/TablePlaceholder/TablePlaceholder.styles';
|
||||||
|
|
||||||
const TablePlaceholder: FC = ({ children }) => {
|
export const TablePlaceholder: FC = ({ children }) => {
|
||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
return <Box className={styles.emptyStateListItem}>{children}</Box>;
|
return <Box className={styles.emptyStateListItem}>{children}</Box>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TablePlaceholder;
|
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
import { makeStyles } from 'tss-react/mui';
|
||||||
|
|
||||||
|
export const useStyles = makeStyles()(theme => ({
|
||||||
|
searchField: {
|
||||||
|
width: '45px',
|
||||||
|
'& .search-icon': {
|
||||||
|
marginRight: 0,
|
||||||
|
},
|
||||||
|
'& .input-container, .clear-container': {
|
||||||
|
width: 0,
|
||||||
|
},
|
||||||
|
'& input::placeholder': {
|
||||||
|
color: 'transparent',
|
||||||
|
transition: 'color 0.6s',
|
||||||
|
},
|
||||||
|
'& input:focus-within::placeholder': {
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchFieldEnter: {
|
||||||
|
width: '250px',
|
||||||
|
transition: 'width 0.6s',
|
||||||
|
'& .search-icon': {
|
||||||
|
marginRight: '8px',
|
||||||
|
},
|
||||||
|
'& .input-container': {
|
||||||
|
width: '100%',
|
||||||
|
transition: 'width 0.6s',
|
||||||
|
},
|
||||||
|
'& .clear-container': {
|
||||||
|
width: '30px',
|
||||||
|
transition: 'width 0.6s',
|
||||||
|
},
|
||||||
|
'& .search-container': {
|
||||||
|
borderColor: theme.palette.grey[300],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchFieldLeave: {
|
||||||
|
width: '45px',
|
||||||
|
transition: 'width 0.6s',
|
||||||
|
'& .search-icon': {
|
||||||
|
marginRight: 0,
|
||||||
|
transition: 'margin-right 0.6s',
|
||||||
|
},
|
||||||
|
'& .input-container, .clear-container': {
|
||||||
|
width: 0,
|
||||||
|
transition: 'width 0.6s',
|
||||||
|
},
|
||||||
|
'& .search-container': {
|
||||||
|
borderColor: 'transparent',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchButton: {
|
||||||
|
marginTop: '-4px',
|
||||||
|
marginBottom: '-4px',
|
||||||
|
marginRight: '-4px',
|
||||||
|
marginLeft: '-4px',
|
||||||
|
},
|
||||||
|
}));
|
@ -0,0 +1,75 @@
|
|||||||
|
import { FC, useState } from 'react';
|
||||||
|
import { IconButton, Tooltip } from '@mui/material';
|
||||||
|
import { Search } from '@mui/icons-material';
|
||||||
|
import { useAsyncDebounce } from 'react-table';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import AnimateOnMount from 'component/common/AnimateOnMount/AnimateOnMount';
|
||||||
|
import { TableSearchField } from './TableSearchField/TableSearchField';
|
||||||
|
import { useStyles } from './TableSearch.styles';
|
||||||
|
|
||||||
|
interface ITableSearchProps {
|
||||||
|
initialValue?: string;
|
||||||
|
onChange?: (value: string) => void;
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TableSearch: FC<ITableSearchProps> = ({
|
||||||
|
initialValue,
|
||||||
|
onChange = () => {},
|
||||||
|
placeholder = 'Search',
|
||||||
|
}) => {
|
||||||
|
const [searchInputState, setSearchInputState] = useState(initialValue);
|
||||||
|
const [isSearchExpanded, setIsSearchExpanded] = useState(
|
||||||
|
Boolean(initialValue)
|
||||||
|
);
|
||||||
|
const [isAnimating, setIsAnimating] = useState(false);
|
||||||
|
const debouncedOnSearch = useAsyncDebounce(onChange, 200);
|
||||||
|
|
||||||
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
|
const onBlur = (clear = false) => {
|
||||||
|
if (!searchInputState || clear) {
|
||||||
|
setIsSearchExpanded(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSearchChange = (value: string) => {
|
||||||
|
debouncedOnSearch(value);
|
||||||
|
setSearchInputState(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AnimateOnMount
|
||||||
|
mounted={isSearchExpanded}
|
||||||
|
start={styles.searchField}
|
||||||
|
enter={styles.searchFieldEnter}
|
||||||
|
leave={styles.searchFieldLeave}
|
||||||
|
onStart={() => setIsAnimating(true)}
|
||||||
|
onEnd={() => setIsAnimating(false)}
|
||||||
|
>
|
||||||
|
<TableSearchField
|
||||||
|
value={searchInputState!}
|
||||||
|
onChange={onSearchChange}
|
||||||
|
placeholder={`${placeholder}…`}
|
||||||
|
onBlur={onBlur}
|
||||||
|
/>
|
||||||
|
</AnimateOnMount>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={!isSearchExpanded && !isAnimating}
|
||||||
|
show={
|
||||||
|
<Tooltip title={placeholder} arrow>
|
||||||
|
<IconButton
|
||||||
|
aria-label={placeholder}
|
||||||
|
onClick={() => setIsSearchExpanded(true)}
|
||||||
|
size="large"
|
||||||
|
className={styles.searchButton}
|
||||||
|
>
|
||||||
|
<Search />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,43 @@
|
|||||||
|
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.paper,
|
||||||
|
border: `1px solid ${theme.palette.grey[300]}`,
|
||||||
|
borderRadius: '25px',
|
||||||
|
padding: '3px 5px 3px 12px',
|
||||||
|
maxWidth: '450px',
|
||||||
|
[theme.breakpoints.down('sm')]: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
'&.search-container:focus-within': {
|
||||||
|
borderColor: theme.palette.primary.light,
|
||||||
|
boxShadow: theme.boxShadows.main,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
searchIcon: {
|
||||||
|
marginRight: 8,
|
||||||
|
color: theme.palette.grey[600],
|
||||||
|
},
|
||||||
|
clearContainer: {
|
||||||
|
width: '30px',
|
||||||
|
'& > button': {
|
||||||
|
padding: '7px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
clearIcon: {
|
||||||
|
color: theme.palette.grey[600],
|
||||||
|
fontSize: '18px',
|
||||||
|
},
|
||||||
|
inputRoot: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
}));
|
@ -0,0 +1,73 @@
|
|||||||
|
import { IconButton, InputBase, Tooltip } from '@mui/material';
|
||||||
|
import { Search, Close } from '@mui/icons-material';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useStyles } from './TableSearchField.styles';
|
||||||
|
|
||||||
|
interface ITableSearchFieldProps {
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
className?: string;
|
||||||
|
placeholder: string;
|
||||||
|
onBlur?: (clear?: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TableSearchField = ({
|
||||||
|
value = '',
|
||||||
|
onChange,
|
||||||
|
className,
|
||||||
|
placeholder,
|
||||||
|
onBlur,
|
||||||
|
}: ITableSearchFieldProps) => {
|
||||||
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div
|
||||||
|
className={classnames(
|
||||||
|
styles.search,
|
||||||
|
className,
|
||||||
|
'search-container'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Search
|
||||||
|
className={classnames(styles.searchIcon, 'search-icon')}
|
||||||
|
/>
|
||||||
|
<InputBase
|
||||||
|
autoFocus
|
||||||
|
placeholder={placeholder}
|
||||||
|
classes={{
|
||||||
|
root: classnames(styles.inputRoot, 'input-container'),
|
||||||
|
}}
|
||||||
|
inputProps={{ 'aria-label': placeholder }}
|
||||||
|
value={value}
|
||||||
|
onChange={e => onChange(e.target.value)}
|
||||||
|
onBlur={() => onBlur?.()}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={classnames(
|
||||||
|
styles.clearContainer,
|
||||||
|
'clear-container'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(value)}
|
||||||
|
show={
|
||||||
|
<Tooltip title="Clear search query" arrow>
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
onChange('');
|
||||||
|
onBlur?.(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Close className={styles.clearIcon} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,12 +1,30 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { makeStyles } from 'tss-react/mui';
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const useStyles = makeStyles()(theme => ({
|
||||||
root: {
|
toolbar: {
|
||||||
paddingLeft: theme.spacing(4),
|
paddingLeft: theme.spacing(4),
|
||||||
paddingRight: theme.spacing(4),
|
paddingRight: theme.spacing(4),
|
||||||
paddingTop: theme.spacing(2.5),
|
paddingTop: theme.spacing(2),
|
||||||
paddingBottom: theme.spacing(2.5),
|
paddingBottom: theme.spacing(2),
|
||||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||||
justifyContent: 'space-between',
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
flex: 1,
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
verticalSeparator: {
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: theme.palette.grey[500],
|
||||||
|
width: '1px',
|
||||||
|
display: 'inline-block',
|
||||||
|
marginLeft: theme.spacing(2),
|
||||||
|
marginRight: theme.spacing(4),
|
||||||
|
padding: '10px 0',
|
||||||
|
verticalAlign: 'middle',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
import { FC } from 'react';
|
import { FC, VFC } from 'react';
|
||||||
import { Toolbar, Typography } from '@mui/material';
|
import { Box, Toolbar, Typography } from '@mui/material';
|
||||||
import { useStyles } from './TableToolbar.styles';
|
import { useStyles } from './TableToolbar.styles';
|
||||||
|
|
||||||
interface ITableToolbarProps {
|
interface ITableToolbarProps {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TableToolbar: FC<ITableToolbarProps> = ({ title, children }) => {
|
export const TableToolbarComponent: FC<ITableToolbarProps> & {
|
||||||
|
Divider: VFC;
|
||||||
|
} = ({ title, children }) => {
|
||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Toolbar className={styles.root}>
|
<Toolbar className={styles.toolbar}>
|
||||||
<Typography variant="h1" component="h1" data-loading>
|
<Typography variant="h1" data-loading>
|
||||||
{title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
{children}
|
<Box className={styles.actions}>{children}</Box>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Divider: VFC = () => {
|
||||||
|
const { classes: styles } = useStyles();
|
||||||
|
|
||||||
|
return <Box className={styles.verticalSeparator} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
TableToolbarComponent.Divider = Divider;
|
||||||
|
|
||||||
|
export const TableToolbar = TableToolbarComponent;
|
||||||
|
8
frontend/src/component/common/Table/index.ts
Normal file
8
frontend/src/component/common/Table/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export { TableContainer } from './TableContainer/TableContainer';
|
||||||
|
export { TableToolbar } from './TableToolbar/TableToolbar';
|
||||||
|
export { TableSearch } from './TableSearch/TableSearch';
|
||||||
|
export { Table } from './Table';
|
||||||
|
export { SortableTableHeader } from './SortableTableHeader/SortableTableHeader';
|
||||||
|
export { TableBody, TableRow } from '@mui/material';
|
||||||
|
export { TableCell } from './TableCell/TableCell';
|
||||||
|
export { TablePlaceholder } from './TablePlaceholder/TablePlaceholder';
|
@ -2,7 +2,7 @@ import { useFeatures } from 'hooks/api/getters/useFeatures/useFeatures';
|
|||||||
import { FeatureSchema } from 'openapi';
|
import { FeatureSchema } from 'openapi';
|
||||||
import { FeatureToggleListTable } from './FeatureToggleListTable/FeatureToggleListTable';
|
import { FeatureToggleListTable } from './FeatureToggleListTable/FeatureToggleListTable';
|
||||||
|
|
||||||
const featuresPlaceholder: FeatureSchema[] = Array(7).fill({
|
const featuresPlaceholder: FeatureSchema[] = Array(15).fill({
|
||||||
name: 'Name of the feature',
|
name: 'Name of the feature',
|
||||||
description: 'Short description of the feature',
|
description: 'Short description of the feature',
|
||||||
type: '-',
|
type: '-',
|
||||||
|
@ -2,7 +2,7 @@ import { VFC } from 'react';
|
|||||||
import { useLocationSettings } from 'hooks/useLocationSettings';
|
import { useLocationSettings } from 'hooks/useLocationSettings';
|
||||||
import { formatDateYMD, formatDateYMDHMS } from 'utils/formatDate';
|
import { formatDateYMD, formatDateYMDHMS } from 'utils/formatDate';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { Tooltip } from '@mui/material';
|
import { Box, Tooltip } from '@mui/material';
|
||||||
|
|
||||||
interface IDateCellProps {
|
interface IDateCellProps {
|
||||||
value?: Date | null;
|
value?: Date | null;
|
||||||
@ -12,21 +12,26 @@ export const DateCell: VFC<IDateCellProps> = ({ value }) => {
|
|||||||
const { locationSettings } = useLocationSettings();
|
const { locationSettings } = useLocationSettings();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionallyRender
|
<Box sx={{ py: 1.5, px: 2 }}>
|
||||||
condition={Boolean(value)}
|
<ConditionallyRender
|
||||||
show={
|
condition={Boolean(value)}
|
||||||
<Tooltip
|
show={
|
||||||
title={formatDateYMDHMS(
|
<Tooltip
|
||||||
value as Date,
|
title={formatDateYMDHMS(
|
||||||
locationSettings.locale
|
value as Date,
|
||||||
)}
|
locationSettings.locale
|
||||||
arrow
|
)}
|
||||||
>
|
arrow
|
||||||
<span data-loading>
|
>
|
||||||
{formatDateYMD(value as Date, locationSettings.locale)}
|
<span data-loading role="tooltip">
|
||||||
</span>
|
{formatDateYMD(
|
||||||
</Tooltip>
|
value as Date,
|
||||||
}
|
locationSettings.locale
|
||||||
/>
|
)}
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { makeStyles } from 'tss-react/mui';
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const useStyles = makeStyles()(theme => ({
|
||||||
|
container: {
|
||||||
|
paddingTop: theme.spacing(1.5),
|
||||||
|
paddingBottom: theme.spacing(1.5),
|
||||||
|
paddingLeft: theme.spacing(2),
|
||||||
|
paddingRight: theme.spacing(2),
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
minHeight: '62px',
|
||||||
|
},
|
||||||
description: {
|
description: {
|
||||||
color: theme.palette.grey[800],
|
color: theme.palette.grey[800],
|
||||||
fontSize: 'inherit',
|
fontSize: 'inherit',
|
@ -0,0 +1,55 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { Link, Typography } from '@mui/material';
|
||||||
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useStyles } from './FeatureLinkCell.styles';
|
||||||
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
|
|
||||||
|
interface IFeatureLinkCellProps {
|
||||||
|
title?: string;
|
||||||
|
to: string;
|
||||||
|
subtitle?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FeatureLinkCell: FC<IFeatureLinkCellProps> = ({
|
||||||
|
title,
|
||||||
|
to,
|
||||||
|
subtitle,
|
||||||
|
}) => {
|
||||||
|
const { classes: styles } = useStyles();
|
||||||
|
const search = useSearchHighlightContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
component={RouterLink}
|
||||||
|
to={to}
|
||||||
|
underline="hover"
|
||||||
|
className={styles.container}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span data-loading>
|
||||||
|
<Highlighter search={search}>{title}</Highlighter>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(subtitle)}
|
||||||
|
show={
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<Typography
|
||||||
|
className={styles.description}
|
||||||
|
component="span"
|
||||||
|
data-loading
|
||||||
|
>
|
||||||
|
<Highlighter search={search}>
|
||||||
|
{subtitle}
|
||||||
|
</Highlighter>
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
@ -1,53 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { Link, Typography } from '@mui/material';
|
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { useStyles } from './FeatureNameCell.styles';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
|
||||||
|
|
||||||
interface IFeatureNameCellProps {
|
|
||||||
name?: string;
|
|
||||||
project?: string;
|
|
||||||
description?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FeatureNameCell: FC<IFeatureNameCellProps> = ({
|
|
||||||
name,
|
|
||||||
project,
|
|
||||||
description,
|
|
||||||
}) => {
|
|
||||||
const { classes: styles } = useStyles();
|
|
||||||
const search = useSearchHighlightContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Link
|
|
||||||
component={RouterLink}
|
|
||||||
to={`/projects/${project}/features/${name}`}
|
|
||||||
underline="hover"
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Highlighter search={search}>{name}</Highlighter>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(description)}
|
|
||||||
show={
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
<Typography
|
|
||||||
className={styles.description}
|
|
||||||
component="span"
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Highlighter search={search}>
|
|
||||||
{description}
|
|
||||||
</Highlighter>
|
|
||||||
</Typography>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -2,6 +2,10 @@ import { makeStyles } from 'tss-react/mui';
|
|||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const useStyles = makeStyles()(theme => ({
|
||||||
container: {
|
container: {
|
||||||
|
display: 'flex',
|
||||||
|
padding: theme.spacing(1.5),
|
||||||
|
},
|
||||||
|
box: {
|
||||||
width: '38px',
|
width: '38px',
|
||||||
height: '38px',
|
height: '38px',
|
||||||
background: 'gray',
|
background: 'gray',
|
||||||
|
@ -63,15 +63,18 @@ const Wrapper: FC<{ unit?: string; tooltip: string }> = ({
|
|||||||
const getColor = useFeatureColor();
|
const getColor = useFeatureColor();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={tooltip} arrow>
|
<div className={styles.container}>
|
||||||
<div
|
<Tooltip title={tooltip} arrow describeChild>
|
||||||
className={styles.container}
|
<div
|
||||||
style={{ background: getColor(unit) }}
|
role="tooltip"
|
||||||
data-loading
|
className={styles.box}
|
||||||
>
|
style={{ background: getColor(unit) }}
|
||||||
{children}
|
data-loading
|
||||||
</div>
|
>
|
||||||
</Tooltip>
|
{children}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
import { useStyles } from './FeatureStaleCell.styles';
|
import { useStyles } from './FeatureStaleCell.styles';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
@ -10,12 +10,14 @@ interface IFeatureStaleCellProps {
|
|||||||
export const FeatureStaleCell: VFC<IFeatureStaleCellProps> = ({ value }) => {
|
export const FeatureStaleCell: VFC<IFeatureStaleCellProps> = ({ value }) => {
|
||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
return (
|
return (
|
||||||
<Typography
|
<Box sx={{ py: 1.5, px: 2 }}>
|
||||||
component="span"
|
<Typography
|
||||||
className={classnames(styles.status, value && styles.stale)}
|
component="span"
|
||||||
data-loading
|
className={classnames(styles.status, value && styles.stale)}
|
||||||
>
|
data-loading
|
||||||
{value ? 'Stale' : 'Active'}
|
>
|
||||||
</Typography>
|
{value ? 'Stale' : 'Active'}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,28 +1,25 @@
|
|||||||
import { useEffect, useMemo, VFC } from 'react';
|
import { useEffect, useMemo, VFC } from 'react';
|
||||||
import {
|
import { Link, useMediaQuery, useTheme } from '@mui/material';
|
||||||
Link,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableRow,
|
|
||||||
useMediaQuery,
|
|
||||||
useTheme,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
import { useGlobalFilter, useSortBy, useTable } from 'react-table';
|
import { useGlobalFilter, useSortBy, useTable } from 'react-table';
|
||||||
import useLoading from 'hooks/useLoading';
|
import useLoading from 'hooks/useLoading';
|
||||||
import { SortableTableHeader } from 'component/common/Table/SortableTableHeader/SortableTableHeader';
|
import {
|
||||||
import { TableActions } from 'component/common/Table/TableActions/TableActions';
|
TableContainer,
|
||||||
import { TablePanel } from 'component/common/Table/TablePanel/TablePanel';
|
TableToolbar,
|
||||||
import { TableToolbar } from 'component/common/Table/TableToolbar/TableToolbar';
|
Table,
|
||||||
import TablePlaceholder from 'component/common/Table/TablePlaceholder/TablePlaceholder';
|
SortableTableHeader,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
TablePlaceholder,
|
||||||
|
TableSearch,
|
||||||
|
} from 'component/common/Table';
|
||||||
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
import { DateCell } from './DateCell/DateCell';
|
import { DateCell } from './DateCell/DateCell';
|
||||||
import { FeatureNameCell } from './FeatureNameCell/FeatureNameCell';
|
import { FeatureLinkCell } from './FeatureLinkCell/FeatureLinkCell';
|
||||||
import { FeatureSeenCell } from './FeatureSeenCell/FeatureSeenCell';
|
import { FeatureSeenCell } from './FeatureSeenCell/FeatureSeenCell';
|
||||||
import { FeatureStaleCell } from './FeatureStaleCell/FeatureStaleCell';
|
import { FeatureStaleCell } from './FeatureStaleCell/FeatureStaleCell';
|
||||||
import { FeatureTypeCell } from './FeatureTypeCell/FeatureTypeCell';
|
import { FeatureTypeCell } from './FeatureTypeCell/FeatureTypeCell';
|
||||||
import { LinkCell } from './LinkCell/LinkCell';
|
|
||||||
import { CreateFeatureButton } from '../../CreateFeatureButton/CreateFeatureButton';
|
import { CreateFeatureButton } from '../../CreateFeatureButton/CreateFeatureButton';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
@ -51,17 +48,29 @@ const columns = [
|
|||||||
accessor: 'lastSeenAt',
|
accessor: 'lastSeenAt',
|
||||||
Cell: FeatureSeenCell,
|
Cell: FeatureSeenCell,
|
||||||
sortType: 'date',
|
sortType: 'date',
|
||||||
|
totalWidth: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Type',
|
Header: 'Type',
|
||||||
accessor: 'type',
|
accessor: 'type',
|
||||||
Cell: FeatureTypeCell,
|
Cell: FeatureTypeCell,
|
||||||
|
totalWidth: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Feature toggle name',
|
Header: 'Feature toggle name',
|
||||||
accessor: 'name',
|
accessor: 'name',
|
||||||
// @ts-expect-error // TODO: props type
|
Cell: ({
|
||||||
Cell: ({ row: { original } }) => <FeatureNameCell {...original} />,
|
row: {
|
||||||
|
// @ts-expect-error -- props type
|
||||||
|
original: { name, description, project },
|
||||||
|
},
|
||||||
|
}) => (
|
||||||
|
<FeatureLinkCell
|
||||||
|
title={name}
|
||||||
|
subtitle={description}
|
||||||
|
to={`/projects/${project}/features/${name}`}
|
||||||
|
/>
|
||||||
|
),
|
||||||
sortType: 'alphanumeric',
|
sortType: 'alphanumeric',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -74,7 +83,7 @@ const columns = [
|
|||||||
Header: 'Project ID',
|
Header: 'Project ID',
|
||||||
accessor: 'project',
|
accessor: 'project',
|
||||||
Cell: ({ value }: { value: string }) => (
|
Cell: ({ value }: { value: string }) => (
|
||||||
<LinkCell to={`/projects/${value}`}>{value}</LinkCell>
|
<FeatureLinkCell title={value} to={`/projects/${value}`} />
|
||||||
),
|
),
|
||||||
sortType: 'alphanumeric',
|
sortType: 'alphanumeric',
|
||||||
},
|
},
|
||||||
@ -123,6 +132,7 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
|
|||||||
initialState,
|
initialState,
|
||||||
sortTypes,
|
sortTypes,
|
||||||
autoResetGlobalFilter: false,
|
autoResetGlobalFilter: false,
|
||||||
|
disableSortRemove: true,
|
||||||
},
|
},
|
||||||
useGlobalFilter,
|
useGlobalFilter,
|
||||||
useSortBy
|
useSortBy
|
||||||
@ -130,7 +140,13 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSmallScreen) {
|
if (isSmallScreen) {
|
||||||
setHiddenColumns(['lastSeenAt', 'type', 'stale', 'description']);
|
setHiddenColumns([
|
||||||
|
'lastSeenAt',
|
||||||
|
'type',
|
||||||
|
'stale',
|
||||||
|
'description',
|
||||||
|
'createdAt',
|
||||||
|
]);
|
||||||
} else if (isMediumScreen) {
|
} else if (isMediumScreen) {
|
||||||
setHiddenColumns(['lastSeenAt', 'stale', 'description']);
|
setHiddenColumns(['lastSeenAt', 'stale', 'description']);
|
||||||
} else {
|
} else {
|
||||||
@ -139,27 +155,26 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
|
|||||||
}, [setHiddenColumns, isSmallScreen, isMediumScreen]);
|
}, [setHiddenColumns, isSmallScreen, isMediumScreen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TablePanel
|
<TableContainer ref={ref}>
|
||||||
ref={ref}
|
<TableToolbar title={`Feature toggles (${data.length})`}>
|
||||||
header={
|
<TableSearch
|
||||||
<TableToolbar title={`Feature Flags (${data.length})`}>
|
initialValue={globalFilter}
|
||||||
<TableActions isSeparated onSearch={setGlobalFilter}>
|
onChange={setGlobalFilter}
|
||||||
<Link
|
/>
|
||||||
component={RouterLink}
|
<TableToolbar.Divider />
|
||||||
to="/archive"
|
<Link
|
||||||
underline="always"
|
component={RouterLink}
|
||||||
sx={{ marginRight: 3 }}
|
to="/archive"
|
||||||
>
|
underline="always"
|
||||||
View archive
|
sx={{ marginRight: 3 }}
|
||||||
</Link>
|
>
|
||||||
<CreateFeatureButton
|
View archive
|
||||||
loading={false}
|
</Link>
|
||||||
filter={{ query: '', project: 'default' }}
|
<CreateFeatureButton
|
||||||
/>
|
loading={false}
|
||||||
</TableActions>
|
filter={{ query: '', project: 'default' }}
|
||||||
</TableToolbar>
|
/>
|
||||||
}
|
</TableToolbar>
|
||||||
>
|
|
||||||
<SearchHighlightProvider value={globalFilter}>
|
<SearchHighlightProvider value={globalFilter}>
|
||||||
<Table {...getTableProps()}>
|
<Table {...getTableProps()}>
|
||||||
<SortableTableHeader headerGroups={headerGroups} />
|
<SortableTableHeader headerGroups={headerGroups} />
|
||||||
@ -182,12 +197,24 @@ export const FeatureToggleListTable: VFC<IExperimentProps> = ({
|
|||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={rows.length === 0}
|
condition={rows.length === 0}
|
||||||
show={
|
show={
|
||||||
<TablePlaceholder>
|
<ConditionallyRender
|
||||||
No features available. Get started by adding a new
|
condition={globalFilter?.length > 0}
|
||||||
feature toggle.
|
show={
|
||||||
</TablePlaceholder>
|
<TablePlaceholder>
|
||||||
|
No features or projects found matching “
|
||||||
|
{globalFilter}
|
||||||
|
”
|
||||||
|
</TablePlaceholder>
|
||||||
|
}
|
||||||
|
elseShow={
|
||||||
|
<TablePlaceholder>
|
||||||
|
No features available. Get started by adding a
|
||||||
|
new feature toggle.
|
||||||
|
</TablePlaceholder>
|
||||||
|
}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</TablePanel>
|
</TableContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import { makeStyles } from 'tss-react/mui';
|
import { makeStyles } from 'tss-react/mui';
|
||||||
|
|
||||||
export const useStyles = makeStyles()(theme => ({
|
export const useStyles = makeStyles()(theme => ({
|
||||||
|
container: {
|
||||||
|
padding: theme.spacing(1.5),
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
icon: {
|
icon: {
|
||||||
marginTop: theme.spacing(0.5),
|
marginTop: theme.spacing(0.5),
|
||||||
color: theme.palette.grey[600],
|
color: theme.palette.grey[600],
|
||||||
|
@ -20,8 +20,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 (
|
||||||
<Tooltip arrow placement="right" title={title}>
|
<div className={styles.container}>
|
||||||
<IconComponent data-loading className={styles.icon} />
|
<Tooltip arrow placement="right" title={title} describeChild>
|
||||||
</Tooltip>
|
<IconComponent data-loading className={styles.icon} />
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { VFC } from 'react';
|
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
|
||||||
import { Link } from '@mui/material';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
|
||||||
|
|
||||||
interface ILinkCellProps {
|
|
||||||
to: string;
|
|
||||||
children?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LinkCell: VFC<ILinkCellProps> = ({ children, to }) => {
|
|
||||||
const search = useSearchHighlightContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link component={RouterLink} to={to} data-loading underline="hover">
|
|
||||||
<Highlighter search={search}>{children}</Highlighter>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
@ -83,7 +83,7 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
color: '#000',
|
color: '#000',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
color: theme.palette.grey[600],
|
color: theme.palette.grey[700],
|
||||||
},
|
},
|
||||||
wideButton: {
|
wideButton: {
|
||||||
borderRadius: 100,
|
borderRadius: 100,
|
||||||
|
@ -15,6 +15,6 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
color: theme.palette.grey[600],
|
color: theme.palette.grey[700],
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -51,22 +51,6 @@ export default createTheme({
|
|||||||
light: colors.purple[700],
|
light: colors.purple[700],
|
||||||
dark: colors.purple[900],
|
dark: colors.purple[900],
|
||||||
},
|
},
|
||||||
grey: colors.grey,
|
|
||||||
neutral: {
|
|
||||||
main: '#18243e',
|
|
||||||
},
|
|
||||||
chips: {
|
|
||||||
main: '#b0bec5',
|
|
||||||
},
|
|
||||||
searchField: {
|
|
||||||
main: '#fff',
|
|
||||||
},
|
|
||||||
iconButtons: {
|
|
||||||
main: '#fff',
|
|
||||||
},
|
|
||||||
tabs: {
|
|
||||||
main: '#efefef',
|
|
||||||
},
|
|
||||||
success: {
|
success: {
|
||||||
light: colors.green[100],
|
light: colors.green[100],
|
||||||
main: colors.green[700],
|
main: colors.green[700],
|
||||||
@ -82,6 +66,22 @@ export default createTheme({
|
|||||||
main: colors.red[700],
|
main: colors.red[700],
|
||||||
dark: colors.red[800],
|
dark: colors.red[800],
|
||||||
},
|
},
|
||||||
|
grey: colors.grey,
|
||||||
|
// neutral: {
|
||||||
|
// main: '#18243e',
|
||||||
|
// },
|
||||||
|
chips: {
|
||||||
|
main: '#b0bec5',
|
||||||
|
},
|
||||||
|
searchField: {
|
||||||
|
main: '#fff',
|
||||||
|
},
|
||||||
|
iconButtons: {
|
||||||
|
main: '#fff',
|
||||||
|
},
|
||||||
|
tabs: {
|
||||||
|
main: '#efefef',
|
||||||
|
},
|
||||||
division: {
|
division: {
|
||||||
main: '#f1f1f1',
|
main: '#f1f1f1',
|
||||||
},
|
},
|
||||||
@ -97,5 +97,12 @@ export default createTheme({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
MuiLink: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
color: colors.purple[900],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,9 @@ import { SimplePaletteColorOptions } from '@mui/material';
|
|||||||
|
|
||||||
declare module '@mui/material/styles' {
|
declare module '@mui/material/styles' {
|
||||||
interface CustomTheme {
|
interface CustomTheme {
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
fontSizes: {
|
fontSizes: {
|
||||||
mainHeader: string;
|
mainHeader: string;
|
||||||
subHeader: string;
|
subHeader: string;
|
||||||
@ -9,12 +12,18 @@ declare module '@mui/material/styles' {
|
|||||||
smallBody: string;
|
smallBody: string;
|
||||||
smallerBody: string;
|
smallerBody: string;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
fontWeight: {
|
fontWeight: {
|
||||||
thin: number;
|
thin: number;
|
||||||
medium: number;
|
medium: number;
|
||||||
semi: number;
|
semi: number;
|
||||||
bold: number;
|
bold: number;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
code: {
|
code: {
|
||||||
main: string;
|
main: string;
|
||||||
diffAdd: string;
|
diffAdd: string;
|
||||||
@ -23,21 +32,44 @@ declare module '@mui/material/styles' {
|
|||||||
edited: string;
|
edited: string;
|
||||||
background: string;
|
background: string;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
main: string;
|
main: string;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
boxShadows: {
|
boxShadows: {
|
||||||
main: string;
|
main: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CustomPalette {
|
interface CustomPalette {
|
||||||
neutral: SimplePaletteColorOptions;
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
chips: SimplePaletteColorOptions;
|
chips: SimplePaletteColorOptions;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
searchField: SimplePaletteColorOptions;
|
searchField: SimplePaletteColorOptions;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
iconButtons: SimplePaletteColorOptions;
|
iconButtons: SimplePaletteColorOptions;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
tabs: SimplePaletteColorOptions;
|
tabs: SimplePaletteColorOptions;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
division: SimplePaletteColorOptions;
|
division: SimplePaletteColorOptions;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
footer: SimplePaletteColorOptions;
|
footer: SimplePaletteColorOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user