From 7d01dbb7486416d2b924accd30564748d097a2ae Mon Sep 17 00:00:00 2001 From: Jaanus Sellin Date: Fri, 26 Apr 2024 12:20:34 +0300 Subject: [PATCH] feat: feature completed connected to backend (#6947) Connects feature complete to backend --- .../FeatureLifecycleTooltip.test.tsx | 14 +++++++++-- .../FeatureLifecycleTooltip.tsx | 16 +++++++++--- .../FeatureOverviewMetaData.tsx | 11 +++++++- .../useFeatureLifecycleApi.ts | 25 +++++++++++++++++++ 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 frontend/src/hooks/api/actions/useFeatureLifecycleApi/useFeatureLifecycleApi.ts diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.test.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.test.tsx index ed6280b56c..f982268f7c 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.test.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.test.tsx @@ -11,9 +11,19 @@ const twoMinutesAgo = '2024-04-25T08:03:00.000Z'; const oneHourAgo = '2024-04-25T07:05:00.000Z'; const twoHoursAgo = '2024-04-25T06:05:00.000Z'; -const renderOpenTooltip = (stage: LifecycleStage, onArchive = () => {}) => { +const renderOpenTooltip = ( + stage: LifecycleStage, + onArchive = () => {}, + onComplete = () => {}, + loading = true, +) => { render( - + child , { permissions: [{ permission: DELETE_FEATURE }] }, diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.tsx index ddc4d447bf..fd86746412 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FeatureLifecycleTooltip.tsx @@ -257,7 +257,10 @@ const BoldTitle = styled(Typography)(({ theme }) => ({ fontWeight: theme.fontWeight.bold, })); -const LiveStageDescription: FC = ({ children }) => { +const LiveStageDescription: FC<{ + onComplete: () => void; + loading: boolean; +}> = ({ children, onComplete, loading }) => { return ( <> Is this feature complete? @@ -274,6 +277,8 @@ const LiveStageDescription: FC = ({ children }) => { variant='outlined' permission={UPDATE_FEATURE} size='small' + onClick={onComplete} + disabled={loading} > Mark Completed @@ -351,7 +356,9 @@ export const FeatureLifecycleTooltip: FC<{ children: React.ReactElement; stage: LifecycleStage; onArchive: () => void; -}> = ({ children, stage, onArchive }) => ( + onComplete: () => void; + loading: boolean; +}> = ({ children, stage, onArchive, onComplete, loading }) => ( )} {stage.name === 'live' && ( - + )} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx index bcbc56fa6f..dc6dffb313 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx @@ -14,6 +14,7 @@ import { FeatureArchiveDialog } from 'component/common/FeatureArchiveDialog/Feat import { useState } from 'react'; import { FeatureArchiveNotAllowedDialog } from 'component/common/FeatureArchiveDialog/FeatureArchiveNotAllowedDialog'; import { populateCurrentStage } from '../FeatureLifecycle/populateCurrentStage'; +import useFeatureLifecycleApi from 'hooks/api/actions/useFeatureLifecycleApi/useFeatureLifecycleApi'; const StyledContainer = styled('div')(({ theme }) => ({ borderRadius: theme.shape.borderRadiusLarge, @@ -79,9 +80,10 @@ export const StyledLabel = styled('span')(({ theme }) => ({ const FeatureOverviewMetaData = () => { const projectId = useRequiredPathParam('projectId'); const featureId = useRequiredPathParam('featureId'); - const { feature } = useFeature(projectId, featureId); + const { feature, refetchFeature } = useFeature(projectId, featureId); const { project, description, type } = feature; const featureLifecycleEnabled = useUiFlag('featureLifecycle'); + const { markFeatureCompleted, loading } = useFeatureLifecycleApi(); const navigate = useNavigate(); const [showDelDialog, setShowDelDialog] = useState(false); @@ -89,6 +91,11 @@ const FeatureOverviewMetaData = () => { const currentStage = populateCurrentStage(feature); + const onComplete = async () => { + await markFeatureCompleted(featureId, projectId); + refetchFeature(); + }; + return ( @@ -122,6 +129,8 @@ const FeatureOverviewMetaData = () => { setShowDelDialog(true)} + onComplete={onComplete} + loading={loading} > { + const { makeRequest, makeLightRequest, createRequest, errors, loading } = + useAPI({ + propagateErrors: true, + }); + + const markFeatureCompleted = async (name: string, project: string) => { + const path = `api/admin/projects/${project}/features/${name}/lifecycle/complete`; + const req = createRequest(path, { + method: 'POST', + }); + + return makeRequest(req.caller, req.id); + }; + + return { + markFeatureCompleted, + errors, + loading, + }; +}; + +export default useFeatureLifecycleApi;