[IMP] mail: create model view for activity popover

task-2579306

closes odoo/odoo#81859

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Didier (did)
2022-01-12 17:33:52 +00:00
committed by Sébastien Theys
parent 33f58b2824
commit cfd5adbb2e
6 changed files with 104 additions and 98 deletions
@@ -121,7 +121,7 @@
<i class="fa fa-check"/> Mark Done
</button>
<t t-set="opened">
<ActivityMarkDonePopover activityLocalId="activityView.activity.localId"/>
<ActivityMarkDonePopover localId="activityView.activityMarkDonePopoverView.localId"/>
</t>
</Popover>
</t>
@@ -1,5 +1,7 @@
/** @odoo-module **/
import { useComponentToModel } from '@mail/component_hooks/use_component_to_model/use_component_to_model';
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model/use_ref_to_model';
import { registerMessagingComponent } from '@mail/utils/messaging_component';
const { Component } = owl;
@@ -12,6 +14,8 @@ export class ActivityMarkDonePopover extends Component {
*/
setup() {
super.setup();
useComponentToModel({ fieldName: 'component', modelName: 'ActivityMarkDonePopoverView', propNameAsRecordLocalId: 'localId' });
useRefToModel({ fieldName: 'feedbackTextareaRef', modelName: 'ActivityMarkDonePopoverView', propNameAsRecordLocalId: 'localId', refName: 'feedbackTextarea' });
this._feedbackTextareaRef = useRef('feedbackTextarea');
onMounted(() => this._mounted());
}
@@ -22,92 +26,23 @@ export class ActivityMarkDonePopover extends Component {
_mounted() {
this._feedbackTextareaRef.el.focus();
if (this.activity.feedbackBackup) {
this._feedbackTextareaRef.el.value = this.activity.feedbackBackup;
if (this.activityMarkDonePopoverView.activityViewOwner.activity.feedbackBackup) {
this._feedbackTextareaRef.el.value = this.activityMarkDonePopoverView.activityViewOwner.activity.feedbackBackup;
}
}
/**
* @returns {Activity}
* @returns {ActivityMarkDonePopoverView}
*/
get activity() {
return this.messaging && this.messaging.models['Activity'].get(this.props.activityLocalId);
}
/**
* @returns {string}
*/
get DONE_AND_SCHEDULE_NEXT() {
return this.env._t("Done & Schedule Next");
}
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
*/
_close() {
this.trigger('o-popover-close');
}
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
*/
_onBlur() {
if (!this.activity) {
return;
}
this.activity.update({
feedbackBackup: this._feedbackTextareaRef.el.value,
});
}
/**
* @private
*/
_onClickDiscard() {
this._close();
}
/**
* @private
*/
async _onClickDone() {
await this.activity.markAsDone({
feedback: this._feedbackTextareaRef.el.value,
});
this.trigger('reload', { keepChanges: true });
}
/**
* @private
*/
_onClickDoneAndScheduleNext() {
this.activity.markAsDoneAndScheduleNext({
feedback: this._feedbackTextareaRef.el.value,
});
}
/**
* @private
*/
_onKeydown(ev) {
if (ev.key === 'Escape') {
this._close();
}
get activityMarkDonePopoverView() {
return this.messaging && this.messaging.models['ActivityMarkDonePopoverView'].get(this.props.localId);
}
}
Object.assign(ActivityMarkDonePopover, {
props: {
activityLocalId: String,
localId: String,
},
template: 'mail.ActivityMarkDonePopover',
});
@@ -2,17 +2,19 @@
<templates xml:space="preserve">
<t t-name="mail.ActivityMarkDonePopover" owl="1">
<div class="o_ActivityMarkDonePopover" t-attf-class="{{ className }}" t-on-keydown="_onKeydown" t-ref="root">
<t t-if="activity">
<textarea class="form-control o_ActivityMarkDonePopover_feedback" rows="3" placeholder="Write Feedback" t-on-blur="_onBlur" t-ref="feedbackTextarea"/>
<div class="o_ActivityMarkDonePopover" t-attf-class="{{ className }}" t-on-keydown="activityMarkDonePopoverView and activityMarkDonePopoverView.onKeydown" t-ref="root">
<t t-if="activityMarkDonePopoverView">
<textarea class="form-control o_ActivityMarkDonePopover_feedback" rows="3" placeholder="Write Feedback" t-on-blur="activityMarkDonePopoverView.onBlur" t-ref="feedbackTextarea"/>
<div class="o_ActivityMarkDonePopover_buttons">
<button type="button" class="o_ActivityMarkDonePopover_doneScheduleNextButton btn btn-sm btn-primary" t-on-click="_onClickDoneAndScheduleNext" t-esc="DONE_AND_SCHEDULE_NEXT"/>
<t t-if="activity.chaining_type === 'suggest'">
<button type="button" class="o_ActivityMarkDonePopover_doneButton btn btn-sm btn-primary" t-on-click="_onClickDone">
<button type="button" class="o_ActivityMarkDonePopover_doneScheduleNextButton btn btn-sm btn-primary" t-on-click="activityMarkDonePopoverView.onClickDoneAndScheduleNext">
Done &amp; Schedule Next
</button>
<t t-if="activityMarkDonePopoverView.activityViewOwner.activity.chaining_type === 'suggest'">
<button type="button" class="o_ActivityMarkDonePopover_doneButton btn btn-sm btn-primary" t-on-click="activityMarkDonePopoverView.onClickDone">
Done
</button>
</t>
<button type="button" class="o_ActivityMarkDonePopover_discardButton btn btn-sm btn-link" t-on-click="_onClickDiscard">
<button type="button" class="o_ActivityMarkDonePopover_discardButton btn btn-sm btn-link" t-on-click="activityMarkDonePopoverView.onClickDiscard">
Discard
</button>
</div>
@@ -1,13 +1,6 @@
/** @odoo-module **/
import { insert } from '@mail/model/model_field_command';
import {
afterEach,
afterNextRender,
beforeEach,
createRootMessagingComponent,
start,
} from '@mail/utils/test_utils';
import { afterEach, beforeEach, start } from '@mail/utils/test_utils';
import Bus from 'web.Bus';
@@ -18,13 +11,6 @@ QUnit.module('activity_mark_done_popover_tests.js', {
beforeEach() {
beforeEach(this);
this.createActivityMarkDonePopoverComponent = async activity => {
await createRootMessagingComponent(this, "ActivityMarkDonePopover", {
props: { activityLocalId: activity.localId },
target: this.widget.el,
});
};
this.start = async params => {
const res = await start({ ...params, data: this.data });
const { components, env, widget } = res;
@@ -0,0 +1,78 @@
/** @odoo-module **/
import { registerModel } from '@mail/model/model_core';
import { attr, one2one } from '@mail/model/model_field';
registerModel({
name: 'ActivityMarkDonePopoverView',
identifyingFields: ['activityViewOwner'],
recordMethods: {
/**
* Handles blur on this feedback textarea.
*/
onBlur() {
if (!this.exists() || !this.feedbackTextareaRef || !this.feedbackTextareaRef.el) {
return;
}
this._backupFeedback();
},
/**
* Handles click on this "Discard" button.
*/
onClickDiscard() {
this._close();
},
/**
* Handles click on this "Done" button.
*/
async onClickDone() {
await this.activityViewOwner.activity.markAsDone({
feedback: this.feedbackTextareaRef.el.value,
});
if (!this.exists() || !this.component) {
return;
}
this.component.trigger('reload', { keepChanges: true });
},
/**
* Handles click on this "Done & Schedule Next" button.
*/
onClickDoneAndScheduleNext() {
this.activityViewOwner.activity.markAsDoneAndScheduleNext({
feedback: this.feedbackTextareaRef.el.value,
});
},
/**
* Handles keydown on this activity mark done.
*/
onKeydown(ev) {
if (ev.key === 'Escape') {
this._close();
}
},
/**
* @private
*/
_backupFeedback() {
this.activityViewOwner.activity.update({
feedbackBackup: this.feedbackTextareaRef.el.value,
});
},
/**
* @private
*/
_close() {
this._backupFeedback();
this.component.trigger('o-popover-close');
},
},
fields: {
activityViewOwner: one2one('ActivityView', {
inverse: 'activityMarkDonePopoverView',
readonly: true,
required: true,
}),
component: attr(),
feedbackTextareaRef: attr(),
},
});
@@ -150,6 +150,11 @@ registerModel({
readonly: true,
required: true,
}),
activityMarkDonePopoverView: one2one('ActivityMarkDonePopoverView', {
default: insertAndReplace(),
inverse: 'activityViewOwner',
isCausal: true,
}),
/**
* Determines whether the details are visible.
*/