mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-12 01:17:04 +02:00
refactor: port some things to TS (#843)
* refactor: port useSort to TS * refactor: port loadingFeatures to TS * refactor: port admin index to TS * refactor: port TagTypeList to TS * refactor: merge route interfaces * refactor: port common utils to TS * refactor: fix snapshot date typo * refactor: port Reporting utils to TS * refactor: improve PermissionIconButton prop types
This commit is contained in:
parent
73652b66e9
commit
a088866124
@ -9,15 +9,17 @@ import {
|
||||
sortFeaturesByExpiredAtDescending,
|
||||
sortFeaturesByStatusAscending,
|
||||
sortFeaturesByStatusDescending,
|
||||
} from './utils';
|
||||
} from 'component/Reporting/utils';
|
||||
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
|
||||
|
||||
const getTestData = () => [
|
||||
const getTestData = (): IFeatureToggleListItem[] => [
|
||||
{
|
||||
name: 'abe',
|
||||
createdAt: '2021-02-14T02:42:34.515Z',
|
||||
lastSeenAt: '2021-02-21T19:34:21.830Z',
|
||||
type: 'release',
|
||||
stale: false,
|
||||
environments: [],
|
||||
},
|
||||
{
|
||||
name: 'bet',
|
||||
@ -25,6 +27,7 @@ const getTestData = () => [
|
||||
lastSeenAt: '2021-02-19T19:34:21.830Z',
|
||||
type: 'release',
|
||||
stale: false,
|
||||
environments: [],
|
||||
},
|
||||
{
|
||||
name: 'cat',
|
||||
@ -32,6 +35,7 @@ const getTestData = () => [
|
||||
lastSeenAt: '2021-02-18T19:34:21.830Z',
|
||||
type: 'experiment',
|
||||
stale: true,
|
||||
environments: [],
|
||||
},
|
||||
];
|
||||
|
@ -4,38 +4,54 @@ import differenceInDays from 'date-fns/differenceInDays';
|
||||
import { EXPERIMENT, OPERATIONAL, RELEASE } from 'constants/featureToggleTypes';
|
||||
|
||||
import { FOURTYDAYS, SEVENDAYS } from './constants';
|
||||
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
|
||||
|
||||
export const toggleExpiryByTypeMap = {
|
||||
export const toggleExpiryByTypeMap: Record<string, number> = {
|
||||
[EXPERIMENT]: FOURTYDAYS,
|
||||
[RELEASE]: FOURTYDAYS,
|
||||
[OPERATIONAL]: SEVENDAYS,
|
||||
};
|
||||
|
||||
export const applyCheckedToFeatures = (features, checkedState) =>
|
||||
features.map(feature => ({ ...feature, checked: checkedState }));
|
||||
export interface IFeatureToggleListItemCheck extends IFeatureToggleListItem {
|
||||
checked: boolean;
|
||||
}
|
||||
|
||||
export const getCheckedState = (name, features) => {
|
||||
export const applyCheckedToFeatures = (
|
||||
features: IFeatureToggleListItem[],
|
||||
checkedState: boolean
|
||||
): IFeatureToggleListItemCheck[] => {
|
||||
return features.map(feature => ({
|
||||
...feature,
|
||||
checked: checkedState,
|
||||
}));
|
||||
};
|
||||
|
||||
export const getCheckedState = (
|
||||
name: string,
|
||||
features: IFeatureToggleListItemCheck[]
|
||||
) => {
|
||||
const feature = features.find(feature => feature.name === name);
|
||||
|
||||
if (feature) {
|
||||
return feature.checked ? feature.checked : false;
|
||||
return feature.checked;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getDiffInDays = (date, now) =>
|
||||
export const getDiffInDays = (date: Date, now: Date) =>
|
||||
Math.abs(differenceInDays(date, now));
|
||||
|
||||
export const formatProjectOptions = projects =>
|
||||
projects.map(project => ({ key: project.id, label: project.name }));
|
||||
|
||||
export const expired = (diff, type) => {
|
||||
export const expired = (diff: number, type: string) => {
|
||||
if (diff >= toggleExpiryByTypeMap[type]) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getObjectProperties = (target, ...keys) => {
|
||||
const newObject = {};
|
||||
export const getObjectProperties = <T extends object>(
|
||||
target: T,
|
||||
...keys: (keyof T)[]
|
||||
): Partial<T> => {
|
||||
const newObject: Partial<T> = {};
|
||||
|
||||
keys.forEach(key => {
|
||||
if (target[key] !== undefined) {
|
||||
@ -46,7 +62,9 @@ export const getObjectProperties = (target, ...keys) => {
|
||||
return newObject;
|
||||
};
|
||||
|
||||
export const sortFeaturesByNameAscending = features => {
|
||||
export const sortFeaturesByNameAscending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
sorted.sort((a, b) => {
|
||||
if (a.name < b.name) {
|
||||
@ -60,10 +78,14 @@ export const sortFeaturesByNameAscending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByNameDescending = features =>
|
||||
export const sortFeaturesByNameDescending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] =>
|
||||
sortFeaturesByNameAscending([...features]).reverse();
|
||||
|
||||
export const sortFeaturesByLastSeenAscending = features => {
|
||||
export const sortFeaturesByLastSeenAscending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
sorted.sort((a, b) => {
|
||||
if (!a.lastSeenAt) return -1;
|
||||
@ -77,10 +99,14 @@ export const sortFeaturesByLastSeenAscending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByLastSeenDescending = features =>
|
||||
export const sortFeaturesByLastSeenDescending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] =>
|
||||
sortFeaturesByLastSeenAscending([...features]).reverse();
|
||||
|
||||
export const sortFeaturesByCreatedAtAscending = features => {
|
||||
export const sortFeaturesByCreatedAtAscending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
sorted.sort((a, b) => {
|
||||
const dateA = parseISO(a.createdAt);
|
||||
@ -91,10 +117,14 @@ export const sortFeaturesByCreatedAtAscending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByCreatedAtDescending = features =>
|
||||
export const sortFeaturesByCreatedAtDescending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] =>
|
||||
sortFeaturesByCreatedAtAscending([...features]).reverse();
|
||||
|
||||
export const sortFeaturesByExpiredAtAscending = features => {
|
||||
export const sortFeaturesByExpiredAtAscending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
sorted.sort((a, b) => {
|
||||
const now = new Date();
|
||||
@ -120,7 +150,9 @@ export const sortFeaturesByExpiredAtAscending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByExpiredAtDescending = features => {
|
||||
export const sortFeaturesByExpiredAtDescending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
const now = new Date();
|
||||
sorted.sort((a, b) => {
|
||||
@ -146,7 +178,9 @@ export const sortFeaturesByExpiredAtDescending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByStatusAscending = features => {
|
||||
export const sortFeaturesByStatusAscending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] => {
|
||||
const sorted = [...features];
|
||||
sorted.sort((a, b) => {
|
||||
if (a.stale) return 1;
|
||||
@ -156,15 +190,17 @@ export const sortFeaturesByStatusAscending = features => {
|
||||
return sorted;
|
||||
};
|
||||
|
||||
export const sortFeaturesByStatusDescending = features =>
|
||||
export const sortFeaturesByStatusDescending = (
|
||||
features: IFeatureToggleListItem[]
|
||||
): IFeatureToggleListItem[] =>
|
||||
sortFeaturesByStatusAscending([...features]).reverse();
|
||||
|
||||
export const pluralize = (items, word) => {
|
||||
export const pluralize = (items: number, word: string): string => {
|
||||
if (items === 1) return `${items} ${word}`;
|
||||
return `${items} ${word}s`;
|
||||
};
|
||||
|
||||
export const getDates = dateString => {
|
||||
export const getDates = (dateString: string): [Date, Date] => {
|
||||
const date = parseISO(dateString);
|
||||
const now = new Date();
|
||||
|
@ -69,7 +69,7 @@ const Constraint = ({
|
||||
show={
|
||||
<div className={styles.btnContainer}>
|
||||
<PermissionIconButton
|
||||
onClick={editCallback}
|
||||
onClick={editCallback!}
|
||||
permission={UPDATE_FEATURE}
|
||||
projectId={projectId}
|
||||
disabled={disabledEdit}
|
||||
@ -78,7 +78,7 @@ const Constraint = ({
|
||||
</PermissionIconButton>
|
||||
|
||||
<PermissionIconButton
|
||||
onClick={deleteCallback}
|
||||
onClick={deleteCallback!}
|
||||
permission={UPDATE_FEATURE}
|
||||
projectId={projectId}
|
||||
>
|
||||
|
@ -100,7 +100,7 @@ export const ConstraintAccordionViewHeader = ({
|
||||
condition={Boolean(onEditClick)}
|
||||
show={
|
||||
<PermissionIconButton
|
||||
onClick={onEditClick}
|
||||
onClick={onEditClick!}
|
||||
permission={UPDATE_FEATURE_STRATEGY}
|
||||
projectId={projectId}
|
||||
environmentId={environmentId}
|
||||
@ -114,7 +114,7 @@ export const ConstraintAccordionViewHeader = ({
|
||||
condition={Boolean(onDeleteClick)}
|
||||
show={
|
||||
<PermissionIconButton
|
||||
onClick={onDeleteClick}
|
||||
onClick={onDeleteClick!}
|
||||
permission={UPDATE_FEATURE_STRATEGY}
|
||||
projectId={projectId}
|
||||
environmentId={environmentId}
|
||||
|
@ -1,26 +1,37 @@
|
||||
import { IconButton, Tooltip, IconButtonProps } from '@material-ui/core';
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext, ReactNode } from 'react';
|
||||
import AccessContext from 'contexts/AccessContext';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
interface IPermissionIconButtonProps extends IconButtonProps {
|
||||
interface IPermissionIconButtonProps {
|
||||
permission: string;
|
||||
Icon?: React.ElementType;
|
||||
onClick?: (e: any) => void;
|
||||
projectId?: string;
|
||||
environmentId?: string;
|
||||
className?: string;
|
||||
title?: string;
|
||||
children?: ReactNode;
|
||||
disabled?: boolean;
|
||||
hidden?: boolean;
|
||||
type?: 'button';
|
||||
edge?: IconButtonProps['edge'];
|
||||
}
|
||||
|
||||
const PermissionIconButton: React.FC<IPermissionIconButtonProps> = ({
|
||||
interface IButtonProps extends IPermissionIconButtonProps {
|
||||
onClick: (event: React.SyntheticEvent) => void;
|
||||
}
|
||||
|
||||
interface ILinkProps extends IPermissionIconButtonProps {
|
||||
component: typeof Link;
|
||||
to: string;
|
||||
}
|
||||
|
||||
const PermissionIconButton = ({
|
||||
permission,
|
||||
Icon,
|
||||
onClick,
|
||||
projectId,
|
||||
children,
|
||||
environmentId,
|
||||
...rest
|
||||
}) => {
|
||||
}: IButtonProps | ILinkProps) => {
|
||||
const { hasAccess } = useContext(AccessContext);
|
||||
let access;
|
||||
|
||||
@ -39,7 +50,7 @@ const PermissionIconButton: React.FC<IPermissionIconButtonProps> = ({
|
||||
return (
|
||||
<Tooltip title={tooltipText} arrow>
|
||||
<span>
|
||||
<IconButton onClick={onClick} disabled={!access} {...rest}>
|
||||
<IconButton disabled={!access} {...rest}>
|
||||
{children}
|
||||
</IconButton>
|
||||
</span>
|
||||
|
@ -1,17 +1,21 @@
|
||||
import { weightTypes } from '../feature/FeatureView/FeatureVariants/FeatureVariantsList/AddFeatureVariant/enums';
|
||||
import { IFlags } from 'interfaces/uiConfig';
|
||||
import { IRoute } from 'interfaces/route';
|
||||
import { IFeatureVariant } from 'interfaces/featureToggle';
|
||||
|
||||
export const filterByFlags = flags => r => {
|
||||
if (r.flag && !flags[r.flag]) {
|
||||
return false;
|
||||
export const filterByFlags = (flags: IFlags) => (r: IRoute) => {
|
||||
if (!r.flag) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
return (flags as unknown as Record<string, boolean>)[r.flag];
|
||||
};
|
||||
|
||||
export const scrollToTop = () => {
|
||||
window.scrollTo(0, 0);
|
||||
};
|
||||
|
||||
export const trim = value => {
|
||||
export const trim = (value: string): string => {
|
||||
if (value && value.trim) {
|
||||
return value.trim();
|
||||
} else {
|
||||
@ -19,7 +23,7 @@ export const trim = value => {
|
||||
}
|
||||
};
|
||||
|
||||
export function updateWeight(variants, totalWeight) {
|
||||
export function updateWeight(variants: IFeatureVariant[], totalWeight: number) {
|
||||
if (variants.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@ -48,7 +52,9 @@ export function updateWeight(variants, totalWeight) {
|
||||
throw new Error('There must be at least one variable variant');
|
||||
}
|
||||
|
||||
const percentage = parseInt(remainingPercentage / variableVariantCount);
|
||||
const percentage = parseInt(
|
||||
String(remainingPercentage / variableVariantCount)
|
||||
);
|
||||
|
||||
return variants.map(variant => {
|
||||
if (variant.weightType !== weightTypes.FIX) {
|
@ -1,4 +1,6 @@
|
||||
const loadingFeatures = [
|
||||
import { IFeatureToggle } from 'interfaces/featureToggle';
|
||||
|
||||
const loadingFeatures: Partial<IFeatureToggle>[] = [
|
||||
{
|
||||
createdAt: '2021-03-19T09:16:21.329Z',
|
||||
description: '',
|
||||
@ -6,7 +8,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'one',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -19,7 +20,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'two',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -32,7 +32,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'three',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -45,7 +44,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'four',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -58,7 +56,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'five',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -71,7 +68,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'six',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -84,7 +80,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'seven',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -97,7 +92,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'eight',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -110,7 +104,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'nine',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
||||
@ -123,7 +116,6 @@ const loadingFeatures = [
|
||||
lastSeenAt: '2021-03-24T10:46:38.036Z',
|
||||
name: 'ten',
|
||||
project: 'default',
|
||||
reviveName: 'cool-thing',
|
||||
stale: true,
|
||||
strategies: [],
|
||||
variants: [],
|
@ -1,11 +1,13 @@
|
||||
const loadingFeatures = [
|
||||
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
|
||||
|
||||
const loadingFeatures: IFeatureToggleListItem[] = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loading1',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -13,10 +15,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loadg2',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -24,10 +26,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loading3',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -35,10 +37,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loadi4',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -46,10 +48,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loadi5',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -57,10 +59,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loadg6',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -68,10 +70,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'loading7',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -79,10 +81,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'ln8',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
@ -90,10 +92,10 @@ const loadingFeatures = [
|
||||
{
|
||||
type: 'release',
|
||||
name: 'load9',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
environments: [
|
||||
{
|
||||
name: ':global:',
|
||||
displayName: 'Across all environments',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
|
@ -51,7 +51,6 @@ const FeatureOverviewEnvironmentStrategy = ({
|
||||
permission={UPDATE_FEATURE_STRATEGY}
|
||||
environmentId={environmentId}
|
||||
projectId={projectId}
|
||||
// @ts-expect-error
|
||||
component={Link}
|
||||
to={editStrategyPath}
|
||||
>
|
||||
|
@ -49,7 +49,6 @@ const FeatureOverviewMetaData = () => {
|
||||
<PermissionIconButton
|
||||
projectId={projectId}
|
||||
permission={UPDATE_FEATURE}
|
||||
// @ts-expect-error
|
||||
component={Link}
|
||||
to={`/projects/${projectId}/features/${featureId}/settings`}
|
||||
>
|
||||
@ -65,7 +64,6 @@ const FeatureOverviewMetaData = () => {
|
||||
<PermissionIconButton
|
||||
projectId={projectId}
|
||||
permission={UPDATE_FEATURE}
|
||||
// @ts-expect-error
|
||||
component={Link}
|
||||
to={`/projects/${projectId}/features/${featureId}/settings`}
|
||||
>
|
||||
|
@ -141,7 +141,6 @@ export const FeatureView = () => {
|
||||
permission={CREATE_FEATURE}
|
||||
projectId={projectId}
|
||||
data-loading
|
||||
// @ts-expect-error
|
||||
component={Link}
|
||||
to={`/projects/${projectId}/features/${featureId}/strategies/copy`}
|
||||
>
|
||||
|
@ -50,26 +50,9 @@ import { CreateUnleashContextPage } from 'component/context/CreateUnleashContext
|
||||
import { CreateSegment } from 'component/segments/CreateSegment/CreateSegment';
|
||||
import { EditSegment } from 'component/segments/EditSegment/EditSegment';
|
||||
import { SegmentsList } from 'component/segments/SegmentList/SegmentList';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { IRoute } from 'interfaces/route';
|
||||
|
||||
interface Route {
|
||||
path: string;
|
||||
title: string;
|
||||
type: string;
|
||||
layout?: string;
|
||||
parent?: string;
|
||||
flag?: string;
|
||||
hidden?: Boolean;
|
||||
component: FunctionComponent;
|
||||
|
||||
menu: {
|
||||
mobile?: boolean;
|
||||
advanced?: boolean;
|
||||
adminSettings?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export const routes: Route[] = [
|
||||
export const routes: IRoute[] = [
|
||||
// Splash
|
||||
{
|
||||
path: '/splash/:splashId',
|
||||
|
@ -52,7 +52,6 @@ const ProjectInfo = ({
|
||||
<PermissionIconButton
|
||||
permission={UPDATE_PROJECT}
|
||||
projectId={id}
|
||||
// @ts-expect-error
|
||||
component={Link}
|
||||
className={permissionButtonClass}
|
||||
data-loading
|
||||
|
@ -27,10 +27,14 @@ import useTagTypes from 'hooks/api/getters/useTagTypes/useTagTypes';
|
||||
import useToast from 'hooks/useToast';
|
||||
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { ITagType } from 'interfaces/tags';
|
||||
|
||||
export const TagTypeList = () => {
|
||||
const { hasAccess } = useContext(AccessContext);
|
||||
const [deletion, setDeletion] = useState({ open: false });
|
||||
const [deletion, setDeletion] = useState<{
|
||||
open: boolean;
|
||||
name?: string;
|
||||
}>({ open: false });
|
||||
const history = useHistory();
|
||||
const smallScreen = useMediaQuery('(max-width:700px)');
|
||||
const { deleteTagType } = useTagTypesApi();
|
||||
@ -39,14 +43,16 @@ export const TagTypeList = () => {
|
||||
|
||||
const deleteTag = async () => {
|
||||
try {
|
||||
await deleteTagType(deletion.name);
|
||||
refetch();
|
||||
setDeletion({ open: false });
|
||||
setToastData({
|
||||
type: 'success',
|
||||
show: true,
|
||||
text: 'Successfully deleted tag type.',
|
||||
});
|
||||
if (deletion.name) {
|
||||
await deleteTagType(deletion.name);
|
||||
refetch();
|
||||
setDeletion({ open: false });
|
||||
setToastData({
|
||||
type: 'success',
|
||||
show: true,
|
||||
title: 'Successfully deleted tag type.',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
setToastApiError(formatUnknownError(error));
|
||||
}
|
||||
@ -91,7 +97,7 @@ export const TagTypeList = () => {
|
||||
/>
|
||||
);
|
||||
|
||||
const renderTagType = tagType => {
|
||||
const renderTagType = (tagType: ITagType) => {
|
||||
let link = (
|
||||
<Link to={`/tag-types/edit/${tagType.name}`}>
|
||||
<strong>{tagType.name}</strong>
|
||||
@ -126,7 +132,7 @@ export const TagTypeList = () => {
|
||||
component={Link}
|
||||
to={`/tag-types/edit/${tagType.name}`}
|
||||
>
|
||||
<Edit className={styles.icon} />
|
||||
<Edit className={styles.icon} titleAccess="Edit tag type" />
|
||||
</PermissionIconButton>
|
||||
<ConditionallyRender
|
||||
condition={hasAccess(DELETE_TAG_TYPE)}
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { TagTypeList } from '../TagTypeList';
|
||||
import { TagTypeList } from 'component/tags/TagTypeList/TagTypeList';
|
||||
import renderer from 'react-test-renderer';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { ThemeProvider } from '@material-ui/styles';
|
@ -9,7 +9,7 @@ Object {
|
||||
"filtered": Array [
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -81,7 +81,7 @@ Object {
|
||||
"filtered": Array [
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -96,7 +96,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -111,7 +111,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -137,7 +137,7 @@ Object {
|
||||
"filtered": Array [
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -152,7 +152,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -179,7 +179,7 @@ Object {
|
||||
"filtered": Array [
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
@ -194,7 +194,7 @@ Object {
|
||||
},
|
||||
Object {
|
||||
"archived": false,
|
||||
"createdAt": "22006-01-02T15:04:05Z",
|
||||
"createdAt": "2006-01-02T15:04:05Z",
|
||||
"description": "1",
|
||||
"enabled": false,
|
||||
"environments": Array [],
|
||||
|
@ -102,7 +102,7 @@ const mockFeatureToggle = (
|
||||
strategies: [],
|
||||
variants: [],
|
||||
environments: [],
|
||||
createdAt: '22006-01-02T15:04:05Z',
|
||||
createdAt: '2006-01-02T15:04:05Z',
|
||||
lastSeenAt: '2006-01-02T15:04:05Z',
|
||||
...overrides,
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
sortFeaturesByExpiredAtDescending,
|
||||
sortFeaturesByStatusAscending,
|
||||
sortFeaturesByStatusDescending,
|
||||
} from '../component/Reporting/utils';
|
||||
} from 'component/Reporting/utils';
|
||||
|
||||
import {
|
||||
LAST_SEEN,
|
||||
@ -19,7 +19,8 @@ import {
|
||||
EXPIRED,
|
||||
STATUS,
|
||||
REPORT,
|
||||
} from '../component/Reporting/constants';
|
||||
} from 'component/Reporting/constants';
|
||||
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
|
||||
|
||||
const useSort = () => {
|
||||
const [sortData, setSortData] = useState({
|
||||
@ -27,7 +28,7 @@ const useSort = () => {
|
||||
ascending: true,
|
||||
});
|
||||
|
||||
const handleSortName = features => {
|
||||
const handleSortName = (features: IFeatureToggleListItem[]) => {
|
||||
if (sortData.ascending) {
|
||||
return sortFeaturesByNameAscending(features);
|
||||
}
|
||||
@ -35,35 +36,35 @@ const useSort = () => {
|
||||
return sortFeaturesByNameDescending(features);
|
||||
};
|
||||
|
||||
const handleSortLastSeen = features => {
|
||||
const handleSortLastSeen = (features: IFeatureToggleListItem[]) => {
|
||||
if (sortData.ascending) {
|
||||
return sortFeaturesByLastSeenAscending(features);
|
||||
}
|
||||
return sortFeaturesByLastSeenDescending(features);
|
||||
};
|
||||
|
||||
const handleSortCreatedAt = features => {
|
||||
const handleSortCreatedAt = (features: IFeatureToggleListItem[]) => {
|
||||
if (sortData.ascending) {
|
||||
return sortFeaturesByCreatedAtAscending(features);
|
||||
}
|
||||
return sortFeaturesByCreatedAtDescending(features);
|
||||
};
|
||||
|
||||
const handleSortExpiredAt = features => {
|
||||
const handleSortExpiredAt = (features: IFeatureToggleListItem[]) => {
|
||||
if (sortData.ascending) {
|
||||
return sortFeaturesByExpiredAtAscending(features);
|
||||
}
|
||||
return sortFeaturesByExpiredAtDescending(features);
|
||||
};
|
||||
|
||||
const handleSortStatus = features => {
|
||||
const handleSortStatus = (features: IFeatureToggleListItem[]) => {
|
||||
if (sortData.ascending) {
|
||||
return sortFeaturesByStatusAscending(features);
|
||||
}
|
||||
return sortFeaturesByStatusDescending(features);
|
||||
};
|
||||
|
||||
const sort = features => {
|
||||
const sort = (features: IFeatureToggleListItem[]) => {
|
||||
switch (sortData.sortKey) {
|
||||
case NAME:
|
||||
return handleSortName(features);
|
@ -3,6 +3,9 @@ import { IFeatureStrategy } from './strategy';
|
||||
export interface IFeatureToggleListItem {
|
||||
type: string;
|
||||
name: string;
|
||||
stale?: boolean;
|
||||
lastSeenAt?: string;
|
||||
createdAt: string;
|
||||
environments: IEnvironments[];
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,19 @@
|
||||
import React from 'react';
|
||||
import { FunctionComponent } from 'react';
|
||||
|
||||
interface IRoute {
|
||||
export interface IRoute {
|
||||
path: string;
|
||||
icon?: string;
|
||||
title?: string;
|
||||
component: React.ComponentType;
|
||||
title: string;
|
||||
type: string;
|
||||
hidden?: boolean;
|
||||
flag?: string;
|
||||
layout?: string;
|
||||
parent?: string;
|
||||
flag?: string;
|
||||
hidden?: boolean;
|
||||
component: FunctionComponent;
|
||||
menu: IRouteMenu;
|
||||
}
|
||||
|
||||
export default IRoute;
|
||||
interface IRouteMenu {
|
||||
mobile?: boolean;
|
||||
advanced?: boolean;
|
||||
adminSettings?: boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user