110 lines
5.2 KiB
JavaScript
110 lines
5.2 KiB
JavaScript
/** @odoo-module */
|
|
|
|
import { useService } from "@web/core/utils/hooks";
|
|
import { Deferred, KeepLast } from "@web/core/utils/concurrency";
|
|
import { patch } from "@web/core/utils/patch";
|
|
import { Chatter } from "@mail/chatter/web_portal/chatter";
|
|
import { useCallbackRecorder } from "@web/search/action_hook";
|
|
import {
|
|
onWillUnmount,
|
|
useEffect,
|
|
} from "@odoo/owl";
|
|
|
|
/**
|
|
* Knowledge articles can interact with some records with the help of the
|
|
* @see KnowledgeCommandsService .
|
|
* If any record in a form view has a chatter with the ability to send message
|
|
* and/or attach files, they are a potential target for Knowledge macros.
|
|
*/
|
|
const ChatterPatch = {
|
|
setup() {
|
|
super.setup(...arguments);
|
|
if (this.env.__knowledgeUpdateCommandsRecordInfo__) {
|
|
this.knowledgeCommandsService = useService("knowledgeCommandsService");
|
|
// Only keep the last request to register a recordInfo active.
|
|
const keepLastRecordInfoRequest = new KeepLast();
|
|
// Keep track of the fact that the chatter thread is ready and has
|
|
// loaded its access rights.
|
|
let chatterThreadReady = new Deferred();
|
|
let previousThreadId = this.props.threadId;
|
|
useEffect(
|
|
// Access rights of the current thread of the chatter are
|
|
// populated asynchronously after the chatter is mounted, this
|
|
// method keeps track of those changes in order to determine
|
|
// when a recordInfo request can be evaluated.
|
|
(threadId, canPostOnReadonly, hasReadAccess, hasWriteAccess) => {
|
|
if (previousThreadId !== threadId) {
|
|
// If the chatter changes threadId, resolve the current
|
|
// promise keeping track of the thread state to false,
|
|
// so that an ongoing request to evaluate a recordInfo
|
|
// (related to the previous thread) will be discarded.
|
|
chatterThreadReady.resolve(false);
|
|
chatterThreadReady = new Deferred();
|
|
}
|
|
if (
|
|
canPostOnReadonly !== undefined &&
|
|
hasReadAccess !== undefined &&
|
|
hasWriteAccess !== undefined
|
|
) {
|
|
// When the access rights are all loaded, the thread
|
|
// is ready and a recordInfo request can be evaluated.
|
|
chatterThreadReady.resolve(true);
|
|
}
|
|
previousThreadId = threadId;
|
|
},
|
|
() => [
|
|
this.props.threadId,
|
|
this.state.thread?.canPostOnReadonly,
|
|
this.state.thread?.hasReadAccess,
|
|
this.state.thread?.hasWriteAccess,
|
|
]
|
|
);
|
|
onWillUnmount(() => {
|
|
// If there is an ongoing request to evaluate a recordInfo,
|
|
// discard it.
|
|
chatterThreadReady.resolve(false);
|
|
});
|
|
useCallbackRecorder(
|
|
this.env.__knowledgeUpdateCommandsRecordInfo__,
|
|
// Callback used to record the values related to the ability to
|
|
// post messages or attach files on the current record.
|
|
async (recordInfo) => {
|
|
// At each new recording request, all previous ongoing
|
|
// requests are discarded through the keepLast.
|
|
const chatterThreadReadyForRecordInfo = keepLastRecordInfoRequest.add(chatterThreadReady);
|
|
if (!await chatterThreadReadyForRecordInfo) {
|
|
// If the chatterThreadReadyForRecordInfo promise
|
|
// resolves to false, the recording request should be
|
|
// discarded.
|
|
return;
|
|
}
|
|
if (
|
|
!this.env.model.root?.resId ||
|
|
recordInfo.resId !== this.env.model.root.resId ||
|
|
recordInfo.resModel !== this.env.model.root.resModel
|
|
) {
|
|
// Ensure that the current record matches the recordInfo
|
|
// candidate.
|
|
return;
|
|
}
|
|
// The conditions for the ability to post or attach should
|
|
// be the same as the ones in the Chatter template.
|
|
Object.assign(recordInfo, {
|
|
canPostMessages:
|
|
this.props.threadId &&
|
|
(this.state.thread?.hasWriteAccess ||
|
|
(this.state.thread?.hasReadAccess &&
|
|
this.state.thread?.canPostOnReadonly)),
|
|
canAttachFiles: this.props.threadId && this.state.thread?.hasWriteAccess,
|
|
});
|
|
if (this.knowledgeCommandsService.isRecordCompatibleWithMacro(recordInfo)) {
|
|
this.knowledgeCommandsService.setCommandsRecordInfo(recordInfo);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
}
|
|
};
|
|
|
|
patch(Chatter.prototype, ChatterPatch);
|