1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-15 01:16:22 +02:00

fix: add project move warning when change requests exists with the fe… (#2526)

* This PR adds a warning when you attempt to move a feature toggle if
you have existing pending drafts that reference the feature. You need to
resolve the drafts before the feature can be moved from one project to
another.
This commit is contained in:
Fredrik Strand Oseberg 2022-11-24 15:55:16 +01:00 committed by GitHub
parent 3f881caa37
commit d63f5d9a4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 6 deletions

View File

@ -11,6 +11,7 @@ import FeatureSettingsProjectConfirm from './FeatureSettingsProjectConfirm/Featu
import { formatUnknownError } from 'utils/formatUnknownError';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import useProjects from 'hooks/api/getters/useProjects/useProjects';
import { usePendingChangeRequestsForFeature } from 'hooks/api/getters/usePendingChangeRequestsForFeature/usePendingChangeRequestsForFeature';
const FeatureSettingsProject = () => {
const { hasAccess } = useContext(AccessContext);
@ -23,6 +24,10 @@ const FeatureSettingsProject = () => {
const [project, setProject] = useState(projectId);
const { projects } = useProjects();
const navigate = useNavigate();
const { changeRequests } = usePendingChangeRequestsForFeature(
projectId,
featureId
);
const onConfirm = async () => {
try {
@ -69,6 +74,7 @@ const FeatureSettingsProject = () => {
Save
</PermissionButton>
<FeatureSettingsProjectConfirm
changeRequests={changeRequests}
projectId={project}
open={showConfirmDialog}
feature={feature}

View File

@ -5,7 +5,10 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { useStyles } from './FeatureSettingsProjectConfirm.styles';
import { arraysHaveSameItems } from 'utils/arraysHaveSameItems';
import { Alert } from '@mui/material';
import { Alert, List, ListItem } from '@mui/material';
import { Link } from 'react-router-dom';
import { IChangeRequest } from 'component/changeRequest/changeRequest.types';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
interface IFeatureSettingsProjectConfirm {
projectId: string;
@ -13,6 +16,7 @@ interface IFeatureSettingsProjectConfirm {
onClose: () => void;
onClick: (args: any) => void;
feature: IFeatureToggle;
changeRequests: IChangeRequest[] | undefined;
}
const FeatureSettingsProjectConfirm = ({
@ -21,7 +25,9 @@ const FeatureSettingsProjectConfirm = ({
onClose,
onClick,
feature,
changeRequests,
}: IFeatureSettingsProjectConfirm) => {
const currentProjectId = useRequiredPathParam('projectId');
const { project } = useProject(projectId);
const { classes: styles } = useStyles();
@ -32,9 +38,13 @@ const FeatureSettingsProjectConfirm = ({
);
}, [feature, project]);
const hasPendingChangeRequests = changeRequests
? changeRequests.length > 0
: false;
return (
<ConditionallyRender
condition={hasSameEnvironments}
condition={hasSameEnvironments && !hasPendingChangeRequests}
show={
<Dialogue
open={open}
@ -49,11 +59,11 @@ const FeatureSettingsProjectConfirm = ({
This feature toggle is compatible with the new
project.
</Alert>
<p>
Are you sure you want to change the project for this
toggle?
</p>
</div>
<p>
Are you sure you want to change the project for this
toggle?
</p>
</Dialogue>
}
elseShow={
@ -72,6 +82,35 @@ const FeatureSettingsProjectConfirm = ({
projects, both projects must have the exact same
environments enabled.
</p>
<ConditionallyRender
condition={hasPendingChangeRequests}
show={
<>
<p>
In addition the feature toggle must not
have any pending change requests. This
feature toggle is currently referenced
in the following change requests:
</p>
<List>
{changeRequests?.map(changeRequest => {
return (
<ListItem
key={changeRequest.id}
>
<Link
to={`/projects/${currentProjectId}/change-requests/${changeRequest.id}`}
>
View change request{' '}
{changeRequest.id}
</Link>
</ListItem>
);
})}
</List>
</>
}
/>
</div>
</Dialogue>
}

View File

@ -0,0 +1,31 @@
import useSWR from 'swr';
import { formatApiPath } from 'utils/formatPath';
import handleErrorResponses from '../httpErrorResponseHandler';
import { IChangeRequest } from 'component/changeRequest/changeRequest.types';
import useUiConfig from '../useUiConfig/useUiConfig';
const fetcher = (path: string) => {
return fetch(path)
.then(handleErrorResponses('ChangeRequest'))
.then(res => res.json());
};
export const usePendingChangeRequestsForFeature = (
project: string,
featureName: string
) => {
const { isOss } = useUiConfig();
const { data, error, mutate } = useSWR<IChangeRequest[]>(
formatApiPath(
`api/admin/projects/${project}/change-requests/pending/${featureName}`
),
(path: string) => (isOss() ? Promise.resolve([]) : fetcher(path))
);
return {
changeRequests: data,
loading: !error && !data,
refetch: mutate,
error,
};
};