mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
Merge pull request #552 from Unleash/fix/environment-guidance
fix:environment guidance
This commit is contained in:
commit
eab9f89c84
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "unleash-frontend",
|
||||
"description": "unleash your features",
|
||||
"version": "4.3.1",
|
||||
"version": "4.3.0",
|
||||
"keywords": [
|
||||
"unleash",
|
||||
"feature toggle",
|
||||
@ -40,7 +40,7 @@
|
||||
"@material-ui/core": "4.12.3",
|
||||
"@material-ui/icons": "4.11.2",
|
||||
"@material-ui/lab": "4.0.0-alpha.60",
|
||||
"@testing-library/jest-dom": "5.16.1",
|
||||
"@testing-library/jest-dom": "5.16.0",
|
||||
"@testing-library/react": "12.1.2",
|
||||
"@testing-library/user-event": "13.5.0",
|
||||
"@types/debounce": "1.2.1",
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
infoText: {
|
||||
marginBottom: '10px',
|
||||
fontSize: theme.fontSizes.bodySize,
|
||||
},
|
||||
}));
|
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import Dialogue from '../Dialogue';
|
||||
import { useStyles } from './EnvironmentStrategyDialog.styles';
|
||||
|
||||
interface IEnvironmentStrategyDialogProps {
|
||||
open: boolean;
|
||||
featureId: string;
|
||||
projectId: string;
|
||||
onClose: () => void;
|
||||
environmentName?: string;
|
||||
}
|
||||
const EnvironmentStrategyDialog = ({
|
||||
open,
|
||||
environmentName,
|
||||
featureId,
|
||||
projectId,
|
||||
onClose,
|
||||
}: IEnvironmentStrategyDialogProps) => {
|
||||
const styles = useStyles();
|
||||
const history = useHistory();
|
||||
const strategiesLink = `/projects/${projectId}/features2/${featureId}/strategies?environment=${environmentName}&addStrategy=true`;
|
||||
|
||||
return (
|
||||
<Dialogue
|
||||
open={open}
|
||||
maxWidth="sm"
|
||||
onClick={() => history.push(strategiesLink)}
|
||||
onClose={() => onClose()}
|
||||
title="You need to add a strategy to your toggle"
|
||||
primaryButtonText="Take me directly to add strategy"
|
||||
secondaryButtonText="Cancel"
|
||||
>
|
||||
<p className={styles.infoText}>
|
||||
Before you can enable the toggle in the environment, you need to
|
||||
add an activation strategy.
|
||||
</p>
|
||||
<p className={styles.infoText}>
|
||||
You can add the activation strategy by selecting the toggle, open
|
||||
the environment accordion and add the activation strategy.
|
||||
</p>
|
||||
</Dialogue>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnvironmentStrategyDialog;
|
@ -48,11 +48,4 @@ export const useStyles = makeStyles(theme => ({
|
||||
textDecoration: 'none',
|
||||
color: 'inherit',
|
||||
},
|
||||
envName: {
|
||||
display: 'inline-block',
|
||||
width: '90px',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
}));
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
IFeatureToggleListItem,
|
||||
} from '../../../interfaces/featureToggle';
|
||||
import PaginateUI from '../../common/PaginateUI/PaginateUI';
|
||||
import StringTruncator from '../../common/StringTruncator/StringTruncator';
|
||||
interface IFeatureToggleListNewProps {
|
||||
features: IFeatureToggleListItem[];
|
||||
loading: boolean;
|
||||
@ -236,12 +237,11 @@ const FeatureToggleListNew = ({
|
||||
)}
|
||||
align="center"
|
||||
>
|
||||
<span
|
||||
<StringTruncator
|
||||
text={env.name}
|
||||
maxWidth="90"
|
||||
data-loading
|
||||
className={styles.envName}
|
||||
>
|
||||
{env.name}
|
||||
</span>
|
||||
/>
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useRef } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { TableCell, TableRow } from '@material-ui/core';
|
||||
import { useHistory } from 'react-router';
|
||||
|
||||
@ -17,6 +17,8 @@ import useProject from '../../../../hooks/api/getters/useProject/useProject';
|
||||
import { UPDATE_FEATURE } from '../../../providers/AccessProvider/permissions';
|
||||
import PermissionSwitch from '../../../common/PermissionSwitch/PermissionSwitch';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ENVIRONMENT_STRATEGY_ERROR } from '../../../../constants/apiErrors';
|
||||
import EnvironmentStrategyDialog from '../../../common/EnvironmentStrategiesDialog/EnvironmentStrategyDialog';
|
||||
|
||||
interface IFeatureToggleListNewItemProps {
|
||||
name: string;
|
||||
@ -46,6 +48,12 @@ const FeatureToggleListNewItem = ({
|
||||
const styles = useStyles();
|
||||
const history = useHistory();
|
||||
const ref = useRef(null);
|
||||
const [showInfoBox, setShowInfoBox] = useState(false);
|
||||
const [environmentName, setEnvironmentName] = useState('');
|
||||
|
||||
const closeInfoBox = () => {
|
||||
setShowInfoBox(false);
|
||||
};
|
||||
|
||||
const onClick = (e: SyntheticEvent) => {
|
||||
if (!ref.current?.contains(e.target)) {
|
||||
@ -53,7 +61,7 @@ const FeatureToggleListNewItem = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggle = (env: IEnvironments, e: SyntheticEvent) => {
|
||||
const handleToggle = (env: IEnvironments) => {
|
||||
toggleFeatureByEnvironment(env.name, env.enabled)
|
||||
.then(() => {
|
||||
setToastData({
|
||||
@ -64,11 +72,15 @@ const FeatureToggleListNewItem = ({
|
||||
refetch();
|
||||
})
|
||||
.catch(e => {
|
||||
setToastData({
|
||||
show: true,
|
||||
type: 'error',
|
||||
text: e.message,
|
||||
});
|
||||
if (e.message === ENVIRONMENT_STRATEGY_ERROR) {
|
||||
setShowInfoBox(true);
|
||||
} else {
|
||||
setToastData({
|
||||
show: true,
|
||||
type: 'error',
|
||||
text: e.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -140,7 +152,10 @@ const FeatureToggleListNewItem = ({
|
||||
projectId={projectId}
|
||||
permission={UPDATE_FEATURE}
|
||||
ref={ref}
|
||||
onClick={handleToggle.bind(this, env)}
|
||||
onClick={() => {
|
||||
handleToggle(env);
|
||||
setEnvironmentName(env.name);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</TableCell>
|
||||
@ -148,6 +163,13 @@ const FeatureToggleListNewItem = ({
|
||||
})}
|
||||
</TableRow>
|
||||
{toast}
|
||||
<EnvironmentStrategyDialog
|
||||
open={showInfoBox}
|
||||
onClose={closeInfoBox}
|
||||
projectId={projectId}
|
||||
featureId={name}
|
||||
environmentName={environmentName}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { useParams } from 'react-router';
|
||||
import { ENVIRONMENT_STRATEGY_ERROR } from '../../../../../../constants/apiErrors';
|
||||
import useFeatureApi from '../../../../../../hooks/api/actions/useFeatureApi/useFeatureApi';
|
||||
import useFeature from '../../../../../../hooks/api/getters/useFeature/useFeature';
|
||||
import { TSetToastData } from '../../../../../../hooks/useToast';
|
||||
@ -13,6 +14,7 @@ interface IFeatureOverviewEnvSwitchProps {
|
||||
setToastData: TSetToastData;
|
||||
callback?: () => void;
|
||||
text?: string;
|
||||
showInfoBox?: () => void;
|
||||
}
|
||||
|
||||
const FeatureOverviewEnvSwitch = ({
|
||||
@ -20,6 +22,7 @@ const FeatureOverviewEnvSwitch = ({
|
||||
setToastData,
|
||||
callback,
|
||||
text,
|
||||
showInfoBox,
|
||||
}: IFeatureOverviewEnvSwitchProps) => {
|
||||
const { featureId, projectId } = useParams<IFeatureViewParams>();
|
||||
const { toggleFeatureEnvironmentOn, toggleFeatureEnvironmentOff } =
|
||||
@ -39,11 +42,15 @@ const FeatureOverviewEnvSwitch = ({
|
||||
callback();
|
||||
}
|
||||
} catch (e: any) {
|
||||
setToastData({
|
||||
show: true,
|
||||
type: 'error',
|
||||
text: e.toString(),
|
||||
});
|
||||
if (e.message === ENVIRONMENT_STRATEGY_ERROR) {
|
||||
showInfoBox(true);
|
||||
} else {
|
||||
setToastData({
|
||||
show: true,
|
||||
type: 'error',
|
||||
text: e.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import { useState } from 'react';
|
||||
import { useParams } from 'react-router';
|
||||
import useFeatureApi from '../../../../../hooks/api/actions/useFeatureApi/useFeatureApi';
|
||||
import useFeature from '../../../../../hooks/api/getters/useFeature/useFeature';
|
||||
import useToast from '../../../../../hooks/useToast';
|
||||
import { IFeatureViewParams } from '../../../../../interfaces/params';
|
||||
import EnvironmentStrategyDialog from '../../../../common/EnvironmentStrategiesDialog/EnvironmentStrategyDialog';
|
||||
import FeatureOverviewEnvSwitch from './FeatureOverviewEnvSwitch/FeatureOverviewEnvSwitch';
|
||||
import { useStyles } from './FeatureOverviewEnvSwitches.styles';
|
||||
|
||||
@ -13,6 +15,12 @@ const FeatureOverviewEnvSwitches = () => {
|
||||
useFeatureApi();
|
||||
const { feature } = useFeature(projectId, featureId);
|
||||
const { toast, setToastData } = useToast();
|
||||
const [showInfoBox, setShowInfoBox] = useState(false);
|
||||
const [environmentName, setEnvironmentName] = useState('');
|
||||
|
||||
const closeInfoBox = () => {
|
||||
setShowInfoBox(false);
|
||||
};
|
||||
|
||||
const renderEnvironmentSwitches = () => {
|
||||
return feature?.environments.map(env => {
|
||||
@ -21,6 +29,10 @@ const FeatureOverviewEnvSwitches = () => {
|
||||
key={env.name}
|
||||
env={env}
|
||||
setToastData={setToastData}
|
||||
showInfoBox={() => {
|
||||
setEnvironmentName(env.name);
|
||||
setShowInfoBox(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -38,6 +50,13 @@ const FeatureOverviewEnvSwitches = () => {
|
||||
</Tooltip>
|
||||
{renderEnvironmentSwitches()}
|
||||
{toast}
|
||||
<EnvironmentStrategyDialog
|
||||
open={showInfoBox}
|
||||
onClose={closeInfoBox}
|
||||
projectId={projectId}
|
||||
featureId={featureId}
|
||||
environmentName={environmentName}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -62,7 +62,6 @@ const FeatureStrategiesEnvironments = () => {
|
||||
useEffect(() => {
|
||||
if (addStrategy) {
|
||||
setExpandedSidebar(true);
|
||||
history.replace(history.location.pathname);
|
||||
}
|
||||
if (!feature) return;
|
||||
|
||||
|
1
frontend/src/constants/apiErrors.ts
Normal file
1
frontend/src/constants/apiErrors.ts
Normal file
@ -0,0 +1 @@
|
||||
export const ENVIRONMENT_STRATEGY_ERROR = 'You can not enable the environment before it has strategies';
|
@ -1886,10 +1886,10 @@
|
||||
lz-string "^1.4.4"
|
||||
pretty-format "^27.0.2"
|
||||
|
||||
"@testing-library/jest-dom@5.16.1":
|
||||
version "5.16.1"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz#3db7df5ae97596264a7da9696fe14695ba02e51f"
|
||||
integrity sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==
|
||||
"@testing-library/jest-dom@5.16.0":
|
||||
version "5.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.0.tgz#de1a7c5fedfeb80eb2be9fc81f61473973b302b3"
|
||||
integrity sha512-ECygvCL6ufPfHna4fsk7o24+3PVNhRbioDpFbfSVEZaglT6EjuRP+w8I5tzigFz1fobpvCrVRoKyR4qx2QUCxw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.9.2"
|
||||
"@types/testing-library__jest-dom" "^5.9.1"
|
||||
|
Loading…
Reference in New Issue
Block a user