From ddd7a2caafd00bb6129cb0a8e9c12de567d83f07 Mon Sep 17 00:00:00 2001 From: Youssef Date: Fri, 25 Feb 2022 09:14:07 +0100 Subject: [PATCH 1/6] feat: add search functionality --- .../ProjectFeatureToggles.tsx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index 33e2bea70a..e0fae770b1 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -1,4 +1,4 @@ -import { useContext } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { IconButton } from '@material-ui/core'; import { Add } from '@material-ui/icons'; import FilterListIcon from '@material-ui/icons/FilterList'; @@ -31,7 +31,19 @@ const ProjectFeatureToggles = ({ const history = useHistory(); const { hasAccess } = useContext(AccessContext); const { uiConfig } = useUiConfig(); + const [filteredFeatures, setFilteredFeatures] = + useState(features); + const searchFeatures = () => { + const filteredData = features.filter(feature => { + return Object.values(feature) + .join('') + .toLowerCase() + .includes('ENV'.toLowerCase()); + }); + setFilteredFeatures(filteredData); + }; + return ( 0} + condition={filteredFeatures?.length > 0} show={ From 722c06b73fb06ee0b3c4721e89ea496175c52901 Mon Sep 17 00:00:00 2001 From: Youssef Date: Mon, 28 Feb 2022 16:27:23 +0100 Subject: [PATCH 2/6] feat: add search input in project features --- .../ResponsiveButton/ResponsiveButton.tsx | 2 + .../component/common/SearchField/styles.js | 1 + .../ProjectFeatureToggles.styles.ts | 13 +++++ .../ProjectFeatureToggles.tsx | 58 ++++++++++--------- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx index 0edb2cb94f..f515cc4a1e 100644 --- a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx +++ b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx @@ -12,6 +12,7 @@ interface IResponsiveButtonProps { projectId?: string; environmentId?: string; maxWidth: string; + className?: string; } const ResponsiveButton: React.FC = ({ @@ -24,6 +25,7 @@ const ResponsiveButton: React.FC = ({ permission, environmentId, projectId, + className, ...rest }) => { const smallScreen = useMediaQuery(`(max-width:${maxWidth})`); diff --git a/frontend/src/component/common/SearchField/styles.js b/frontend/src/component/common/SearchField/styles.js index ed7c9e480a..3d495b0803 100644 --- a/frontend/src/component/common/SearchField/styles.js +++ b/frontend/src/component/common/SearchField/styles.js @@ -20,6 +20,7 @@ export const useStyles = makeStyles(theme => ({ }, searchIcon: { marginRight: '8px', + color: theme.palette.grey[600], }, inputRoot: { width: '100%', diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts index 1437920b3c..b8ee003208 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts @@ -37,4 +37,17 @@ export const useStyles = makeStyles(theme => ({ link: { textDecoration: 'none', }, + actionsContainer: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, + search: { + border: `1px solid ${theme.palette.grey[300]}`, + height: '35px', + marginRight: '2rem', + }, + button: { + whiteSpace: 'nowrap', + }, })); diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index e0fae770b1..e7c5950c9c 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -1,21 +1,22 @@ -import { useContext, useEffect, useState } from 'react'; +import { useContext, useMemo, useState } from 'react'; import { IconButton } from '@material-ui/core'; import { Add } from '@material-ui/icons'; import FilterListIcon from '@material-ui/icons/FilterList'; import { useParams } from 'react-router'; import { Link, useHistory } from 'react-router-dom'; -import AccessContext from '../../../../contexts/AccessContext'; -import { IFeatureToggleListItem } from '../../../../interfaces/featureToggle'; -import { getCreateTogglePath } from '../../../../utils/route-path-helpers'; -import ConditionallyRender from '../../../common/ConditionallyRender'; -import { PROJECTFILTERING } from '../../../common/flags'; -import HeaderTitle from '../../../common/HeaderTitle'; -import PageContent from '../../../common/PageContent'; -import ResponsiveButton from '../../../common/ResponsiveButton/ResponsiveButton'; -import FeatureToggleListNew from '../../../feature/FeatureToggleListNew/FeatureToggleListNew'; +import AccessContext from 'contexts/AccessContext'; +import { SearchField } from 'component/common/SearchField/SearchField'; +import ConditionallyRender from 'component/common/ConditionallyRender'; +import { PROJECTFILTERING } from 'component/common/flags'; +import HeaderTitle from 'component/common/HeaderTitle'; +import PageContent from 'component/common/PageContent'; +import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton'; +import FeatureToggleListNew from 'component/feature/FeatureToggleListNew/FeatureToggleListNew'; +import { IFeatureToggleListItem } from 'interfaces/featureToggle'; +import { getCreateTogglePath } from 'utils/route-path-helpers'; import { useStyles } from './ProjectFeatureToggles.styles'; -import { CREATE_FEATURE } from '../../../providers/AccessProvider/permissions'; -import useUiConfig from '../../../../hooks/api/getters/useUiConfig/useUiConfig'; +import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; interface IProjectFeatureToggles { features: IFeatureToggleListItem[]; @@ -27,23 +28,20 @@ const ProjectFeatureToggles = ({ loading, }: IProjectFeatureToggles) => { const styles = useStyles(); - const { id } = useParams(); + const { id } = useParams<{ id: string }>(); const history = useHistory(); const { hasAccess } = useContext(AccessContext); const { uiConfig } = useUiConfig(); - const [filteredFeatures, setFilteredFeatures] = - useState(features); + const [filter, setFilter] = useState(''); + useState(features); + + const filteredFeatures = useMemo(() => { + const regExp = new RegExp(filter, 'i'); + return filter + ? features?.filter(feature => regExp.test(feature?.name)) + : features; + }, [features, filter]); - const searchFeatures = () => { - const filteredData = features.filter(feature => { - return Object.values(feature) - .join('') - .toLowerCase() - .includes('ENV'.toLowerCase()); - }); - setFilteredFeatures(filteredData); - }; - return ( +
+ New feature toggle - +
} /> } From 65713bc78fbf4ef6c2fd8e81b1c2e4e4d7990350 Mon Sep 17 00:00:00 2001 From: Youssef Date: Mon, 28 Feb 2022 17:20:47 +0100 Subject: [PATCH 3/6] style: add className for SearchField --- .../ProjectFeatureToggles/ProjectFeatureToggles.tsx | 9 +++++---- .../src/component/project/Project/ProjectOverview.tsx | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index e7c5950c9c..b356ebf8a1 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -17,13 +17,14 @@ import { getCreateTogglePath } from 'utils/route-path-helpers'; import { useStyles } from './ProjectFeatureToggles.styles'; import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import classnames from 'classnames'; interface IProjectFeatureToggles { features: IFeatureToggleListItem[]; loading: boolean; } -const ProjectFeatureToggles = ({ +export const ProjectFeatureToggles = ({ features, loading, }: IProjectFeatureToggles) => { @@ -55,7 +56,9 @@ const ProjectFeatureToggles = ({ ); }; - -export default ProjectFeatureToggles; diff --git a/frontend/src/component/project/Project/ProjectOverview.tsx b/frontend/src/component/project/Project/ProjectOverview.tsx index de4564da79..a61d8c7481 100644 --- a/frontend/src/component/project/Project/ProjectOverview.tsx +++ b/frontend/src/component/project/Project/ProjectOverview.tsx @@ -1,5 +1,5 @@ import useProject from '../../../hooks/api/getters/useProject/useProject'; -import ProjectFeatureToggles from './ProjectFeatureToggles/ProjectFeatureToggles'; +import { ProjectFeatureToggles } from './ProjectFeatureToggles/ProjectFeatureToggles'; import ProjectInfo from './ProjectInfo/ProjectInfo'; import { useStyles } from './Project.styles'; From 4f3b34115b4063a356ca1a5ca4d33a06c82de140 Mon Sep 17 00:00:00 2001 From: Youssef Date: Tue, 1 Mar 2022 09:03:25 +0100 Subject: [PATCH 4/6] fix: update PR based on feedback --- .../common/ResponsiveButton/ResponsiveButton.tsx | 1 - frontend/src/component/common/SearchField/styles.js | 2 +- .../ProjectFeatureToggles.styles.ts | 2 +- .../ProjectFeatureToggles/ProjectFeatureToggles.tsx | 9 ++++----- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx index f515cc4a1e..71602501e8 100644 --- a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx +++ b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx @@ -25,7 +25,6 @@ const ResponsiveButton: React.FC = ({ permission, environmentId, projectId, - className, ...rest }) => { const smallScreen = useMediaQuery(`(max-width:${maxWidth})`); diff --git a/frontend/src/component/common/SearchField/styles.js b/frontend/src/component/common/SearchField/styles.js index 3d495b0803..25262fd324 100644 --- a/frontend/src/component/common/SearchField/styles.js +++ b/frontend/src/component/common/SearchField/styles.js @@ -19,7 +19,7 @@ export const useStyles = makeStyles(theme => ({ }, }, searchIcon: { - marginRight: '8px', + marginRight: 8, color: theme.palette.grey[600], }, inputRoot: { diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts index b8ee003208..889b1cece1 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts @@ -44,7 +44,7 @@ export const useStyles = makeStyles(theme => ({ }, search: { border: `1px solid ${theme.palette.grey[300]}`, - height: '35px', + height: 35, marginRight: '2rem', }, button: { diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index b356ebf8a1..6fe73c123d 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -19,7 +19,7 @@ import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import classnames from 'classnames'; -interface IProjectFeatureToggles { +interface IProjectFeatureTogglesProps { features: IFeatureToggleListItem[]; loading: boolean; } @@ -27,19 +27,18 @@ interface IProjectFeatureToggles { export const ProjectFeatureToggles = ({ features, loading, -}: IProjectFeatureToggles) => { +}: IProjectFeatureTogglesProps) => { const styles = useStyles(); const { id } = useParams<{ id: string }>(); const history = useHistory(); const { hasAccess } = useContext(AccessContext); const { uiConfig } = useUiConfig(); const [filter, setFilter] = useState(''); - useState(features); const filteredFeatures = useMemo(() => { const regExp = new RegExp(filter, 'i'); return filter - ? features?.filter(feature => regExp.test(feature?.name)) + ? features.filter(feature => regExp.test(feature.name)) : features; }, [features, filter]); @@ -98,7 +97,7 @@ export const ProjectFeatureToggles = ({ } > 0} + condition={filteredFeatures.length > 0} show={ Date: Tue, 1 Mar 2022 10:23:04 +0100 Subject: [PATCH 5/6] fix: add mobile view for search --- .../ProjectFeatureToggles/ProjectFeatureToggles.styles.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts index 889b1cece1..7f1acfa041 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts @@ -22,6 +22,10 @@ export const useStyles = makeStyles(theme => ({ title: { fontSize: '1rem', fontWeight: 'normal', + visibility: 'hidden', + [theme.breakpoints.up('sm')]: { + visibility: 'visible', + }, }, iconButton: { marginRight: '1rem', From 3bcbd0fd5069473a9262607bcf00f14fc0a03fe2 Mon Sep 17 00:00:00 2001 From: Youssef Date: Tue, 1 Mar 2022 15:42:30 +0100 Subject: [PATCH 6/6] style: use display instead of visibility --- .../ProjectFeatureToggles/ProjectFeatureToggles.styles.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts index 7f1acfa041..01c4c66fca 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.styles.ts @@ -22,9 +22,9 @@ export const useStyles = makeStyles(theme => ({ title: { fontSize: '1rem', fontWeight: 'normal', - visibility: 'hidden', - [theme.breakpoints.up('sm')]: { - visibility: 'visible', + display: 'unset', + [theme.breakpoints.down(600)]: { + display: 'none', }, }, iconButton: {