mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: discard suggested draft change (#2285)
* feat: discard suggested draft change * fix: suggest changes api frontend integration * fix suggested changes discard
This commit is contained in:
		
							parent
							
								
									15c22d7630
								
							
						
					
					
						commit
						f39d1021d0
					
				@ -16,7 +16,7 @@ export const DraftBanner: VFC<IDraftBannerProps> = ({ project }) => {
 | 
			
		||||
    const { draft, loading } = useSuggestedChangesDraft(project);
 | 
			
		||||
    const environment = '';
 | 
			
		||||
 | 
			
		||||
    if (!loading && draft?.length === 0) {
 | 
			
		||||
    if ((!loading && !draft) || draft?.length === 0) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,17 @@
 | 
			
		||||
import { FC } from 'react';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
import { Box, Card, Typography } from '@mui/material';
 | 
			
		||||
import ToggleOnIcon from '@mui/icons-material/ToggleOn';
 | 
			
		||||
 | 
			
		||||
interface ISuggestedFeatureToggleChange {
 | 
			
		||||
    featureToggleName: string;
 | 
			
		||||
    featureName: string;
 | 
			
		||||
    projectId: string;
 | 
			
		||||
    onNavigate?: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SuggestedFeatureToggleChange: FC<
 | 
			
		||||
    ISuggestedFeatureToggleChange
 | 
			
		||||
> = ({ featureToggleName, children }) => {
 | 
			
		||||
> = ({ featureName, projectId, onNavigate, children }) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <Card
 | 
			
		||||
            elevation={0}
 | 
			
		||||
@ -28,7 +31,15 @@ export const SuggestedFeatureToggleChange: FC<
 | 
			
		||||
            >
 | 
			
		||||
                <Box sx={{ display: 'flex', gap: 1 }}>
 | 
			
		||||
                    <ToggleOnIcon color="disabled" />
 | 
			
		||||
                    <Typography color="primary">{featureToggleName}</Typography>
 | 
			
		||||
                    <Typography
 | 
			
		||||
                        component={Link}
 | 
			
		||||
                        to={`/projects/${projectId}/features/${featureName}`}
 | 
			
		||||
                        color="primary"
 | 
			
		||||
                        sx={{ textDecoration: 'none' }}
 | 
			
		||||
                        onClick={onNavigate}
 | 
			
		||||
                    >
 | 
			
		||||
                        {featureName}
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                </Box>
 | 
			
		||||
            </Box>
 | 
			
		||||
            <Box sx={{ p: 2 }}>{children}</Box>
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,20 @@
 | 
			
		||||
import { Box } from '@mui/material';
 | 
			
		||||
import { FC } from 'react';
 | 
			
		||||
import { VFC } from 'react';
 | 
			
		||||
import { Link, Box, Typography } from '@mui/material';
 | 
			
		||||
import { PlaygroundResultChip } from 'component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip';
 | 
			
		||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
 | 
			
		||||
 | 
			
		||||
export const ToggleStatusChange: FC<{ enabled: boolean }> = ({ enabled }) => {
 | 
			
		||||
interface IPlaygroundResultsTable {
 | 
			
		||||
    enabled: boolean;
 | 
			
		||||
    onDiscard?: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ToggleStatusChange: VFC<IPlaygroundResultsTable> = ({
 | 
			
		||||
    enabled,
 | 
			
		||||
    onDiscard,
 | 
			
		||||
}) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <Box sx={{ p: 1 }}>
 | 
			
		||||
        <Box sx={{ p: 1, display: 'flex', justifyContent: 'space-between' }}>
 | 
			
		||||
            <Box>
 | 
			
		||||
                New status:{' '}
 | 
			
		||||
                <PlaygroundResultChip
 | 
			
		||||
                    showIcon={false}
 | 
			
		||||
@ -12,5 +22,14 @@ export const ToggleStatusChange: FC<{ enabled: boolean }> = ({ enabled }) => {
 | 
			
		||||
                    enabled={enabled}
 | 
			
		||||
                />
 | 
			
		||||
            </Box>
 | 
			
		||||
            <ConditionallyRender
 | 
			
		||||
                condition={Boolean(onDiscard)}
 | 
			
		||||
                show={
 | 
			
		||||
                    <Box>
 | 
			
		||||
                        <Link onClick={onDiscard}>Discard</Link>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                }
 | 
			
		||||
            />
 | 
			
		||||
        </Box>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -135,6 +135,10 @@ export const SuggestedChangesSidebar: VFC<ISuggestedChangesSidebarProps> = ({
 | 
			
		||||
                        <hr />
 | 
			
		||||
                        <SuggestedChangeset
 | 
			
		||||
                            suggestedChange={environmentChangeset}
 | 
			
		||||
                            onNavigate={() => {
 | 
			
		||||
                                onClose();
 | 
			
		||||
                            }}
 | 
			
		||||
                            onRefetch={refetchSuggestedChanges}
 | 
			
		||||
                        />
 | 
			
		||||
                        <Box sx={{ display: 'flex' }}>
 | 
			
		||||
                            <ConditionallyRender
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { FC } from 'react';
 | 
			
		||||
import { useCallback, VFC } from 'react';
 | 
			
		||||
import { Box } from '@mui/material';
 | 
			
		||||
import { SuggestedFeatureToggleChange } from '../SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange';
 | 
			
		||||
import { objectId } from 'utils/objectId';
 | 
			
		||||
@ -14,17 +14,49 @@ import { ToggleStatusChange } from '../SuggestedChangeOverview/SuggestedFeatureT
 | 
			
		||||
//     GetFeatureStrategyIcon,
 | 
			
		||||
// } from 'utils/strategyNames';
 | 
			
		||||
import type { ISuggestChangesResponse } from 'hooks/api/getters/useSuggestedChangesDraft/useSuggestedChangesDraft';
 | 
			
		||||
import { useSuggestChangeApi } from 'hooks/api/actions/useSuggestChangeApi/useSuggestChangeApi';
 | 
			
		||||
import { formatUnknownError } from 'utils/formatUnknownError';
 | 
			
		||||
import useToast from 'hooks/useToast';
 | 
			
		||||
 | 
			
		||||
export const SuggestedChangeset: FC<{
 | 
			
		||||
interface ISuggestedChangeset {
 | 
			
		||||
    suggestedChange: ISuggestChangesResponse;
 | 
			
		||||
}> = ({ suggestedChange }) => {
 | 
			
		||||
    onRefetch?: () => void;
 | 
			
		||||
    onNavigate?: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SuggestedChangeset: VFC<ISuggestedChangeset> = ({
 | 
			
		||||
    suggestedChange,
 | 
			
		||||
    onRefetch,
 | 
			
		||||
    onNavigate,
 | 
			
		||||
}) => {
 | 
			
		||||
    const { discardSuggestions } = useSuggestChangeApi();
 | 
			
		||||
    const { setToastData, setToastApiError } = useToast();
 | 
			
		||||
    const onDiscard = (id: number) => async () => {
 | 
			
		||||
        try {
 | 
			
		||||
            await discardSuggestions(
 | 
			
		||||
                suggestedChange.project,
 | 
			
		||||
                suggestedChange.id,
 | 
			
		||||
                id
 | 
			
		||||
            );
 | 
			
		||||
            setToastData({
 | 
			
		||||
                title: 'Change discarded from suggestion draft.',
 | 
			
		||||
                type: 'success',
 | 
			
		||||
            });
 | 
			
		||||
            onRefetch?.();
 | 
			
		||||
        } catch (error: unknown) {
 | 
			
		||||
            setToastApiError(formatUnknownError(error));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Box>
 | 
			
		||||
            Changes
 | 
			
		||||
            {suggestedChange.features?.map(featureToggleChange => (
 | 
			
		||||
                <SuggestedFeatureToggleChange
 | 
			
		||||
                    key={featureToggleChange.name}
 | 
			
		||||
                    featureToggleName={featureToggleChange.name}
 | 
			
		||||
                    featureName={featureToggleChange.name}
 | 
			
		||||
                    projectId={suggestedChange.project}
 | 
			
		||||
                    onNavigate={onNavigate}
 | 
			
		||||
                >
 | 
			
		||||
                    {featureToggleChange.changes.map(change => (
 | 
			
		||||
                        <Box key={objectId(change)}>
 | 
			
		||||
@ -33,6 +65,7 @@ export const SuggestedChangeset: FC<{
 | 
			
		||||
                                show={
 | 
			
		||||
                                    <ToggleStatusChange
 | 
			
		||||
                                        enabled={change?.payload?.enabled}
 | 
			
		||||
                                        onDiscard={onDiscard(change.id)}
 | 
			
		||||
                                    />
 | 
			
		||||
                                }
 | 
			
		||||
                            />
 | 
			
		||||
 | 
			
		||||
@ -64,10 +64,27 @@ export const useSuggestChangeApi = () => {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const discardSuggestions = async (
 | 
			
		||||
        project: string,
 | 
			
		||||
        changesetId: number,
 | 
			
		||||
        changeId: number
 | 
			
		||||
    ) => {
 | 
			
		||||
        const path = `api/admin/projects/${project}/suggest-changes/${changesetId}/changes/${changeId}`;
 | 
			
		||||
        const req = createRequest(path, {
 | 
			
		||||
            method: 'DELETE',
 | 
			
		||||
        });
 | 
			
		||||
        try {
 | 
			
		||||
            return await makeRequest(req.caller, req.id);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            throw e;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        addSuggestion,
 | 
			
		||||
        applyChanges,
 | 
			
		||||
        changeState,
 | 
			
		||||
        discardSuggestions,
 | 
			
		||||
        errors,
 | 
			
		||||
        loading,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user