Skip to content

Commit 30b1ecc

Browse files
committed
First implementation
1 parent 07d2f44 commit 30b1ecc

File tree

3 files changed

+119
-53
lines changed

3 files changed

+119
-53
lines changed

web/server/vue-cli/src/components/Report/ReportFilter/Filters/UniqueFilter.vue

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
<template>
2-
<v-checkbox
3-
class="ma-0 py-0"
4-
:hide-details="true"
5-
:input-value="isUnique"
6-
@change="setIsUnique"
7-
>
8-
<template v-slot:label>
9-
Unique reports
10-
<tooltip-help-icon>
11-
This narrows the report list to unique report types. The same bug may
12-
appear several times if it is found in different runs or on different
13-
control paths, i.e. through different function calls. By checking
14-
<b>Unique reports</b>, a report appears only once even if it is found
15-
on several paths or in different runs.
16-
</tooltip-help-icon>
17-
</template>
18-
</v-checkbox>
2+
<div class="d-flex align-center">
3+
<v-select
4+
:value="uniqueMode"
5+
:items="options"
6+
label="Unique reports"
7+
dense
8+
hide-details
9+
class="ma-0 py-0"
10+
@change="setUniqueMode"
11+
/>
12+
<tooltip-help-icon>
13+
This narrows the report list to unique report types. The same bug may
14+
appear several times if it is found in different runs or on different
15+
control paths, i.e. through different function calls. By checking
16+
<b>Unique reports</b>, a report appears only once even if it is found
17+
on several paths or in different runs.
18+
</tooltip-help-icon>
19+
</div>
1920
</template>
2021

