Skip to content

Commit

Permalink
Added feature to integrate aq entities with 3rd party systems (#123)
Browse files Browse the repository at this point in the history
* added initial version of feature that provides abilites to add links to tests from others systems
* added references to test, issue, testrun
* added publish results form
* added workflow status support
* added publish service to propogate statuses to jira
* added ability to add ref on the create issue dialog
* added dialog to add/change reference on publish
* added returning an empty array if entity id was undefined
* added abilities to add/remove ref on the issue create modal
* removed redundant components
* updated changelog and verion rised to 1.3.0
  • Loading branch information
DmitryBogatko authored Feb 28, 2021
1 parent cbc9f0a commit 2b029dc
Show file tree
Hide file tree
Showing 79 changed files with 2,173 additions and 192 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## 1.3.0 (2021-02-26)
- Added feature that allows to link aquality entities (tests, issues and test runs) with 3rd party systems like Jira, Xray, TestRail and etc. In this version only Jira and Xray support has been added.

## 1.2.2 (2021-01-19)
- Fix of an issue with switching between detailed/non-detailed view on the dashboard

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aquality-tracking-ui",
"version": "1.2.2",
"version": "1.3.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand Down
35 changes: 0 additions & 35 deletions src/app/app.component.spec.ts

This file was deleted.

13 changes: 11 additions & 2 deletions src/app/pages/administration/main/administration.child.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import { PermissionsService } from 'src/app/services/permissions/current-permiss
import { UserService } from 'src/app/services/user/user.services';
import { GuardService } from 'src/app/services/guard.service';
import { AdministrationProjectManagerGuard, AdministrationProjectGuard, AdministrationGlobalGuard } from 'src/app/shared/guards/administration-guard.service';

import { IntegrationSystemsComponent } from '../projects/integrations/systems/integration-systems.component';
import { IntegrationsComponent } from '../projects/integrations/integrations/integrations.component';
import { TtsStatusComponent } from '../projects/integrations/tts-status/tts-status.component';
import { WorkflowStatusesComponent } from '../projects/integrations/workflow-statuses/workflow-statuses.component';
import { SystemViewComponent } from '../projects/integrations/system-view/system-view.component';
@NgModule({
imports: [
administrationChildRouting,
Expand All @@ -27,7 +31,12 @@ import { AdministrationProjectManagerGuard, AdministrationProjectGuard, Administ
AdministrationResolutionsComponent,
ImportBodyPatternsComponent,
APITokenComponent,
AdministrationProjectSettingsComponent
AdministrationProjectSettingsComponent,
IntegrationSystemsComponent,
IntegrationsComponent,
TtsStatusComponent,
WorkflowStatusesComponent,
SystemViewComponent
],
providers: [
ProjectService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { APITokenComponent } from '../projects/api-token/api-token.component';
import { AdministrationPermissionsComponent } from '../projects/permissions/administration.permissions.component';
import { AdministrationResolutionsComponent } from '../projects/resolutions/administration.resolutions.component';
import { AdministrationUsersComponent } from '../global/users/administration.users.component';
import { IntegrationsComponent } from '../projects/integrations/integrations/integrations.component'
import {
AdministrationProjectManagerGuard,
AdministrationGlobalGuard,
Expand All @@ -18,11 +19,12 @@ const administrationChildRoutes: Routes = [
{
path: 'project', canActivate: [AdministrationProjectGuard],
children: [
{ path: 'permissions', component: AdministrationPermissionsComponent, canActivate: [AdministrationProjectManagerGuard]},
{ path: 'resolutions', component: AdministrationResolutionsComponent, canActivate: [AdministrationProjectManagerGuard]},
{ path: 'importBodyPatterns', component: ImportBodyPatternsComponent, canActivate: [AdministrationProjectManagerGuard]},
{ path: 'apiToken', component: APITokenComponent, canActivate: [AdministrationProjectManagerGuard]},
{ path: 'projectSettings', component: AdministrationProjectSettingsComponent, canActivate: [AdministrationProjectManagerGuard]}
{ path: 'permissions', component: AdministrationPermissionsComponent, canActivate: [AdministrationProjectManagerGuard] },
{ path: 'resolutions', component: AdministrationResolutionsComponent, canActivate: [AdministrationProjectManagerGuard] },
{ path: 'importBodyPatterns', component: ImportBodyPatternsComponent, canActivate: [AdministrationProjectManagerGuard] },
{ path: 'apiToken', component: APITokenComponent, canActivate: [AdministrationProjectManagerGuard] },
{ path: 'projectSettings', component: AdministrationProjectSettingsComponent, canActivate: [AdministrationProjectManagerGuard] },
{ path: 'integrations', component: IntegrationsComponent, canActivate: [AdministrationProjectManagerGuard] }
]
}, {
path: 'global', canActivate: [AdministrationGlobalGuard],
Expand Down
38 changes: 13 additions & 25 deletions src/app/pages/administration/main/administration.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,28 @@
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Application Settings
</mat-list-item>
<mat-list-item *ngIf="globalEditor" id='users-administration' routerLink="global/users" [routerLinkActiveOptions]="{ exact: false }"
routerLinkActive="active">
<mat-list-item *ngIf="globalEditor" id='users-administration' routerLink="global/users"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Users
</mat-list-item>
</mat-nav-list>

<mat-nav-list>
<div class="sidebar-header">
<span class="sidebar-header">Project</span>
</div>
<mat-list-item *ngIf="localManager" id='projectSettings-administration' routerLink="project/projectSettings"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Settings
</mat-list-item>
<mat-list-item *ngIf="localManager" id='permissions-administration' routerLink="project/permissions"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Permissions
</mat-list-item>
<mat-list-item *ngIf="localManager" id='resolutions-administration' routerLink="project/resolutions"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Resolutions
</mat-list-item>
<mat-list-item *ngIf="localManager" id='body-pattern-administration' routerLink="project/importBodyPatterns"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
Unique Body Patterns
</mat-list-item>
<mat-list-item *ngIf="localManager" id='api-token-administration' routerLink="project/apiToken"
[routerLinkActiveOptions]="{ exact: false }" routerLinkActive="active">
API Token
</mat-list-item>

<div *ngIf="localManager">
<mat-list-item *ngFor="let item of projectSettingItems" id='{{item.id}}'
routerLink="{{item.routerLink}}" [routerLinkActiveOptions]="{ exact: false }"
routerLinkActive="active">
{{item.name}}
</mat-list-item>
</div>
</mat-nav-list>
</div>

<div class="col-sm-10 content">
<router-outlet></router-outlet>
</div>
</div>
</div>
11 changes: 10 additions & 1 deletion src/app/pages/administration/main/administration.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Project } from '../../../shared/models/project';
import { ProjectService } from 'src/app/services/project/project.service';
import { ELocalPermissions, PermissionsService, EGlobalPermissions } from 'src/app/services/permissions/current-permissions.service';
import { UserService } from 'src/app/services/user/user.services';
import { ProjectSettingItem } from '../projects/project-setting-item';

@Component({
templateUrl: './administration.component.html',
Expand All @@ -16,13 +17,21 @@ export class AdministrationComponent implements OnInit {
localManager: boolean;
localEditor: boolean;

projectSettingItems: ProjectSettingItem[] = [
{ id: 'projectSettings-administration', name: 'Settings', routerLink: 'project/projectSettings' },
{ id: 'permissions-administration', name: 'Permissions', routerLink: 'project/permissions' },
{ id: 'resolutions-administration', name: 'Resolutions', routerLink: 'project/resolutions' },
{ id: 'body-pattern-administration', name: 'Unique Body Patterns', routerLink: 'project/importBodyPatterns' },
{ id: 'api-token-administration', name: 'API Token', routerLink: 'project/apiToken' },
{ id: 'integrations-administration', name: 'Integrations', routerLink: 'project/integrations' }
]

constructor(
private projectService: ProjectService,
public userService: UserService,
private permissionsService: PermissionsService
) { }


async ngOnInit() {
this.projects = await this.projectService.getProjects(this.project);
this.globalEditor = await this.permissionsService.hasPermissions([EGlobalPermissions.admin, EGlobalPermissions.manager]);
Expand Down
5 changes: 4 additions & 1 deletion src/app/pages/administration/main/administration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ProjectService } from 'src/app/services/project/project.service';
import { UserService } from 'src/app/services/user/user.services';
import { PermissionsService } from 'src/app/services/permissions/current-permissions.service';
import { GuardService } from 'src/app/services/guard.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
imports: [
Expand All @@ -21,7 +22,9 @@ import { GuardService } from 'src/app/services/guard.service';
UserService,
PermissionsService,
AdministrationGuard,
GuardService
GuardService,
FormsModule,
ReactiveFormsModule
],
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="contatiner">
<div class="row">
<div *ngIf="projects" class="col-md-12 form-row">

<div class="col-md-1 p-2">
Project:
</div>

<div class="col-md-5 p-2">
<lookup-autocomplete id="project-selector" [small]=true placeholder="Select Project"
[allowEmptyValue]="false" [propertiesToShow]="['name']" [array]="projects" [model]="selectedProject"
(modelChange)="onProjectChange($event)"></lookup-autocomplete>
</div>
</div>
</div>

<app-integration-systems *ngIf='isProjectSelected()' [projectId]='selectedProject.id'></app-integration-systems>
</div>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Component, OnInit } from '@angular/core';
import { ProjectService } from 'src/app/services/project/project.service';
import { System } from 'src/app/shared/models/integrations/system';
import { Project } from 'src/app/shared/models/project';

@Component({
selector: 'app-integrations',
templateUrl: './integrations.component.html',
styleUrls: ['./integrations.component.scss']
})
export class IntegrationsComponent implements OnInit {

projects: Project[] = [];
selectedProject: Project;
systems: System[] = [];

constructor(private projectService: ProjectService) {}

ngOnInit(): void {
this.projectService.getProjects({}).then(projects => {
this.projects = projects;
this.selectedProject = projects[0];
});
}

onProjectChange($event: Project) {
this.selectedProject = $event;
}

isProjectSelected(): boolean {
return this.selectedProject != undefined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="container row p-2"></div>
<div class="border bg-light rounded p-2">
<div class="container row">
<div class="col-md-6 p-2">
<div class="row p-2">
<div class="col-md-3 p-2">
{{system.name}}
</div>
<div class="col-md-6 p-2">
<a [href]="system.url">{{system.url}}</a>
</div>
<div class="col-md-3 p-2">
<button id="system-delete" type="submit" class="btn btn-primary btn-sm"
(click)="deleteSystem(system)">Delete</button>
</div>
</div>
</div>
</div>

<div class="container row">
<div class="col-md-12 p-2">
<app-tts-status [projectId]="projectId" [system]="system"></app-tts-status>
</div>
</div>

<div class="container row">
<div class="col-md-12 p-2">
<app-workflow-statuses [projectId]="projectId" [system]="system"></app-workflow-statuses>
</div>
</div>

</div>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { SystemService } from 'src/app/services/integrations/system.service';
import { System } from 'src/app/shared/models/integrations/system';

@Component({
selector: 'app-system-view',
templateUrl: './system-view.component.html',
styleUrls: ['./system-view.component.scss']
})
export class SystemViewComponent implements OnInit {

@Input() projectId: number;
@Input() system: System;
@Output() onDelete = new EventEmitter<System>();

constructor(
private systemService: SystemService
) { }

ngOnInit(): void {
}

deleteSystem(system: System) {
this.systemService.delete(this.projectId, system.id).subscribe(() => {
this.onDelete.emit(system);
})
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<form [formGroup]='addSystemForm' (ngSubmit)="addSystem()">
<div class="form-row">

<div class="col-md-1 p-2">
<select id="system-type" formControlName="type" class="form-control form-control-sm input-lg">
<option *ngFor="let type of systemTypes" [ngValue]="type"
[attr.selected]="systemTypes.length > 0 ? systemTypes[0] : null">
{{type.name}}</option>
</select>
<i class="fa fa-caret-down"></i>
</div>

<div class="col-md-1 p-2">
<select id="system-tts-type" formControlName="ttsType" class="form-control form-control-sm input-lg">
<option *ngFor="let ttsType of ttsTypes" [ngValue]="ttsType"
[attr.selected]="ttsTypes.length > 0 ? ttsTypes[0] : null">
{{ttsType.name}}</option>
</select>
<i class="fa fa-caret-down"></i>
</div>

<div class="col-md-2 p-2">
<input id="system-name" formControlName="name" type="text" trim="blur"
class="form-control form-control-sm" placeholder="Name" required>
</div>

<div class="col-md-3 p-2">
<input id="system-url" formControlName="url" type="text" trim="blur"
class="form-control form-control-sm" placeholder="URL" required>
</div>

<div class="col-md-1 p-2">
<input id="system-username" formControlName="username" type="text" trim="blur"
class="form-control form-control-sm" placeholder="Username" required>
</div>

<div class="col-md-1 p-2">
<input id="system-password" formControlName="password" type="password" trim="blur"
class="form-control form-control-sm" placeholder="Password" required>
</div>

<div class="col-md-2 p-2">
<input id="system-api-token" formControlName="apiToken" type="text" trim="blur"
class="form-control form-control-sm" placeholder="API Token" required>
</div>

<div class="col-md-1 p-2">
<button id="system-add" type="submit" class="btn btn-primary btn-sm"
[disabled]="addSystemForm.invalid">Add</button>
</div>
</div>
</form>

<app-system-view *ngFor="let system of systems"
[projectId]="projectId"
[system]="system"
(onDelete)="deleteSystem($event)">
</app-system-view>
Loading

0 comments on commit 2b029dc

Please sign in to comment.