PHP Classes
elePHPant
Icontem

File: resources/assets/js/components/ActiveJob.vue

Recommend this page to a friend!
  Classes of Insolita  >  Laravel Interactive Jobs  >  resources/assets/js/components/ActiveJob.vue  >  Download  
File: resources/assets/js/components/ActiveJob.vue
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Laravel Interactive Jobs
Run background jobs and monitor progress on a page
Author: By
Last change:
Date: 2 months ago
Size: 5,308 bytes
 

 

Contents

Class file image Download
<template>
    <div class="card" v-show="job">
        <div class="card-header">
            <span v-html="label"></span> {{job.title}} [{{job.command}}: {{job.id}}]
            <a class="float-right" @click="remove(job.id)" v-show="single !== 1">
                <i class="fa fa-times-circle-o" aria-hidden="true"></i>
            </a>
        </div>
        <div class="card-body">
            <div v-show="job.payload">
                <div class="row">
                    <div class="col-6">
                        <b>Options:</b>
                        <ul>
                            <li v-for="(val, param) in job.payload">
                                <b>{{param}}</b>: {{val}}
                            </li>
                        </ul>
                    </div>
                    <div class="col-6">
                        <p><b>Attempts:</b> {{job.attempts}}</p>
                        <p><b>Created At:</b> {{job.created_at}}</p>
                    </div>
                </div>

            </div>
            <div>
                <div class="progress">
                    <div class="progress-bar" :class="barClass"
                         role="progressbar" :style="barStyle" v-bind:property="job.progress">
                        {{ job.progress }}
                    </div>
                </div>
                <div class="log" v-show="logs.length">
                    <ul class="list-group">
                        <li class="list-group-item" v-for="log in logs">
                            {{ log }}
                        </li>
                    </ul>
                </div>
            </div>
            <div v-show="isJobFinished && job.report">
                <div v-show="job.report">
                    <b>Report:</b>
                    <p>{{job.report}}</p>
                </div>
                <a :href="'/logs/'+job.name+'/'+job.id" class="btn btn-flat btn-info">
                    See Execution Logs
                </a>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            job: {},
            isSingle: 1
        },
        data() {
            return {
                logs: [],
                labels: {
                    'success': '<div class="badge badge-success">SUCCESS</div>',
                    'fail': '<div class="badge badge-danger">FAIL</div>',
                    'retry': '<div class="badge badge-dark">RETRY</div>',
                    'pending': '<div class="badge badge-primary">PENDING</div>',
                    'declined': '<div class="badge badge-warning">DECLINED</div>',
                    'processing': '<div class="badge badge-info">PROCESSING</div>'
                },
                bar: {
                    'success': 'bg-success',
                    'fail': 'bg-danger',
                    'retry': 'bg-warning',
                    'pending': 'bg-primary',
                    'declined': 'bg-dark',
                    'processing': 'bg-info'
                }
            }
        },
        computed: {
            barStyle() {
                if (this.job.state === 'success') {
                    this.job.progress = 100;
                }
                return {'width': this.job.progress + '%'};
            },
            barClass() {
                let barClass = this.bar[this.job.state];
                if(this.state==='processing'){
                    barClass += ' progress-bar-stripped progress-bar-animated'
                }
                return barClass;
            },
            label() {
                return this.labels[this.job.state] || this.labels.pending;
            }
        },
        methods: {
            remove(id){
                this.$echo.leave(`Job.${this.job.id}`);
                this.$nextTick(function () {
                    this.$emit('removeItem', id);
                });
            },
            addLog(text) {
                this.logs.push(text);
            },
            isJobFinished() {
                return ['success', 'fail'].includes(this.job.state);
            },
            updateJob(job){
                this.job.state = job.state;
                this.job.report = job.report;
                this.job.progress = job.progress;
                this.job.attempts = job.attempts;
            },

            jobSubscribe() {
                this.$echo.private(`Job.${this.job.id}`).notification((notification) => {
                    if (notification.message_type === 'progress') {
                        this.job.progress = notification.message;
                    } else if (notification.message_type === 'state') {
                        this.updateJob(JSON.parse(notification.job));
                    } else {
                        this.logs.unshift(notification.message);
                    }
                });
            }
        },
        mounted() {
            if(typeof this.job === 'string'){
                this.job = JSON.parse(this.job);
            }
            console.log('Component mounted.');
            if (!this.isJobFinished()) {
                this.jobSubscribe();
            }
        }
    }
</script>

<style>
    .log {
        height: 200px;
        max-height: 200px;
        overflow-y: auto;
    }
</style>