mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-29 01:15:48 +02:00
feat: add onboarding status to personal dashboard api (#8302)
This commit is contained in:
parent
01afe87302
commit
ac90c942db
@ -18,7 +18,6 @@ import { Badge } from '../common/Badge/Badge';
|
|||||||
import { ConnectSDK, CreateFlag } from './ConnectSDK';
|
import { ConnectSDK, CreateFlag } from './ConnectSDK';
|
||||||
import { WelcomeDialog } from './WelcomeDialog';
|
import { WelcomeDialog } from './WelcomeDialog';
|
||||||
import { useLocalStorageState } from 'hooks/useLocalStorageState';
|
import { useLocalStorageState } from 'hooks/useLocalStorageState';
|
||||||
import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
|
|
||||||
import { ProjectSetupComplete } from './ProjectSetupComplete';
|
import { ProjectSetupComplete } from './ProjectSetupComplete';
|
||||||
import { usePersonalDashboard } from 'hooks/api/getters/usePersonalDashboard/usePersonalDashboard';
|
import { usePersonalDashboard } from 'hooks/api/getters/usePersonalDashboard/usePersonalDashboard';
|
||||||
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
|
import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons';
|
||||||
@ -182,13 +181,11 @@ export const PersonalDashboard = () => {
|
|||||||
personalDashboard?.projects || [],
|
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 } =
|
const { personalDashboardProjectDetails, loading: loadingDetails } =
|
||||||
usePersonalDashboardProjectDetails(activeProject);
|
usePersonalDashboardProjectDetails(activeProject);
|
||||||
|
|
||||||
const stage = activeProjectOverview?.onboardingStatus.status ?? 'loading';
|
const stage =
|
||||||
|
personalDashboardProjectDetails?.onboardingStatus.status ?? 'loading';
|
||||||
|
|
||||||
const [welcomeDialog, setWelcomeDialog] = useLocalStorageState<
|
const [welcomeDialog, setWelcomeDialog] = useLocalStorageState<
|
||||||
'open' | 'closed'
|
'open' | 'closed'
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import type { PersonalDashboardProjectDetailsSchemaLatestEventsItem } from './personalDashboardProjectDetailsSchemaLatestEventsItem';
|
import type { PersonalDashboardProjectDetailsSchemaLatestEventsItem } from './personalDashboardProjectDetailsSchemaLatestEventsItem';
|
||||||
import type { PersonalDashboardProjectDetailsSchemaOwners } from './personalDashboardProjectDetailsSchemaOwners';
|
import type { PersonalDashboardProjectDetailsSchemaOwners } from './personalDashboardProjectDetailsSchemaOwners';
|
||||||
import type { PersonalDashboardProjectDetailsSchemaRolesItem } from './personalDashboardProjectDetailsSchemaRolesItem';
|
import type { PersonalDashboardProjectDetailsSchemaRolesItem } from './personalDashboardProjectDetailsSchemaRolesItem';
|
||||||
|
import type { ProjectOverviewSchemaOnboardingStatus } from './projectOverviewSchemaOnboardingStatus';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project details in personal dashboard
|
* Project details in personal dashboard
|
||||||
@ -20,4 +21,5 @@ export interface PersonalDashboardProjectDetailsSchema {
|
|||||||
* @minItems 1
|
* @minItems 1
|
||||||
*/
|
*/
|
||||||
roles: PersonalDashboardProjectDetailsSchemaRolesItem[];
|
roles: PersonalDashboardProjectDetailsSchemaRolesItem[];
|
||||||
|
onboardingStatus: ProjectOverviewSchemaOnboardingStatus;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ import { FakePrivateProjectChecker } from '../private-project/fakePrivateProject
|
|||||||
import { PrivateProjectChecker } from '../private-project/privateProjectChecker';
|
import { PrivateProjectChecker } from '../private-project/privateProjectChecker';
|
||||||
import { AccountStore } from '../../db/account-store';
|
import { AccountStore } from '../../db/account-store';
|
||||||
import { FakeAccountStore } from '../../../test/fixtures/fake-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 = (
|
export const createPersonalDashboardService = (
|
||||||
db: Db,
|
db: Db,
|
||||||
@ -24,6 +26,7 @@ export const createPersonalDashboardService = (
|
|||||||
new PersonalDashboardReadModel(db),
|
new PersonalDashboardReadModel(db),
|
||||||
new ProjectOwnersReadModel(db),
|
new ProjectOwnersReadModel(db),
|
||||||
new ProjectReadModel(db, config.eventBus, config.flagResolver),
|
new ProjectReadModel(db, config.eventBus, config.flagResolver),
|
||||||
|
new OnboardingReadModel(db),
|
||||||
new EventStore(db, config.getLogger),
|
new EventStore(db, config.getLogger),
|
||||||
new FeatureEventFormatterMd({
|
new FeatureEventFormatterMd({
|
||||||
unleashUrl: config.server.unleashUrl,
|
unleashUrl: config.server.unleashUrl,
|
||||||
@ -39,6 +42,7 @@ export const createFakePersonalDashboardService = (config: IUnleashConfig) => {
|
|||||||
new FakePersonalDashboardReadModel(),
|
new FakePersonalDashboardReadModel(),
|
||||||
new FakeProjectOwnersReadModel(),
|
new FakeProjectOwnersReadModel(),
|
||||||
new FakeProjectReadModel(),
|
new FakeProjectReadModel(),
|
||||||
|
new FakeOnboardingReadModel(),
|
||||||
new FakeEventStore(),
|
new FakeEventStore(),
|
||||||
new FeatureEventFormatterMd({
|
new FeatureEventFormatterMd({
|
||||||
unleashUrl: config.server.unleashUrl,
|
unleashUrl: config.server.unleashUrl,
|
||||||
|
@ -191,6 +191,10 @@ test('should return personal dashboard project details', async () => {
|
|||||||
expect(body).toMatchObject({
|
expect(body).toMatchObject({
|
||||||
owners: [{}],
|
owners: [{}],
|
||||||
roles: [{}],
|
roles: [{}],
|
||||||
|
onboardingStatus: {
|
||||||
|
status: 'first-flag-created',
|
||||||
|
feature: 'log_feature_a',
|
||||||
|
},
|
||||||
latestEvents: [
|
latestEvents: [
|
||||||
{
|
{
|
||||||
createdBy: 'new_user@test.com',
|
createdBy: 'new_user@test.com',
|
||||||
|
@ -9,9 +9,15 @@ import type {
|
|||||||
} from './personal-dashboard-read-model-type';
|
} from './personal-dashboard-read-model-type';
|
||||||
import type { IProjectReadModel } from '../project/project-read-model-type';
|
import type { IProjectReadModel } from '../project/project-read-model-type';
|
||||||
import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType';
|
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 type { FeatureEventFormatter } from '../../addons/feature-event-formatter-md';
|
||||||
import { generateImageUrl } from '../../util';
|
import { generateImageUrl } from '../../util';
|
||||||
|
import type { OnboardingStatus } from '../onboarding/onboarding-read-model-type';
|
||||||
|
|
||||||
type PersonalProjectDetails = {
|
type PersonalProjectDetails = {
|
||||||
latestEvents: {
|
latestEvents: {
|
||||||
@ -20,6 +26,7 @@ type PersonalProjectDetails = {
|
|||||||
id: number;
|
id: number;
|
||||||
createdByImageUrl: string;
|
createdByImageUrl: string;
|
||||||
}[];
|
}[];
|
||||||
|
onboardingStatus: OnboardingStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class PersonalDashboardService {
|
export class PersonalDashboardService {
|
||||||
@ -37,10 +44,13 @@ export class PersonalDashboardService {
|
|||||||
|
|
||||||
private accountStore: IAccountStore;
|
private accountStore: IAccountStore;
|
||||||
|
|
||||||
|
private onboardingReadModel: IOnboardingReadModel;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
personalDashboardReadModel: IPersonalDashboardReadModel,
|
personalDashboardReadModel: IPersonalDashboardReadModel,
|
||||||
projectOwnersReadModel: IProjectOwnersReadModel,
|
projectOwnersReadModel: IProjectOwnersReadModel,
|
||||||
projectReadModel: IProjectReadModel,
|
projectReadModel: IProjectReadModel,
|
||||||
|
onboardingReadModel: IOnboardingReadModel,
|
||||||
eventStore: IEventStore,
|
eventStore: IEventStore,
|
||||||
featureEventFormatter: FeatureEventFormatter,
|
featureEventFormatter: FeatureEventFormatter,
|
||||||
privateProjectChecker: IPrivateProjectChecker,
|
privateProjectChecker: IPrivateProjectChecker,
|
||||||
@ -49,6 +59,7 @@ export class PersonalDashboardService {
|
|||||||
this.personalDashboardReadModel = personalDashboardReadModel;
|
this.personalDashboardReadModel = personalDashboardReadModel;
|
||||||
this.projectOwnersReadModel = projectOwnersReadModel;
|
this.projectOwnersReadModel = projectOwnersReadModel;
|
||||||
this.projectReadModel = projectReadModel;
|
this.projectReadModel = projectReadModel;
|
||||||
|
this.onboardingReadModel = onboardingReadModel;
|
||||||
this.eventStore = eventStore;
|
this.eventStore = eventStore;
|
||||||
this.featureEventFormatter = featureEventFormatter;
|
this.featureEventFormatter = featureEventFormatter;
|
||||||
this.privateProjectChecker = privateProjectChecker;
|
this.privateProjectChecker = privateProjectChecker;
|
||||||
@ -100,6 +111,11 @@ export class PersonalDashboardService {
|
|||||||
[{ field: 'project', operator: 'IS', values: [projectId] }],
|
[{ field: 'project', operator: 'IS', values: [projectId] }],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onboardingStatus =
|
||||||
|
await this.onboardingReadModel.getOnboardingStatusForProject(
|
||||||
|
projectId,
|
||||||
|
);
|
||||||
|
|
||||||
const formattedEvents = recentEvents.map((event) => ({
|
const formattedEvents = recentEvents.map((event) => ({
|
||||||
summary: this.featureEventFormatter.format(event).text,
|
summary: this.featureEventFormatter.format(event).text,
|
||||||
createdBy: event.createdBy,
|
createdBy: event.createdBy,
|
||||||
@ -107,7 +123,7 @@ export class PersonalDashboardService {
|
|||||||
createdByImageUrl: generateImageUrl({ email: event.createdBy }),
|
createdByImageUrl: generateImageUrl({ email: event.createdBy }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return { latestEvents: formattedEvents };
|
return { latestEvents: formattedEvents, onboardingStatus };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAdmins(): Promise<MinimalUser[]> {
|
async getAdmins(): Promise<MinimalUser[]> {
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import type { FromSchema } from 'json-schema-to-ts';
|
import type { FromSchema } from 'json-schema-to-ts';
|
||||||
import { projectSchema } from './project-schema';
|
import { projectSchema } from './project-schema';
|
||||||
|
import { projectOverviewSchema } from './project-overview-schema';
|
||||||
|
|
||||||
export const personalDashboardProjectDetailsSchema = {
|
export const personalDashboardProjectDetailsSchema = {
|
||||||
$id: '#/components/schemas/personalDashboardProjectDetailsSchema',
|
$id: '#/components/schemas/personalDashboardProjectDetailsSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description: 'Project details in personal dashboard',
|
description: 'Project details in personal dashboard',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['owners', 'roles', 'latestEvents'],
|
required: ['owners', 'roles', 'latestEvents', 'onboardingStatus'],
|
||||||
properties: {
|
properties: {
|
||||||
|
onboardingStatus: projectOverviewSchema.properties.onboardingStatus,
|
||||||
latestEvents: {
|
latestEvents: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description: 'The latest events for the project.',
|
description: 'The latest events for the project.',
|
||||||
|
Loading…
Reference in New Issue
Block a user