mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-28 00:06:53 +01:00
fix:handle non-existing feature toggle
This commit is contained in:
parent
195cded10b
commit
b5072928b3
@ -75,17 +75,32 @@ const App = ({ location, user, fetchUiBootstrap, feedback }: IAppProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SWRConfig value={{
|
<SWRConfig
|
||||||
onError: (error) => {
|
value={{
|
||||||
if (!isUnauthorized()) {
|
onErrorRetry: (
|
||||||
setToastData({
|
error,
|
||||||
show: true,
|
_key,
|
||||||
type: 'error',
|
_config,
|
||||||
text: error.message,
|
revalidate,
|
||||||
});
|
{ retryCount }
|
||||||
}
|
) => {
|
||||||
},
|
// Never retry on 404.
|
||||||
}}>
|
if (error.status === 404) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
setTimeout(() => revalidate({ retryCount }), 5000);
|
||||||
|
},
|
||||||
|
onError: error => {
|
||||||
|
if (!isUnauthorized()) {
|
||||||
|
setToastData({
|
||||||
|
show: true,
|
||||||
|
type: 'error',
|
||||||
|
text: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<LayoutPicker location={location}>
|
<LayoutPicker location={location}>
|
||||||
<Switch>
|
<Switch>
|
||||||
|
@ -18,10 +18,12 @@ import FeatureVariants from './FeatureVariants/FeatureVariants';
|
|||||||
import { useStyles } from './FeatureView2.styles';
|
import { useStyles } from './FeatureView2.styles';
|
||||||
import FeatureSettings from './FeatureSettings/FeatureSettings';
|
import FeatureSettings from './FeatureSettings/FeatureSettings';
|
||||||
import useLoading from '../../../hooks/useLoading';
|
import useLoading from '../../../hooks/useLoading';
|
||||||
|
import ConditionallyRender from '../../common/ConditionallyRender';
|
||||||
|
import { getCreateTogglePath } from '../../../utils/route-path-helpers';
|
||||||
|
|
||||||
const FeatureView2 = () => {
|
const FeatureView2 = () => {
|
||||||
const { projectId, featureId } = useParams<IFeatureViewParams>();
|
const { projectId, featureId } = useParams<IFeatureViewParams>();
|
||||||
const { feature, loading } = useFeature(projectId, featureId);
|
const { feature, loading, error } = useFeature(projectId, featureId);
|
||||||
const { a11yProps } = useTabs(0);
|
const { a11yProps } = useTabs(0);
|
||||||
const { archiveFeatureToggle } = useFeatureApi();
|
const { archiveFeatureToggle } = useFeatureApi();
|
||||||
const { toast, setToastData } = useToast();
|
const { toast, setToastData } = useToast();
|
||||||
@ -97,82 +99,104 @@ const FeatureView2 = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const renderFeatureNotExist = () => {
|
||||||
<div ref={ref}>
|
return (
|
||||||
<div className={styles.header}>
|
<div>
|
||||||
<div className={styles.innerContainer}>
|
<p>
|
||||||
<h2 className={styles.featureViewHeader} data-loading>
|
The feature <strong>{featureId} </strong>does not exist. Do
|
||||||
{feature.name}
|
you want to
|
||||||
</h2>
|
<Link to={getCreateTogglePath(projectId)}>create it</Link>
|
||||||
<div className={styles.actions}>
|
?
|
||||||
<PermissionIconButton
|
</p>
|
||||||
permission={UPDATE_FEATURE}
|
|
||||||
tooltip="Copy"
|
|
||||||
data-loading
|
|
||||||
component={Link}
|
|
||||||
to={`/projects/${projectId}/features2/${featureId}/strategies/copy`}
|
|
||||||
>
|
|
||||||
<FileCopy />
|
|
||||||
</PermissionIconButton>
|
|
||||||
<PermissionIconButton
|
|
||||||
permission={UPDATE_FEATURE}
|
|
||||||
tooltip="Archive feature toggle"
|
|
||||||
data-loading
|
|
||||||
onClick={() => setShowDelDialog(true)}
|
|
||||||
>
|
|
||||||
<Archive />
|
|
||||||
</PermissionIconButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.separator} />
|
|
||||||
<div className={styles.tabContainer}>
|
|
||||||
<Tabs
|
|
||||||
value={history.location.pathname}
|
|
||||||
indicatorColor="primary"
|
|
||||||
textColor="primary"
|
|
||||||
className={styles.tabNavigation}
|
|
||||||
>
|
|
||||||
{renderTabs()}
|
|
||||||
</Tabs>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Route
|
);
|
||||||
exact
|
};
|
||||||
path={`/projects/:projectId/features2/:featureId`}
|
|
||||||
component={FeatureOverview}
|
return (
|
||||||
/>
|
<ConditionallyRender
|
||||||
<Route
|
condition={error === undefined}
|
||||||
path={`/projects/:projectId/features2/:featureId/strategies`}
|
show={
|
||||||
component={FeatureStrategies}
|
<div ref={ref}>
|
||||||
/>
|
<div className={styles.header}>
|
||||||
<Route
|
<div className={styles.innerContainer}>
|
||||||
path={`/projects/:projectId/features2/:featureId/metrics`}
|
<h2
|
||||||
component={FeatureMetrics}
|
className={styles.featureViewHeader}
|
||||||
/>
|
data-loading
|
||||||
<Route
|
>
|
||||||
path={`/projects/:projectId/features2/:featureId/logs`}
|
{feature.name}
|
||||||
component={FeatureLog}
|
</h2>
|
||||||
/>
|
<div className={styles.actions}>
|
||||||
<Route
|
<PermissionIconButton
|
||||||
path={`/projects/:projectId/features2/:featureId/variants`}
|
permission={UPDATE_FEATURE}
|
||||||
component={FeatureVariants}
|
tooltip="Copy"
|
||||||
/>
|
data-loading
|
||||||
<Route
|
component={Link}
|
||||||
path={`/projects/:projectId/features2/:featureId/settings`}
|
to={`/projects/${projectId}/features2/${featureId}/strategies/copy`}
|
||||||
component={FeatureSettings}
|
>
|
||||||
/>
|
<FileCopy />
|
||||||
<Dialogue
|
</PermissionIconButton>
|
||||||
onClick={() => archiveToggle()}
|
<PermissionIconButton
|
||||||
open={showDelDialog}
|
permission={UPDATE_FEATURE}
|
||||||
onClose={handleCancel}
|
tooltip="Archive feature toggle"
|
||||||
primaryButtonText="Archive toggle"
|
data-loading
|
||||||
secondaryButtonText="Cancel"
|
onClick={() => setShowDelDialog(true)}
|
||||||
title="Archive feature toggle"
|
>
|
||||||
>
|
<Archive />
|
||||||
Are you sure you want to archive this feature toggle?
|
</PermissionIconButton>
|
||||||
</Dialogue>
|
</div>
|
||||||
{toast}
|
</div>
|
||||||
</div>
|
<div className={styles.separator} />
|
||||||
|
<div className={styles.tabContainer}>
|
||||||
|
<Tabs
|
||||||
|
value={history.location.pathname}
|
||||||
|
indicatorColor="primary"
|
||||||
|
textColor="primary"
|
||||||
|
className={styles.tabNavigation}
|
||||||
|
>
|
||||||
|
{renderTabs()}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={`/projects/:projectId/features2/:featureId`}
|
||||||
|
component={FeatureOverview}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`/projects/:projectId/features2/:featureId/strategies`}
|
||||||
|
component={FeatureStrategies}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`/projects/:projectId/features2/:featureId/metrics`}
|
||||||
|
component={FeatureMetrics}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`/projects/:projectId/features2/:featureId/logs`}
|
||||||
|
component={FeatureLog}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`/projects/:projectId/features2/:featureId/variants`}
|
||||||
|
component={FeatureVariants}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path={`/projects/:projectId/features2/:featureId/settings`}
|
||||||
|
component={FeatureSettings}
|
||||||
|
/>
|
||||||
|
<Dialogue
|
||||||
|
onClick={() => archiveToggle()}
|
||||||
|
open={showDelDialog}
|
||||||
|
onClose={handleCancel}
|
||||||
|
primaryButtonText="Archive toggle"
|
||||||
|
secondaryButtonText="Cancel"
|
||||||
|
title="Archive feature toggle"
|
||||||
|
>
|
||||||
|
Are you sure you want to archive this feature toggle?
|
||||||
|
</Dialogue>
|
||||||
|
{toast}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
elseShow={renderFeatureNotExist()}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user