[FIX] web: ListViewHeaderButton use the correct context
Before this commit, when a ListViewHeaderButton was clicked, the view context wasn't sent to the server. As ListViewHeaderButton shows, the onClickViewButton API is not correct. It expects a record in params but this is not correct in the case of ListViewHeaderButton. So we decided not to pass a record but a getParams callback that allows us to calculate the params when we need them. Part-of: odoo/odoo#97558
This commit is contained in:
@@ -17,28 +17,24 @@ export class ExpenseFormController extends FormController {
|
||||
const t = this.env._t;
|
||||
const previousOnClickViewButton = this.env.onClickViewButton;
|
||||
useSubEnv({
|
||||
async onClickViewButton({ clickParams, record}) {
|
||||
if (clickParams.name === "action_submit_expenses") {
|
||||
if (record.data.duplicate_expense_ids.count) {
|
||||
dialogService.add(ConfirmationDialog, {
|
||||
body: t("An expense of same category, amount and date already exists."),
|
||||
confirm: async () => {
|
||||
orm.call(
|
||||
'hr.expense',
|
||||
'action_approve_duplicates',
|
||||
[record.data.id],
|
||||
);
|
||||
previousOnClickViewButton({ clickParams, record});
|
||||
},
|
||||
cancel: () => {},
|
||||
});
|
||||
} else {
|
||||
previousOnClickViewButton({ clickParams, record});
|
||||
}
|
||||
async onClickViewButton(params) {
|
||||
const record = this.model.root;
|
||||
if (
|
||||
params.clickParams.name === "action_submit_expenses" &&
|
||||
record.data.duplicate_expense_ids.count
|
||||
) {
|
||||
dialogService.add(ConfirmationDialog, {
|
||||
body: t("An expense of same category, amount and date already exists."),
|
||||
confirm: async () => {
|
||||
orm.call("hr.expense", "action_approve_duplicates", [record.resId]);
|
||||
previousOnClickViewButton(params);
|
||||
},
|
||||
cancel: () => {},
|
||||
});
|
||||
} else {
|
||||
previousOnClickViewButton({ clickParams, record});
|
||||
previousOnClickViewButton(params);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -48,4 +44,4 @@ export const ExpenseFormView = {
|
||||
Controller: ExpenseFormController,
|
||||
};
|
||||
|
||||
registry.category("views").add('hr_expense_form_view', ExpenseFormView);
|
||||
registry.category("views").add("hr_expense_form_view", ExpenseFormView);
|
||||
|
||||
@@ -20,23 +20,27 @@ const { Component, onWillStart, useSubEnv, useEffect, useRef } = owl;
|
||||
|
||||
export class ListViewHeaderButton extends ViewButton {
|
||||
async onClick() {
|
||||
const clickParams = this.props.clickParams;
|
||||
const resIds = await this.props.getSelectedResIds();
|
||||
const resModel = this.props.resModel;
|
||||
const { clickParams, list } = this.props;
|
||||
const resIds = await list.getResIds(true);
|
||||
clickParams.buttonContext = {
|
||||
active_domain: this.props.domain,
|
||||
// active_id: resIds[0], // FGE TODO
|
||||
active_ids: resIds,
|
||||
active_model: resModel,
|
||||
active_model: list.resModel,
|
||||
};
|
||||
|
||||
this.env.onClickViewButton({
|
||||
clickParams,
|
||||
record: { resModel, resIds },
|
||||
getResParams: () => ({
|
||||
context: list.context,
|
||||
evalContext: list.evalContext,
|
||||
resModel: list.resModel,
|
||||
resIds,
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
ListViewHeaderButton.props = [...ViewButton.props, "resModel", "domain", "getSelectedResIds"];
|
||||
ListViewHeaderButton.props = [...ViewButton.props, "list", "domain"];
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -53,12 +53,11 @@
|
||||
<t t-if="nbSelected">
|
||||
<t t-foreach="archInfo.headerButtons" t-as="button" t-key="button.id">
|
||||
<ListViewHeaderButton
|
||||
list="model.root"
|
||||
clickParams="button.clickParams"
|
||||
defaultRank="button.defaultRank"
|
||||
domain="props.domain"
|
||||
icon="button.icon"
|
||||
getSelectedResIds.bind="getSelectedResIds"
|
||||
resModel="model.root.resModel"
|
||||
string="button.string"
|
||||
title="button.title"
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { DROPDOWN } from "@web/core/dropdown/dropdown";
|
||||
import { pick } from "@web/core/utils/objects";
|
||||
import { debounce as debounceFn } from "@web/core/utils/timing";
|
||||
|
||||
const { Component } = owl;
|
||||
@@ -84,7 +85,8 @@ export class ViewButton extends Component {
|
||||
}
|
||||
this.env.onClickViewButton({
|
||||
clickParams: this.clickParams,
|
||||
record: this.props.record,
|
||||
getResParams: () =>
|
||||
pick(this.props.record, "context", "evalContext", "resModel", "resId", "resIds"),
|
||||
beforeExecute: () => {
|
||||
if (this.env[DROPDOWN]) {
|
||||
this.env[DROPDOWN].close();
|
||||
|
||||
@@ -37,7 +37,7 @@ export function useViewButtons(model, ref, options = {}) {
|
||||
return true;
|
||||
});
|
||||
useSubEnv({
|
||||
async onClickViewButton({ clickParams, record, beforeExecute }) {
|
||||
async onClickViewButton({ clickParams, getResParams, beforeExecute }) {
|
||||
const manuallyDisabledButtons = disableButtons(getEl());
|
||||
|
||||
async function execute() {
|
||||
@@ -51,15 +51,13 @@ export function useViewButtons(model, ref, options = {}) {
|
||||
enableButtons(getEl(), manuallyDisabledButtons);
|
||||
return;
|
||||
}
|
||||
const resId = record.resId;
|
||||
const resIds = record.resIds || model.resIds;
|
||||
const params = getResParams();
|
||||
const resId = params.resId;
|
||||
const resIds = params.resIds || model.resIds;
|
||||
let buttonContext = {};
|
||||
if (clickParams.context) {
|
||||
if (typeof clickParams.context === "string") {
|
||||
const valuesForEval = Object.assign({}, record.evalContext, {
|
||||
active_id: resId,
|
||||
active_ids: resIds,
|
||||
});
|
||||
const valuesForEval = Object.assign({}, params.evalContext);
|
||||
buttonContext = evaluateExpr(clickParams.context, valuesForEval);
|
||||
} else {
|
||||
buttonContext = clickParams.context;
|
||||
@@ -69,13 +67,13 @@ export function useViewButtons(model, ref, options = {}) {
|
||||
Object.assign(buttonContext, clickParams.buttonContext);
|
||||
}
|
||||
const doActionParams = Object.assign({}, clickParams, {
|
||||
resModel: record.resModel || model.resModel,
|
||||
resModel: params.resModel || model.resModel,
|
||||
resId,
|
||||
resIds,
|
||||
context: record.context || {}, //LPE FIXME new Context(payload.env.context).eval();
|
||||
context: params.context || {}, //LPE FIXME new Context(payload.env.context).eval();
|
||||
buttonContext,
|
||||
onClose: async () => {
|
||||
const reload = options.reload || (() => record.model.root.load());
|
||||
const reload = options.reload || (() => model.root.load());
|
||||
await reload();
|
||||
comp.render(true); // FIXME WOWL reactivity
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { useAutofocus } from "@web/core/utils/hooks";
|
||||
import { pick } from "@web/core/utils/objects";
|
||||
import { formView } from "@web/views/form/form_view";
|
||||
import { useViewButtons } from "@web/views/view_button/view_button_hook";
|
||||
import { SettingsConfirmationDialog } from "./settings_confirmation_dialog";
|
||||
@@ -91,7 +92,8 @@ export class SettingsFormController extends formView.Controller {
|
||||
name: "execute",
|
||||
type: "object",
|
||||
},
|
||||
record: this.model.root,
|
||||
getResParams: () =>
|
||||
pick(this.model.root, "context", "evalContext", "resModel", "resId", "resIds"),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,7 +103,8 @@ export class SettingsFormController extends formView.Controller {
|
||||
name: "cancel",
|
||||
type: "object",
|
||||
},
|
||||
record: this.model.root,
|
||||
getResParams: () =>
|
||||
pick(this.model.root, "context", "evalContext", "resModel", "resId", "resIds"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,6 +765,9 @@ QUnit.module("Views", (hooks) => {
|
||||
</header>
|
||||
<field name="foo" />
|
||||
</tree>`,
|
||||
context: {
|
||||
paf: "pif",
|
||||
},
|
||||
});
|
||||
patchWithCleanup(list.env.services.action, {
|
||||
doActionButton: async (params) => {
|
||||
@@ -784,7 +787,12 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
assert.strictEqual(resModel, "foo");
|
||||
assert.deepEqual([...resIds], [1]);
|
||||
assert.strictEqual(JSON.stringify(context), "{}");
|
||||
assert.deepEqual(context, {
|
||||
lang: "en",
|
||||
paf: "pif",
|
||||
tz: "taht",
|
||||
uid: 7,
|
||||
});
|
||||
},
|
||||
});
|
||||
await click(
|
||||
@@ -835,7 +843,11 @@ QUnit.module("Views", (hooks) => {
|
||||
active_model: "foo",
|
||||
});
|
||||
|
||||
assert.strictEqual(JSON.stringify(context), "{}");
|
||||
assert.deepEqual(context, {
|
||||
lang: "en",
|
||||
tz: "taht",
|
||||
uid: 7,
|
||||
});
|
||||
assert.strictEqual(resModel, "foo");
|
||||
assert.deepEqual([...resIds], [1, 2, 3, 4]);
|
||||
},
|
||||
|
||||
@@ -46,17 +46,16 @@ QUnit.module("UseViewButton tests", (hooks) => {
|
||||
}
|
||||
|
||||
onClick() {
|
||||
const record = {
|
||||
const getResParams = () => ({
|
||||
resIds: [3],
|
||||
resId: 3,
|
||||
load: () => {},
|
||||
};
|
||||
});
|
||||
const clickParams = {};
|
||||
const beforeExecute = () => {
|
||||
assert.step("beforeExecuteAction on handler");
|
||||
return executeInHandler;
|
||||
};
|
||||
this.env.onClickViewButton({ beforeExecute, record, clickParams });
|
||||
this.env.onClickViewButton({ beforeExecute, getResParams, clickParams });
|
||||
}
|
||||
}
|
||||
MyComponent.template = xml`<div t-ref="root" t-on-click="onClick" class="myComponent">Some text</div>`;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { pick } from "@web/core/utils/objects";
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
@@ -13,9 +14,10 @@ class RedirectField extends Component {
|
||||
this.env.onClickViewButton({
|
||||
clickParams: {
|
||||
type: "object",
|
||||
name: "open_website_url"
|
||||
name: "open_website_url",
|
||||
},
|
||||
record: this.props.record,
|
||||
getResParams: () =>
|
||||
pick(this.props.record, "context", "evalContext", "resModel", "resId", "resIds"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user