agendash 1.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +3 -2
- package/History.md +80 -58
- package/LICENSE +1 -1
- package/README.md +173 -49
- package/all-jobs.png +0 -0
- package/app.js +12 -7
- package/bin/agendash-standalone-fastify.js +61 -0
- package/bin/agendash-standalone-hapi.js +60 -0
- package/bin/agendash-standalone-koa.js +56 -0
- package/bin/agendash-standalone.js +47 -15
- package/create-job.png +0 -0
- package/entrypoint.sh +1 -1
- package/lib/controllers/agendash.js +340 -0
- package/lib/middlewares/README.md +12 -5
- package/lib/middlewares/express.js +58 -34
- package/lib/middlewares/fastify.js +75 -0
- package/lib/middlewares/hapi.js +65 -88
- package/lib/middlewares/koa.js +71 -0
- package/mobile-ui-sm.png +0 -0
- package/mobile-ui-xs.png +0 -0
- package/package.json +45 -36
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/app/assets/ArgensdashV2Logo.svg +18 -0
- package/public/app/css/styles.css +221 -0
- package/public/app/js/confirmDelete.js +40 -0
- package/public/app/js/confirmDeleteMulti.js +45 -0
- package/public/app/js/confirmRequeue.js +40 -0
- package/public/app/js/confirmRequeueMulti.js +45 -0
- package/public/app/js/confirms.js +8 -0
- package/public/app/js/jobdetail.js +48 -0
- package/public/app/js/joblist.js +239 -0
- package/public/app/js/main.js +275 -0
- package/public/app/js/newJob.js +89 -0
- package/public/app/js/sidebar.js +121 -0
- package/public/app/js/topbar.js +95 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +40 -164
- package/public/site.webmanifest +1 -0
- package/search.png +0 -0
- package/.editorconfig +0 -7
- package/.travis.yml +0 -24
- package/job-details.png +0 -0
- package/lib/agendash.js +0 -295
- package/public/css/bootstrap-theme.css +0 -587
- package/public/css/bootstrap-theme.css.map +0 -1
- package/public/css/bootstrap-theme.min.css +0 -6
- package/public/css/bootstrap-theme.min.css.map +0 -1
- package/public/css/bootstrap.css +0 -6760
- package/public/css/bootstrap.css.map +0 -1
- package/public/css/bootstrap.min.css +0 -6
- package/public/css/bootstrap.min.css.map +0 -1
- package/public/css/dashboard.css +0 -94
- package/public/fonts/glyphicons-halflings-regular.eot +0 -0
- package/public/fonts/glyphicons-halflings-regular.svg +0 -288
- package/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- package/public/fonts/glyphicons-halflings-regular.woff +0 -0
- package/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
- package/public/js/backbone-min.js +0 -2
- package/public/js/backbone-min.map +0 -1
- package/public/js/bootstrap.js +0 -2363
- package/public/js/bootstrap.min.js +0 -7
- package/public/js/jquery-2.2.0.min.js +0 -4
- package/public/js/lodash.min.js +0 -120
- package/public/js/main.js +0 -414
- package/public/js/moment.min.js +0 -7
- package/test/test-express.js +0 -98
- package/test/test-hapi.js +0 -104
- package/yarn.lock +0 -4412
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const confirmDelete = Vue.component("confirm-delete", {
|
|
2
|
+
props: ["job"],
|
|
3
|
+
methods: {
|
|
4
|
+
deleteOne(id) {
|
|
5
|
+
const url = `api/jobs/delete`;
|
|
6
|
+
let body = { jobIds: [id] };
|
|
7
|
+
return axios
|
|
8
|
+
.post(url, body)
|
|
9
|
+
.then((result) => result.data)
|
|
10
|
+
.then((data) => {
|
|
11
|
+
this.$emit("popup-message", "delete");
|
|
12
|
+
this.$emit("refresh-data");
|
|
13
|
+
})
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
template: `
|
|
18
|
+
<div class="modal fade" id="modalDeleteSure" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
19
|
+
<!-- Modal -->
|
|
20
|
+
<div class="modal-dialog" role="document">
|
|
21
|
+
<div class="modal-content">
|
|
22
|
+
<div class="modal-header">
|
|
23
|
+
<h5 class="modal-title" id="exampleModalLabel">Confirm Delete Permanently</h5>
|
|
24
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
25
|
+
<span aria-hidden="true">×</span>
|
|
26
|
+
</button>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="modal-body">
|
|
29
|
+
<p>ID: {{job.job._id}}</p>
|
|
30
|
+
<p>Name: {{job.job.name}}</p>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="modal-footer">
|
|
33
|
+
<button type="button" class="btn btn-danger" data-dismiss="modal" @click="deleteOne(job.job._id)">Delete</button>
|
|
34
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
`,
|
|
40
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const confirmDeleteMulti = Vue.component("confirm-multi-delete", {
|
|
2
|
+
props: ["jobs"],
|
|
3
|
+
methods: {
|
|
4
|
+
deleteMulti(ids) {
|
|
5
|
+
const url = `api/jobs/delete`;
|
|
6
|
+
let body = { jobIds: ids };
|
|
7
|
+
return axios
|
|
8
|
+
.post(url, body)
|
|
9
|
+
.then((result) => result.data)
|
|
10
|
+
.then((data) => {
|
|
11
|
+
this.$emit("popup-message", "delete");
|
|
12
|
+
this.$emit("refresh-data");
|
|
13
|
+
})
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
template: `
|
|
18
|
+
<div class="modal fade" id="modalDeleteSureMulti" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
19
|
+
<!-- Modal -->
|
|
20
|
+
<h1>MULTI</h1>
|
|
21
|
+
<div class="modal-dialog" role="document">
|
|
22
|
+
<div class="modal-content">
|
|
23
|
+
<div class="modal-header">
|
|
24
|
+
<h5 class="modal-title" id="exampleModalLabel">Confirm Delete Permanently</h5>
|
|
25
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
26
|
+
<span aria-hidden="true">×</span>
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="modal-body">
|
|
30
|
+
<div class="row px-3" v-for="job in jobs">
|
|
31
|
+
<div class="col">
|
|
32
|
+
<p>Job Id: {{job}}</p>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="modal-footer">
|
|
38
|
+
<button type="button" class="btn btn-danger" data-dismiss="modal" @click="deleteMulti(jobs)">Delete</button>
|
|
39
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
`,
|
|
45
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const confirmRequeue = Vue.component("confirm-requeue", {
|
|
2
|
+
props: ["job"],
|
|
3
|
+
methods: {
|
|
4
|
+
RequeueOne(id) {
|
|
5
|
+
const url = `api/jobs/requeue`;
|
|
6
|
+
let body = { jobIds: [id] };
|
|
7
|
+
return axios
|
|
8
|
+
.post(url, body)
|
|
9
|
+
.then((result) => result.data)
|
|
10
|
+
.then((data) => {
|
|
11
|
+
this.$emit("popup-message");
|
|
12
|
+
this.$emit("refresh-data");
|
|
13
|
+
})
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
template: `
|
|
18
|
+
<div class="modal fade" id="modalRequeueSure" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
19
|
+
<!-- Modal -->
|
|
20
|
+
<div class="modal-dialog" role="document">
|
|
21
|
+
<div class="modal-content">
|
|
22
|
+
<div class="modal-header">
|
|
23
|
+
<h5 class="modal-title" id="exampleModalLabel">Confirm requeue job</h5>
|
|
24
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
25
|
+
<span aria-hidden="true">×</span>
|
|
26
|
+
</button>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="modal-body">
|
|
29
|
+
<p>ID: {{job.job._id}}</p>
|
|
30
|
+
<p>Name: {{job.job.name}}</p>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="modal-footer">
|
|
33
|
+
<button type="button" class="btn btn-info" data-dismiss="modal" @click="RequeueOne(job.job._id)">Requeue Job</button>
|
|
34
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
`,
|
|
40
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const confirmRequeueMulti = Vue.component("confirm-multi-requeue", {
|
|
2
|
+
props: ["jobs"],
|
|
3
|
+
methods: {
|
|
4
|
+
RequeueMulti(ids) {
|
|
5
|
+
const url = `api/jobs/requeue`;
|
|
6
|
+
let body = { jobIds: ids };
|
|
7
|
+
return axios
|
|
8
|
+
.post(url, body)
|
|
9
|
+
.then((result) => result.data)
|
|
10
|
+
.then((data) => {
|
|
11
|
+
this.$emit("popup-message");
|
|
12
|
+
this.$emit("refresh-data");
|
|
13
|
+
this.$emit("ready-clean");
|
|
14
|
+
})
|
|
15
|
+
.catch(console.log);
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
template: `
|
|
19
|
+
<div class="modal fade" id="modalRequeueSureMulti" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
20
|
+
<!-- Modal -->
|
|
21
|
+
<h1>MULTI</h1>
|
|
22
|
+
<div class="modal-dialog" role="document">
|
|
23
|
+
<div class="modal-content">
|
|
24
|
+
<div class="modal-header">
|
|
25
|
+
<h5 class="modal-title" id="exampleModalLabel">Confirm requeue job</h5>
|
|
26
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
27
|
+
<span aria-hidden="true">×</span>
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="modal-body">
|
|
31
|
+
<div class="row px-3" v-for="job in jobs">
|
|
32
|
+
<div class="col">
|
|
33
|
+
<p>Job Id: {{job}}</p>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="modal-footer">
|
|
38
|
+
<button type="button" class="btn btn-info" data-dismiss="modal" @click="RequeueMulti(jobs)">Requeue Job</button>
|
|
39
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
`,
|
|
45
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const popupmessage = Vue.component("popup-message", {
|
|
2
|
+
props: ["job", "deletec", "requeuec", "createc"],
|
|
3
|
+
template: `
|
|
4
|
+
<div v-if="deletec" class="alert alert-success popupmessage">Job Deleted successfull</div>
|
|
5
|
+
<div v-else-if="requeuec" class="alert alert-success popupmessage">Job Requeue successfull</div>
|
|
6
|
+
<div v-else-if="createc" class="alert alert-success popupmessage">Job Created successfull</div>
|
|
7
|
+
`,
|
|
8
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const jobDetail = Vue.component("job-detail", {
|
|
2
|
+
props: ["job"],
|
|
3
|
+
filters: {
|
|
4
|
+
formatJSON(jsonstr) {
|
|
5
|
+
return JSON.stringify(jsonstr, null, 2);
|
|
6
|
+
},
|
|
7
|
+
},
|
|
8
|
+
methods: {
|
|
9
|
+
formatDate(date) {
|
|
10
|
+
return moment(date).format("DD-MM-YYYY HH:mm:ss");
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
template: `
|
|
14
|
+
<div class="modal fade" id="modalData" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
15
|
+
<!-- Modal -->
|
|
16
|
+
<div class="modal-dialog" role="document">
|
|
17
|
+
<div class="modal-content">
|
|
18
|
+
<div class="modal-header">
|
|
19
|
+
<h5 class="modal-title" id="exampleModalLabel">Job Data - {{job.job.name}}</h5>
|
|
20
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
21
|
+
<span aria-hidden="true">×</span>
|
|
22
|
+
</button>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="modal-body">
|
|
25
|
+
<div class="row my-3">
|
|
26
|
+
<div class="col">
|
|
27
|
+
<p><strong>Next run starts: </strong>{{ formatDate(job.job.nextRunAt) }}</p>
|
|
28
|
+
<p><strong>Last run started: </strong>{{ formatDate(job.job.lastRunAt) }}</p>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<p><strong>Metadata: </strong></p>
|
|
32
|
+
<prism-editor class="json-editor" :lineNumbers="true" :readonly="true" :code="job.job.data | formatJSON" language="json"></prism-editor>
|
|
33
|
+
<div v-if='job.failed' class="row mt-3">
|
|
34
|
+
<div class="col pt-3 bg-danger text-light">
|
|
35
|
+
<p><strong>Fail Count:</strong> {{job.job.failCount}}</p>
|
|
36
|
+
<p><strong>Failed At:</strong> {{formatDate(job.job.failedAt)}}</p>
|
|
37
|
+
<p><strong>Reason:</strong> {{job.job.failReason}}</p>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="modal-footer">
|
|
42
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
`,
|
|
48
|
+
});
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
const jobList = Vue.component("job-list", {
|
|
2
|
+
data: () => ({
|
|
3
|
+
multijobs: [],
|
|
4
|
+
currentSort: "name",
|
|
5
|
+
currentSortDir: "asc",
|
|
6
|
+
}),
|
|
7
|
+
props: ["jobs", "pagesize", "pagenumber", "sendClean", "loading"],
|
|
8
|
+
computed: {
|
|
9
|
+
sortedJobs: function () {
|
|
10
|
+
return this.jobs.sort((a, b) => {
|
|
11
|
+
let displayA, displayB;
|
|
12
|
+
if (this.currentSort === "name") {
|
|
13
|
+
displayA = a.job[this.currentSort]
|
|
14
|
+
? a.job[this.currentSort].toLowerCase()
|
|
15
|
+
: "";
|
|
16
|
+
displayB = a.job[this.currentSort]
|
|
17
|
+
? b.job[this.currentSort].toLowerCase()
|
|
18
|
+
: "";
|
|
19
|
+
} else {
|
|
20
|
+
displayA = moment(a.job[this.currentSort]);
|
|
21
|
+
displayB = moment(b.job[this.currentSort]);
|
|
22
|
+
}
|
|
23
|
+
let modifier = 1;
|
|
24
|
+
if (this.currentSortDir === "desc") modifier = -1;
|
|
25
|
+
if (displayA < displayB) return -1 * modifier;
|
|
26
|
+
if (displayA > displayB) return 1 * modifier;
|
|
27
|
+
return 0;
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
watch: {
|
|
32
|
+
jobs() {
|
|
33
|
+
// reset multijobs when jobs have changed
|
|
34
|
+
this.multijobs = [];
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
methods: {
|
|
38
|
+
sort(s) {
|
|
39
|
+
//if s == current sort, reverse
|
|
40
|
+
if (s === this.currentSort) {
|
|
41
|
+
this.currentSortDir = this.currentSortDir === "asc" ? "desc" : "asc";
|
|
42
|
+
}
|
|
43
|
+
this.currentSort = s;
|
|
44
|
+
},
|
|
45
|
+
sendQueued() {
|
|
46
|
+
this.$emit("confirm-multi-requeue", this.multijobs);
|
|
47
|
+
// this.multijobs = []
|
|
48
|
+
},
|
|
49
|
+
sendDelete() {
|
|
50
|
+
this.$emit("confirm-multi-delete", this.multijobs);
|
|
51
|
+
// this.multijobs = []
|
|
52
|
+
},
|
|
53
|
+
cleanMulti() {
|
|
54
|
+
return console.log("received Clean Multi");
|
|
55
|
+
},
|
|
56
|
+
formatTitle(date) {
|
|
57
|
+
if (!date) return;
|
|
58
|
+
return moment(date).format();
|
|
59
|
+
},
|
|
60
|
+
formatDate(date) {
|
|
61
|
+
if (!date) return;
|
|
62
|
+
return moment(date).fromNow();
|
|
63
|
+
},
|
|
64
|
+
checkAllCheckboxes() {
|
|
65
|
+
const checkboxes = document.querySelectorAll(".checkbox-triggerable");
|
|
66
|
+
for (const checkbox of checkboxes) {
|
|
67
|
+
checkbox.click();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
toggleList(job) {
|
|
71
|
+
if (this.multijobs.includes(job.job._id)) {
|
|
72
|
+
this.multijobs.splice(this.multijobs.indexOf(job.job._id), 1);
|
|
73
|
+
} else {
|
|
74
|
+
this.multijobs.push(job.job._id);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
template: `
|
|
79
|
+
<div v-on:sendClean="cleanMulti">
|
|
80
|
+
<div >
|
|
81
|
+
<div class="d-flex justify-content-end mb-2">
|
|
82
|
+
<span class="mr-2">{{ multijobs.length }} jobs selected</span>
|
|
83
|
+
<button :disabled="!multijobs.length" data-toggle="modal" data-target="#modalRequeueSureMulti" @click="sendQueued" class="btn btn-primary mr-2" data-placement="top" title="Requeue list of selecteds Jobs"> Multiple Requeue </button>
|
|
84
|
+
<button :disabled="!multijobs.length" data-toggle="modal" data-target="#modalDeleteSureMulti" @click="sendDelete" class="btn btn-danger" data-placement="top" title="Delete list of selecteds Jobs"> Multiple Delete </button>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<table class="table table-striped d-none d-xl-table">
|
|
89
|
+
<thead class="thead-dark">
|
|
90
|
+
<tr>
|
|
91
|
+
<th @click="checkAllCheckboxes()" scope="col"> Multi </th>
|
|
92
|
+
<th @click="sort('status')" scope="col"> Status </th>
|
|
93
|
+
<th @click="sort('name')" scope="col"> Name <i v-if="currentSort === 'name' && currentSortDir === 'asc'" class="material-icons sortable" title="Sort Z to A">arrow_drop_down</i>
|
|
94
|
+
<i v-else-if="currentSort === 'name' && currentSortDir === 'desc'" class="material-icons sortable" title="Sort A to Z">arrow_drop_up</i>
|
|
95
|
+
<i v-else class="material-icons sortableinactive" title="Sort A to Z">arrow_drop_down</i>
|
|
96
|
+
</th>
|
|
97
|
+
<th @click="sort('lastRunAt')" scope="col"> Last run started <i v-if="currentSort === 'lastRunAt' && currentSortDir === 'asc'" class="material-icons sortable" title="Sort Z to A">arrow_drop_up</i>
|
|
98
|
+
<i v-else-if="currentSort === 'lastRunAt' && currentSortDir === 'desc'" class="material-icons sortable" title="Sort A to Z">arrow_drop_down</i>
|
|
99
|
+
<i v-else class="material-icons sortableinactive" title="Sort A to Z">arrow_drop_down</i>
|
|
100
|
+
</th>
|
|
101
|
+
<th @click="sort('nextRunAt')" scope="col"> Next run starts
|
|
102
|
+
<i v-if="currentSort === 'nextRunAt' && currentSortDir === 'asc'" class="material-icons sortable" title="Sort Z to A">arrow_drop_up</i>
|
|
103
|
+
<i v-else-if="currentSort === 'nextRunAt' && currentSortDir === 'desc'" class="material-icons sortable" title="Sort A to Z">arrow_drop_down</i>
|
|
104
|
+
<i v-else class="material-icons sortableinactive" title="Sort A to Z">arrow_drop_down</i>
|
|
105
|
+
|
|
106
|
+
</th>
|
|
107
|
+
<th @click="sort('lastFinishedAt')" scope="col"> Last finished
|
|
108
|
+
<i v-if="currentSort === 'lastFinishedAt' && currentSortDir === 'asc'" class="material-icons sortable" title="Sort Z to A">arrow_drop_up</i>
|
|
109
|
+
<i v-else-if="currentSort === 'lastFinishedAt' && currentSortDir === 'desc'" class="material-icons sortable" title="Sort A to Z">arrow_drop_down</i>
|
|
110
|
+
<i v-else class="material-icons sortableinactive" title="Sort A to Z">arrow_drop_down</i>
|
|
111
|
+
</th>
|
|
112
|
+
<th scope="col"> Locked </th>
|
|
113
|
+
<th scope="col"> Actions </th>
|
|
114
|
+
</tr>
|
|
115
|
+
</thead>
|
|
116
|
+
<tbody v-if="loading">
|
|
117
|
+
<tr>
|
|
118
|
+
<td colspan='10' scope="row">
|
|
119
|
+
<div class="col-12 my-5 ml-auto text-center">
|
|
120
|
+
<div class="text-center my-5 py-5">
|
|
121
|
+
<div class="spinner-border" role="status">
|
|
122
|
+
</div>
|
|
123
|
+
<div>
|
|
124
|
+
<span class="">Loading Jobs...</span>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</td>
|
|
129
|
+
</tr>
|
|
130
|
+
</tbody>
|
|
131
|
+
|
|
132
|
+
<tbody v-else>
|
|
133
|
+
<tr v-for="job in sortedJobs">
|
|
134
|
+
<td width="10" class="mult-select">
|
|
135
|
+
<input v-model="multijobs" :id='job.job._id' class="checkbox-triggerable" type="checkbox" :value="job.job._id"></input>
|
|
136
|
+
</td>
|
|
137
|
+
<td th scope="row" class="job-name">
|
|
138
|
+
<i v-if="job.repeating" class="oi oi-timer pill-own bg-info"><span>{{job.job.repeatInterval}}</span></i>
|
|
139
|
+
<i v-if="job.scheduled" class="pill-own bg-info pill-withoutIcon"><span>Scheduled</span></i>
|
|
140
|
+
<i v-if="job.completed" class="pill-own bg-success pill-withoutIcon"><span>Completed</span></i>
|
|
141
|
+
<i v-if="job.queued" class="pill-own bg-primary pill-withoutIcon"><span>Queued</span></i>
|
|
142
|
+
<i v-if="job.failed" class="pill-own bg-danger pill-withoutIcon"><span>Failed</span></i>
|
|
143
|
+
<i v-if="job.running" class="pill-own bg-warning pill-withoutIcon"><span>Running</span></i>
|
|
144
|
+
</td>
|
|
145
|
+
<td class="job-name" @click="toggleList(job)"> {{job.job.name}} </td>
|
|
146
|
+
<td class="job-lastRunAt" :title="formatTitle(job.job.lastRunAt)" @click="toggleList(job)"> {{ formatDate(job.job.lastRunAt) }} </td>
|
|
147
|
+
<td class="job-nextRunAt" :title="formatTitle(job.job.nextRunAt)" @click="toggleList(job)"> {{ formatDate(job.job.nextRunAt) }} </td>
|
|
148
|
+
<td class="job-finishedAt" :title="formatTitle(job.job.lastFinishedAt)" @click="toggleList(job)"> {{ formatDate(job.job.lastFinishedAt) }} </td>
|
|
149
|
+
<td class="job-lockedAt" :title="formatTitle(job.job.lockedAt)" @click="toggleList(job)"> {{ formatDate(job.job.lockedAt) }} </td>
|
|
150
|
+
<td class="job-actions">
|
|
151
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-primary" data-toggle="modal" data-target="#modalRequeueSure" @click="$emit('confirm-requeue', job)" data-placement="left" title="Requeue">update</i>
|
|
152
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-success" data-toggle="modal" data-target="#modalData" @click="$emit('show-job-detail', job)" data-placement="top" title="Job Data">visibility</i>
|
|
153
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-danger" data-toggle="modal" data-target="#modalDeleteSure" @click="$emit('confirm-delete', job)" data-placement="top" title="Delete permanently">delete_forever</i>
|
|
154
|
+
</td>
|
|
155
|
+
</tr>
|
|
156
|
+
</tbody>
|
|
157
|
+
</table>
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
<div class="d-xl-none">
|
|
161
|
+
<div class="row">
|
|
162
|
+
<div v-for="job in sortedJobs" class="col col-xs-6 order-1 p-1">
|
|
163
|
+
<div class="card bg-light" >
|
|
164
|
+
<div class="card-header card-responsive-title-container">
|
|
165
|
+
<div class="card-responsive-name" @click="toggleList(job)">
|
|
166
|
+
{{job.job.name}}
|
|
167
|
+
</div>
|
|
168
|
+
<div class="d-flex align-items-center">
|
|
169
|
+
<div class="card-responsive-status-title mr-2" style="font-size: 18px; display: flex; align-items: center">
|
|
170
|
+
<input v-model="multijobs" :id='job.job._id' type="checkbox" :value="job.job._id" class="card-responsive-checkbox"></input>
|
|
171
|
+
</div>
|
|
172
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-primary material-icons-size mr-1" data-toggle="modal" data-target="#modalRequeueSure" @click="$emit('confirm-requeue', job)" data-placement="left" title="Requeue">update</i>
|
|
173
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-success material-icons-size mr-1" data-toggle="modal" data-target="#modalData" @click="$emit('show-job-detail', job)" data-placement="top" title="Job Data">visibility</i>
|
|
174
|
+
<i class="material-icons md-dark md-custom action-btn viewData text-danger material-icons-size" data-toggle="modal" data-target="#modalDeleteSure" @click="$emit('confirm-delete', job)" data-placement="top" title="Delete permanently">delete_forever</i>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="card-body">
|
|
178
|
+
<div class="d-flex justify-content-center mb-2">
|
|
179
|
+
<i v-if="job.repeating" class="oi oi-timer pill-own mr-2 bg-info pill-own-card"><span class="pill-own-card-info">{{job.job.repeatInterval}}</span></i>
|
|
180
|
+
<i v-if="job.scheduled" class="pill-own mr-2 bg-info pill-withoutIcon pill-own-card"><span class="pill-own-card-info">Scheduled</span></i>
|
|
181
|
+
<i v-if="job.completed" class="pill-own mr-2 bg-success pill-withoutIcon pill-own-card"><span class="pill-own-card-info">Completed</span></i>
|
|
182
|
+
<i v-if="job.queued" class="pill-own mr-2 bg-primary pill-withoutIcon pill-own-card"><span class="pill-own-card-info">Queued</span></i>
|
|
183
|
+
<i v-if="job.failed" class="pill-own mr-2 bg-danger pill-withoutIcon pill-own-card"><span class="pill-own-card-info">Failed</span></i>
|
|
184
|
+
<i v-if="job.running" class="pill-own mr-2 bg-warning pill-withoutIcon pill-own-card"><span class="pill-own-card-info">Running</span></i>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="row">
|
|
187
|
+
<div class="col col-md-6 text-center">
|
|
188
|
+
<div class="card-responsive-status-title">
|
|
189
|
+
Last run started
|
|
190
|
+
</div>
|
|
191
|
+
<div class="mb-3" :title="formatTitle(job.job.lastRunAt)">
|
|
192
|
+
{{ formatDate(job.job.lastRunAt) }}
|
|
193
|
+
</div>
|
|
194
|
+
<div class="card-responsive-status-title">
|
|
195
|
+
Last finished
|
|
196
|
+
</div>
|
|
197
|
+
<div :title="formatTitle(job.job.lastFinishedAt)">
|
|
198
|
+
{{ formatDate(job.job.lastFinishedAt) }}
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="col col-md-6 text-center">
|
|
202
|
+
<div class="card-responsive-status-title">
|
|
203
|
+
Next run starts
|
|
204
|
+
</div>
|
|
205
|
+
<div class="mb-3" :title="formatTitle(job.job.nextRunAt)">
|
|
206
|
+
{{ formatDate(job.job.nextRunAt) }}
|
|
207
|
+
</div>
|
|
208
|
+
<div class="card-responsive-status-title">
|
|
209
|
+
Locked
|
|
210
|
+
</div>
|
|
211
|
+
<div :title="formatTitle(job.job.lockedAt)">
|
|
212
|
+
{{ formatDate(job.job.lockedAt) || "-" }}
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
<div></div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
<div class="row">
|
|
225
|
+
<div class="col d-flex justify-content-center">
|
|
226
|
+
<nav aria-label="Page navigation example">
|
|
227
|
+
<ul class="pagination">
|
|
228
|
+
<li class="page-item" :class="pagenumber === 1 ? 'disabled': ''"><a class="page-link" @click="$emit('pagechange', 'prev')">Previous</a></li>
|
|
229
|
+
<!-- <li class="page-item" :class="pagenumber === 1 ? 'disabled': ''"><a class="page-link" @click="$emit('pagechange', 'prev')">{{pagenumber -1}}</a></li>
|
|
230
|
+
<li class="page-item active"><a class="page-link">{{pagenumber}}</a></li>
|
|
231
|
+
<li class="page-item"><a style="cursor:pointer;" class="page-link" @click="$emit('pagechange', 'next')">{{pagenumber +1}}</a></li> -->
|
|
232
|
+
<li class="page-item"><a style="cursor:pointer;" class="page-link" @click="$emit('pagechange', 'next')">Next</a></li>
|
|
233
|
+
</ul>
|
|
234
|
+
</nav>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
`,
|
|
239
|
+
});
|