mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
feat: project list frontend filter
This commit is contained in:
parent
279d3431eb
commit
df29999d38
@ -1,5 +1,6 @@
|
|||||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
import { useContext, useMemo, useState } from 'react';
|
||||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
import { BooleanParam, StringParam, withDefault } from 'use-query-params';
|
||||||
import { mutate } from 'swr';
|
import { mutate } from 'swr';
|
||||||
import { getProjectFetcher } from 'hooks/api/getters/useProject/getProjectFetcher';
|
import { getProjectFetcher } from 'hooks/api/getters/useProject/getProjectFetcher';
|
||||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||||
@ -31,6 +32,7 @@ import { ReactComponent as ProPlanIconLight } from 'assets/icons/pro-enterprise-
|
|||||||
import { safeRegExp } from '@server/util/escape-regex';
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
|
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { usePersistentTableState } from 'hooks/usePersistentTableState';
|
||||||
import { useProfile } from 'hooks/api/getters/useProfile/useProfile';
|
import { useProfile } from 'hooks/api/getters/useProfile/useProfile';
|
||||||
import { shouldDisplayInMyProjects } from './should-display-in-my-projects';
|
import { shouldDisplayInMyProjects } from './should-display-in-my-projects';
|
||||||
|
|
||||||
@ -75,8 +77,6 @@ const StyledButtonGroup = styled(ToggleButtonGroup)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
type PageQueryType = Partial<Record<'search', string>>;
|
|
||||||
|
|
||||||
type projectMap = {
|
type projectMap = {
|
||||||
[index: string]: boolean;
|
[index: string]: boolean;
|
||||||
};
|
};
|
||||||
@ -131,32 +131,34 @@ export const ProjectListNew = () => {
|
|||||||
const { projects, loading, error, refetch } = useProjects();
|
const { projects, loading, error, refetch } = useProjects();
|
||||||
const [fetchedProjects, setFetchedProjects] = useState<projectMap>({});
|
const [fetchedProjects, setFetchedProjects] = useState<projectMap>({});
|
||||||
const { isOss } = useUiConfig();
|
const { isOss } = useUiConfig();
|
||||||
|
|
||||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
|
||||||
const [searchValue, setSearchValue] = useState(
|
|
||||||
searchParams.get('search') || '',
|
|
||||||
);
|
|
||||||
|
|
||||||
const showProjectFilterButtons = useUiFlag('projectListFilterMyProjects');
|
const showProjectFilterButtons = useUiFlag('projectListFilterMyProjects');
|
||||||
const filters = ['All projects', 'My projects'];
|
|
||||||
const [filter, setFilter] = useState(filters[0]);
|
|
||||||
const myProjects = new Set(useProfile().profile?.projects || []);
|
const myProjects = new Set(useProfile().profile?.projects || []);
|
||||||
|
|
||||||
useEffect(() => {
|
const filterOptions = [
|
||||||
const tableState: PageQueryType = {};
|
{
|
||||||
if (searchValue) {
|
label: 'All projects',
|
||||||
tableState.search = searchValue;
|
value: false,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
label: 'My projects',
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
setSearchParams(tableState, {
|
const stateConfig = {
|
||||||
replace: true,
|
myProjects: withDefault(BooleanParam, false),
|
||||||
});
|
search: withDefault(StringParam, ''),
|
||||||
}, [searchValue, setSearchParams]);
|
};
|
||||||
|
const [filterState, setFilterState] = usePersistentTableState(
|
||||||
|
`projects-list`,
|
||||||
|
stateConfig,
|
||||||
|
);
|
||||||
|
const searchValue = filterState.search;
|
||||||
|
|
||||||
const filteredProjects = useMemo(() => {
|
const filteredProjects = useMemo(() => {
|
||||||
const preFilteredProjects =
|
const preFilteredProjects =
|
||||||
showProjectFilterButtons && filter === 'My projects'
|
showProjectFilterButtons && filterState.myProjects
|
||||||
? projects.filter(shouldDisplayInMyProjects(myProjects))
|
? projects.filter(shouldDisplayInMyProjects(myProjects))
|
||||||
: projects;
|
: projects;
|
||||||
|
|
||||||
@ -176,7 +178,13 @@ export const ProjectListNew = () => {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
}, [projects, searchValue, filter, myProjects, showProjectFilterButtons]);
|
}, [
|
||||||
|
projects,
|
||||||
|
searchValue,
|
||||||
|
filterState.myProjects,
|
||||||
|
myProjects,
|
||||||
|
showProjectFilterButtons,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleHover = (projectId: string) => {
|
const handleHover = (projectId: string) => {
|
||||||
if (fetchedProjects[projectId]) {
|
if (fetchedProjects[projectId]) {
|
||||||
@ -218,21 +226,23 @@ export const ProjectListNew = () => {
|
|||||||
aria-label='project list filter'
|
aria-label='project list filter'
|
||||||
size='small'
|
size='small'
|
||||||
color='primary'
|
color='primary'
|
||||||
value={filter}
|
value={filterState.myProjects}
|
||||||
exclusive
|
exclusive
|
||||||
onChange={(event, value) => {
|
onChange={(event, value) => {
|
||||||
if (value !== null) {
|
if (value !== null) {
|
||||||
setFilter(value);
|
setFilterState({
|
||||||
|
myProjects: value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{filters.map((filter) => {
|
{filterOptions.map((filter) => {
|
||||||
return (
|
return (
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
key={filter}
|
key={`${filter.value}`}
|
||||||
value={filter}
|
value={filter.value}
|
||||||
>
|
>
|
||||||
{filter}
|
{filter.label}
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -248,7 +258,9 @@ export const ProjectListNew = () => {
|
|||||||
<>
|
<>
|
||||||
<Search
|
<Search
|
||||||
initialValue={searchValue}
|
initialValue={searchValue}
|
||||||
onChange={setSearchValue}
|
onChange={(search) =>
|
||||||
|
setFilterState({ search })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<PageHeader.Divider />
|
<PageHeader.Divider />
|
||||||
</>
|
</>
|
||||||
@ -274,7 +286,9 @@ export const ProjectListNew = () => {
|
|||||||
show={
|
show={
|
||||||
<Search
|
<Search
|
||||||
initialValue={searchValue}
|
initialValue={searchValue}
|
||||||
onChange={setSearchValue}
|
onChange={(search) =>
|
||||||
|
setFilterState({ search })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user