From f6c7420c432e22ddd95ab792e8bfa44b01da54be Mon Sep 17 00:00:00 2001 From: kwasniew Date: Mon, 30 Sep 2024 13:55:45 +0200 Subject: [PATCH] feat: add onboarding status to personal dashboard api --- .../personalDashboard/PersonalDashboard.tsx | 7 ++----- .../personalDashboardProjectDetailsSchema.ts | 2 ++ .../createPersonalDashboardService.ts | 4 ++++ .../personal-dashboard-controller.e2e.test.ts | 4 ++++ .../personal-dashboard-service.ts | 20 +++++++++++++++++-- ...rsonal-dashboard-project-details-schema.ts | 4 +++- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontend/src/component/personalDashboard/PersonalDashboard.tsx b/frontend/src/component/personalDashboard/PersonalDashboard.tsx index 30cd5bddbf06..00ed9a00723f 100644 --- a/frontend/src/component/personalDashboard/PersonalDashboard.tsx +++ b/frontend/src/component/personalDashboard/PersonalDashboard.tsx @@ -18,7 +18,6 @@ import { Badge } from '../common/Badge/Badge'; import { ConnectSDK, CreateFlag } from './ConnectSDK'; import { WelcomeDialog } from './WelcomeDialog'; import { useLocalStorageState } from 'hooks/useLocalStorageState'; -import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview'; import { ProjectSetupComplete } from './ProjectSetupComplete'; import { usePersonalDashboard } from 'hooks/api/getters/usePersonalDashboard/usePersonalDashboard'; import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; @@ -182,13 +181,11 @@ export const PersonalDashboard = () => { personalDashboard?.projects || [], ); - // TODO: since we use this one only for the onboarding status, we can add th eonboarding status to the personal dashboard project details API - const { project: activeProjectOverview, loading } = - useProjectOverview(activeProject); const { personalDashboardProjectDetails, loading: loadingDetails } = usePersonalDashboardProjectDetails(activeProject); - const stage = activeProjectOverview?.onboardingStatus.status ?? 'loading'; + const stage = + personalDashboardProjectDetails?.onboardingStatus.status ?? 'loading'; const [welcomeDialog, setWelcomeDialog] = useLocalStorageState< 'open' | 'closed' diff --git a/frontend/src/openapi/models/personalDashboardProjectDetailsSchema.ts b/frontend/src/openapi/models/personalDashboardProjectDetailsSchema.ts index f41797a47c96..b629214bc292 100644 --- a/frontend/src/openapi/models/personalDashboardProjectDetailsSchema.ts +++ b/frontend/src/openapi/models/personalDashboardProjectDetailsSchema.ts @@ -6,6 +6,7 @@ import type { PersonalDashboardProjectDetailsSchemaLatestEventsItem } from './personalDashboardProjectDetailsSchemaLatestEventsItem'; import type { PersonalDashboardProjectDetailsSchemaOwners } from './personalDashboardProjectDetailsSchemaOwners'; import type { PersonalDashboardProjectDetailsSchemaRolesItem } from './personalDashboardProjectDetailsSchemaRolesItem'; +import type { ProjectOverviewSchemaOnboardingStatus } from './projectOverviewSchemaOnboardingStatus'; /** * Project details in personal dashboard @@ -20,4 +21,5 @@ export interface PersonalDashboardProjectDetailsSchema { * @minItems 1 */ roles: PersonalDashboardProjectDetailsSchemaRolesItem[]; + onboardingStatus: ProjectOverviewSchemaOnboardingStatus; } diff --git a/src/lib/features/personal-dashboard/createPersonalDashboardService.ts b/src/lib/features/personal-dashboard/createPersonalDashboardService.ts index a376f2bf5d17..ec830ab6dc6a 100644 --- a/src/lib/features/personal-dashboard/createPersonalDashboardService.ts +++ b/src/lib/features/personal-dashboard/createPersonalDashboardService.ts @@ -14,6 +14,8 @@ import { FakePrivateProjectChecker } from '../private-project/fakePrivateProject import { PrivateProjectChecker } from '../private-project/privateProjectChecker'; import { AccountStore } from '../../db/account-store'; import { FakeAccountStore } from '../../../test/fixtures/fake-account-store'; +import { OnboardingReadModel } from '../onboarding/onboarding-read-model'; +import { FakeOnboardingReadModel } from '../onboarding/fake-onboarding-read-model'; export const createPersonalDashboardService = ( db: Db, @@ -24,6 +26,7 @@ export const createPersonalDashboardService = ( new PersonalDashboardReadModel(db), new ProjectOwnersReadModel(db), new ProjectReadModel(db, config.eventBus, config.flagResolver), + new OnboardingReadModel(db), new EventStore(db, config.getLogger), new FeatureEventFormatterMd({ unleashUrl: config.server.unleashUrl, @@ -39,6 +42,7 @@ export const createFakePersonalDashboardService = (config: IUnleashConfig) => { new FakePersonalDashboardReadModel(), new FakeProjectOwnersReadModel(), new FakeProjectReadModel(), + new FakeOnboardingReadModel(), new FakeEventStore(), new FeatureEventFormatterMd({ unleashUrl: config.server.unleashUrl, diff --git a/src/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.ts b/src/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.ts index bd6336b5131a..55a7f9ac5e4f 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.ts @@ -191,6 +191,10 @@ test('should return personal dashboard project details', async () => { expect(body).toMatchObject({ owners: [{}], roles: [{}], + onboardingStatus: { + status: 'first-flag-created', + feature: 'log_feature_a', + }, latestEvents: [ { createdBy: 'new_user@test.com', diff --git a/src/lib/features/personal-dashboard/personal-dashboard-service.ts b/src/lib/features/personal-dashboard/personal-dashboard-service.ts index da5753724da4..f6a15d64cae4 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-service.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-service.ts @@ -9,9 +9,15 @@ import type { } from './personal-dashboard-read-model-type'; import type { IProjectReadModel } from '../project/project-read-model-type'; import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType'; -import type { IAccountStore, IEventStore, MinimalUser } from '../../types'; +import type { + IAccountStore, + IEventStore, + IOnboardingReadModel, + MinimalUser, +} from '../../types'; import type { FeatureEventFormatter } from '../../addons/feature-event-formatter-md'; import { generateImageUrl } from '../../util'; +import type { OnboardingStatus } from '../onboarding/onboarding-read-model-type'; type PersonalProjectDetails = { latestEvents: { @@ -20,6 +26,7 @@ type PersonalProjectDetails = { id: number; createdByImageUrl: string; }[]; + onboardingStatus: OnboardingStatus; }; export class PersonalDashboardService { @@ -37,10 +44,13 @@ export class PersonalDashboardService { private accountStore: IAccountStore; + private onboardingReadModel: IOnboardingReadModel; + constructor( personalDashboardReadModel: IPersonalDashboardReadModel, projectOwnersReadModel: IProjectOwnersReadModel, projectReadModel: IProjectReadModel, + onboardingReadModel: IOnboardingReadModel, eventStore: IEventStore, featureEventFormatter: FeatureEventFormatter, privateProjectChecker: IPrivateProjectChecker, @@ -49,6 +59,7 @@ export class PersonalDashboardService { this.personalDashboardReadModel = personalDashboardReadModel; this.projectOwnersReadModel = projectOwnersReadModel; this.projectReadModel = projectReadModel; + this.onboardingReadModel = onboardingReadModel; this.eventStore = eventStore; this.featureEventFormatter = featureEventFormatter; this.privateProjectChecker = privateProjectChecker; @@ -100,6 +111,11 @@ export class PersonalDashboardService { [{ field: 'project', operator: 'IS', values: [projectId] }], ); + const onboardingStatus = + await this.onboardingReadModel.getOnboardingStatusForProject( + projectId, + ); + const formattedEvents = recentEvents.map((event) => ({ summary: this.featureEventFormatter.format(event).text, createdBy: event.createdBy, @@ -107,7 +123,7 @@ export class PersonalDashboardService { createdByImageUrl: generateImageUrl({ email: event.createdBy }), })); - return { latestEvents: formattedEvents }; + return { latestEvents: formattedEvents, onboardingStatus }; } async getAdmins(): Promise { diff --git a/src/lib/openapi/spec/personal-dashboard-project-details-schema.ts b/src/lib/openapi/spec/personal-dashboard-project-details-schema.ts index 7c51686f6643..2af4b55b2351 100644 --- a/src/lib/openapi/spec/personal-dashboard-project-details-schema.ts +++ b/src/lib/openapi/spec/personal-dashboard-project-details-schema.ts @@ -1,13 +1,15 @@ import type { FromSchema } from 'json-schema-to-ts'; import { projectSchema } from './project-schema'; +import { projectOverviewSchema } from './project-overview-schema'; export const personalDashboardProjectDetailsSchema = { $id: '#/components/schemas/personalDashboardProjectDetailsSchema', type: 'object', description: 'Project details in personal dashboard', additionalProperties: false, - required: ['owners', 'roles', 'latestEvents'], + required: ['owners', 'roles', 'latestEvents', 'onboardingStatus'], properties: { + onboardingStatus: projectOverviewSchema.properties.onboardingStatus, latestEvents: { type: 'array', description: 'The latest events for the project.',