mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-10 01:16:39 +02:00
chore: track metrics for how many CRs are moved into next state with conflicts (#6109)
Use React's context to track how many CRs are moved into their next state with conflicts present. This PR wraps environment change requests and change request overviews in a change request plausible context that contains a `willOverwriteStrategyChanges` property. This property is updated by the diff calculation if there are any conflicts and then read by the `changeState` function in the `useChangeRequestApi` hook. As long as at least one of the strategies in the CR contain conflicts, it will be marked as overwriting changes.
This commit is contained in:
parent
1d18187f7d
commit
73c4c62ea3
@ -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;
|
||||
|
@ -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);
|
||||
};
|
@ -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<IChangeRequestSidebarProps> = ({
|
||||
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<void>,
|
||||
) => {
|
||||
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<IChangeRequestSidebarProps> = ({
|
||||
header={<ReviewChangesHeader />}
|
||||
>
|
||||
{data?.map((environmentChangeRequest) => (
|
||||
<EnvironmentChangeRequest
|
||||
<ChangeRequestPlausibleProvider
|
||||
key={environmentChangeRequest.id}
|
||||
environmentChangeRequest={environmentChangeRequest}
|
||||
onClose={onClose}
|
||||
onReview={onReview}
|
||||
onDiscard={onDiscard}
|
||||
value={{
|
||||
willOverwriteStrategyChanges:
|
||||
changeRequestChangesWillOverwrite,
|
||||
registerWillOverwriteStrategyChanges: () =>
|
||||
setChangeRequestChangesWillOverwrite(true),
|
||||
}}
|
||||
>
|
||||
<ChangeRequest
|
||||
changeRequest={environmentChangeRequest}
|
||||
onNavigate={onClose}
|
||||
onRefetch={refetchChangeRequest}
|
||||
/>
|
||||
</EnvironmentChangeRequest>
|
||||
<EnvironmentChangeRequest
|
||||
key={environmentChangeRequest.id}
|
||||
environmentChangeRequest={environmentChangeRequest}
|
||||
onClose={onClose}
|
||||
onReview={onReview}
|
||||
onDiscard={onDiscard}
|
||||
>
|
||||
<ChangeRequest
|
||||
changeRequest={environmentChangeRequest}
|
||||
onNavigate={onClose}
|
||||
onRefetch={refetchChangeRequest}
|
||||
/>
|
||||
</EnvironmentChangeRequest>
|
||||
</ChangeRequestPlausibleProvider>
|
||||
))}
|
||||
</StyledPageContent>
|
||||
</DynamicSidebarModal>
|
||||
|
@ -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>) => 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 (
|
||||
<Box key={environmentChangeRequest.id}>
|
||||
@ -141,12 +148,7 @@ export const EnvironmentChangeRequest: FC<{
|
||||
show={
|
||||
<>
|
||||
<SubmitChangeRequestButton
|
||||
onClick={() =>
|
||||
onReview(
|
||||
environmentChangeRequest.id,
|
||||
commentText,
|
||||
)
|
||||
}
|
||||
onClick={() => onReview(sendToReview)}
|
||||
count={changesCount(
|
||||
environmentChangeRequest,
|
||||
)}
|
||||
|
@ -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 = () => {
|
||||
/>
|
||||
<Route
|
||||
path='change-requests/:id'
|
||||
element={<ChangeRequestOverview />}
|
||||
element={
|
||||
<ChangeRequestPlausibleProvider
|
||||
value={{
|
||||
willOverwriteStrategyChanges:
|
||||
changeRequestChangesWillOverwrite,
|
||||
registerWillOverwriteStrategyChanges: () =>
|
||||
setChangeRequestChangesWillOverwrite(true),
|
||||
}}
|
||||
>
|
||||
<ChangeRequestOverview />
|
||||
</ChangeRequestPlausibleProvider>
|
||||
}
|
||||
/>
|
||||
<Route path='settings/*' element={<ProjectSettings />} />
|
||||
<Route path='metrics' element={<ProjectDoraMetrics />} />
|
||||
|
@ -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),
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user