From 730aaee54ad6ca3fc53cc04718b08ef643105b55 Mon Sep 17 00:00:00 2001 From: Valentine Lejeune Date: Thu, 15 Apr 2021 15:23:52 +0200 Subject: [PATCH] feat: add jira step & display issues in gridjs table --- src/http/http.module.ts | 4 +- src/http/jira.service.ts | 33 +++++++ src/proxy-page/proxy-page.module.ts | 3 +- src/proxy-page/proxy-page.service.ts | 5 + src/proxy-page/proxy-page.step.ts | 3 +- src/proxy-page/steps/addJira.ts | 143 +++++++++++++++++++++++++++ 6 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 src/http/jira.service.ts create mode 100644 src/proxy-page/steps/addJira.ts diff --git a/src/http/http.module.ts b/src/http/http.module.ts index 4aebd88c7..30099bc8b 100644 --- a/src/http/http.module.ts +++ b/src/http/http.module.ts @@ -8,6 +8,7 @@ import { } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import Config from '../config/config'; +import { JiraService } from './jira.service'; @Module({ imports: [ @@ -25,7 +26,8 @@ import Config from '../config/config'; inject: [ConfigService], }), ], - exports: [BaseHttpModule], + providers: [JiraService], + exports: [BaseHttpModule, JiraService], }) export class HttpModule implements OnModuleInit { constructor(private readonly httpService: HttpService) {} diff --git a/src/http/jira.service.ts b/src/http/jira.service.ts new file mode 100644 index 000000000..45f3fcb78 --- /dev/null +++ b/src/http/jira.service.ts @@ -0,0 +1,33 @@ +import { HttpService, Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class JiraService { + baseUrl = 'https://iadc.atlassian.net/rest/api/2'; + + headers = {}; + + constructor( + private httpService: HttpService, + private configService: ConfigService, + ) { + const credentials = `${this.configService.get( + 'confluence.apiUsername', + )}:${this.configService.get('confluence.apiToken')}`; + + this.headers = { + Authorization: `Basic ${credentials}`, + }; + } + + findTickets(jqlSearch: string, fields: string, maxResult = 100) { + const url = `${this.baseUrl}/search?jql=${jqlSearch}&fields=${fields}&maxResults=${maxResult}`; + + return this.httpService + .get(url, { + headers: this.headers, + }) + .toPromise() + .then((res) => res.data); + } +} diff --git a/src/proxy-page/proxy-page.module.ts b/src/proxy-page/proxy-page.module.ts index 32e907263..95a00852b 100644 --- a/src/proxy-page/proxy-page.module.ts +++ b/src/proxy-page/proxy-page.module.ts @@ -3,9 +3,10 @@ import { ConfluenceModule } from '../confluence/confluence.module'; import { ContextService } from '../context/context.service'; import { ProxyPageService } from './proxy-page.service'; import { ProxyPageController } from './proxy-page.controller'; +import { HttpModule } from 'src/http/http.module'; @Module({ - imports: [ConfluenceModule], + imports: [ConfluenceModule, HttpModule], providers: [ProxyPageService, ContextService], controllers: [ProxyPageController], exports: [], diff --git a/src/proxy-page/proxy-page.service.ts b/src/proxy-page/proxy-page.service.ts index 4dac5ffed..3f980893b 100644 --- a/src/proxy-page/proxy-page.service.ts +++ b/src/proxy-page/proxy-page.service.ts @@ -25,6 +25,8 @@ import addHeaderBlog from './steps/addHeaderBlog'; import addSlides from './steps/addSlides'; import addMessageBus from './steps/addMessageBus'; import addCopyLinks from './steps/addCopyLinks'; +import addJira from './steps/addJira'; +import { JiraService } from 'src/http/jira.service'; @Injectable() export class ProxyPageService { @@ -33,6 +35,7 @@ export class ProxyPageService { private config: ConfigService, private confluence: ConfluenceService, private context: ContextService, + private jiraService: JiraService, ) {} private initContext( @@ -73,6 +76,7 @@ export class ProxyPageService { ): Promise { const results = await this.confluence.getPage(spaceKey, pageId); this.initContext(spaceKey, pageId, theme, results); + const addJiraPromise = addJira()(this.context, this.jiraService); fixHtmlHead(this.config)(this.context); fixContentWidth()(this.context); fixLinks(this.config)(this.context); @@ -98,6 +102,7 @@ export class ProxyPageService { addTheme()(this.context); addScrollToTop()(this.context); addCopyLinks()(this.context); + await addJiraPromise; this.context.Close(); return this.context.getHtmlBody(); } diff --git a/src/proxy-page/proxy-page.step.ts b/src/proxy-page/proxy-page.step.ts index 1572eaee3..034c4a1b4 100644 --- a/src/proxy-page/proxy-page.step.ts +++ b/src/proxy-page/proxy-page.step.ts @@ -1,5 +1,6 @@ +import { JiraService } from 'src/http/jira.service'; import { ContextService } from '../context/context.service'; export interface Step { - (context: ContextService): void | Promise; + (context: ContextService, jira?: JiraService): void | Promise; } diff --git a/src/proxy-page/steps/addJira.ts b/src/proxy-page/steps/addJira.ts new file mode 100644 index 000000000..6e65e9c6d --- /dev/null +++ b/src/proxy-page/steps/addJira.ts @@ -0,0 +1,143 @@ +import { ContextService } from '../../context/context.service'; +import { Step } from '../proxy-page.step'; +import cheerio from 'cheerio'; +import { JiraService } from 'src/http/jira.service'; + +export default (): Step => { + return async ( + context: ContextService, + jiraService: JiraService, + ): Promise => { + context.setPerfMark('addJira'); + const $ = context.getCheerioBody(); + + if (!$('.refresh-wiki') || !$('.refresh-wiki').data()) { + context.getPerfMeasure('addJira'); + return; + } + + const wikimarkup: string = $('.refresh-wiki').data().wikimarkup; + const xmlWikimarkup = cheerio.load(wikimarkup, { xmlMode: true }); + const filter = xmlWikimarkup('ac\\:parameter[ac\\:name="jqlQuery"]').text(); + const columns = + xmlWikimarkup('ac\\:parameter[ac\\:name="columns"]').text() + + ',issuetype'; + const maximumIssues = xmlWikimarkup( + 'ac\\:parameter[ac\\:name="maximumIssues"]', + ).text(); + const { issues } = await jiraService.findTickets( + filter, + columns, + Number(maximumIssues), + ); + + const data = []; + issues.forEach((issue) => { + data.push({ + key: { + name: issue.key, + link: `https://iadc.atlassian.net/browse/${issue.key}?src=confmacro`, + }, + t: issue.fields.issuetype?.iconUrl, + summary: { + name: issue.fields.summary, + link: `https://iadc.atlassian.net/browse/${issue.key}?src=confmacro`, + }, + updated: `${new Date(issue.fields.updated).toLocaleString('en-EN', { + year: 'numeric', + month: 'short', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + })}`, + assignee: issue.fields.assignee?.displayName, + pr: issue.fields.priority.iconUrl, + status: { + name: issue.fields.status.name, + color: issue.fields.status.statusCategory.colorName, + }, + resolution: issue.fields.resolution.name, + }); + }); + + // remove the header + $('div[id^="jira-issues-"]').remove(); + + // remove the 'loading...' text + $('div[id^="refresh-issues-loading-"]').remove(); + + // remove the actualize link + $('.refresh-issues-bottom').remove(); + + // add the grid using http://gridjs.io library + $('#Content').append( + '', + '', + '
', + ``, + ); + + context.getPerfMeasure('addJira'); + }; +};