Skip to content
Snippets Groups Projects
Commit ab50c855 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

fixes #17

parent 0781fd2d
Branches
No related tags found
No related merge requests found
...@@ -5,10 +5,7 @@ ...@@ -5,10 +5,7 @@
var lastRequestController = null; var lastRequestController = null;
$(document).ready(function () { $(document).ready(function () {
if (document.getElementById('trac-migrate') === null) { if (document.getElementById('trac-migrate') !== null) {
return;
}
let source = null; let source = null;
STUDIP.loadChunk('vue').then(function ({createApp}) { STUDIP.loadChunk('vue').then(function ({createApp}) {
createApp({ createApp({
...@@ -39,11 +36,7 @@ ...@@ -39,11 +36,7 @@
clearTimeout(searchTimeout); clearTimeout(searchTimeout);
searchTimeout = setTimeout(function () { searchTimeout = setTimeout(function () {
const url = STUDIP.URLHelper.getURL(source, {term: needle}); const url = STUDIP.URLHelper.getURL(source, {term: needle});
fetch(url, { signal }).then(function (response) { fetch(url, { signal }).then(response => this.results = response.json());
return response.json();
}).then(function (json) {
this.results = json;
}.bind(this));
}.bind(this), 300); }.bind(this), 300);
} }
}, },
...@@ -63,5 +56,45 @@ ...@@ -63,5 +56,45 @@
} }
}).$mount('#trac-migrate'); }).$mount('#trac-migrate');
}); });
} else if (document.getElementById('dashboard') !== null) {
const dashboard = document.getElementById('dashboard');
const issues = JSON.parse(dashboard.dataset.issues);
const qmLabels = JSON.parse(dashboard.dataset.qmLabels);
let filters = {};
Object.values(qmLabels).forEach(abbr => filters[abbr] = null);
STUDIP.loadChunk('vue').then(({createApp}) => {
createApp({
data () {
return {
issues,
qmLabels,
filters
};
},
methods: {
getStateForIssueAndQmLabel(issue, qm) {
return issue.qm_states[qm];
},
},
computed: {
filteredIssues() {
return this.issues.filter(issue => {
for (const [key, value] of Object.entries(this.filters)) {
if (value === null) {
continue;
}
if (issue.qm_states[key] !== value) {
return false;
}
}
return true;
});
}
}
}).$mount('#dashboard');
});
}
}); });
}(jQuery, STUDIP)); }(jQuery, STUDIP));
<?php <?php
final class DashboardController extends TracToGitlab\Controller final class DashboardController extends TracToGitlab\Controller
{ {
const QM_LABEL_MAPPING = [
'Anwendungs-Doku' => 'userdoc',
'Barrierefreiheit' => 'a11y',
'Code-Review' => 'code',
'Entwicklungs-Doku' => 'devdoc',
'Funktionalität' => 'func',
'GUI-Richtlinien' => 'gui',
'Schnittstellen' => 'iface',
'Textstrings' => 'text',
];
public function before_filter(&$action, &$args) public function before_filter(&$action, &$args)
{ {
parent::before_filter($action, $args); parent::before_filter($action, $args);
...@@ -152,6 +141,6 @@ final class DashboardController extends TracToGitlab\Controller ...@@ -152,6 +141,6 @@ final class DashboardController extends TracToGitlab\Controller
private function getQMLabelMapping() private function getQMLabelMapping()
{ {
return self::QM_LABEL_MAPPING; return TracToGitlab\GitlabIssue::QM_LABEL_MAPPING;
} }
} }
<?php <?php
namespace TracToGitlab; namespace TracToGitlab;
final class GitlabIssue final class GitlabIssue implements \JsonSerializable
{ {
const QM_LABEL_MAPPING = [
'Anwendungs-Doku' => 'userdoc',
'Barrierefreiheit' => 'a11y',
'Code-Review' => 'code',
'Entwicklungs-Doku' => 'devdoc',
'Funktionalität' => 'func',
'GUI-Richtlinien' => 'gui',
'Schnittstellen' => 'iface',
'Textstrings' => 'text',
];
private $issue; private $issue;
private $mrs; private $mrs;
...@@ -36,7 +47,7 @@ final class GitlabIssue ...@@ -36,7 +47,7 @@ final class GitlabIssue
return $this->issue[$offset] ?? null; return $this->issue[$offset] ?? null;
} }
public function isClosed() public function isClosed(): bool
{ {
return $this->issue['state'] !== 'opened'; return $this->issue['state'] !== 'opened';
} }
...@@ -69,11 +80,9 @@ final class GitlabIssue ...@@ -69,11 +80,9 @@ final class GitlabIssue
return in_array('StEP', $this->issue['labels']); return in_array('StEP', $this->issue['labels']);
} }
public function getIconForQMLabel(string $label) public function getIconForQMLabel(string $label): string
{ {
foreach ($this->issue['labels'] as $l) { $state = $this->getStateForQMLabel($label);
if (preg_match("/^QM::{$label}::(.)$/", $l, $match)) {
$state = $match[1];
if ($state === '+') { if ($state === '+') {
return \Icon::create('accept', \Icon::ROLE_STATUS_GREEN); return \Icon::create('accept', \Icon::ROLE_STATUS_GREEN);
} }
...@@ -83,8 +92,39 @@ final class GitlabIssue ...@@ -83,8 +92,39 @@ final class GitlabIssue
if ($state === '-') { if ($state === '-') {
return \Icon::create('decline', \Icon::ROLE_STATUS_RED); return \Icon::create('decline', \Icon::ROLE_STATUS_RED);
} }
return '';
}
public function getStateForQMLabel(string $label): ?string
{
foreach ($this->issue['labels'] as $l) {
if (preg_match("/^QM::{$label}::(.)$/", $l, $match)) {
return $match[1];
}
} }
return null;
} }
return '';
public function jsonSerialize()
{
$result = [
'iid' => $this->iid,
'title' => $this->title,
'type' => $this->type,
'author' => $this->author['username'],
'assignee' => $this->assignee,
'web_url' => $this->web_url,
'closed' => $this->isClosed(),
'merge_requests' => $this->issue['merge_requests_count'],
'merged' => $this->isMerged(),
'qm_states' => array_combine(
array_values(self::QM_LABEL_MAPPING),
array_map(function ($qm) {
return $this->getStateForQMLabel($qm);
}, array_keys(self::QM_LABEL_MAPPING))
),
];
return $result;
} }
} }
pluginname=Trac to gitlab converter pluginname=Trac to gitlab converter
pluginclassname=TracToGitlabPlugin pluginclassname=TracToGitlabPlugin
origin=UOL origin=UOL
version=1.2 version=1.3
studipMinVersion=5.0 studipMinVersion=5.0
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* @var array<int, TracToGitlab\GitlabIssue> $issues * @var array<int, TracToGitlab\GitlabIssue> $issues
*/ */
?> ?>
<div id="dashboard" data-issues='<?= json_encode($issues) ?>' data-qm-labels='<?= json_encode($mapping) ?>' v-cloak>
<table class="default"> <table class="default">
<thead> <thead>
<tr> <tr>
...@@ -14,13 +15,9 @@ ...@@ -14,13 +15,9 @@
<th><?= _('Titel') ?></th> <th><?= _('Titel') ?></th>
<th><?= _('Autor') ?></th> <th><?= _('Autor') ?></th>
<th><?= _('Bearbeiter') ?></th> <th><?= _('Bearbeiter') ?></th>
<? foreach ($mapping as $label => $abbrevation): ?> <th v-for="(abbr, label) in qmLabels">
<th> <abbr :title="label">{{ abbr }}</abbr>
<abbr title="<?= htmlReady($label) ?>">
<?= htmlReady($abbrevation) ?>
</abbr>
</th> </th>
<? endforeach; ?>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -31,49 +28,60 @@ ...@@ -31,49 +28,60 @@
</td> </td>
</tr> </tr>
<? endif; ?> <? endif; ?>
<? foreach ($issues as $issue): ?> <tr v-for="issue in filteredIssues">
<tr>
<td> <td>
<a href="<?= htmlReady($issue->web_url) ?>" target="_blank"> <a :href="issue.web_url" target="_blank">
#<?= htmlReady($issue->iid) ?> #{{ issue.iid }}
</a> </a>
</td> </td>
<td><?= htmlReady($issue->type) ?></td> <td>{{ issue.type }}</td>
<td> <td>{{ issue.closed ? 'closed' : 'open' }}</td>
<? if ($issue->isClosed()): ?> <td v-if="!issue.merge_requests">
closed
<? else: ?>
open
<? endif; ?>
</td>
<td>
<? if (!$issue->hasMergeRequests()): ?>
<abbr title="<?= _('Kein MR') ?>"> <abbr title="<?= _('Kein MR') ?>">
<?= Icon::create('decline', Icon::ROLE_STATUS_RED) ?> <?= Icon::create('decline', Icon::ROLE_STATUS_RED) ?>
</abbr> </abbr>
<? elseif ($issue->isMerged()): ?> </td>
<td v-else-if="issue.merged">
<abbr title="<?= _('MR bereits gemerget') ?>"> <abbr title="<?= _('MR bereits gemerget') ?>">
<?= Icon::create('accept', Icon::ROLE_STATUS_GREEN) ?> <?= Icon::create('accept', Icon::ROLE_STATUS_GREEN) ?>
</abbr> </abbr>
<? else: ?> </td>
<td v-else>
<abbr title="<?= _('MR noch nicht gemerget') ?>"> <abbr title="<?= _('MR noch nicht gemerget') ?>">
<?= Icon::create('date', Icon::ROLE_STATUS_YELLOW) ?> <?= Icon::create('date', Icon::ROLE_STATUS_YELLOW) ?>
</abbr> </abbr>
<? endif; ?>
</td> </td>
<td> <td>
<a href="<?= htmlReady($issue->web_url) ?>" target="_blank"> <a :href="issue.web_url" target="_blank">
<?= htmlReady($issue->title) ?> {{ issue.title }}
</a> </a>
</td> </td>
<td><?= htmlReady($issue->author['username']) ?></td> <td>{{ issue.author }}</td>
<td><?= htmlReady($issue->assignee) ?></td> <td>{{ issue.assignee }}</td>
<? foreach ($mapping as $label => $abbrevation): ?> <td v-for="(abbr, label) in qmLabels">
<td> <studip-icon shape="accept" role="status-green" v-if="getStateForIssueAndQmLabel(issue, abbr) === '+'"></studip-icon>
<?= $issue->getIconForQMLabel($label) ?> <studip-icon shape="question" role="status-yellow" v-else-if="getStateForIssueAndQmLabel(issue, abbr) === '?'"></studip-icon>
<studip-icon shape="decline" role="status-red" v-else-if="getStateForIssueAndQmLabel(issue, abbr) === '-'"></studip-icon>
</td> </td>
<? endforeach; ?>
</tr> </tr>
<? endforeach; ?> </tr>
</tbody> </tbody>
</table> </table>
<mounting-portal mount-to="#layout-sidebar .sidebar" name="sidebar-filter" append>
<div class="sidebar-widget">
<div class="sidebar-widget-header">Filter</div>
<div class="sidebar-widget-content">
<label v-for="(abbr, label) in qmLabels" style="display: block;">
{{ label }}
<select v-model="filters[abbr]" style="display: block;" class="sidebar-selectlist">
<option :value="null"></option>
<option>+</option>
<option>?</option>
<option>-</option>
</select>
</label>
</div>
</div>
</mounting-portal>
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment