pinkmine/libs/event-emitter/src/dashboards/widget-data-loader/list-issues-by-users.widget-data-loader.service.ts

141 lines
4.6 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-namespace */
import { IssueUrlEnhancer } from '@app/event-emitter/issue-enhancers/issue-url-enhancer';
import { TagStyledEnhancerNs } from '@app/event-emitter/issue-enhancers/tag-styled-enhancer';
import { TimePassedHighlightEnhancer } from '@app/event-emitter/issue-enhancers/time-passed-highlight-enhancer';
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 * as PriorityStylesEnhancerNs from '@app/event-emitter/issue-enhancers/priority-styles-enhancer';
import { WidgetDataLoaderInterface } from '../widget-data-loader-interface';
import {
AppError,
Result,
createAppError,
success,
} from '@app/event-emitter/utils/result';
export namespace ListIssuesByUsersWidgetNs {
export namespace Models {
export type Params = {
fromRootIssueId?: number;
fromQuery?: nano.MangoQuery;
userKey: string;
userSort?: boolean;
statuses: string[];
} & TagStyledEnhancerNs.ConfigWithTagsStyles;
export type FindResult = {
result?: any;
error?: FindErrors;
};
export enum FindErrors {
NOT_FOUND = 'NOT_FOUND',
}
}
}
type Params = ListIssuesByUsersWidgetNs.Models.Params;
type ExtendedIssue = RedmineTypes.Issue & Record<string, any>;
type FindResult = ListIssuesByUsersWidgetNs.Models.FindResult;
@Injectable()
export class ListIssuesByUsersWidgetDataLoaderService
implements WidgetDataLoaderInterface<Params, any, any>
{
private logger = new Logger(ListIssuesByUsersWidgetDataLoaderService.name);
private issuesLoader: IssuesServiceNs.IssuesLoader;
constructor(
private issuesService: IssuesService,
private timePassedHighlightEnhancer: TimePassedHighlightEnhancer,
private issueUrlEnhancer: IssueUrlEnhancer,
) {
this.issuesLoader = this.issuesService.createDynamicIssuesLoader();
}
isMyConfig(): boolean {
return true;
}
async load(widgetParams: Params): Promise<Result<any, AppError>> {
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);
return fail(createAppError(errMsg));
}
await store.enhanceIssues([
this.timePassedHighlightEnhancer,
this.issueUrlEnhancer,
TagStyledEnhancerNs.CreateTagStyledEnhancerForConfig(widgetParams),
PriorityStylesEnhancerNs.CreatePriorityStylesEnhancer(widgetParams),
]);
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 success(res);
}
private async getListFromRoot(issueId: number): Promise<FlatIssuesStore> {
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<FlatIssuesStore> {
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<string, any> {
return {
title: user,
};
}
}