1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-28 00:06:53 +01:00

feat: insights filters (#7608)

This commit is contained in:
Mateusz Kwasniewski 2024-07-17 11:30:58 +02:00 committed by GitHub
parent 13d02685d8
commit 39f6cbd66c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 134 additions and 21 deletions

View File

@ -11,8 +11,9 @@ import { InsightsHeader } from './components/InsightsHeader/InsightsHeader';
import { useInsightsData } from './hooks/useInsightsData';
import { InsightsCharts } from './InsightsCharts';
import { LegacyInsightsCharts } from './LegacyInsightsCharts';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useUiFlag } from 'hooks/useUiFlag';
import { InsightsFilters } from './InsightsFilters';
import { FilterItemParam } from '../../utils/serializeQueryParams';
const StickyWrapper = styled(Box, {
shouldForwardProp: (prop) => prop !== 'scrolled',
@ -33,7 +34,7 @@ const StyledProjectSelect = styled(ProjectSelect)(({ theme }) => ({
},
}));
export const Insights: VFC = () => {
const LegacyInsights = () => {
const [scrolled, setScrolled] = useState(false);
const { insights, loading, error } = useInsights();
const stateConfig = {
@ -61,8 +62,6 @@ export const Insights: VFC = () => {
window.addEventListener('scroll', handleScroll);
}
const isInsightsV2Enabled = useUiFlag('insightsV2');
return (
<>
<StickyWrapper scrolled={scrolled}>
@ -77,23 +76,65 @@ export const Insights: VFC = () => {
}
/>
</StickyWrapper>
<ConditionallyRender
condition={isInsightsV2Enabled}
show={
<InsightsCharts
loading={loading}
projects={projects}
{...insightsData}
/>
}
elseShow={
<LegacyInsightsCharts
loading={loading}
projects={projects}
{...insightsData}
/>
}
<LegacyInsightsCharts
loading={loading}
projects={projects}
{...insightsData}
/>
</>
);
};
const NewInsights = () => {
const [scrolled, setScrolled] = useState(false);
const stateConfig = {
projects: FilterItemParam,
from: FilterItemParam,
to: FilterItemParam,
};
const [state, setState] = usePersistentTableState('insights', stateConfig);
const { insights, loading, error } = useInsights(
state.from?.values[0],
state.to?.values[0],
);
const projects = state.projects?.values ?? [allOption.id];
const insightsData = useInsightsData(insights, projects);
const handleScroll = () => {
if (!scrolled && window.scrollY > 0) {
setScrolled(true);
} else if (scrolled && window.scrollY === 0) {
setScrolled(false);
}
};
if (typeof window !== 'undefined') {
window.addEventListener('scroll', handleScroll);
}
return (
<>
<StickyWrapper scrolled={scrolled}>
<InsightsHeader
actions={
<InsightsFilters state={state} onChange={setState} />
}
/>
</StickyWrapper>
<InsightsCharts
loading={loading}
projects={projects}
{...insightsData}
/>
</>
);
};
export const Insights: VFC = () => {
const isInsightsV2Enabled = useUiFlag('insightsV2');
if (isInsightsV2Enabled) return <NewInsights />;
return <LegacyInsights />;
};

View File

@ -0,0 +1,69 @@
import { type FC, useEffect, useState } from 'react';
import useProjects from 'hooks/api/getters/useProjects/useProjects';
import {
type FilterItemParamHolder,
Filters,
type IFilterItem,
} from 'component/filter/Filters/Filters';
interface IFeatureToggleFiltersProps {
state: FilterItemParamHolder;
onChange: (value: FilterItemParamHolder) => void;
}
export const InsightsFilters: FC<IFeatureToggleFiltersProps> = ({
state,
onChange,
}) => {
const { projects } = useProjects();
const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]);
useEffect(() => {
const projectsOptions = (projects || []).map((project) => ({
label: project.name,
value: project.id,
}));
const hasMultipleProjects = projectsOptions.length > 1;
const availableFilters: IFilterItem[] = [
{
label: 'Date From',
icon: 'today',
options: [],
filterKey: 'from',
dateOperators: ['IS'],
},
{
label: 'Date To',
icon: 'today',
options: [],
filterKey: 'to',
dateOperators: ['IS'],
},
...(hasMultipleProjects
? ([
{
label: 'Project',
icon: 'topic',
options: projectsOptions,
filterKey: 'projects',
singularOperators: ['IS'],
pluralOperators: ['IS_ANY_OF'],
},
] as IFilterItem[])
: []),
];
setAvailableFilters(availableFilters);
}, [JSON.stringify(projects)]);
return (
<Filters
availableFilters={availableFilters}
state={state}
onChange={onChange}
/>
);
};

View File

@ -18,6 +18,7 @@ type DashboardHeaderProps = {
const StyledActionsContainer = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
[theme.breakpoints.down('md')]: {
flexDirection: 'column',

View File

@ -12,9 +12,11 @@ interface IUseInsightsDataOutput {
}
export const useInsights = (
from = '',
to = '',
options?: SWRConfiguration,
): IUseInsightsDataOutput => {
const path = formatApiPath('api/admin/insights');
const path = formatApiPath(`api/admin/insights?from=${from}&to=${to}`);
const { data, error } = useSWR<InstanceInsightsSchema>(
path,