1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-11-24 20:06:55 +01:00
unleash.unleash/frontend/src/component/feature/FeatureToggleList/FeatureToggleArchiveList.tsx

179 lines
6.3 KiB
TypeScript

import { Dispatch, SetStateAction, useContext, VFC } from 'react';
import classnames from 'classnames';
import { Link } from 'react-router-dom';
import { List, ListItem } from '@mui/material';
import useMediaQuery from '@mui/material/useMediaQuery';
import { IFlags } from 'interfaces/uiConfig';
import { SearchField } from 'component/common/SearchField/SearchField';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { PageContent } from 'component/common/PageContent/PageContent';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import AccessContext from 'contexts/AccessContext';
import { IFeaturesFilter } from 'hooks/useFeaturesFilter';
import { FeatureToggleListItem } from './FeatureToggleListItem/FeatureToggleListItem';
import { FeatureToggleListActions } from './FeatureToggleListActions/FeatureToggleListActions';
import { CreateFeatureButton } from '../CreateFeatureButton/CreateFeatureButton';
import { IFeaturesSort } from 'hooks/useFeaturesSort';
import { FeatureSchema } from 'openapi';
import { useStyles } from './styles';
interface IFeatureToggleListProps {
features: FeatureSchema[];
loading?: boolean;
flags?: IFlags;
filter: IFeaturesFilter;
setFilter: Dispatch<SetStateAction<IFeaturesFilter>>;
sort: IFeaturesSort;
setSort: Dispatch<SetStateAction<IFeaturesSort>>;
onRevive?: (feature: string) => void;
inProject?: boolean;
isArchive?: boolean;
}
const loadingFeaturesPlaceholder: FeatureSchema[] = Array(10)
.fill({
createdAt: '2021-03-19T09:16:21.329Z',
description: ' ',
enabled: true,
lastSeenAt: '2021-03-24T10:46:38.036Z',
name: '',
project: 'default',
stale: true,
strategies: [],
variants: [],
type: 'release',
archived: false,
environments: [],
impressionData: false,
})
.map((feature, index) => ({ ...feature, name: `${index}` })); // ID for React key
export const FeatureToggleList: VFC<IFeatureToggleListProps> = ({
features,
onRevive,
inProject,
isArchive,
loading,
flags,
filter,
setFilter,
sort,
setSort,
}) => {
const { hasAccess } = useContext(AccessContext);
const { classes: styles } = useStyles();
const smallScreen = useMediaQuery('(max-width:800px)');
const mobileView = useMediaQuery('(max-width:600px)');
const setFilterQuery = (v: string) => {
const query = v && typeof v === 'string' ? v.trim() : '';
setFilter(prev => ({ ...prev, query }));
};
const renderFeatures = () => {
if (loading) {
return loadingFeaturesPlaceholder.map(feature => (
<FeatureToggleListItem
key={feature.name}
feature={feature}
onRevive={onRevive}
hasAccess={hasAccess}
className={'skeleton'}
flags={flags}
/>
));
}
return (
<ConditionallyRender
condition={features.length > 0}
show={features.map(feature => (
<FeatureToggleListItem
key={feature.name}
feature={feature}
onRevive={onRevive}
hasAccess={hasAccess}
flags={flags}
inProject={inProject}
/>
))}
elseShow={
<ListItem className={styles.emptyStateListItem}>
No archived features.
</ListItem>
}
/>
);
};
const searchResultsHeader = filter.query
? ` (${features.length} matches)`
: '';
const headerTitle = isArchive
? inProject
? `Archived project features ${searchResultsHeader}`
: `Archived features ${searchResultsHeader}`
: `Features ${searchResultsHeader}`;
return (
<div>
<div
className={classnames(styles.searchBarContainer, {
dense: inProject,
})}
>
<SearchField
initialValue={filter.query}
updateValue={setFilterQuery}
showValueChip={!mobileView}
className={classnames(styles.searchBar, {
skeleton: loading,
})}
/>
<ConditionallyRender
condition={!mobileView && !isArchive}
show={<Link to="/archive">Archive</Link>}
/>
</div>
<PageContent
header={
<PageHeader
loading={loading}
title={headerTitle}
actions={
<div className={styles.actionsContainer}>
<ConditionallyRender
condition={!smallScreen}
show={
<FeatureToggleListActions
filter={filter}
setFilter={setFilter}
sort={sort}
setSort={setSort}
loading={loading}
inProject={inProject}
/>
}
/>
<ConditionallyRender
condition={!isArchive}
show={
<CreateFeatureButton
filter={filter}
loading={Boolean(loading)}
/>
}
/>
</div>
}
/>
}
>
<List>{renderFeatures()}</List>
</PageContent>
</div>
);
};