[IMP] mail: send channel update to the client
Before this PR, channel update were not sent via bus notifications. Part of task-2821415 closes odoo/odoo#136623 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -273,11 +273,25 @@ class Channel(models.Model):
|
||||
failing_channels = self.sudo().filtered(lambda channel: channel.channel_type != vals.get('channel_type'))
|
||||
if failing_channels:
|
||||
raise UserError(_('Cannot change the channel type of: %(channel_names)s', channel_names=', '.join(failing_channels.mapped('name'))))
|
||||
notifications = []
|
||||
for channel in self:
|
||||
current_val = channel.read(vals.keys())[0]
|
||||
diff = {}
|
||||
for key in vals.keys():
|
||||
if current_val.get(key) != vals.get(key) and key != "image_128":
|
||||
diff[key] = vals[key]
|
||||
if diff:
|
||||
notifications.append([channel, "mail.record/insert", {
|
||||
"Thread": {
|
||||
"id": current_val["id"],
|
||||
"model": "discuss.channel",
|
||||
**diff
|
||||
}
|
||||
}])
|
||||
result = super().write(vals)
|
||||
if vals.get('group_ids'):
|
||||
self._subscribe_users_automatically()
|
||||
if 'image_128' in vals:
|
||||
notifications = []
|
||||
for channel in self:
|
||||
notifications.append([channel, 'mail.record/insert', {
|
||||
'Channel': {
|
||||
@@ -285,7 +299,7 @@ class Channel(models.Model):
|
||||
'id': channel.id,
|
||||
}
|
||||
}])
|
||||
self.env['bus.bus']._sendmany(notifications)
|
||||
self.env['bus.bus']._sendmany(notifications)
|
||||
return result
|
||||
|
||||
def init(self):
|
||||
@@ -1001,7 +1015,7 @@ class Channel(models.Model):
|
||||
'foldStateCount': state_count,
|
||||
'id': session_state.channel_id.id,
|
||||
'model': 'discuss.channel',
|
||||
'serverFoldState': state,
|
||||
'fold_state': state,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1112,24 +1126,10 @@ class Channel(models.Model):
|
||||
def channel_rename(self, name):
|
||||
self.ensure_one()
|
||||
self.write({'name': name})
|
||||
self.env['bus.bus']._sendone(self, 'mail.record/insert', {
|
||||
'Thread': {
|
||||
'id': self.id,
|
||||
'model': 'discuss.channel',
|
||||
'name': name,
|
||||
}
|
||||
})
|
||||
|
||||
def channel_change_description(self, description):
|
||||
self.ensure_one()
|
||||
self.write({'description': description})
|
||||
self.env['bus.bus']._sendone(self, 'mail.record/insert', {
|
||||
'Thread': {
|
||||
'id': self.id,
|
||||
'description': description,
|
||||
'model': 'discuss.channel',
|
||||
}
|
||||
})
|
||||
|
||||
def channel_join(self):
|
||||
""" Shortcut to add the current user as member of self channels.
|
||||
|
||||
@@ -87,10 +87,10 @@ export class DiscussCoreWeb {
|
||||
if (payload.Thread) {
|
||||
const data = payload.Thread;
|
||||
const thread = this.store.Thread.get(data);
|
||||
if (data.serverFoldState && thread && data.foldStateCount > thread.foldStateCount) {
|
||||
if (data.fold_state && thread && data.foldStateCount > thread.foldStateCount) {
|
||||
thread.foldStateCount = data.foldStateCount;
|
||||
if (data.serverFoldState !== thread.state) {
|
||||
thread.state = data.serverFoldState;
|
||||
if (data.fold_state !== thread.state) {
|
||||
thread.state = data.fold_state;
|
||||
if (thread.state === "closed") {
|
||||
const chatWindow = this.store.discuss.chatWindows.find((chatWindow) =>
|
||||
chatWindow.thread?.eq(thread)
|
||||
|
||||
@@ -7,6 +7,7 @@ import { start } from "@mail/../tests/helpers/test_utils";
|
||||
|
||||
import { getOrigin } from "@web/core/utils/urls";
|
||||
import { click, contains, insertText } from "@web/../tests/utils";
|
||||
import { triggerHotkey } from "@web/../tests/helpers/utils";
|
||||
|
||||
QUnit.module("discuss sidebar");
|
||||
|
||||
@@ -1158,3 +1159,21 @@ QUnit.test("Unpinning channel closes its chat window", async () => {
|
||||
await openFormView("discuss.channel");
|
||||
await contains(".o-mail-ChatWindow", { count: 0, text: "Sales" });
|
||||
});
|
||||
|
||||
QUnit.test("Update channel data via bus notification", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "Sales",
|
||||
channel_member_ids: [Command.create({ partner_id: pyEnv.currentPartnerId })],
|
||||
channel_type: "channel",
|
||||
create_uid: pyEnv.currentUserId,
|
||||
});
|
||||
const tab1 = await start({ asTab: true });
|
||||
const tab2 = await start({ asTab: true });
|
||||
tab1.openDiscuss(channelId);
|
||||
tab2.openDiscuss(channelId);
|
||||
await contains(".o-mail-DiscussSidebarChannel", { text: "Sales", target: tab1.target });
|
||||
await insertText(".o-mail-Discuss-threadName", "test", { target: tab1.target });
|
||||
await triggerHotkey("Enter");
|
||||
await contains(".o-mail-DiscussSidebarChannel", { text: "Salestest", target: tab2.target });
|
||||
});
|
||||
|
||||
@@ -10,6 +10,40 @@ import { Command } from "@mail/../tests/helpers/command";
|
||||
const { DateTime } = luxon;
|
||||
|
||||
patch(MockServer.prototype, {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
mockWrite(model, args) {
|
||||
const notifications = [];
|
||||
if (model == "discuss.channel") {
|
||||
const vals = args[1];
|
||||
const [channel] = this.getRecords(model, [["id", "=", args[0][0]]]);
|
||||
if (channel) {
|
||||
const diff = {};
|
||||
for (const key in vals) {
|
||||
if (channel[key] != vals[key] && key !== "image_128") {
|
||||
diff[key] = vals[key];
|
||||
}
|
||||
}
|
||||
notifications.push([
|
||||
channel,
|
||||
"mail.record/insert",
|
||||
{
|
||||
Thread: {
|
||||
id: channel.id,
|
||||
model: "discuss.channel",
|
||||
...diff,
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
const mockWriteResult = super.mockWrite(...arguments);
|
||||
if (notifications.length) {
|
||||
this.pyEnv["bus.bus"]._sendmany(notifications);
|
||||
}
|
||||
return mockWriteResult;
|
||||
},
|
||||
async _performRPC(route, args) {
|
||||
if (args.model === "discuss.channel" && args.method === "execute_command_help") {
|
||||
return this._mockDiscussChannelExecuteCommandHelp(args.args[0], args.model);
|
||||
@@ -488,7 +522,7 @@ patch(MockServer.prototype, {
|
||||
foldStateCount: state_count,
|
||||
id: channel.id,
|
||||
model: "discuss.channel",
|
||||
serverFoldState: foldState,
|
||||
fold_state: foldState,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -777,24 +811,10 @@ patch(MockServer.prototype, {
|
||||
_mockDiscussChannelChannelRename(ids, name) {
|
||||
const channel = this.getRecords("discuss.channel", [["id", "in", ids]])[0];
|
||||
this.pyEnv["discuss.channel"].write([channel.id], { name });
|
||||
this.pyEnv["bus.bus"]._sendone(channel, "mail.record/insert", {
|
||||
Thread: {
|
||||
id: channel.id,
|
||||
model: "discuss.channel",
|
||||
name: name,
|
||||
},
|
||||
});
|
||||
},
|
||||
_mockDiscussChannelChannelChangeDescription(ids, description) {
|
||||
const channel = this.getRecords("discuss.channel", [["id", "in", ids]])[0];
|
||||
this.pyEnv["discuss.channel"].write([channel.id], { description });
|
||||
this.pyEnv["bus.bus"]._sendone(channel, "mail.record/insert", {
|
||||
Thread: {
|
||||
id: channel.id,
|
||||
model: "discuss.channel",
|
||||
description: description,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Simulates `channel_set_custom_name` on `discuss.channel`.
|
||||
|
||||
@@ -504,6 +504,25 @@ class TestChannelInternals(MailCommon):
|
||||
test_channel.image_128 = base64.b64encode(("<svg/>").encode())
|
||||
self.assertEqual(test_channel.avatar_128, test_channel.image_128)
|
||||
|
||||
def test_channel_write_should_send_notification(self):
|
||||
channel = self.env['discuss.channel'].create({"name": "test", "description": "test"})
|
||||
# do the operation once before the assert to grab the value to expect
|
||||
with self.assertBus(
|
||||
[(self.cr.dbname, 'discuss.channel', channel.id)],
|
||||
[{
|
||||
"type": "mail.record/insert",
|
||||
"payload": {
|
||||
'Thread': {
|
||||
"id": channel.id,
|
||||
"model": "discuss.channel",
|
||||
"name": "test test",
|
||||
}
|
||||
},
|
||||
}]
|
||||
):
|
||||
channel.name = "test test"
|
||||
channel.description = "test"
|
||||
|
||||
def test_channel_write_should_send_notification_if_image_128_changed(self):
|
||||
channel = self.env['discuss.channel'].create({'name': '', 'uuid': 'test-uuid'})
|
||||
# do the operation once before the assert to grab the value to expect
|
||||
|
||||
Reference in New Issue
Block a user