mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-12 13:48:35 +02:00
fix: archived feature layout (#2713)
This commit is contained in:
parent
45652f6bf9
commit
111dddd746
@ -1,19 +1,13 @@
|
|||||||
import {
|
import { FC } from 'react';
|
||||||
render,
|
import { render, screen, within, fireEvent } from '@testing-library/react';
|
||||||
screen,
|
|
||||||
waitFor,
|
|
||||||
within,
|
|
||||||
getAllByRole,
|
|
||||||
fireEvent,
|
|
||||||
} from '@testing-library/react';
|
|
||||||
import { MemoryRouter, Routes, Route } from 'react-router-dom';
|
import { MemoryRouter, Routes, Route } from 'react-router-dom';
|
||||||
import { FeatureView } from '../feature/FeatureView/FeatureView';
|
|
||||||
import { ThemeProvider } from 'themes/ThemeProvider';
|
import { ThemeProvider } from 'themes/ThemeProvider';
|
||||||
|
import { MainLayout } from 'component/layout/MainLayout/MainLayout';
|
||||||
|
import { FeatureView } from '../feature/FeatureView/FeatureView';
|
||||||
import { AccessProvider } from '../providers/AccessProvider/AccessProvider';
|
import { AccessProvider } from '../providers/AccessProvider/AccessProvider';
|
||||||
import { AnnouncerProvider } from '../common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
import { AnnouncerProvider } from '../common/Announcer/AnnouncerProvider/AnnouncerProvider';
|
||||||
import { testServerRoute, testServerSetup } from '../../utils/testServer';
|
import { testServerRoute, testServerSetup } from '../../utils/testServer';
|
||||||
import { UIProviderContainer } from '../providers/UIProvider/UIProviderContainer';
|
import { UIProviderContainer } from '../providers/UIProvider/UIProviderContainer';
|
||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
const server = testServerSetup();
|
const server = testServerSetup();
|
||||||
|
|
||||||
@ -227,7 +221,10 @@ const UnleashUiSetup: FC<{ path: string; pathTemplate: string }> = ({
|
|||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<AnnouncerProvider>
|
<AnnouncerProvider>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path={pathTemplate} element={children} />
|
<Route
|
||||||
|
path={pathTemplate}
|
||||||
|
element={<MainLayout>{children}</MainLayout>}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</AnnouncerProvider>
|
</AnnouncerProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
@ -31,7 +31,10 @@ export const FeatureNotFound = () => {
|
|||||||
The feature{' '}
|
The feature{' '}
|
||||||
<strong className={styles.featureId}>{featureId}</strong> has
|
<strong className={styles.featureId}>{featureId}</strong> has
|
||||||
been archived. You can find it on the{' '}
|
been archived. You can find it on the{' '}
|
||||||
<Link to={'/archive'}>archive page</Link>.
|
<Link to={`/projects/${projectId}/archive`}>
|
||||||
|
project archive page
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Tab, Tabs, useMediaQuery } from '@mui/material';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { Tab, Tabs, useMediaQuery } from '@mui/material';
|
||||||
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
|
import { Archive, FileCopy, Label, WatchLater } from '@mui/icons-material';
|
||||||
import {
|
import {
|
||||||
Link,
|
Link,
|
||||||
@ -30,11 +30,7 @@ import { FeatureStatusChip } from 'component/common/FeatureStatusChip/FeatureSta
|
|||||||
import { FeatureNotFound } from 'component/feature/FeatureView/FeatureNotFound/FeatureNotFound';
|
import { FeatureNotFound } from 'component/feature/FeatureView/FeatureNotFound/FeatureNotFound';
|
||||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||||
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
|
import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveDialog';
|
||||||
import { DraftBanner } from 'component/changeRequest/DraftBanner/DraftBanner';
|
|
||||||
import { MainLayout } from 'component/layout/MainLayout/MainLayout';
|
|
||||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
|
||||||
import { useFavoriteFeaturesApi } from 'hooks/api/actions/useFavoriteFeaturesApi/useFavoriteFeaturesApi';
|
import { useFavoriteFeaturesApi } from 'hooks/api/actions/useFavoriteFeaturesApi/useFavoriteFeaturesApi';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
|
||||||
import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton';
|
import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton';
|
||||||
|
|
||||||
export const FeatureView = () => {
|
export const FeatureView = () => {
|
||||||
@ -43,9 +39,6 @@ export const FeatureView = () => {
|
|||||||
const { refetch: projectRefetch } = useProject(projectId);
|
const { refetch: projectRefetch } = useProject(projectId);
|
||||||
const { favorite, unfavorite } = useFavoriteFeaturesApi();
|
const { favorite, unfavorite } = useFavoriteFeaturesApi();
|
||||||
const { refetchFeature } = useFeature(projectId, featureId);
|
const { refetchFeature } = useFeature(projectId, featureId);
|
||||||
const { isChangeRequestConfiguredInAnyEnv } =
|
|
||||||
useChangeRequestsEnabled(projectId);
|
|
||||||
const { uiConfig } = useUiConfig();
|
|
||||||
|
|
||||||
const [openTagDialog, setOpenTagDialog] = useState(false);
|
const [openTagDialog, setOpenTagDialog] = useState(false);
|
||||||
const [showDelDialog, setShowDelDialog] = useState(false);
|
const [showDelDialog, setShowDelDialog] = useState(false);
|
||||||
@ -86,10 +79,6 @@ export const FeatureView = () => {
|
|||||||
|
|
||||||
const activeTab = tabData.find(tab => tab.path === pathname) ?? tabData[0];
|
const activeTab = tabData.find(tab => tab.path === pathname) ?? tabData[0];
|
||||||
|
|
||||||
if (status === 404) {
|
|
||||||
return <FeatureNotFound />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onFavorite = async () => {
|
const onFavorite = async () => {
|
||||||
if (feature?.favorite) {
|
if (feature?.favorite) {
|
||||||
await unfavorite(projectId, feature.name);
|
await unfavorite(projectId, feature.name);
|
||||||
@ -99,150 +88,125 @@ export const FeatureView = () => {
|
|||||||
refetchFeature();
|
refetchFeature();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
if (status === 404) {
|
||||||
<MainLayout
|
return <FeatureNotFound />;
|
||||||
ref={ref}
|
}
|
||||||
subheader={
|
|
||||||
isChangeRequestConfiguredInAnyEnv() ? (
|
|
||||||
<DraftBanner project={projectId} />
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={error === undefined}
|
|
||||||
show={
|
|
||||||
<div ref={ref}>
|
|
||||||
<div className={styles.header}>
|
|
||||||
<div className={styles.innerContainer}>
|
|
||||||
<div className={styles.toggleInfoContainer}>
|
|
||||||
<FavoriteIconButton
|
|
||||||
onClick={onFavorite}
|
|
||||||
isFavorite={feature?.favorite}
|
|
||||||
/>
|
|
||||||
<h1
|
|
||||||
className={styles.featureViewHeader}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
{feature.name}{' '}
|
|
||||||
</h1>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={!smallScreen}
|
|
||||||
show={
|
|
||||||
<FeatureStatusChip
|
|
||||||
stale={feature?.stale}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.toolbarContainer}>
|
if (error !== undefined) {
|
||||||
<PermissionIconButton
|
return <div ref={ref} />;
|
||||||
permission={CREATE_FEATURE}
|
}
|
||||||
projectId={projectId}
|
|
||||||
data-loading
|
return (
|
||||||
component={Link}
|
<div ref={ref}>
|
||||||
to={`/projects/${projectId}/features/${featureId}/strategies/copy`}
|
<div className={styles.header}>
|
||||||
tooltipProps={{
|
<div className={styles.innerContainer}>
|
||||||
title: 'Copy feature toggle',
|
<div className={styles.toggleInfoContainer}>
|
||||||
}}
|
<FavoriteIconButton
|
||||||
>
|
onClick={onFavorite}
|
||||||
<FileCopy />
|
isFavorite={feature?.favorite}
|
||||||
</PermissionIconButton>
|
|
||||||
<PermissionIconButton
|
|
||||||
permission={DELETE_FEATURE}
|
|
||||||
projectId={projectId}
|
|
||||||
tooltipProps={{
|
|
||||||
title: 'Archive feature toggle',
|
|
||||||
}}
|
|
||||||
data-loading
|
|
||||||
onClick={() => setShowDelDialog(true)}
|
|
||||||
>
|
|
||||||
<Archive />
|
|
||||||
</PermissionIconButton>
|
|
||||||
<PermissionIconButton
|
|
||||||
onClick={() => setOpenStaleDialog(true)}
|
|
||||||
permission={UPDATE_FEATURE}
|
|
||||||
projectId={projectId}
|
|
||||||
tooltipProps={{
|
|
||||||
title: 'Toggle stale state',
|
|
||||||
}}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<WatchLater />
|
|
||||||
</PermissionIconButton>
|
|
||||||
<PermissionIconButton
|
|
||||||
onClick={() => setOpenTagDialog(true)}
|
|
||||||
permission={UPDATE_FEATURE}
|
|
||||||
projectId={projectId}
|
|
||||||
tooltipProps={{ title: 'Add tag' }}
|
|
||||||
data-loading
|
|
||||||
>
|
|
||||||
<Label />
|
|
||||||
</PermissionIconButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.separator} />
|
|
||||||
<div className={styles.tabContainer}>
|
|
||||||
<Tabs
|
|
||||||
value={activeTab.path}
|
|
||||||
indicatorColor="primary"
|
|
||||||
textColor="primary"
|
|
||||||
>
|
|
||||||
{tabData.map(tab => (
|
|
||||||
<Tab
|
|
||||||
key={tab.title}
|
|
||||||
label={tab.title}
|
|
||||||
value={tab.path}
|
|
||||||
onClick={() => navigate(tab.path)}
|
|
||||||
className={styles.tabButton}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Tabs>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Routes>
|
|
||||||
<Route
|
|
||||||
path="metrics"
|
|
||||||
element={<FeatureMetrics />}
|
|
||||||
/>
|
|
||||||
<Route path="logs" element={<FeatureLog />} />
|
|
||||||
<Route
|
|
||||||
path="variants"
|
|
||||||
element={<FeatureVariants />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="settings"
|
|
||||||
element={<FeatureSettings />}
|
|
||||||
/>
|
|
||||||
<Route path="*" element={<FeatureOverview />} />
|
|
||||||
</Routes>
|
|
||||||
<FeatureArchiveDialog
|
|
||||||
isOpen={showDelDialog}
|
|
||||||
onConfirm={() => {
|
|
||||||
projectRefetch();
|
|
||||||
navigate(`/projects/${projectId}`);
|
|
||||||
}}
|
|
||||||
onClose={() => setShowDelDialog(false)}
|
|
||||||
projectId={projectId}
|
|
||||||
featureId={featureId}
|
|
||||||
/>
|
/>
|
||||||
<FeatureStaleDialog
|
<h1 className={styles.featureViewHeader} data-loading>
|
||||||
isStale={feature.stale}
|
{feature.name}{' '}
|
||||||
isOpen={openStaleDialog}
|
</h1>
|
||||||
onClose={() => {
|
<ConditionallyRender
|
||||||
setOpenStaleDialog(false);
|
condition={!smallScreen}
|
||||||
refetchFeature();
|
show={<FeatureStatusChip stale={feature?.stale} />}
|
||||||
}}
|
|
||||||
featureId={featureId}
|
|
||||||
projectId={projectId}
|
|
||||||
/>
|
|
||||||
<AddTagDialog
|
|
||||||
open={openTagDialog}
|
|
||||||
setOpen={setOpenTagDialog}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
|
<div className={styles.toolbarContainer}>
|
||||||
|
<PermissionIconButton
|
||||||
|
permission={CREATE_FEATURE}
|
||||||
|
projectId={projectId}
|
||||||
|
data-loading
|
||||||
|
component={Link}
|
||||||
|
to={`/projects/${projectId}/features/${featureId}/strategies/copy`}
|
||||||
|
tooltipProps={{
|
||||||
|
title: 'Copy feature toggle',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FileCopy />
|
||||||
|
</PermissionIconButton>
|
||||||
|
<PermissionIconButton
|
||||||
|
permission={DELETE_FEATURE}
|
||||||
|
projectId={projectId}
|
||||||
|
tooltipProps={{
|
||||||
|
title: 'Archive feature toggle',
|
||||||
|
}}
|
||||||
|
data-loading
|
||||||
|
onClick={() => setShowDelDialog(true)}
|
||||||
|
>
|
||||||
|
<Archive />
|
||||||
|
</PermissionIconButton>
|
||||||
|
<PermissionIconButton
|
||||||
|
onClick={() => setOpenStaleDialog(true)}
|
||||||
|
permission={UPDATE_FEATURE}
|
||||||
|
projectId={projectId}
|
||||||
|
tooltipProps={{
|
||||||
|
title: 'Toggle stale state',
|
||||||
|
}}
|
||||||
|
data-loading
|
||||||
|
>
|
||||||
|
<WatchLater />
|
||||||
|
</PermissionIconButton>
|
||||||
|
<PermissionIconButton
|
||||||
|
onClick={() => setOpenTagDialog(true)}
|
||||||
|
permission={UPDATE_FEATURE}
|
||||||
|
projectId={projectId}
|
||||||
|
tooltipProps={{ title: 'Add tag' }}
|
||||||
|
data-loading
|
||||||
|
>
|
||||||
|
<Label />
|
||||||
|
</PermissionIconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.separator} />
|
||||||
|
<div className={styles.tabContainer}>
|
||||||
|
<Tabs
|
||||||
|
value={activeTab.path}
|
||||||
|
indicatorColor="primary"
|
||||||
|
textColor="primary"
|
||||||
|
>
|
||||||
|
{tabData.map(tab => (
|
||||||
|
<Tab
|
||||||
|
key={tab.title}
|
||||||
|
label={tab.title}
|
||||||
|
value={tab.path}
|
||||||
|
onClick={() => navigate(tab.path)}
|
||||||
|
className={styles.tabButton}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Routes>
|
||||||
|
<Route path="metrics" element={<FeatureMetrics />} />
|
||||||
|
<Route path="logs" element={<FeatureLog />} />
|
||||||
|
<Route path="variants" element={<FeatureVariants />} />
|
||||||
|
<Route path="settings" element={<FeatureSettings />} />
|
||||||
|
<Route path="*" element={<FeatureOverview />} />
|
||||||
|
</Routes>
|
||||||
|
<FeatureArchiveDialog
|
||||||
|
isOpen={showDelDialog}
|
||||||
|
onConfirm={() => {
|
||||||
|
projectRefetch();
|
||||||
|
navigate(`/projects/${projectId}`);
|
||||||
|
}}
|
||||||
|
onClose={() => setShowDelDialog(false)}
|
||||||
|
projectId={projectId}
|
||||||
|
featureId={featureId}
|
||||||
/>
|
/>
|
||||||
</MainLayout>
|
<FeatureStaleDialog
|
||||||
|
isStale={feature.stale}
|
||||||
|
isOpen={openStaleDialog}
|
||||||
|
onClose={() => {
|
||||||
|
setOpenStaleDialog(false);
|
||||||
|
refetchFeature();
|
||||||
|
}}
|
||||||
|
featureId={featureId}
|
||||||
|
projectId={projectId}
|
||||||
|
/>
|
||||||
|
<AddTagDialog open={openTagDialog} setOpen={setOpenTagDialog} />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,10 +2,10 @@ import { FC, useState, VFC } from 'react';
|
|||||||
import { Box, Button, styled, Typography } from '@mui/material';
|
import { Box, Button, styled, Typography } from '@mui/material';
|
||||||
import { useStyles as useAppStyles } from 'component/App.styles';
|
import { useStyles as useAppStyles } from 'component/App.styles';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { ChangeRequestSidebar } from '../ChangeRequestSidebar/ChangeRequestSidebar';
|
import { ChangeRequestSidebar } from 'component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar';
|
||||||
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
|
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
|
||||||
import { IChangeRequest } from '../changeRequest.types';
|
import { IChangeRequest } from 'component/changeRequest/changeRequest.types';
|
||||||
import { changesCount } from '../changesCount';
|
import { changesCount } from 'component/changeRequest/changesCount';
|
||||||
|
|
||||||
interface IDraftBannerProps {
|
interface IDraftBannerProps {
|
||||||
project: string;
|
project: string;
|
@ -12,6 +12,10 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
|||||||
import { SkipNavLink } from 'component/common/SkipNav/SkipNavLink';
|
import { SkipNavLink } from 'component/common/SkipNav/SkipNavLink';
|
||||||
import { SkipNavTarget } from 'component/common/SkipNav/SkipNavTarget';
|
import { SkipNavTarget } from 'component/common/SkipNav/SkipNavTarget';
|
||||||
import { formatAssetPath } from 'utils/formatPath';
|
import { formatAssetPath } from 'utils/formatPath';
|
||||||
|
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
||||||
|
import { DraftBanner } from './DraftBanner/DraftBanner';
|
||||||
|
|
||||||
const useStyles = makeStyles()(theme => ({
|
const useStyles = makeStyles()(theme => ({
|
||||||
container: {
|
container: {
|
||||||
@ -30,14 +34,17 @@ const useStyles = makeStyles()(theme => ({
|
|||||||
|
|
||||||
interface IMainLayoutProps {
|
interface IMainLayoutProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
subheader?: ReactNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
||||||
({ children, subheader }, ref) => {
|
({ children }, ref) => {
|
||||||
const { classes } = useStyles();
|
const { classes } = useStyles();
|
||||||
const { classes: styles } = useAppStyles();
|
const { classes: styles } = useAppStyles();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
|
const projectId = useOptionalPathParam('projectId');
|
||||||
|
const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled(
|
||||||
|
projectId || ''
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -46,7 +53,12 @@ export const MainLayout = forwardRef<HTMLDivElement, IMainLayoutProps>(
|
|||||||
<SkipNavTarget />
|
<SkipNavTarget />
|
||||||
<Grid container className={classes.container}>
|
<Grid container className={classes.container}>
|
||||||
<main className={classnames(styles.contentWrapper)}>
|
<main className={classnames(styles.contentWrapper)}>
|
||||||
{subheader}
|
<ConditionallyRender
|
||||||
|
condition={Boolean(
|
||||||
|
projectId && isChangeRequestConfiguredInAnyEnv()
|
||||||
|
)}
|
||||||
|
show={<DraftBanner project={projectId || ''} />}
|
||||||
|
/>
|
||||||
<Grid
|
<Grid
|
||||||
item
|
item
|
||||||
className={styles.content}
|
className={styles.content}
|
||||||
|
@ -54,7 +54,6 @@ exports[`returns all baseRoutes 1`] = `
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"isStandalone": true,
|
|
||||||
"menu": {},
|
"menu": {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:projectId/features/:featureId/*",
|
"path": "/projects/:projectId/features/:featureId/*",
|
||||||
@ -80,7 +79,6 @@ exports[`returns all baseRoutes 1`] = `
|
|||||||
{
|
{
|
||||||
"component": [Function],
|
"component": [Function],
|
||||||
"flag": "P",
|
"flag": "P",
|
||||||
"isStandalone": true,
|
|
||||||
"menu": {},
|
"menu": {},
|
||||||
"parent": "/projects",
|
"parent": "/projects",
|
||||||
"path": "/projects/:projectId/*",
|
"path": "/projects/:projectId/*",
|
||||||
|
@ -123,7 +123,6 @@ export const routes: IRoute[] = [
|
|||||||
title: 'FeatureView',
|
title: 'FeatureView',
|
||||||
component: FeatureView,
|
component: FeatureView,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
isStandalone: true,
|
|
||||||
menu: {},
|
menu: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -150,7 +149,6 @@ export const routes: IRoute[] = [
|
|||||||
flag: P,
|
flag: P,
|
||||||
type: 'protected',
|
type: 'protected',
|
||||||
menu: {},
|
menu: {},
|
||||||
isStandalone: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/projects',
|
path: '/projects',
|
||||||
|
@ -37,11 +37,8 @@ import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
|
|||||||
import { DeleteProjectDialogue } from './DeleteProject/DeleteProjectDialogue';
|
import { DeleteProjectDialogue } from './DeleteProject/DeleteProjectDialogue';
|
||||||
import { ProjectLog } from './ProjectLog/ProjectLog';
|
import { ProjectLog } from './ProjectLog/ProjectLog';
|
||||||
import { ChangeRequestOverview } from 'component/changeRequest/ChangeRequestOverview/ChangeRequestOverview';
|
import { ChangeRequestOverview } from 'component/changeRequest/ChangeRequestOverview/ChangeRequestOverview';
|
||||||
import { DraftBanner } from 'component/changeRequest/DraftBanner/DraftBanner';
|
|
||||||
import { MainLayout } from 'component/layout/MainLayout/MainLayout';
|
|
||||||
import { ProjectChangeRequests } from '../../changeRequest/ProjectChangeRequests/ProjectChangeRequests';
|
import { ProjectChangeRequests } from '../../changeRequest/ProjectChangeRequests/ProjectChangeRequests';
|
||||||
import { ProjectSettings } from './ProjectSettings/ProjectSettings';
|
import { ProjectSettings } from './ProjectSettings/ProjectSettings';
|
||||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
|
||||||
import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
|
import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
|
||||||
|
|
||||||
const Project = () => {
|
const Project = () => {
|
||||||
@ -55,8 +52,6 @@ const Project = () => {
|
|||||||
const { isOss } = useUiConfig();
|
const { isOss } = useUiConfig();
|
||||||
const basePath = `/projects/${projectId}`;
|
const basePath = `/projects/${projectId}`;
|
||||||
const projectName = project?.name || projectId;
|
const projectName = project?.name || projectId;
|
||||||
const { isChangeRequestConfiguredInAnyEnv } =
|
|
||||||
useChangeRequestsEnabled(projectId);
|
|
||||||
const { favorite, unfavorite } = useFavoriteProjectsApi();
|
const { favorite, unfavorite } = useFavoriteProjectsApi();
|
||||||
|
|
||||||
const [showDelDialog, setShowDelDialog] = useState(false);
|
const [showDelDialog, setShowDelDialog] = useState(false);
|
||||||
@ -122,14 +117,7 @@ const Project = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainLayout
|
<div ref={ref}>
|
||||||
ref={ref}
|
|
||||||
subheader={
|
|
||||||
isChangeRequestConfiguredInAnyEnv() ? (
|
|
||||||
<DraftBanner project={projectId} />
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<StyledHeader>
|
<StyledHeader>
|
||||||
<StyledInnerContainer>
|
<StyledInnerContainer>
|
||||||
<StyledTopRow>
|
<StyledTopRow>
|
||||||
@ -259,7 +247,7 @@ const Project = () => {
|
|||||||
<Route path="settings/*" element={<ProjectSettings />} />
|
<Route path="settings/*" element={<ProjectSettings />} />
|
||||||
<Route path="*" element={<ProjectOverview />} />
|
<Route path="*" element={<ProjectOverview />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</MainLayout>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user