agendash 3.1.0 → 4.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/History.md +118 -0
- package/bin/agendash-standalone-fastify.js +1 -1
- package/lib/controllers/agendash.js +4 -3
- package/lib/middlewares/fastify.js +1 -1
- package/package.json +6 -6
- package/public/app/css/styles.css +13 -1
- package/public/app/js/jobdetail.js +1 -1
- package/public/app/js/joblist.js +15 -6
- package/public/app/js/main.js +21 -13
- package/public/app/js/sidebar.js +1 -1
- package/public/app/js/topbar.js +2 -2
package/History.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 4.0.0
|
|
2
|
+
|
|
3
|
+
- Drop support for node 12. Add support for node 18 and MongoDB 5.0.
|
|
4
|
+
- Fastify upgraded to v4. #215
|
|
5
|
+
- Various UI fixes. #212 #203
|
|
6
|
+
- Vulnerability fixes. #220
|
|
7
|
+
- Requeue and Delete job fixes. #226 #227
|
|
8
|
+
|
|
9
|
+
# 3.1.0
|
|
10
|
+
|
|
11
|
+
- Add Content-Security-Policy header to all server implementations
|
|
12
|
+
|
|
13
|
+
# 3.0.0
|
|
14
|
+
|
|
15
|
+
- BREAKING: Drop support for MongoDB v3.4, only >=v3.6 is supported now.
|
|
16
|
+
- BREAKING: Drop support for node 10, but added node 16 support.
|
|
17
|
+
- feat: add `fastify` support #194
|
|
18
|
+
- fix: a lot of rendering issues
|
|
19
|
+
- fix: newer version of `mongodb` compatibility #193
|
|
20
|
+
|
|
21
|
+
This file won't mention contributors anymore. Because all contributors are listed on the [main page](https://github.com/agenda/agendash) now. Thanks, GitHub!
|
|
22
|
+
|
|
23
|
+
# 2.1.0 - JSON validation when creating jobs
|
|
24
|
+
|
|
25
|
+
- feat: Add json validator message when createJob #169 (thanks @love8587)
|
|
26
|
+
|
|
27
|
+
# 2.0.0 - First public release of v2 as Agendash proper
|
|
28
|
+
|
|
29
|
+
Complete rewrite of Agendash in Vue.js!
|
|
30
|
+
|
|
31
|
+
Supports Node.js 10 and up.
|
|
32
|
+
|
|
33
|
+
# 2.0.0-beta0.8.2 / 2020-12-04 - As agendash2, in parallel repository https://github.com/agenda/agendash-v2
|
|
34
|
+
|
|
35
|
+
- fix: search by job name, small side bar design fix and toggle improvements (thanks @simllll)
|
|
36
|
+
- fix: joblist reset fix (thanks @simllll)
|
|
37
|
+
- fix: improve design on desktop + close sidebar on mobile when clicked on something (thanks @simllll)
|
|
38
|
+
- feat: enable options.query as number (thanks @Enubia @simllll)
|
|
39
|
+
- feat: multiselect checkboxes (thanks @Enubia @simllll)
|
|
40
|
+
|
|
41
|
+
# 2.0.0-beta0.1.0 / 2020-04-30 - First public release of Agendash2 in parallel repository https://github.com/agenda/agendash-v2
|
|
42
|
+
|
|
43
|
+
- New frontend written from scratch in Vue.js
|
|
44
|
+
- Add search
|
|
45
|
+
- Add pagination
|
|
46
|
+
- Change default refresh interval to 60 seconds
|
|
47
|
+
|
|
48
|
+
# 1.0.0 / 2019-02-25
|
|
49
|
+
|
|
50
|
+
- Add Hapi v17 middleware, drop support for Node.js v6 & v7 (#81) by umens (**BREAKING**)
|
|
51
|
+
- Support Agenda version 2 by alexkwolfe (**BREAKING**)
|
|
52
|
+
|
|
53
|
+
# 0.5.0 / 2019-02-25
|
|
54
|
+
|
|
55
|
+
- Update dependencies (#69, #70) (**BREAKING**)
|
|
56
|
+
- Agenda `>=0.7.0 <1.0.0` → `^1.0.3` and thus require MongoDB v3+
|
|
57
|
+
- async `^1.0.0` → `^2.6.0`
|
|
58
|
+
- Drop support for Node.js v4 and v5 (might still work but we're stopping testing these) (**BREAKING**)
|
|
59
|
+
- Switch testing with Mocha to [Ava](https://www.npmjs.com/package/ava) (#70)
|
|
60
|
+
- Docker support (#54) by WoLfulus
|
|
61
|
+
- Fix 404 errors when deleting and re-queuing jobs (#61) by koresar
|
|
62
|
+
|
|
63
|
+
# 0.4.0 / 2016-10-27
|
|
64
|
+
|
|
65
|
+
- (simison) Agenda dependency version `<1.0.0` to avoid breaking dependency.
|
|
66
|
+
- (loris) Fix #24 - Added indexes for faster queries.
|
|
67
|
+
- Fix #28 - Removed dependency on Mongo Driver.
|
|
68
|
+
- Added API tests with mocha and supertest. No frontend tests.
|
|
69
|
+
|
|
70
|
+
# 0.3.2 / 2016-06-30
|
|
71
|
+
|
|
72
|
+
- (HugoCornu) Fix #19 "Schedule Job" - Don't repeat job if user didn't want it repeated
|
|
73
|
+
|
|
74
|
+
# 0.3.1 / 2016-04-12
|
|
75
|
+
|
|
76
|
+
- (simison) Add engines key to package.json
|
|
77
|
+
|
|
78
|
+
# 0.3.0 / 2016-04-04
|
|
79
|
+
|
|
80
|
+
- (bh-chaker) Schedule Job Feature - create new jobs from the UI
|
|
81
|
+
- Limit to 200 jobs on page, no UI for configuration
|
|
82
|
+
|
|
83
|
+
# 0.2.1 / 2016-03-25
|
|
84
|
+
|
|
85
|
+
- (vziukas) Recurring job count and labels
|
|
86
|
+
- Fixed "queued" label colors
|
|
87
|
+
|
|
88
|
+
# 0.2.0 / 2016-03-18
|
|
89
|
+
|
|
90
|
+
- (vziukas) Configurable title
|
|
91
|
+
- Middleware option moved to "options" object
|
|
92
|
+
|
|
93
|
+
# 0.1.1 / 2016-03-17
|
|
94
|
+
|
|
95
|
+
- (vziukas) multiple instances of agendash can each have a separate agenda
|
|
96
|
+
|
|
97
|
+
# 0.1.0 / 2016-03-15
|
|
98
|
+
|
|
99
|
+
- (rapidia) remove "arrow function" syntax for non-chrome browsers
|
|
100
|
+
- (ebourmalo) Fix the middleware usage and use a proper structure
|
|
101
|
+
|
|
102
|
+
# 0.0.5 / 2016-02-24
|
|
103
|
+
|
|
104
|
+
- Batch requeue and delete
|
|
105
|
+
- Select All and Select None
|
|
106
|
+
|
|
107
|
+
# 0.0.4 / 2016-02-24
|
|
108
|
+
|
|
109
|
+
- Select multiple jobs
|
|
110
|
+
|
|
111
|
+
# 0.0.2 / 2016-02-23
|
|
112
|
+
|
|
113
|
+
- version bump so npm will update docs
|
|
114
|
+
- Added screenshots
|
|
115
|
+
|
|
116
|
+
# 0.0.1 / 2016-02-23
|
|
117
|
+
|
|
118
|
+
- Initial Release
|
|
@@ -42,7 +42,7 @@ module.exports = function (agenda, options) {
|
|
|
42
42
|
|
|
43
43
|
if (options.query && options.property) {
|
|
44
44
|
if (options.isObjectId) {
|
|
45
|
-
preMatch[options.property] = ObjectId(options.query);
|
|
45
|
+
preMatch[options.property] = new ObjectId(options.query);
|
|
46
46
|
} else if (/^\d+$/.test(options.query)) {
|
|
47
47
|
preMatch[options.property] = Number.parseInt(options.query, 10);
|
|
48
48
|
} else {
|
|
@@ -61,6 +61,7 @@ module.exports = function (agenda, options) {
|
|
|
61
61
|
{ $match: preMatch },
|
|
62
62
|
{
|
|
63
63
|
$sort: {
|
|
64
|
+
repeatInterval: -1,
|
|
64
65
|
nextRunAt: -1,
|
|
65
66
|
lastRunAt: -1,
|
|
66
67
|
lastFinishedAt: -1,
|
|
@@ -284,7 +285,7 @@ module.exports = function (agenda, options) {
|
|
|
284
285
|
const collection = agenda._collection.collection || agenda._collection;
|
|
285
286
|
const jobs = await collection
|
|
286
287
|
.find({
|
|
287
|
-
_id: { $in: jobIds.map((jobId) => ObjectId(jobId)) },
|
|
288
|
+
_id: { $in: jobIds.map((jobId) => new ObjectId(jobId)) },
|
|
288
289
|
})
|
|
289
290
|
.toArray();
|
|
290
291
|
if (jobs.length === 0) {
|
|
@@ -306,7 +307,7 @@ module.exports = function (agenda, options) {
|
|
|
306
307
|
}
|
|
307
308
|
|
|
308
309
|
return agenda.cancel({
|
|
309
|
-
_id: { $in: jobIds.map((jobId) => ObjectId(jobId)) },
|
|
310
|
+
_id: { $in: jobIds.map((jobId) => new ObjectId(jobId)) },
|
|
310
311
|
});
|
|
311
312
|
};
|
|
312
313
|
|
|
@@ -4,7 +4,7 @@ const csp = require("../csp");
|
|
|
4
4
|
module.exports = (agendash) => (instance, opts, done) => {
|
|
5
5
|
const { api, requeueJobs, deleteJobs, createJob } = agendash;
|
|
6
6
|
|
|
7
|
-
instance.register(require("fastify
|
|
7
|
+
instance.register(require("@fastify/static"), {
|
|
8
8
|
root: path.join(__dirname, "../../public"),
|
|
9
9
|
});
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agendash",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.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",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=14.0.0"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "run-p lint ava",
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"agenda": "^4.2.1",
|
|
41
|
-
"body-parser": "^1.
|
|
41
|
+
"body-parser": "^1.19.2",
|
|
42
42
|
"commander": "^2.9.0",
|
|
43
|
-
"express": "^4.
|
|
43
|
+
"express": "^4.17.3",
|
|
44
44
|
"mongodb": "*",
|
|
45
45
|
"semver": "^7.3.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
+
"@fastify/static": "^6.5.0",
|
|
48
49
|
"@hapi/hapi": "^20.2.1",
|
|
49
50
|
"@hapi/inert": "^6.0.5",
|
|
50
51
|
"ava": "3.15.0",
|
|
51
52
|
"eslint": "7.19.0",
|
|
52
|
-
"fastify": "^
|
|
53
|
-
"fastify-static": "^4.5.0",
|
|
53
|
+
"fastify": "^4.9.2",
|
|
54
54
|
"koa": "2.13.1",
|
|
55
55
|
"koa-bodyparser": "4.3.0",
|
|
56
56
|
"koa-router": "10.0.0",
|
|
@@ -122,8 +122,20 @@ code {
|
|
|
122
122
|
margin: 0 2px;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
.job-detail-dialog {
|
|
126
|
+
max-width: calc(100vw - 1.75rem * 2);
|
|
127
|
+
}
|
|
128
|
+
.modal-body > * {
|
|
129
|
+
flex: 0 1 auto;
|
|
130
|
+
}
|
|
131
|
+
.modal-body {
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-flow: column;
|
|
134
|
+
max-height: calc(100vh - 195px);
|
|
135
|
+
}
|
|
136
|
+
|
|
125
137
|
.json-editor {
|
|
126
|
-
|
|
138
|
+
flex: 1 1 auto;
|
|
127
139
|
}
|
|
128
140
|
.card-responsive-title-container {
|
|
129
141
|
display: flex;
|
|
@@ -13,7 +13,7 @@ const jobDetail = Vue.component("job-detail", {
|
|
|
13
13
|
template: `
|
|
14
14
|
<div class="modal fade" id="modalData" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
15
15
|
<!-- Modal -->
|
|
16
|
-
<div class="modal-dialog" role="document">
|
|
16
|
+
<div class="modal-dialog job-detail-dialog" role="document">
|
|
17
17
|
<div class="modal-content">
|
|
18
18
|
<div class="modal-header">
|
|
19
19
|
<h5 class="modal-title" id="exampleModalLabel">Job Data - {{job.job.name}}</h5>
|
package/public/app/js/joblist.js
CHANGED
|
@@ -4,10 +4,10 @@ const jobList = Vue.component("job-list", {
|
|
|
4
4
|
currentSort: "name",
|
|
5
5
|
currentSortDir: "asc",
|
|
6
6
|
}),
|
|
7
|
-
props: ["jobs", "pagesize", "pagenumber", "sendClean", "loading"],
|
|
7
|
+
props: ["jobs", "pagesize", "pagenumber", "totalPages", "sendClean", "loading"],
|
|
8
8
|
computed: {
|
|
9
9
|
sortedJobs: function () {
|
|
10
|
-
|
|
10
|
+
var sortedJobs = this.jobs.sort((a, b) => {
|
|
11
11
|
let displayA, displayB;
|
|
12
12
|
if (this.currentSort === "name") {
|
|
13
13
|
displayA = a.job[this.currentSort]
|
|
@@ -26,6 +26,12 @@ const jobList = Vue.component("job-list", {
|
|
|
26
26
|
if (displayA > displayB) return 1 * modifier;
|
|
27
27
|
return 0;
|
|
28
28
|
});
|
|
29
|
+
|
|
30
|
+
/** Show recurring jobs first */
|
|
31
|
+
return Array.prototype.concat(
|
|
32
|
+
sortedJobs.filter(job => job.repeating === true),
|
|
33
|
+
sortedJobs.filter(job => job.repeating === false),
|
|
34
|
+
)
|
|
29
35
|
},
|
|
30
36
|
},
|
|
31
37
|
watch: {
|
|
@@ -226,14 +232,17 @@ const jobList = Vue.component("job-list", {
|
|
|
226
232
|
<nav aria-label="Page navigation example">
|
|
227
233
|
<ul class="pagination">
|
|
228
234
|
<li class="page-item" :class="pagenumber === 1 ? 'disabled': ''"><a class="page-link" @click="$emit('pagechange', 'prev')">Previous</a></li>
|
|
229
|
-
|
|
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>
|
|
235
|
+
<li class="page-item" :class="pagenumber >= totalPages ? 'disabled': ''"> <a style="cursor:pointer;" class="page-link" @click="$emit('pagechange', 'next')">Next</a> </li>
|
|
233
236
|
</ul>
|
|
234
237
|
</nav>
|
|
235
238
|
</div>
|
|
236
239
|
</div>
|
|
240
|
+
|
|
241
|
+
<div class="row">
|
|
242
|
+
<div class="col d-flex justify-content-center">
|
|
243
|
+
Page: {{pagenumber}} / {{totalPages}}
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
237
246
|
</div>
|
|
238
247
|
`,
|
|
239
248
|
});
|
package/public/app/js/main.js
CHANGED
|
@@ -2,9 +2,10 @@ const app = Vue.component("app", {
|
|
|
2
2
|
data: () => ({
|
|
3
3
|
jobs: [],
|
|
4
4
|
overview: [],
|
|
5
|
-
refresh:
|
|
5
|
+
refresh: 30,
|
|
6
6
|
showDetail: false,
|
|
7
7
|
pagenumber: 1,
|
|
8
|
+
totalPages: 0,
|
|
8
9
|
showConfirm: false,
|
|
9
10
|
showConfirmMulti: false,
|
|
10
11
|
showConfirmRequeue: false,
|
|
@@ -13,7 +14,7 @@ const app = Vue.component("app", {
|
|
|
13
14
|
jobData: {},
|
|
14
15
|
deletec: false,
|
|
15
16
|
requeuec: false,
|
|
16
|
-
pagesize:
|
|
17
|
+
pagesize: 50,
|
|
17
18
|
sendClean: false,
|
|
18
19
|
createc: false,
|
|
19
20
|
property: "",
|
|
@@ -66,14 +67,19 @@ const app = Vue.component("app", {
|
|
|
66
67
|
this.showNewJob = true;
|
|
67
68
|
},
|
|
68
69
|
searchForm(name, search, property, limit, skip, refresh, state, object) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
this.pagesize = limit ? limit : this.pagesize
|
|
71
|
+
this.name = name
|
|
72
|
+
this.search = search
|
|
73
|
+
this.property = property
|
|
74
|
+
this.skip = skip
|
|
75
|
+
this.refresh = refresh
|
|
76
|
+
this.state = state
|
|
77
|
+
this.object = object ? object : this.object
|
|
78
|
+
|
|
79
|
+
// Form changed, reset the pagination state
|
|
80
|
+
this.pagenumber = 1
|
|
81
|
+
this.totalPages = 1
|
|
82
|
+
|
|
77
83
|
this.fetchData(
|
|
78
84
|
this.name,
|
|
79
85
|
this.search,
|
|
@@ -120,9 +126,9 @@ const app = Vue.component("app", {
|
|
|
120
126
|
name = "",
|
|
121
127
|
search = "",
|
|
122
128
|
property = "",
|
|
123
|
-
limit =
|
|
129
|
+
limit = 50,
|
|
124
130
|
skip = 0,
|
|
125
|
-
refresh =
|
|
131
|
+
refresh = 30,
|
|
126
132
|
state = "",
|
|
127
133
|
object
|
|
128
134
|
) {
|
|
@@ -143,6 +149,7 @@ const app = Vue.component("app", {
|
|
|
143
149
|
this.object = object;
|
|
144
150
|
this.overview = data.overview;
|
|
145
151
|
this.loading = false;
|
|
152
|
+
this.totalPages = data.totalPages;
|
|
146
153
|
},
|
|
147
154
|
() => {
|
|
148
155
|
this.loading = false;
|
|
@@ -229,7 +236,7 @@ const app = Vue.component("app", {
|
|
|
229
236
|
>
|
|
230
237
|
</sidebar>
|
|
231
238
|
</div>
|
|
232
|
-
<main role="main" class="col-md-10 ml-sm-auto col-lg-10 px-4">
|
|
239
|
+
<main role="main" class="col-md-10 ml-sm-auto col-lg-10 px-4 pt-3 pb-5">
|
|
233
240
|
<div class="col-12">
|
|
234
241
|
<topbar v-on:search-form="searchForm"
|
|
235
242
|
:name='name'
|
|
@@ -249,6 +256,7 @@ const app = Vue.component("app", {
|
|
|
249
256
|
v-on:pagechange="pagechange"
|
|
250
257
|
:pagesize="pagesize"
|
|
251
258
|
:pagenumber='pagenumber'
|
|
259
|
+
:totalPages='totalPages'
|
|
252
260
|
:skip="skip"
|
|
253
261
|
:jobs="jobs"
|
|
254
262
|
:sendClean='sendClean'
|
package/public/app/js/sidebar.js
CHANGED
|
@@ -63,7 +63,7 @@ const sidebar = Vue.component("sidebar", {
|
|
|
63
63
|
},
|
|
64
64
|
},
|
|
65
65
|
template: `
|
|
66
|
-
<div class="col sidebar">
|
|
66
|
+
<div class="col sidebar pt-4">
|
|
67
67
|
<div class="row">
|
|
68
68
|
<div class="col ">
|
|
69
69
|
<button data-toggle="modal" data-target="#modalNewJob" @click="$emit('new-job')" data-placement="top" title="Add a new job" class="btn btn-block btn-outline-success"><i class="oi oi-plus IcoInButton"></i> New Job</button>
|