1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-08 01:15:49 +02:00

chore: rename toggle to flag #1 (#7092)

Rename feature toggle to feature flag in the UI and code.
Starting with low hanging fruits.
Trying to keep these ~100 LoC.
This commit is contained in:
Jaanus Sellin 2024-05-21 15:18:00 +03:00 committed by GitHub
parent 45eff83a8a
commit 8897f2ea75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 112 additions and 113 deletions

View File

@ -32,7 +32,7 @@ export const InstanceStats: VFC = () => {
{ title: 'Instance Id', value: stats?.instanceId, offset: false },
{ title: versionTitle, value: version },
{ title: 'Users', value: stats?.users },
{ title: 'Feature toggles', value: stats?.featureToggles },
{ title: 'Feature flags', value: stats?.featureToggles },
{ title: 'Projects', value: stats?.projects },
{ title: 'Environments', value: stats?.environments },
{ title: 'Roles', value: stats?.roles },

View File

@ -36,7 +36,7 @@ const featureCollectionDetails = {
infoText:
'We collect data about your instance to improve the Unleash product user experience. We may also use the data in case you need help from our support team. Data collection is for internal use only and is not shared with third parties outside Unleash. As we want you to be in control of your data, we will leave it up to you to allow us to collect your data.',
concreteDetails: {
'Feature toggles': 'The number of feature toggles in your instance',
'Feature flags': 'The number of feature toggles in your instance',
Users: 'The number of users registered in your instance',
Projects: 'The number of projects in your instance',
'Context Fields': 'The number of custom context fields in use',

View File

@ -87,15 +87,15 @@ test('should show confirm dialog when reviving toggle', async () => {
await screen.findByText('someFeature');
const reviveButton = screen.getAllByTestId(
'revive-feature-toggle-button',
'revive-feature-flag-button',
)?.[0];
fireEvent.click(reviveButton);
await screen.findByText('Revive feature toggle?');
const reviveTogglesButton = screen.getByRole('button', {
name: /Revive feature toggle/i,
await screen.findByText('Revive feature flag?');
const reviveFlagsButton = screen.getByRole('button', {
name: /Revive feature flag/i,
});
fireEvent.click(reviveTogglesButton);
fireEvent.click(reviveFlagsButton);
await screen.findByText("And we're back!");
});
@ -121,10 +121,10 @@ test('should show confirm dialog when batch reviving toggle', async () => {
const batchReviveButton = await screen.findByText(/Revive/i);
await userEvent.click(batchReviveButton!);
await screen.findByText('Revive feature toggles?');
await screen.findByText('Revive feature flags?');
const reviveTogglesButton = screen.getByRole('button', {
name: /Revive feature toggles/i,
name: /Revive feature flags/i,
});
fireEvent.click(reviveTogglesButton);
@ -143,11 +143,11 @@ test('should show info box when disableAllEnvsOnRevive flag is on', async () =>
await screen.findByText('someFeature');
const reviveButton = screen.getAllByTestId(
'revive-feature-toggle-button',
'revive-feature-flag-button',
)?.[0];
fireEvent.click(reviveButton);
await screen.findByText('Revive feature toggle?');
await screen.findByText('Revive feature flag?');
await screen.findByText(
'Revived feature toggles will be automatically disabled in all environments',
);

View File

@ -25,15 +25,15 @@ export const ArchivedFeatureActionCell: VFC<IReviveArchivedFeatureCell> = ({
onClick={onRevive}
projectId={project}
permission={UPDATE_FEATURE}
tooltipProps={{ title: 'Revive feature toggle' }}
data-testid={`revive-feature-toggle-button`}
tooltipProps={{ title: 'Revive feature flag' }}
data-testid={`revive-feature-flag-button`}
>
<Undo />
</PermissionIconButton>
<PermissionIconButton
permission={DELETE_FEATURE}
projectId={project}
tooltipProps={{ title: 'Delete feature toggle' }}
tooltipProps={{ title: 'Delete feature flag' }}
onClick={onDelete}
>
<Delete />

View File

@ -52,10 +52,10 @@ export const ArchivedFeatureReviveConfirm = ({
setOpen(false);
};
const title = `Revive feature toggle${
const title = `Revive feature flag${
revivedFeatures.length > 1 ? 's' : ''
}?`;
const primaryBtnText = `Revive feature toggle${
const primaryBtnText = `Revive feature flag${
revivedFeatures.length > 1 ? 's' : ''
}`;

View File

@ -68,7 +68,7 @@ test('Add single archive feature change to change request', async () => {
/>,
);
expect(screen.getByText('Archive feature toggle')).toBeInTheDocument();
expect(screen.getByText('Archive feature flag')).toBeInTheDocument();
await screen.findByText(
'Archiving features with dependencies will also remove those dependencies.',
);
@ -98,7 +98,7 @@ test('Add multiple archive feature changes to change request', async () => {
/>,
);
await screen.findByText('Archive feature toggles');
await screen.findByText('Archive feature flags');
await screen.findByText(
'Archiving features with dependencies will also remove those dependencies.',
);
@ -129,7 +129,7 @@ test('Skip change request does not affect archive', async () => {
{ permissions: [{ permission: 'SKIP_CHANGE_REQUEST' }] },
);
await screen.findByText('Archive feature toggle');
await screen.findByText('Archive feature flag');
const button = await screen.findByText('Add change to draft');
await waitFor(() => expect(button).toBeEnabled());
@ -157,7 +157,7 @@ test('Show error message when multiple parents of orphaned children are archived
/>,
);
await screen.findByText('2 feature toggles');
await screen.findByText('2 feature flags');
await screen.findByText(
'have child features that depend on them and are not part of the archive operation. These parent features can not be archived:',
);

View File

@ -53,11 +53,11 @@ const UsageWarning = ({
variant={'body2'}
display='inline'
>
{`${ids.length} feature toggles `}
{`${ids.length} feature flags `}
</Typography>
<span>
have usage from applications. If you archive these feature
toggles they will not be available to Client SDKs:
flags they will not be available to Client SDKs:
</span>
<ul>
{ids?.map((id) => (
@ -94,7 +94,7 @@ const ArchiveParentError = ({
variant={'body2'}
display='inline'
>
{`${ids.length} feature toggles `}
{`${ids.length} feature flags `}
</Typography>
<span>
have child features that depend on them and are not part of
@ -194,9 +194,9 @@ const useActionButtonText = (projectId: string, isBulkArchive: boolean) => {
return 'Add change to draft';
}
if (isBulkArchive) {
return 'Archive toggles';
return 'Archive flags';
}
return 'Archive toggle';
return 'Archive flag';
};
const useArchiveAction = ({
@ -239,8 +239,8 @@ const useArchiveAction = ({
refetchChangeRequests();
setToastData({
text: isBulkArchive
? 'Your archive feature toggles changes have been added to change request'
: 'Your archive feature toggle change has been added to change request',
? 'Your archive feature flags changes have been added to change request'
: 'Your archive feature flag change has been added to change request',
type: 'success',
title: isBulkArchive
? 'Changes added to a draft'
@ -251,7 +251,7 @@ const useArchiveAction = ({
const archiveToggle = async () => {
await archiveFeatureToggle(projectId, featureIds[0]);
setToastData({
text: 'Your feature toggle has been archived',
text: 'Your feature flag has been archived',
type: 'success',
title: 'Feature archived',
});
@ -260,7 +260,7 @@ const useArchiveAction = ({
const archiveToggles = async () => {
await archiveFeatures(projectId, featureIds);
setToastData({
text: 'Selected feature toggles have been archived',
text: 'Selected feature flags have been archived',
type: 'success',
title: 'Features archived',
});
@ -339,8 +339,8 @@ export const FeatureArchiveDialog: VFC<IFeatureArchiveDialogProps> = ({
const buttonText = useActionButtonText(projectId, isBulkArchive);
const dialogTitle = isBulkArchive
? 'Archive feature toggles'
: 'Archive feature toggle';
? 'Archive feature flags'
: 'Archive feature flag';
const archiveAction = useArchiveAction({
projectId,
@ -381,8 +381,7 @@ export const FeatureArchiveDialog: VFC<IFeatureArchiveDialogProps> = ({
<>
<p>
Are you sure you want to archive{' '}
<strong>{featureIds?.length}</strong> feature
toggles?
<strong>{featureIds?.length}</strong> feature flags?
</p>
<ConditionallyRender
@ -433,8 +432,8 @@ export const FeatureArchiveDialog: VFC<IFeatureArchiveDialogProps> = ({
<p>
Are you sure you want to archive{' '}
{isBulkArchive
? 'these feature toggles'
: 'this feature toggle'}
? 'these feature flags'
: 'this feature flag'}
?
</p>
<ConditionallyRender

View File

@ -24,17 +24,17 @@ export const FeatureStaleDialog = ({
const { setToastData, setToastApiError } = useToast();
const { patchFeatureToggle } = useFeatureApi();
const toggleToStaleContent = (
<Typography>Setting a toggle to stale marks it for cleanup</Typography>
const flagToStaleContent = (
<Typography>Setting a flag to stale marks it for cleanup</Typography>
);
const toggleToActiveContent = (
const flagToActiveContent = (
<Typography>
Setting a toggle to active marks it as in active use
Setting a flag to active marks it as in active use
</Typography>
);
const toggleActionText = isStale ? 'active' : 'stale';
const flagActionText = isStale ? 'active' : 'stale';
const onSubmit = async (event: React.SyntheticEvent) => {
event.stopPropagation();
@ -51,13 +51,13 @@ export const FeatureStaleDialog = ({
setToastData({
type: 'success',
title: "And we're back!",
text: 'The toggle is no longer marked as stale.',
text: 'The flag is no longer marked as stale.',
});
} else {
setToastData({
type: 'success',
title: 'A job well done.',
text: 'The toggle has been marked as stale.',
text: 'The flag has been marked as stale.',
});
}
};
@ -66,15 +66,15 @@ export const FeatureStaleDialog = ({
<Dialogue
open={isOpen}
secondaryButtonText={'Cancel'}
primaryButtonText={`Flip to ${toggleActionText}`}
title={`Set feature state to ${toggleActionText}`}
primaryButtonText={`Flip to ${flagActionText}`}
title={`Set feature state to ${flagActionText}`}
onClick={onSubmit}
onClose={onClose}
>
<ConditionallyRender
condition={isStale}
show={toggleToActiveContent}
elseShow={toggleToStaleContent}
show={flagToActiveContent}
elseShow={flagToStaleContent}
/>
</Dialogue>
);

View File

@ -67,7 +67,7 @@ const StyledInnerContainer = styled('div')(({ theme }) => ({
},
}));
const StyledToggleInfoContainer = styled('div')({
const StyledFlagInfoContainer = styled('div')({
display: 'flex',
alignItems: 'center',
});
@ -240,13 +240,13 @@ export const FeatureView = () => {
<div ref={ref}>
<StyledHeader>
<StyledInnerContainer>
<StyledToggleInfoContainer>
<StyledFlagInfoContainer>
<FavoriteIconButton
onClick={onFavorite}
isFavorite={feature?.favorite}
/>
<div>
<StyledToggleInfoContainer>
<StyledFlagInfoContainer>
<StyledFeatureViewHeader data-loading>
{feature.name}{' '}
</StyledFeatureViewHeader>
@ -279,7 +279,7 @@ export const FeatureView = () => {
/>
}
/>
</StyledToggleInfoContainer>
</StyledFlagInfoContainer>
<ConditionallyRender
condition={feature.dependencies.length > 0}
show={
@ -306,7 +306,7 @@ export const FeatureView = () => {
}
/>
</div>
</StyledToggleInfoContainer>
</StyledFlagInfoContainer>
<StyledToolbarContainer>
<PermissionIconButton
@ -325,7 +325,7 @@ export const FeatureView = () => {
permission={DELETE_FEATURE}
projectId={projectId}
tooltipProps={{
title: 'Archive feature toggle',
title: 'Archive feature flag',
}}
data-loading
onClick={() => setShowDelDialog(true)}

View File

@ -35,7 +35,7 @@ test('batch archive', async () => {
archiveButton.click();
screen.getByText('Archive feature toggles');
screen.getByText('Archive feature flags');
screen.getByText('featureA');
screen.getByText('featureB');
});

View File

@ -1,11 +1,11 @@
import type { IFeatureToggleListItem } from 'interfaces/featureToggle';
import type { IFeatureFlagListItem } from 'interfaces/featureToggle';
import { KILLSWITCH, PERMISSION } from 'constants/featureToggleTypes';
import { expired, getDiffInDays } from '../utils';
import { parseISO, subDays } from 'date-fns';
import type { FeatureTypeSchema } from 'openapi';
export const formatExpiredAt = (
feature: IFeatureToggleListItem,
feature: IFeatureFlagListItem,
featureTypes: FeatureTypeSchema[],
): string | undefined => {
const { type, createdAt } = feature;

View File

@ -1,4 +1,4 @@
import type { IFeatureToggleListItem } from 'interfaces/featureToggle';
import type { IFeatureFlagListItem } from 'interfaces/featureToggle';
import { expired, getDiffInDays } from '../utils';
import { KILLSWITCH, PERMISSION } from 'constants/featureToggleTypes';
import { parseISO } from 'date-fns';
@ -7,7 +7,7 @@ import type { FeatureTypeSchema } from 'openapi';
export type ReportingStatus = 'potentially-stale' | 'healthy';
export const formatStatus = (
feature: IFeatureToggleListItem,
feature: IFeatureFlagListItem,
featureTypes: FeatureTypeSchema[],
): ReportingStatus => {
const { type, createdAt } = feature;

View File

@ -1,7 +1,7 @@
import { useMemo } from 'react';
import type {
IEnvironments,
IFeatureToggleListItem,
IFeatureFlagListItem,
} from 'interfaces/featureToggle';
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
import { PageContent } from 'component/common/PageContent/PageContent';
@ -35,7 +35,7 @@ import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
interface IReportTableProps {
projectId: string;
features: IFeatureToggleListItem[];
features: IFeatureFlagListItem[];
}
export interface IReportTableRow {

View File

@ -9,7 +9,7 @@ import {
} from './useSearch';
import type { FC } from 'react';
import { render, screen } from '@testing-library/react';
import type { IFeatureToggleListItem } from '../interfaces/featureToggle';
import type { IFeatureFlagListItem } from '../interfaces/featureToggle';
const columns = [
{
@ -39,12 +39,12 @@ const columns = [
(value === 'seen' && row.seen) || (value === 'never' && !row.seen),
},
{
accessor: (row: IFeatureToggleListItem) =>
accessor: (row: IFeatureFlagListItem) =>
row.tags?.map(({ type, value }) => `${type}:${value}`).join('\n') ||
'',
searchable: true,
filterName: 'tags',
filterBy(row: IFeatureToggleListItem, values: string[]) {
filterBy(row: IFeatureFlagListItem, values: string[]) {
return includesFilter(getColumnValues(this, row), values);
},
},
@ -52,7 +52,7 @@ const columns = [
const data = [
{
name: 'my-feature-toggle',
name: 'my-feature-flag',
project: 'default',
stale: false,
type: 'release',
@ -63,7 +63,7 @@ const data = [
],
},
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
type: 'experiment',
@ -71,7 +71,7 @@ const data = [
tags: [],
},
{
name: 'my-feature-toggle-3',
name: 'my-feature-flag-3',
project: 'my-project',
stale: false,
type: 'operational',
@ -79,7 +79,7 @@ const data = [
tags: [],
},
{
name: 'my-feature-toggle-4',
name: 'my-feature-flag-4',
project: 'my-project',
stale: true,
type: 'permission',
@ -124,8 +124,8 @@ describe('getSearchText', () => {
const tests = [
{ input: 'project:textsearch default', expectation: 'default' },
{
input: 'project:default state:active feature-toggle',
expectation: 'feature-toggle',
input: 'project:default state:active feature-flag',
expectation: 'feature-flag',
},
{ input: 'project:default', expectation: '' },
{ input: '', expectation: '' },
@ -133,12 +133,12 @@ describe('getSearchText', () => {
{ input: 'a:', expectation: 'a:' },
{ input: 'my-feature:test', expectation: 'my-feature:test' },
{
input: 'my-new-feature-toggle project:defaultstate:active',
expectation: 'my-new-feature-toggle',
input: 'my-new-feature-flag project:defaultstate:active',
expectation: 'my-new-feature-flag',
},
{
input: 'my-new-feature-toggle project:default state:active',
expectation: 'my-new-feature-toggle',
input: 'my-new-feature-flag project:default state:active',
expectation: 'my-new-feature-flag',
},
];
@ -149,10 +149,10 @@ describe('getSearchText', () => {
});
it('should return search value without multiple filters', () => {
const input = 'project:default state:active feature-toggle';
const input = 'project:default state:active feature-flag';
const result = getSearchText(input);
expect(result).toBe('feature-toggle');
expect(result).toBe('feature-flag');
});
});
@ -163,7 +163,7 @@ describe('searchInFilteredData', () => {
input: 'project',
expectation: [
{
name: 'my-feature-toggle-3',
name: 'my-feature-flag-3',
project: 'my-project',
stale: false,
tags: [],
@ -171,7 +171,7 @@ describe('searchInFilteredData', () => {
seen: false,
},
{
name: 'my-feature-toggle-4',
name: 'my-feature-flag-4',
project: 'my-project',
stale: true,
tags: [],
@ -181,10 +181,10 @@ describe('searchInFilteredData', () => {
],
},
{
input: 'toggle-2',
input: 'flag-2',
expectation: [
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
tags: [],
@ -194,7 +194,7 @@ describe('searchInFilteredData', () => {
],
},
{
input: 'non-existing-toggle',
input: 'non-existing-flag',
expectation: [],
},
];
@ -210,7 +210,7 @@ describe('searchInFilteredData', () => {
expect(result).toEqual([
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
tags: [],
@ -225,7 +225,7 @@ describe('searchInFilteredData', () => {
expect(result).toEqual([
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
tags: [],
@ -233,7 +233,7 @@ describe('searchInFilteredData', () => {
seen: false,
},
{
name: 'my-feature-toggle-3',
name: 'my-feature-flag-3',
project: 'my-project',
stale: false,
tags: [],
@ -251,7 +251,7 @@ describe('filter', () => {
input: 'project:default',
expectation: [
{
name: 'my-feature-toggle',
name: 'my-feature-flag',
project: 'default',
stale: false,
tags: [
@ -262,7 +262,7 @@ describe('filter', () => {
seen: true,
},
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
tags: [],
@ -275,7 +275,7 @@ describe('filter', () => {
input: 'state:active',
expectation: [
{
name: 'my-feature-toggle',
name: 'my-feature-flag',
project: 'default',
stale: false,
tags: [
@ -286,7 +286,7 @@ describe('filter', () => {
seen: true,
},
{
name: 'my-feature-toggle-3',
name: 'my-feature-flag-3',
project: 'my-project',
stale: false,
tags: [],
@ -312,7 +312,7 @@ describe('filter', () => {
expect(result).toEqual([
{
name: 'my-feature-toggle-3',
name: 'my-feature-flag-3',
project: 'my-project',
stale: false,
tags: [],
@ -320,7 +320,7 @@ describe('filter', () => {
seen: false,
},
{
name: 'my-feature-toggle-4',
name: 'my-feature-flag-4',
project: 'my-project',
stale: true,
tags: [],
@ -335,7 +335,7 @@ describe('filter', () => {
expect(result).toEqual([
{
name: 'my-feature-toggle-2',
name: 'my-feature-flag-2',
project: 'default',
stale: true,
tags: [],
@ -343,7 +343,7 @@ describe('filter', () => {
seen: false,
},
{
name: 'my-feature-toggle-4',
name: 'my-feature-flag-4',
project: 'my-project',
stale: true,
tags: [],
@ -370,13 +370,13 @@ describe('Search and filter data', () => {
it('should filter single value', () => {
render(<SearchData searchValue={'project:my-project'} />);
screen.getByText('my-feature-toggle-3,my-feature-toggle-4');
screen.getByText('my-feature-flag-3,my-feature-flag-4');
});
it('should filter multiple values', () => {
render(<SearchData searchValue={'project:my-project,another-value'} />);
screen.getByText('my-feature-toggle-3,my-feature-toggle-4');
screen.getByText('my-feature-flag-3,my-feature-flag-4');
});
it('should filter multiple values with spaces', () => {
@ -384,7 +384,7 @@ describe('Search and filter data', () => {
<SearchData searchValue={'project:my-project , another-value'} />,
);
screen.getByText('my-feature-toggle-3,my-feature-toggle-4');
screen.getByText('my-feature-flag-3,my-feature-flag-4');
});
it('should handle multiple filters', () => {
@ -394,7 +394,7 @@ describe('Search and filter data', () => {
/>,
);
screen.getByText('my-feature-toggle-3');
screen.getByText('my-feature-flag-3');
});
it('should handle multiple filters with long spaces', () => {
@ -406,67 +406,67 @@ describe('Search and filter data', () => {
/>,
);
screen.getByText('my-feature-toggle-3,my-feature-toggle-4');
screen.getByText('my-feature-flag-3,my-feature-flag-4');
});
it('should handle multiple filters and search string in between', () => {
render(
<SearchData
searchValue={
'project:my-project , another-value toggle-3 state:active , stale'
'project:my-project , another-value flag-3 state:active , stale'
}
/>,
);
screen.getByText('my-feature-toggle-3');
screen.getByText('my-feature-flag-3');
});
it('should handle multiple filters and search string at the end', () => {
render(
<SearchData
searchValue={
'project:my-project , another-value state:active , stale toggle-3'
'project:my-project , another-value state:active , stale flag-3'
}
/>,
);
screen.getByText('my-feature-toggle-3');
screen.getByText('my-feature-flag-3');
});
it('should handle multiple filters and search string at the beginning', () => {
render(
<SearchData
searchValue={
'toggle-3 project:my-project , another-value state:active , stale'
'flag-3 project:my-project , another-value state:active , stale'
}
/>,
);
screen.getByText('my-feature-toggle-3');
screen.getByText('my-feature-flag-3');
});
it('should return basic search text', () => {
render(<SearchText searchValue={'toggle-3'} />);
render(<SearchText searchValue={'flag-3'} />);
screen.getByText('toggle-3');
screen.getByText('flag-3');
});
it('should return advanced search text', () => {
render(
<SearchText
searchValue={
'project:my-project , another-value toggle-3 state:active , stale'
'project:my-project , another-value flag-3 state:active , stale'
}
/>,
);
screen.getByText('toggle-3');
screen.getByText('flag-3');
});
it('should support custom filter and accessor', () => {
render(<SearchData searchValue={'tags:simple:tag'} />);
screen.getByText('my-feature-toggle');
screen.getByText('my-feature-flag');
});
it('should support search on top of filter', () => {
@ -478,22 +478,22 @@ describe('Search and filter data', () => {
it('should support custom filter with spaces', () => {
render(<SearchData searchValue={'tags:"simple:some space",tag'} />);
screen.getByText('my-feature-toggle');
screen.getByText('my-feature-flag');
});
it('should support custom filter with spaces - space in second term', () => {
render(<SearchData searchValue={'tags:tag,"simple:some space"'} />);
screen.getByText('my-feature-toggle');
screen.getByText('my-feature-flag');
});
it('should support quotes in filter and search', () => {
render(
<SearchData
searchValue={'tags:tag,"simple:some space" "my-feature-toggle"'}
searchValue={'tags:tag,"simple:some space" "my-feature-flag"'}
/>,
);
screen.getByText('my-feature-toggle');
screen.getByText('my-feature-flag');
});
});

View File

@ -4,7 +4,7 @@ import type { ITag } from './tags';
/**
* @deprecated use FeatureSchema from openapi
*/
export interface IFeatureToggleListItem {
export interface IFeatureFlagListItem {
type: string;
name: string;
stale?: boolean;

View File

@ -1,5 +1,5 @@
import type { ProjectSchema, ProjectStatsSchema } from 'openapi';
import type { IFeatureToggleListItem } from './featureToggle';
import type { IFeatureFlagListItem } from './featureToggle';
import type { ProjectEnvironmentType } from 'component/project/Project/ProjectFeatureToggles/hooks/useEnvironmentsRef';
import type { ProjectMode } from 'component/project/Project/hooks/useProjectEnterpriseSettingsForm';
@ -37,7 +37,7 @@ export interface IProject {
health: number;
stats: ProjectStatsSchema;
favorite: boolean;
features: IFeatureToggleListItem[];
features: IFeatureFlagListItem[];
mode: ProjectMode;
defaultStickiness: string;
featureLimit?: number;