/* eslint-disable @typescript-eslint/no-namespace */ import { IssuesService, IssuesServiceNs, } from '@app/event-emitter/issues/issues.service'; import { RedmineTypes } from '@app/event-emitter/models/redmine-types'; import { FlatIssuesStore } from '@app/event-emitter/utils/flat-issues-store'; import { GetValueFromObjectByKey } from '@app/event-emitter/utils/get-value-from-object-by-key'; import { TreeIssuesStore } from '@app/event-emitter/utils/tree-issues-store'; import { Injectable, Logger } from '@nestjs/common'; import nano from 'nano'; import { WidgetInterface } from '../widget-interface'; export namespace ListIssuesByUsersWidgetNs { export namespace Models { export type Params = { fromRootIssueId?: number; fromQuery?: nano.MangoQuery; userKey: string; userSort?: boolean; statuses: string[]; }; export type FindResult = { result?: any; error?: FindErrors; }; export enum FindErrors { NOT_FOUND = 'NOT_FOUND', } } } type Params = ListIssuesByUsersWidgetNs.Models.Params; type ExtendedIssue = RedmineTypes.Issue & Record; type FindResult = ListIssuesByUsersWidgetNs.Models.FindResult; @Injectable() export class ListIssuesByUsersWidgetService implements WidgetInterface { private logger = new Logger(ListIssuesByUsersWidgetService.name); private issuesLoader: IssuesServiceNs.IssuesLoader; constructor(private issuesService: IssuesService) { this.issuesLoader = this.issuesService.createDynamicIssuesLoader(); } isMyConfig(): boolean { return true; } async render(widgetParams: Params): Promise { let store: FlatIssuesStore; if (widgetParams.fromRootIssueId) { store = await this.getListFromRoot(widgetParams.fromRootIssueId); } else if (widgetParams.fromQuery) { store = await this.getListByQuery(widgetParams.fromQuery); } else { const errMsg = `Wrong widgetParams value`; this.logger.error(errMsg); throw new Error(errMsg); } const grouped = store.groupByStatusWithExtra((issue) => { const res = this.getUserValueByKey(issue, widgetParams.userKey); return res.result || 'Unknown'; }, widgetParams.statuses); let res = [] as any[]; for (const user in grouped) { if (Object.prototype.hasOwnProperty.call(grouped, user)) { const data = grouped[user]; res.push({ data: data, metainfo: this.createMetaInfo(user), }); } } if (widgetParams.userSort) { res = res.sort((a, b) => { return a.metainfo.title.localeCompare(b.metainfo.title); }); } return res; } private async getListFromRoot(issueId: number): Promise { const treeStore = new TreeIssuesStore(); const rootIssue = await this.issuesService.getIssue(issueId); treeStore.setRootIssue(rootIssue); await treeStore.fillData(this.issuesLoader); return treeStore.getFlatStore(); } private async getListByQuery( query: nano.MangoQuery, ): Promise { const rawData = await this.issuesService.find(query); const store = new FlatIssuesStore(); for (let i = 0; i < rawData.length; i++) { const issue = rawData[i]; store.push(issue); } return store; } private getUserValueByKey(issue: ExtendedIssue, key: string): FindResult { const value = GetValueFromObjectByKey(issue, key); if (value.result) { return { result: value.result }; } else { return { error: ListIssuesByUsersWidgetNs.Models.FindErrors.NOT_FOUND }; } } private createMetaInfo(user: string): Record { return { title: user, }; } }