diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx index d07d16e5f8..8c6bf2ae42 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChangeOverwriteWarning.tsx @@ -1,8 +1,10 @@ import { Box, styled } from '@mui/material'; import { IChangeRequestUpdateStrategy } from 'component/changeRequest/changeRequest.types'; +import { useChangeRequestPlausibleContext } from 'component/changeRequest/ChangeRequestContext'; import { useUiFlag } from 'hooks/useUiFlag'; import { IFeatureStrategy } from 'interfaces/strategy'; import { getChangesThatWouldBeOverwritten } from './strategy-change-diff-calculation'; +import { useEffect } from 'react'; const ChangesToOverwriteWarning = styled(Box)(({ theme }) => ({ color: theme.palette.warning.dark, @@ -76,6 +78,14 @@ export const ChangesToOverwrite: React.FC<{ const changesThatWouldBeOverwritten = checkForChanges ? getChangesThatWouldBeOverwritten(currentStrategy, change) : null; + const { registerWillOverwriteStrategyChanges } = + useChangeRequestPlausibleContext(); + + useEffect(() => { + if (changesThatWouldBeOverwritten) { + registerWillOverwriteStrategyChanges(); + } + }, [changesThatWouldBeOverwritten]); if (!changesThatWouldBeOverwritten) { return null; diff --git a/frontend/src/component/changeRequest/ChangeRequestContext.tsx b/frontend/src/component/changeRequest/ChangeRequestContext.tsx new file mode 100644 index 0000000000..2611acc5c9 --- /dev/null +++ b/frontend/src/component/changeRequest/ChangeRequestContext.tsx @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; + +const defaultContext = { + willOverwriteStrategyChanges: false, + registerWillOverwriteStrategyChanges: () => {}, +}; + +const ChangeRequestPlausibleContext = createContext(defaultContext); + +export const ChangeRequestPlausibleProvider = + ChangeRequestPlausibleContext.Provider; + +export const useChangeRequestPlausibleContext = (): typeof defaultContext => { + return useContext(ChangeRequestPlausibleContext); +}; diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx index 3177cb7b07..1a28abc734 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx @@ -1,4 +1,4 @@ -import { VFC } from 'react'; +import { useState, VFC } from 'react'; import { Box, Button, styled, Typography } from '@mui/material'; import { DynamicSidebarModal } from 'component/common/SidebarModal/SidebarModal'; import { PageContent } from 'component/common/PageContent/PageContent'; @@ -11,6 +11,7 @@ import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import { EnvironmentChangeRequest } from './EnvironmentChangeRequest/EnvironmentChangeRequest'; import { ReviewChangesHeader } from './ReviewChangesHeader/ReviewChangesHeader'; +import { ChangeRequestPlausibleProvider } from '../ChangeRequestContext'; interface IChangeRequestSidebarProps { open: boolean; @@ -76,15 +77,18 @@ export const ChangeRequestSidebar: VFC = ({ loading, refetch: refetchChangeRequest, } = usePendingChangeRequests(project); - const { changeState, discardDraft } = useChangeRequestApi(); + const { discardDraft } = useChangeRequestApi(); const { setToastApiError } = useToast(); + const [ + changeRequestChangesWillOverwrite, + setChangeRequestChangesWillOverwrite, + ] = useState(false); - const onReview = async (draftId: number, comment?: string) => { + const onReview = async ( + changeState: (project: string) => Promise, + ) => { try { - await changeState(project, draftId, 'Draft', { - state: 'In review', - comment, - }); + await changeState(project); refetchChangeRequest(); } catch (error: unknown) { setToastApiError(formatUnknownError(error)); @@ -130,19 +134,29 @@ export const ChangeRequestSidebar: VFC = ({ header={} > {data?.map((environmentChangeRequest) => ( - + setChangeRequestChangesWillOverwrite(true), + }} > - - + + + + ))} diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx index 7a38a6fe14..45a6c7973f 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx @@ -23,6 +23,7 @@ import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser'; import Input from 'component/common/Input/Input'; import { ChangeRequestTitle } from './ChangeRequestTitle'; import { UpdateCount } from 'component/changeRequest/UpdateCount'; +import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; const SubmitChangeRequestButton: FC<{ onClick: () => void; count: number }> = ({ onClick, @@ -56,7 +57,7 @@ const ChangeRequestContent = styled(Box)(({ theme }) => ({ export const EnvironmentChangeRequest: FC<{ environmentChangeRequest: ChangeRequestType; onClose: () => void; - onReview: (id: number, comment?: string) => void; + onReview: (changeState: (project: string) => Promise) => void; onDiscard: (id: number) => void; }> = ({ environmentChangeRequest, onClose, onReview, onDiscard, children }) => { const theme = useTheme(); @@ -64,6 +65,12 @@ export const EnvironmentChangeRequest: FC<{ const [commentText, setCommentText] = useState(''); const { user } = useAuthUser(); const [title, setTitle] = useState(environmentChangeRequest.title); + const { changeState } = useChangeRequestApi(); + const sendToReview = async (project: string) => + changeState(project, environmentChangeRequest.id, 'Draft', { + state: 'In review', + comment: commentText, + }); return ( @@ -141,12 +148,7 @@ export const EnvironmentChangeRequest: FC<{ show={ <> - onReview( - environmentChangeRequest.id, - commentText, - ) - } + onClick={() => onReview(sendToReview)} count={changesCount( environmentChangeRequest, )} diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index 573f3afda2..d7bea11e1a 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -41,6 +41,7 @@ import { Badge } from 'component/common/Badge/Badge'; import { ProjectDoraMetrics } from './ProjectDoraMetrics/ProjectDoraMetrics'; import { UiFlags } from 'interfaces/uiConfig'; import { HiddenProjectIconWithTooltip } from './HiddenProjectIconWithTooltip/HiddenProjectIconWithTooltip'; +import { ChangeRequestPlausibleProvider } from 'component/changeRequest/ChangeRequestContext'; const StyledBadge = styled(Badge)(({ theme }) => ({ position: 'absolute', @@ -76,6 +77,11 @@ export const Project = () => { const [showDelDialog, setShowDelDialog] = useState(false); + const [ + changeRequestChangesWillOverwrite, + setChangeRequestChangesWillOverwrite, + ] = useState(false); + const tabs: ITab[] = [ { title: 'Overview', @@ -293,7 +299,18 @@ export const Project = () => { /> } + element={ + + setChangeRequestChangesWillOverwrite(true), + }} + > + + + } /> } /> } /> diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index d131d321f9..b28a0be9b7 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -3,6 +3,7 @@ import { usePlausibleTracker } from '../../../usePlausibleTracker'; import { PlausibleChangeRequestState } from 'component/changeRequest/changeRequest.types'; import { getUniqueChangeRequestId } from 'utils/unique-change-request-id'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { useChangeRequestPlausibleContext } from 'component/changeRequest/ChangeRequestContext'; export interface IChangeSchema { feature: string | null; @@ -33,6 +34,7 @@ export const useChangeRequestApi = () => { propagateErrors: true, }); const { uiConfig } = useUiConfig(); + const { willOverwriteStrategyChanges } = useChangeRequestPlausibleContext(); const addChange = async ( project: string, @@ -75,6 +77,7 @@ export const useChangeRequestApi = () => { props: { eventType: payload.state, previousState, + willOverwriteStrategyChanges, id: getUniqueChangeRequestId(uiConfig, changeRequestId), }, });