mirror of
https://github.com/Unleash/unleash.git
synced 2025-11-10 01:19:53 +01:00
feat: change "archived" flags filter placement on project flags list (#10710)
Archived flags link will now it will show up on the right side, next to import/export, which makes it more in line with flags overview. Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This commit is contained in:
parent
da22cb0d65
commit
f5af92b5ee
@ -41,7 +41,7 @@ import {
|
|||||||
useProjectFeatureSearchActions,
|
useProjectFeatureSearchActions,
|
||||||
} from './useProjectFeatureSearch.ts';
|
} from './useProjectFeatureSearch.ts';
|
||||||
import { AvatarCell } from './AvatarCell.tsx';
|
import { AvatarCell } from './AvatarCell.tsx';
|
||||||
import { styled, useMediaQuery, useTheme } from '@mui/material';
|
import { Box, styled, useMediaQuery, useTheme } from '@mui/material';
|
||||||
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
||||||
import { ConnectSdkDialog } from '../../../onboarding/dialog/ConnectSdkDialog.tsx';
|
import { ConnectSdkDialog } from '../../../onboarding/dialog/ConnectSdkDialog.tsx';
|
||||||
import { ProjectOnboarding } from '../../../onboarding/flow/ProjectOnboarding.tsx';
|
import { ProjectOnboarding } from '../../../onboarding/flow/ProjectOnboarding.tsx';
|
||||||
@ -101,8 +101,25 @@ const ButtonGroup = styled('div')(({ theme }) => ({
|
|||||||
paddingInline: theme.spacing(1.5),
|
paddingInline: theme.spacing(1.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const LinkToggle = styled('button')(({ theme }) => ({
|
||||||
|
background: 'none',
|
||||||
|
border: 'none',
|
||||||
|
padding: 0,
|
||||||
|
margin: theme.spacing(0, 1.5),
|
||||||
|
marginLeft: 'auto',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
textDecoration: 'underline',
|
||||||
|
font: 'inherit',
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'none',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const ProjectFeatureToggles = ({
|
export const ProjectFeatureToggles = ({
|
||||||
environments,
|
environments: availableEnvironments,
|
||||||
}: ProjectFeatureTogglesProps) => {
|
}: ProjectFeatureTogglesProps) => {
|
||||||
const { trackEvent } = usePlausibleTracker();
|
const { trackEvent } = usePlausibleTracker();
|
||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
@ -192,6 +209,17 @@ export const ProjectFeatureToggles = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showCleanupReminder = !tableState.lastSeenAt && !tableState.lifecycle;
|
||||||
|
const showArchived = Boolean(tableState.archived);
|
||||||
|
const toggleArchived = () => {
|
||||||
|
if (showArchived) {
|
||||||
|
setTableState({ archived: undefined });
|
||||||
|
} else {
|
||||||
|
setTableState({ archived: { operator: 'IS', values: ['true'] } });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const environments = showArchived ? [] : availableEnvironments;
|
||||||
|
|
||||||
const columns = useMemo(
|
const columns = useMemo(
|
||||||
() => [
|
() => [
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
@ -493,8 +521,6 @@ export const ProjectFeatureToggles = ({
|
|||||||
|
|
||||||
const selectedData = useSelectedData(features, rowSelection);
|
const selectedData = useSelectedData(features, rowSelection);
|
||||||
|
|
||||||
const showCleanupReminder = !tableState.lastSeenAt && !tableState.lifecycle;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
@ -527,6 +553,23 @@ export const ProjectFeatureToggles = ({
|
|||||||
isLoading={initialLoad}
|
isLoading={initialLoad}
|
||||||
totalItems={total}
|
totalItems={total}
|
||||||
environmentsToExport={environments}
|
environmentsToExport={environments}
|
||||||
|
actions={
|
||||||
|
flagsUiFilterRefactorEnabled ? (
|
||||||
|
<LinkToggle
|
||||||
|
type='button'
|
||||||
|
onClick={toggleArchived}
|
||||||
|
>
|
||||||
|
{showArchived
|
||||||
|
? 'View active flags'
|
||||||
|
: 'View archived flags'}
|
||||||
|
</LinkToggle>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
title={
|
||||||
|
showArchived
|
||||||
|
? 'Archived feature flags'
|
||||||
|
: 'Feature flags'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<LegacyProjectFeatureTogglesHeader
|
<LegacyProjectFeatureTogglesHeader
|
||||||
@ -559,12 +602,22 @@ export const ProjectFeatureToggles = ({
|
|||||||
{flagsUiFilterRefactorEnabled ? (
|
{flagsUiFilterRefactorEnabled ? (
|
||||||
<FiltersContainer>
|
<FiltersContainer>
|
||||||
<FilterRow>
|
<FilterRow>
|
||||||
<ProjectLifecycleFilters
|
{showArchived ? (
|
||||||
projectId={projectId}
|
<Box sx={{ marginRight: 'auto' }}>
|
||||||
state={filterState}
|
<ProjectOverviewFilters
|
||||||
onChange={setTableState}
|
project={projectId}
|
||||||
total={loading ? undefined : total}
|
onChange={setTableState}
|
||||||
/>
|
state={filterState}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<ProjectLifecycleFilters
|
||||||
|
projectId={projectId}
|
||||||
|
state={filterState}
|
||||||
|
onChange={setTableState}
|
||||||
|
total={loading ? undefined : total}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{isSmallScreen ? null : (
|
{isSmallScreen ? null : (
|
||||||
<ProjectFlagsSearch
|
<ProjectFlagsSearch
|
||||||
searchQuery={tableState.query || ''}
|
searchQuery={tableState.query || ''}
|
||||||
@ -580,13 +633,15 @@ export const ProjectFeatureToggles = ({
|
|||||||
onToggle={onToggleColumnVisibility}
|
onToggle={onToggleColumnVisibility}
|
||||||
/>
|
/>
|
||||||
</FilterRow>
|
</FilterRow>
|
||||||
<FilterRow>
|
{showArchived ? null : (
|
||||||
<ProjectOverviewFilters
|
<FilterRow>
|
||||||
project={projectId}
|
<ProjectOverviewFilters
|
||||||
onChange={setTableState}
|
project={projectId}
|
||||||
state={filterState}
|
onChange={setTableState}
|
||||||
/>
|
state={filterState}
|
||||||
</FilterRow>
|
/>
|
||||||
|
</FilterRow>
|
||||||
|
)}
|
||||||
{isSmallScreen ? (
|
{isSmallScreen ? (
|
||||||
<ProjectFlagsSearch
|
<ProjectFlagsSearch
|
||||||
searchQuery={tableState.query || ''}
|
searchQuery={tableState.query || ''}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { type FC, useState } from 'react';
|
import { type FC, type ReactNode, useState } from 'react';
|
||||||
import { Box, IconButton, Tooltip } from '@mui/material';
|
import { Box, IconButton, Tooltip } from '@mui/material';
|
||||||
import useLoading from 'hooks/useLoading';
|
import useLoading from 'hooks/useLoading';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
@ -12,11 +12,19 @@ type ProjectFeatureTogglesHeaderProps = {
|
|||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
totalItems?: number;
|
totalItems?: number;
|
||||||
environmentsToExport?: string[];
|
environmentsToExport?: string[];
|
||||||
|
actions?: ReactNode;
|
||||||
|
title?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ProjectFeatureTogglesHeader: FC<
|
export const ProjectFeatureTogglesHeader: FC<
|
||||||
ProjectFeatureTogglesHeaderProps
|
ProjectFeatureTogglesHeaderProps
|
||||||
> = ({ isLoading, totalItems, environmentsToExport }) => {
|
> = ({
|
||||||
|
isLoading,
|
||||||
|
totalItems,
|
||||||
|
environmentsToExport,
|
||||||
|
actions,
|
||||||
|
title = 'Feature flags',
|
||||||
|
}) => {
|
||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const headerLoadingRef = useLoading(isLoading || false);
|
const headerLoadingRef = useLoading(isLoading || false);
|
||||||
const [showExportDialog, setShowExportDialog] = useState(false);
|
const [showExportDialog, setShowExportDialog] = useState(false);
|
||||||
@ -24,11 +32,12 @@ export const ProjectFeatureTogglesHeader: FC<
|
|||||||
return (
|
return (
|
||||||
<Box ref={headerLoadingRef} aria-busy={isLoading} aria-live='polite'>
|
<Box ref={headerLoadingRef} aria-busy={isLoading} aria-live='polite'>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
titleElement={`Feature flags ${
|
titleElement={`${title} ${
|
||||||
totalItems !== undefined ? `(${totalItems})` : ''
|
totalItems !== undefined ? `(${totalItems})` : ''
|
||||||
}`}
|
}`}
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
|
{actions}
|
||||||
<Tooltip title='Export all project flags' arrow>
|
<Tooltip title='Export all project flags' arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
data-loading
|
data-loading
|
||||||
|
|||||||
@ -120,14 +120,18 @@ export const ProjectOverviewFilters: FC<ProjectOverviewFiltersProps> = ({
|
|||||||
singularOperators: ['IS', 'IS_NOT'],
|
singularOperators: ['IS', 'IS_NOT'],
|
||||||
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
|
pluralOperators: ['IS_ANY_OF', 'IS_NONE_OF'],
|
||||||
},
|
},
|
||||||
{
|
...(!flagsUiFilterRefactorEnabled
|
||||||
label: 'Show only archived',
|
? [
|
||||||
icon: 'inventory',
|
{
|
||||||
options: [{ label: 'True', value: 'true' }],
|
label: 'Show only archived',
|
||||||
filterKey: 'archived',
|
icon: 'inventory',
|
||||||
singularOperators: ['IS'],
|
options: [{ label: 'True', value: 'true' }],
|
||||||
pluralOperators: ['IS_ANY_OF'],
|
filterKey: 'archived',
|
||||||
},
|
singularOperators: ['IS'],
|
||||||
|
pluralOperators: ['IS_ANY_OF'],
|
||||||
|
} satisfies IFilterItem,
|
||||||
|
]
|
||||||
|
: []),
|
||||||
];
|
];
|
||||||
|
|
||||||
setAvailableFilters(availableFilters);
|
setAvailableFilters(availableFilters);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user