Web: add filter bar for job status

This commit is contained in:
Sybren A. Stüvel 2022-05-16 18:15:51 +02:00
parent 9fd4d55fdb
commit 163611ff19
3 changed files with 71 additions and 22 deletions

View File

@ -283,13 +283,33 @@ footer {
.indicator {
--indicator-color: var(--color-background);
--indicator-size: 6px;
background-color: var(--indicator-color);
border: 3px solid var(--indicator-color);
border: calc(var(--indicator-size)/2) solid var(--indicator-color);
border-radius: 50%;
display: block;
height: 6px;
width: 6px;
height: var(--indicator-size);
width: var(--indicator-size);
}
ul.status-filter-bar {
align-items: center;
display: flex;
list-style-type: none;
padding: 0;
margin: 0.3rem 0;
}
ul.status-filter-bar .status-filter-indicator {
margin: 2px;
opacity: 33%;
cursor: pointer;
}
ul.status-filter-bar .status-filter-indicator.active {
opacity: 100%;
}
ul.status-filter-bar .status-filter-indicator .indicator {
--indicator-size: 15px;
}
.status-active {
@ -351,11 +371,3 @@ footer {
.tabulator-row.active-row.tabulator-row-even {
background-color: var(--table-color-background-row-active-even);
}
ul.status-filter-bar {
align-items: center;
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
}

View File

@ -2,6 +2,11 @@
<div>
<h2 class="column-title">Jobs</h2>
<job-actions-bar />
<status-filter-bar
:availableStatuses="availableStatuses"
:activeStatuses="shownStatuses"
@click="toggleStatusFilter"
/>
<div class="job-list" id="flamenco_job_list"></div>
</div>
</template>
@ -10,21 +15,24 @@
import { TabulatorFull as Tabulator } from 'tabulator-tables';
import * as datetime from "@/datetime";
import * as API from '@/manager-api'
import { toTitleCase } from '@/strings';
import { indicator } from '@/statusindicator';
import { apiClient } from '@/stores/api-query-count';
import JobActionsBar from '@/components/JobActionsBar.vue'
import StatusFilterBar from '@/components/StatusFilterBar.vue'
export default {
name: 'JobsTable',
props: ["activeJobID"],
emits: ["tableRowClicked"],
components: {
JobActionsBar,
JobActionsBar, StatusFilterBar,
},
data: () => {
return {
filteredStatuses: new Set(),
shownStatuses: [],
availableStatuses: [], // Will be filled after data is loaded from the backend.
indicator: indicator, // So that the template can use this function too.
};
},
mounted() {
@ -111,16 +119,19 @@ export default {
// "Down-cast" to JobUpdate to only get those fields, just for debugging things:
// data.jobs = data.jobs.map((j) => API.JobUpdate.constructFromObject(j));
this.tabulator.setData(data.jobs);
this._refreshAvailableStatuses();
},
processJobUpdate(jobUpdate) {
// updateData() will only overwrite properties that are actually set on
// jobUpdate, and leave the rest as-is.
this.tabulator.updateData([jobUpdate])
.then(this.sortData);
this._refreshAvailableStatuses();
},
processNewJob(jobUpdate) {
this.tabulator.addData([jobUpdate])
.then(this.sortData);
this._refreshAvailableStatuses();
},
onRowClick(event, row) {
@ -132,23 +143,31 @@ export default {
// Depending on which cell was clicked, take a different action.
const columnName = event.target.getAttribute("tabulator-field");
if (columnName == "status") {
this._toggleStatusFilter(rowData.status);
this.toggleStatusFilter(rowData.status);
return;
}
this.$emit("tableRowClicked", rowData);
},
_toggleStatusFilter(status) {
if (!this.filteredStatuses.delete(status)) {
this.filteredStatuses.add(status);
toggleStatusFilter(status) {
const asSet = new Set(this.shownStatuses);
if (!asSet.delete(status)) {
asSet.add(status);
}
this.shownStatuses = Array.from(asSet).sort();
this.tabulator.refreshFilter();
},
_filterByStatus(job) {
if (this.filteredStatuses.size) {
return this.filteredStatuses.has(job.status);
}
if (this.shownStatuses.length == 0) {
return true;
}
return this.shownStatuses.indexOf(job.status) >= 0;
},
_refreshAvailableStatuses() {
const statuses = new Set();
for (let row of this.tabulator.getData()) {
statuses.add(row.status);
}
this.availableStatuses = Array.from(statuses).sort();
},
_reformatRow(jobID) {

View File

@ -0,0 +1,18 @@
<script setup>
import { ref } from 'vue'
import { indicator } from '@/statusindicator';
defineProps(['availableStatuses', 'activeStatuses']);
const emit = defineEmits(['click'])
</script>
<template>
<ul class="status-filter-bar">
<li v-for="status in availableStatuses" class="status-filter-indicator"
:data-status="status"
:class="{active: activeStatuses.indexOf(status) >= 0}"
@click="emit('click', status)"
v-html="indicator(status)"
></li>
</ul>
</template>