1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-13 11:17:26 +02:00
unleash.unleash/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProject.tsx
olav 159c54ed37 fix: resolve issues around changing a toggle's project (#978)
* refactor: show save button before using the dropdown

* refactor: simplify FeatureSettingsProject toast message

* refactor: fix FeatureProjectSelect filter prop type

* refactor: hide change project page for non-enterprise

* refactor: derive move targets from projects list instead of from permissions

* refactor: align frontend project compat check with backend

* refactor: fix useProject object stability

* refactor: disable the save button for the current project

* refactor: require equal environments when moving toggles

* refactor: improve arraysHaveSameItems name
2022-05-18 11:07:19 +02:00

83 lines
3.2 KiB
TypeScript

import { useContext, useState, useMemo } from 'react';
import { useNavigate } from 'react-router';
import AccessContext from 'contexts/AccessContext';
import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import useToast from 'hooks/useToast';
import { MOVE_FEATURE_TOGGLE } from 'component/providers/AccessProvider/permissions';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import FeatureProjectSelect from './FeatureProjectSelect/FeatureProjectSelect';
import FeatureSettingsProjectConfirm from './FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm';
import { formatUnknownError } from 'utils/formatUnknownError';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import useProjects from 'hooks/api/getters/useProjects/useProjects';
const FeatureSettingsProject = () => {
const { hasAccess } = useContext(AccessContext);
const projectId = useRequiredPathParam('projectId');
const featureId = useRequiredPathParam('featureId');
const { feature, refetchFeature } = useFeature(projectId, featureId);
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
const { changeFeatureProject } = useFeatureApi();
const { setToastData, setToastApiError } = useToast();
const [project, setProject] = useState(projectId);
const { projects } = useProjects();
const navigate = useNavigate();
const onConfirm = async () => {
try {
if (project) {
await changeFeatureProject(projectId, featureId, project);
refetchFeature();
setToastData({ title: 'Project changed', type: 'success' });
setShowConfirmDialog(false);
navigate(
`/projects/${project}/features/${featureId}/settings`,
{ replace: true }
);
}
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
const targetProjectIds = useMemo(() => {
return projects
.map(project => project.id)
.filter(projectId => hasAccess(MOVE_FEATURE_TOGGLE, projectId));
}, [projects, hasAccess]);
if (targetProjectIds.length === 0) {
return null;
}
return (
<>
<FeatureProjectSelect
value={project}
onChange={setProject}
label="Project"
filter={projectId => targetProjectIds.includes(projectId)}
enabled
/>
<PermissionButton
permission={MOVE_FEATURE_TOGGLE}
onClick={() => setShowConfirmDialog(true)}
disabled={project === projectId}
projectId={projectId}
>
Save
</PermissionButton>
<FeatureSettingsProjectConfirm
projectId={project}
open={showConfirmDialog}
feature={feature}
onClose={() => setShowConfirmDialog(false)}
onClick={onConfirm}
/>
</>
);
};
export default FeatureSettingsProject;