From 86c2fc14004b70070c1ee76b9cf5b4d8d1555a2d Mon Sep 17 00:00:00 2001 From: laramerdol Date: Sat, 27 Jan 2024 00:12:01 +0300 Subject: [PATCH] Fix issue #104: Code refactoring: Modify the project source code to enable new analysis easily --- .../anomaly-statistic.component.css} | 0 .../anomaly-statistic.component.html} | 0 .../anomaly-statistic.component.ts} | 68 +- .../anomalies/anomaly/anomaly.component.css} | 0 .../anomalies/anomaly/anomaly.component.html} | 0 .../anomalies/anomaly/anomaly.component.ts | 48 ++ .../closed-reopen-ping-pong.component.css | 0 .../closed-reopen-ping-pong.component.html | 0 .../closed-reopen-ping-pong.component.ts | 66 +- .../ignored-bugs/ignored-bugs.component.css | 0 .../ignored-bugs/ignored-bugs.component.html | 0 .../ignored-bugs/ignored-bugs.component.ts | 65 +- ...sing-environment-information.component.css | 0 ...ing-environment-information.component.html | 0 ...ssing-environment-information.component.ts | 65 +- .../missing-priority.component.css | 0 .../missing-priority.component.html | 0 .../missing-priority.component.ts | 65 +- .../no-assignee-resolver-bug.component.css | 0 .../no-assignee-resolver-bug.component.html | 0 .../no-assignee-resolver-bug.component.ts | 66 +- .../no-comment-bugs.component.css | 0 .../no-comment-bugs.component.html | 0 .../no-comment-bugs.component.ts | 65 +- ...no-link-to-bug-fixing-commit.component.css | 0 ...o-link-to-bug-fixing-commit.component.html | 0 .../no-link-to-bug-fixing-commit.component.ts | 69 +- .../not-referenced-duplicates.component.css | 0 .../not-referenced-duplicates.component.html | 0 .../not-referenced-duplicates.component.ts | 64 +- .../reassignment-bug-assignee.component.css | 0 .../reassignment-bug-assignee.component.html | 0 .../reassignment-bug-assignee.component.ts | 66 +- .../same-resolver-closer.component.css | 0 .../same-resolver-closer.component.html | 0 .../same-resolver-closer.component.ts | 69 +- .../unassigned-bugs.component.css | 0 .../unassigned-bugs.component.html | 0 .../unassigned-bugs.component.ts | 80 +- .../collaborators.component.css} | 0 .../collaborators.component.html} | 0 .../collaborators/collaborators.component.ts} | 25 +- .../comment-collaborators.component.css} | 0 .../comment-collaborators.component.html} | 0 .../comment-collaborators.component.ts} | 22 +- .../comment-contributors.component.css} | 0 .../comment-contributors.component.html} | 0 .../comment-contributors.component.ts} | 68 +- .../developer-commits.component.css} | 0 .../developer-commits.component.html} | 0 .../developer-commits.component.ts} | 70 +- .../expert-recommendation.component.css} | 0 .../expert-recommendation.component.html} | 0 .../expert-recommendation.component.ts} | 86 +- .../custom/analyses/query-helper.service.ts | 123 +++ .../reviewer-recommendation.component.css} | 0 .../reviewer-recommendation.component.html} | 0 .../reviewer-recommendation.component.ts} | 202 ++--- .../context-menu-customization.service.ts | 10 +- .../cy-style-customization.service.ts | 0 .../group-customization.service.ts | 6 +- .../navbar-customization.service.ts | 6 +- .../theoretic-properties-custom.service.ts | 6 +- .../toolbar-customization.service.ts | 6 +- src/app/custom/customization.module.ts | 100 +-- .../modal-content.component.spec.ts | 23 - .../modal-content.component.css} | 0 .../modal-content.component.html | 0 .../modal-content/modal-content.component.ts | 0 .../object-queries.component.css} | 0 .../object-queries.component.html | 0 .../object-queries.component.ts | 30 +- .../report-tab/report.component.css | 0 .../report-tab/report.component.html | 0 .../report-tab/report.component.ts | 5 +- .../report-commit/report-commit.component.css | 0 .../report-commit.component.html | 0 .../report-commit/report-commit.component.ts | 4 +- .../report-developer.component.css | 0 .../report-developer.component.html | 0 .../report-developer.component.ts | 4 +- .../report-file/report-file.component.css | 0 .../report-file/report-file.component.html | 0 .../report-file/report-file.component.ts | 4 +- .../report-issue/report-issue.component.css | 0 .../report-issue/report-issue.component.html | 0 .../report-issue/report-issue.component.ts | 4 +- .../report-pr/report-pr.component.css | 0 .../report-pr/report-pr.component.html | 0 .../report-pr/report-pr.component.ts | 4 +- src/app/custom/queries/query-helper.ts | 55 -- .../queries/query2/query2.component.spec.ts | 23 - .../queries/query4/query4.component.spec.ts | 23 - .../custom/queries/query5/query5.component.ts | 24 - .../queries/query7/query7.component.spec.ts | 23 - .../queries/query8/query8.component.spec.ts | 23 - ...heoretic-properties-custom.service.spec.ts | 16 - .../context-menu/context-menu.service.ts | 2 +- src/app/visuall/global-variable.service.ts | 2 +- src/app/visuall/navbar/navbar.component.ts | 2 +- .../map-tab/group-tab/group-tab.component.ts | 2 +- .../object-tab/object-tab.component.html | 18 +- .../object-tab/object-tab.component.ts | 765 +++++++++--------- src/app/visuall/toolbar/toolbar.component.ts | 2 +- 104 files changed, 926 insertions(+), 1718 deletions(-) rename src/app/custom/{queries/query1/query1.component.css => analyses/anomalies/anomaly-statistic/anomaly-statistic.component.css} (100%) rename src/app/custom/{queries/query6/query6.component.html => analyses/anomalies/anomaly-statistic/anomaly-statistic.component.html} (100%) rename src/app/custom/{queries/query6/query6.component.ts => analyses/anomalies/anomaly-statistic/anomaly-statistic.component.ts} (78%) rename src/app/custom/{modal-content/modal-content.component.css => analyses/anomalies/anomaly/anomaly.component.css} (100%) rename src/app/custom/{queries/query5/query5.component.html => analyses/anomalies/anomaly/anomaly.component.html} (100%) create mode 100644 src/app/custom/analyses/anomalies/anomaly/anomaly.component.ts rename src/app/custom/{ => analyses}/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts (78%) rename src/app/custom/{ => analyses}/anomalies/ignored-bugs/ignored-bugs.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/ignored-bugs/ignored-bugs.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/ignored-bugs/ignored-bugs.component.ts (81%) rename src/app/custom/{ => analyses}/anomalies/missing-environment-information/missing-environment-information.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/missing-environment-information/missing-environment-information.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/missing-environment-information/missing-environment-information.component.ts (78%) rename src/app/custom/{ => analyses}/anomalies/missing-priority/missing-priority.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/missing-priority/missing-priority.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/missing-priority/missing-priority.component.ts (78%) rename src/app/custom/{ => analyses}/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts (78%) rename src/app/custom/{ => analyses}/anomalies/no-comment-bugs/no-comment-bugs.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/no-comment-bugs/no-comment-bugs.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/no-comment-bugs/no-comment-bugs.component.ts (77%) rename src/app/custom/{ => analyses}/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts (77%) rename src/app/custom/{ => analyses}/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts (77%) rename src/app/custom/{ => analyses}/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts (79%) rename src/app/custom/{ => analyses}/anomalies/same-resolver-closer/same-resolver-closer.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/same-resolver-closer/same-resolver-closer.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/same-resolver-closer/same-resolver-closer.component.ts (78%) rename src/app/custom/{ => analyses}/anomalies/unassigned-bugs/unassigned-bugs.component.css (100%) rename src/app/custom/{ => analyses}/anomalies/unassigned-bugs/unassigned-bugs.component.html (100%) rename src/app/custom/{ => analyses}/anomalies/unassigned-bugs/unassigned-bugs.component.ts (73%) rename src/app/custom/{object-queries/object-queries.component.css => analyses/collaborators/collaborators.component.css} (100%) rename src/app/custom/{queries/query7/query7.component.html => analyses/collaborators/collaborators.component.html} (100%) rename src/app/custom/{queries/query7/query7.component.ts => analyses/collaborators/collaborators.component.ts} (93%) rename src/app/custom/{queries/query2/query2.component.css => analyses/comment-collaborators/comment-collaborators.component.css} (100%) rename src/app/custom/{queries/query8/query8.component.html => analyses/comment-collaborators/comment-collaborators.component.html} (100%) rename src/app/custom/{queries/query8/query8.component.ts => analyses/comment-collaborators/comment-collaborators.component.ts} (94%) rename src/app/custom/{queries/query4/query4.component.css => analyses/comment-contributors/comment-contributors.component.css} (100%) rename src/app/custom/{queries/query2/query2.component.html => analyses/comment-contributors/comment-contributors.component.html} (100%) rename src/app/custom/{queries/query2/query2.component.ts => analyses/comment-contributors/comment-contributors.component.ts} (79%) rename src/app/custom/{queries/query3/query3.component.css => analyses/developer-commits/developer-commits.component.css} (100%) rename src/app/custom/{queries/query1/query1.component.html => analyses/developer-commits/developer-commits.component.html} (100%) rename src/app/custom/{queries/query1/query1.component.ts => analyses/developer-commits/developer-commits.component.ts} (80%) rename src/app/custom/{queries/query5/query5.component.css => analyses/expert-recommendation/expert-recommendation.component.css} (100%) rename src/app/custom/{queries/query4/query4.component.html => analyses/expert-recommendation/expert-recommendation.component.html} (100%) rename src/app/custom/{queries/query4/query4.component.ts => analyses/expert-recommendation/expert-recommendation.component.ts} (86%) create mode 100644 src/app/custom/analyses/query-helper.service.ts rename src/app/custom/{queries/query6/query6.component.css => analyses/reviewer-recommendation/reviewer-recommendation.component.css} (100%) rename src/app/custom/{queries/query3/query3.component.html => analyses/reviewer-recommendation/reviewer-recommendation.component.html} (100%) rename src/app/custom/{queries/query3/query3.component.ts => analyses/reviewer-recommendation/reviewer-recommendation.component.ts} (83%) rename src/app/custom/{ => customization-service}/context-menu-customization.service.ts (99%) rename src/app/custom/{ => customization-service}/cy-style-customization.service.ts (100%) rename src/app/custom/{ => customization-service}/group-customization.service.ts (92%) rename src/app/custom/{ => customization-service}/navbar-customization.service.ts (95%) rename src/app/custom/{ => customization-service}/theoretic-properties-custom.service.ts (97%) rename src/app/custom/{ => customization-service}/toolbar-customization.service.ts (94%) delete mode 100644 src/app/custom/modal-content/modal-content.component.spec.ts rename src/app/custom/{queries/query7/query7.component.css => object-tab/modal-content/modal-content.component.css} (100%) rename src/app/custom/{ => object-tab}/modal-content/modal-content.component.html (100%) rename src/app/custom/{ => object-tab}/modal-content/modal-content.component.ts (100%) rename src/app/custom/{queries/query8/query8.component.css => object-tab/object-queries-tab/object-queries.component.css} (100%) rename src/app/custom/{object-queries => object-tab/object-queries-tab}/object-queries.component.html (100%) rename src/app/custom/{object-queries => object-tab/object-queries-tab}/object-queries.component.ts (62%) rename src/app/custom/{ => object-tab}/report-tab/report.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/report.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/report.component.ts (92%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-commit/report-commit.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-commit/report-commit.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-commit/report-commit.component.ts (97%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-developer/report-developer.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-developer/report-developer.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-developer/report-developer.component.ts (97%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-file/report-file.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-file/report-file.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-file/report-file.component.ts (97%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-issue/report-issue.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-issue/report-issue.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-issue/report-issue.component.ts (97%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-pr/report-pr.component.css (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-pr/report-pr.component.html (100%) rename src/app/custom/{ => object-tab}/report-tab/sub-report-tabs/report-pr/report-pr.component.ts (98%) delete mode 100644 src/app/custom/queries/query-helper.ts delete mode 100644 src/app/custom/queries/query2/query2.component.spec.ts delete mode 100644 src/app/custom/queries/query4/query4.component.spec.ts delete mode 100644 src/app/custom/queries/query5/query5.component.ts delete mode 100644 src/app/custom/queries/query7/query7.component.spec.ts delete mode 100644 src/app/custom/queries/query8/query8.component.spec.ts delete mode 100644 src/app/custom/theoretic-properties-custom.service.spec.ts diff --git a/src/app/custom/queries/query1/query1.component.css b/src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.css similarity index 100% rename from src/app/custom/queries/query1/query1.component.css rename to src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.css diff --git a/src/app/custom/queries/query6/query6.component.html b/src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.html similarity index 100% rename from src/app/custom/queries/query6/query6.component.html rename to src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.html diff --git a/src/app/custom/queries/query6/query6.component.ts b/src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.ts similarity index 78% rename from src/app/custom/queries/query6/query6.component.ts rename to src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.ts index f16d5b8d..bd0dbd8b 100644 --- a/src/app/custom/queries/query6/query6.component.ts +++ b/src/app/custom/analyses/anomalies/anomaly-statistic/anomaly-statistic.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; export interface Anomaly { @@ -12,11 +12,11 @@ export interface Anomaly { anomalies: string; } @Component({ - selector: 'app-query6', - templateUrl: './query6.component.html', - styleUrls: ['./query6.component.css'] + selector: 'app-anomaly-statistic', + templateUrl: './anomaly-statistic.component.html', + styleUrls: ['./anomaly-statistic.component.css'] }) -export class Query6Component implements OnInit { +export class AnomalyStatisticComponent implements OnInit { tableInput: TableViewInput = { @@ -29,7 +29,7 @@ export class Query6Component implements OnInit { clearTableFilter = new Subject(); count: number; issueList:string[] = []; - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -58,7 +58,7 @@ export class Query6Component implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -83,10 +83,10 @@ export class Query6Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -121,8 +121,8 @@ export class Query6Component implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter =this._h.getDateRangeCQL(); const cql = `MATCH (n : Issue)-[r]-(d:Developer) WHERE n.anomalyCount = ${this.count} and ${dateFilter} RETURN n,r,d` @@ -183,7 +183,7 @@ export class Query6Component implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n:Issue)-[r]-(d:Developer) WHERE ${idFilter} return n,d,r` this._dbService.runQuery(cql, cb); @@ -198,26 +198,6 @@ export class Query6Component implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -253,18 +233,4 @@ export class Query6Component implements OnInit { // For this query, we should specifically bring the related nodes and their 1-neighborhood - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } \ No newline at end of file diff --git a/src/app/custom/modal-content/modal-content.component.css b/src/app/custom/analyses/anomalies/anomaly/anomaly.component.css similarity index 100% rename from src/app/custom/modal-content/modal-content.component.css rename to src/app/custom/analyses/anomalies/anomaly/anomaly.component.css diff --git a/src/app/custom/queries/query5/query5.component.html b/src/app/custom/analyses/anomalies/anomaly/anomaly.component.html similarity index 100% rename from src/app/custom/queries/query5/query5.component.html rename to src/app/custom/analyses/anomalies/anomaly/anomaly.component.html diff --git a/src/app/custom/analyses/anomalies/anomaly/anomaly.component.ts b/src/app/custom/analyses/anomalies/anomaly/anomaly.component.ts new file mode 100644 index 00000000..4d8d101f --- /dev/null +++ b/src/app/custom/analyses/anomalies/anomaly/anomaly.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit } from '@angular/core'; +import { CustomizationModule } from '../../../customization.module'; +import { UnassignedBugsComponent } from '../unassigned-bugs/unassigned-bugs.component'; +import { NoLinkToBugFixingCommitComponent } from '../no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component'; +import { IgnoredBugsComponent } from '../ignored-bugs/ignored-bugs.component'; +import { MissingPriorityComponent } from '../missing-priority/missing-priority.component'; +import { NotReferencedDuplicatesComponent } from '../not-referenced-duplicates/not-referenced-duplicates.component'; +import { MissingEnvironmentInformationComponent } from '../missing-environment-information/missing-environment-information.component'; +import { ReassignmentBugAssigneeComponent } from '../reassignment-bug-assignee/reassignment-bug-assignee.component'; +import { NoCommentBugsComponent } from '../no-comment-bugs/no-comment-bugs.component'; +import { NoAssigneeResolverBugComponent } from '../no-assignee-resolver-bug/no-assignee-resolver-bug.component'; +import { ClosedReopenPingPongComponent } from '../closed-reopen-ping-pong/closed-reopen-ping-pong.component'; +import { SameResolverCloserComponent } from '../same-resolver-closer/same-resolver-closer.component'; +@Component({ + selector: 'app-anomaly', + templateUrl: './anomaly.component.html', + styleUrls: ['./anomaly.component.css'] +}) +export class AnomalyComponent implements OnInit { + anomaly: string; + selectedIdx: number; + + anomalies: { component: any, text: string }[] = [ + { component: UnassignedBugsComponent, text: 'Unassigned Bugs' }, + { component: NoLinkToBugFixingCommitComponent, text: 'No Link to Bug-Fixing Commit' }, + { component: IgnoredBugsComponent, text: 'Ignored Bugs' }, + { component: MissingPriorityComponent, text: 'Missing Priority' }, + { component: NotReferencedDuplicatesComponent, text: 'Not referenced duplicates' }, + { component: MissingEnvironmentInformationComponent, text: 'Missing Environment Information' }, + { component: ReassignmentBugAssigneeComponent, text: 'Reassignment of Bug Assignee' }, + { component: NoCommentBugsComponent, text: 'No comment bugs' }, + { component: NoAssigneeResolverBugComponent, text: 'Non-Assignee Resolver of Bug' }, + { component: ClosedReopenPingPongComponent, text: 'Closed-Reopen Ping Pong' }, + { component: SameResolverCloserComponent, text: 'Same Resolver and Closer' }, + + ]; + + constructor() { + this.selectedIdx = -1; + } + changeAnomaly(event) { + this.selectedIdx = this.anomalies.findIndex(x => x.text == event.target.value); + } + ngOnInit(): void { + this.anomaly = ''; + } + +} diff --git a/src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.css b/src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.css similarity index 100% rename from src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.css rename to src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.css diff --git a/src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.html b/src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.html similarity index 100% rename from src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.html rename to src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.html diff --git a/src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts b/src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts similarity index 78% rename from src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts rename to src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts index c9090172..038d6b2c 100644 --- a/src/app/custom/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts +++ b/src/app/custom/analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component.ts @@ -1,11 +1,11 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -31,7 +31,7 @@ export class ClosedReopenPingPongComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { this.count= this._g.userPrefs?.anomalyDefaultValues?.reopenCount.getValue() ||1; } @@ -55,7 +55,7 @@ export class ClosedReopenPingPongComponent implements OnInit { this.count= this._g.userPrefs?.anomalyDefaultValues?.reopenCount.getValue() ||1; const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; if (isClientSidePagination && cnt > limit4clientSidePaginated) { @@ -75,10 +75,10 @@ export class ClosedReopenPingPongComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -113,8 +113,8 @@ export class ClosedReopenPingPongComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = ` MATCH (n:Issue) WHERE 'Closed reopen ping pong' IN n.anomalyList AND ${dateFilter} @@ -170,7 +170,7 @@ export class ClosedReopenPingPongComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = ` MATCH (n:Issue) @@ -189,26 +189,6 @@ export class ClosedReopenPingPongComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -240,25 +220,5 @@ export class ClosedReopenPingPongComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.css b/src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.css similarity index 100% rename from src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.css rename to src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.css diff --git a/src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.html b/src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.html similarity index 100% rename from src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.html rename to src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.html diff --git a/src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.ts b/src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.ts similarity index 81% rename from src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.ts rename to src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.ts index 80575d8b..e523f385 100644 --- a/src/app/custom/anomalies/ignored-bugs/ignored-bugs.component.ts +++ b/src/app/custom/analyses/anomalies/ignored-bugs/ignored-bugs.component.ts @@ -1,11 +1,11 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -32,7 +32,7 @@ export class IgnoredBugsComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -55,7 +55,7 @@ export class IgnoredBugsComponent implements OnInit { this.time = this._g.userPrefs.anomalyDefaultValues.ignoreBug.getValue() const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; if (isClientSidePagination && cnt > limit4clientSidePaginated) { @@ -76,10 +76,10 @@ export class IgnoredBugsComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -118,8 +118,8 @@ export class IgnoredBugsComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'n.name', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(null, 'n.name', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql =`MATCH (n) WHERE 'Ignored bug' IN n.anomalyList AND ${dateFilter} @@ -199,7 +199,7 @@ export class IgnoredBugsComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n) @@ -218,26 +218,6 @@ export class IgnoredBugsComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -269,23 +249,4 @@ export class IgnoredBugsComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.css b/src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.css similarity index 100% rename from src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.css rename to src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.css diff --git a/src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.html b/src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.html similarity index 100% rename from src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.html rename to src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.html diff --git a/src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.ts b/src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.ts similarity index 78% rename from src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.ts rename to src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.ts index 22e2b655..a31f93fa 100644 --- a/src/app/custom/anomalies/missing-environment-information/missing-environment-information.component.ts +++ b/src/app/custom/analyses/anomalies/missing-environment-information/missing-environment-information.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -30,7 +30,7 @@ export class MissingEnvironmentInformationComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -52,7 +52,7 @@ export class MissingEnvironmentInformationComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -77,10 +77,10 @@ export class MissingEnvironmentInformationComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -113,8 +113,8 @@ export class MissingEnvironmentInformationComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n) WHERE 'Missing Environment Information' IN n.anomalyList AND ${dateFilter} @@ -181,7 +181,7 @@ export class MissingEnvironmentInformationComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n) @@ -200,27 +200,6 @@ export class MissingEnvironmentInformationComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -253,22 +232,4 @@ export class MissingEnvironmentInformationComponent implements OnInit { return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/missing-priority/missing-priority.component.css b/src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.css similarity index 100% rename from src/app/custom/anomalies/missing-priority/missing-priority.component.css rename to src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.css diff --git a/src/app/custom/anomalies/missing-priority/missing-priority.component.html b/src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.html similarity index 100% rename from src/app/custom/anomalies/missing-priority/missing-priority.component.html rename to src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.html diff --git a/src/app/custom/anomalies/missing-priority/missing-priority.component.ts b/src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.ts similarity index 78% rename from src/app/custom/anomalies/missing-priority/missing-priority.component.ts rename to src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.ts index fbc08c09..1a2836e5 100644 --- a/src/app/custom/anomalies/missing-priority/missing-priority.component.ts +++ b/src/app/custom/analyses/anomalies/missing-priority/missing-priority.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -31,7 +31,7 @@ export class MissingPriorityComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -53,7 +53,7 @@ export class MissingPriorityComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -78,10 +78,10 @@ export class MissingPriorityComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -116,8 +116,8 @@ export class MissingPriorityComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue) WHERE 'Missing Priority' IN n.anomalyList AND ${dateFilter} @@ -173,7 +173,7 @@ export class MissingPriorityComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n:Issue) @@ -192,27 +192,6 @@ export class MissingPriorityComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -244,22 +223,4 @@ export class MissingPriorityComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.css b/src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.css similarity index 100% rename from src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.css rename to src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.css diff --git a/src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.html b/src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.html similarity index 100% rename from src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.html rename to src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.html diff --git a/src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts b/src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts similarity index 78% rename from src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts rename to src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts index ca145e15..3ee4a107 100644 --- a/src/app/custom/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts +++ b/src/app/custom/analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -31,7 +31,7 @@ export class NoAssigneeResolverBugComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -53,7 +53,7 @@ export class NoAssigneeResolverBugComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -78,10 +78,10 @@ export class NoAssigneeResolverBugComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -115,8 +115,8 @@ export class NoAssigneeResolverBugComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue)-[r1:ASSIGNED_TO]-(assignee:Developer), (n:Issue)<-[r2:RESOLVED]-(resolver:Developer) @@ -172,7 +172,7 @@ export class NoAssigneeResolverBugComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (resolver:Developer)-[r2:RESOLVED]->(n:Issue)-[r1:ASSIGNED_TO]-(assignee:Developer) @@ -190,27 +190,6 @@ export class NoAssigneeResolverBugComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -243,24 +222,5 @@ export class NoAssigneeResolverBugComponent implements OnInit { return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.css b/src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.css similarity index 100% rename from src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.css rename to src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.css diff --git a/src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.html b/src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.html similarity index 100% rename from src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.html rename to src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.html diff --git a/src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.ts b/src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.ts similarity index 77% rename from src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.ts rename to src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.ts index 3a3ae647..623acb2d 100644 --- a/src/app/custom/anomalies/no-comment-bugs/no-comment-bugs.component.ts +++ b/src/app/custom/analyses/anomalies/no-comment-bugs/no-comment-bugs.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -29,7 +29,7 @@ export class NoCommentBugsComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -51,7 +51,7 @@ export class NoCommentBugsComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -76,10 +76,10 @@ export class NoCommentBugsComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -113,8 +113,8 @@ export class NoCommentBugsComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue) WHERE 'No comment on issue' IN n.anomalyList AND ${dateFilter} @@ -170,7 +170,7 @@ export class NoCommentBugsComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n:Issue) @@ -189,27 +189,6 @@ export class NoCommentBugsComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -242,22 +221,4 @@ export class NoCommentBugsComponent implements OnInit { return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.css b/src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.css similarity index 100% rename from src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.css rename to src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.css diff --git a/src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.html b/src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.html similarity index 100% rename from src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.html rename to src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.html diff --git a/src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts b/src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts similarity index 77% rename from src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts rename to src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts index 09e8d5e4..cb99007c 100644 --- a/src/app/custom/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts +++ b/src/app/custom/analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -31,7 +31,7 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } @@ -53,7 +53,7 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -78,10 +78,10 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -116,8 +116,8 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue) WHERE 'No link to bug fixing commit or pull request' IN n.anomalyList AND ${dateFilter} OPTIONAL MATCH (n)-[r:ASSIGNED_TO]-(d) @@ -186,7 +186,7 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph); } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n:Issue) @@ -205,26 +205,6 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -256,27 +236,4 @@ export class NoLinkToBugFixingCommitComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return `n.createdAt > ${d1} AND n.createdAt < ${d2} `; - } } diff --git a/src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.css b/src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.css similarity index 100% rename from src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.css rename to src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.css diff --git a/src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.html b/src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.html similarity index 100% rename from src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.html rename to src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.html diff --git a/src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts b/src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts similarity index 77% rename from src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts rename to src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts index 64cec193..5777ba1f 100644 --- a/src/app/custom/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts +++ b/src/app/custom/analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -30,7 +30,7 @@ export class NotReferencedDuplicatesComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -52,7 +52,7 @@ export class NotReferencedDuplicatesComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -77,10 +77,10 @@ export class NotReferencedDuplicatesComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -116,8 +116,8 @@ export class NotReferencedDuplicatesComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue) WHERE 'Not Referenced duplicate' IN n.anomalyList AND ${dateFilter} @@ -176,7 +176,7 @@ export class NotReferencedDuplicatesComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = `MATCH (n:Issue) @@ -195,27 +195,6 @@ export class NotReferencedDuplicatesComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -248,21 +227,4 @@ export class NotReferencedDuplicatesComponent implements OnInit { return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.css b/src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.css similarity index 100% rename from src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.css rename to src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.css diff --git a/src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.html b/src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.html similarity index 100% rename from src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.html rename to src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.html diff --git a/src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts b/src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts similarity index 79% rename from src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts rename to src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts index 0cb0831a..d9aafb2b 100644 --- a/src/app/custom/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts +++ b/src/app/custom/analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -30,7 +30,7 @@ export class ReassignmentBugAssigneeComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { this.count= this._g.userPrefs?.anomalyDefaultValues?.assigneeChangeCount.getValue() ||1; } @@ -55,7 +55,7 @@ export class ReassignmentBugAssigneeComponent implements OnInit { this.count= this._g.userPrefs?.anomalyDefaultValues?.assigneeChangeCount.getValue() ||1; const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -80,10 +80,10 @@ export class ReassignmentBugAssigneeComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -118,8 +118,8 @@ export class ReassignmentBugAssigneeComponent implements OnInit { return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = ` MATCH (n:Issue) WHERE 'Reassignment of Bug Assignee' IN n.anomalyList @@ -191,7 +191,7 @@ export class ReassignmentBugAssigneeComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = ` MATCH (n:Issue) WHERE 'Reassignment of Bug Assignee' IN n.anomalyList and ${idFilter} @@ -209,27 +209,6 @@ export class ReassignmentBugAssigneeComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -261,24 +240,5 @@ export class ReassignmentBugAssigneeComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.css b/src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.css similarity index 100% rename from src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.css rename to src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.css diff --git a/src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.html b/src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.html similarity index 100% rename from src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.html rename to src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.html diff --git a/src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.ts b/src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.ts similarity index 78% rename from src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.ts rename to src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.ts index e1191487..9b9070ca 100644 --- a/src/app/custom/anomalies/same-resolver-closer/same-resolver-closer.component.ts +++ b/src/app/custom/analyses/anomalies/same-resolver-closer/same-resolver-closer.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -31,7 +31,7 @@ export class SameResolverCloserComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -53,7 +53,7 @@ export class SameResolverCloserComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; if (isClientSidePagination && cnt > limit4clientSidePaginated) { @@ -74,10 +74,10 @@ export class SameResolverCloserComponent implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); const ui2Db = { 'Developer': 'Developer' ,'Issues': 'Issues','Count': 'Count'}; - const orderExpr = getOrderByExpression4Query(filter, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -109,8 +109,8 @@ export class SameResolverCloserComponent implements OnInit { } const ui2Db = { 'Developer': 'Developer' ,'Issues': 'Issues','Count': 'Count'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = ` MATCH (n:Developer)-[r1:RESOLVED ]->(issue:Issue) MATCH (n)-[r2:CLOSED]->(issue) @@ -188,10 +188,10 @@ export class SameResolverCloserComponent implements OnInit { edegeIds.push(edge.id) }); } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = { 'Developer': 'Developer' ,'Issues': 'Issues','Count': 'Count'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = ` MATCH (n:Developer)-[r1:RESOLVED ]->(issue:Issue) MATCH (n)-[r2:CLOSED]->(issue) @@ -209,26 +209,6 @@ export class SameResolverCloserComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -261,23 +241,4 @@ export class SameResolverCloserComponent implements OnInit { return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= issue.createdAt AND ${d1}<= issue.closeDate`; - } - } \ No newline at end of file diff --git a/src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.css b/src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.css similarity index 100% rename from src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.css rename to src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.css diff --git a/src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.html b/src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.html similarity index 100% rename from src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.html rename to src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.html diff --git a/src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.ts b/src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.ts similarity index 73% rename from src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.ts rename to src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.ts index 3c9b0ef9..a68ae7d0 100644 --- a/src/app/custom/anomalies/unassigned-bugs/unassigned-bugs.component.ts +++ b/src/app/custom/analyses/anomalies/unassigned-bugs/unassigned-bugs.component.ts @@ -1,13 +1,12 @@ import { Component, OnInit } from '@angular/core'; -import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; -import { CytoscapeService } from '../../../visuall/cytoscape.service'; -import { GlobalVariableService } from '../../../visuall/global-variable.service'; -import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; +import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { CytoscapeService } from '../../../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; -import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; export interface Anomaly { Issue: string; @@ -20,8 +19,6 @@ export interface Anomaly { }) export class UnassignedBugsComponent implements OnInit { - - tableInput: TableViewInput = { columns: ['issue','resolver'], results: [], results2: [],isEmphasizeOnHover: true, tableTitle: 'Query Results', classNameOfObjects: 'Issue', isShowExportAsCSV: true, resultCnt: 0, currPage: 1, pageSize: 0, isLoadGraph: false, isMergeGraph: true, isNodeData: true, isSelect: false @@ -31,7 +28,7 @@ export class UnassignedBugsComponent implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -53,35 +50,28 @@ export class UnassignedBugsComponent implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData =this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; - if (isClientSidePagination && cnt > limit4clientSidePaginated) { - cnt = limit4clientSidePaginated; - + cnt = limit4clientSidePaginated; } if (isClientSidePagination) { - this.fillTable(this.filterTableResponse(processedTableData, filter), cnt); - + this.fillTable(this.filterTableResponse(processedTableData, filter), cnt); } else { - this.fillTable(processedTableData, cnt); - + this.fillTable(processedTableData, cnt); } if (!filter) { this.tableResponse = processedTableData; - } }; if (isClientSidePagination && filter) { this.fillTable(this.filterTableResponse(this.tableResponse, filter), null); return; } - const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'id', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr = this._h.getOrderByExpression4Query(filter, 'issue', 'asc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -113,10 +103,7 @@ export class UnassignedBugsComponent implements OnInit { this._cyService.loadElementsFromDatabase(this.filterGraphResponse(this.graphResponse), this.tableInput.isMergeGraph); return; } - const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); - + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Issue) WHERE 'Unassigned issue' IN n.anomalyList AND ${dateFilter} OPTIONAL MATCH (n)-[r:RESOLVED]-(d) return n,d,r` @@ -125,7 +112,6 @@ export class UnassignedBugsComponent implements OnInit { } private filterGraphResponse(x: GraphResponse): GraphResponse { const r: GraphResponse = { nodes: [], edges: x.edges }; - const nodeIdDict = {}; for (let i = 0; i < this.tableInput.results.length; i++) { nodeIdDict[this.tableInput.results[i][0].val] = true; @@ -170,8 +156,7 @@ export class UnassignedBugsComponent implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); - const ui2Db = {'issue': 'n.name'}; + const idFilter = this._h.buildIdFilter(e.dbIds); const cql = `MATCH(n:Issue) WHERE 'Unassigned issue' IN n.anomalyList AND ${idFilter} @@ -188,26 +173,6 @@ export class UnassignedBugsComponent implements OnInit { } } - // zip paralel arrays - private preprocessTableData(data): Anomaly[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Anomaly[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Anomaly) - } - return objArr; - } - private filterTableResponse(x: Anomaly[], filter: TableFiltering): Anomaly[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { const skip = filter && filter.skip ? filter.skip : 0; @@ -239,22 +204,5 @@ export class UnassignedBugsComponent implements OnInit { const skip = filter && filter.skip ? filter.skip : 0; return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; - } } diff --git a/src/app/custom/object-queries/object-queries.component.css b/src/app/custom/analyses/collaborators/collaborators.component.css similarity index 100% rename from src/app/custom/object-queries/object-queries.component.css rename to src/app/custom/analyses/collaborators/collaborators.component.css diff --git a/src/app/custom/queries/query7/query7.component.html b/src/app/custom/analyses/collaborators/collaborators.component.html similarity index 100% rename from src/app/custom/queries/query7/query7.component.html rename to src/app/custom/analyses/collaborators/collaborators.component.html diff --git a/src/app/custom/queries/query7/query7.component.ts b/src/app/custom/analyses/collaborators/collaborators.component.ts similarity index 93% rename from src/app/custom/queries/query7/query7.component.ts rename to src/app/custom/analyses/collaborators/collaborators.component.ts index d2599486..53b96199 100644 --- a/src/app/custom/queries/query7/query7.component.ts +++ b/src/app/custom/analyses/collaborators/collaborators.component.ts @@ -4,21 +4,21 @@ import { CytoscapeService } from '../../../visuall/cytoscape.service'; import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { GENERIC_TYPE, LONG_MAX, LONG_MIN } from 'src/app/visuall/constants'; import { GroupingOptionTypes, TimebarGraphInclusionTypes } from 'src/app/visuall/user-preference'; -import { GroupCustomizationService } from 'src/app/custom/group-customization.service'; +import { GroupCustomizationService } from 'src/app/custom/customization-service/group-customization.service'; export interface Collaborator { Name: string; Collaboration: number; } @Component({ - selector: 'app-query7', - templateUrl: './query7.component.html', - styleUrls: ['./query7.component.css'] + selector: 'app-collaborators', + templateUrl: './collaborators.component.html', + styleUrls: ['./collaborators.component.css'] }) -export class Query7Component implements OnInit { +export class CollaboratorsComponent implements OnInit { developer: String = ""; developerId : String = ""; @@ -34,7 +34,8 @@ export class Query7Component implements OnInit { graphResponse = null; clearTableFilter = new Subject(); number: Number = 3; - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _group: GroupCustomizationService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, + private _group: GroupCustomizationService, private _h: QueryHelperService) { } ngOnInit() { @@ -95,9 +96,9 @@ export class Query7Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); const ui2Db = {'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'collaboration', 'desc', ui2Db); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'collaboration', 'desc', ui2Db); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -162,9 +163,9 @@ export class Query7Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); const ui2Db = {'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); const f1 = this.dateFilterFromUserPref('n', true); const f2 = this.dateFilterFromUserPref('issue', true); const f3 = this.dateFilterFromUserPref('d1', true); @@ -241,7 +242,7 @@ export class Query7Component implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql = diff --git a/src/app/custom/queries/query2/query2.component.css b/src/app/custom/analyses/comment-collaborators/comment-collaborators.component.css similarity index 100% rename from src/app/custom/queries/query2/query2.component.css rename to src/app/custom/analyses/comment-collaborators/comment-collaborators.component.css diff --git a/src/app/custom/queries/query8/query8.component.html b/src/app/custom/analyses/comment-collaborators/comment-collaborators.component.html similarity index 100% rename from src/app/custom/queries/query8/query8.component.html rename to src/app/custom/analyses/comment-collaborators/comment-collaborators.component.html diff --git a/src/app/custom/queries/query8/query8.component.ts b/src/app/custom/analyses/comment-collaborators/comment-collaborators.component.ts similarity index 94% rename from src/app/custom/queries/query8/query8.component.ts rename to src/app/custom/analyses/comment-collaborators/comment-collaborators.component.ts index a1df8f54..ee1f0d67 100644 --- a/src/app/custom/queries/query8/query8.component.ts +++ b/src/app/custom/analyses/comment-collaborators/comment-collaborators.component.ts @@ -4,7 +4,7 @@ import { CytoscapeService } from '../../../visuall/cytoscape.service'; import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; +import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { GENERIC_TYPE, LONG_MAX, LONG_MIN } from 'src/app/visuall/constants'; import { TimebarGraphInclusionTypes } from 'src/app/visuall/user-preference'; @@ -14,11 +14,11 @@ export interface Collaborator { CollaborationScore: number; } @Component({ - selector: 'app-query8', - templateUrl: './query8.component.html', - styleUrls: ['./query8.component.css'] + selector: 'app-comment-collaborators', + templateUrl: './comment-collaborators.component.html', + styleUrls: ['./comment-collaborators.component.css'] }) -export class Query8Component implements OnInit { +export class CommentCollaboratorsComponent implements OnInit { developer: String = ""; developerId : String = ""; @@ -34,7 +34,7 @@ export class Query8Component implements OnInit { graphResponse = null; clearTableFilter = new Subject(); number: Number = 3; - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -95,9 +95,9 @@ export class Query8Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); const ui2Db = {'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); const f1 = this.dateFilterFromUserPref('n', true); const f2 = this.dateFilterFromUserPref('issue', true); const f3 = this.dateFilterFromUserPref('d1', true); @@ -165,9 +165,9 @@ export class Query8Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Developer'], isIgnoreCase); const ui2Db = {'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'collaborationScore', 'desc', ui2Db); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'collaborationScore', 'desc', ui2Db); const f1 = this.dateFilterFromUserPref('n', true); const f2 = this.dateFilterFromUserPref('issue', true); const f3 = this.dateFilterFromUserPref('d1', true); @@ -245,7 +245,7 @@ export class Query8Component implements OnInit { const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = {'issue': 'n.name'}; const cql=` diff --git a/src/app/custom/queries/query4/query4.component.css b/src/app/custom/analyses/comment-contributors/comment-contributors.component.css similarity index 100% rename from src/app/custom/queries/query4/query4.component.css rename to src/app/custom/analyses/comment-contributors/comment-contributors.component.css diff --git a/src/app/custom/queries/query2/query2.component.html b/src/app/custom/analyses/comment-contributors/comment-contributors.component.html similarity index 100% rename from src/app/custom/queries/query2/query2.component.html rename to src/app/custom/analyses/comment-contributors/comment-contributors.component.html diff --git a/src/app/custom/queries/query2/query2.component.ts b/src/app/custom/analyses/comment-contributors/comment-contributors.component.ts similarity index 79% rename from src/app/custom/queries/query2/query2.component.ts rename to src/app/custom/analyses/comment-contributors/comment-contributors.component.ts index 8ed0e7eb..94629df6 100644 --- a/src/app/custom/queries/query2/query2.component.ts +++ b/src/app/custom/analyses/comment-contributors/comment-contributors.component.ts @@ -4,7 +4,7 @@ import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; - import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../../queries/query-helper'; + import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid } from 'src/app/visuall/constants'; @@ -13,11 +13,11 @@ Count: string; } @Component({ - selector: 'app-query2', - templateUrl: './query2.component.html', - styleUrls: ['./query2.component.css'] + selector: 'app-comment-contributors', + templateUrl: './comment-contributors.component.html', + styleUrls: ['./comment-contributors.component.css'] }) - export class Query2Component implements OnInit { + export class CommentContributorsComponent implements OnInit { tableInput: TableViewInput = { columns: ['developer','count'], results: [], results2: [],isEmphasizeOnHover: true, tableTitle: 'Query Results', classNameOfObjects: 'Issue', isShowExportAsCSV: true, resultCnt: 0, currPage: 1, pageSize: 0, isLoadGraph: false, isMergeGraph: true, isNodeData: true, isSelect: false @@ -27,7 +27,7 @@ graphResponse = null; clearTableFilter = new Subject(); issue = "" - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { } ngOnInit() { @@ -53,7 +53,7 @@ loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -78,10 +78,10 @@ return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['Issue'], isIgnoreCase); const ui2Db = {'issue': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -119,8 +119,8 @@ return; } const ui2Db = { 'issue': 'n.name'}; - const orderExpr = getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h.getOrderByExpression4Query(null, 'Count', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (issue:Issue {name:'${this.issue}'}) WITH issue, [cmtr in issue.commenterList] AS commenterList @@ -165,8 +165,8 @@ const cb = (x) => { this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) } - const idFilter = buildIdFilter(e.dbIds); - const dateFilter = this.getDateRangeCQL(); + const idFilter = this._h. buildIdFilter(e.dbIds); + const dateFilter = this._h.getDateRangeCQL(); const ui2Db = {'issue': 'n.name'}; const cql =`MATCH (issue:Issue {name:'${this.issue}'}) WITH issue, [cmtr in issue.commenterList] AS commenterList @@ -188,27 +188,7 @@ this.loadGraph(skip, filter); } } - - // zip paralel arrays - private preprocessTableData(data): Developer[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: Developer[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as Developer) - } - - return objArr; - } + private filterTableResponse(x: Developer[], filter: TableFiltering): Developer[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { @@ -242,24 +222,6 @@ return filtered.slice(skip, skip + this._g.userPrefs.dataPageSize.getValue()); } - // tableInput is already filtered. Use that to filter graph elements. - // For this query, we should specifically bring the related nodes and their 1-neighborhood - - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1 ); - const c = new Date(d2); - const b = a.toISOString() - const d =c.toISOString() - - return ` ${d2} >= n.start AND ${d1}<= n.end`; - } } \ No newline at end of file diff --git a/src/app/custom/queries/query3/query3.component.css b/src/app/custom/analyses/developer-commits/developer-commits.component.css similarity index 100% rename from src/app/custom/queries/query3/query3.component.css rename to src/app/custom/analyses/developer-commits/developer-commits.component.css diff --git a/src/app/custom/queries/query1/query1.component.html b/src/app/custom/analyses/developer-commits/developer-commits.component.html similarity index 100% rename from src/app/custom/queries/query1/query1.component.html rename to src/app/custom/analyses/developer-commits/developer-commits.component.html diff --git a/src/app/custom/queries/query1/query1.component.ts b/src/app/custom/analyses/developer-commits/developer-commits.component.ts similarity index 80% rename from src/app/custom/queries/query1/query1.component.ts rename to src/app/custom/analyses/developer-commits/developer-commits.component.ts index a7449671..eafb2ce6 100644 --- a/src/app/custom/queries/query1/query1.component.ts +++ b/src/app/custom/analyses/developer-commits/developer-commits.component.ts @@ -4,7 +4,7 @@ import { CytoscapeService } from '../../../visuall/cytoscape.service'; import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../query-helper'; +import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; //This query is for @@ -13,12 +13,12 @@ export interface CommitData { commit: string; } @Component({ - selector: 'app-query1', - templateUrl: './query1.component.html', - styleUrls: ['./query1.component.css'] + selector: 'app-developer-commits', + templateUrl: './developer-commits.component.html', + styleUrls: ['./developer-commits.component.css'] }) -export class Query1Component implements OnInit { +export class DeveloperCommitsComponent implements OnInit { developer: string; developers: string[]; tableInput: TableViewInput = { @@ -30,7 +30,7 @@ export class Query1Component implements OnInit { graphResponse = null; clearTableFilter = new Subject(); - constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService) { + constructor(private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _h: QueryHelperService) { this.developers = []; } @@ -43,7 +43,7 @@ export class Query1Component implements OnInit { } setTimeout(() => { - const dateFilter = this.getDateRangeCQL(); + const dateFilter = this._h.getDateRangeCQL(); this._dbService.runQuery(`MATCH (n:Developer) RETURN distinct n.name`, (x) => this.fillGenres(x), DbResponseType.table); }, 5); let name = "" @@ -68,7 +68,7 @@ export class Query1Component implements OnInit { loadTable(skip: number, filter?: TableFiltering) { const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableData(x,['id'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; @@ -93,10 +93,10 @@ export class Query1Component implements OnInit { return; } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['n.name'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['n.name'], isIgnoreCase); const ui2Db = { 'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'n.name', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'n.name', 'desc', ui2Db); + const dateFilter =this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -133,10 +133,10 @@ export class Query1Component implements OnInit { } const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['n.name'], isIgnoreCase); + const txtCondition =this._h.getQueryCondition4TxtFilter(filter, ['n.name'], isIgnoreCase); const ui2Db = { 'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(filter, 'n.name', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(filter, 'n.name', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -182,10 +182,10 @@ export class Query1Component implements OnInit { getDataForQueryResult(e: TableRowMeta) { const cb = (x) => this._cyService.loadElementsFromDatabase(x, this.tableInput.isMergeGraph) - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h. buildIdFilter(e.dbIds); const ui2Db = { 'name': 'n.name' }; - const orderExpr = getOrderByExpression4Query(null, 'n.name', 'desc', ui2Db); - const dateFilter = this.getDateRangeCQL(); + const orderExpr =this._h. getOrderByExpression4Query(null, 'n.name', 'desc', ui2Db); + const dateFilter = this._h.getDateRangeCQL(); const cql = `MATCH (n:Commit) <-[r:COMMITTED]-(d:Developer {name: '${this.developer}' }) @@ -203,27 +203,6 @@ export class Query1Component implements OnInit { this.loadGraph(skip, filter); } } - // zip paralel arrays - private preprocessTableData(data): CommitData[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['id'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data; - const objArr: CommitData[] = []; - for (let i = 0; i < rawData.length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - obj[uiColumns[j]] = rawData[i][columnMapping[j]]; - } - objArr.push(obj as CommitData) - } - return objArr; - } - - private filterTableResponse(x: CommitData[], filter: TableFiltering): CommitData[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { @@ -277,19 +256,4 @@ export class Query1Component implements OnInit { } return r; } - - private getDateRangeCQL() { - const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); - if (!isLimit) { - return 'TRUE'; - } - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const a = new Date(d1); - const c = new Date(d2); - const b = a.toISOString() - const d = c.toISOString() - - return ` ${d2} >= n.createdAt AND ${d1}<= n.end`; - } } diff --git a/src/app/custom/queries/query5/query5.component.css b/src/app/custom/analyses/expert-recommendation/expert-recommendation.component.css similarity index 100% rename from src/app/custom/queries/query5/query5.component.css rename to src/app/custom/analyses/expert-recommendation/expert-recommendation.component.css diff --git a/src/app/custom/queries/query4/query4.component.html b/src/app/custom/analyses/expert-recommendation/expert-recommendation.component.html similarity index 100% rename from src/app/custom/queries/query4/query4.component.html rename to src/app/custom/analyses/expert-recommendation/expert-recommendation.component.html diff --git a/src/app/custom/queries/query4/query4.component.ts b/src/app/custom/analyses/expert-recommendation/expert-recommendation.component.ts similarity index 86% rename from src/app/custom/queries/query4/query4.component.ts rename to src/app/custom/analyses/expert-recommendation/expert-recommendation.component.ts index a4d92aa5..298f9d75 100644 --- a/src/app/custom/queries/query4/query4.component.ts +++ b/src/app/custom/analyses/expert-recommendation/expert-recommendation.component.ts @@ -6,14 +6,14 @@ import { CytoscapeService } from '../../../visuall/cytoscape.service'; import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../query-helper'; +import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid, readTxtFile, isJson } from 'src/app/visuall/constants'; import { GroupingOptionTypes } from '../../../visuall/user-preference'; -import { GroupCustomizationService } from 'src/app/custom/group-customization.service'; +import { GroupCustomizationService } from 'src/app/custom/customization-service/group-customization.service'; import { GENERIC_TYPE, LONG_MAX, LONG_MIN } from 'src/app/visuall/constants'; import { TimebarGraphInclusionTypes } from 'src/app/visuall/user-preference'; -import { TheoreticPropertiesCustomService } from 'src/app/custom/theoretic-properties-custom.service' +import { TheoreticPropertiesCustomService } from 'src/app/custom/customization-service/theoretic-properties-custom.service' export interface DeveloperData { name: string; score: number; @@ -21,11 +21,11 @@ export interface DeveloperData { } @Component({ - selector: 'app-query4', - templateUrl: './query4.component.html', - styleUrls: ['./query4.component.css'] + selector: 'app-expert-recommendation', + templateUrl: './expert-recommendation.component.html', + styleUrls: ['./expert-recommendation.component.css'] }) -export class Query4Component implements OnInit { +export class ExpertRecommendationComponent implements OnInit { githubHttpOptions: any; authentication: any; file: string; @@ -60,7 +60,8 @@ export class Query4Component implements OnInit { currNodeSize = this.NODE_SIZE; algorithm = null; - constructor(private http: HttpClient, private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _group: GroupCustomizationService, private _gt: TheoreticPropertiesCustomService) { + constructor(private http: HttpClient, private _dbService: Neo4jDb, private _cyService: CytoscapeService, + private _g: GlobalVariableService, private _group: GroupCustomizationService, private _gt: TheoreticPropertiesCustomService, private _h: QueryHelperService) { this.files = []; this.possibleDevelopers = []; this.developers = []; @@ -111,7 +112,7 @@ export class Query4Component implements OnInit { this.developers = x.data[0][0] this.scores = x.data[0][2] - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableDataZip(x,['elementId'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; if (isClientSidePagination && cnt > limit4clientSidePaginated) { @@ -135,20 +136,12 @@ export class Query4Component implements OnInit { this.fillTable(this.filterTableResponse(this.tableResponse, filter), null); return; } - //const idFilter = buildIdFilter(e.dbIds); + //const idFilter = this._h. buildIdFilter(e.dbIds); const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['score'], isIgnoreCase); + const txtCondition = this._h.getQueryCondition4TxtFilter(filter, ['score'], isIgnoreCase); const ui2Db = { 'name': 'name', "score": "score" }; - const orderExpr = getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); - const f1 = this.dateFilterFromUserPref('a', true); - const f2 = this.dateFilterFromUserPref('b', true); - let f = ''; - if (f1.length > 0) { - f += ' AND ' + f1.substr(5); - } - if (f2.length > 0) { - f += f2; - } + const orderExpr = this._h.getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); + let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -299,9 +292,9 @@ export class Query4Component implements OnInit { } } - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h.buildIdFilter(e.dbIds); const ui2Db = { 'Title': 'n.primary_title' }; - const orderExpr = getOrderByExpression4Query(null, 'score', 'desc', ui2Db); + const orderExpr = this._h.getOrderByExpression4Query(null, 'score', 'desc', ui2Db); const pageSize = this.getPageSize4Backend(); const orderBy = 'score'; let orderDir = 0; @@ -472,51 +465,4 @@ export class Query4Component implements OnInit { s += '}' return s; } - - private dateFilterFromUserPref(varName: string, isNode: boolean): string { - if (!this._g.userPrefs.isLimitDbQueries2range.getValue()) { - return ''; - } - let s = ''; - let keys = []; - - if (isNode) { - keys = Object.keys(this._g.appDescription.getValue().objects); - } else { - keys = Object.keys(this._g.appDescription.getValue().relations); - } - - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const inclusionType = this._g.userPrefs.objectInclusionType.getValue(); - const mapping = this._g.appDescription.getValue().timebarDataMapping; - - if (!mapping || Object.keys(mapping).length < 1) { - return ''; - } - - s = ' AND ('; - for (const k of keys) { - if (!mapping[k]) { - continue; - } - const p1 = `COALESCE(${varName}.${mapping[k].begin_datetime}, ${LONG_MIN})`; - const p2 = `COALESCE(${varName}.${mapping[k].end_datetime}, ${LONG_MAX})`; - const bothNull = `(${varName}.${mapping[k].end_datetime} IS NULL AND ${varName}.${mapping[k].begin_datetime} IS NULL)` - if (inclusionType == TimebarGraphInclusionTypes.overlaps) { - s += `(${bothNull} OR (${p1} <= ${d2} AND ${p2} >= ${d1})) AND`; - } else if (inclusionType == TimebarGraphInclusionTypes.contains) { - s += `(${bothNull} OR (${d1} <= ${p1} AND ${d2} >= ${p2})) AND`; - } else if (inclusionType == TimebarGraphInclusionTypes.contained_by) { - s += `(${bothNull} OR (${p1} <= ${d1} AND ${p2} >= ${d2})) AND`; - } - - } - s = s.slice(0, -4) - s += ')' - return s; - } - - - } \ No newline at end of file diff --git a/src/app/custom/analyses/query-helper.service.ts b/src/app/custom/analyses/query-helper.service.ts new file mode 100644 index 00000000..c375bb22 --- /dev/null +++ b/src/app/custom/analyses/query-helper.service.ts @@ -0,0 +1,123 @@ +import { Injectable } from '@angular/core'; +import { TableFiltering } from '../../shared/table-view/table-view-types'; +import { GlobalVariableService } from '../../visuall/global-variable.service'; +import { CytoscapeService } from '../../visuall/cytoscape.service'; + +@Injectable({ + providedIn: 'root' +}) +export class QueryHelperService { + + + constructor(private _g: GlobalVariableService, private _cyService: CytoscapeService) {} + +getQueryCondition4TxtFilter(filter: TableFiltering, cols: string[], isIgnoreCase: boolean): string { + if (filter == null || filter.txt.length < 1) { + return ''; + } + let s = ''; + + for (let i = 0; i < cols.length; i++) { + if (isIgnoreCase) { + s += ` LOWER(toString(${cols[i]})) CONTAINS LOWER('${filter.txt}') OR `; + } else { + s += ` toString(${cols[i]}) CONTAINS '${filter.txt}' OR `; + } + } + s = s.slice(0, -3); + s = 'AND (' + s + ')'; + return s; +} + + + +getOrderByExpression4Query(filter: TableFiltering, orderBy: string, orderDirection: string, ui2Db: any) { + if (filter != null && filter.orderDirection.length > 0 && filter.orderBy.length > 0) { + orderBy = ui2Db[filter.orderBy]; + orderDirection = filter.orderDirection; + } + return orderBy + ' ' + orderDirection; +} + +buildIdFilter(ids: string[] | number[], hasEnd = false, isEdgeQuery = false): string { + if (ids === undefined) { + return ''; + } + let varName = 'n'; + if (isEdgeQuery) { + varName = 'e'; + } + let cql = ''; + if (ids.length > 0) { + cql = '('; + } + for (let i = 0; i < ids.length; i++) { + cql += `ElementId(${varName})='${ids[i]}' OR ` + } + + if (ids.length > 0) { + cql = cql.slice(0, -4); + + cql += ')'; + if (hasEnd) { + cql += ' AND '; + } + } + return cql; +} + +preprocessTableDataZip(data, uiColumns): any[] { + console.log(data) + const dbColumns = data.columns as string[]; + let columnMapping = []; + for (let i = 0; i < uiColumns.length; i++) { + columnMapping.push(dbColumns.indexOf(uiColumns[i])); + } + const rawData = data.data[0]; + const objArr: any[] = []; + for (let i = 0; i < rawData[0].length; i++) { + const obj = {}; + for (let j = 0; j < columnMapping.length; j++) { + obj[uiColumns[j]] = rawData[columnMapping[j]][i]; + } + objArr.push(obj as any) + } + return objArr; +} + +preprocessTableData(data, uiColumns): any[] { + const dbColumns = data.columns as string[]; + let columnMapping = []; + for (let i = 0; i < uiColumns.length; i++) { + columnMapping.push(dbColumns.indexOf(uiColumns[i])); + } + const rawData = data.data; + const objArr: any[] = []; + for (let i = 0; i < rawData.length; i++) { + const obj = {}; + for (let j = 0; j < columnMapping.length; j++) { + obj[uiColumns[j]] = rawData[i][columnMapping[j]]; + } + objArr.push(obj as any) + } + return objArr; +} + + +getDateRangeCQL() { + + const isLimit = this._g.userPrefs.isLimitDbQueries2range.getValue(); + if (!isLimit) { + return 'TRUE'; + } + const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); + const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); + const a = new Date(d1); + const c = new Date(d2); + const b = a.toISOString() + const d = c.toISOString() + + return ` ${d2} >= n.createdAt AND ${d1}<= n.closeDate`; +} + +} \ No newline at end of file diff --git a/src/app/custom/queries/query6/query6.component.css b/src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.css similarity index 100% rename from src/app/custom/queries/query6/query6.component.css rename to src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.css diff --git a/src/app/custom/queries/query3/query3.component.html b/src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.html similarity index 100% rename from src/app/custom/queries/query3/query3.component.html rename to src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.html diff --git a/src/app/custom/queries/query3/query3.component.ts b/src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.ts similarity index 83% rename from src/app/custom/queries/query3/query3.component.ts rename to src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.ts index be7fe5c7..8e4ba7b8 100644 --- a/src/app/custom/queries/query3/query3.component.ts +++ b/src/app/custom/analyses/reviewer-recommendation/reviewer-recommendation.component.ts @@ -7,28 +7,25 @@ import { GlobalVariableService } from '../../../visuall/global-variable.service' import { formatNumber } from '@angular/common'; import { TableViewInput, TableDataType, TableFiltering, TableRowMeta, TableData } from '../../../shared/table-view/table-view-types'; import { Subject } from 'rxjs'; -import { buildIdFilter, getOrderByExpression4Query, getQueryCondition4TxtFilter } from '../query-helper'; +import { QueryHelperService} from '../query-helper.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { getCyStyleFromColorAndWid, readTxtFile, isJson } from 'src/app/visuall/constants'; import { GroupingOptionTypes } from '../../../visuall/user-preference'; -import { GroupCustomizationService } from 'src/app/custom/group-customization.service'; -import { debounce2, debounce, COLLAPSED_EDGE_CLASS, mapColor } from 'src/app/visuall/constants'; -import { TheoreticPropertiesCustomService } from 'src/app/custom/theoretic-properties-custom.service' -import { GENERIC_TYPE, LONG_MAX, LONG_MIN } from 'src/app/visuall/constants'; -import { TimebarGraphInclusionTypes } from 'src/app/visuall/user-preference'; +import { GroupCustomizationService } from 'src/app/custom/customization-service/group-customization.service'; +import { TheoreticPropertiesCustomService } from 'src/app/custom/customization-service/theoretic-properties-custom.service' import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { ModalContentComponent } from '../../modal-content/modal-content.component'; +import { ModalContentComponent } from '../../object-tab/modal-content/modal-content.component'; export interface DeveloperData { name: string; score: number; id: string; } @Component({ - selector: 'app-query3', - templateUrl: './query3.component.html', - styleUrls: ['./query3.component.css'] + selector: 'app-reviewer-recommendation', + templateUrl: './reviewer-recommendation.component.html', + styleUrls: ['./reviewer-recommendation.component.css'] }) -export class Query3Component implements OnInit { +export class ReviewerRecommendationComponent implements OnInit { githubHttpOptions: any; authentication: any; pr: string; @@ -62,7 +59,8 @@ export class Query3Component implements OnInit { algorithm = null; recency: boolean = false; - constructor(private http: HttpClient, private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, private _group: GroupCustomizationService, private _gt: TheoreticPropertiesCustomService, private modalService: NgbModal) { + constructor(private http: HttpClient, private _dbService: Neo4jDb, private _cyService: CytoscapeService, private _g: GlobalVariableService, + private _group: GroupCustomizationService, private _gt: TheoreticPropertiesCustomService, private modalService: NgbModal, private _h: QueryHelperService) { this.prs = []; this.developers = []; this.scores = []; @@ -72,7 +70,6 @@ export class Query3Component implements OnInit { } ngOnInit() { - this._dbService.runQuery('MATCH (m:PullRequest) return m.name as name , elementId(m) as id order by m.name ', (x) => { this.fillGenres(x) }, DbResponseType.table); @@ -94,48 +91,6 @@ export class Query3Component implements OnInit { } }, 500) } - assign() { - this.http.get(`http://${window.location.hostname}:4445/getAuthentication`).subscribe(data => { - this.authentication = data; - this.githubHttpOptions = { - headers: new HttpHeaders({ - 'Authorization': `Bearer ${this.authentication.github_token}`, - 'Accept': 'application/vnd.github.v3+json', - "X-GitHub-Api-Version": "2022-11-28", - 'Content-Type': 'application/json' - }) - }; - if (this.authentication.authenticated) { - this.reviewers = this.tableInput.results.filter((_, i) => this.tableInput.results2[i]).map(x => x[1].val) as string[]; - const url = `https://api.github.com/repos/${this.authentication.github_repo}/pulls/${this.pr}/requested_reviewers`; - const headers = { - 'Accept': 'application/vnd.github+json', - 'Authorization': `Bearer ${this.authentication.github_token}`, - 'X-GitHub-Api-Version': '2022-11-28', - 'Content-Type': 'application/json' - }; - const body = { - reviewers: this.reviewers - }; - - this.http.post(url, body, { headers }).subscribe( - (response) => { - this.openModal('assigned', "Pull Request " + this.pr, response["html_url"]); - console.log('Reviewers added successfully:', response); - }, - (error) => { - console.log(error.error.message); - this.openModal('error', undefined, undefined, "Assignment error", error.error.message); - } - - ); - } else { - this.openModal('error', undefined, undefined, "You are not authenticated", "You are not authenticated for performing this task") - } - } - ); - } - prepareQuery() { this.tableInput.currPage = 1; @@ -145,27 +100,26 @@ export class Query3Component implements OnInit { } loadTable(skip: number, filter?: TableFiltering) { - this.developers = []; - this.scores = []; this.prId = this.prIds[this.prs.indexOf(this.pr)] const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; + const cb = (x) => { this.developers = x.data[0][0] this.scores = x.data[0][2] - if(this.developers.length > 0){ + if (this.developers.length > 0) { this.assigned = true } - else{ + else { this.assigned = false } - const processedTableData = this.preprocessTableData(x); + const processedTableData = this._h.preprocessTableDataZip(x,['elementId'].concat(this.tableInput.columns)); const limit4clientSidePaginated = this._g.userPrefs.dataPageSize.getValue() * this._g.userPrefs.dataPageLimit.getValue(); let cnt = x.data.length; if (isClientSidePagination && cnt > limit4clientSidePaginated) { cnt = limit4clientSidePaginated; } if (isClientSidePagination) { - this.fillTable(this.filterTableResponse(processedTableData, filter), cnt); + this.fillTable(this.filterTableResponse(x, filter), cnt); } else { this.fillTable(processedTableData, cnt); } @@ -182,20 +136,11 @@ export class Query3Component implements OnInit { this.fillTable(this.filterTableResponse(this.tableResponse, filter), null); return; } - //const idFilter = buildIdFilter(e.dbIds); + //const idFilter = this._h. buildIdFilter(e.dbIds); const isIgnoreCase = this._g.userPrefs.isIgnoreCaseInText.getValue(); - const txtCondition = getQueryCondition4TxtFilter(filter, ['score'], isIgnoreCase); + const txtCondition = this._h.getQueryCondition4TxtFilter(filter, ['score'], isIgnoreCase); const ui2Db = { 'name': 'name', "score": "score" }; - const orderExpr = getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); - const f1 = this.dateFilterFromUserPref('a', true); - const f2 = this.dateFilterFromUserPref('b', true); - let f = ''; - if (f1.length > 0) { - f += ' WHERE ' + f1.substr(5); - } - if (f2.length > 0) { - f += f2; - } + const orderExpr = this._h.getOrderByExpression4Query(filter, 'score', 'desc', ui2Db); let dataCnt = this.tableInput.pageSize; if (isClientSidePagination) { dataCnt = this._g.userPrefs.dataPageLimit.getValue() * this._g.userPrefs.dataPageSize.getValue(); @@ -218,7 +163,7 @@ export class Query3Component implements OnInit { const cbSub1 = (x) => { this.fileIds = x.data[0][0] if (this.fileIds.length > 0) { - this._dbService.runQuery(`MATCH (file:File)-[*1..${this.number}]-(developer:Developer) + this._dbService.runQuery(`MATCH (file:File)-[*1..${this.number}]-(developer:Developer) WHERE elementId(file) IN ['${this.fileIds.join("','")}'] RETURN COLLECT(DISTINCT elementId(developer)) AS developersList`, cbSub2, DbResponseType.table, false); } @@ -233,7 +178,6 @@ export class Query3Component implements OnInit { const cbSub3 = (x) => { let ignoredDevelopers = x.data[0][0] this.possibleDevelopers = this.possibleDevelopers.filter(dev => !ignoredDevelopers.includes(dev)); - console.log(this.possibleDevelopers, ignoredDevelopers) if (this.possibleDevelopers.length > 0) { this._dbService.runQuery(`CALL findNodesWithMostPathBetweenTable(['${this.fileIds.join("','")}'], ['COMMENTED'],['${this.possibleDevelopers.join("','")}'],'${this.recency ? 'recency' : 'none'}',3,${this.number}, false, ${pageSize}, ${currPage}, null, false, '${orderBy}', ${orderDir}, ${timeMap}, ${d1}, ${d2}, ${inclusionType}, ${timeout}, null)`, cb, DbResponseType.table, false); @@ -311,7 +255,7 @@ export class Query3Component implements OnInit { } const inclusionType = this._g.userPrefs.objectInclusionType.getValue(); const timeout = this._g.userPrefs.dbTimeout.getValue() * 1000; - if (this.fileIds.length > 0 && this.possibleDevelopers.length>0) { + if (this.fileIds.length > 0 && this.possibleDevelopers.length > 0) { this._dbService.runQuery(`CALL findNodesWithMostPathBetweenGraph(['${this.fileIds.join("','")}'], ['COMMENTED'],['${this.possibleDevelopers.join("','")}'],'${this.recency ? 'recency' : 'none'}',3,${this.number}, false, ${pageSize}, ${currPage}, null, false, '${orderBy}', ${orderDir}, ${timeMap}, ${d1}, ${d2}, ${inclusionType}, ${timeout}, null)`, cb, DbResponseType.graph, false); } @@ -354,7 +298,7 @@ export class Query3Component implements OnInit { getDataForQueryResult(e: TableRowMeta) { let filter = this.tableFilter; const skip = (this.tableInput.currPage - 1) * this.tableInput.pageSize; - const idFilter = buildIdFilter(e.dbIds); + const idFilter = this._h.buildIdFilter(e.dbIds); const isClientSidePagination = this._g.userPrefs.queryResultPagination.getValue() == 'Client'; const cb = (x) => { this.seeds = [] @@ -416,7 +360,7 @@ export class Query3Component implements OnInit { } const inclusionType = this._g.userPrefs.objectInclusionType.getValue(); const timeout = this._g.userPrefs.dbTimeout.getValue() * 1000; - if (this.fileIds.length > 0 && this.possibleDevelopers.length>0) { + if (this.fileIds.length > 0 && this.possibleDevelopers.length > 0) { this._dbService.runQuery(`CALL findNodesWithMostPathBetweenGraph(['${this.fileIds.join("','")}'], ['COMMENTED'],['${this.possibleDevelopers.join("','")}'],'${this.recency ? 'recency' : 'none'}',3,${this.number}, false, ${pageSize}, ${currPage}, null, false, '${orderBy}', ${orderDir}, ${timeMap}, ${d1}, ${d2}, ${inclusionType}, ${timeout}, null)`, cb, DbResponseType.graph, false); } @@ -428,31 +372,6 @@ export class Query3Component implements OnInit { this.loadTable(skip, filter); } - // zip paralel arrays - private preprocessTableData(data): DeveloperData[] { - const dbColumns = data.columns as string[]; - const uiColumns = ['elementId'].concat(this.tableInput.columns); - let columnMapping = []; - for (let i = 0; i < uiColumns.length; i++) { - columnMapping.push(dbColumns.indexOf(uiColumns[i])); - } - const rawData = data.data[0]; - const objArr: DeveloperData[] = []; - for (let i = 0; i < rawData[0].length; i++) { - const obj = {}; - for (let j = 0; j < columnMapping.length; j++) { - if (uiColumns[j] == 'score') { - obj[uiColumns[j]] = rawData[columnMapping[j]][i].toFixed(5); - } - else { - obj[uiColumns[j]] = rawData[columnMapping[j]][i]; - } - } - objArr.push(obj as DeveloperData) - } - return objArr; - } - private filterTableResponse(x: DeveloperData[], filter: TableFiltering): DeveloperData[] { if (!filter || ((!filter.txt || filter.txt.length < 1) && filter.orderDirection == '' && (!filter.skip || filter.skip == 0))) { @@ -594,49 +513,48 @@ export class Query3Component implements OnInit { return s; } - private dateFilterFromUserPref(varName: string, isNode: boolean): string { - if (!this._g.userPrefs.isLimitDbQueries2range.getValue()) { - return ''; - } - let s = ''; - let keys = []; - - if (isNode) { - keys = Object.keys(this._g.appDescription.getValue().objects); - } else { - keys = Object.keys(this._g.appDescription.getValue().relations); - } - - const d1 = this._g.userPrefs.dbQueryTimeRange.start.getValue(); - const d2 = this._g.userPrefs.dbQueryTimeRange.end.getValue(); - const inclusionType = this._g.userPrefs.objectInclusionType.getValue(); - const mapping = this._g.appDescription.getValue().timebarDataMapping; + assign() { + this.http.get(`http://${window.location.hostname}:4445/getAuthentication`).subscribe(data => { + this.authentication = data; + this.githubHttpOptions = { + headers: new HttpHeaders({ + 'Authorization': `Bearer ${this.authentication.github_token}`, + 'Accept': 'application/vnd.github.v3+json', + "X-GitHub-Api-Version": "2022-11-28", + 'Content-Type': 'application/json' + }) + }; + if (this.authentication.authenticated) { + this.reviewers = this.tableInput.results.filter((_, i) => this.tableInput.results2[i]).map(x => x[1].val) as string[]; + const url = `https://api.github.com/repos/${this.authentication.github_repo}/pulls/${this.pr}/requested_reviewers`; + const headers = { + 'Accept': 'application/vnd.github+json', + 'Authorization': `Bearer ${this.authentication.github_token}`, + 'X-GitHub-Api-Version': '2022-11-28', + 'Content-Type': 'application/json' + }; + const body = { + reviewers: this.reviewers + }; - if (!mapping || Object.keys(mapping).length < 1) { - return ''; - } + this.http.post(url, body, { headers }).subscribe( + (response) => { + this.openModal('assigned', "Pull Request " + this.pr, response["html_url"]); + console.log('Reviewers added successfully:', response); + }, + (error) => { + console.log(error.error.message); + this.openModal('error', undefined, undefined, "Assignment error", error.error.message); + } - s = ' AND ('; - for (const k of keys) { - if (!mapping[k]) { - continue; - } - const p1 = `COALESCE(${varName}.${mapping[k].begin_datetime}, ${LONG_MIN})`; - const p2 = `COALESCE(${varName}.${mapping[k].end_datetime}, ${LONG_MAX})`; - const bothNull = `(${varName}.${mapping[k].end_datetime} IS NULL AND ${varName}.${mapping[k].begin_datetime} IS NULL)` - if (inclusionType == TimebarGraphInclusionTypes.overlaps) { - s += `(${bothNull} OR (${p1} <= ${d2} AND ${p2} >= ${d1})) AND`; - } else if (inclusionType == TimebarGraphInclusionTypes.contains) { - s += `(${bothNull} OR (${d1} <= ${p1} AND ${d2} >= ${p2})) AND`; - } else if (inclusionType == TimebarGraphInclusionTypes.contained_by) { - s += `(${bothNull} OR (${p1} <= ${d1} AND ${p2} >= ${d2})) AND`; + ); + } else { + this.openModal('error', undefined, undefined, "You are not authenticated", "You are not authenticated for performing this task") } - } - s = s.slice(0, -4) - s += ')' - return s; + ); } +} + -} \ No newline at end of file diff --git a/src/app/custom/context-menu-customization.service.ts b/src/app/custom/customization-service/context-menu-customization.service.ts similarity index 99% rename from src/app/custom/context-menu-customization.service.ts rename to src/app/custom/customization-service/context-menu-customization.service.ts index b51f6e76..6414981f 100644 --- a/src/app/custom/context-menu-customization.service.ts +++ b/src/app/custom/customization-service/context-menu-customization.service.ts @@ -1,9 +1,9 @@ import { Injectable } from "@angular/core"; -import { CytoscapeService } from "../visuall/cytoscape.service"; -import { DbAdapterService } from "../visuall/db-service/db-adapter.service"; -import { GlobalVariableService } from "../visuall/global-variable.service"; -import { ContextMenuItem } from "../visuall/context-menu/icontext-menu"; -import { DbQueryMeta, HistoryMetaData } from "../visuall/db-service/data-types"; +import { CytoscapeService } from "../../visuall/cytoscape.service"; +import { DbAdapterService } from "../../visuall/db-service/db-adapter.service"; +import { GlobalVariableService } from "../../visuall/global-variable.service"; +import { ContextMenuItem } from "../../visuall/context-menu/icontext-menu"; +import { DbQueryMeta, HistoryMetaData } from "../../visuall/db-service/data-types"; import { HttpClient } from '@angular/common/http'; import { forEach } from "cypress/types/lodash"; diff --git a/src/app/custom/cy-style-customization.service.ts b/src/app/custom/customization-service/cy-style-customization.service.ts similarity index 100% rename from src/app/custom/cy-style-customization.service.ts rename to src/app/custom/customization-service/cy-style-customization.service.ts diff --git a/src/app/custom/group-customization.service.ts b/src/app/custom/customization-service/group-customization.service.ts similarity index 92% rename from src/app/custom/group-customization.service.ts rename to src/app/custom/customization-service/group-customization.service.ts index e062c288..c1659748 100644 --- a/src/app/custom/group-customization.service.ts +++ b/src/app/custom/customization-service/group-customization.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; -import { CytoscapeService } from '../visuall/cytoscape.service'; -import { GlobalVariableService } from '../visuall/global-variable.service'; -import { GroupingOptionTypes } from '../visuall/user-preference'; +import { CytoscapeService } from '../../visuall/cytoscape.service'; +import { GlobalVariableService } from '../../visuall/global-variable.service'; +import { GroupingOptionTypes } from '../../visuall/user-preference'; @Injectable({ providedIn: 'root' diff --git a/src/app/custom/navbar-customization.service.ts b/src/app/custom/customization-service/navbar-customization.service.ts similarity index 95% rename from src/app/custom/navbar-customization.service.ts rename to src/app/custom/customization-service/navbar-customization.service.ts index 9b71d474..774b3249 100644 --- a/src/app/custom/navbar-customization.service.ts +++ b/src/app/custom/customization-service/navbar-customization.service.ts @@ -1,12 +1,12 @@ import { Component, Injectable } from '@angular/core'; -import { NavbarDropdown } from '../visuall/navbar/inavbar'; -import { GlobalVariableService } from '../visuall/global-variable.service'; +import { NavbarDropdown } from '../../visuall/navbar/inavbar'; +import { GlobalVariableService } from '../../visuall/global-variable.service'; import { ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog'; import { MatMenuTrigger } from '@angular/material/menu'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; -import { Neo4jDb } from '../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../visuall/db-service/neo4j-db.service'; @Injectable({ providedIn: 'root' }) diff --git a/src/app/custom/theoretic-properties-custom.service.ts b/src/app/custom/customization-service/theoretic-properties-custom.service.ts similarity index 97% rename from src/app/custom/theoretic-properties-custom.service.ts rename to src/app/custom/customization-service/theoretic-properties-custom.service.ts index 84c5d370..c004d2cf 100644 --- a/src/app/custom/theoretic-properties-custom.service.ts +++ b/src/app/custom/customization-service/theoretic-properties-custom.service.ts @@ -1,9 +1,9 @@ import { Injectable } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../visuall/global-variable.service'; +import { GlobalVariableService } from '../../visuall/global-variable.service'; import { formatNumber } from '@angular/common'; -import { CytoscapeService } from '../visuall/cytoscape.service'; -import { debounce2, debounce, COLLAPSED_EDGE_CLASS, mapColor } from '../visuall/constants'; +import { CytoscapeService } from '../../visuall/cytoscape.service'; +import { debounce2, debounce, COLLAPSED_EDGE_CLASS, mapColor } from '../../visuall/constants'; import { Subscription } from 'rxjs'; @Injectable({ diff --git a/src/app/custom/toolbar-customization.service.ts b/src/app/custom/customization-service/toolbar-customization.service.ts similarity index 94% rename from src/app/custom/toolbar-customization.service.ts rename to src/app/custom/customization-service/toolbar-customization.service.ts index 8ee25ece..b7cdc931 100644 --- a/src/app/custom/toolbar-customization.service.ts +++ b/src/app/custom/customization-service/toolbar-customization.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; -import { ToolbarDiv } from '../visuall/toolbar/itoolbar'; -import { GlobalVariableService } from '../visuall/global-variable.service'; +import { ToolbarDiv } from '../../visuall/toolbar/itoolbar'; +import { GlobalVariableService } from '../../visuall/global-variable.service'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; -import { Neo4jDb } from '../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../visuall/db-service/neo4j-db.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/custom/customization.module.ts b/src/app/custom/customization.module.ts index 1ab9efb9..385f6399 100644 --- a/src/app/custom/customization.module.ts +++ b/src/app/custom/customization.module.ts @@ -2,51 +2,51 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Neo4jDb } from '../visuall/db-service/neo4j-db.service'; import { DbService } from '../visuall/db-service/data-types'; -import { Query1Component } from './queries/query1/query1.component'; -import { Query3Component } from './queries/query3/query3.component'; -import { Query5Component } from './queries/query5/query5.component'; -import { Query6Component } from './queries/query6/query6.component'; +import { DeveloperCommitsComponent } from './analyses/developer-commits/developer-commits.component'; +import { ReviewerRecommendationComponent } from './analyses/reviewer-recommendation/reviewer-recommendation.component'; +import { AnomalyComponent } from './analyses/anomalies/anomaly/anomaly.component'; +import { AnomalyStatisticComponent } from './analyses/anomalies/anomaly-statistic/anomaly-statistic.component'; import { SharedModule } from '../shared/shared.module'; import { FormsModule } from '@angular/forms'; import { Rule, RuleNode, TimebarMetric } from '../visuall/operation-tabs/map-tab/query-types'; -import { ReportComponent } from './report-tab/report.component'; -import { ObjectQueriesComponent } from './object-queries/object-queries.component' +import { ReportComponent } from './object-tab/report-tab/report.component'; +import { ObjectQueriesComponent } from './object-tab/object-queries-tab/object-queries.component' import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; -import { UnassignedBugsComponent } from './anomalies/unassigned-bugs/unassigned-bugs.component'; -import { NoLinkToBugFixingCommitComponent } from './anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component'; -import { IgnoredBugsComponent } from './anomalies/ignored-bugs/ignored-bugs.component'; -import { MissingPriorityComponent } from './anomalies/missing-priority/missing-priority.component'; -import { NotReferencedDuplicatesComponent } from './anomalies/not-referenced-duplicates/not-referenced-duplicates.component'; -import { MissingEnvironmentInformationComponent } from './anomalies/missing-environment-information/missing-environment-information.component'; -import { ReassignmentBugAssigneeComponent } from './anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component'; -import { NoCommentBugsComponent } from './anomalies/no-comment-bugs/no-comment-bugs.component'; -import { NoAssigneeResolverBugComponent } from './anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component'; -import { ClosedReopenPingPongComponent } from './anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component'; -import { SameResolverCloserComponent } from './anomalies/same-resolver-closer/same-resolver-closer.component'; +import { UnassignedBugsComponent } from './analyses/anomalies/unassigned-bugs/unassigned-bugs.component'; +import { NoLinkToBugFixingCommitComponent } from './analyses/anomalies/no-link-to-bug-fixing-commit/no-link-to-bug-fixing-commit.component'; +import { IgnoredBugsComponent } from './analyses/anomalies/ignored-bugs/ignored-bugs.component'; +import { MissingPriorityComponent } from './analyses/anomalies/missing-priority/missing-priority.component'; +import { NotReferencedDuplicatesComponent } from './analyses/anomalies/not-referenced-duplicates/not-referenced-duplicates.component'; +import { MissingEnvironmentInformationComponent } from './analyses/anomalies/missing-environment-information/missing-environment-information.component'; +import { ReassignmentBugAssigneeComponent } from './analyses/anomalies/reassignment-bug-assignee/reassignment-bug-assignee.component'; +import { NoCommentBugsComponent } from './analyses/anomalies/no-comment-bugs/no-comment-bugs.component'; +import { NoAssigneeResolverBugComponent } from './analyses/anomalies/no-assignee-resolver-bug/no-assignee-resolver-bug.component'; +import { ClosedReopenPingPongComponent } from './analyses/anomalies/closed-reopen-ping-pong/closed-reopen-ping-pong.component'; +import { SameResolverCloserComponent } from './analyses/anomalies/same-resolver-closer/same-resolver-closer.component'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { ModalContentComponent } from './modal-content/modal-content.component'; -import { Query4Component } from './queries/query4/query4.component'; -import { Query2Component } from './queries/query2/query2.component'; -import { Query7Component } from './queries/query7/query7.component'; -import { Query8Component } from './queries/query8/query8.component'; -import { ReportIssueComponent } from './report-tab/sub-report-tabs/report-issue/report-issue.component'; -import { ReportPrComponent } from './report-tab/sub-report-tabs/report-pr/report-pr.component'; -import { ReportDeveloperComponent } from './report-tab/sub-report-tabs/report-developer/report-developer.component'; -import { ReportCommitComponent } from './report-tab/sub-report-tabs/report-commit/report-commit.component'; -import { ReportFileComponent } from './report-tab/sub-report-tabs/report-file/report-file.component'; +import { ModalContentComponent } from './object-tab/modal-content/modal-content.component'; +import { ExpertRecommendationComponent } from './analyses/expert-recommendation/expert-recommendation.component'; +import { CommentContributorsComponent } from './analyses/comment-contributors/comment-contributors.component'; +import { CollaboratorsComponent } from './analyses/collaborators/collaborators.component'; +import { CommentCollaboratorsComponent } from './analyses/comment-collaborators/comment-collaborators.component'; +import { ReportIssueComponent } from './object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component'; +import { ReportPrComponent } from './object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component'; +import { ReportDeveloperComponent } from './object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component'; +import { ReportCommitComponent } from './object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component'; +import { ReportFileComponent } from './object-tab/report-tab/sub-report-tabs/report-file/report-file.component'; // import { AsdComponent } from './asd/asd.component'; // import statements for custom components should be here @NgModule({ // custom components should be inside declarations declarations: [ - Query1Component, - Query3Component, - Query6Component, + DeveloperCommitsComponent, + ReviewerRecommendationComponent, + AnomalyStatisticComponent, ReportComponent, ObjectQueriesComponent, - Query5Component, + AnomalyComponent, UnassignedBugsComponent, NoLinkToBugFixingCommitComponent, IgnoredBugsComponent, @@ -59,10 +59,10 @@ import { ReportFileComponent } from './report-tab/sub-report-tabs/report-file/re ClosedReopenPingPongComponent, SameResolverCloserComponent, ModalContentComponent, - Query4Component, - Query2Component, - Query7Component, - Query8Component, + ExpertRecommendationComponent, + CommentContributorsComponent, + CollaboratorsComponent, + CommentCollaboratorsComponent, ReportIssueComponent, ReportPrComponent, ReportDeveloperComponent, @@ -79,13 +79,11 @@ import { ReportFileComponent } from './report-tab/sub-report-tabs/report-file/re }) export class CustomizationModule { - // static operationTabs: { component: any, text: string }[] = [{ component: AsdComponent, text: 'Dummy' }]; - // static operationTabs: { component: any, text: string }[] = [{ component: Query5Component, text: 'Get Anomalies' }]; + static operationTabs: { component: any, text: string }[] = []; - static reportTab: { component: any, text: string }[] = [ - { component: ReportComponent, text: 'Report' } - ]; + static objSubTabs: { component: any, text: string }[] = [ + { component: ReportComponent, text: 'Report' }, { component: ObjectQueriesComponent, text: 'Queries' } ]; @@ -93,26 +91,12 @@ export class CustomizationModule { static databaseSubTabs: { component: any, text: string }[] = []; static settingsSubTabs: { component: any, text: string }[] = []; static queries: { component: any, text: string }[] = [ - { component: Query1Component, text: 'Get Commits of Developer' }, - { component: Query3Component, text: 'Get Recommended Reviewers' }, - { component: Query5Component, text: 'Get Anomalies' }, - { component: Query6Component, text: 'Get Anomaly Statistics' } - + { component: DeveloperCommitsComponent, text: 'Get Commits of Developer' }, + { component: ReviewerRecommendationComponent, text: 'Get Recommended Reviewers' }, + { component: AnomalyComponent, text: 'Get Anomalies' }, + { component: AnomalyStatisticComponent, text: 'Get Anomaly Statistics' } ]; - static anomalies: { component: any, text: string }[] = [ - { component: UnassignedBugsComponent, text: 'Unassigned Bugs' }, - { component: NoLinkToBugFixingCommitComponent, text: 'No Link to Bug-Fixing Commit' }, - { component: IgnoredBugsComponent, text: 'Ignored Bugs' }, - { component: MissingPriorityComponent, text: 'Missing Priority' }, - { component: NotReferencedDuplicatesComponent, text: 'Not referenced duplicates' }, - { component: MissingEnvironmentInformationComponent, text: 'Missing Environment Information' }, - { component: ReassignmentBugAssigneeComponent, text: 'Reassignment of Bug Assignee' }, - { component: NoCommentBugsComponent, text: 'No comment bugs' }, - { component: NoAssigneeResolverBugComponent, text: 'Non-Assignee Resolver of Bug' }, - { component: ClosedReopenPingPongComponent, text: 'Closed-Reopen Ping Pong' }, - { component: SameResolverCloserComponent, text: 'Same Resolver and Closer' }, - ]; static db: DbService; static defaultTimebarMetrics: TimebarMetric[]; constructor(private _db: Neo4jDb) { diff --git a/src/app/custom/modal-content/modal-content.component.spec.ts b/src/app/custom/modal-content/modal-content.component.spec.ts deleted file mode 100644 index 412a0933..00000000 --- a/src/app/custom/modal-content/modal-content.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ModalContentComponent } from './modal-content.component'; - -describe('ModalContentComponent', () => { - let component: ModalContentComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ ModalContentComponent ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(ModalContentComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/custom/queries/query7/query7.component.css b/src/app/custom/object-tab/modal-content/modal-content.component.css similarity index 100% rename from src/app/custom/queries/query7/query7.component.css rename to src/app/custom/object-tab/modal-content/modal-content.component.css diff --git a/src/app/custom/modal-content/modal-content.component.html b/src/app/custom/object-tab/modal-content/modal-content.component.html similarity index 100% rename from src/app/custom/modal-content/modal-content.component.html rename to src/app/custom/object-tab/modal-content/modal-content.component.html diff --git a/src/app/custom/modal-content/modal-content.component.ts b/src/app/custom/object-tab/modal-content/modal-content.component.ts similarity index 100% rename from src/app/custom/modal-content/modal-content.component.ts rename to src/app/custom/object-tab/modal-content/modal-content.component.ts diff --git a/src/app/custom/queries/query8/query8.component.css b/src/app/custom/object-tab/object-queries-tab/object-queries.component.css similarity index 100% rename from src/app/custom/queries/query8/query8.component.css rename to src/app/custom/object-tab/object-queries-tab/object-queries.component.css diff --git a/src/app/custom/object-queries/object-queries.component.html b/src/app/custom/object-tab/object-queries-tab/object-queries.component.html similarity index 100% rename from src/app/custom/object-queries/object-queries.component.html rename to src/app/custom/object-tab/object-queries-tab/object-queries.component.html diff --git a/src/app/custom/object-queries/object-queries.component.ts b/src/app/custom/object-tab/object-queries-tab/object-queries.component.ts similarity index 62% rename from src/app/custom/object-queries/object-queries.component.ts rename to src/app/custom/object-tab/object-queries-tab/object-queries.component.ts index 4668f43f..6666f501 100644 --- a/src/app/custom/object-queries/object-queries.component.ts +++ b/src/app/custom/object-tab/object-queries-tab/object-queries.component.ts @@ -1,18 +1,18 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Neo4jDb } from '../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { ModalContentComponent } from './../modal-content/modal-content.component'; +import { ModalContentComponent } from '../modal-content/modal-content.component'; import { BehaviorSubject } from 'rxjs'; -import { Query1Component } from '../queries/query1/query1.component'; -import { Query2Component } from '../queries/query2/query2.component'; -import { Query3Component } from '../queries/query3/query3.component'; -import { Query4Component } from '../queries/query4/query4.component'; -import { Query7Component } from '../queries/query7/query7.component'; -import { Query8Component } from '../queries/query8/query8.component'; +import { DeveloperCommitsComponent } from '../../analyses/developer-commits/developer-commits.component'; +import { CommentContributorsComponent } from '../../analyses/comment-contributors/comment-contributors.component'; +import { ReviewerRecommendationComponent } from '../../analyses/reviewer-recommendation/reviewer-recommendation.component'; +import { ExpertRecommendationComponent } from '../../analyses/expert-recommendation/expert-recommendation.component'; +import { CollaboratorsComponent } from '../../analyses/collaborators/collaborators.component'; +import { CommentCollaboratorsComponent } from '../../analyses/comment-collaborators/comment-collaborators.component'; @Component({ selector: 'app-object-queries', templateUrl: './object-queries.component.html', @@ -33,18 +33,18 @@ export class ObjectQueriesComponent implements OnInit { constructor(public _dbService: Neo4jDb, private _g: GlobalVariableService, private http: HttpClient,private modalService: NgbModal) { this.developerQueries = [ - { component: Query1Component, text: 'Get Commits' }, - { component: Query7Component, text: 'Get Collaborators' }, - { component: Query8Component, text: 'Get Comment Only Collaborators' }, + { component: DeveloperCommitsComponent, text: 'Get Commits' }, + { component: CollaboratorsComponent, text: 'Get Collaborators' }, + { component: CommentCollaboratorsComponent, text: 'Get Comment Only Collaborators' }, ]; this.prQueries = [ - { component: Query3Component, text: 'Get Recommended Reviewers' }, + { component: ReviewerRecommendationComponent, text: 'Get Recommended Reviewers' }, ]; this.fileQueries = [ - { component: Query4Component, text: 'Get Experts' }, + { component: ExpertRecommendationComponent, text: 'Get Experts' }, ]; this.issueQueries = [ - { component: Query2Component, text: 'Get Comment Contributors' }, + { component: CommentContributorsComponent, text: 'Get Comment Contributors' }, ]; this.commitQueries = [ ]; diff --git a/src/app/custom/report-tab/report.component.css b/src/app/custom/object-tab/report-tab/report.component.css similarity index 100% rename from src/app/custom/report-tab/report.component.css rename to src/app/custom/object-tab/report-tab/report.component.css diff --git a/src/app/custom/report-tab/report.component.html b/src/app/custom/object-tab/report-tab/report.component.html similarity index 100% rename from src/app/custom/report-tab/report.component.html rename to src/app/custom/object-tab/report-tab/report.component.html diff --git a/src/app/custom/report-tab/report.component.ts b/src/app/custom/object-tab/report-tab/report.component.ts similarity index 92% rename from src/app/custom/report-tab/report.component.ts rename to src/app/custom/object-tab/report-tab/report.component.ts index 42317fcf..f13898ae 100644 --- a/src/app/custom/report-tab/report.component.ts +++ b/src/app/custom/object-tab/report-tab/report.component.ts @@ -1,8 +1,8 @@ import { Component, ViewChild, ViewContainerRef, ComponentRef, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../visuall/global-variable.service'; -import { Neo4jDb } from '../../visuall/db-service/neo4j-db.service'; +import { GlobalVariableService } from '../../../visuall/global-variable.service'; +import { Neo4jDb } from '../../../visuall/db-service/neo4j-db.service'; import { BehaviorSubject } from 'rxjs'; import { ReportIssueComponent } from './sub-report-tabs/report-issue/report-issue.component'; import { ReportPrComponent } from './sub-report-tabs/report-pr/report-pr.component'; @@ -65,7 +65,6 @@ export class ReportComponent implements OnInit { } loadDynamicComponent(component: any) { this.componentRef = this.container.createComponent(component); - console.log('Component Ref:', this.componentRef); } diff --git a/src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.css b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.css similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.css rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.css diff --git a/src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.html b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.html similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.html rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.html diff --git a/src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.ts b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.ts similarity index 97% rename from src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.ts rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.ts index cfc2b234..8ce88341 100644 --- a/src/app/custom/report-tab/sub-report-tabs/report-commit/report-commit.component.ts +++ b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-commit/report-commit.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ModalContentComponent } from '../../../modal-content/modal-content.component'; diff --git a/src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.css b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.css similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.css rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.css diff --git a/src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.html b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.html similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.html rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.html diff --git a/src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.ts b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.ts similarity index 97% rename from src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.ts rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.ts index 88be8d33..c62dca73 100644 --- a/src/app/custom/report-tab/sub-report-tabs/report-developer/report-developer.component.ts +++ b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-developer/report-developer.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ModalContentComponent } from '../../../modal-content/modal-content.component'; diff --git a/src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.css b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.css similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.css rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.css diff --git a/src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.html b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.html similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.html rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.html diff --git a/src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.ts b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.ts similarity index 97% rename from src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.ts rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.ts index d64e3a9a..1c731e01 100644 --- a/src/app/custom/report-tab/sub-report-tabs/report-file/report-file.component.ts +++ b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-file/report-file.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ModalContentComponent } from '../../../modal-content/modal-content.component'; diff --git a/src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.css b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.css similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.css rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.css diff --git a/src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.html b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.html similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.html rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.html diff --git a/src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.ts b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.ts similarity index 97% rename from src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.ts rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.ts index dd881ef1..8052c553 100644 --- a/src/app/custom/report-tab/sub-report-tabs/report-issue/report-issue.component.ts +++ b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-issue/report-issue.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType } from 'src/app/visuall/db-service/data-types'; import { HttpClient } from '@angular/common/http'; -import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ModalContentComponent } from '../../../modal-content/modal-content.component'; diff --git a/src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.css b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.css similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.css rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.css diff --git a/src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.html b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.html similarity index 100% rename from src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.html rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.html diff --git a/src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.ts b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.ts similarity index 98% rename from src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.ts rename to src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.ts index 4da17f4c..0a9130a0 100644 --- a/src/app/custom/report-tab/sub-report-tabs/report-pr/report-pr.component.ts +++ b/src/app/custom/object-tab/report-tab/sub-report-tabs/report-pr/report-pr.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { GlobalVariableService } from '../../../../visuall/global-variable.service'; +import { GlobalVariableService } from '../../../../../visuall/global-variable.service'; import { Observable } from 'rxjs'; import { DbResponseType, GraphResponse } from 'src/app/visuall/db-service/data-types'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Neo4jDb } from '../../../../visuall/db-service/neo4j-db.service'; +import { Neo4jDb } from '../../../../../visuall/db-service/neo4j-db.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ModalContentComponent } from '../../../modal-content/modal-content.component'; diff --git a/src/app/custom/queries/query-helper.ts b/src/app/custom/queries/query-helper.ts deleted file mode 100644 index dd384b0e..00000000 --- a/src/app/custom/queries/query-helper.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { TableFiltering } from '../../shared/table-view/table-view-types'; - -export function getQueryCondition4TxtFilter(filter: TableFiltering, cols: string[], isIgnoreCase: boolean): string { - if (filter == null || filter.txt.length < 1) { - return ''; - } - let s = ''; - - for (let i = 0; i < cols.length; i++) { - if (isIgnoreCase) { - s += ` LOWER(toString(${cols[i]})) CONTAINS LOWER('${filter.txt}') OR `; - } else { - s += ` toString(${cols[i]}) CONTAINS '${filter.txt}' OR `; - } - } - s = s.slice(0, -3); - s = 'AND (' + s + ')'; - return s; -} - - -export function getOrderByExpression4Query(filter: TableFiltering, orderBy: string, orderDirection: string, ui2Db: any) { - if (filter != null && filter.orderDirection.length > 0 && filter.orderBy.length > 0) { - orderBy = ui2Db[filter.orderBy]; - orderDirection = filter.orderDirection; - } - return orderBy + ' ' + orderDirection; -} - -export function buildIdFilter(ids: string[] | number[], hasEnd = false, isEdgeQuery = false): string { - if (ids === undefined) { - return ''; - } - let varName = 'n'; - if (isEdgeQuery) { - varName = 'e'; - } - let cql = ''; - if (ids.length > 0) { - cql = '('; - } - for (let i = 0; i < ids.length; i++) { - cql += `ElementId(${varName})='${ids[i]}' OR ` - } - - if (ids.length > 0) { - cql = cql.slice(0, -4); - - cql += ')'; - if (hasEnd) { - cql += ' AND '; - } - } - return cql; -} \ No newline at end of file diff --git a/src/app/custom/queries/query2/query2.component.spec.ts b/src/app/custom/queries/query2/query2.component.spec.ts deleted file mode 100644 index 84c847e4..00000000 --- a/src/app/custom/queries/query2/query2.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Query7Component } from './query2.component'; - -describe('Query7Component', () => { - let component: Query7Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ Query7Component ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(Query7Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/custom/queries/query4/query4.component.spec.ts b/src/app/custom/queries/query4/query4.component.spec.ts deleted file mode 100644 index b7431fdc..00000000 --- a/src/app/custom/queries/query4/query4.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Query4Component } from './query4.component'; - -describe('Query4Component', () => { - let component: Query4Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ Query4Component ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(Query4Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/custom/queries/query5/query5.component.ts b/src/app/custom/queries/query5/query5.component.ts deleted file mode 100644 index 41bdfca6..00000000 --- a/src/app/custom/queries/query5/query5.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CustomizationModule } from '../../../custom/customization.module'; -@Component({ - selector: 'app-query5', - templateUrl: './query5.component.html', - styleUrls: ['./query5.component.css'] -}) -export class Query5Component implements OnInit { - anomaly: string; - selectedIdx: number; - anomalies:{ component: any, text: string }[]; - - constructor() { - this.anomalies = CustomizationModule.anomalies; - this.selectedIdx = -1; - } - changeAnomaly(event) { - this.selectedIdx = this.anomalies.findIndex(x => x.text == event.target.value); - } - ngOnInit(): void { - this.anomaly = ''; - } - -} diff --git a/src/app/custom/queries/query7/query7.component.spec.ts b/src/app/custom/queries/query7/query7.component.spec.ts deleted file mode 100644 index 3d7b1bd8..00000000 --- a/src/app/custom/queries/query7/query7.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Query7Component } from './query7.component'; - -describe('Query7Component', () => { - let component: Query7Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ Query7Component ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(Query7Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/custom/queries/query8/query8.component.spec.ts b/src/app/custom/queries/query8/query8.component.spec.ts deleted file mode 100644 index cb473a42..00000000 --- a/src/app/custom/queries/query8/query8.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { Query8Component } from './query8.component'; - -describe('Query8Component', () => { - let component: Query8Component; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ Query8Component ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(Query8Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/custom/theoretic-properties-custom.service.spec.ts b/src/app/custom/theoretic-properties-custom.service.spec.ts deleted file mode 100644 index 58e5ddc2..00000000 --- a/src/app/custom/theoretic-properties-custom.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { TheoreticPropertiesCustomService } from './theoretic-properties-custom.service'; - -describe('TheoreticPropertiesCustomService', () => { - let service: TheoreticPropertiesCustomService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(TheoreticPropertiesCustomService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/src/app/visuall/context-menu/context-menu.service.ts b/src/app/visuall/context-menu/context-menu.service.ts index 757a8579..dfd93e5b 100644 --- a/src/app/visuall/context-menu/context-menu.service.ts +++ b/src/app/visuall/context-menu/context-menu.service.ts @@ -4,7 +4,7 @@ import * as contextMenus from 'cytoscape-context-menus'; import { CytoscapeService } from '../cytoscape.service'; import { GlobalVariableService } from '../global-variable.service'; import { ContextMenuItem } from './icontext-menu'; -import { ContextMenuCustomizationService } from '../../custom/context-menu-customization.service'; +import { ContextMenuCustomizationService } from '../../custom/customization-service/context-menu-customization.service'; import { COLLAPSED_EDGE_CLASS, CLUSTER_CLASS } from './../constants'; @Injectable({ diff --git a/src/app/visuall/global-variable.service.ts b/src/app/visuall/global-variable.service.ts index 42d23f39..08b4cb62 100644 --- a/src/app/visuall/global-variable.service.ts +++ b/src/app/visuall/global-variable.service.ts @@ -7,7 +7,7 @@ import { isPrimitiveType, debounce, LAYOUT_ANIM_DUR, COLLAPSED_EDGE_CLASS, COLLA import { GraphHistoryItem, GraphElem } from './db-service/data-types'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ErrorModalComponent } from './popups/error-modal/error-modal.component'; -import { CyStyleCustomizationService } from '../custom/cy-style-customization.service'; +import { CyStyleCustomizationService } from '../custom/customization-service/cy-style-customization.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/visuall/navbar/navbar.component.ts b/src/app/visuall/navbar/navbar.component.ts index 77aba733..2eb4182b 100644 --- a/src/app/visuall/navbar/navbar.component.ts +++ b/src/app/visuall/navbar/navbar.component.ts @@ -7,7 +7,7 @@ import { SaveAsPngModalComponent } from '../popups/save-as-png-modal/save-as-png import { AboutModalComponent } from '../popups/about-modal/about-modal.component'; import { QuickHelpModalComponent } from '../popups/quick-help-modal/quick-help-modal.component'; import { LegendModalComponent } from '../popups/legend-modal/legend-modal.component'; -import { NavbarCustomizationService } from '../../custom/navbar-customization.service'; +import { NavbarCustomizationService } from '../../custom/customization-service/navbar-customization.service'; import { NavbarDropdown, NavbarAction } from './inavbar'; import { UserProfileService } from '../user-profile.service'; import { readTxtFile, CLUSTER_CLASS } from '../constants'; diff --git a/src/app/visuall/operation-tabs/map-tab/group-tab/group-tab.component.ts b/src/app/visuall/operation-tabs/map-tab/group-tab/group-tab.component.ts index 90ad8672..1ced2592 100644 --- a/src/app/visuall/operation-tabs/map-tab/group-tab/group-tab.component.ts +++ b/src/app/visuall/operation-tabs/map-tab/group-tab/group-tab.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { CytoscapeService } from '../../../cytoscape.service'; import { areSetsEqual } from '../../../constants'; import { GlobalVariableService } from '../../../global-variable.service'; -import { GroupCustomizationService } from '../../../../custom/group-customization.service'; +import { GroupCustomizationService } from '../../../../custom/customization-service/group-customization.service'; @Component({ selector: 'app-group-tab', templateUrl: './group-tab.component.html', diff --git a/src/app/visuall/operation-tabs/object-tab/object-tab.component.html b/src/app/visuall/operation-tabs/object-tab/object-tab.component.html index 6ce5c09d..c72f947c 100644 --- a/src/app/visuall/operation-tabs/object-tab/object-tab.component.html +++ b/src/app/visuall/operation-tabs/object-tab/object-tab.component.html @@ -11,11 +11,6 @@ {{item.key}} {{item.val}} - - {{item.key}} - link - @@ -35,12 +30,7 @@ -
- -
- -
-
- \ No newline at end of file + + + + \ No newline at end of file diff --git a/src/app/visuall/operation-tabs/object-tab/object-tab.component.ts b/src/app/visuall/operation-tabs/object-tab/object-tab.component.ts index de0591a9..38638ef1 100644 --- a/src/app/visuall/operation-tabs/object-tab/object-tab.component.ts +++ b/src/app/visuall/operation-tabs/object-tab/object-tab.component.ts @@ -1,10 +1,11 @@ -import { Component, OnDestroy, OnInit, ElementRef, ViewChild, SimpleChanges, OnChanges, Input } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { GlobalVariableService } from '../../global-variable.service'; import { getPropNamesFromObj, DATE_PROP_END, DATE_PROP_START, findTypeOfAttribute, debounce, COLLAPSED_EDGE_CLASS, OBJ_INFO_UPDATE_DELAY, CLUSTER_CLASS, extend } from '../../constants'; import { TableViewInput, TableData, TableDataType, TableFiltering, property2TableData, filterTableDatas } from '../../../shared/table-view/table-view-types'; import { Subject, Subscription } from 'rxjs'; import { CytoscapeService } from '../../cytoscape.service'; import { CustomizationModule } from '../../../custom/customization.module'; + @Component({ selector: 'app-object-tab', templateUrl: './object-tab.component.html', @@ -12,29 +13,26 @@ import { CustomizationModule } from '../../../custom/customization.module'; }) export class ObjectTabComponent implements OnInit, OnDestroy { - @ViewChild('panelContainer', { static: false }) panelContainer: ElementRef; - @Input() openReportTab: boolean; - @Input() selectedItemProps: any[]; - openReport: boolean =false; - previousName: string = null; nodeClasses: Set; edgeClasses: Set; selectedClasses: string; - selectedItemPropsURL: any[]; + selectedItemProps: any[]; tableFilled = new Subject(); multiObjTableFilled = new Subject(); clearMultiObjTableFilter = new Subject(); isShowStatsTable: boolean = false; isShowObjTable = false; customSubTabs: { component: any, text: string }[] = CustomizationModule.objSubTabs; - reportTab:{ component: any, text: string }[] = CustomizationModule.reportTab; + tableInput: TableViewInput = { - columns: ['Type', 'Count', 'Selected', 'Hidden'], isHide0: true, results: [], results2: [], resultCnt: 0, currPage: 1, pageSize: 20, tableTitle: 'Statistics', - isShowExportAsCSV: true, isLoadGraph: true, columnLimit: 5, isMergeGraph: false, isNodeData: false, isUseCySelector4Highlight: true, isHideLoadGraph: true + columns: ['Type', 'Count', 'Selected', 'Hidden'], isHide0: true, results: [], resultCnt: 0, currPage: 1, pageSize: 20, tableTitle: 'Statistics', + isShowExportAsCSV: true, isLoadGraph: true, columnLimit: 5, isMergeGraph: false, isNodeData: false, isUseCySelector4Highlight: true, isHideLoadGraph: true, + results2: [] }; multiObjTableInp: TableViewInput = { - columns: ['Type'], isHide0: true, results: [], results2: [], resultCnt: 0, currPage: 1, pageSize: 20, isReplace_inHeaders: true, tableTitle: 'Properties', - isShowExportAsCSV: true, isEmphasizeOnHover: true, isLoadGraph: true, isMergeGraph: false, isNodeData: false, isUseCySelector4Highlight: true, isHideLoadGraph: true + columns: ['Type'], isHide0: true, results: [], resultCnt: 0, currPage: 1, pageSize: 20, isReplace_inHeaders: true, tableTitle: 'Properties', + isShowExportAsCSV: true, isEmphasizeOnHover: true, isLoadGraph: true, isMergeGraph: false, isNodeData: false, isUseCySelector4Highlight: true, isHideLoadGraph: true, + results2: [] }; private NODE_TYPE = '_NODE_'; private EDGE_TYPE = '_EDGE_'; @@ -44,463 +42,430 @@ export class ObjectTabComponent implements OnInit, OnDestroy { constructor(private _g: GlobalVariableService, private _cyService: CytoscapeService) { this.selectedItemProps = []; - this.selectedItemPropsURL = []; } - ngOnInit() { - - this._g.openReportTab.subscribe((isOpen) => { - this.openReport = isOpen; - }); this.appDescSubs = this._g.appDescription.subscribe(x => { - if (x === null) { - return; - } - this.dataModelSubs = this._g.dataModel.subscribe(x2 => { - if (x2 === null) { + if (x === null) { return; } - x2.edges = x2.edges; - this.nodeClasses = new Set([]); - this.edgeClasses = new Set([]); - for (const key in x2.nodes) { - this.nodeClasses.add(key); - } - - for (const key in x2.edges) { - this.edgeClasses.add(key); - } - - this.shownElemsSubs = this._g.shownElemsChanged.subscribe(() => { this.showStats() }); - this.showObjectProps(); - this.showStats(); - this._cyService.showObjPropsFn = debounce(this.showObjectProps, OBJ_INFO_UPDATE_DELAY).bind(this); - this._cyService.showStatsFn = debounce(this.showStats, OBJ_INFO_UPDATE_DELAY).bind(this); + this.dataModelSubs = this._g.dataModel.subscribe(x2 => { + if (x2 === null) { + return; + } + x2.edges = x2.edges; + this.nodeClasses = new Set([]); + this.edgeClasses = new Set([]); + for (const key in x2.nodes) { + this.nodeClasses.add(key); + } + + for (const key in x2.edges) { + this.edgeClasses.add(key); + } + + this.shownElemsSubs = this._g.shownElemsChanged.subscribe(() => { this.showStats() }); + this.showObjectProps(); + this.showStats(); + this._cyService.showObjPropsFn = debounce(this.showObjectProps, OBJ_INFO_UPDATE_DELAY).bind(this); + this._cyService.showStatsFn = debounce(this.showStats, OBJ_INFO_UPDATE_DELAY).bind(this); + }); }); - }); - } - handleSelectedItemChange() { - if (this.selectedItemProps && this.selectedItemProps.length > 0) { - const newName = this.selectedItemProps[0].val; - if (newName !== this.previousName) { - this.openReportTab = this.openReport; - this.previousName = newName; - let timeout = setTimeout(()=>{ - this._g.openReportTab.next(false) - },600) - } - } } -ngOnDestroy(): void { - if(this.appDescSubs) { - this.appDescSubs.unsubscribe(); -} -if (this.dataModelSubs) { - this.dataModelSubs.unsubscribe(); -} -if (this.shownElemsSubs) { - this.shownElemsSubs.unsubscribe(); -} + ngOnDestroy(): void { + if (this.appDescSubs) { + this.appDescSubs.unsubscribe(); + } + if (this.dataModelSubs) { + this.dataModelSubs.unsubscribe(); + } + if (this.shownElemsSubs) { + this.shownElemsSubs.unsubscribe(); + } } -showObjectProps() { - let selected = this._g.cy.$(':selected'); - this.isShowObjTable = false; - if (selected.filter('.' + COLLAPSED_EDGE_CLASS).length > 0) { - this.isShowObjTable = true; - this.showCompoundEdgeProps(true); - return; - } - if (selected.length > 1 && (selected.length == selected.filter('node').length || selected.length == selected.filter('edge').length)) { - this.isShowObjTable = true; - this.showMultiObjTable(true); - return; - } - const selectedNonMeta = selected.not('.' + COLLAPSED_EDGE_CLASS); - let props: { [x: string]: any; }, classNames: any[]; - [props, classNames] = this.getCommonObjectProps(selectedNonMeta); - const properties = this._g.dataModel.getValue(); - // remove undefined but somehow added properties (cuz of extensions) - let definedProperties = getPropNamesFromObj([properties.nodes, properties.edges], false); - for (let k in props) { - if (!definedProperties.has(k)) { - delete props[k]; + showObjectProps() { + let selected = this._g.cy.$(':selected'); + this.isShowObjTable = false; + if (selected.filter('.' + COLLAPSED_EDGE_CLASS).length > 0) { + this.isShowObjTable = true; + this.showCompoundEdgeProps(true); + return; + } + if (selected.length > 1 && (selected.length == selected.filter('node').length || selected.length == selected.filter('edge').length)) { + this.isShowObjTable = true; + this.showMultiObjTable(true); + return; + } + const selectedNonMeta = selected.not('.' + COLLAPSED_EDGE_CLASS); + let props: { [x: string]: any; }, classNames: any[]; + [props, classNames] = this.getCommonObjectProps(selectedNonMeta); + const properties = this._g.dataModel.getValue(); + // remove undefined but somehow added properties (cuz of extensions) + let definedProperties = getPropNamesFromObj([properties.nodes, properties.edges], false); + for (let k in props) { + if (!definedProperties.has(k)) { + delete props[k]; + } } - } - // remove classes added from extensions and other stuff - classNames = classNames.filter(x => this.nodeClasses.has(x) || this.edgeClasses.has(x)); - this.renderObjectProps(props, classNames, selectedNonMeta.length); -} - -showCompoundEdgeProps(isNeed2Filter: boolean) { - const compoundEdges = this._g.cy.edges(':selected').filter('.' + COLLAPSED_EDGE_CLASS); - const selectedNodeCnt = this._g.cy.nodes(':selected').length; - this.selectedClasses = ''; - this.selectedItemProps.length = 0; - this.selectedItemPropsURL.length = 0; - if (compoundEdges.length < 1 || selectedNodeCnt > 0) { - return; + // remove classes added from extensions and other stuff + classNames = classNames.filter(x => this.nodeClasses.has(x) || this.edgeClasses.has(x)); + this.renderObjectProps(props, classNames, selectedNonMeta.length); } - let idMappingForHighlight = {}; - let edges = this._g.cy.collection(); - for (let i = 0; i < compoundEdges.length; i++) { - let collapsed = compoundEdges[i].data('collapsedEdges'); - edges = edges.union(collapsed); - for (let j = 0; j < collapsed.length; j++) { - idMappingForHighlight[collapsed[j].id()] = compoundEdges[i].id(); + + showCompoundEdgeProps(isNeed2Filter: boolean) { + const compoundEdges = this._g.cy.edges(':selected').filter('.' + COLLAPSED_EDGE_CLASS); + const selectedNodeCnt = this._g.cy.nodes(':selected').length; + this.selectedClasses = ''; + this.selectedItemProps.length = 0; + if (compoundEdges.length < 1 || selectedNodeCnt > 0) { + return; } + let idMappingForHighlight = {}; + let edges = this._g.cy.collection(); + for (let i = 0; i < compoundEdges.length; i++) { + let collapsed = compoundEdges[i].data('collapsedEdges'); + edges = edges.union(collapsed); + for (let j = 0; j < collapsed.length; j++) { + idMappingForHighlight[collapsed[j].id()] = compoundEdges[i].id(); + } + } + let stdSelectedEdges = this._g.cy.edges(':selected').not('.' + COLLAPSED_EDGE_CLASS) + for (let i = 0; i < stdSelectedEdges.length; i++) { + idMappingForHighlight[stdSelectedEdges[i].id()] = stdSelectedEdges[i].id(); + } + edges = edges.union(stdSelectedEdges); + this.fillMultiObjTable(edges, false, idMappingForHighlight, isNeed2Filter); } - let stdSelectedEdges = this._g.cy.edges(':selected').not('.' + COLLAPSED_EDGE_CLASS) - for (let i = 0; i < stdSelectedEdges.length; i++) { - idMappingForHighlight[stdSelectedEdges[i].id()] = stdSelectedEdges[i].id(); - } - edges = edges.union(stdSelectedEdges); - this.fillMultiObjTable(edges, false, idMappingForHighlight, isNeed2Filter); -} private fillMultiObjTable(elems, isNode: boolean, idMappingForHighlight: any, isNeed2Filter: boolean) { - this.multiObjTableInp.isNodeData = isNode; - let elemTypesArr = elems.map(x => x.classes()[0]); - let elemTypes = {}; - for (let i = 0; i < elemTypesArr.length; i++) { - elemTypes[elemTypesArr[i]] = true; - } - const properties = this._g.dataModel.getValue(); - let definedProperties = {}; - for (let edgeType in elemTypes) { - if (isNode) { - for (let j in properties.nodes[edgeType]) { - definedProperties[j] = true; + this.multiObjTableInp.isNodeData = isNode; + let elemTypesArr = elems.map(x => x.classes()[0]); + let elemTypes = {}; + for (let i = 0; i < elemTypesArr.length; i++) { + elemTypes[elemTypesArr[i]] = true; + } + const properties = this._g.dataModel.getValue(); + let definedProperties = {}; + for (let edgeType in elemTypes) { + if (isNode) { + for (let j in properties.nodes[edgeType]) { + definedProperties[j] = true; + } + } else { + for (let j in properties.edges[edgeType]) { + definedProperties[j] = true; + } } - } else { - for (let j in properties.edges[edgeType]) { - definedProperties[j] = true; + } + this.multiObjTableInp.columns = ['Type'].concat(Object.keys(definedProperties)); + this.multiObjTableInp.results = []; + this.multiObjTableInp.classNames = []; + let elemTypeCnt = {}; + const enumMapping = this._g.getEnumMapping(); + for (let i = 0; i < elems.length; i++) { + let className = elems[i].classes()[0]; + if (elemTypeCnt[className]) { + elemTypeCnt[className] += 1; + } else { + elemTypeCnt[className] = 1; + } + let row: TableData[] = [{ type: TableDataType.string, val: '#' + idMappingForHighlight[elems[i].id()] }, { type: TableDataType.string, val: className }]; + for (let j in definedProperties) { + row.push(property2TableData(properties, enumMapping, j, elems[i].data(j) ?? '', className, !isNode)); } + this.multiObjTableInp.results.push(row); + this.multiObjTableInp.classNames.push(className); } - } - this.multiObjTableInp.columns = ['Type'].concat(Object.keys(definedProperties)); - this.multiObjTableInp.results = []; - this.multiObjTableInp.classNames = []; - let elemTypeCnt = {}; - const enumMapping = this._g.getEnumMapping(); - for (let i = 0; i < elems.length; i++) { - let className = elems[i].classes()[0]; - if (elemTypeCnt[className]) { - elemTypeCnt[className] += 1; - } else { - elemTypeCnt[className] = 1; + for (let k in elemTypeCnt) { + this.selectedClasses += k + '(' + elemTypeCnt[k] + ') '; } - let row: TableData[] = [{ type: TableDataType.string, val: '#' + idMappingForHighlight[elems[i].id()] }, { type: TableDataType.string, val: className }]; - for (let j in definedProperties) { - row.push(property2TableData(properties, enumMapping, j, elems[i].data(j) ?? '', className, !isNode)); + this.multiObjTableInp.pageSize = this._g.userPrefs.dataPageSize.getValue(); + this.multiObjTableInp.currPage = 1; + this.multiObjTableInp.resultCnt = this.multiObjTableInp.results.length; + // if too many edges need to be shown, we should make pagination + if (isNeed2Filter) { + this.clearMultiObjTableFilter.next(true); + filterTableDatas({ orderBy: '', orderDirection: '', txt: '' }, this.multiObjTableInp, this._g.userPrefs.isIgnoreCaseInText.getValue()); } - this.multiObjTableInp.results.push(row); - this.multiObjTableInp.classNames.push(className); - } - for (let k in elemTypeCnt) { - this.selectedClasses += k + '(' + elemTypeCnt[k] + ') '; - } - this.multiObjTableInp.pageSize = this._g.userPrefs.dataPageSize.getValue(); - this.multiObjTableInp.currPage = 1; - this.multiObjTableInp.resultCnt = this.multiObjTableInp.results.length; - // if too many edges need to be shown, we should make pagination - if (isNeed2Filter) { - this.clearMultiObjTableFilter.next(true); - filterTableDatas({ orderBy: '', orderDirection: '', txt: '' }, this.multiObjTableInp, this._g.userPrefs.isIgnoreCaseInText.getValue()); - } - setTimeout(() => { - this.multiObjTableFilled.next(true); - }, 100); -} - -showMultiObjTable(isNeed2Filter: boolean) { - let selected = this._g.cy.$(':selected').not('.' + CLUSTER_CLASS); - this.selectedClasses = ''; - this.selectedItemProps.length = 0; - this.selectedItemPropsURL.length = 0; - let hasNode = selected.filter('node').length > 0; - if (hasNode && selected.filter('edge').length > 0) { - return; + setTimeout(() => { + this.multiObjTableFilled.next(true); + }, 100); } - let idMappingForHighlight = {}; - for (let i = 0; i < selected.length; i++) { - let id = selected[i].id(); - idMappingForHighlight[id] = id; - } - this.fillMultiObjTable(selected, hasNode, idMappingForHighlight, isNeed2Filter); -} - -renderObjectProps(props, classNames, selectedCount) { - if (classNames && classNames.length > 0) { - classNames = classNames.join(' & '); + showMultiObjTable(isNeed2Filter: boolean) { + let selected = this._g.cy.$(':selected').not('.' + CLUSTER_CLASS); + this.selectedClasses = ''; + this.selectedItemProps.length = 0; + let hasNode = selected.filter('node').length > 0; + if (hasNode && selected.filter('edge').length > 0) { + return; + } + let idMappingForHighlight = {}; + for (let i = 0; i < selected.length; i++) { + let id = selected[i].id(); + idMappingForHighlight[id] = id; + } + this.fillMultiObjTable(selected, hasNode, idMappingForHighlight, isNeed2Filter); } - this.selectedClasses = classNames; - this.selectedItemProps.length = 0; - this.selectedItemPropsURL.length = 0; + renderObjectProps(props, classNames, selectedCount) { - let propKeys = Object.keys(props); - // get ordered keys if only one item is selected - if (selectedCount === 1) { - propKeys = this.orderPropertyKeysIf1Selected(classNames) || propKeys; - } - const properties = this._g.dataModel.getValue(); - for (const key of propKeys) { + if (classNames && classNames.length > 0) { + classNames = classNames.join(' & '); + } - // Replace - and _ with space - let renderedKey = key.replace(/[_\-]/g, ' '); - let renderedValue = props[key]; + this.selectedClasses = classNames; + this.selectedItemProps.length = 0; - const attributeType = findTypeOfAttribute(key, properties.nodes, properties.edges); - if (attributeType === 'datetime') { - if ( typeof renderedValue !== 'undefined' && renderedValue < 2208988800000) { - renderedValue = new Date(renderedValue).toLocaleString(); - } else { - renderedValue = '-'; - } - - } - if (key === 'url') { - this.selectedItemPropsURL.push({ key: renderedKey, val: renderedValue }); + let propKeys = Object.keys(props); + // get ordered keys if only one item is selected + if (selectedCount === 1) { + propKeys = this.orderPropertyKeysIf1Selected(classNames) || propKeys; } + const properties = this._g.dataModel.getValue(); + for (const key of propKeys) { + + // Replace - and _ with space + let renderedKey = key.replace(/[_\-]/g, ' '); + let renderedValue = props[key]; + + const attributeType = findTypeOfAttribute(key, properties.nodes, properties.edges); + if (attributeType === 'datetime') { + if (typeof renderedValue !== 'undefined') { + renderedValue = new Date(renderedValue).toLocaleString(); + } else { + renderedValue = ''; + } + } - if (key.toLowerCase() === DATE_PROP_START || - key.toLowerCase() === DATE_PROP_END) { - this.selectedItemProps.push({ key: renderedKey, val: renderedValue }); - this.handleSelectedItemChange() - continue; - } - renderedValue = this.getMappedProperty(this.selectedClasses, key, renderedValue); - if (key != 'url') { + if (key.toLowerCase() === DATE_PROP_START || + key.toLowerCase() === DATE_PROP_END) { + this.selectedItemProps.push({ key: renderedKey, val: renderedValue }); + continue; + } + renderedValue = this.getMappedProperty(this.selectedClasses, key, renderedValue); this.selectedItemProps.push({ key: renderedKey, val: renderedValue }); - this.handleSelectedItemChange() } - } -} - -toggleReportTab() { - this.openReportTab = !this.openReportTab; -} -// get common key-value pairs for non-nested properties -getCommonObjectProps(eleList) { - let superObj = {}; - let superClassNames = {}; - let commonProps = {}; - let commonClassNames = []; - let firstElem = null; - - // Assume ele is instance of Cytoscape.js element - eleList.forEach(ele => { - const e = ele.json(); - const data = e.data; - const classes = e.classes; - const classArray = classes.split(' '); - - // construct superClassNames - for (let i = 0; i < classArray.length; i++) { - const c = classArray[i]; - if (superClassNames[c]) { - superClassNames[c] += 1; - } else { - superClassNames[c] = 1; + + // get common key-value pairs for non-nested properties + getCommonObjectProps(eleList) { + let superObj = {}; + let superClassNames = {}; + let commonProps = {}; + let commonClassNames = []; + let firstElem = null; + + // Assume ele is instance of Cytoscape.js element + eleList.forEach(ele => { + const e = ele.json(); + const data = e.data; + const classes = e.classes; + const classArray = classes.split(' '); + + // construct superClassNames + for (let i = 0; i < classArray.length; i++) { + const c = classArray[i]; + if (superClassNames[c]) { + superClassNames[c] += 1; + } else { + superClassNames[c] = 1; + } } - } - if (firstElem === null) { - firstElem = extend(firstElem, data); - } + if (firstElem === null) { + firstElem = extend(firstElem, data); + } - if (eleList.length === 1) { - commonClassNames = classArray; - return; - } + if (eleList.length === 1) { + commonClassNames = classArray; + return; + } - // count common key-value pairs - this.countKeyValuePairs(data, superObj); - }); + // count common key-value pairs + this.countKeyValuePairs(data, superObj); + }); - if (eleList.length === 1) { - return [firstElem, commonClassNames]; - } + if (eleList.length === 1) { + return [firstElem, commonClassNames]; + } - const eleCount = eleList.length; + const eleCount = eleList.length; - // get common key-value pairs - for (const [k, v] of Object.entries(superObj)) { - for (const [, v2] of Object.entries(v)) { - if (v2 === eleCount) { - commonProps[k] = firstElem[k]; + // get common key-value pairs + for (const [k, v] of Object.entries(superObj)) { + for (const [, v2] of Object.entries(v)) { + if (v2 === eleCount) { + commonProps[k] = firstElem[k]; + } } } - } - // get common class names - for (const [k, v] of Object.entries(superClassNames)) { - if (v === eleCount) { - commonClassNames.push(k); + // get common class names + for (const [k, v] of Object.entries(superClassNames)) { + if (v === eleCount) { + commonClassNames.push(k); + } } - } - return [commonProps, commonClassNames]; -} + return [commonProps, commonClassNames]; + } -countKeyValuePairs(data, superObj) { - for (const [k, v] of Object.entries(data)) { - const valueProperty = v + ''; - if (superObj[k]) { - if (superObj[k][valueProperty]) { - superObj[k][valueProperty] += 1; + countKeyValuePairs(data, superObj) { + for (const [k, v] of Object.entries(data)) { + const valueProperty = v + ''; + if (superObj[k]) { + if (superObj[k][valueProperty]) { + superObj[k][valueProperty] += 1; + } else { + superObj[k][valueProperty] = 1 + } } else { - superObj[k][valueProperty] = 1 + const o2 = {}; + o2[valueProperty] = 1; + superObj[k] = o2; } - } else { - const o2 = {}; - o2[valueProperty] = 1; - superObj[k] = o2; } } -} - -orderPropertyKeysIf1Selected(classNames) { - const properties = this._g.dataModel.getValue(); - const nodeProps = properties.nodes[classNames]; - const edgeProps = properties.edges[classNames]; - if (nodeProps) { - return Object.keys(nodeProps); - } else if (edgeProps) { - return Object.keys(edgeProps); - } - return null; -} - -getMappedProperty(className: string, propertyName: string, propertyValue: string): string { - const enumMap = this._g.getEnumMapping(); - let classes = Object.keys(enumMap); - let c = classes.find(x => x == className); - if (!c) { - return propertyValue; + + orderPropertyKeysIf1Selected(classNames) { + const properties = this._g.dataModel.getValue(); + const nodeProps = properties.nodes[classNames]; + const edgeProps = properties.edges[classNames]; + if (nodeProps) { + return Object.keys(nodeProps); + } else if (edgeProps) { + return Object.keys(edgeProps); + } + return null; } - const mapping = enumMap[c][propertyName]; - if (!mapping) { + getMappedProperty(className: string, propertyName: string, propertyValue: string): string { + const enumMap = this._g.getEnumMapping(); + let classes = Object.keys(enumMap); + let c = classes.find(x => x == className); + if (!c) { + return propertyValue; + } + + const mapping = enumMap[c][propertyName]; + if (!mapping) { + return propertyValue; + } + const val = enumMap[c][propertyName][propertyValue]; + if (val != null || val != undefined) { + return val; + } return propertyValue; } - const val = enumMap[c][propertyName][propertyValue]; - if (val != null || val != undefined) { - return val; - } - return propertyValue; -} - -showStats() { - let stat = {}; - let classSet = new Set(); - let elems = this._g.cy.$(); - for (let i = 0; i < elems.length; i++) { - let curr = elems[i]; - let c = curr.classes(); - let isSelected = curr.selected(); - let isVisible = curr.visible(); - for (let j = 0; j < c.length; j++) { - if (!this.nodeClasses.has(c[j]) && !this.edgeClasses.has(c[j]) && c[j] != COLLAPSED_EDGE_CLASS) { - continue; - } - classSet.add(c[j]); - let TYPE_CLASS = curr.isNode() ? this.NODE_TYPE : this.EDGE_TYPE; - this.increaseCountInObj(stat, TYPE_CLASS, 'total'); - this.increaseCountInObj(stat, c[j], 'total'); - - if (isSelected) { - this.increaseCountInObj(stat, c[j], 'selected'); - this.increaseCountInObj(stat, TYPE_CLASS, 'selected'); - } - if (!isVisible) { - this.increaseCountInObj(stat, c[j], 'hidden'); - this.increaseCountInObj(stat, TYPE_CLASS, 'hidden'); + + showStats() { + let stat = {}; + let classSet = new Set(); + let elems = this._g.cy.$(); + for (let i = 0; i < elems.length; i++) { + let curr = elems[i]; + let c = curr.classes(); + let isSelected = curr.selected(); + let isVisible = curr.visible(); + for (let j = 0; j < c.length; j++) { + if (!this.nodeClasses.has(c[j]) && !this.edgeClasses.has(c[j]) && c[j] != COLLAPSED_EDGE_CLASS) { + continue; + } + classSet.add(c[j]); + let TYPE_CLASS = curr.isNode() ? this.NODE_TYPE : this.EDGE_TYPE; + this.increaseCountInObj(stat, TYPE_CLASS, 'total'); + this.increaseCountInObj(stat, c[j], 'total'); + + if (isSelected) { + this.increaseCountInObj(stat, c[j], 'selected'); + this.increaseCountInObj(stat, TYPE_CLASS, 'selected'); + } + if (!isVisible) { + this.increaseCountInObj(stat, c[j], 'hidden'); + this.increaseCountInObj(stat, TYPE_CLASS, 'hidden'); + } } } + classSet.add(this.NODE_TYPE); + classSet.add(this.EDGE_TYPE); + this.setStatStrFromObj(stat, classSet); + this.isShowStatsTable = elems.length > 0; } - classSet.add(this.NODE_TYPE); - classSet.add(this.EDGE_TYPE); - this.setStatStrFromObj(stat, classSet); - this.isShowStatsTable = elems.length > 0; -} private setStatStrFromObj(stat, classSet: Set) { - this.tableInput.results = []; - this.tableInput.classNames = []; - for (let c of classSet) { - if (stat[c] === undefined) { - continue; - } - let cySelector = '.' + c; - // first element must be ID, ID is irrelevant here - let row: TableData[] = [{ val: cySelector, type: TableDataType.string }]; - if (c == this.NODE_TYPE) { - row[0].val = 'node'; - row.push({ val: 'Node', type: TableDataType.string }); - } else if (c == this.EDGE_TYPE) { - row[0].val = 'edge'; - row.push({ val: 'Edge', type: TableDataType.string }); - } else if (c == COLLAPSED_EDGE_CLASS) { - row[0].val = '.' + COLLAPSED_EDGE_CLASS; - row.push({ val: 'Meta edge', type: TableDataType.string }); - } else { - row.push({ val: c, type: TableDataType.string }); - } - row.push({ val: stat[c].total, type: TableDataType.number }); + this.tableInput.results = []; + this.tableInput.classNames = []; + for (let c of classSet) { + if (stat[c] === undefined) { + continue; + } + let cySelector = '.' + c; + // first element must be ID, ID is irrelevant here + let row: TableData[] = [{ val: cySelector, type: TableDataType.string }]; + if (c == this.NODE_TYPE) { + row[0].val = 'node'; + row.push({ val: 'Node', type: TableDataType.string }); + } else if (c == this.EDGE_TYPE) { + row[0].val = 'edge'; + row.push({ val: 'Edge', type: TableDataType.string }); + } else if (c == COLLAPSED_EDGE_CLASS) { + row[0].val = '.' + COLLAPSED_EDGE_CLASS; + row.push({ val: 'Meta edge', type: TableDataType.string }); + } else { + row.push({ val: c, type: TableDataType.string }); + } + row.push({ val: stat[c].total, type: TableDataType.number }); - if (stat[c]['selected']) { - row.push({ val: stat[c]['selected'], type: TableDataType.number }); - } else { - row.push({ val: 0, type: TableDataType.number }); + if (stat[c]['selected']) { + row.push({ val: stat[c]['selected'], type: TableDataType.number }); + } else { + row.push({ val: 0, type: TableDataType.number }); + } + if (stat[c]['hidden']) { + row.push({ val: stat[c]['hidden'], type: TableDataType.number }); + } else { + row.push({ val: 0, type: TableDataType.number }); + } + this.tableInput.results.push(row); + this.tableInput.classNames.push(row[1].val); } - if (stat[c]['hidden']) { - row.push({ val: stat[c]['hidden'], type: TableDataType.number }); + this.tableInput.pageSize = this._g.userPrefs.dataPageSize.getValue(); + + // let tableView ngOnInit finish + setTimeout(() => this.tableFilled.next(true), 100); + } + + private increaseCountInObj(obj, p1: string, p2: string) { + if (obj[p1]) { + if (obj[p1][p2] === undefined) { + obj[p1][p2] = 1; + } else { + obj[p1][p2] += 1; + } } else { - row.push({ val: 0, type: TableDataType.number }); + obj[p1] = {}; + obj[p1][p2] = 1; } - this.tableInput.results.push(row); - this.tableInput.classNames.push(row[1].val); } - this.tableInput.pageSize = this._g.userPrefs.dataPageSize.getValue(); - // let tableView ngOnInit finish - setTimeout(() => this.tableFilled.next(true), 100); -} + filterTable(filter: TableFiltering) { + this.showStats(); + filterTableDatas(filter, this.tableInput, this._g.userPrefs.isIgnoreCaseInText.getValue()); + setTimeout(() => this.tableFilled.next(true), 100); + } - private increaseCountInObj(obj, p1: string, p2: string) { - if (obj[p1]) { - if (obj[p1][p2] === undefined) { - obj[p1][p2] = 1; + filterMultiObjTable(filter: TableFiltering) { + if (this._g.cy.edges(':selected').filter('.' + COLLAPSED_EDGE_CLASS).length > 0) { + this.showCompoundEdgeProps(false); } else { - obj[p1][p2] += 1; + this.showMultiObjTable(false); } - } else { - obj[p1] = {}; - obj[p1][p2] = 1; - } -} - -filterTable(filter: TableFiltering) { - this.showStats(); - filterTableDatas(filter, this.tableInput, this._g.userPrefs.isIgnoreCaseInText.getValue()); - setTimeout(() => this.tableFilled.next(true), 100); -} - -filterMultiObjTable(filter: TableFiltering) { - if (this._g.cy.edges(':selected').filter('.' + COLLAPSED_EDGE_CLASS).length > 0) { - this.showCompoundEdgeProps(false); - } else { - this.showMultiObjTable(false); + filterTableDatas(filter, this.multiObjTableInp, this._g.userPrefs.isIgnoreCaseInText.getValue()); + setTimeout(() => this.multiObjTableFilled.next(true), 100); } - filterTableDatas(filter, this.multiObjTableInp, this._g.userPrefs.isIgnoreCaseInText.getValue()); - setTimeout(() => this.multiObjTableFilled.next(true), 100); -} -} +} \ No newline at end of file diff --git a/src/app/visuall/toolbar/toolbar.component.ts b/src/app/visuall/toolbar/toolbar.component.ts index 808d5dd3..75ae23e1 100644 --- a/src/app/visuall/toolbar/toolbar.component.ts +++ b/src/app/visuall/toolbar/toolbar.component.ts @@ -7,7 +7,7 @@ import { QuickHelpModalComponent } from '../popups/quick-help-modal/quick-help-m import { LegendModalComponent } from '../popups/legend-modal/legend-modal.component'; import { GlobalVariableService } from '../global-variable.service'; import { getPropNamesFromObj } from '../constants'; -import { ToolbarCustomizationService } from '../../custom/toolbar-customization.service'; +import { ToolbarCustomizationService } from '../../custom/customization-service/toolbar-customization.service'; import { ToolbarDiv, ToolbarAction } from './itoolbar'; import { Subscription } from 'rxjs'; import { UserProfileService } from '../user-profile.service';