From 6d130f61f6406a63e596fbf571fac116a782055f Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Fri, 20 May 2022 10:29:23 +0200 Subject: [PATCH] feat: new contexts table (#998) * feat: new contexts table * improve context list actions * refactor: disabled icon colors * fix: update snapshots * fix: icons * fix: context fields typo --- .../ProjectRoleListItem.styles.ts | 3 - .../ProjectRoleListItem.tsx | 4 +- .../ConstraintAccordion.styles.ts | 2 +- .../EnvironmentIcon/EnvironmentIcon.tsx | 2 +- .../common/HelpIcon/HelpIcon.styles.ts | 2 +- .../PermissionIconButton.tsx | 8 +- .../component/common/SearchField/styles.ts | 2 +- .../CellSortable/CellSortable.styles.ts | 12 + .../CellSortable/CellSortable.tsx | 16 +- .../SortableTableHeader.tsx | 4 +- .../TableSearchField.styles.ts | 4 +- .../TableSearchField.styles.ts | 2 +- .../cells/FeatureLinkCell/FeatureLinkCell.tsx | 60 ---- .../FeatureTypeCell/FeatureTypeCell.styles.ts | 2 +- .../LinkCell.styles.ts} | 2 + .../common/Table/cells/LinkCell/LinkCell.tsx | 63 ++++ .../AddContextButton/AddContextButton.tsx | 45 +++ .../ContextActionsCell/ContextActionsCell.tsx | 54 ++++ .../context/ContextList/ContextList.tsx | 298 +++++++++++------- .../component/context/ContextList/styles.ts | 11 - .../EnvironmentCard/EnvironmentCard.styles.ts | 2 +- .../FeatureToggleListTable.tsx | 6 +- .../FeatureOverviewEnvironment.styles.ts | 2 +- ...atureOverviewEnvironmentStrategy.styles.ts | 2 +- .../FeatureType/FeatureType.styles.ts | 2 +- .../FeedbackCES/FeedbackCES.styles.ts | 2 +- .../ColumnsMenu/ColumnsMenu.tsx | 4 +- .../ProjectFeatureToggles.tsx | 5 +- .../SegmentListItem/SegmentListItem.styles.ts | 2 +- .../StrategiesList/StrategiesList.tsx | 2 +- .../StrategiesList.test.tsx.snap | 68 ++-- .../useUnleashContext/useUnleashContext.ts | 25 +- frontend/src/themes/theme.ts | 8 + frontend/src/themes/themeTypes.ts | 8 + 34 files changed, 462 insertions(+), 272 deletions(-) delete mode 100644 frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.tsx rename frontend/src/component/common/Table/cells/{FeatureLinkCell/FeatureLinkCell.styles.ts => LinkCell/LinkCell.styles.ts} (98%) create mode 100644 frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx create mode 100644 frontend/src/component/context/ContextList/AddContextButton/AddContextButton.tsx create mode 100644 frontend/src/component/context/ContextList/ContextActionsCell/ContextActionsCell.tsx delete mode 100644 frontend/src/component/context/ContextList/styles.ts diff --git a/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.styles.ts b/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.styles.ts index c6afc58a38..f56f1f4782 100644 --- a/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.styles.ts +++ b/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.styles.ts @@ -10,9 +10,6 @@ export const useStyles = makeStyles()(theme => ({ textAlign: 'left', maxWidth: '300px', }, - icon: { - color: theme.palette.grey[600], - }, description: { textAlign: 'left', maxWidth: '300px', diff --git a/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.tsx b/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.tsx index 92e089d8ec..657238ee1e 100644 --- a/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.tsx +++ b/frontend/src/component/admin/projectRoles/ProjectRoles/ProjectRoleList/ProjectRoleListItem/ProjectRoleListItem.tsx @@ -2,7 +2,7 @@ import { useStyles } from './ProjectRoleListItem.styles'; import { TableCell, TableRow, Typography } from '@mui/material'; import { Delete, Edit } from '@mui/icons-material'; import { ADMIN } from 'component/providers/AccessProvider/permissions'; -import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle'; +import { SupervisedUserCircle } from '@mui/icons-material'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import { IProjectRole } from 'interfaces/role'; import { useNavigate } from 'react-router-dom'; @@ -34,7 +34,7 @@ const RoleListItem = ({ <> - + diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts index c4e0accb0a..e8b48942ac 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts @@ -154,7 +154,7 @@ export const useStyles = makeStyles()(theme => ({ height: '32.5px', width: '32.5px', marginRight: '0.5rem', - fill: theme.palette.grey[600], + fill: theme.palette.inactiveIcon, }, singleValueView: { display: 'flex', diff --git a/frontend/src/component/common/EnvironmentIcon/EnvironmentIcon.tsx b/frontend/src/component/common/EnvironmentIcon/EnvironmentIcon.tsx index 486e2b1ad6..d169ce670c 100644 --- a/frontend/src/component/common/EnvironmentIcon/EnvironmentIcon.tsx +++ b/frontend/src/component/common/EnvironmentIcon/EnvironmentIcon.tsx @@ -14,7 +14,7 @@ const EnvironmentIcon = ({ enabled, className }: IEnvironmentIcon) => { const container = { backgroundColor: enabled ? theme.palette.primary.light - : theme.palette.grey[600], + : theme.palette.inactiveIcon, borderRadius: '50%', width: '28px', height: '28px', diff --git a/frontend/src/component/common/HelpIcon/HelpIcon.styles.ts b/frontend/src/component/common/HelpIcon/HelpIcon.styles.ts index a322a05907..a017afcda9 100644 --- a/frontend/src/component/common/HelpIcon/HelpIcon.styles.ts +++ b/frontend/src/component/common/HelpIcon/HelpIcon.styles.ts @@ -17,6 +17,6 @@ export const useStyles = makeStyles()(theme => ({ }, icon: { fontSize: '1rem', - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, })); diff --git a/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx b/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx index 4f3fb2f4eb..a7ad231603 100644 --- a/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx +++ b/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx @@ -55,9 +55,11 @@ const PermissionIconButton = ({ title={formatAccessText(access, tooltipProps?.title)} arrow > - - {children} - +
+ + {children} + +
); }; diff --git a/frontend/src/component/common/SearchField/styles.ts b/frontend/src/component/common/SearchField/styles.ts index 458a1116af..3317521aac 100644 --- a/frontend/src/component/common/SearchField/styles.ts +++ b/frontend/src/component/common/SearchField/styles.ts @@ -20,7 +20,7 @@ export const useStyles = makeStyles()(theme => ({ }, searchIcon: { marginRight: 8, - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, inputRoot: { width: '100%', diff --git a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.styles.ts b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.styles.ts index 123c9512fe..20a108e8d7 100644 --- a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.styles.ts +++ b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.styles.ts @@ -55,4 +55,16 @@ export const useStyles = makeStyles()(theme => ({ overflow: 'hidden', }, }, + alignLeft: { + justifyContent: 'flex-start', + textAlign: 'left', + }, + alignRight: { + justifyContent: 'flex-end', + textAlign: 'right', + }, + alignCenter: { + justifyContent: 'center', + textAlign: 'center', + }, })); diff --git a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx index cba689ba35..33191d03ba 100644 --- a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx +++ b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx @@ -58,18 +58,18 @@ export const CellSortable: FC = ({ ); }; - const justifyContent = useMemo(() => { + const alignClass = useMemo(() => { switch (align) { case 'left': - return 'flex-start'; + return styles.alignLeft; case 'center': - return 'center'; + return styles.alignCenter; case 'right': - return 'flex-end'; + return styles.alignRight; default: return undefined; } - }, [align]); + }, [align, styles]); useEffect(() => { const updateTitle = () => { @@ -102,10 +102,10 @@ export const CellSortable: FC = ({ } - elseShow={children} + elseShow={
{children}
} />
); diff --git a/frontend/src/component/common/Table/SortableTableHeader/SortableTableHeader.tsx b/frontend/src/component/common/Table/SortableTableHeader/SortableTableHeader.tsx index 96957da85d..4a70abc7e2 100644 --- a/frontend/src/component/common/Table/SortableTableHeader/SortableTableHeader.tsx +++ b/frontend/src/component/common/Table/SortableTableHeader/SortableTableHeader.tsx @@ -28,7 +28,9 @@ export const SortableTableHeader: VFC = ({ return ( ({ }, searchIcon: { marginRight: 8, - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, clearContainer: { width: '30px', @@ -34,8 +34,6 @@ export const useStyles = makeStyles()(theme => ({ }, }, clearIcon: { - // color: theme.palette.grey[700], - color: 'red', fontSize: '18px', }, inputRoot: { diff --git a/frontend/src/component/common/Table/TableSearch/TableSearchField/TableSearchField.styles.ts b/frontend/src/component/common/Table/TableSearch/TableSearchField/TableSearchField.styles.ts index cb4fd1640e..875fcd5431 100644 --- a/frontend/src/component/common/Table/TableSearch/TableSearchField/TableSearchField.styles.ts +++ b/frontend/src/component/common/Table/TableSearch/TableSearchField/TableSearchField.styles.ts @@ -25,7 +25,7 @@ export const useStyles = makeStyles()(theme => ({ }, searchIcon: { marginRight: 8, - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, clearContainer: { width: '30px', diff --git a/frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.tsx b/frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.tsx deleted file mode 100644 index 03a6a9793f..0000000000 --- a/frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.tsx +++ /dev/null @@ -1,60 +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 './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 = ({ - title, - to, - subtitle, -}) => { - const { classes: styles } = useStyles(); - const search = useSearchHighlightContext(); - - return ( - -
- - {title} - - - - - {subtitle} - - - - } - /> -
- - ); -}; diff --git a/frontend/src/component/common/Table/cells/FeatureTypeCell/FeatureTypeCell.styles.ts b/frontend/src/component/common/Table/cells/FeatureTypeCell/FeatureTypeCell.styles.ts index 0b6a2a282a..2cbed1538b 100644 --- a/frontend/src/component/common/Table/cells/FeatureTypeCell/FeatureTypeCell.styles.ts +++ b/frontend/src/component/common/Table/cells/FeatureTypeCell/FeatureTypeCell.styles.ts @@ -8,6 +8,6 @@ export const useStyles = makeStyles()(theme => ({ alignItems: 'center', }, icon: { - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, })); diff --git a/frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.styles.ts b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.styles.ts similarity index 98% rename from frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.styles.ts rename to frontend/src/component/common/Table/cells/LinkCell/LinkCell.styles.ts index 6d521392ec..4e900c3329 100644 --- a/frontend/src/component/common/Table/cells/FeatureLinkCell/FeatureLinkCell.styles.ts +++ b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.styles.ts @@ -9,6 +9,8 @@ export const useStyles = makeStyles()(theme => ({ display: 'flex', alignItems: 'center', minHeight: '62px', + }, + link: { '&:hover, &:focus': { textDecoration: 'none', '& > div > span:first-of-type': { diff --git a/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx new file mode 100644 index 0000000000..a446278839 --- /dev/null +++ b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx @@ -0,0 +1,63 @@ +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 './LinkCell.styles'; +import { Highlighter } from 'component/common/Highlighter/Highlighter'; +import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; +import classnames from 'classnames'; + +interface ILinkCellProps { + title?: string; + to?: string; + subtitle?: string; +} + +export const LinkCell: FC = ({ title, to, subtitle }) => { + const { classes: styles } = useStyles(); + const search = useSearchHighlightContext(); + + const content = ( +
+ + {title} + + + + + {subtitle} + + + + } + /> +
+ ); + + return to ? ( + + {content} + + ) : ( + {content} + ); +}; diff --git a/frontend/src/component/context/ContextList/AddContextButton/AddContextButton.tsx b/frontend/src/component/context/ContextList/AddContextButton/AddContextButton.tsx new file mode 100644 index 0000000000..540f4344cb --- /dev/null +++ b/frontend/src/component/context/ContextList/AddContextButton/AddContextButton.tsx @@ -0,0 +1,45 @@ +import { useContext, VFC } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Button, IconButton, Tooltip, useMediaQuery } from '@mui/material'; +import { Add } from '@mui/icons-material'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import AccessContext from 'contexts/AccessContext'; +import { CREATE_CONTEXT_FIELD } from 'component/providers/AccessProvider/permissions'; + +interface IAddContextButtonProps {} + +export const AddContextButton: VFC = () => { + const smallScreen = useMediaQuery('(max-width:700px)'); + const { hasAccess } = useContext(AccessContext); + const navigate = useNavigate(); + + return ( + + navigate('/context/create')} + size="large" + > + + + + } + elseShow={ + + } + /> + } + /> + ); +}; diff --git a/frontend/src/component/context/ContextList/ContextActionsCell/ContextActionsCell.tsx b/frontend/src/component/context/ContextList/ContextActionsCell/ContextActionsCell.tsx new file mode 100644 index 0000000000..d589332a49 --- /dev/null +++ b/frontend/src/component/context/ContextList/ContextActionsCell/ContextActionsCell.tsx @@ -0,0 +1,54 @@ +import { VFC } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Delete, Edit } from '@mui/icons-material'; +import { Box } from '@mui/material'; +import { + DELETE_CONTEXT_FIELD, + UPDATE_CONTEXT_FIELD, +} from 'component/providers/AccessProvider/permissions'; +import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; + +interface IContextActionsCellProps { + name: string; + onDelete: () => void; +} + +export const ContextActionsCell: VFC = ({ + name, + onDelete, +}) => { + const navigate = useNavigate(); + + return ( + + navigate(`/context/edit/${name}`)} + data-loading + aria-label="edit" + tooltipProps={{ + title: 'Edit context field', + }} + > + + + + + + + ); +}; diff --git a/frontend/src/component/context/ContextList/ContextList.tsx b/frontend/src/component/context/ContextList/ContextList.tsx index 28beae6a06..3f9d1cfd1e 100644 --- a/frontend/src/component/context/ContextList/ContextList.tsx +++ b/frontend/src/component/context/ContextList/ContextList.tsx @@ -1,42 +1,133 @@ -import { useContext, useState, VFC } from 'react'; -import { Add, Album, Delete, Edit } from '@mui/icons-material'; -import { Link, useNavigate } from 'react-router-dom'; +import { useContext, useMemo, useState, VFC } from 'react'; +import { useGlobalFilter, useSortBy, useTable } from 'react-table'; import { - Button, - IconButton, - List, - ListItem, - ListItemIcon, - ListItemText, - Tooltip, - useMediaQuery, -} from '@mui/material'; + Table, + SortableTableHeader, + TableBody, + TableCell, + TableRow, + TablePlaceholder, + TableSearch, +} from 'component/common/Table'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { - CREATE_CONTEXT_FIELD, - DELETE_CONTEXT_FIELD, - UPDATE_CONTEXT_FIELD, -} from 'component/providers/AccessProvider/permissions'; +import { UPDATE_CONTEXT_FIELD } from 'component/providers/AccessProvider/permissions'; import { Dialogue as ConfirmDialogue } from 'component/common/Dialogue/Dialogue'; import AccessContext from 'contexts/AccessContext'; import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext'; import useContextsApi from 'hooks/api/actions/useContextsApi/useContextsApi'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { useStyles } from './styles'; +import { AddContextButton } from './AddContextButton/AddContextButton'; +import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; +import { sortTypes } from 'utils/sortTypes'; +import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; +import { ContextActionsCell } from './ContextActionsCell/ContextActionsCell'; +import { Adjust } from '@mui/icons-material'; +import { Box } from '@mui/material'; const ContextList: VFC = () => { const { hasAccess } = useContext(AccessContext); const [showDelDialogue, setShowDelDialogue] = useState(false); - const smallScreen = useMediaQuery('(max-width:700px)'); const [name, setName] = useState(); - const { context, refetchUnleashContext } = useUnleashContext(); + const { context, refetchUnleashContext, loading } = useUnleashContext(); const { removeContext } = useContextsApi(); const { setToastData, setToastApiError } = useToast(); - const navigate = useNavigate(); - const { classes: styles } = useStyles(); + const data = useMemo(() => { + if (loading) { + return Array(5).fill({ + name: 'Context name', + description: 'Context description when loading', + }); + } + + return context + .map(({ name, description, sortOrder }) => ({ + name, + description, + sortOrder, + })) + .sort((a, b) => a.sortOrder - b.sortOrder); + }, [context, loading]); + + const columns = useMemo( + () => [ + { + id: 'Icon', + Cell: () => ( + + + + ), + }, + { + Header: 'Name', + accessor: 'name', + width: '90%', + Cell: ({ + row: { + original: { name, description }, + }, + }: any) => ( + + ), + sortType: 'alphanumeric', + }, + { + Header: 'Actions', + id: 'Actions', + align: 'center', + Cell: ({ + row: { + original: { name }, + }, + }: any) => ( + { + setName(name); + setShowDelDialogue(true); + }} + /> + ), + width: 150, + disableSortBy: true, + }, + { + accessor: 'description', + disableSortBy: true, + }, + { + accessor: 'sortOrder', + sortType: 'number', + }, + ], + [hasAccess] + ); + + const initialState = useMemo( + () => ({ + sortBy: [{ id: 'name', desc: false }], + hiddenColumns: ['description', 'sortOrder'], + }), + [] + ); const onDeleteContext = async () => { try { @@ -57,103 +148,86 @@ const ContextList: VFC = () => { setShowDelDialogue(false); }; - const contextList = () => - context.map(field => ( - - - - - - {field.name} - - } - elseShow={{field.name}} - /> - } - secondary={field.description} - /> - - - navigate(`/context/edit/${field.name}`) - } - size="large" - > - - - - } - /> - - { - setName(field.name); - setShowDelDialogue(true); - }} - size="large" - > - - - - } - /> - - )); - const headerButton = () => ( - - navigate('/context/create')} - size="large" - > - - - - } - elseShow={ - - } - /> - } - /> + const { + getTableProps, + getTableBodyProps, + headerGroups, + rows, + prepareRow, + state: { globalFilter }, + setGlobalFilter, + } = useTable( + { + columns: columns as any[], // TODO: fix after `react-table` v8 update + data, + initialState, + sortTypes, + autoResetGlobalFilter: false, + autoResetSortBy: false, + disableSortRemove: true, + }, + useGlobalFilter, + useSortBy ); return ( + + + + + + } + /> } > - - 0} - show={contextList} - elseShow={No context fields defined} - /> - + + + + + {rows.map(row => { + prepareRow(row); + return ( + + {row.cells.map(cell => ( + + {cell.render('Cell')} + + ))} + + ); + })} + +
+
+ 0} + show={ + + No contexts found matching “ + {globalFilter} + ” + + } + elseShow={ + + No contexts available. Get started by adding + one. + + } + /> + } + /> ({ minWidth: '450px', }, icon: { - fill: theme.palette.grey[600], + fill: theme.palette.inactiveIcon, marginRight: '0.5rem', }, header: { diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable/FeatureToggleListTable.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable/FeatureToggleListTable.tsx index 0ee8269942..f468829649 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable/FeatureToggleListTable.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable/FeatureToggleListTable.tsx @@ -13,7 +13,7 @@ import { } from 'component/common/Table'; import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { DateCell } from '../../../common/Table/cells/DateCell/DateCell'; -import { FeatureLinkCell } from 'component/common/Table/cells/FeatureLinkCell/FeatureLinkCell'; +import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { FeatureSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureSeenCell'; import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/FeatureTypeCell'; import { FeatureStaleCell } from './FeatureStaleCell/FeatureStaleCell'; @@ -53,7 +53,7 @@ const columns = [ original: { name, description, project }, }, }) => ( - ( - + ), sortType: 'alphanumeric', }, diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.styles.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.styles.ts index cee5317601..347bbf3955 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.styles.ts +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.styles.ts @@ -116,7 +116,7 @@ export const useStyles = makeStyles()(theme => ({ }, }, strategyIcon: { - fill: theme.palette.grey[600], + fill: theme.palette.inactiveIcon, }, container: { display: 'flex', diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironmentStrategies/FeatureOverviewEnvironmentStrategy/FeatureOverviewEnvironmentStrategy.styles.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironmentStrategies/FeatureOverviewEnvironmentStrategy/FeatureOverviewEnvironmentStrategy.styles.ts index 40ce3dd57a..8573aebca0 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironmentStrategies/FeatureOverviewEnvironmentStrategy/FeatureOverviewEnvironmentStrategy.styles.ts +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironmentStrategies/FeatureOverviewEnvironmentStrategy/FeatureOverviewEnvironmentStrategy.styles.ts @@ -16,7 +16,7 @@ export const useStyles = makeStyles()(theme => ({ borderBottom: `1px solid ${theme.palette.grey[300]}`, }, icon: { - fill: theme.palette.grey[600], + fill: theme.palette.inactiveIcon, }, actions: { marginLeft: 'auto', diff --git a/frontend/src/component/feature/FeatureView/FeatureType/FeatureType.styles.ts b/frontend/src/component/feature/FeatureView/FeatureType/FeatureType.styles.ts index 68cada78df..2611881121 100644 --- a/frontend/src/component/feature/FeatureView/FeatureType/FeatureType.styles.ts +++ b/frontend/src/component/feature/FeatureView/FeatureType/FeatureType.styles.ts @@ -2,6 +2,6 @@ import { makeStyles } from 'tss-react/mui'; export const useStyles = makeStyles()(theme => ({ icon: { - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, })); diff --git a/frontend/src/component/feedback/FeedbackCES/FeedbackCES.styles.ts b/frontend/src/component/feedback/FeedbackCES/FeedbackCES.styles.ts index fe7670afbc..bc226dd5ce 100644 --- a/frontend/src/component/feedback/FeedbackCES/FeedbackCES.styles.ts +++ b/frontend/src/component/feedback/FeedbackCES/FeedbackCES.styles.ts @@ -32,6 +32,6 @@ export const useStyles = makeStyles()(theme => ({ }, closeIcon: { fontSize: '1.5rem', - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, })); diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx index 86b080ff43..c329725c65 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx @@ -14,7 +14,7 @@ import { useMediaQuery, useTheme, } from '@mui/material'; -import ViewColumnIcon from '@mui/icons-material/ViewColumn'; +import ColumnIcon from '@mui/icons-material/ViewWeek'; import CloseIcon from '@mui/icons-material/Close'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useStyles } from './ColumnsMenu.styles'; @@ -105,7 +105,7 @@ export const ColumnsMenu: VFC = ({ className={classes.button} data-loading > - + diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index 8fc93b5ec8..22a8bde75d 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -11,7 +11,7 @@ import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; -import { FeatureLinkCell } from 'component/common/Table/cells/FeatureLinkCell/FeatureLinkCell'; +import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { FeatureSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureSeenCell'; import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/FeatureTypeCell'; import { sortTypes } from 'utils/sortTypes'; @@ -176,7 +176,7 @@ export const ProjectFeatureToggles = ({ Header: 'Feature toggle name', accessor: 'name', Cell: ({ value }: { value: string }) => ( - @@ -271,6 +271,7 @@ export const ProjectFeatureToggles = ({ () => filters?.find(filterRow => filterRow?.id === 'name')?.value || '', [filters] ); + return ( ({ maxWidth: '300px', }, icon: { - color: theme.palette.grey[600], + color: theme.palette.inactiveIcon, }, descriptionCell: { textAlign: 'left', diff --git a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx index 86d1d95543..1b4f51626b 100644 --- a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx +++ b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx @@ -255,7 +255,7 @@ export const StrategiesList = () => { strategies.map(strategy => ( - +
- + +
void; loading: boolean; error?: Error; - CONTEXT_CACHE_KEY: string; } const useUnleashContext = ( @@ -30,24 +28,17 @@ const useUnleashContext = ( const CONTEXT_CACHE_KEY = 'api/admin/context'; - const { data, error } = useSWR(CONTEXT_CACHE_KEY, fetcher, options); - - const [loading, setLoading] = useState(!error && !data); - - const refetchUnleashContext = () => { - mutate(CONTEXT_CACHE_KEY); - }; - - useEffect(() => { - setLoading(!error && !data); - }, [data, error]); + const { data, mutate, error, isValidating } = useSWR( + CONTEXT_CACHE_KEY, + fetcher, + options + ); return { context: data || [], error, - loading, - refetchUnleashContext, - CONTEXT_CACHE_KEY, + loading: isValidating && !error && !data, + refetchUnleashContext: mutate, }; }; diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts index ded0b545e1..76a4508849 100644 --- a/frontend/src/themes/theme.ts +++ b/frontend/src/themes/theme.ts @@ -100,6 +100,7 @@ export default createTheme({ inactive: colors.orange[200], abandoned: colors.red[200], }, + inactiveIcon: colors.grey[600], }, components: { MuiLink: { @@ -244,5 +245,12 @@ export default createTheme({ }, }, }, + MuiIcon: { + styleOverrides: { + colorDisabled: { + color: colors.grey[600], + }, + }, + }, }, }); diff --git a/frontend/src/themes/themeTypes.ts b/frontend/src/themes/themeTypes.ts index f15658a8a5..0c59e9ea74 100644 --- a/frontend/src/themes/themeTypes.ts +++ b/frontend/src/themes/themeTypes.ts @@ -61,6 +61,14 @@ declare module '@mui/material/styles' { * For sidebar container background. */ sidebarContainer: string; + /** + * Icon that doesn't have an action (visual only, no click handler). + * + * @deprecated use ``. + * ⚠️ `color` only works with `import { YourIcon } from "@mui/icons"` + * and not with `import YourIcon from "@mui/icons/YourIcon"`. + */ + inactiveIcon: string; } interface Theme extends CustomTheme {}