mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Feature toggle types list (#4260)
## About the changes 
This commit is contained in:
		
							parent
							
								
									35fbd8f271
								
							
						
					
					
						commit
						ef495a35ee
					
				@ -5,12 +5,11 @@ import { IRole, PredefinedRoleType } from 'interfaces/role';
 | 
			
		||||
import useToast from 'hooks/useToast';
 | 
			
		||||
import { formatUnknownError } from 'utils/formatUnknownError';
 | 
			
		||||
import { PageContent } from 'component/common/PageContent/PageContent';
 | 
			
		||||
import { useMediaQuery } from '@mui/material';
 | 
			
		||||
import { useTheme, useMediaQuery } from '@mui/material';
 | 
			
		||||
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
 | 
			
		||||
import { useFlexLayout, useSortBy, useTable } from 'react-table';
 | 
			
		||||
import { sortTypes } from 'utils/sortTypes';
 | 
			
		||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
 | 
			
		||||
import theme from 'themes/theme';
 | 
			
		||||
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
 | 
			
		||||
import { useSearch } from 'hooks/useSearch';
 | 
			
		||||
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
 | 
			
		||||
@ -42,6 +41,7 @@ export const RolesTable = ({
 | 
			
		||||
    setSelectedRole,
 | 
			
		||||
}: IRolesTableProps) => {
 | 
			
		||||
    const { setToastData, setToastApiError } = useToast();
 | 
			
		||||
    const theme = useTheme();
 | 
			
		||||
 | 
			
		||||
    const { roles, projectRoles, refetch, loading } = useRoles();
 | 
			
		||||
    const { removeRole } = useRolesApi();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										190
									
								
								frontend/src/component/featureTypes/FeatureTypesList.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								frontend/src/component/featureTypes/FeatureTypesList.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,190 @@
 | 
			
		||||
import { useMemo } from 'react';
 | 
			
		||||
import { useSortBy, useTable } from 'react-table';
 | 
			
		||||
import { sortTypes } from 'utils/sortTypes';
 | 
			
		||||
import { PageContent } from 'component/common/PageContent/PageContent';
 | 
			
		||||
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
 | 
			
		||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
 | 
			
		||||
import { Box, Typography, useMediaQuery, useTheme } from '@mui/material';
 | 
			
		||||
import {
 | 
			
		||||
    Table,
 | 
			
		||||
    TableBody,
 | 
			
		||||
    TableCell,
 | 
			
		||||
    TableRow,
 | 
			
		||||
    SortableTableHeader,
 | 
			
		||||
} from 'component/common/Table';
 | 
			
		||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
 | 
			
		||||
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
 | 
			
		||||
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
 | 
			
		||||
import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell';
 | 
			
		||||
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
 | 
			
		||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
 | 
			
		||||
import { Edit } from '@mui/icons-material';
 | 
			
		||||
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
 | 
			
		||||
 | 
			
		||||
export const FeatureTypesList = () => {
 | 
			
		||||
    const { featureTypes, loading } = useFeatureTypes();
 | 
			
		||||
    const theme = useTheme();
 | 
			
		||||
    const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
 | 
			
		||||
 | 
			
		||||
    const columns = useMemo(
 | 
			
		||||
        () => [
 | 
			
		||||
            {
 | 
			
		||||
                accessor: 'id',
 | 
			
		||||
                Cell: ({ value }: { value: string }) => {
 | 
			
		||||
                    const IconComponent = getFeatureTypeIcons(value);
 | 
			
		||||
                    return (
 | 
			
		||||
                        <IconCell
 | 
			
		||||
                            icon={
 | 
			
		||||
                                <IconComponent
 | 
			
		||||
                                    data-loading="true"
 | 
			
		||||
                                    color="action"
 | 
			
		||||
                                />
 | 
			
		||||
                            }
 | 
			
		||||
                        />
 | 
			
		||||
                    );
 | 
			
		||||
                },
 | 
			
		||||
                width: 50,
 | 
			
		||||
                disableSortBy: true,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Name',
 | 
			
		||||
                accessor: 'name',
 | 
			
		||||
                minWidth: 125,
 | 
			
		||||
                Cell: TextCell,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Description',
 | 
			
		||||
                accessor: 'description',
 | 
			
		||||
                width: '80%',
 | 
			
		||||
                Cell: ({ value }: { value: string }) => (
 | 
			
		||||
                    <Typography
 | 
			
		||||
                        component="div"
 | 
			
		||||
                        variant="body2"
 | 
			
		||||
                        color="text.secondary"
 | 
			
		||||
                        lineHeight={2}
 | 
			
		||||
                    >
 | 
			
		||||
                        <TextCell lineClamp={1}>{value}</TextCell>
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                ),
 | 
			
		||||
                disableSortBy: true,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Lifetime',
 | 
			
		||||
                accessor: 'lifetimeDays',
 | 
			
		||||
                Cell: ({ value }: { value: number }) => {
 | 
			
		||||
                    if (value) {
 | 
			
		||||
                        return (
 | 
			
		||||
                            <TextCell>
 | 
			
		||||
                                {value === 1 ? '1 day' : `${value} days`}
 | 
			
		||||
                            </TextCell>
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return <TextCell>doesn't expire</TextCell>;
 | 
			
		||||
                },
 | 
			
		||||
                sortInverted: true,
 | 
			
		||||
                minWidth: 150,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                Header: 'Actions',
 | 
			
		||||
                Cell: ({ row: { original: featureType } }: any) => (
 | 
			
		||||
                    <Box sx={theme => ({ padding: theme.spacing(0.5, 0) })}>
 | 
			
		||||
                        <ActionCell>
 | 
			
		||||
                            <PermissionIconButton
 | 
			
		||||
                                disabled={!featureType.id}
 | 
			
		||||
                                data-loading="true"
 | 
			
		||||
                                onClick={() => {}}
 | 
			
		||||
                                permission={ADMIN}
 | 
			
		||||
                                tooltipProps={{
 | 
			
		||||
                                    title: 'Edit feature toggle type',
 | 
			
		||||
                                }}
 | 
			
		||||
                            >
 | 
			
		||||
                                <Edit />
 | 
			
		||||
                            </PermissionIconButton>
 | 
			
		||||
                        </ActionCell>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                ),
 | 
			
		||||
                disableSortBy: true,
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
        []
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const data = useMemo(
 | 
			
		||||
        () =>
 | 
			
		||||
            loading
 | 
			
		||||
                ? Array(5).fill({
 | 
			
		||||
                      id: '',
 | 
			
		||||
                      name: 'Loading...',
 | 
			
		||||
                      description: 'Loading...',
 | 
			
		||||
                      lifetimeDays: 1,
 | 
			
		||||
                  })
 | 
			
		||||
                : featureTypes,
 | 
			
		||||
        [loading, featureTypes]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const {
 | 
			
		||||
        getTableProps,
 | 
			
		||||
        getTableBodyProps,
 | 
			
		||||
        headerGroups,
 | 
			
		||||
        rows,
 | 
			
		||||
        prepareRow,
 | 
			
		||||
        setHiddenColumns,
 | 
			
		||||
    } = useTable(
 | 
			
		||||
        {
 | 
			
		||||
            columns: columns as any[],
 | 
			
		||||
            data,
 | 
			
		||||
            sortTypes,
 | 
			
		||||
            autoResetSortBy: false,
 | 
			
		||||
            disableSortRemove: true,
 | 
			
		||||
        },
 | 
			
		||||
        useSortBy
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    useConditionallyHiddenColumns(
 | 
			
		||||
        [
 | 
			
		||||
            {
 | 
			
		||||
                condition: isSmallScreen,
 | 
			
		||||
                columns: ['description'],
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
        setHiddenColumns,
 | 
			
		||||
        columns
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <PageContent
 | 
			
		||||
            isLoading={loading}
 | 
			
		||||
            header={
 | 
			
		||||
                <PageHeader>
 | 
			
		||||
                    <Typography
 | 
			
		||||
                        component="h2"
 | 
			
		||||
                        sx={theme => ({
 | 
			
		||||
                            fontSize: theme.fontSizes.mainHeader,
 | 
			
		||||
                        })}
 | 
			
		||||
                    >
 | 
			
		||||
                        Feature toggle types
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                </PageHeader>
 | 
			
		||||
            }
 | 
			
		||||
        >
 | 
			
		||||
            <Table {...getTableProps()}>
 | 
			
		||||
                <SortableTableHeader headerGroups={headerGroups} />
 | 
			
		||||
                <TableBody {...getTableBodyProps()}>
 | 
			
		||||
                    {rows.map(row => {
 | 
			
		||||
                        prepareRow(row);
 | 
			
		||||
                        return (
 | 
			
		||||
                            <TableRow hover {...row.getRowProps()}>
 | 
			
		||||
                                {row.cells.map(cell => (
 | 
			
		||||
                                    <TableCell {...cell.getCellProps()}>
 | 
			
		||||
                                        {cell.render('Cell')}
 | 
			
		||||
                                    </TableCell>
 | 
			
		||||
                                ))}
 | 
			
		||||
                            </TableRow>
 | 
			
		||||
                        );
 | 
			
		||||
                    })}
 | 
			
		||||
                </TableBody>
 | 
			
		||||
            </Table>
 | 
			
		||||
        </PageContent>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
@ -193,6 +193,17 @@ exports[`returns all baseRoutes 1`] = `
 | 
			
		||||
    "title": "Context fields",
 | 
			
		||||
    "type": "protected",
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "component": [Function],
 | 
			
		||||
    "flag": "configurableFeatureTypeLifetimes",
 | 
			
		||||
    "menu": {
 | 
			
		||||
      "advanced": true,
 | 
			
		||||
      "mobile": true,
 | 
			
		||||
    },
 | 
			
		||||
    "path": "/feature-toggle-type",
 | 
			
		||||
    "title": "Feature toggle types",
 | 
			
		||||
    "type": "protected",
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "component": [Function],
 | 
			
		||||
    "menu": {},
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,7 @@ import { LazyAdmin } from 'component/admin/LazyAdmin';
 | 
			
		||||
import { LazyProject } from 'component/project/Project/LazyProject';
 | 
			
		||||
import { AdminRedirect } from 'component/admin/AdminRedirect';
 | 
			
		||||
import { LoginHistory } from 'component/loginHistory/LoginHistory';
 | 
			
		||||
import { FeatureTypesList } from 'component/featureTypes/FeatureTypesList';
 | 
			
		||||
 | 
			
		||||
export const routes: IRoute[] = [
 | 
			
		||||
    // Splash
 | 
			
		||||
@ -209,6 +210,16 @@ export const routes: IRoute[] = [
 | 
			
		||||
        menu: { mobile: true, advanced: true },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Feature types
 | 
			
		||||
    {
 | 
			
		||||
        path: '/feature-toggle-type',
 | 
			
		||||
        title: 'Feature toggle types',
 | 
			
		||||
        component: FeatureTypesList,
 | 
			
		||||
        type: 'protected',
 | 
			
		||||
        menu: { mobile: true, advanced: true },
 | 
			
		||||
        flag: 'configurableFeatureTypeLifetimes',
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Strategies
 | 
			
		||||
    {
 | 
			
		||||
        path: '/strategies/create',
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ export interface IFlags {
 | 
			
		||||
    customRootRoles?: boolean;
 | 
			
		||||
    strategyVariant?: boolean;
 | 
			
		||||
    newProjectLayout?: boolean;
 | 
			
		||||
    configurableFeatureTypeLifetimes?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IVersionInfo {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user