1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- <template>
- <div class="job-window">
- <div v-for="job in sortedJobs"
- v-bind:key="job.identifier"
- class="job">
- <div v-if="job.finished"
- class="remove" @click="removeJob(job.identifier)">
- <img alt="remove" src="@/assets/icons/x-circle.svg">
- </div>
- <div class="subtitle">{{ job.type }}</div>
- <div class="title">{{ job.name }}</div>
- <div v-if="job.exception" class="error">{{ job.exception }}</div>
- <progress-bar v-if="!job.finished"
- :progress="job.progress"/>
- </div>
- </div>
- </template>
- <script>
- import ProgressBar from "@/components/base/progress-bar";
- export default {
- name: "job-window",
- components: {ProgressBar},
- props: ['jobs'],
- computed: {
- sortedJobs: function () {
- return [...this.jobs].sort((j, k) => j.updated < k.updated ? +1 : -1);
- }
- },
- methods: {
- removeJob: function (id) {
- this.$root.socket.post(`/jobs/${id}/remove`, {remove: true});
- }
- }
- }
- </script>
- <style scoped>
- .job-window {
- position: absolute;
- top: 100%;
- right: 0;
- width: 100vw;
- max-width: 24rem;
- max-height: calc(100vh - 100%);
- padding: 0.75rem;
- background-color: rgba(40, 40, 40, 0.8);
- z-index: 99;
- overflow: auto;
- }
- .job {
- border: 1px solid rgba(255, 255, 255, 0.4);
- border-radius: 0.25rem;
- padding: 0.5rem;
- background-color: #7f7f7f;
- position: relative;
- }
- .job:not(:last-child) {
- margin-bottom: 1rem;
- }
- .remove {
- position: absolute;
- top: 0;
- right: 0;
- padding: 0.5rem;
- }
- .remove img {
- width: 1rem;
- filter: invert(1);
- }
- .subtitle {
- font-size: 70%;
- }
- .title {
- font-size: 90%;
- }
- .error {
- color: #FF1111;
- font-size: 80%;
- }
- .progress-bar {
- height: 0.7rem;
- border-color: whitesmoke;
- margin-top: 0.2rem;
- }
- </style>
|