import { inject, Injectable } from '@angular/core'; import { CommandResult, CreateProjectInput, MemberInput, Project, ProjectAnalytics, ProjectInsights, PortfolioProject, Home, ProjectSettings, ProjectsGateway, ProjectStats, UpdateProjectInput, } from '@task-stream/web/tracker/domain'; import { map, Observable } from 'rxjs'; import { AddProjectMemberDocument, ChangeProjectMemberRoleDocument, CreateProjectDocument, DeleteProjectDocument, ArchiveProjectDocument, UnarchiveProjectDocument, MyProjectsDocument, ProjectAnalyticsDocument, ProjectInsightsDocument, PortfolioDocument, MyHomeDocument, ProjectDocument, ProjectStatsDocument, PublicProjectsDocument, RemoveProjectMemberDocument, UpdateProjectDocument, UpdateProjectSettingsDocument, } from '../graphql/generated'; import { GraphqlOperations } from './graphql-operations'; import { toCommandResult, toIssueSummary, toProject, toSettingsInput, toStats, } from './mappers'; @Injectable() export class GraphqlProjectsGateway extends ProjectsGateway { private readonly gql = inject(GraphqlOperations); myProjects(): Observable { return this.gql .query(MyProjectsDocument) .pipe(map((d) => d.myProjects.map(toProject))); } publicProjects(): Observable { return this.gql .query(PublicProjectsDocument) .pipe(map((d) => d.publicProjects.map(toProject))); } project(idOrKey: string): Observable { return this.gql .query(ProjectDocument, { idOrKey }) .pipe(map((d) => toProject(d.project))); } stats(projectId: string): Observable { return this.gql .query(ProjectStatsDocument, { idOrKey: projectId }) .pipe(map((d) => toStats(d.project.stats))); } myHome(): Observable { return this.gql .query(MyHomeDocument, {}) .pipe(map((d) => d.myHome as Home)); } portfolio(): Observable { return this.gql.query(PortfolioDocument, {}).pipe( map((d) => d.portfolio.map((p) => ({ ...(p as unknown as PortfolioProject), epics: p.epics.map((e) => ({ issue: toIssueSummary(e.issue), progress: { ...e.progress }, links: [], })), })), ), ); } insights( projectId: string, since: string | null, ): Observable { return this.gql .query(ProjectInsightsDocument, { idOrKey: projectId, since }) .pipe(map((d) => d.project.insights as ProjectInsights)); } analytics(projectId: string, days: number): Observable { return this.gql .query(ProjectAnalyticsDocument, { idOrKey: projectId, days }) .pipe(map((d) => d.project.analytics)); } updateSettings( projectId: string, settings: ProjectSettings, ): Observable { return this.gql .mutate(UpdateProjectSettingsDocument, { projectId, settings: toSettingsInput(settings), }) .pipe(map((d) => toCommandResult(d.updateProjectSettings))); } create(input: CreateProjectInput): Observable { return this.gql .mutate(CreateProjectDocument, { input }) .pipe(map((d) => toCommandResult(d.createProject))); } update(input: UpdateProjectInput): Observable { return this.gql .mutate(UpdateProjectDocument, { input }) .pipe(map((d) => toCommandResult(d.updateProject))); } setArchived(projectId: string, archived: boolean): Observable { return archived ? this.gql .mutate(ArchiveProjectDocument, { projectId }) .pipe(map((d) => toCommandResult(d.archiveProject))) : this.gql .mutate(UnarchiveProjectDocument, { projectId }) .pipe(map((d) => toCommandResult(d.unarchiveProject))); } delete(projectId: string, confirmKey: string): Observable { return this.gql .mutate(DeleteProjectDocument, { projectId, confirmKey }) .pipe(map((d) => toCommandResult(d.deleteProject))); } addMember(input: MemberInput): Observable { return this.gql .mutate(AddProjectMemberDocument, { input: input as never }) .pipe(map((d) => toCommandResult(d.addProjectMember))); } changeMemberRole(input: MemberInput): Observable { return this.gql .mutate(ChangeProjectMemberRoleDocument, { input: input as never }) .pipe(map((d) => toCommandResult(d.changeProjectMemberRole))); } removeMember(projectId: string, userId: string): Observable { return this.gql .mutate(RemoveProjectMemberDocument, { projectId, userId }) .pipe(map((d) => toCommandResult(d.removeProjectMember))); } }