mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-11 00:08:30 +01:00
integrate change request settings be (#2403)
<!-- Thanks for creating a PR! To make it easier for reviewers and everyone else to understand what your changes relate to, please add some relevant content to the headings below. Feel free to ignore or delete sections that you don't think are relevant. Thank you! ❤️ --> Integrates frontend with the change request settings backedn ## About the changes <!-- Describe the changes introduced. What are they and why are they being introduced? Feel free to also add screenshots or steps to view the changes if they're visual. --> <!-- Does it close an issue? Multiple? --> Closes # <!-- (For internal contributors): Does it relate to an issue on public roadmap? --> <!-- Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: # --> ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? -->
This commit is contained in:
parent
70e020ffeb
commit
c57baeb35e
@ -12,6 +12,12 @@ export interface IChangeRequest {
|
||||
approvals: IChangeRequestApproval[];
|
||||
}
|
||||
|
||||
export interface IChangeRequestEnvironmentConfig {
|
||||
environment: string;
|
||||
type: string;
|
||||
changeRequestEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface IChangeRequestFeature {
|
||||
name: string;
|
||||
conflict?: string;
|
||||
|
@ -1,43 +1,71 @@
|
||||
import { useMemo, useState, VFC } from 'react';
|
||||
import { HeaderGroup, Row } from 'react-table';
|
||||
import { HeaderGroup, useGlobalFilter, useTable } from 'react-table';
|
||||
import { Alert, Box, Typography } from '@mui/material';
|
||||
import {
|
||||
SortableTableHeader,
|
||||
Table,
|
||||
TableCell,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableRow,
|
||||
} from 'component/common/Table';
|
||||
import { useGlobalFilter, useTable } from 'react-table';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||
import PermissionSwitch from 'component/common/PermissionSwitch/PermissionSwitch';
|
||||
import { UPDATE_FEATURE_ENVIRONMENT } from 'component/providers/AccessProvider/permissions';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { useChangeRequestConfig } from '../../../../../hooks/api/getters/useChangeRequestConfig/useChangeRequestConfig';
|
||||
import { useChangeRequestApi } from '../../../../../hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
|
||||
import { UPDATE_PROJECT } from '@server/types/permissions';
|
||||
import useToast from '../../../../../hooks/useToast';
|
||||
import { formatUnknownError } from '../../../../../utils/formatUnknownError';
|
||||
|
||||
export const ChangeRequestConfiguration: VFC = () => {
|
||||
const [dialogState, setDialogState] = useState<{
|
||||
isOpen: boolean;
|
||||
enableEnvironment?: string;
|
||||
isEnabled: boolean;
|
||||
}>({
|
||||
isOpen: false,
|
||||
enableEnvironment: '',
|
||||
isEnabled: false,
|
||||
});
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
const data = [
|
||||
{
|
||||
environment: 'dev',
|
||||
type: 'test',
|
||||
isEnabled: false,
|
||||
},
|
||||
] as any[]; // FIXME: type
|
||||
const { data, loading, refetchChangeRequestConfig } =
|
||||
useChangeRequestConfig(projectId);
|
||||
const { updateChangeRequestEnvironmentConfig } = useChangeRequestApi();
|
||||
const { setToastData, setToastApiError } = useToast();
|
||||
|
||||
const onClick = (enableEnvironment: string) => () => {
|
||||
setDialogState({ isOpen: true, enableEnvironment });
|
||||
const onClick = (enableEnvironment: string, isEnabled: boolean) => () => {
|
||||
setDialogState({ isOpen: true, enableEnvironment, isEnabled });
|
||||
};
|
||||
|
||||
const onConfirm = async () => {
|
||||
if (dialogState.enableEnvironment) {
|
||||
try {
|
||||
await updateChangeRequestEnvironmentConfig(
|
||||
projectId,
|
||||
dialogState.enableEnvironment,
|
||||
!dialogState.isEnabled
|
||||
);
|
||||
setToastData({
|
||||
type: 'success',
|
||||
title: 'Updated change request status',
|
||||
text: 'Successfully updated change request status.',
|
||||
});
|
||||
refetchChangeRequestConfig();
|
||||
} catch (error) {
|
||||
const message = formatUnknownError(error);
|
||||
setToastApiError(message);
|
||||
}
|
||||
}
|
||||
setDialogState({
|
||||
isOpen: false,
|
||||
enableEnvironment: '',
|
||||
isEnabled: false,
|
||||
});
|
||||
};
|
||||
|
||||
const columns = useMemo(
|
||||
@ -55,7 +83,8 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'isEnabled',
|
||||
accessor: 'changeRequestEnabled',
|
||||
id: 'changeRequestEnabled',
|
||||
align: 'center',
|
||||
|
||||
Cell: ({ value, row: { original } }: any) => (
|
||||
@ -67,9 +96,12 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
checked={value}
|
||||
environmentId={original.environment}
|
||||
projectId={projectId}
|
||||
permission={UPDATE_FEATURE_ENVIRONMENT} // FIXME: permission - enable change request
|
||||
permission={UPDATE_PROJECT}
|
||||
inputProps={{ 'aria-label': original.environment }}
|
||||
onClick={onClick(original.environment)}
|
||||
onClick={onClick(
|
||||
original.environment,
|
||||
original.changeRequestEnabled
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
),
|
||||
@ -84,6 +116,7 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
|
||||
useTable(
|
||||
{
|
||||
// @ts-ignore
|
||||
columns,
|
||||
data,
|
||||
sortTypes,
|
||||
@ -95,11 +128,10 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
},
|
||||
useGlobalFilter
|
||||
);
|
||||
|
||||
return (
|
||||
<PageContent
|
||||
header={<PageHeader titleElement="Change request configuration" />}
|
||||
// isLoading={loading}
|
||||
isLoading={loading}
|
||||
>
|
||||
<Alert severity="info" sx={{ mb: 3 }}>
|
||||
If change request is enabled for an environment, then any change
|
||||
@ -128,20 +160,21 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
</Table>
|
||||
|
||||
<Dialogue
|
||||
onClick={() => {
|
||||
alert('clicked');
|
||||
/* FIXME: API action */
|
||||
}}
|
||||
onClick={() => onConfirm()}
|
||||
open={dialogState.isOpen}
|
||||
onClose={() =>
|
||||
setDialogState(state => ({ ...state, isOpen: false }))
|
||||
}
|
||||
primaryButtonText="Enable"
|
||||
primaryButtonText={dialogState.isEnabled ? 'Disable' : 'Enable'}
|
||||
secondaryButtonText="Cancel"
|
||||
title="Enable change request"
|
||||
title={`${
|
||||
dialogState.isEnabled ? 'Disable' : 'Enable'
|
||||
} change requests`}
|
||||
>
|
||||
<Typography sx={{ mb: 1 }}>
|
||||
You are about to enable “Change request”
|
||||
You are about to{' '}
|
||||
{dialogState.isEnabled ? 'disable' : 'enable'} “Change
|
||||
request”
|
||||
<ConditionallyRender
|
||||
condition={Boolean(dialogState.enableEnvironment)}
|
||||
show={
|
||||
@ -154,12 +187,18 @@ export const ChangeRequestConfiguration: VFC = () => {
|
||||
/>
|
||||
.
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
When enabling change request for an environment, you need to
|
||||
be sure that your Unleash Admin already have created the
|
||||
custom project roles in your Unleash instance so you can
|
||||
assign your project members from the project access page.
|
||||
</Typography>
|
||||
<ConditionallyRender
|
||||
condition={!dialogState.isEnabled}
|
||||
show={
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
When enabling change request for an environment, you
|
||||
need to be sure that your Unleash Admin already have
|
||||
created the custom project roles in your Unleash
|
||||
instance so you can assign your project members from
|
||||
the project access page.
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Dialogue>
|
||||
</PageContent>
|
||||
);
|
||||
|
@ -67,10 +67,28 @@ export const useChangeRequestApi = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const updateChangeRequestEnvironmentConfig = async (
|
||||
project: string,
|
||||
environment: string,
|
||||
enabled: boolean
|
||||
) => {
|
||||
const path = `api/admin/projects/${project}/environments/${environment}/change-requests/config`;
|
||||
const req = createRequest(path, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ changeRequestsEnabled: enabled }),
|
||||
});
|
||||
try {
|
||||
return await makeRequest(req.caller, req.id);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
addChangeRequest,
|
||||
changeState,
|
||||
discardChangeRequestEvent,
|
||||
updateChangeRequestEnvironmentConfig,
|
||||
errors,
|
||||
loading,
|
||||
};
|
||||
|
@ -0,0 +1,24 @@
|
||||
import useSWR from 'swr';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
import { IChangeRequestEnvironmentConfig } from 'component/changeRequest/changeRequest.types';
|
||||
|
||||
export const useChangeRequestConfig = (projectId: string) => {
|
||||
const { data, error, mutate } = useSWR<IChangeRequestEnvironmentConfig[]>(
|
||||
formatApiPath(`api/admin/projects/${projectId}/change-requests/config`),
|
||||
fetcher
|
||||
);
|
||||
|
||||
return {
|
||||
data: data || [],
|
||||
loading: !error && !data,
|
||||
refetchChangeRequestConfig: () => mutate(),
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
const fetcher = (path: string) => {
|
||||
return fetch(path)
|
||||
.then(handleErrorResponses('Request changes'))
|
||||
.then(res => res.json());
|
||||
};
|
24
yarn.lock
24
yarn.lock
@ -2126,13 +2126,12 @@ body-parser@1.19.0:
|
||||
raw-body "2.4.0"
|
||||
type-is "~1.6.17"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
braces@^3.0.1, braces@^3.0.2:
|
||||
version "3.0.2"
|
||||
@ -2505,11 +2504,6 @@ compression@^1.7.4:
|
||||
safe-buffer "5.1.2"
|
||||
vary "~1.1.2"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
concat-stream@^1.5.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz"
|
||||
@ -5396,12 +5390,12 @@ min-indent@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz"
|
||||
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
|
||||
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2, minimatch@^5.0.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.2, minimatch@^5.0.0, minimatch@^5.0.1:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
|
||||
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist-options@4.1.0:
|
||||
version "4.1.0"
|
||||
|
Loading…
Reference in New Issue
Block a user