[IMP] mail: delete time model, add clock and clock watcher models
The Time model is deleted and replaced with the new Clock model. The differences are that there can be several clocks, whereas Time was a singleton, and that a clock must define the frequency at which it updates. The new model ClockWatcher is added to model a record that makes use of a clock. This is currently useful for the clocks to set or clear intervals as needed. closes odoo/odoo#86219 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
@@ -74,7 +74,7 @@ registerModel({
|
||||
if (!this.activity.dateDeadline) {
|
||||
return clear();
|
||||
}
|
||||
const today = moment(this.messaging.time.currentDateEveryMinute.getTime()).startOf('day');
|
||||
const today = moment(this.clockWatcher.clock.date.getTime()).startOf('day');
|
||||
const momentDeadlineDate = moment(auto_str_to_date(this.activity.dateDeadline));
|
||||
// true means no rounding
|
||||
const diff = momentDeadlineDate.diff(today, 'days', true);
|
||||
@@ -167,6 +167,15 @@ registerModel({
|
||||
assignedUserText: attr({
|
||||
compute: '_computeAssignedUserText',
|
||||
}),
|
||||
clockWatcher: one('ClockWatcher', {
|
||||
default: insertAndReplace({
|
||||
clock: insertAndReplace({
|
||||
frequency: 60 * 1000,
|
||||
}),
|
||||
}),
|
||||
inverse: 'activityViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
/**
|
||||
* Compute the label for "when" the activity is due.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr, many } from '@mail/model/model_field';
|
||||
import { OnChange } from '@mail/model/model_onchange';
|
||||
|
||||
/**
|
||||
* Models a record that provides the current date, updated at a given frequency.
|
||||
*/
|
||||
registerModel({
|
||||
name: 'Clock',
|
||||
identifyingFields: ['frequency'],
|
||||
lifecycleHooks: {
|
||||
_willDelete() {
|
||||
this.messaging.browser.clearInterval(this.tickInterval);
|
||||
},
|
||||
},
|
||||
recordMethods: {
|
||||
/**
|
||||
* @private
|
||||
* @returns {integer}
|
||||
*/
|
||||
_computeTickInterval() {
|
||||
return this.messaging.browser.setInterval(this._onInterval, this.frequency);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onChangeWatchers() {
|
||||
if (this.watchers.length === 0) {
|
||||
this.delete();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onInterval() {
|
||||
this.update({ date: new Date() });
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
/**
|
||||
* A Date object set at the current date, updated at every tick.
|
||||
*/
|
||||
date: attr({
|
||||
default: new Date(),
|
||||
}),
|
||||
/**
|
||||
* An integer representing the frequency in milliseconds at which `date`
|
||||
* must be recomputed.
|
||||
*/
|
||||
frequency: attr({
|
||||
readonly: true,
|
||||
required: true,
|
||||
}),
|
||||
tickInterval: attr({
|
||||
compute: '_computeTickInterval',
|
||||
}),
|
||||
/**
|
||||
* The records that are making use of this clock.
|
||||
*
|
||||
* The clock self-destructs when there are no more watchers.
|
||||
*/
|
||||
watchers: many('ClockWatcher', {
|
||||
inverse: 'clock',
|
||||
isCausal: true,
|
||||
}),
|
||||
},
|
||||
onChanges: [
|
||||
new OnChange({
|
||||
dependencies: ['watchers'],
|
||||
methodName: '_onChangeWatchers',
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { one } from '@mail/model/model_field';
|
||||
|
||||
/**
|
||||
* Models a record that makes use of a clock.
|
||||
*/
|
||||
registerModel({
|
||||
name: 'ClockWatcher',
|
||||
identifyingFields: [['activityViewOwner']],
|
||||
fields: {
|
||||
activityViewOwner: one('ActivityView', {
|
||||
inverse: 'clockWatcher',
|
||||
readonly: true,
|
||||
}),
|
||||
clock: one('Clock', {
|
||||
inverse: 'watchers',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -375,12 +375,6 @@ registerModel({
|
||||
* Mailbox Starred.
|
||||
*/
|
||||
starred: one('Thread'),
|
||||
time: one('Time', {
|
||||
default: insertAndReplace(),
|
||||
isCausal: true,
|
||||
readonly: true,
|
||||
required: true,
|
||||
}),
|
||||
userSetting: one('UserSetting', {
|
||||
isCausal: true,
|
||||
}),
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr } from '@mail/model/model_field';
|
||||
|
||||
registerModel({
|
||||
name: 'Time',
|
||||
identifyingFields: ['messaging'],
|
||||
lifecycleHooks: {
|
||||
_willDelete() {
|
||||
clearInterval(this.everyMinuteIntervalId);
|
||||
},
|
||||
},
|
||||
recordMethods: {
|
||||
/**
|
||||
* @private
|
||||
* @returns {number}
|
||||
*/
|
||||
_computeEveryMinuteIntervalId() {
|
||||
return setInterval(this._onEveryMinuteTimeout, 60 * 1000);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onEveryMinuteTimeout() {
|
||||
this.update({ currentDateEveryMinute: new Date() });
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
/**
|
||||
* Contains a Date object that is set to the current time, and is
|
||||
* (re-)computed every minute.
|
||||
*/
|
||||
currentDateEveryMinute: attr({
|
||||
default: new Date(),
|
||||
}),
|
||||
everyMinuteIntervalId: attr({
|
||||
compute: '_computeEveryMinuteIntervalId',
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { insertAndReplace } from '@mail/model/model_field_command';
|
||||
import { afterEach, beforeEach, start } from '@mail/utils/test_utils';
|
||||
|
||||
QUnit.module('mail', {}, function () {
|
||||
QUnit.module('clock_model_tests', {
|
||||
async beforeEach() {
|
||||
await beforeEach(this);
|
||||
|
||||
this.start = async params => {
|
||||
const res = await start({ ...params, data: this.data });
|
||||
const { apps, env, widget } = res;
|
||||
this.apps = apps;
|
||||
this.env = env;
|
||||
this.widget = widget;
|
||||
return res;
|
||||
};
|
||||
},
|
||||
afterEach() {
|
||||
afterEach(this);
|
||||
},
|
||||
});
|
||||
|
||||
QUnit.test('Deleting all the watchers of a clock should result in the deletion of the clock itself.', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
await this.start();
|
||||
const watcher = this.messaging.models['ClockWatcher'].insert({
|
||||
clock: insertAndReplace({ frequency: 180 * 1000 }),
|
||||
qunitTestOwner: insertAndReplace(),
|
||||
});
|
||||
const { clock } = watcher;
|
||||
|
||||
watcher.delete();
|
||||
assert.notOk(
|
||||
clock.exists(),
|
||||
"deleting all the watchers of a clock should result in the deletion of the clock itself."
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addFields, patchIdentifyingFields } from '@mail/model/model_core';
|
||||
import { one } from '@mail/model/model_field';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/clock_watcher/clock_watcher';
|
||||
|
||||
patchIdentifyingFields('ClockWatcher', identifyingFields => {
|
||||
identifyingFields[0].push('qunitTestOwner');
|
||||
});
|
||||
|
||||
addFields('ClockWatcher', {
|
||||
qunitTestOwner: one('QUnitTest', {
|
||||
inverse: 'clockWatcher',
|
||||
readonly: true,
|
||||
}),
|
||||
});
|
||||
@@ -7,6 +7,10 @@ registerModel({
|
||||
name: 'QUnitTest',
|
||||
identifyingFields: [], // singleton acceptable (only one test at a time)
|
||||
fields: {
|
||||
clockWatcher: one('ClockWatcher', {
|
||||
inverse: 'qunitTestOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
composer: one('Composer', {
|
||||
isCausal: true,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user