1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

Project Archive

This commit is contained in:
andreas-unleash 2022-06-06 12:12:28 +03:00
parent b622767ae9
commit 406c187372
5 changed files with 201 additions and 89 deletions

View File

@ -10,7 +10,6 @@ import {
TableSearch,
} from 'component/common/Table';
import {
SortingRule,
useFlexLayout,
useGlobalFilter,
useSortBy,
@ -23,7 +22,6 @@ import { useEffect, useMemo, useState } from 'react';
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
import { DateCell } from 'component/common/Table/cells/DateCell/DateCell';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useFeaturesArchive } from '../../../hooks/api/getters/useFeaturesArchive/useFeaturesArchive';
import { FeatureTypeCell } from '../../common/Table/cells/FeatureTypeCell/FeatureTypeCell';
import { FeatureSeenCell } from '../../common/Table/cells/FeatureSeenCell/FeatureSeenCell';
import { LinkCell } from '../../common/Table/cells/LinkCell/LinkCell';
@ -31,28 +29,61 @@ import { FeatureStaleCell } from '../../feature/FeatureToggleList/FeatureStaleCe
import { TimeAgoCell } from '../../common/Table/cells/TimeAgoCell/TimeAgoCell';
import { ReviveArchivedFeatureCell } from 'component/common/Table/cells/ReviveArchivedFeatureCell/ReviveArchivedFeatureCell';
import { useStyles } from '../../feature/FeatureToggleList/styles';
import { useSearchParams } from 'react-router-dom';
import { useLocalStorage } from '../../../hooks/useLocalStorage';
import { useVirtualizedRange } from '../../../hooks/useVirtualizedRange';
import {
featuresPlaceholder,
PageQueryType,
} from '../../feature/FeatureToggleList/FeatureToggleListTable';
import theme from 'themes/theme';
import { FeatureSchema } from '../../../openapi';
import { useFeatureArchiveApi } from '../../../hooks/api/actions/useFeatureArchiveApi/useReviveFeatureApi';
import useToast from '../../../hooks/useToast';
const defaultSort: SortingRule<string> = { id: 'createdAt', desc: true };
export interface IFeaturesArchiveTableProps {
archivedFeatures: FeatureSchema[];
refetch: any;
loading: boolean;
inProject: boolean;
storedParams: any;
setStoredParams: any;
searchParams: any;
setSearchParams: any;
}
export const ArchiveTable = () => {
export const ArchiveTable = ({
archivedFeatures = [],
loading,
inProject,
refetch,
storedParams,
setStoredParams,
searchParams,
setSearchParams,
}: IFeaturesArchiveTableProps) => {
const rowHeight = theme.shape.tableRowHeight;
const { classes } = useStyles();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const isMediumScreen = useMediaQuery(theme.breakpoints.down('lg'));
const [searchParams, setSearchParams] = useSearchParams();
const [storedParams, setStoredParams] = useLocalStorage(
'ArchiveTable:v1',
defaultSort
);
const { archivedFeatures = [], loading } = useFeaturesArchive();
const { setToastData, setToastApiError } = useToast();
const { reviveFeature } = useFeatureArchiveApi();
const onRevive = (feature: string) => {
reviveFeature(feature)
.then(refetch)
.then(() =>
setToastData({
type: 'success',
title: "And we're back!",
text: 'The feature toggle has been revived.',
confetti: true,
})
)
.catch(e => setToastApiError(e.toString()));
};
const columns = useColumns(onRevive);
const data = useMemo(
() =>
archivedFeatures?.length === 0 && loading
@ -85,7 +116,7 @@ export const ArchiveTable = () => {
setHiddenColumns,
} = useTable(
{
columns: COLUMNS as any,
columns: columns as any,
data: data as any,
initialState,
sortTypes,
@ -134,7 +165,9 @@ export const ArchiveTable = () => {
isLoading={loading}
header={
<PageHeader
title={`Archived (${
title={`${
inProject ? 'Project Features Archive' : 'Archived'
} (${
rows.length < data.length
? `${rows.length} of ${data.length}`
: data.length
@ -216,72 +249,78 @@ export const ArchiveTable = () => {
);
};
const COLUMNS = [
{
id: 'Seen',
Header: 'Seen',
maxWidth: 85,
canSort: true,
Cell: FeatureSeenCell,
disableGlobalFilter: true,
},
{
id: 'Type',
Header: 'Type',
maxWidth: 85,
canSort: true,
Cell: FeatureTypeCell,
disableGlobalFilter: true,
},
{
Header: 'Feature toggle Name',
accessor: 'name',
maxWidth: 150,
Cell: ({ value, row: { original } }: any) => (
<HighlightCell value={value} subtitle={original.description} />
),
sortType: 'alphanumeric',
},
{
Header: 'Created',
accessor: 'createdAt',
maxWidth: 150,
Cell: DateCell,
sortType: 'date',
disableGlobalFilter: true,
},
{
Header: 'Archived',
accessor: 'archivedAt',
maxWidth: 150,
Cell: TimeAgoCell,
sortType: 'date',
disableGlobalFilter: true,
},
{
Header: 'Project ID',
accessor: 'project',
sortType: 'alphanumeric',
maxWidth: 150,
Cell: ({ value }: any) => (
<LinkCell title={value} to={`/projects/${value}}`} />
),
},
{
Header: 'Status',
accessor: 'stale',
Cell: FeatureStaleCell,
sortType: 'boolean',
maxWidth: 120,
disableGlobalFilter: true,
},
{
Header: 'Actions',
id: 'Actions',
align: 'center',
maxWidth: 85,
canSort: false,
disableGlobalFilter: true,
Cell: ReviveArchivedFeatureCell,
},
];
const useColumns = (onRevive: any) => {
return [
{
id: 'Seen',
Header: 'Seen',
maxWidth: 85,
canSort: true,
Cell: FeatureSeenCell,
disableGlobalFilter: true,
},
{
id: 'Type',
Header: 'Type',
maxWidth: 85,
canSort: true,
Cell: FeatureTypeCell,
disableGlobalFilter: true,
},
{
Header: 'Feature toggle Name',
accessor: 'name',
maxWidth: 150,
Cell: ({ value, row: { original } }: any) => (
<HighlightCell value={value} subtitle={original.description} />
),
sortType: 'alphanumeric',
},
{
Header: 'Created',
accessor: 'createdAt',
maxWidth: 150,
Cell: DateCell,
sortType: 'date',
disableGlobalFilter: true,
},
{
Header: 'Archived',
accessor: 'archivedAt',
maxWidth: 150,
Cell: TimeAgoCell,
sortType: 'date',
disableGlobalFilter: true,
},
{
Header: 'Project ID',
accessor: 'project',
sortType: 'alphanumeric',
maxWidth: 150,
Cell: ({ value }: any) => (
<LinkCell title={value} to={`/projects/${value}}`} />
),
},
{
Header: 'Status',
accessor: 'stale',
Cell: FeatureStaleCell,
sortType: 'boolean',
maxWidth: 120,
disableGlobalFilter: true,
},
{
Header: 'Actions',
id: 'Actions',
align: 'center',
maxWidth: 85,
canSort: false,
disableGlobalFilter: true,
Cell: ({ row: { original } }: any) => (
<ReviveArchivedFeatureCell
onRevive={() => onRevive(original.name)}
/>
),
},
];
};

View File

@ -0,0 +1,34 @@
import { useFeaturesArchive } from '../../hooks/api/getters/useFeaturesArchive/useFeaturesArchive';
import { ArchiveTable } from './ArchiveTable/ArchiveTable';
import { useSearchParams } from 'react-router-dom';
import { useLocalStorage } from '../../hooks/useLocalStorage';
import { SortingRule } from 'react-table';
const defaultSort: SortingRule<string> = { id: 'createdAt', desc: true };
export const FeaturesArchiveTable = () => {
const {
archivedFeatures = [],
loading,
refetchArchived,
} = useFeaturesArchive();
const [searchParams, setSearchParams] = useSearchParams();
const [storedParams, setStoredParams] = useLocalStorage(
'FeaturesArchiveTable:v1',
defaultSort
);
return (
<ArchiveTable
archivedFeatures={archivedFeatures}
loading={loading}
searchParams={searchParams}
setSearchParams={setSearchParams}
storedParams={storedParams}
setStoredParams={setStoredParams}
refetch={refetchArchived}
inProject={false}
/>
);
};

View File

@ -0,0 +1,40 @@
import { ArchiveTable } from './ArchiveTable/ArchiveTable';
import { useSearchParams } from 'react-router-dom';
import { useLocalStorage } from '../../hooks/useLocalStorage';
import { SortingRule } from 'react-table';
import { useProjectFeaturesArchive } from '../../hooks/api/getters/useProjectFeaturesArchive/useProjectFeaturesArchive';
const defaultSort: SortingRule<string> = { id: 'archivedAt', desc: true };
interface IProjectFeaturesTable {
projectId: string;
}
export const ProjectFeaturesArchiveTable = ({
projectId,
}: IProjectFeaturesTable) => {
const {
archivedFeatures = [],
refetchArchived,
loading,
} = useProjectFeaturesArchive(projectId);
const [searchParams, setSearchParams] = useSearchParams();
const [storedParams, setStoredParams] = useLocalStorage(
'ProjectFeaturesArchiveTable:v1',
defaultSort
);
return (
<ArchiveTable
archivedFeatures={archivedFeatures}
loading={loading}
searchParams={searchParams}
setSearchParams={setSearchParams}
storedParams={storedParams}
setStoredParams={setStoredParams}
refetch={refetchArchived}
inProject={true}
/>
);
};

View File

@ -51,7 +51,7 @@ import { IRoute } from 'interfaces/route';
import { EnvironmentTable } from 'component/environments/EnvironmentTable/EnvironmentTable';
import { SegmentTable } from 'component/segments/SegmentTable/SegmentTable';
import RedirectAdminInvoices from 'component/admin/billing/RedirectAdminInvoices/RedirectAdminInvoices';
import { ArchiveTable } from '../archive/ArchiveTable/ArchiveTable';
import { FeaturesArchiveTable } from '../archive/FeaturesArchiveTable';
export const routes: IRoute[] = [
// Splash
@ -375,7 +375,7 @@ export const routes: IRoute[] = [
{
path: '/archive',
title: 'Archived toggles',
component: ArchiveTable,
component: FeaturesArchiveTable,
type: 'protected',
menu: {},
},

View File

@ -1,5 +1,4 @@
import { ProjectFeaturesArchiveList } from 'component/archive/ProjectFeaturesArchiveList';
import { usePageTitle } from 'hooks/usePageTitle';
import { ProjectFeaturesArchiveTable } from '../../../archive/ProjectFeaturesArchiveTable';
interface IProjectFeaturesArchiveProps {
projectId: string;
@ -8,7 +7,7 @@ interface IProjectFeaturesArchiveProps {
export const ProjectFeaturesArchive = ({
projectId,
}: IProjectFeaturesArchiveProps) => {
usePageTitle('Project Archived Features');
// usePageTitle('Project Archived Features');
return <ProjectFeaturesArchiveList projectId={projectId} />;
return <ProjectFeaturesArchiveTable projectId={projectId} />;
};