From 108c78063d06b56cd98f120c2a8904d356a64160 Mon Sep 17 00:00:00 2001 From: sjaanus Date: Thu, 25 Jan 2024 14:42:02 +0200 Subject: [PATCH 1/5] feat: add conflict count to cr metrics --- .../ChangeRequestOverview.tsx | 70 ++++++++++++++----- .../ChangeRequestSidebar.tsx | 2 +- .../useChangeRequestApi.ts | 9 +++ 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx index 68a7a0b1a576..362001816702 100644 --- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx @@ -34,7 +34,6 @@ import { ChangeRequestRejectScheduledDialogue, } from './ChangeRequestScheduledDialogs/changeRequestScheduledDialogs'; import { ScheduleChangeRequestDialog } from './ChangeRequestScheduledDialogs/ScheduleChangeRequestDialog'; -import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import { PlausibleChangeRequestState } from '../changeRequest.types'; const StyledAsideBox = styled(Box)(({ theme }) => ({ @@ -105,7 +104,6 @@ export const ChangeRequestOverview: FC = () => { const { isChangeRequestConfiguredForReview } = useChangeRequestsEnabled(projectId); const scheduleChangeRequests = useUiFlag('scheduledConfigurationChanges'); - const { trackEvent } = usePlausibleTracker(); if (!changeRequest) { return null; @@ -115,6 +113,10 @@ export const ChangeRequestOverview: FC = () => { changeRequest.environment, ); + const conflictCount = changeRequest.features.filter( + (feature) => feature.conflict, + ).length; + const getCurrentState = (): PlausibleChangeRequestState => { switch (changeRequest.state) { case 'Scheduled': @@ -126,9 +128,15 @@ export const ChangeRequestOverview: FC = () => { const onApplyChanges = async () => { try { - await changeState(projectId, Number(id), getCurrentState(), { - state: 'Applied', - }); + await changeState( + projectId, + Number(id), + getCurrentState(), + conflictCount, + { + state: 'Applied', + }, + ); setShowApplyScheduledDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -144,10 +152,16 @@ export const ChangeRequestOverview: FC = () => { const onScheduleChangeRequest = async (scheduledDate: Date) => { try { - await changeState(projectId, Number(id), getCurrentState(), { - state: 'Scheduled', - scheduledAt: scheduledDate.toISOString(), - }); + await changeState( + projectId, + Number(id), + getCurrentState(), + conflictCount, + { + state: 'Scheduled', + scheduledAt: scheduledDate.toISOString(), + }, + ); setShowScheduleChangeDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -178,9 +192,15 @@ export const ChangeRequestOverview: FC = () => { const onCancelChanges = async () => { try { - await changeState(projectId, Number(id), getCurrentState(), { - state: 'Cancelled', - }); + await changeState( + projectId, + Number(id), + getCurrentState(), + conflictCount, + { + state: 'Cancelled', + }, + ); setShowCancelDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -196,10 +216,16 @@ export const ChangeRequestOverview: FC = () => { const onReject = async (comment?: string) => { try { - await changeState(projectId, Number(id), getCurrentState(), { - state: 'Rejected', - comment, - }); + await changeState( + projectId, + Number(id), + getCurrentState(), + conflictCount, + { + state: 'Rejected', + comment, + }, + ); setShowRejectDialog(false); setToastData({ type: 'success', @@ -215,9 +241,15 @@ export const ChangeRequestOverview: FC = () => { const onApprove = async () => { try { - await changeState(projectId, Number(id), getCurrentState(), { - state: 'Approved', - }); + await changeState( + projectId, + Number(id), + getCurrentState(), + conflictCount, + { + state: 'Approved', + }, + ); refetchChangeRequest(); refetchChangeRequestOpen(); setToastData({ diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx index 3177cb7b079a..170a1174b42b 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx @@ -81,7 +81,7 @@ export const ChangeRequestSidebar: VFC = ({ const onReview = async (draftId: number, comment?: string) => { try { - await changeState(project, draftId, 'Draft', { + await changeState(project, draftId, 'Draft', 0, { state: 'In review', comment, }); diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index 00dddaa01527..dd3c3419abc1 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -56,6 +56,7 @@ export const useChangeRequestApi = () => { project: string, changeRequestId: number, previousState: PlausibleChangeRequestState, + conflictCount: number, payload: { state: | 'Approved' @@ -68,10 +69,18 @@ export const useChangeRequestApi = () => { scheduledAt?: string; }, ) => { + console.log({ + eventType: payload.state, + previousState, + id: changeRequestId, + conflictCount, + }); trackEvent('change_request', { props: { eventType: payload.state, previousState, + id: changeRequestId, + conflictCount, }, }); From 42c1422cf47fb30f91ede3437d26e7d58fa0c80b Mon Sep 17 00:00:00 2001 From: sjaanus Date: Thu, 25 Jan 2024 14:43:23 +0200 Subject: [PATCH 2/5] Fix --- .../api/actions/useChangeRequestApi/useChangeRequestApi.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index dd3c3419abc1..80b004b8d93d 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -69,12 +69,6 @@ export const useChangeRequestApi = () => { scheduledAt?: string; }, ) => { - console.log({ - eventType: payload.state, - previousState, - id: changeRequestId, - conflictCount, - }); trackEvent('change_request', { props: { eventType: payload.state, From dc0a1980cb982d6abe7b045676d538cc6f062b47 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 26 Jan 2024 12:39:27 +0400 Subject: [PATCH 3/5] conflict-cr: use CR ids that are unique across Unleash installations --- .../actions/useChangeRequestApi/useChangeRequestApi.ts | 4 +++- frontend/src/utils/unique-change-request-id.ts | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frontend/src/utils/unique-change-request-id.ts diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index 80b004b8d93d..07ff8663b433 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -1,6 +1,7 @@ import useAPI from '../useApi/useApi'; import { usePlausibleTracker } from '../../../usePlausibleTracker'; import { PlausibleChangeRequestState } from 'component/changeRequest/changeRequest.types'; +import { getUniqueChangeRequestId } from 'utils/unique-change-request-id'; export interface IChangeSchema { feature: string | null; @@ -30,6 +31,7 @@ export const useChangeRequestApi = () => { const { makeRequest, createRequest, errors, loading } = useAPI({ propagateErrors: true, }); + const { uiConfig } = useUiConfig(); const addChange = async ( project: string, @@ -73,7 +75,7 @@ export const useChangeRequestApi = () => { props: { eventType: payload.state, previousState, - id: changeRequestId, + id: getUniqueChangeRequestId(uiConfig, changeRequestId), conflictCount, }, }); diff --git a/frontend/src/utils/unique-change-request-id.ts b/frontend/src/utils/unique-change-request-id.ts new file mode 100644 index 000000000000..15f16fbfe0cc --- /dev/null +++ b/frontend/src/utils/unique-change-request-id.ts @@ -0,0 +1,10 @@ +import { IUiConfig } from 'interfaces/uiConfig'; + +export const getUniqueChangeRequestId = ( + uiConfig: Pick, + changeRequestId: number, +) => { + return `${ + uiConfig.baseUriPath || uiConfig.versionInfo?.instanceId + }/change-requests/${changeRequestId}?version=${uiConfig.versionInfo}`; +}; From f43650546a6ad16c2a7de4335816864937f15108 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 26 Jan 2024 12:47:58 +0400 Subject: [PATCH 4/5] Chore: add missing import --- .../hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index 07ff8663b433..b68d9125b8c2 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -2,6 +2,7 @@ import useAPI from '../useApi/useApi'; 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'; export interface IChangeSchema { feature: string | null; From a5c664c9a3beb8ec86d78b68a17adc8763ed67de Mon Sep 17 00:00:00 2001 From: sjaanus Date: Tue, 30 Jan 2024 10:20:51 +0200 Subject: [PATCH 5/5] Rever conflict --- .../ChangeRequestOverview.tsx | 68 +++++-------------- .../ChangeRequestSidebar.tsx | 2 +- .../useChangeRequestApi.ts | 2 - 3 files changed, 18 insertions(+), 54 deletions(-) diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx index 362001816702..0746576f7ab1 100644 --- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx @@ -113,10 +113,6 @@ export const ChangeRequestOverview: FC = () => { changeRequest.environment, ); - const conflictCount = changeRequest.features.filter( - (feature) => feature.conflict, - ).length; - const getCurrentState = (): PlausibleChangeRequestState => { switch (changeRequest.state) { case 'Scheduled': @@ -128,15 +124,9 @@ export const ChangeRequestOverview: FC = () => { const onApplyChanges = async () => { try { - await changeState( - projectId, - Number(id), - getCurrentState(), - conflictCount, - { - state: 'Applied', - }, - ); + await changeState(projectId, Number(id), getCurrentState(), { + state: 'Applied', + }); setShowApplyScheduledDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -152,16 +142,10 @@ export const ChangeRequestOverview: FC = () => { const onScheduleChangeRequest = async (scheduledDate: Date) => { try { - await changeState( - projectId, - Number(id), - getCurrentState(), - conflictCount, - { - state: 'Scheduled', - scheduledAt: scheduledDate.toISOString(), - }, - ); + await changeState(projectId, Number(id), getCurrentState(), { + state: 'Scheduled', + scheduledAt: scheduledDate.toISOString(), + }); setShowScheduleChangeDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -192,15 +176,9 @@ export const ChangeRequestOverview: FC = () => { const onCancelChanges = async () => { try { - await changeState( - projectId, - Number(id), - getCurrentState(), - conflictCount, - { - state: 'Cancelled', - }, - ); + await changeState(projectId, Number(id), getCurrentState(), { + state: 'Cancelled', + }); setShowCancelDialog(false); refetchChangeRequest(); refetchChangeRequestOpen(); @@ -216,16 +194,10 @@ export const ChangeRequestOverview: FC = () => { const onReject = async (comment?: string) => { try { - await changeState( - projectId, - Number(id), - getCurrentState(), - conflictCount, - { - state: 'Rejected', - comment, - }, - ); + await changeState(projectId, Number(id), getCurrentState(), { + state: 'Rejected', + comment, + }); setShowRejectDialog(false); setToastData({ type: 'success', @@ -241,15 +213,9 @@ export const ChangeRequestOverview: FC = () => { const onApprove = async () => { try { - await changeState( - projectId, - Number(id), - getCurrentState(), - conflictCount, - { - state: 'Approved', - }, - ); + await changeState(projectId, Number(id), getCurrentState(), { + state: 'Approved', + }); refetchChangeRequest(); refetchChangeRequestOpen(); setToastData({ diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx index 170a1174b42b..3177cb7b079a 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar.tsx @@ -81,7 +81,7 @@ export const ChangeRequestSidebar: VFC = ({ const onReview = async (draftId: number, comment?: string) => { try { - await changeState(project, draftId, 'Draft', 0, { + await changeState(project, draftId, 'Draft', { state: 'In review', comment, }); diff --git a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts index b68d9125b8c2..d131d321f9d4 100644 --- a/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts +++ b/frontend/src/hooks/api/actions/useChangeRequestApi/useChangeRequestApi.ts @@ -59,7 +59,6 @@ export const useChangeRequestApi = () => { project: string, changeRequestId: number, previousState: PlausibleChangeRequestState, - conflictCount: number, payload: { state: | 'Approved' @@ -77,7 +76,6 @@ export const useChangeRequestApi = () => { eventType: payload.state, previousState, id: getUniqueChangeRequestId(uiConfig, changeRequestId), - conflictCount, }, });