Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[develop] Support batches #844

Merged
merged 13 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10,943 changes: 10,941 additions & 2 deletions public/app-dark.css

Large diffs are not rendered by default.

10,943 changes: 10,941 additions & 2 deletions public/app.css

Large diffs are not rendered by default.

79,965 changes: 79,963 additions & 2 deletions public/app.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/app.js": "/app.js?id=4f93645700a6c5485654",
"/app.css": "/app.css?id=99048465add47d086ac7",
"/app-dark.css": "/app-dark.css?id=f42b555818ed19478827"
"/app.js": "/app.js?id=465f639b623ec9231aad",
"/app.css": "/app.css?id=f4bfed2b51f0e5e0dcb6",
"/app-dark.css": "/app-dark.css?id=9ef119e56b37b9067363"
}
7 changes: 7 additions & 0 deletions resources/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export default {
return moment(unixTime * 1000).add(new Date().getTimezoneOffset() / 60);
},

/**
* Format the given date with respect to timezone.
*/
formatDateIso(date) {
return moment(date).add(new Date().getTimezoneOffset() / 60);
},

/**
* Extract the job base name.
*/
Expand Down
12 changes: 12 additions & 0 deletions resources/js/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,16 @@ export default [
name: 'failed-jobs-preview',
component: require('./screens/failedJobs/job').default,
},

{
path: '/batches',
name: 'batches',
component: require('./screens/batches/index').default,
},

{
path: '/batches/:batchId',
name: 'batches-preview',
component: require('./screens/batches/preview').default,
},
];
202 changes: 202 additions & 0 deletions resources/js/screens/batches/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<script type="text/ecmascript-6">
export default {
/**
* The component's data.
*/
data() {
return {
ready: false,
loadingNewEntries: false,
hasNewEntries: false,
page: 1,
previousFirstId: null,
batches: [],
};
},

/**
* Prepare the component.
*/
mounted() {
document.title = "Horizon - Batches";

this.loadBatches();

this.refreshBatchesPeriodically();
},

/**
* Clean after the component is destroyed.
*/
destroyed() {
clearInterval(this.interval);
},


/**
* Watch these properties for changes.
*/
watch: {
'$route'() {
this.page = 1;

this.loadBatches();
},
},


methods: {
/**
* Load the batches.
*/
loadBatches(beforeId = '', refreshing = false) {
if (!refreshing) {
this.ready = false;
}

this.$http.get(Horizon.basePath + '/api/batches?before_id=' + beforeId)
.then(response => {
if (!this.$root.autoLoadsNewEntries && refreshing && !response.data.batches.length) {
return;
}


if (!this.$root.autoLoadsNewEntries && refreshing && this.batches.length && _.first(response.data.batches).id !== _.first(this.batches).id) {
this.hasNewEntries = true;
} else {
this.batches = response.data.batches;
}

this.ready = true;
});
},


loadNewEntries() {
this.batches = [];

this.loadBatches(0, false);

this.hasNewEntries = false;
},


/**
* Refresh the batches every period of time.
*/
refreshBatchesPeriodically() {
this.interval = setInterval(() => {
if (this.page != 1) return;

this.loadBatches('', true);
}, 3000);
},


/**
* Load the batches for the previous page.
*/
previous() {
this.loadBatches(
this.page == 2 ? '' : this.previousFirstId
);

this.page -= 1;

this.hasNewEntries = false;
},


/**
* Load the batches for the next page.
*/
next() {
this.previousFirstId = _.first(this.batches).id + '0';

this.loadBatches(
_.last(this.batches).id
);

this.page += 1;

this.hasNewEntries = false;
}
}
}
</script>

<template>
<div>
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<h5>Batches</h5>
</div>

<div v-if="!ready" class="d-flex align-items-center justify-content-center card-bg-secondary p-5 bottom-radius">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="icon spin mr-2 fill-text-color">
<path d="M12 10a2 2 0 0 1-3.41 1.41A2 2 0 0 1 10 8V0a9.97 9.97 0 0 1 10 10h-8zm7.9 1.41A10 10 0 1 1 8.59.1v2.03a8 8 0 1 0 9.29 9.29h2.02zm-4.07 0a6 6 0 1 1-7.25-7.25v2.1a3.99 3.99 0 0 0-1.4 6.57 4 4 0 0 0 6.56-1.42h2.1z"></path>
</svg>

<span>Loading...</span>
</div>


<div v-if="ready && batches.length == 0" class="d-flex flex-column align-items-center justify-content-center card-bg-secondary p-5 bottom-radius">
<span>There aren't any batches.</span>
</div>

<table v-if="ready && batches.length > 0" class="table table-hover table-sm mb-0">
<thead>
<tr>
<th>Batch</th>
<th>Status</th>
<th>Size</th>
<th>Completion</th>
<th class="text-right">Created At</th>
</tr>
</thead>

<tbody>
<tr v-if="hasNewEntries" key="newEntries" class="dontanimate">
<td colspan="100" class="text-center card-bg-secondary py-1">
<small><a href="#" v-on:click.prevent="loadNewEntries" v-if="!loadingNewEntries">Load New Entries</a></small>

<small v-if="loadingNewEntries">Loading...</small>
</td>
</tr>

<tr v-for="batch in batches" :key="batch.id">
<td>
<router-link :title="batch.id" :to="{ name: 'batches-preview', params: { batchId: batch.id }}">
{{ batch.name || batch.id }}
</router-link>
</td>
<td>
<small class="badge badge-danger badge-sm" v-if="batch.failedJobs > 0 && batch.progress < 100">
Failures
</small>
<small class="badge badge-success badge-sm" v-if="batch.progress == 100">
Finished
</small>
<small class="badge badge-secondary badge-sm" v-if="batch.pendingJobs > 0 && !batch.failedJobs">
Pending
</small>
</td>
<td>{{batch.totalJobs}}</td>
<td>{{batch.progress}}%</td>

<td class="text-right table-fit">
{{ formatDateIso(batch.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
</td>
</tr>
</tbody>
</table>

<div v-if="ready && batches.length" class="p-3 d-flex justify-content-between border-top">
<button @click="previous" class="btn btn-secondary btn-md" :disabled="page==1">Previous</button>
<button @click="next" class="btn btn-secondary btn-md" :disabled="batches.length < 50">Next</button>
</div>
</div>

</div>
</template>
Loading