Merge branch 'master-upstream-patch-25112021' into 'master'

Master upstream patch 25112021

See merge request flectra-hq/flectra!506
This commit is contained in:
Parthiv Patel committed 2021-11-25 09:49:29 +00:00
commit 4e4593b880
16 files changed
+121 -18

No files matched your search

+2 -1
View File
@@ -14,12 +14,13 @@ class Employee(models.Model):
self.ensure_one()
cars = self.env['fleet.vehicle.assignation.log'].search([
('driver_id', 'in', (self.user_id.partner_id | self.sudo().address_home_id).ids)]).mapped('vehicle_id')
return {
"type": "ir.actions.act_window",
"res_model": "fleet.vehicle",
"views": [[False, "kanban"], [False, "form"], [False, "tree"]],
"domain": [("id", "in", cars.ids)],
"context": dict(create=False),
"context": dict(self._context, create=False),
"name": "History Employee Cars",
}
+1 -1
View File
@@ -173,7 +173,7 @@ class LinkTracker(models.Model):
def action_view_statistics(self):
action = self.env['ir.actions.act_window']._for_xml_id('link_tracker.link_tracker_click_action_statistics')
action['domain'] = [('link_id', '=', self.id)]
action['context'] = dict(action.get('context', {}), create=False)
action['context'] = dict(self._context, create=False)
return action
def action_visit_page(self):
@@ -112,6 +112,21 @@ class Message extends Component {
* regular time.
*/
this._intervalId = undefined;
/**
* States the index of the last "read more" that was inserted.
* Useful to remember the state for each "read more" even if their DOM
* is re-rendered.
*/
this._lastReadMoreIndex = 0;
/**
* Determines whether each "read more" is opened or closed. The keys are
* index, which is determined by their order of appearance in the DOM.
* If body changes so that "read more" count is different, their default
* value will be "wrong" at the next render but this is an acceptable
* limitation. It's more important to save the state correctly in a
* typical non-changing situation.
*/
this._isReadMoreByIndex = new Map();
this._constructor();
}
@@ -404,6 +419,7 @@ class Message extends Component {
}
for (const group of groups) {
const index = this._lastReadMoreIndex++;
// Insert link just before the first node
const $readMoreLess = $('<a>', {
class: 'o_Message_readMoreLess',
@@ -412,16 +428,23 @@ class Message extends Component {
}).insertBefore(group[0]);
// Toggle All next nodes
let isReadMore = true;
$readMoreLess.click(e => {
e.preventDefault();
isReadMore = !isReadMore;
if (!this._isReadMoreByIndex.has(index)) {
this._isReadMoreByIndex.set(index, true);
}
const updateFromState = () => {
const isReadMore = this._isReadMoreByIndex.get(index);
for (const $child of group) {
$child.hide();
$child.toggle(!isReadMore);
}
$readMoreLess.text(isReadMore ? READ_MORE : READ_LESS);
};
$readMoreLess.click(e => {
e.preventDefault();
this._isReadMoreByIndex.set(index, !this._isReadMoreByIndex.get(index));
updateFromState();
});
updateFromState();
}
}
@@ -443,6 +466,7 @@ class Message extends Component {
for (const el of [...this._contentRef.el.querySelectorAll(':scope .o_Message_readMoreLess')]) {
el.remove();
}
this._lastReadMoreIndex = 0;
this._insertReadMoreLess($(this._contentRef.el));
this.env.messagingBus.trigger('o-component-message-read-more-less-inserted', {
message: this.message,
@@ -975,6 +975,81 @@ QUnit.test('chatter just contains "creating a new record" message during the cre
);
});
QUnit.test('[TECHNICAL] unfolded read more/less links should not fold on message click besides those button links', async function (assert) {
// message click triggers a re-render. Before writing of this test, the
// insertion of read more/less links were done during render. This meant
// any re-render would re-insert the read more/less links. If some button
// links were unfolded, any re-render would fold them again.
//
// This previous behavior is undesirable, and results to bothersome UX
// such as inability to copy/paste unfolded message content due to click
// from text selection automatically folding all read more/less links.
assert.expect(3);
this.data['mail.message'].records.push({
author_id: 100,
// "data-o-mail-quote" added by server is intended to be compacted in read more/less blocks
body: `
<div>
Dear Joel Willis,<br>
Thank you for your enquiry.<br>
If you have any questions, please let us know.
<br><br>
Thank you,<br>
<span data-o-mail-quote="1">-- <br data-o-mail-quote="1">
System
</span>
</div>
`,
id: 1000,
model: 'res.partner',
res_id: 2,
});
this.data['res.partner'].records.push({
display_name: "Someone",
id: 100,
});
await this.createView({
data: this.data,
hasView: true,
// View params
View: FormView,
model: 'res.partner',
res_id: 2,
arch: `
<form string="Partners">
<sheet>
<field name="name"/>
</sheet>
<div class="oe_chatter">
<field name="message_ids"/>
</div>
</form>
`,
});
assert.strictEqual(
document.querySelector('.o_Message_readMoreLess').textContent,
"read more",
"read more/less link on message should be folded initially (read more)"
);
document.querySelector('.o_Message_readMoreLess').click(),
assert.strictEqual(
document.querySelector('.o_Message_readMoreLess').textContent,
"read less",
"read more/less link on message should be unfolded after a click from initial rendering (read less)"
);
await afterNextRender(
() => document.querySelector('.o_Message').click(),
);
assert.strictEqual(
document.querySelector('.o_Message_readMoreLess').textContent,
"read less",
"read more/less link on message should still be unfolded after a click on message aside of this button click (read less)"
);
});
});
});
});
+1 -1
View File
@@ -393,7 +393,7 @@ class MassMailing(models.Model):
'view_mode': 'tree',
'res_model': self.mailing_model_real,
'domain': [('id', 'in', res_ids)],
'context': dict(create=False)
'context': dict(self._context, create=False)
}
def update_opt_out(self, email, list_ids, value):
+2 -2
View File
@@ -407,7 +407,7 @@ class MrpProduction(models.Model):
else:
action['views'] = form_view
action['res_id'] = pickings.id
action['context'] = dict(action.get('context', {}), create=False, default_origin=self.name)
action['context'] = dict(self._context, default_origin=self.name, create=False)
return action
@api.depends('product_uom_id', 'product_qty', 'product_id.uom_id')
@@ -1623,7 +1623,7 @@ class MrpProduction(models.Model):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap")
action['domain'] = [('production_id', '=', self.id)]
action['context'] = dict(action.get('context', {}), create=False)
action['context'] = dict(self._context, default_origin=self.name)
return action
@api.model
+1 -1
View File
@@ -1364,7 +1364,7 @@ class Task(models.Model):
'res_model': 'project.task',
'res_id': self.parent_id.id,
'type': 'ir.actions.act_window',
'context': dict(create=False)
'context': dict(self._context, create=False)
}
def action_subtask(self):
@@ -115,8 +115,9 @@ class PurchaseOrder(models.Model):
# Recompute prices for new/modified lines:
for line in self.order_line.filtered(lambda line: line.product_id.id in product_ids):
res = line._product_id_change() or res
line._product_id_change()
line._onchange_quantity()
res = line.onchange_product_id_warning() or res
return res
def _get_matrix(self, product_template):
+1 -1
View File
@@ -283,5 +283,5 @@ class ProductionLot(models.Model):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_form_action")
action['domain'] = [('id', 'in', self.mapped('purchase_order_ids.id'))]
action['context'] = dict(action.get('context', {}), create=False)
action['context'] = dict(self._context, create=False)
return action
+1 -1
View File
@@ -26,7 +26,7 @@ class CouponProgram(models.Model):
'search_view_id': [self.env.ref('sale.sale_order_view_search_inherit_quotation').id],
'type': 'ir.actions.act_window',
'domain': [('id', 'in', orders.ids)],
'context': dict(create=False),
'context': dict(self._context, create=False),
}
def _check_promo_code(self, order, coupon_code):
@@ -10,7 +10,7 @@
<button type="object" name="action_view_task" class="oe_stat_button" icon="fa-tasks" attrs="{'invisible': [('tasks_count', '=', 0)]}" groups="project.group_project_user">
<field name="tasks_count" widget="statinfo" string="Tasks"/>
</button>
<button type="object" name="action_view_project_ids" class="oe_stat_button" icon="fa-puzzle-piece" string="Project" attrs="{'invisible': [('project_ids', '=', [])]}" groups="project.group_project_manager">
<button type="object" name="action_view_project_ids" class="oe_stat_button" icon="fa-puzzle-piece" string="Project" attrs="{'invisible': ['|', ('state', 'in', ['draft', 'sent']), ('project_ids', '=', [])]}" groups="project.group_project_manager">
<field name="project_ids" invisible="1"/>
</button>
</xpath>
+1 -1
View File
@@ -204,7 +204,7 @@ class SaleOrder(models.Model):
picking_id = picking_id[0]
else:
picking_id = pickings[0]
action['context'] = dict(action.get('context', {}), default_partner_id=self.partner_id.id, default_picking_type_id=picking_id.picking_type_id.id, default_origin=self.name, default_group_id=picking_id.group_id.id, group_by=[])
action['context'] = dict(self._context, default_partner_id=self.partner_id.id, default_picking_type_id=picking_id.picking_type_id.id, default_origin=self.name, default_group_id=picking_id.group_id.id)
return action
def action_cancel(self):
+1 -1
View File
@@ -183,5 +183,5 @@ class ProductionLot(models.Model):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id("sale.action_orders")
action['domain'] = [('id', 'in', self.mapped('sale_order_ids.id'))]
action['context'] = dict(action.get('context', {}), create=False)
action['context'] = dict(self._context, create=False)
return action
+1 -1
View File
@@ -1375,7 +1375,7 @@ class Picking(models.Model):
action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap")
scraps = self.env['stock.scrap'].search([('picking_id', '=', self.id)])
action['domain'] = [('id', 'in', scraps.ids)]
action['context'] = dict(action.get('context', {}), create=False)
action['context'] = dict(self._context, create=False)
return action
def action_see_packages(self):
@@ -28,7 +28,7 @@ class StockInventory(models.Model):
self.ensure_one()
action_data = self.env['ir.actions.act_window']._for_xml_id('account.action_move_journal_line')
action_data['domain'] = [('stock_move_id.id', 'in', self.move_ids.ids)]
action_data['context'] = dict(action_data.get('context', {}), create=False)
action_data['context'] = dict(self._context, create=False)
return action_data
def post_inventory(self):
+2
View File
@@ -196,6 +196,8 @@ class Page(models.Model):
if not pages_linked_to_iruiview and not page.view_id.inherit_children_ids:
# If there is no other pages linked to that ir_ui_view, we can delete the ir_ui_view
page.view_id.unlink()
# Make sure website._get_menu_ids() will be recomputed
self.clear_caches()
return super(Page, self).unlink()
def write(self, vals):