agendash 2.0.0 → 3.1.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/README.md +59 -22
- package/app.js +9 -5
- package/bin/agendash-standalone-fastify.js +61 -0
- package/bin/agendash-standalone-hapi.js +36 -18
- package/bin/agendash-standalone-koa.js +30 -14
- package/bin/agendash-standalone.js +44 -19
- package/lib/controllers/agendash.js +228 -110
- package/lib/csp.js +28 -0
- package/lib/middlewares/README.md +3 -1
- package/lib/middlewares/express.js +43 -17
- package/lib/middlewares/fastify.js +77 -0
- package/lib/middlewares/hapi.js +58 -33
- package/lib/middlewares/koa.js +29 -20
- package/package.json +37 -35
- package/public/app/js/confirmDelete.js +14 -13
- package/public/app/js/confirmDeleteMulti.js +14 -13
- package/public/app/js/confirmRequeue.js +14 -13
- package/public/app/js/confirmRequeueMulti.js +15 -14
- package/public/app/js/confirms.js +4 -4
- package/public/app/js/jobdetail.js +9 -9
- package/public/app/js/joblist.js +50 -43
- package/public/app/js/main.js +109 -72
- package/public/app/js/newJob.js +37 -23
- package/public/app/js/sidebar.js +51 -26
- package/public/app/js/topbar.js +15 -5
- package/.editorconfig +0 -7
- package/.idea/agendash.iml +0 -12
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/misc.xml +0 -92
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.travis.yml +0 -27
- package/.vscode/launch.json +0 -15
- package/History.md +0 -106
- package/renovate.json +0 -5
- package/test/test-express.js +0 -82
- package/test/test-hapi.js +0 -106
- package/test/test-koa.js +0 -85
package/lib/middlewares/hapi.js
CHANGED
|
@@ -1,76 +1,101 @@
|
|
|
1
|
-
const path = require(
|
|
2
|
-
const pack = require(
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const pack = require("../../package.json");
|
|
3
|
+
const csp = require("../csp");
|
|
3
4
|
|
|
4
|
-
module.exports = agendash => {
|
|
5
|
-
const {api, requeueJobs, deleteJobs, createJob} = agendash;
|
|
5
|
+
module.exports = (agendash) => {
|
|
6
|
+
const { api, requeueJobs, deleteJobs, createJob } = agendash;
|
|
6
7
|
return {
|
|
7
8
|
pkg: pack,
|
|
8
9
|
register: (server, options) => {
|
|
10
|
+
server.ext("onPreResponse", (req, h) => {
|
|
11
|
+
req.response.header("Content-Security-Policy", csp);
|
|
12
|
+
return h.continue;
|
|
13
|
+
});
|
|
14
|
+
|
|
9
15
|
server.route([
|
|
10
16
|
{
|
|
11
|
-
method:
|
|
12
|
-
path:
|
|
17
|
+
method: "GET",
|
|
18
|
+
path: "/{param*}",
|
|
13
19
|
handler: {
|
|
14
20
|
directory: {
|
|
15
|
-
path: path.join(__dirname,
|
|
16
|
-
}
|
|
21
|
+
path: path.join(__dirname, "../../public"),
|
|
22
|
+
},
|
|
17
23
|
},
|
|
18
24
|
config: {
|
|
19
|
-
auth: options.auth || false
|
|
20
|
-
}
|
|
25
|
+
auth: options.auth || false,
|
|
26
|
+
},
|
|
21
27
|
},
|
|
22
28
|
{
|
|
23
|
-
method:
|
|
24
|
-
path:
|
|
29
|
+
method: "GET",
|
|
30
|
+
path: "/api",
|
|
25
31
|
handler(request) {
|
|
26
|
-
const {
|
|
27
|
-
|
|
32
|
+
const {
|
|
33
|
+
job,
|
|
34
|
+
state,
|
|
35
|
+
limit,
|
|
36
|
+
skip,
|
|
37
|
+
q,
|
|
38
|
+
property,
|
|
39
|
+
isObjectId,
|
|
40
|
+
} = request.query;
|
|
41
|
+
return api(job, state, {
|
|
42
|
+
query: q,
|
|
43
|
+
property,
|
|
44
|
+
isObjectId,
|
|
45
|
+
skip,
|
|
46
|
+
limit,
|
|
47
|
+
});
|
|
28
48
|
},
|
|
29
49
|
config: {
|
|
30
|
-
auth: options.auth || false
|
|
31
|
-
}
|
|
50
|
+
auth: options.auth || false,
|
|
51
|
+
},
|
|
32
52
|
},
|
|
33
53
|
{
|
|
34
|
-
method:
|
|
35
|
-
path:
|
|
54
|
+
method: "POST",
|
|
55
|
+
path: "/api/jobs/requeue",
|
|
36
56
|
handler(request) {
|
|
37
57
|
return requeueJobs(request.payload.jobIds);
|
|
38
58
|
},
|
|
39
59
|
config: {
|
|
40
|
-
auth: options.auth || false
|
|
41
|
-
}
|
|
60
|
+
auth: options.auth || false,
|
|
61
|
+
},
|
|
42
62
|
},
|
|
43
63
|
{
|
|
44
|
-
method:
|
|
45
|
-
path:
|
|
64
|
+
method: "POST",
|
|
65
|
+
path: "/api/jobs/delete",
|
|
46
66
|
async handler(request, h) {
|
|
47
67
|
const deleted = await deleteJobs(request.payload.jobIds);
|
|
48
68
|
if (deleted) {
|
|
49
|
-
return h.response({deleted: true});
|
|
69
|
+
return h.response({ deleted: true });
|
|
50
70
|
}
|
|
51
71
|
|
|
52
72
|
return h.code(404);
|
|
53
73
|
},
|
|
54
74
|
config: {
|
|
55
|
-
auth: options.auth || false
|
|
56
|
-
}
|
|
75
|
+
auth: options.auth || false,
|
|
76
|
+
},
|
|
57
77
|
},
|
|
58
78
|
{
|
|
59
|
-
method:
|
|
60
|
-
path:
|
|
79
|
+
method: "POST",
|
|
80
|
+
path: "/api/jobs/create",
|
|
61
81
|
async handler(request, h) {
|
|
62
|
-
const created = await createJob(
|
|
82
|
+
const created = await createJob(
|
|
83
|
+
request.payload.jobName,
|
|
84
|
+
request.payload.jobSchedule,
|
|
85
|
+
request.payload.jobRepeatEvery,
|
|
86
|
+
request.payload.jobData
|
|
87
|
+
);
|
|
63
88
|
if (created) {
|
|
64
|
-
return h.response({created: true});
|
|
89
|
+
return h.response({ created: true });
|
|
65
90
|
}
|
|
66
91
|
|
|
67
92
|
return h.code(404);
|
|
68
93
|
},
|
|
69
94
|
config: {
|
|
70
|
-
auth: options.auth || false
|
|
71
|
-
}
|
|
72
|
-
}
|
|
95
|
+
auth: options.auth || false,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
73
98
|
]);
|
|
74
|
-
}
|
|
99
|
+
},
|
|
75
100
|
};
|
|
76
101
|
};
|
package/lib/middlewares/koa.js
CHANGED
|
@@ -1,28 +1,42 @@
|
|
|
1
|
-
const path = require(
|
|
2
|
-
const bodyParser = require(
|
|
3
|
-
const Router = require(
|
|
4
|
-
const koaStatic = require(
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const bodyParser = require("koa-bodyparser");
|
|
3
|
+
const Router = require("koa-router");
|
|
4
|
+
const koaStatic = require("koa-static");
|
|
5
|
+
const csp = require("../csp");
|
|
5
6
|
|
|
6
|
-
module.exports = agendash => {
|
|
7
|
+
module.exports = (agendash) => {
|
|
7
8
|
const middlewares = [];
|
|
8
9
|
|
|
9
|
-
middlewares.push(
|
|
10
|
+
middlewares.push(async (ctx, next) => {
|
|
11
|
+
await next();
|
|
12
|
+
ctx.set("Content-Security-Policy", csp);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
middlewares.push(
|
|
16
|
+
koaStatic(path.resolve(__dirname, "../../public"), { defer: true })
|
|
17
|
+
);
|
|
10
18
|
|
|
11
19
|
middlewares.push(bodyParser());
|
|
12
20
|
|
|
13
21
|
const routerApi = new Router();
|
|
14
22
|
|
|
15
|
-
routerApi.get(
|
|
16
|
-
const {job, state, skip, limit, q, property, isObjectId} = query;
|
|
23
|
+
routerApi.get("/api", async ({ response, query }) => {
|
|
24
|
+
const { job, state, skip, limit, q, property, isObjectId } = query;
|
|
17
25
|
try {
|
|
18
|
-
response.body = await agendash.api(job, state, {
|
|
26
|
+
response.body = await agendash.api(job, state, {
|
|
27
|
+
query: q,
|
|
28
|
+
property,
|
|
29
|
+
isObjectId,
|
|
30
|
+
skip,
|
|
31
|
+
limit,
|
|
32
|
+
});
|
|
19
33
|
} catch (error) {
|
|
20
34
|
response.status = 400;
|
|
21
35
|
response.body = error;
|
|
22
36
|
}
|
|
23
37
|
});
|
|
24
38
|
|
|
25
|
-
routerApi.post(
|
|
39
|
+
routerApi.post("/api/jobs/requeue", async ({ request, response }) => {
|
|
26
40
|
try {
|
|
27
41
|
response.body = await agendash.requeueJobs(request.body.jobIds);
|
|
28
42
|
} catch (error) {
|
|
@@ -31,11 +45,11 @@ module.exports = agendash => {
|
|
|
31
45
|
}
|
|
32
46
|
});
|
|
33
47
|
|
|
34
|
-
routerApi.post(
|
|
48
|
+
routerApi.post("/api/jobs/delete", async ({ request, response }) => {
|
|
35
49
|
try {
|
|
36
50
|
await agendash.deleteJobs(request.body.jobIds);
|
|
37
51
|
response.body = {
|
|
38
|
-
deleted: true
|
|
52
|
+
deleted: true,
|
|
39
53
|
};
|
|
40
54
|
} catch (error) {
|
|
41
55
|
response.status = 404;
|
|
@@ -43,18 +57,13 @@ module.exports = agendash => {
|
|
|
43
57
|
}
|
|
44
58
|
});
|
|
45
59
|
|
|
46
|
-
routerApi.post(
|
|
47
|
-
const {
|
|
48
|
-
jobData,
|
|
49
|
-
jobName,
|
|
50
|
-
jobSchedule,
|
|
51
|
-
jobRepeatEvery
|
|
52
|
-
} = request.body;
|
|
60
|
+
routerApi.post("/api/jobs/create", async ({ request, response }) => {
|
|
61
|
+
const { jobData, jobName, jobSchedule, jobRepeatEvery } = request.body;
|
|
53
62
|
|
|
54
63
|
try {
|
|
55
64
|
await agendash.createJob(jobName, jobSchedule, jobRepeatEvery, jobData);
|
|
56
65
|
response.body = {
|
|
57
|
-
created: true
|
|
66
|
+
created: true,
|
|
58
67
|
};
|
|
59
68
|
} catch (error) {
|
|
60
69
|
response.status = 404;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agendash",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "A modern dashboard for Agenda.js with Pagination and Search capabilities",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"bin": "bin/agendash-standalone.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "run-p lint ava",
|
|
12
|
-
"lint": "
|
|
12
|
+
"lint": "eslint ./",
|
|
13
13
|
"ava": "ava -v -c 1"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -27,8 +27,17 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/agenda/agendash#readme",
|
|
29
29
|
"license": "MIT",
|
|
30
|
+
"files": [
|
|
31
|
+
"bin",
|
|
32
|
+
"lib",
|
|
33
|
+
"public",
|
|
34
|
+
"app.js",
|
|
35
|
+
"*.png",
|
|
36
|
+
"Dockerfile",
|
|
37
|
+
"entrypoint.sh"
|
|
38
|
+
],
|
|
30
39
|
"dependencies": {
|
|
31
|
-
"agenda": "^
|
|
40
|
+
"agenda": "^4.2.1",
|
|
32
41
|
"body-parser": "^1.15.0",
|
|
33
42
|
"commander": "^2.9.0",
|
|
34
43
|
"express": "^4.0.0",
|
|
@@ -36,38 +45,31 @@
|
|
|
36
45
|
"semver": "^7.3.4"
|
|
37
46
|
},
|
|
38
47
|
"devDependencies": {
|
|
39
|
-
"@hapi/hapi": "^
|
|
40
|
-
"@hapi/inert": "^6.0.
|
|
41
|
-
"ava": "
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"koa
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
48
|
+
"@hapi/hapi": "^20.2.1",
|
|
49
|
+
"@hapi/inert": "^6.0.5",
|
|
50
|
+
"ava": "3.15.0",
|
|
51
|
+
"eslint": "7.19.0",
|
|
52
|
+
"fastify": "^3.24.0",
|
|
53
|
+
"fastify-static": "^4.5.0",
|
|
54
|
+
"koa": "2.13.1",
|
|
55
|
+
"koa-bodyparser": "4.3.0",
|
|
56
|
+
"koa-router": "10.0.0",
|
|
57
|
+
"koa-static": "5.0.0",
|
|
58
|
+
"npm-run-all": "4.1.5",
|
|
59
|
+
"prettier": "2.2.1",
|
|
60
|
+
"supertest": "^6.2.2"
|
|
49
61
|
},
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"max-params": [
|
|
58
|
-
"error",
|
|
59
|
-
5
|
|
60
|
-
],
|
|
61
|
-
"max-nested-callbacks": [
|
|
62
|
-
"error",
|
|
63
|
-
5
|
|
64
|
-
]
|
|
62
|
+
"eslintConfig": {
|
|
63
|
+
"parserOptions": {
|
|
64
|
+
"ecmaVersion": 2019
|
|
65
|
+
},
|
|
66
|
+
"env": {
|
|
67
|
+
"es6": true,
|
|
68
|
+
"node": true
|
|
65
69
|
},
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
]
|
|
72
|
-
}
|
|
70
|
+
"extends": "eslint:recommended"
|
|
71
|
+
},
|
|
72
|
+
"eslintIgnore": [
|
|
73
|
+
"public"
|
|
74
|
+
]
|
|
73
75
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const confirmDelete = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const confirmDelete = Vue.component("confirm-delete", {
|
|
2
|
+
props: ["job"],
|
|
3
3
|
methods: {
|
|
4
|
-
deleteOne(id){
|
|
4
|
+
deleteOne(id) {
|
|
5
5
|
const url = `api/jobs/delete`;
|
|
6
|
-
let body = {jobIds: [id]};
|
|
7
|
-
return axios
|
|
8
|
-
.
|
|
9
|
-
.then(
|
|
10
|
-
|
|
11
|
-
this.$emit(
|
|
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");
|
|
12
13
|
})
|
|
13
|
-
.catch(console.log)
|
|
14
|
-
}
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
15
16
|
},
|
|
16
17
|
template: `
|
|
17
18
|
<div class="modal fade" id="modalDeleteSure" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
@@ -35,5 +36,5 @@ const confirmDelete = Vue.component('confirm-delete', {
|
|
|
35
36
|
</div>
|
|
36
37
|
</div>
|
|
37
38
|
</div>
|
|
38
|
-
|
|
39
|
-
})
|
|
39
|
+
`,
|
|
40
|
+
});
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const confirmDeleteMulti = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const confirmDeleteMulti = Vue.component("confirm-multi-delete", {
|
|
2
|
+
props: ["jobs"],
|
|
3
3
|
methods: {
|
|
4
|
-
deleteMulti(ids){
|
|
4
|
+
deleteMulti(ids) {
|
|
5
5
|
const url = `api/jobs/delete`;
|
|
6
|
-
let body = {jobIds: ids};
|
|
7
|
-
return axios
|
|
8
|
-
.
|
|
9
|
-
.then(
|
|
10
|
-
|
|
11
|
-
this.$emit(
|
|
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");
|
|
12
13
|
})
|
|
13
|
-
.catch(console.log)
|
|
14
|
-
}
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
15
16
|
},
|
|
16
17
|
template: `
|
|
17
18
|
<div class="modal fade" id="modalDeleteSureMulti" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
@@ -40,5 +41,5 @@ const confirmDeleteMulti = Vue.component('confirm-multi-delete', {
|
|
|
40
41
|
</div>
|
|
41
42
|
</div>
|
|
42
43
|
</div>
|
|
43
|
-
|
|
44
|
-
})
|
|
44
|
+
`,
|
|
45
|
+
});
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
const confirmRequeue = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const confirmRequeue = Vue.component("confirm-requeue", {
|
|
2
|
+
props: ["job"],
|
|
3
3
|
methods: {
|
|
4
|
-
RequeueOne(id){
|
|
4
|
+
RequeueOne(id) {
|
|
5
5
|
const url = `api/jobs/requeue`;
|
|
6
|
-
let body = {jobIds: [id]};
|
|
7
|
-
return axios
|
|
8
|
-
.
|
|
9
|
-
.then(
|
|
10
|
-
|
|
11
|
-
this.$emit(
|
|
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");
|
|
12
13
|
})
|
|
13
|
-
.catch(console.log)
|
|
14
|
-
}
|
|
14
|
+
.catch(console.log);
|
|
15
|
+
},
|
|
15
16
|
},
|
|
16
17
|
template: `
|
|
17
18
|
<div class="modal fade" id="modalRequeueSure" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
@@ -35,5 +36,5 @@ const confirmRequeue = Vue.component('confirm-requeue', {
|
|
|
35
36
|
</div>
|
|
36
37
|
</div>
|
|
37
38
|
</div>
|
|
38
|
-
|
|
39
|
-
})
|
|
39
|
+
`,
|
|
40
|
+
});
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
const confirmRequeueMulti = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const confirmRequeueMulti = Vue.component("confirm-multi-requeue", {
|
|
2
|
+
props: ["jobs"],
|
|
3
3
|
methods: {
|
|
4
|
-
RequeueMulti(ids){
|
|
4
|
+
RequeueMulti(ids) {
|
|
5
5
|
const url = `api/jobs/requeue`;
|
|
6
|
-
let body = {jobIds: ids};
|
|
7
|
-
return axios
|
|
8
|
-
.
|
|
9
|
-
.then(
|
|
10
|
-
|
|
11
|
-
this.$emit(
|
|
12
|
-
this.$emit(
|
|
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");
|
|
13
14
|
})
|
|
14
|
-
.catch(console.log)
|
|
15
|
-
}
|
|
15
|
+
.catch(console.log);
|
|
16
|
+
},
|
|
16
17
|
},
|
|
17
18
|
template: `
|
|
18
19
|
<div class="modal fade" id="modalRequeueSureMulti" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
@@ -40,5 +41,5 @@ const confirmRequeueMulti = Vue.component('confirm-multi-requeue', {
|
|
|
40
41
|
</div>
|
|
41
42
|
</div>
|
|
42
43
|
</div>
|
|
43
|
-
|
|
44
|
-
})
|
|
44
|
+
`,
|
|
45
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const popupmessage = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const popupmessage = Vue.component("popup-message", {
|
|
2
|
+
props: ["job", "deletec", "requeuec", "createc"],
|
|
3
3
|
template: `
|
|
4
4
|
<div v-if="deletec" class="alert alert-success popupmessage">Job Deleted successfull</div>
|
|
5
5
|
<div v-else-if="requeuec" class="alert alert-success popupmessage">Job Requeue successfull</div>
|
|
6
6
|
<div v-else-if="createc" class="alert alert-success popupmessage">Job Created successfull</div>
|
|
7
|
-
|
|
8
|
-
})
|
|
7
|
+
`,
|
|
8
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const jobDetail = Vue.component(
|
|
2
|
-
props: [
|
|
1
|
+
const jobDetail = Vue.component("job-detail", {
|
|
2
|
+
props: ["job"],
|
|
3
3
|
filters: {
|
|
4
|
-
formatJSON(jsonstr){
|
|
4
|
+
formatJSON(jsonstr) {
|
|
5
5
|
return JSON.stringify(jsonstr, null, 2);
|
|
6
6
|
},
|
|
7
7
|
},
|
|
8
8
|
methods: {
|
|
9
|
-
formatDate(date){
|
|
10
|
-
return moment(date).format(
|
|
11
|
-
}
|
|
9
|
+
formatDate(date) {
|
|
10
|
+
return moment(date).format("DD-MM-YYYY HH:mm:ss");
|
|
11
|
+
},
|
|
12
12
|
},
|
|
13
13
|
template: `
|
|
14
14
|
<div class="modal fade" id="modalData" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
@@ -24,7 +24,7 @@ const jobDetail = Vue.component('job-detail', {
|
|
|
24
24
|
<div class="modal-body">
|
|
25
25
|
<div class="row my-3">
|
|
26
26
|
<div class="col">
|
|
27
|
-
<p><strong>Next run starts: </strong>{{ formatDate(job.job.
|
|
27
|
+
<p><strong>Next run starts: </strong>{{ formatDate(job.job.nextRunAt) }}</p>
|
|
28
28
|
<p><strong>Last run started: </strong>{{ formatDate(job.job.lastRunAt) }}</p>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
@@ -44,5 +44,5 @@ const jobDetail = Vue.component('job-detail', {
|
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
</div>
|
|
47
|
-
|
|
48
|
-
})
|
|
47
|
+
`,
|
|
48
|
+
});
|