mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
refactor: replace IProjectCard with openapi type (#8043)
Makes type consistent between frontend and schema generated from backend.
This commit is contained in:
parent
0b2479517f
commit
6030900b40
@ -36,7 +36,6 @@ test('When you have no projects, you should not get a project filter', () => {
|
|||||||
test('When you have only one project, you should not get a project filter', () => {
|
test('When you have only one project, you should not get a project filter', () => {
|
||||||
const { result } = renderHook(() =>
|
const { result } = renderHook(() =>
|
||||||
useEventLogFilters(
|
useEventLogFilters(
|
||||||
// @ts-expect-error: omitting other properties we don't need
|
|
||||||
() => ({ projects: [{ id: 'a', name: 'A' }] }),
|
() => ({ projects: [{ id: 'a', name: 'A' }] }),
|
||||||
() => ({ features: [] }),
|
() => ({ features: [] }),
|
||||||
),
|
),
|
||||||
@ -52,9 +51,7 @@ test('When you have two one project, you should not get a project filter', () =>
|
|||||||
useEventLogFilters(
|
useEventLogFilters(
|
||||||
() => ({
|
() => ({
|
||||||
projects: [
|
projects: [
|
||||||
// @ts-expect-error: omitting other properties we don't need
|
|
||||||
{ id: 'a', name: 'A' },
|
{ id: 'a', name: 'A' },
|
||||||
// @ts-expect-error: omitting other properties we don't need
|
|
||||||
{ id: 'b', name: 'B' },
|
{ id: 'b', name: 'B' },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -11,11 +11,11 @@ import {
|
|||||||
type FeatureSearchResponseSchema,
|
type FeatureSearchResponseSchema,
|
||||||
type SearchFeaturesParams,
|
type SearchFeaturesParams,
|
||||||
} from 'openapi';
|
} from 'openapi';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import { useEventCreators } from 'hooks/api/getters/useEventCreators/useEventCreators';
|
import { useEventCreators } from 'hooks/api/getters/useEventCreators/useEventCreators';
|
||||||
|
|
||||||
export const useEventLogFilters = (
|
export const useEventLogFilters = (
|
||||||
projectsHook: () => { projects: IProjectCard[] },
|
projectsHook: () => { projects: ProjectSchema[] },
|
||||||
featuresHook: (params: SearchFeaturesParams) => {
|
featuresHook: (params: SearchFeaturesParams) => {
|
||||||
features: FeatureSearchResponseSchema[];
|
features: FeatureSearchResponseSchema[];
|
||||||
},
|
},
|
||||||
@ -27,7 +27,7 @@ export const useEventLogFilters = (
|
|||||||
const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]);
|
const [availableFilters, setAvailableFilters] = useState<IFilterItem[]>([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const projectOptions =
|
const projectOptions =
|
||||||
projects?.map((project: IProjectCard) => ({
|
projects?.map((project: ProjectSchema) => ({
|
||||||
label: project.name,
|
label: project.name,
|
||||||
value: project.id,
|
value: project.id,
|
||||||
})) ?? [];
|
})) ?? [];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import GeneralSelect, {
|
import GeneralSelect, {
|
||||||
type ISelectOption,
|
type ISelectOption,
|
||||||
type IGeneralSelectProps,
|
type IGeneralSelectProps,
|
||||||
@ -25,11 +25,11 @@ const FeatureProjectSelect = ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatOption = (project: IProjectCard) => {
|
const formatOption = (project: ProjectSchema) => {
|
||||||
return {
|
return {
|
||||||
key: project.id,
|
key: project.id,
|
||||||
label: project.name,
|
label: project.name,
|
||||||
title: project.description,
|
title: project.description || '',
|
||||||
sx: {
|
sx: {
|
||||||
whiteSpace: 'pre-line',
|
whiteSpace: 'pre-line',
|
||||||
},
|
},
|
||||||
|
@ -10,10 +10,11 @@ export const useProjectColor = () => {
|
|||||||
const projectsSortedByCreatedAt = useMemo(
|
const projectsSortedByCreatedAt = useMemo(
|
||||||
() =>
|
() =>
|
||||||
projects
|
projects
|
||||||
.sort(
|
.sort((a, b) =>
|
||||||
(a, b) =>
|
a.createdAt && b.createdAt
|
||||||
new Date(a.createdAt).getTime() -
|
? new Date(a.createdAt).getTime() -
|
||||||
new Date(b.createdAt).getTime(),
|
new Date(b.createdAt).getTime()
|
||||||
|
: 0,
|
||||||
)
|
)
|
||||||
.map((project) => project.id),
|
.map((project) => project.id),
|
||||||
[projects],
|
[projects],
|
||||||
|
@ -14,7 +14,7 @@ import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter';
|
|||||||
import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge';
|
import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge';
|
||||||
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
|
||||||
import { FavoriteAction } from './FavoriteAction/FavoriteAction';
|
import { FavoriteAction } from './FavoriteAction/FavoriteAction';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
|
|
||||||
export const ProjectCard = ({
|
export const ProjectCard = ({
|
||||||
@ -27,7 +27,7 @@ export const ProjectCard = ({
|
|||||||
mode,
|
mode,
|
||||||
favorite = false,
|
favorite = false,
|
||||||
owners,
|
owners,
|
||||||
}: IProjectCard) => (
|
}: ProjectSchema & { onHover?: () => void }) => (
|
||||||
<StyledProjectCard onMouseEnter={onHover}>
|
<StyledProjectCard onMouseEnter={onHover}>
|
||||||
<StyledProjectCardBody>
|
<StyledProjectCardBody>
|
||||||
<StyledDivHeader>
|
<StyledDivHeader>
|
||||||
|
@ -12,12 +12,12 @@ import { Box, styled } from '@mui/material';
|
|||||||
import { flexColumn } from 'themes/themeStyles';
|
import { flexColumn } from 'themes/themeStyles';
|
||||||
import { TimeAgo } from 'component/common/TimeAgo/TimeAgo';
|
import { TimeAgo } from 'component/common/TimeAgo/TimeAgo';
|
||||||
import { ProjectLastSeen } from './ProjectLastSeen/ProjectLastSeen';
|
import { ProjectLastSeen } from './ProjectLastSeen/ProjectLastSeen';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
import { ProjectMembers } from './ProjectCardFooter/ProjectMembers/ProjectMembers';
|
import { ProjectMembers } from './ProjectCardFooter/ProjectMembers/ProjectMembers';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId';
|
import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId';
|
||||||
|
import type { ProjectSchema } from 'openapi';
|
||||||
|
|
||||||
const StyledUpdated = styled('span')(({ theme }) => ({
|
const StyledUpdated = styled('span')(({ theme }) => ({
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
@ -45,6 +45,8 @@ const StyledHeader = styled('div')(({ theme }) => ({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
type ProjectCardProps = ProjectSchema & { onHover?: () => void };
|
||||||
|
|
||||||
export const ProjectCard = ({
|
export const ProjectCard = ({
|
||||||
name,
|
name,
|
||||||
featureCount,
|
featureCount,
|
||||||
@ -58,7 +60,7 @@ export const ProjectCard = ({
|
|||||||
createdAt,
|
createdAt,
|
||||||
lastUpdatedAt,
|
lastUpdatedAt,
|
||||||
lastReportedFlagUsage,
|
lastReportedFlagUsage,
|
||||||
}: IProjectCard) => {
|
}: ProjectCardProps) => {
|
||||||
const { searchQuery } = useSearchHighlightContext();
|
const { searchQuery } = useSearchHighlightContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,7 +2,7 @@ import { type FC, useContext, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
import AccessContext from 'contexts/AccessContext';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
@ -169,7 +169,7 @@ export const ProjectList = () => {
|
|||||||
|
|
||||||
const ProjectGroupComponent = (props: {
|
const ProjectGroupComponent = (props: {
|
||||||
sectionTitle?: string;
|
sectionTitle?: string;
|
||||||
projects: IProjectCard[];
|
projects: ProjectSchema[];
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<ProjectGroup
|
<ProjectGroup
|
||||||
|
@ -3,8 +3,7 @@ import { Link } from 'react-router-dom';
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { ProjectCard as LegacyProjectCard } from '../ProjectCard/LegacyProjectCard';
|
import { ProjectCard as LegacyProjectCard } from '../ProjectCard/LegacyProjectCard';
|
||||||
import { ProjectCard as NewProjectCard } from '../ProjectCard/ProjectCard';
|
import { ProjectCard as NewProjectCard } from '../ProjectCard/ProjectCard';
|
||||||
|
import type { ProjectSchema } from 'openapi';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
|
||||||
import loadingData from './loadingData';
|
import loadingData from './loadingData';
|
||||||
import { TablePlaceholder } from 'component/common/Table';
|
import { TablePlaceholder } from 'component/common/Table';
|
||||||
import { styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
@ -51,14 +50,14 @@ type ProjectGroupProps = {
|
|||||||
sectionTitle?: string;
|
sectionTitle?: string;
|
||||||
sectionSubtitle?: string;
|
sectionSubtitle?: string;
|
||||||
HeaderActions?: ReactNode;
|
HeaderActions?: ReactNode;
|
||||||
projects: IProjectCard[];
|
projects: ProjectSchema[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**
|
/**
|
||||||
* @deprecated remove with projectListImprovements
|
* @deprecated remove with projectListImprovements
|
||||||
*/
|
*/
|
||||||
searchValue?: string;
|
searchValue?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
ProjectCardComponent?: ComponentType<IProjectCard & any>;
|
ProjectCardComponent?: ComponentType<ProjectSchema & any>;
|
||||||
link?: boolean;
|
link?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,7 +128,7 @@ export const ProjectGroup = ({
|
|||||||
show={() => (
|
show={() => (
|
||||||
<>
|
<>
|
||||||
{loadingData.map(
|
{loadingData.map(
|
||||||
(project: IProjectCard) => (
|
(project: ProjectSchema) => (
|
||||||
<ProjectCard
|
<ProjectCard
|
||||||
data-loading
|
data-loading
|
||||||
createdAt={project.createdAt}
|
createdAt={project.createdAt}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import { groupProjects } from './group-projects';
|
import { groupProjects } from './group-projects';
|
||||||
|
|
||||||
test('should check that the project is a user project OR that it is a favorite', () => {
|
test('should check that the project is a user project OR that it is a favorite', () => {
|
||||||
const myProjectIds = new Set(['my1', 'my2', 'my3']);
|
const myProjectIds = new Set(['my1', 'my2', 'my3']);
|
||||||
|
|
||||||
const projects: IProjectCard[] = [
|
const projects: ProjectSchema[] = [
|
||||||
{ id: 'my1', favorite: true },
|
{ id: 'my1', favorite: true },
|
||||||
{ id: 'my2', favorite: false },
|
{ id: 'my2', favorite: false },
|
||||||
{ id: 'my3' },
|
{ id: 'my3' },
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
|
|
||||||
export const groupProjects = (
|
export const groupProjects = (
|
||||||
myProjectIds: Set<string>,
|
myProjectIds: Set<string>,
|
||||||
filteredProjects: IProjectCard[],
|
filteredProjects: ProjectSchema[],
|
||||||
) => {
|
) => {
|
||||||
const mine: IProjectCard[] = [];
|
const mine: ProjectSchema[] = [];
|
||||||
const other: IProjectCard[] = [];
|
const other: ProjectSchema[] = [];
|
||||||
|
|
||||||
for (const project of filteredProjects) {
|
for (const project of filteredProjects) {
|
||||||
if (project.favorite || myProjectIds.has(project.id)) {
|
if (project.favorite || myProjectIds.has(project.id)) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { groupProjects } from '../group-projects';
|
import { groupProjects } from '../group-projects';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
|
|
||||||
export const useGroupedProjects = (
|
export const useGroupedProjects = (
|
||||||
filteredAndSortedProjects: IProjectCard[],
|
filteredAndSortedProjects: ProjectSchema[],
|
||||||
myProjects: Set<string>,
|
myProjects: Set<string>,
|
||||||
) =>
|
) =>
|
||||||
useMemo(
|
useMemo(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { useProjectsSearchAndSort } from './useProjectsSearchAndSort';
|
import { useProjectsSearchAndSort } from './useProjectsSearchAndSort';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
|
|
||||||
const projects: IProjectCard[] = [
|
const projects: ProjectSchema[] = [
|
||||||
{
|
{
|
||||||
name: 'A - Eagle',
|
name: 'A - Eagle',
|
||||||
id: '1',
|
id: '1',
|
||||||
@ -174,7 +174,7 @@ describe('useProjectsSearchAndSort', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to deal with date', () => {
|
it('should be able to deal with updates', () => {
|
||||||
const hook = renderHook(
|
const hook = renderHook(
|
||||||
(sortBy: string) =>
|
(sortBy: string) =>
|
||||||
useProjectsSearchAndSort(
|
useProjectsSearchAndSort(
|
||||||
@ -189,9 +189,9 @@ describe('useProjectsSearchAndSort', () => {
|
|||||||
{
|
{
|
||||||
name: 'Project B',
|
name: 'Project B',
|
||||||
id: '2',
|
id: '2',
|
||||||
createdAt: new Date('2024-02-01'),
|
createdAt: '2024-02-01',
|
||||||
lastUpdatedAt: new Date('2024-02-10'),
|
lastUpdatedAt: '2024-02-10',
|
||||||
lastReportedFlagUsage: new Date('2024-02-15'),
|
lastReportedFlagUsage: '2024-02-15',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
undefined,
|
undefined,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { safeRegExp } from '@server/util/escape-regex';
|
import { safeRegExp } from '@server/util/escape-regex';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
|
||||||
import type { sortKeys } from '../ProjectsListSort/ProjectsListSort';
|
import type { sortKeys } from '../ProjectsListSort/ProjectsListSort';
|
||||||
|
import type { ProjectSchema } from 'openapi';
|
||||||
|
|
||||||
export const useProjectsSearchAndSort = (
|
export const useProjectsSearchAndSort = (
|
||||||
projects: IProjectCard[],
|
projects: ProjectSchema[],
|
||||||
query?: string | null,
|
query?: string | null,
|
||||||
sortBy?: (typeof sortKeys)[number] | null,
|
sortBy?: (typeof sortKeys)[number] | null,
|
||||||
) =>
|
) =>
|
||||||
|
@ -7,7 +7,7 @@ const loadingData = [
|
|||||||
featureCount: 4,
|
featureCount: 4,
|
||||||
createdAt: '',
|
createdAt: '',
|
||||||
description: '',
|
description: '',
|
||||||
mode: '',
|
mode: 'open' as const,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'loading2',
|
id: 'loading2',
|
||||||
@ -17,7 +17,7 @@ const loadingData = [
|
|||||||
featureCount: 4,
|
featureCount: 4,
|
||||||
createdAt: '',
|
createdAt: '',
|
||||||
description: '',
|
description: '',
|
||||||
mode: '',
|
mode: 'open' as const,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'loading3',
|
id: 'loading3',
|
||||||
@ -27,7 +27,7 @@ const loadingData = [
|
|||||||
featureCount: 4,
|
featureCount: 4,
|
||||||
createdAt: '',
|
createdAt: '',
|
||||||
description: '',
|
description: '',
|
||||||
mode: '',
|
mode: 'open' as const,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'loading4',
|
id: 'loading4',
|
||||||
@ -37,7 +37,7 @@ const loadingData = [
|
|||||||
featureCount: 4,
|
featureCount: 4,
|
||||||
createdAt: '',
|
createdAt: '',
|
||||||
description: '',
|
description: '',
|
||||||
mode: '',
|
mode: 'open' as const,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Alert, styled } from '@mui/material';
|
import { Alert, styled } from '@mui/material';
|
||||||
import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
|
import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit';
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
import type { ProjectSchema } from 'openapi';
|
||||||
import type { IFeatureStrategy } from 'interfaces/strategy';
|
import type { IFeatureStrategy } from 'interfaces/strategy';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { formatStrategyName } from 'utils/strategyNames';
|
import { formatStrategyName } from 'utils/strategyNames';
|
||||||
@ -22,14 +22,14 @@ const StyledAlert = styled(Alert)(({ theme }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
interface ISegmentProjectAlertProps {
|
interface ISegmentProjectAlertProps {
|
||||||
projects: IProjectCard[];
|
projects: ProjectSchema[];
|
||||||
strategies: (
|
strategies: (
|
||||||
| IFeatureStrategy
|
| IFeatureStrategy
|
||||||
| ChangeRequestUpdatedStrategy
|
| ChangeRequestUpdatedStrategy
|
||||||
| ChangeRequestNewStrategy
|
| ChangeRequestNewStrategy
|
||||||
)[];
|
)[];
|
||||||
projectsUsed: string[];
|
projectsUsed: string[];
|
||||||
availableProjects: IProjectCard[];
|
availableProjects: ProjectSchema[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SegmentProjectAlert = ({
|
export const SegmentProjectAlert = ({
|
||||||
|
@ -2,9 +2,8 @@ import useSWR, { mutate, type SWRConfiguration } from 'swr';
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { formatApiPath } from 'utils/formatPath';
|
import { formatApiPath } from 'utils/formatPath';
|
||||||
|
|
||||||
import type { IProjectCard } from 'interfaces/project';
|
|
||||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||||
import type { GetProjectsParams } from 'openapi';
|
import type { GetProjectsParams, ProjectsSchema } from 'openapi';
|
||||||
|
|
||||||
const useProjects = (options: SWRConfiguration & GetProjectsParams = {}) => {
|
const useProjects = (options: SWRConfiguration & GetProjectsParams = {}) => {
|
||||||
const KEY = `api/admin/projects${options.archived ? '?archived=true' : ''}`;
|
const KEY = `api/admin/projects${options.archived ? '?archived=true' : ''}`;
|
||||||
@ -18,7 +17,7 @@ const useProjects = (options: SWRConfiguration & GetProjectsParams = {}) => {
|
|||||||
.then((res) => res.json());
|
.then((res) => res.json());
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, error } = useSWR<{ projects: IProjectCard[] }>(
|
const { data, error } = useSWR<{ projects: ProjectsSchema['projects'] }>(
|
||||||
KEY,
|
KEY,
|
||||||
fetcher,
|
fetcher,
|
||||||
options,
|
options,
|
||||||
|
@ -1,24 +1,8 @@
|
|||||||
import type { ProjectSchema, ProjectStatsSchema } from 'openapi';
|
import type { ProjectStatsSchema } from 'openapi';
|
||||||
import type { IFeatureFlagListItem } from './featureToggle';
|
import type { IFeatureFlagListItem } from './featureToggle';
|
||||||
import type { ProjectEnvironmentType } from 'component/project/Project/ProjectFeatureToggles/hooks/useEnvironmentsRef';
|
import type { ProjectEnvironmentType } from 'component/project/Project/ProjectFeatureToggles/hooks/useEnvironmentsRef';
|
||||||
import type { ProjectMode } from 'component/project/Project/hooks/useProjectEnterpriseSettingsForm';
|
import type { ProjectMode } from 'component/project/Project/hooks/useProjectEnterpriseSettingsForm';
|
||||||
|
|
||||||
export interface IProjectCard {
|
|
||||||
name: string;
|
|
||||||
id: string;
|
|
||||||
createdAt: string | Date;
|
|
||||||
health?: number;
|
|
||||||
description?: string;
|
|
||||||
featureCount?: number;
|
|
||||||
mode?: string;
|
|
||||||
memberCount?: number;
|
|
||||||
onHover?: () => void;
|
|
||||||
favorite?: boolean;
|
|
||||||
owners?: ProjectSchema['owners'];
|
|
||||||
lastUpdatedAt?: Date | string;
|
|
||||||
lastReportedFlagUsage?: Date | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FeatureNamingType = {
|
export type FeatureNamingType = {
|
||||||
pattern: string;
|
pattern: string;
|
||||||
example: string;
|
example: string;
|
||||||
|
@ -41,6 +41,16 @@ export interface ProjectSchema {
|
|||||||
health?: number;
|
health?: number;
|
||||||
/** The id of this project */
|
/** The id of this project */
|
||||||
id: string;
|
id: string;
|
||||||
|
/**
|
||||||
|
* Across all flags in your project this is the last time usage metrics where reported from connected applications.
|
||||||
|
* @nullable
|
||||||
|
*/
|
||||||
|
lastReportedFlagUsage?: string | null;
|
||||||
|
/**
|
||||||
|
* When this project was last updated.
|
||||||
|
* @nullable
|
||||||
|
*/
|
||||||
|
lastUpdatedAt?: string | null;
|
||||||
/** The number of members this project has */
|
/** The number of members this project has */
|
||||||
memberCount?: number;
|
memberCount?: number;
|
||||||
/** The project's [collaboration mode](https://docs.getunleash.io/reference/project-collaboration-mode). Determines whether non-project members can submit change requests or not. */
|
/** The project's [collaboration mode](https://docs.getunleash.io/reference/project-collaboration-mode). Determines whether non-project members can submit change requests or not. */
|
||||||
|
Loading…
Reference in New Issue
Block a user