Web: show job blocklist
The blocklist is now shown in the job details, in its own tab. The list is only fetched when the tab is visible, and doesn't get dynamically updated yet.
This commit is contained in:
parent
f3aab8611c
commit
b6d8882b8e
@ -1,8 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-link :to="{ name: 'workers', params: { workerID: worker.id } }">{{ worker.name }} ({{ worker.address }})</router-link>
|
<router-link :to="{ name: 'workers', params: { workerID: worker.id } }">
|
||||||
|
{{ worker.name }}{{ workerAddress }}
|
||||||
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
// 'worker' should be a Worker or TaskWorker (see schemas defined in `flamenco-openapi.yaml`).
|
// 'worker' should be a Worker or TaskWorker (see schemas defined in `flamenco-openapi.yaml`).
|
||||||
const props = defineProps(['worker']);
|
const props = defineProps(['worker']);
|
||||||
|
const workerAddress = computed(() => {
|
||||||
|
if (props.worker.address) return `(${props.worker.address})`;
|
||||||
|
return "";
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { inject } from "vue";
|
import { inject, computed, provide } from "vue";
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: String,
|
title: String,
|
||||||
});
|
});
|
||||||
const selectedTitle = inject("selectedTitle");
|
const selectedTitle = inject("selectedTitle");
|
||||||
|
const isVisible = computed(() => selectedTitle.value === props.title)
|
||||||
|
provide("isVisible", isVisible);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-show="selectedTitle === title">
|
<div v-show="isVisible">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
91
web/app/src/components/jobs/Blocklist.vue
Normal file
91
web/app/src/components/jobs/Blocklist.vue
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="isFetching" class="dl-no-data">
|
||||||
|
<span>Fetching blocklist...</span>
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<table class="blocklist" v-if="blocklist.length">
|
||||||
|
<tr>
|
||||||
|
<th>Worker</th>
|
||||||
|
<th>Task Type</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="entry in blocklist">
|
||||||
|
<td>
|
||||||
|
<link-worker :worker="{ id: entry.worker_id, name: entry.worker_name }" />
|
||||||
|
</td>
|
||||||
|
<td>{{ entry.task_type }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div v-else class="dl-no-data">
|
||||||
|
<span>This job has no blocked workers.</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<p v-if="errorMsg" class="error">Error fetching blocklist: {{ errorMsg }}</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { apiClient } from '@/stores/api-query-count';
|
||||||
|
import { JobsApi } from '@/manager-api';
|
||||||
|
import LinkWorker from '@/components/LinkWorker.vue';
|
||||||
|
import { watch, onMounted, inject, ref } from 'vue'
|
||||||
|
|
||||||
|
// jobID should be the job UUID string.
|
||||||
|
const props = defineProps(['jobID']);
|
||||||
|
const jobsApi = new JobsApi(apiClient);
|
||||||
|
const isVisible = inject("isVisible");
|
||||||
|
const isFetching = ref(false);
|
||||||
|
const errorMsg = ref("");
|
||||||
|
const blocklist = ref([]);
|
||||||
|
|
||||||
|
function refreshBlocklist() {
|
||||||
|
if (!isVisible.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isFetching.value = true;
|
||||||
|
jobsApi.fetchJobBlocklist(props.jobID)
|
||||||
|
.then((newBlocklist) => {
|
||||||
|
console.log(`received blocklist for job ${props.jobID}`, newBlocklist);
|
||||||
|
blocklist.value = newBlocklist;
|
||||||
|
// TODO: remit 'reshuffled' & handle in parent.
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
errorMsg.value = error.message;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
isFetching.value = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.jobID, refreshBlocklist);
|
||||||
|
watch(isVisible, refreshBlocklist);
|
||||||
|
onMounted(refreshBlocklist);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
table.blocklist {
|
||||||
|
width: 100%;
|
||||||
|
font-family: var(--font-family-mono);
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.blocklist td,
|
||||||
|
table.blocklist th {
|
||||||
|
text-align: left;
|
||||||
|
padding: calc(var(--spacer-sm)/2) var(--spacer-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.blocklist th {
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.blocklist tr {
|
||||||
|
background-color: var(--table-color-background-row);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.blocklist tr:nth-child(odd) {
|
||||||
|
background-color: var(--table-color-background-row-odd);
|
||||||
|
}
|
||||||
|
</style>
|
@ -54,6 +54,9 @@
|
|||||||
<dd>{{ jobData.activity }}</dd>
|
<dd>{{ jobData.activity }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
<TabItem title="Blocklist">
|
||||||
|
<blocklist :jobID="jobData.id" />
|
||||||
|
</TabItem>
|
||||||
</TabsWrapper>
|
</TabsWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -67,6 +70,7 @@ import * as datetime from "@/datetime";
|
|||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { apiClient } from '@/stores/api-query-count';
|
||||||
import LastRenderedImage from '@/components/jobs/LastRenderedImage.vue'
|
import LastRenderedImage from '@/components/jobs/LastRenderedImage.vue'
|
||||||
|
import Blocklist from './Blocklist.vue'
|
||||||
import TabItem from '@/components/TabItem.vue'
|
import TabItem from '@/components/TabItem.vue'
|
||||||
import TabsWrapper from '@/components/TabsWrapper.vue'
|
import TabsWrapper from '@/components/TabsWrapper.vue'
|
||||||
|
|
||||||
@ -81,6 +85,7 @@ export default {
|
|||||||
LastRenderedImage,
|
LastRenderedImage,
|
||||||
TabItem,
|
TabItem,
|
||||||
TabsWrapper,
|
TabsWrapper,
|
||||||
|
Blocklist,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user