diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvSwitches/FeatureOverviewEnvSwitch/FeatureOverviewEnvSwitch.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvSwitches/FeatureOverviewEnvSwitch/FeatureOverviewEnvSwitch.tsx index d4603f2014..4e4e2c4cd9 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvSwitches/FeatureOverviewEnvSwitch/FeatureOverviewEnvSwitch.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvSwitches/FeatureOverviewEnvSwitch/FeatureOverviewEnvSwitch.tsx @@ -10,6 +10,9 @@ import React from 'react'; import { formatUnknownError } from 'utils/formatUnknownError'; import { useStyles } from './FeatureOverviewEnvSwitch.styles'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { useSuggestToggle } from 'hooks/useSuggestToggle'; +import { SuggestChangesDialogue } from 'component/suggestChanges/SuggestChangeConfirmDialog/SuggestChangeConfirmDialog'; interface IFeatureOverviewEnvSwitchProps { env: IFeatureEnvironment; @@ -31,6 +34,12 @@ const FeatureOverviewEnvSwitch = ({ const { refetchFeature } = useFeature(projectId, featureId); const { setToastData, setToastApiError } = useToast(); const { classes: styles } = useStyles(); + const { uiConfig } = useUiConfig(); + const { + onSuggestToggle, + onSuggestToggleClose, + suggestChangesDialogDetails, + } = useSuggestToggle(); const handleToggleEnvironmentOn = async () => { try { @@ -74,6 +83,11 @@ const FeatureOverviewEnvSwitch = ({ }; const toggleEnvironment = async (e: React.ChangeEvent) => { + if (uiConfig?.flags?.suggestChanges && env.name === 'production') { + e.preventDefault(); + onSuggestToggle(featureId, env.name, env.enabled); + return; + } if (env.enabled) { await handleToggleEnvironmentOff(); return; @@ -104,6 +118,13 @@ const FeatureOverviewEnvSwitch = ({ /> {content} + {}} + /> ); }; diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index f2555a6eb2..f1944b98ab 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -24,8 +24,8 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { Routes, Route, useLocation } from 'react-router-dom'; import { DeleteProjectDialogue } from './DeleteProject/DeleteProjectDialogue'; import { ProjectLog } from './ProjectLog/ProjectLog'; -import { SuggestedChangeOverview } from './SuggestedChanges/SuggestedChangeOverview/SuggestedChangeOverview'; -import { DraftBanner } from './SuggestedChanges/DraftBanner/DraftBanner'; +import { SuggestedChangeOverview } from 'component/suggestChanges/SuggestedChangeOverview/SuggestedChangeOverview'; +import { DraftBanner } from 'component/suggestChanges/DraftBanner/DraftBanner'; import { MainLayout } from 'component/layout/MainLayout/MainLayout'; const StyledDiv = styled('div')(() => ({ diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx index a7fc50b255..2a81cc61e3 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -36,6 +36,8 @@ import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/Feat import { useSearch } from 'hooks/useSearch'; import { useMediaQuery } from '@mui/material'; import { Search } from 'component/common/Search/Search'; +import { useSuggestToggle } from 'hooks/useSuggestToggle'; +import { SuggestChangesDialogue } from 'component/suggestChanges/SuggestChangeConfirmDialog/SuggestChangeConfirmDialog'; interface IProjectFeatureTogglesProps { features: IProject['features']; @@ -99,6 +101,11 @@ export const ProjectFeatureToggles = ({ const { toggleFeatureEnvironmentOn, toggleFeatureEnvironmentOff } = useFeatureApi(); + const { + onSuggestToggle, + onSuggestToggleClose, + suggestChangesDialogDetails, + } = useSuggestToggle(); const onToggle = useCallback( async ( @@ -107,6 +114,13 @@ export const ProjectFeatureToggles = ({ environment: string, enabled: boolean ) => { + if ( + uiConfig?.flags?.suggestChanges && + environment === 'production' + ) { + onSuggestToggle(featureName, environment, enabled); + throw new Error('Additional approval required'); + } try { if (enabled) { await toggleFeatureEnvironmentOn( @@ -501,6 +515,13 @@ export const ProjectFeatureToggles = ({ }} featureId={featureArchiveState || ''} projectId={projectId} + />{' '} + {}} /> ); diff --git a/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangeItem/ChangeItem.tsx b/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangeItem/ChangeItem.tsx deleted file mode 100644 index 1ec58ae4ff..0000000000 --- a/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangeItem/ChangeItem.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { VFC } from 'react'; -import { ISuggestChange } from 'interfaces/suggestChangeset'; -import { Box } from '@mui/system'; -import { PlaygroundResultChip } from 'component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; // FIXME: refactor - extract to common - -export const ChangeItem: VFC = ({ action, id, payload }) => { - if (action === 'updateEnabled') { - return ( - - New status:{' '} - - - ); - } - return Change with ID: {id}; -}; diff --git a/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangesetDiff.tsx b/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangesetDiff.tsx deleted file mode 100644 index 62080da9ed..0000000000 --- a/frontend/src/component/project/Project/SuggestedChanges/ChangesetDiff/ChangesetDiff.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { VFC } from 'react'; -import { Box, Typography, Card, styled } from '@mui/material'; -import { ISuggestChange } from 'interfaces/suggestChangeset'; -import EnvironmentIcon from 'component/common/EnvironmentIcon/EnvironmentIcon'; -import StringTruncator from 'component/common/StringTruncator/StringTruncator'; -import { PlaygroundResultChip } from 'component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; // FIXME: refactor - extract to common -import { ChangeItem } from './ChangeItem/ChangeItem'; - -type ChangesetDiffProps = { - changes?: ISuggestChange[]; - state: string; -}; - -const StyledHeader = styled('div')(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - [theme.breakpoints.down(560)]: { - flexDirection: 'column', - textAlign: 'center', - }, - paddingBottom: theme.spacing(1), -})); - -export const ChangesetDiff: VFC = ({ changes, state }) => ( - theme.palette.playgroundBackground, - display: 'flex', - gap: 2, - flexDirection: 'column', - borderRadius: theme => `${theme.shape.borderRadiusExtraLarge}px`, - }} - > - - - - - - - - - - - You request changes for these feature toggles: - - {/* TODO: group by feature name */} - {changes?.map(item => ( - `${theme.shape.borderRadius}px`, - overflow: 'hidden', - border: '1px solid', - borderColor: theme => theme.palette.dividerAlternative, - }} - > - - theme.palette.tableHeaderBackground, - p: 2, - }} - > - {item.feature} - - - - - - ))} - -); diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeSet/SuggestedChangeSet.tsx b/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeSet/SuggestedChangeSet.tsx deleted file mode 100644 index d79f178b79..0000000000 --- a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeSet/SuggestedChangeSet.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { FC } from 'react'; -import { Box, Paper } from '@mui/material'; -import { SuggestedFeatureToggleChange } from '../SuggestedFeatureToggleChange/SuggestedFeatureToggleChange'; -import { objectId } from '../../../../../../utils/objectId'; -import { ConditionallyRender } from '../../../../../common/ConditionallyRender/ConditionallyRender'; -import { ToggleStatusChange } from '../SuggestedFeatureToggleChange/ToggleStatusChange'; -import { - StrategyAddedChange, - StrategyDeletedChange, - StrategyEditedChange, -} from '../SuggestedFeatureToggleChange/StrategyChange'; -import { - formatStrategyName, - GetFeatureStrategyIcon, -} from '../../../../../../utils/strategyNames'; - -export const SuggestedChangeSet: FC<{ suggestedChange: any }> = ({ - suggestedChange, -}) => { - return ( - ({ - marginTop: theme.spacing(2), - marginLeft: theme.spacing(2), - width: '70%', - padding: 2, - borderRadius: theme => `${theme.shape.borderRadiusLarge}px`, - })} - > - ({ - padding: theme.spacing(2), - })} - > - Changes - {suggestedChange.changes?.map((featureToggleChange: any) => ( - - {featureToggleChange.changeSet.map((change: any) => ( - - - } - /> - - - {formatStrategyName( - change.payload.name - )} - - } - /> - } - /> - } - /> - - ))} - - ))} - - - ); -}; diff --git a/frontend/src/component/project/Project/SuggestedChanges/DraftBanner/DraftBanner.tsx b/frontend/src/component/suggestChanges/DraftBanner/DraftBanner.tsx similarity index 83% rename from frontend/src/component/project/Project/SuggestedChanges/DraftBanner/DraftBanner.tsx rename to frontend/src/component/suggestChanges/DraftBanner/DraftBanner.tsx index c5f98de4d8..e46101b4e6 100644 --- a/frontend/src/component/project/Project/SuggestedChanges/DraftBanner/DraftBanner.tsx +++ b/frontend/src/component/suggestChanges/DraftBanner/DraftBanner.tsx @@ -3,6 +3,7 @@ import { Box, Button, Typography } from '@mui/material'; import { useStyles as useAppStyles } from 'component/App.styles'; import WarningAmberIcon from '@mui/icons-material/WarningAmber'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { SuggestedChangesSidebar } from '../SuggestedChangesSidebar/SuggestedChangesSidebar'; interface IDraftBannerProps { environment?: string; @@ -10,7 +11,7 @@ interface IDraftBannerProps { export const DraftBanner: VFC = ({ environment }) => { const { classes } = useAppStyles(); - const [reviewChangesOpen, setReviewChangesOpen] = useState(false); + const [isSidebarOpen, setIsSidebarOpen] = useState(false); return ( = ({ environment }) => { + { + setIsSidebarOpen(false); + }} + /> ); }; diff --git a/frontend/src/component/suggestChanges/SuggestChangeConfirmDialog/SuggestChangeConfirmDialog.tsx b/frontend/src/component/suggestChanges/SuggestChangeConfirmDialog/SuggestChangeConfirmDialog.tsx new file mode 100644 index 0000000000..b1b451622d --- /dev/null +++ b/frontend/src/component/suggestChanges/SuggestChangeConfirmDialog/SuggestChangeConfirmDialog.tsx @@ -0,0 +1,58 @@ +import { FC } from 'react'; +import { Alert, Box, Typography } from '@mui/material'; +import { Dialogue } from 'component/common/Dialogue/Dialogue'; +import useToast from 'hooks/useToast'; +import { formatUnknownError } from 'utils/formatUnknownError'; + +interface ISuggestChangesDialogueProps { + isOpen: boolean; + onConfirm: () => void; + onClose: () => void; + featureName?: string; + environment?: string; + enabled?: boolean; +} + +export const SuggestChangesDialogue: FC = ({ + isOpen, + onConfirm, + onClose, + enabled, + featureName, + environment, +}) => { + const { setToastData, setToastApiError } = useToast(); + + const onSuggestClick = async () => { + try { + alert('Suggesting changes'); + onConfirm(); + } catch (error: unknown) { + setToastApiError(formatUnknownError(error)); + } + }; + + return ( + + + Suggest changes is enabled for {environment}. Your changes needs + to be approved before they will be live. All the changes you do + now will be added into a draft that you can submit for review. + + + Suggested changes: + + + {enabled ? 'Disable' : 'Enable'} feature toggle{' '} + {featureName} in {environment} + + + ); +}; diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx similarity index 86% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx index 558851ba32..cd21b9466f 100644 --- a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx +++ b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeHeader/SuggestedChangeHeader.tsx @@ -1,7 +1,7 @@ import { FC } from 'react'; import { Avatar, Box, Card, Paper, Typography } from '@mui/material'; -import { StyledTrueChip } from '../../../../../playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; -import { ReactComponent as ChangesAppliedIcon } from '../../../../../../assets/icons/merge.svg'; +import { PlaygroundResultChip } from 'component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; +import { ReactComponent as ChangesAppliedIcon } from 'assets/icons/merge.svg'; import TimeAgo from 'react-timeago'; export const SuggestedChangeHeader: FC<{ suggestedChange: any }> = ({ @@ -35,9 +35,10 @@ export const SuggestedChangeHeader: FC<{ suggestedChange: any }> = ({ #{suggestedChange.id} - } + } label="Changes applied" + enabled="unknown" /> diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx similarity index 54% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx index cc90a3fac3..99b7dad527 100644 --- a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx +++ b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeOverview.tsx @@ -1,10 +1,10 @@ import { FC } from 'react'; -import { Box } from '@mui/material'; +import { Box, Paper } from '@mui/material'; import { useSuggestedChange } from 'hooks/api/getters/useSuggestChange/useSuggestedChange'; import { SuggestedChangeHeader } from './SuggestedChangeHeader/SuggestedChangeHeader'; import { SuggestedChangeTimeline } from './SuggestedChangeTimeline/SuggestedChangeTimeline'; import { SuggestedChangeReviewers } from './SuggestedChangeReviewers/SuggestedChangeReviewers'; -import { SuggestedChangeSet } from './SuggestedChangeSet/SuggestedChangeSet'; +import { SuggestedChangeset } from '../SuggestedChangeset/SuggestedChangeset'; export const SuggestedChangeOverview: FC = () => { const { data: suggestedChange } = useSuggestedChange(); @@ -23,8 +23,25 @@ export const SuggestedChangeOverview: FC = () => { - - + ({ + marginTop: theme.spacing(2), + marginLeft: theme.spacing(2), + width: '70%', + padding: 2, + borderRadius: theme => + `${theme.shape.borderRadiusLarge}px`, + })} + > + ({ + padding: theme.spacing(2), + })} + > + + + ); diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeReviewers/SuggestedChangeReviewers.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeReviewers/SuggestedChangeReviewers.tsx similarity index 100% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeReviewers/SuggestedChangeReviewers.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeReviewers/SuggestedChangeReviewers.tsx diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeTimeline/SuggestedChangeTimeline.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeTimeline/SuggestedChangeTimeline.tsx similarity index 100% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedChangeTimeline/SuggestedChangeTimeline.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedChangeTimeline/SuggestedChangeTimeline.tsx diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/StrategyChange.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/StrategyChange.tsx similarity index 100% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/StrategyChange.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/StrategyChange.tsx diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange.tsx similarity index 100% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange.tsx diff --git a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx similarity index 74% rename from frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx rename to frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx index fa68484a50..bad5907f34 100644 --- a/frontend/src/component/project/Project/SuggestedChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx +++ b/frontend/src/component/suggestChanges/SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange.tsx @@ -1,6 +1,6 @@ import { Box } from '@mui/material'; import { FC } from 'react'; -import { PlaygroundResultChip } from '../../../../../playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; +import { PlaygroundResultChip } from 'component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip'; export const ToggleStatusChange: FC<{ enabled: boolean }> = ({ enabled }) => { return ( diff --git a/frontend/src/component/suggestChanges/SuggestedChangesSidebar/SuggestedChangesSidebar.tsx b/frontend/src/component/suggestChanges/SuggestedChangesSidebar/SuggestedChangesSidebar.tsx new file mode 100644 index 0000000000..ebf6c8fdad --- /dev/null +++ b/frontend/src/component/suggestChanges/SuggestedChangesSidebar/SuggestedChangesSidebar.tsx @@ -0,0 +1,135 @@ +import React, { useState, VFC } from 'react'; +import { Box, Button, Typography, styled, Tooltip } from '@mui/material'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; +import { PageContent } from 'component/common/PageContent/PageContent'; +import { PageHeader } from 'component/common/PageHeader/PageHeader'; +import { HelpOutline } from '@mui/icons-material'; +import { useSuggestedChange } from 'hooks/api/getters/useSuggestChange/useSuggestedChange'; +import { SuggestedChangeset } from '../SuggestedChangeset/SuggestedChangeset'; +interface ISuggestedChangesSidebarProps { + open: boolean; + onClose: () => void; +} +const StyledPageContent = styled(PageContent)(({ theme }) => ({ + height: '100vh', + overflow: 'auto', + padding: theme.spacing(7.5, 6), + [theme.breakpoints.down('md')]: { + padding: theme.spacing(4, 2), + }, + '& .header': { + padding: theme.spacing(0, 0, 2, 0), + }, + '& .body': { + padding: theme.spacing(3, 0, 0, 0), + }, + borderRadius: `${theme.spacing(1.5, 0, 0, 1.5)} !important`, +})); +const StyledHelpOutline = styled(HelpOutline)(({ theme }) => ({ + fontSize: theme.fontSizes.mainHeader, + marginLeft: '0.3rem', + color: theme.palette.grey[700], +})); +const StyledHeaderHint = styled('div')(({ theme }) => ({ + color: theme.palette.text.secondary, + fontSize: theme.fontSizes.smallBody, +})); + +export const SuggestedChangesSidebar: VFC = ({ + open, + onClose, +}) => { + const { data: suggestedChange } = useSuggestedChange(); + + const onReview = async () => { + console.log('approve'); + }; + const onDiscard = async () => { + console.log('discard'); + }; + const onApply = async () => { + try { + console.log('apply'); + } catch (e) { + console.log(e); + } + }; + return ( + + + Review your changes + + + + + Make sure you are sending the right changes + suggestions to be reviewed + + + } + > + } + > + {/* TODO: multiple environments (changesets) */} + {suggestedChange?.state} +
+ + + Applied} + /> + Applied} + /> + + + + } + /> + + + + + } + /> + +
+
+ ); +}; diff --git a/frontend/src/component/suggestChanges/SuggestedChangeset/SuggestedChangeset.tsx b/frontend/src/component/suggestChanges/SuggestedChangeset/SuggestedChangeset.tsx new file mode 100644 index 0000000000..ee6d9c373f --- /dev/null +++ b/frontend/src/component/suggestChanges/SuggestedChangeset/SuggestedChangeset.tsx @@ -0,0 +1,65 @@ +import { FC } from 'react'; +import { Box } from '@mui/material'; +import { SuggestedFeatureToggleChange } from '../SuggestedChangeOverview/SuggestedFeatureToggleChange/SuggestedFeatureToggleChange'; +import { objectId } from 'utils/objectId'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { ToggleStatusChange } from '../SuggestedChangeOverview/SuggestedFeatureToggleChange/ToggleStatusChange'; +import { + StrategyAddedChange, + StrategyDeletedChange, + StrategyEditedChange, +} from '../SuggestedChangeOverview/SuggestedFeatureToggleChange/StrategyChange'; +import { + formatStrategyName, + GetFeatureStrategyIcon, +} from 'utils/strategyNames'; + +export const SuggestedChangeset: FC<{ suggestedChange: any }> = ({ + suggestedChange, +}) => { + return ( + + Changes + {suggestedChange.changes?.map((featureToggleChange: any) => ( + + {featureToggleChange.changeSet.map((change: any) => ( + + + } + /> + + + {formatStrategyName( + change.payload.name + )} + + } + /> + } + /> + } + /> + + ))} + + ))} + + ); +}; diff --git a/frontend/src/hooks/useSuggestToggle.ts b/frontend/src/hooks/useSuggestToggle.ts new file mode 100644 index 0000000000..29ab1b0cd1 --- /dev/null +++ b/frontend/src/hooks/useSuggestToggle.ts @@ -0,0 +1,33 @@ +import { useCallback, useState } from 'react'; + +export const useSuggestToggle = () => { + const [suggestChangesDialogDetails, setSuggestChangesDialogDetails] = + useState<{ + enabled?: boolean; + featureName?: string; + environment?: string; + isOpen: boolean; + }>({ isOpen: false }); + + const onSuggestToggle = useCallback( + (featureName: string, environment: string, enabled: boolean) => { + setSuggestChangesDialogDetails({ + featureName, + environment, + enabled, + isOpen: true, + }); + }, + [] + ); + + const onSuggestToggleClose = useCallback(() => { + setSuggestChangesDialogDetails({ isOpen: false }); + }, []); + + return { + onSuggestToggle, + onSuggestToggleClose, + suggestChangesDialogDetails, + }; +};