diff --git a/assets/script.js b/assets/script.js index 223d986ac31cce5bbd543c113adb4d333d3241bc..bdc498376c06a66018a05f92d9fcdcb16632c3b6 100644 --- a/assets/script.js +++ b/assets/script.js @@ -60,7 +60,7 @@ const dashboard = document.getElementById('dashboard'); const issues = JSON.parse(dashboard.dataset.issues); const qmLabels = JSON.parse(dashboard.dataset.qmLabels); - const filters = JSON.parse(dashboard.dataset.filters); + const filters = JSON.parse(dashboard.dataset.filters) || {}; const filterStoreUrl = dashboard.dataset.filterStoreUrl; Object.values(qmLabels).forEach(abbr => { @@ -85,7 +85,7 @@ }, computed: { colspan() { - return 7 + Object.values(qmLabels).length; + return 8 + Object.values(qmLabels).length; }, filteredIssues() { return this.issues.filter(issue => { diff --git a/lib/GitlabIssue.php b/lib/GitlabIssue.php index 9571ec2085f05966a92b12e02d3bf937a4ee2e5c..2b3fd340b740f9dd1de3dba96e569e3708aa58f3 100644 --- a/lib/GitlabIssue.php +++ b/lib/GitlabIssue.php @@ -117,6 +117,19 @@ final class GitlabIssue implements \JsonSerializable 'closed' => $this->isClosed(), 'merge_requests' => count($this->mrs), 'merged' => $this->isMerged(), + 'reviewers' => array_reduce($this->mrs, function ($reviewers, $mr) { + if (!isset($mr['reviewers'])) { + return $reviewers; + } + + foreach ($mr['reviewers'] as $reviewer) { + if (!in_array($reviewer['username'], $reviewers)) { + $reviewers[] = $reviewer['username']; + } + } + + return $reviewers; + }, []), 'qm_states' => array_combine( array_values(self::QM_LABEL_MAPPING), array_map(function ($qm) { diff --git a/views/dashboard/index.php b/views/dashboard/index.php index c37441309e76f5bfaab4e991baeef384f07039f0..2359f1d2a7770d9e95f1e4cdbfc1b24f1ea55d86 100644 --- a/views/dashboard/index.php +++ b/views/dashboard/index.php @@ -9,12 +9,18 @@ $attributes = [ 'data-issues' => json_encode($issues), 'data-qm-labels' => json_encode($mapping), - 'data-filters' => json_encode($filters), + 'data-filters' => json_encode($filters ?: null), 'data-filter-store-url' => $controller->store_filtersURL(), ]; ?> <div id="dashboard" v-cloak <?= arrayToHtmlAttributes($attributes) ?>> <table class="default"> + <caption> + <span v-if="filteredIssues.length !== issues.length"> + {{ filteredIssues.length }} <?= _('von') ?> + </span> + {{ issues.length }} Issues + </caption> <thead> <tr> <th><?= _('Issue') ?></th> @@ -24,6 +30,7 @@ $attributes = [ <th><?= _('Titel') ?></th> <th><?= _('Autor') ?></th> <th><?= _('Bearbeiter') ?></th> + <th><?= _('Reviewer') ?></th> <th v-for="(abbr, label) in qmLabels"> <abbr :title="label">{{ abbr }}</abbr> </th> @@ -70,6 +77,11 @@ $attributes = [ </td> <td>{{ issue.author }}</td> <td>{{ issue.assignee }}</td> + <td> + <ul v-if="issue.reviewers.length > 0" class="list-csv"> + <li v-for="username in issue.reviewers" :key="`reviewer-${issue.iid}-${username}`">{{ username }}</li> + </ul> + </td> <td v-for="(abbr, label) in qmLabels"> <studip-icon shape="accept" role="status-green" v-if="getStateForIssueAndQmLabel(issue, abbr) === '+'"></studip-icon> <studip-icon shape="question" role="status-yellow" v-else-if="getStateForIssueAndQmLabel(issue, abbr) === '?'"></studip-icon>