alchemymvc 1.3.15 → 1.3.17
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/lib/app/behaviour/sluggable_behaviour.js +5 -1
- package/lib/app/conduit/socket_conduit.js +13 -0
- package/lib/app/datasource/mongo_datasource.js +86 -69
- package/lib/app/element/time_ago.js +19 -36
- package/lib/app/helper/alchemy_helper.js +2 -2
- package/lib/app/helper/cron.js +1502 -0
- package/lib/app/helper_datasource/00-nosql_datasource.js +16 -8
- package/lib/app/helper_field/schema_field.js +106 -7
- package/lib/app/helper_model/document.js +1 -0
- package/lib/app/helper_model/field_set.js +13 -0
- package/lib/app/helper_model/model.js +2 -2
- package/lib/app/model/alchemy_task_history_model.js +109 -0
- package/lib/app/model/alchemy_task_model.js +141 -18
- package/lib/bootstrap.js +3 -0
- package/lib/class/conduit.js +78 -21
- package/lib/class/datasource.js +18 -13
- package/lib/class/inode_file.js +5 -1
- package/lib/class/model.js +30 -2
- package/lib/class/route.js +5 -1
- package/lib/class/router.js +7 -2
- package/lib/class/schema_client.js +8 -11
- package/lib/class/session.js +14 -3
- package/lib/class/task.js +297 -145
- package/lib/class/task_service.js +933 -0
- package/lib/core/base.js +23 -1
- package/lib/core/client_alchemy.js +9 -5
- package/lib/core/middleware.js +2 -2
- package/lib/init/alchemy.js +149 -10
- package/lib/init/functions.js +53 -3
- package/package.json +25 -25
|
@@ -590,7 +590,7 @@ NoSQL.setStatic(function areComparable(a, b) {
|
|
|
590
590
|
*
|
|
591
591
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
592
592
|
* @since 1.1.0
|
|
593
|
-
* @version 1.3.
|
|
593
|
+
* @version 1.3.16
|
|
594
594
|
*
|
|
595
595
|
* @param {Criteria} criteria
|
|
596
596
|
* @param {Group} group
|
|
@@ -711,13 +711,16 @@ NoSQL.setMethod(function compileCriteria(criteria, group) {
|
|
|
711
711
|
|
|
712
712
|
let field_entry = {},
|
|
713
713
|
name = entry.target_path,
|
|
714
|
-
|
|
714
|
+
queries_property = name.indexOf('.') > -1;
|
|
715
715
|
|
|
716
716
|
// Do we need to look into an object itself?
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
717
|
+
if (entry.db_property) {
|
|
718
|
+
|
|
719
|
+
// Make sure the query doesn't already specifically query this property
|
|
720
|
+
if (name == entry.field.path) {
|
|
721
|
+
name += '.' + entry.db_property;
|
|
722
|
+
queries_property = true;
|
|
723
|
+
}
|
|
721
724
|
}
|
|
722
725
|
|
|
723
726
|
if (entry.association) {
|
|
@@ -824,10 +827,15 @@ NoSQL.setMethod(function compileCriteria(criteria, group) {
|
|
|
824
827
|
// (entry.field can be undefined if trying to query a path)
|
|
825
828
|
if (entry.field && entry.field.is_translatable) {
|
|
826
829
|
|
|
827
|
-
let prefix = criteria.options.locale
|
|
830
|
+
let prefix = criteria.options.locale,
|
|
831
|
+
specific_prefix = !!prefix;
|
|
832
|
+
|
|
833
|
+
if (specific_prefix && criteria?.model?.translate === false) {
|
|
834
|
+
specific_prefix = false;
|
|
835
|
+
}
|
|
828
836
|
|
|
829
837
|
// If a prefix is specified, only query that translation
|
|
830
|
-
if (
|
|
838
|
+
if (specific_prefix) {
|
|
831
839
|
prefixed_name = name + '.' + prefix;
|
|
832
840
|
} else {
|
|
833
841
|
multiple_fields = [];
|
|
@@ -5,9 +5,19 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
7
7
|
* @since 0.2.0
|
|
8
|
-
* @version 1.
|
|
8
|
+
* @version 1.3.16
|
|
9
9
|
*/
|
|
10
10
|
var SchemaField = Function.inherits('Alchemy.Field', function Schema(schema, name, options) {
|
|
11
|
+
|
|
12
|
+
if (!options) {
|
|
13
|
+
options = {};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// If the contents are array-like, the field itself can't be
|
|
17
|
+
if (this.force_array_contents) {
|
|
18
|
+
options.is_array = false;
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
Schema.super.call(this, schema, name, options);
|
|
12
22
|
|
|
13
23
|
if (options.schema == null || typeof options.schema != 'object') {
|
|
@@ -50,9 +60,18 @@ SchemaField.setDeprecatedProperty('fieldSchema', 'field_schema');
|
|
|
50
60
|
SchemaField.setDatatype('object');
|
|
51
61
|
|
|
52
62
|
/**
|
|
53
|
-
*
|
|
63
|
+
* Is this schema field always an array?
|
|
54
64
|
*
|
|
55
|
-
* @
|
|
65
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
66
|
+
* @since 1.3.16
|
|
67
|
+
* @version 1.3.16
|
|
68
|
+
*
|
|
69
|
+
* @return {Boolean}
|
|
70
|
+
*/
|
|
71
|
+
SchemaField.setProperty('force_array_contents', false);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get the subschema of this field
|
|
56
75
|
*
|
|
57
76
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
58
77
|
* @since 0.2.0
|
|
@@ -160,7 +179,7 @@ SchemaField.setMethod(function getSubschema(record, some_path) {
|
|
|
160
179
|
*
|
|
161
180
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
162
181
|
* @since 0.2.0
|
|
163
|
-
* @version 1.3.
|
|
182
|
+
* @version 1.3.16
|
|
164
183
|
*
|
|
165
184
|
* @param {Object} value Value of field, an object in this case
|
|
166
185
|
* @param {Object} data The data object containing `value`
|
|
@@ -170,6 +189,38 @@ SchemaField.setMethod(function getSubschema(record, some_path) {
|
|
|
170
189
|
*/
|
|
171
190
|
SchemaField.setMethod(function _toDatasource(value, holder, datasource, callback) {
|
|
172
191
|
|
|
192
|
+
if (!this.force_array_contents) {
|
|
193
|
+
return this._toDatasourceFromValue(value, holder, datasource, callback);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
value = Array.cast(value);
|
|
197
|
+
|
|
198
|
+
let tasks = [];
|
|
199
|
+
|
|
200
|
+
for (let entry of value) {
|
|
201
|
+
tasks.push(next => {
|
|
202
|
+
this._toDatasourceFromValue(entry, holder, datasource, next);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
Function.parallel(tasks, callback);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Cast all the subschema values using their _toDatasource method
|
|
211
|
+
*
|
|
212
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
213
|
+
* @since 0.2.0
|
|
214
|
+
* @version 1.3.1
|
|
215
|
+
*
|
|
216
|
+
* @param {Object} value Value of field, an object in this case
|
|
217
|
+
* @param {Object} data The data object containing `value`
|
|
218
|
+
* @param {Datasource} datasource The destination datasource
|
|
219
|
+
*
|
|
220
|
+
* @return {Object}
|
|
221
|
+
*/
|
|
222
|
+
SchemaField.setMethod(function _toDatasourceFromValue(value, holder, datasource, callback) {
|
|
223
|
+
|
|
173
224
|
var that = this,
|
|
174
225
|
sub_schema,
|
|
175
226
|
record,
|
|
@@ -241,13 +292,50 @@ SchemaField.setMethod(function _toDatasource(value, holder, datasource, callback
|
|
|
241
292
|
*
|
|
242
293
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
243
294
|
* @since 0.2.0
|
|
244
|
-
* @version 1.
|
|
295
|
+
* @version 1.3.16
|
|
245
296
|
*
|
|
246
297
|
* @param {Mixed} value
|
|
247
298
|
* @param {Function} callback
|
|
248
299
|
*/
|
|
249
300
|
SchemaField.setMethod(function _toApp(query, options, value, callback) {
|
|
250
301
|
|
|
302
|
+
if (!this.force_array_contents) {
|
|
303
|
+
return this._toAppFromValue(query, options, value, callback);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
value = Array.cast(value);
|
|
307
|
+
|
|
308
|
+
let tasks = [];
|
|
309
|
+
|
|
310
|
+
for (let entry of value) {
|
|
311
|
+
tasks.push(next => {
|
|
312
|
+
this._toAppFromValue(query, options, entry, next);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
Function.parallel(tasks, (err, result) => {
|
|
317
|
+
|
|
318
|
+
if (err) {
|
|
319
|
+
return callback(err);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
callback(null, this.cast(result));
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Turn datasource data into app data
|
|
329
|
+
*
|
|
330
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
331
|
+
* @since 0.2.0
|
|
332
|
+
* @version 1.3.16
|
|
333
|
+
*
|
|
334
|
+
* @param {Mixed} value
|
|
335
|
+
* @param {Function} callback
|
|
336
|
+
*/
|
|
337
|
+
SchemaField.setMethod(function _toAppFromValue(query, options, value, callback) {
|
|
338
|
+
|
|
251
339
|
var that = this,
|
|
252
340
|
recursive,
|
|
253
341
|
Dummy,
|
|
@@ -364,11 +452,11 @@ SchemaField.setMethod(function _toApp(query, options, value, callback) {
|
|
|
364
452
|
return callback(err);
|
|
365
453
|
}
|
|
366
454
|
|
|
367
|
-
callback(null, that.
|
|
455
|
+
callback(null, that.castEntry(result));
|
|
368
456
|
});
|
|
369
457
|
}
|
|
370
458
|
|
|
371
|
-
callback(null, this.
|
|
459
|
+
callback(null, this.castEntry(value));
|
|
372
460
|
});
|
|
373
461
|
|
|
374
462
|
/**
|
|
@@ -424,6 +512,17 @@ SchemaField.setMethod(function translateRecord(prefixes, record, allow_empty) {
|
|
|
424
512
|
}
|
|
425
513
|
});
|
|
426
514
|
|
|
515
|
+
/**
|
|
516
|
+
* Cast an entry
|
|
517
|
+
*
|
|
518
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
519
|
+
* @since 1.3.16
|
|
520
|
+
* @version 1.3.16
|
|
521
|
+
*/
|
|
522
|
+
SchemaField.setMethod(function castEntry(value, to_datasource) {
|
|
523
|
+
return value;
|
|
524
|
+
});
|
|
525
|
+
|
|
427
526
|
/**
|
|
428
527
|
* Cast the value to a document
|
|
429
528
|
*
|
|
@@ -1277,6 +1277,7 @@ Document.setMethod(function hasChanged(name) {
|
|
|
1277
1277
|
|
|
1278
1278
|
for (key in this.$attributes.original_record) {
|
|
1279
1279
|
if (!Object.alike(this.$attributes.original_record[key], this[key])) {
|
|
1280
|
+
// @TODO: some special fields always end up being different
|
|
1280
1281
|
result = true;
|
|
1281
1282
|
break;
|
|
1282
1283
|
}
|
|
@@ -60,6 +60,19 @@ FieldSet.setStatic(function fromArray(fields) {
|
|
|
60
60
|
return set;
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* How many fields have been added to this set?
|
|
65
|
+
*
|
|
66
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
67
|
+
* @since 1.3.16
|
|
68
|
+
* @version 1.3.16
|
|
69
|
+
*
|
|
70
|
+
* @type {Number}
|
|
71
|
+
*/
|
|
72
|
+
FieldSet.setProperty(function size() {
|
|
73
|
+
return this.fields.size;
|
|
74
|
+
});
|
|
75
|
+
|
|
63
76
|
/**
|
|
64
77
|
* Return an object for json-drying this list
|
|
65
78
|
*
|
|
@@ -516,7 +516,7 @@ Model.setMethod(function getDisplayTitleOrNull(item, fallbacks) {
|
|
|
516
516
|
*
|
|
517
517
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
518
518
|
* @since 0.0.1
|
|
519
|
-
* @version 1.3.
|
|
519
|
+
* @version 1.3.16
|
|
520
520
|
*
|
|
521
521
|
* @param {Object} item The record item of this model
|
|
522
522
|
* @param {String|Array} fallbacks Extra fallbacks to use
|
|
@@ -532,7 +532,7 @@ Model.setMethod(function getDisplayTitle(item, fallbacks) {
|
|
|
532
532
|
let result = this.getDisplayTitleOrNull(item, fallbacks);
|
|
533
533
|
|
|
534
534
|
if (result == null) {
|
|
535
|
-
result =
|
|
535
|
+
result = item[this.primary_key] || '';
|
|
536
536
|
|
|
537
537
|
if (result && typeof result != 'string') {
|
|
538
538
|
result = '' + result;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Alchemy Task History model:
|
|
3
|
+
* keep track of all the tasks that have been run
|
|
4
|
+
*
|
|
5
|
+
* @constructor
|
|
6
|
+
*
|
|
7
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
8
|
+
* @since 0.5.0
|
|
9
|
+
* @version 0.5.0
|
|
10
|
+
*/
|
|
11
|
+
const AlchemyTaskHistory = Function.inherits('Alchemy.Model.App', 'AlchemyTaskHistory');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constitute the class wide schema
|
|
15
|
+
*
|
|
16
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
17
|
+
* @since 0.5.0
|
|
18
|
+
* @version 1.3.17
|
|
19
|
+
*/
|
|
20
|
+
AlchemyTaskHistory.constitute(function addTaskFields() {
|
|
21
|
+
|
|
22
|
+
this.belongsTo('AlchemyTask', {
|
|
23
|
+
description : 'The original AlchemyTask document it belonged to',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// The timestamp this was scheduled for
|
|
27
|
+
this.addField('scheduled_at', 'Date', {
|
|
28
|
+
description : 'The original date this was scheduled for',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.addField('process_id', 'Integer', {
|
|
32
|
+
description : 'The process ID of the task',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// The type of Task that is running
|
|
36
|
+
this.addField('type', 'Enum', {
|
|
37
|
+
values: Classes.Alchemy.Task.Task.getLiveDescendantsMap(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// The payload/settings of the task
|
|
41
|
+
this.addField('settings', 'Schema', {
|
|
42
|
+
description : 'The settings of the task at the time it ran',
|
|
43
|
+
schema: 'type'
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.addField('had_error', 'Boolean', {
|
|
47
|
+
description : 'Did this task run into an error?'
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.addField('error_message', 'String', {
|
|
51
|
+
description : 'The main error message'
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.addField('error_stack', 'Text', {
|
|
55
|
+
description : 'The error stack trace'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.addField('is_running', 'Boolean', {
|
|
59
|
+
description : 'Is this task still running?',
|
|
60
|
+
default : false,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.addField('started_at', 'Datetime', {
|
|
64
|
+
description : 'The datetime this task actually started running',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.addField('ended_at', 'Datetime', {
|
|
68
|
+
description : 'The datetime this task actually ended',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
this.addIndex('type');
|
|
72
|
+
this.addIndex('is_running');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Configure the default chimera fieldsets
|
|
77
|
+
*
|
|
78
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
79
|
+
* @since 1.3.17
|
|
80
|
+
* @version 1.3.17
|
|
81
|
+
*/
|
|
82
|
+
AlchemyTaskHistory.constitute(function chimeraConfig() {
|
|
83
|
+
|
|
84
|
+
if (!this.chimera) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Get the list group
|
|
89
|
+
let list = this.chimera.getActionFields('list');
|
|
90
|
+
|
|
91
|
+
list.addField('created');
|
|
92
|
+
list.addField('type');
|
|
93
|
+
list.addField('process_id');
|
|
94
|
+
list.addField('scheduled_at');
|
|
95
|
+
list.addField('started_at');
|
|
96
|
+
list.addField('ended_at');
|
|
97
|
+
list.addField('had_error');
|
|
98
|
+
|
|
99
|
+
// Get the edit group
|
|
100
|
+
let edit = this.chimera.getActionFields('edit');
|
|
101
|
+
|
|
102
|
+
edit.addField('type');
|
|
103
|
+
edit.addField('settings');
|
|
104
|
+
edit.addField('had_error');
|
|
105
|
+
edit.addField('error_message');
|
|
106
|
+
edit.addField('error_stack');
|
|
107
|
+
edit.addField('started_at');
|
|
108
|
+
edit.addField('ended_at');
|
|
109
|
+
});
|
|
@@ -1,34 +1,157 @@
|
|
|
1
|
-
var all_task_types = alchemy.getClassGroup('task');
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* The Alchemy Task
|
|
2
|
+
* The Alchemy Task model:
|
|
3
|
+
*
|
|
5
4
|
*
|
|
6
5
|
* @constructor
|
|
7
6
|
*
|
|
8
|
-
* @author Jelle De Loecker <jelle@
|
|
9
|
-
* @since
|
|
10
|
-
* @version
|
|
7
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
8
|
+
* @since 1.3.17
|
|
9
|
+
* @version 1.3.17
|
|
10
|
+
*/
|
|
11
|
+
const AlchemyTask = Function.inherits('Alchemy.Model.App', 'AlchemyTask');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constitute the class wide schema
|
|
15
|
+
*
|
|
16
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
17
|
+
* @since 1.3.17
|
|
18
|
+
* @version 1.3.17
|
|
11
19
|
*/
|
|
12
|
-
|
|
20
|
+
AlchemyTask.constitute(function addTaskFields() {
|
|
21
|
+
|
|
22
|
+
this.addField('title', 'String', {
|
|
23
|
+
description : 'The title of the task',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
this.addField('type', 'Enum', {
|
|
27
|
+
values : Classes.Alchemy.Task.Task.getLiveDescendantsMap(),
|
|
28
|
+
description : 'The type of task to run',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.addField('settings', 'Schema', {
|
|
32
|
+
description : 'The settings to use for running the task',
|
|
33
|
+
schema: 'type'
|
|
34
|
+
});
|
|
13
35
|
|
|
14
|
-
|
|
36
|
+
this.addField('enabled', 'Boolean', {
|
|
37
|
+
description : 'Is this task enabled?',
|
|
38
|
+
default : true,
|
|
39
|
+
});
|
|
15
40
|
|
|
16
|
-
|
|
41
|
+
this.addField('frequency', 'String', {
|
|
42
|
+
description : 'The frequency this task should run at (CRON syntax)',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.addField('comment', 'Text', {
|
|
46
|
+
description : 'A comment about this task',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
this.addField('schedule_type', 'Enum', {
|
|
50
|
+
values: {
|
|
51
|
+
user : 'User',
|
|
52
|
+
system_forced : 'System (forced)',
|
|
53
|
+
system_fallback : 'System (fallback)',
|
|
54
|
+
},
|
|
55
|
+
default: 'user',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.addField('forced_schedule_checksum', 'String', {
|
|
59
|
+
description : 'Checksum of the cron syntax and settings, set only for tasks originating from forced schedules',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this.addIndex('forced_schedule_checksum', {
|
|
63
|
+
unique : true,
|
|
64
|
+
sparse : true,
|
|
65
|
+
});
|
|
17
66
|
});
|
|
18
67
|
|
|
19
68
|
/**
|
|
20
|
-
*
|
|
69
|
+
* Configure the default chimera fieldsets
|
|
21
70
|
*
|
|
22
|
-
* @author Jelle De Loecker
|
|
23
|
-
* @since
|
|
24
|
-
* @version
|
|
71
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
72
|
+
* @since 1.3.17
|
|
73
|
+
* @version 1.3.17
|
|
25
74
|
*/
|
|
26
|
-
AlchemyTask.constitute(function
|
|
75
|
+
AlchemyTask.constitute(function chimeraConfig() {
|
|
76
|
+
|
|
77
|
+
if (!this.chimera) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Get the list group
|
|
82
|
+
let list = this.chimera.getActionFields('list');
|
|
83
|
+
|
|
84
|
+
list.addField('title');
|
|
85
|
+
list.addField('type');
|
|
86
|
+
list.addField('enabled');
|
|
87
|
+
list.addField('frequency');
|
|
88
|
+
list.addField('schedule_type');
|
|
89
|
+
|
|
90
|
+
// Get the edit group
|
|
91
|
+
let edit = this.chimera.getActionFields('edit');
|
|
92
|
+
|
|
93
|
+
edit.addField('title');
|
|
94
|
+
edit.addField('frequency')
|
|
95
|
+
edit.addField('enabled');
|
|
96
|
+
edit.addField('type');
|
|
97
|
+
edit.addField('settings');
|
|
98
|
+
edit.addField('comment');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Do something before saving the record
|
|
103
|
+
*
|
|
104
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
105
|
+
* @since 1.3.17
|
|
106
|
+
* @version 1.3.17
|
|
107
|
+
*
|
|
108
|
+
* @param {Document.AlchemyTask} doc
|
|
109
|
+
*/
|
|
110
|
+
AlchemyTask.setMethod(function beforeSave(doc) {
|
|
111
|
+
|
|
112
|
+
if (!doc.schedule_type) {
|
|
113
|
+
doc.schedule_type = 'user';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (doc.enabled == null) {
|
|
117
|
+
doc.enabled = false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!doc.title) {
|
|
121
|
+
let title = '';
|
|
122
|
+
|
|
123
|
+
if (doc.schedule_type == 'system_forced') {
|
|
124
|
+
title += 'System forced: ';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (doc.schedule_type == 'system_fallback') {
|
|
128
|
+
title += 'System fallback: ';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
title += doc.type;
|
|
132
|
+
doc.title = title;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Update the schedules after saving
|
|
138
|
+
*
|
|
139
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
140
|
+
* @since 1.3.17
|
|
141
|
+
* @version 1.3.17
|
|
142
|
+
*
|
|
143
|
+
* @param {Object} main
|
|
144
|
+
* @param {Object} info
|
|
145
|
+
*/
|
|
146
|
+
AlchemyTask.setMethod(function afterSave(main, info) {
|
|
27
147
|
|
|
28
|
-
|
|
29
|
-
|
|
148
|
+
if (!main.type) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
30
151
|
|
|
31
|
-
|
|
32
|
-
|
|
152
|
+
if (!alchemy.task_service.has_loaded) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
33
155
|
|
|
156
|
+
alchemy.task_service.rescheduleTasksOfType(main.type);
|
|
34
157
|
});
|
package/lib/bootstrap.js
CHANGED
|
@@ -312,6 +312,9 @@ Alchemy.setMethod(function start(options, callback) {
|
|
|
312
312
|
// Make sure Blast has executed everything that's still waiting
|
|
313
313
|
Blast.doLoaded();
|
|
314
314
|
|
|
315
|
+
// Call the `afterStart` method
|
|
316
|
+
this.ready(() => this.afterStart());
|
|
317
|
+
|
|
315
318
|
// Schedule the callback
|
|
316
319
|
return this.ready(callback);
|
|
317
320
|
});
|