2122
<script>
@@ -29,54 +30,61 @@ export default {
2930
data() {
3031
return {
3132
id: "is-unique",
32-
defaultValue: false
33+
defaultValue: "off",
34+
options: [
35+
{ text: "None", value: "off" },
36+
{ text: "By bug hash (old)", value: "hash" },
37+
{ text: "By file & line (new)", value: "fileline" }
38+
]
3339
};
3440
},
3541
3642
computed: {
37-
isUnique() {
38-
return !!this.$store.state[this.namespace].reportFilter.isUnique;
43+
uniqueMode() {
44+
return this.$store.state[this.namespace].reportFilter._uniqueMode || "off";
3945
}
4046
},
4147
4248
methods: {
43-
setIsUnique(isUnique, updateUrl=true) {
44-
this.setReportFilter({ isUnique: isUnique });
49+
setUniqueMode(mode, updateUrl=true) {
50+
const isUnique = mode === "hash" || mode === "fileline";
51+
this.setReportFilter({ isUnique: isUnique, _uniqueMode: mode });
4552
if (updateUrl) {
4653
this.$emit("update:url");
4754
}
4855
},
4956
50-
encodeValue(isUnique) {
51-
return isUnique ? "on" : "off";
57+
encodeValue(mode) {
58+
return mode;
5259
},
5360
5461
decodeValue(state) {
55-
return state === "on" ? true : false;
62+
if (state === "on" || state === "hash") return "hash";
63+
if (state === "fileline") return "fileline";
64+
return "off";
5665
},
5766
5867
getUrlState() {
5968
return {
60-
[this.id]: this.encodeValue(this.isUnique)
69+
[this.id]: this.encodeValue(this.uniqueMode)
6170
};
6271
},
6372
6473
initByUrl() {
6574
return new Promise(resolve => {
6675
const state = this.$route.query[this.id];
6776
if (state) {
68-
const isUnique = this.decodeValue(state);
69-
this.setIsUnique(isUnique, false);
77+
const mode = this.decodeValue(state);
78+
this.setUniqueMode(mode, false);
7079
} else {
71-
this.setIsUnique(this.defaultValue, false);
80+
this.setUniqueMode(this.defaultValue, false);
7281
}
73-
7482
resolve();
7583
});
7684
},
7785
7886
clear(updateUrl) {
79-
this.setIsUnique(this.defaultValue, updateUrl);
87+
this.setUniqueMode(this.defaultValue, updateUrl);
8088
}
8189
}
8290
};

web/server/vue-cli/src/store/modules/base-filter.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Vue from "vue";
12
import { CompareData, DiffType } from "@cc/report-server-types";
23
import {
34
SET_CMP_DATA,
@@ -30,7 +31,9 @@ const mutations = {
3031
state.runIds = runIds;
3132
},
3233
[SET_REPORT_FILTER](state, params) {
33-
Object.assign(state.reportFilter, params);
34+
Object.keys(params).forEach(key => {
35+
Vue.set(state.reportFilter, key, params[key]);
36+
});
3437
},
3538
[SET_CMP_DATA](state, params) {
3639
if (!params) {

web/server/vue-cli/src/views/Reports.vue

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,11 @@ import { Pane, Splitpanes } from "splitpanes";
173173
import { mapGetters } from "vuex";
174174
175175
import { ccService, handleThriftError } from "@cc-api";
176-
import { Checker, Order, SortMode, SortType } from "@cc/report-server-types";
176+
import {
177+
Checker,
178+
MAX_QUERY_SIZE,
179+
Order, SortMode, SortType
180+
} from "@cc/report-server-types";
177181
178182
import { FillHeight } from "@/directives";
179183
import { BugPathLengthColorMixin, DetectionStatusMixin } from "@/mixins";
@@ -313,7 +317,8 @@ export default {
313317
initalized: false,
314318
checkerDocDialog: false,
315319
selectedChecker: null,
316-
expanded: []
320+
expanded: [],
321+
allGroupedReports: []
317322
};
318323
},
319324
@@ -383,6 +388,10 @@ export default {
383388
"chronological_order": report.annotations["chronological_order"]
384389
};
385390
});
391+
},
392+
393+
isUniqueByFileLine() {
394+
return this.reportFilter._uniqueMode === "fileline";
386395
}
387396
},
388397
@@ -491,11 +500,14 @@ export default {
491500
492501
refresh() {
493502
this.expanded = [];
503+
this.allGroupedReports = [];
494504
495-
ccService.getClient().getRunResultCount(this.runIds,
496-
this.reportFilter, this.cmpData, handleThriftError(res => {
497-
this.totalItems = res.toNumber();
498-
}));
505+
if (!this.isUniqueByFileLine) {
506+
ccService.getClient().getRunResultCount(this.runIds,
507+
this.reportFilter, this.cmpData, handleThriftError(res => {
508+
this.totalItems = res.toNumber();
509+
}));
510+
}
499511
500512
if (this.pagination.page !== 1 && this.initalized) {
501513
this.pagination.page = 1;
@@ -507,26 +519,69 @@ export default {
507519
fetchReports() {
508520
this.loading = true;
509521
510-
const limit = this.pagination.itemsPerPage;
511-
const offset = limit * (this.pagination.page - 1);
512522
const sortType = this.getSortMode();
513523
const getDetails = false;
514524
515-
ccService.getClient().getRunResults(this.runIds, limit, offset, sortType,
516-
this.reportFilter, this.cmpData, getDetails,
517-
handleThriftError(reports => {
518-
this.reports = reports;
525+
if (this.isUniqueByFileLine) {
526+
if (this.allGroupedReports.length === 0) {
527+
ccService.getClient().getRunResults(
528+
this.runIds, MAX_QUERY_SIZE, 0, sortType,
529+
this.reportFilter, this.cmpData, getDetails,
530+
handleThriftError(reports => {
531+
const grouped = {};
532+
reports.forEach(report => {
533+
const key = report.checkedFile + ":" +
534+
(report.line ? report.line.toNumber() : 0);
535+
if (!grouped[key]) {
536+
grouped[key] = { ...report, sameReports: [report] };
537+
} else {
538+
grouped[key].sameReports.push(report);
539+
}
540+
});
541+
this.allGroupedReports = Object.values(grouped);
542+
this.totalItems = this.allGroupedReports.length;
543+
544+
this.allGroupedReports.forEach(group => {
545+
this.$set(this.sameReports, group.bugHash,
546+
[...new Set(group.sameReports.map(
547+
r => r.reviewData.status))]);
548+
});
549+
550+
this._applyFileLinePage();
551+
this.loading = false;
552+
this.initalized = true;
553+
}));
554+
} else {
555+
this._applyFileLinePage();
519556
this.loading = false;
520-
this.initalized = true;
521-
522-
reports.forEach(report => {
523-
ccService.getSameReports(report.bugHash).then(sameReports => {
524-
this.$set(
525-
this.sameReports, report.bugHash,
526-
[ ...new Set(sameReports.map(r => r.reviewData.status)) ]);
557+
}
558+
} else {
559+
const limit = this.pagination.itemsPerPage;
560+
const offset = limit * (this.pagination.page - 1);
561+
562+
ccService.getClient().getRunResults(
563+
this.runIds, limit, offset, sortType,
564+
this.reportFilter, this.cmpData, getDetails,
565+
handleThriftError(reports => {
566+
this.reports = reports;
567+
reports.forEach(report => {
568+
ccService.getSameReports(report.bugHash).then(sameReports => {
569+
this.$set(
570+
this.sameReports, report.bugHash,
571+
[ ...new Set(sameReports.map(
572+
r => r.reviewData.status)) ]);
573+
});
527574
});
528-
});
529-
}));
575+
this.loading = false;
576+
this.initalized = true;
577+
}));
578+
}
579+
},
580+
581+
_applyFileLinePage() {
582+
const limit = this.pagination.itemsPerPage;
583+
const offset = limit * (this.pagination.page - 1);
584+
this.reports = this.allGroupedReports.slice(offset, offset + limit);
530585
}
531586
}
532587
};

0 commit comments

Comments
 (0)