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

implement search, fixes #40

parent f88438ed
No related branches found
No related tags found
No related merge requests found
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
createApp({ createApp({
data () { data () {
return { return {
needle: '',
issues, issues,
qmLabels, qmLabels,
filters filters
...@@ -81,6 +82,13 @@ ...@@ -81,6 +82,13 @@
methods: { methods: {
getStateForIssueAndQmLabel(issue, qm) { getStateForIssueAndQmLabel(issue, qm) {
return issue.qm_states[qm]; return issue.qm_states[qm];
},
valueMatchesNeedle(what) {
if (this.needle.length === 0) {
return false;
}
return what.toLowerCase().includes(this.needle.toLowerCase());
} }
}, },
computed: { computed: {
...@@ -88,7 +96,7 @@ ...@@ -88,7 +96,7 @@
return 8 + Object.values(qmLabels).length; return 8 + Object.values(qmLabels).length;
}, },
filteredIssues() { filteredIssues() {
return this.issues.filter(issue => { let filtered = this.issues.filter(issue => {
for (const [key, value] of Object.entries(this.filters)) { for (const [key, value] of Object.entries(this.filters)) {
if (value === null) { if (value === null) {
continue; continue;
...@@ -99,6 +107,19 @@ ...@@ -99,6 +107,19 @@
} }
return true; return true;
}); });
if (this.needle.length > 0) {
filtered = filtered.filter(issue => {
const ciNeedle = this.needle.toLowerCase();
return issue.iid.toString().includes(this.needle)
|| issue.title.toLowerCase().includes(ciNeedle)
|| (issue.assignee ?? '').toLowerCase().includes(ciNeedle)
|| (issue.author ?? '').toLowerCase().includes(ciNeedle)
|| issue.reviewers.some(reviewer => reviewer.toLowerCase().includes(ciNeedle));
});
}
return filtered;
} }
}, },
watch: { watch: {
......
...@@ -23,3 +23,7 @@ ...@@ -23,3 +23,7 @@
padding: 0 0.5em; padding: 0 0.5em;
} }
} }
td.filter-match {
background-color: var(--yellow-20);
}
...@@ -48,7 +48,7 @@ $attributes = [ ...@@ -48,7 +48,7 @@ $attributes = [
</td> </td>
</tr> </tr>
<tr v-for="issue in filteredIssues"> <tr v-for="issue in filteredIssues">
<td> <td :class="{'filter-match': valueMatchesNeedle(issue.iid.toString())}">
<a :href="issue.web_url" target="_blank"> <a :href="issue.web_url" target="_blank">
#{{ issue.iid }} #{{ issue.iid }}
</a> </a>
...@@ -70,14 +70,18 @@ $attributes = [ ...@@ -70,14 +70,18 @@ $attributes = [
<?= Icon::create('date', Icon::ROLE_STATUS_YELLOW) ?> <?= Icon::create('date', Icon::ROLE_STATUS_YELLOW) ?>
</abbr> </abbr>
</td> </td>
<td> <td :class="{'filter-match': valueMatchesNeedle(issue.title)}">
<a :href="issue.web_url" target="_blank"> <a :href="issue.web_url" target="_blank">
{{ issue.title }} {{ issue.title }}
</a> </a>
</td> </td>
<td>{{ issue.author }}</td> <td :class="{'filter-match': valueMatchesNeedle(issue.author)}">
<td>{{ issue.assignee }}</td> {{ issue.author }}
<td> </td>
<td :class="{'filter-match': valueMatchesNeedle(issue.assignee)}">
{{ issue.assignee }}
</td>
<td :class="{'filter-match': valueMatchesNeedle(issue.reviewers.join('||'))}">
<ul v-if="issue.reviewers.length > 0" class="list-csv"> <ul v-if="issue.reviewers.length > 0" class="list-csv">
<li v-for="username in issue.reviewers" :key="`reviewer-${issue.iid}-${username}`">{{ username }}</li> <li v-for="username in issue.reviewers" :key="`reviewer-${issue.iid}-${username}`">{{ username }}</li>
</ul> </ul>
...@@ -92,8 +96,26 @@ $attributes = [ ...@@ -92,8 +96,26 @@ $attributes = [
</table> </table>
<mounting-portal mount-to="#layout-sidebar .sidebar" name="sidebar-filter" append> <mounting-portal mount-to="#layout-sidebar .sidebar" name="sidebar-filter" append>
<div class="sidebar-widget sidebar-search">
<div class="sidebar-widget-header"><?= _('Suche') ?></div>
<div class="sidebar-widget-content">
<form action="#" @submit="event => event.preventDefault()">
<ul class="needles">
<li>
<div class="input-group files-search">
<input type="text" v-model.trim="needle" placeholder="<?= _('Suchwort') ?>">
<button class="submit-search" type="submit" title="<?= _('Suche auführen') ?>">
<?= Icon::create('search')->asImg(20) ?>
</button>
</div>
</li>
</ul>
</form>
</div>
</div>
<div class="sidebar-widget"> <div class="sidebar-widget">
<div class="sidebar-widget-header">Filter</div> <div class="sidebar-widget-header"><?= _('Filter') ?></div>
<div class="sidebar-widget-content"> <div class="sidebar-widget-content">
<label v-for="(abbr, label) in qmLabels" style="display: block;"> <label v-for="(abbr, label) in qmLabels" style="display: block;">
{{ label }} {{ label }}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment