[IMP] web: merge quick_add with quick_create_form_view_id
https://github.com/odoo/odoo/pull/114827 added a new attribute in the calendar view that allowed passing a form view id that is used in the calendar module to show a different form view when trying to quick create an event. This new attribute, however, was only used in the calendar module. With this in mind, it made sense to allow using this attribute in other modules. This commit implements this, however, the approach used was different. It was decided to merge quick_create_form_view_id with quick_add as both are related to the same feature: quick creation of a record in the calendar view. Now, quick_add receives either a boolean (original behavior) or a number representing the form view id to be shown when quick creating a record. task-3286969 closes odoo/odoo#122923 Related: odoo/documentation#4707 Signed-off-by: Arnaud Joset (arj) <arj@odoo.com>
This commit is contained in:
+23
-24
@@ -36,34 +36,29 @@ export class AttendeeCalendarController extends CalendarController {
|
||||
});
|
||||
}
|
||||
|
||||
getQuickCreateFormViewProps(record) {
|
||||
const props = super.getQuickCreateFormViewProps(record);
|
||||
const onDialogClosed = () => {
|
||||
this.model.load();
|
||||
};
|
||||
return {
|
||||
...props,
|
||||
size: "md",
|
||||
goToFullEvent: (contextData) => {
|
||||
const fullContext = {
|
||||
...props.context,
|
||||
...contextData
|
||||
};
|
||||
this.goToFullEvent(false, fullContext)
|
||||
},
|
||||
onRecordSaved: () => onDialogClosed(),
|
||||
};
|
||||
}
|
||||
|
||||
async editRecord(record, context = {}) {
|
||||
if (record.id) {
|
||||
return this.goToFullEvent(record.id, context);
|
||||
}
|
||||
const onDialogClosed = () => {
|
||||
this.model.load();
|
||||
};
|
||||
return new Promise((resolve) => {
|
||||
this.displayDialog(
|
||||
CalendarQuickCreate, {
|
||||
viewId: this.model.quickCreateFormViewId,
|
||||
resModel: "calendar.event",
|
||||
size: "md",
|
||||
context,
|
||||
goToFullEvent: (contextData) => {
|
||||
const fullContext = {
|
||||
...context,
|
||||
...contextData
|
||||
};
|
||||
this.goToFullEvent(false, fullContext)
|
||||
},
|
||||
onRecordSaved: () => resolve(onDialogClosed()),
|
||||
onRecordDiscarded: () => resolve(onDialogClosed())
|
||||
}, {
|
||||
onClose: () => resolve()
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,3 +115,7 @@ export class AttendeeCalendarController extends CalendarController {
|
||||
}
|
||||
}
|
||||
AttendeeCalendarController.template = "calendar.AttendeeCalendarController";
|
||||
AttendeeCalendarController.components = {
|
||||
...AttendeeCalendarController.components,
|
||||
QuickCreateFormView: CalendarQuickCreate,
|
||||
}
|
||||
|
||||
@@ -352,8 +352,7 @@
|
||||
<calendar js_class="attendee_calendar" string="Meetings" date_start="start" date_stop="stop" date_delay="duration" all_day="allday"
|
||||
event_open_popup="true"
|
||||
event_limit="5"
|
||||
quick_add="0"
|
||||
quick_create_form_view_id="%(calendar.view_calendar_event_form_quick_create)d"
|
||||
quick_add="%(calendar.view_calendar_event_form_quick_create)d"
|
||||
color="partner_ids">
|
||||
<field name="location" attrs="{'invisible': [('location', '=', False)]}" options="{'icon': 'fa fa-map-marker'}"/>
|
||||
<field name="attendee_status" invisible="1"/>
|
||||
|
||||
@@ -29,13 +29,12 @@ export class CalendarArchParser extends XMLParser {
|
||||
let scale = "week";
|
||||
let canCreate = true;
|
||||
let canDelete = true;
|
||||
let hasQuickCreate = true;
|
||||
let quickCreate = true;
|
||||
let hasEditDialog = false;
|
||||
let showUnusualDays = false;
|
||||
let isDateHidden = false;
|
||||
let isTimeHidden = false;
|
||||
let formViewId = false;
|
||||
let quickCreateFormViewId = false;
|
||||
const popoverFields = {};
|
||||
const filtersInfo = {};
|
||||
|
||||
@@ -85,7 +84,14 @@ export class CalendarArchParser extends XMLParser {
|
||||
canDelete = archParseBoolean(node.getAttribute("delete"), true);
|
||||
}
|
||||
if (node.hasAttribute("quick_add")) {
|
||||
hasQuickCreate = archParseBoolean(node.getAttribute("quick_add"), true);
|
||||
quickCreate = archParseBoolean(node.getAttribute("quick_add"), true);
|
||||
// quick_add could contain either false, true or an id for a form view
|
||||
if (quickCreate) {
|
||||
const viewId = parseInt(node.getAttribute("quick_add"), 10);
|
||||
if (viewId > 1) {
|
||||
quickCreate = viewId;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.hasAttribute("event_open_popup")) {
|
||||
hasEditDialog = archParseBoolean(node.getAttribute("event_open_popup"));
|
||||
@@ -102,12 +108,6 @@ export class CalendarArchParser extends XMLParser {
|
||||
if (node.hasAttribute("form_view_id")) {
|
||||
formViewId = parseInt(node.getAttribute("form_view_id"), 10);
|
||||
}
|
||||
if (node.hasAttribute("quick_create_form_view_id")) {
|
||||
quickCreateFormViewId = parseInt(
|
||||
node.getAttribute("quick_create_form_view_id"),
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -189,9 +189,8 @@ export class CalendarArchParser extends XMLParser {
|
||||
fieldNames: [...fieldNames],
|
||||
filtersInfo,
|
||||
formViewId,
|
||||
quickCreateFormViewId,
|
||||
hasEditDialog,
|
||||
hasQuickCreate,
|
||||
quickCreate,
|
||||
isDateHidden,
|
||||
isTimeHidden,
|
||||
popoverFields,
|
||||
|
||||
@@ -116,11 +116,33 @@ export class CalendarController extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
getQuickCreateFormViewProps(record) {
|
||||
const rawRecord = this.model.buildRawRecord(record);
|
||||
const context = this.model.makeContextDefaults(rawRecord);
|
||||
return {
|
||||
resModel: this.model.resModel,
|
||||
viewId: this.model.quickCreateFormViewId,
|
||||
context,
|
||||
};
|
||||
}
|
||||
|
||||
createRecord(record) {
|
||||
if (!this.model.canCreate) {
|
||||
return;
|
||||
}
|
||||
if (this.model.hasQuickCreate) {
|
||||
if (this.model.quickCreateFormViewId) {
|
||||
return new Promise((resolve) => {
|
||||
this.displayDialog(
|
||||
this.constructor.components.QuickCreateFormView,
|
||||
this.getQuickCreateFormViewProps(record),
|
||||
{
|
||||
onClose: () => resolve(),
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.displayDialog(
|
||||
this.constructor.components.QuickCreate,
|
||||
@@ -223,6 +245,7 @@ CalendarController.components = {
|
||||
FilterPanel: CalendarFilterPanel,
|
||||
MobileFilterPanel: CalendarMobileFilterPanel,
|
||||
QuickCreate: CalendarQuickCreate,
|
||||
QuickCreateFormView: FormViewDialog,
|
||||
Layout,
|
||||
SearchBar,
|
||||
ViewScaleSelector,
|
||||
|
||||
@@ -102,7 +102,7 @@ export class CalendarModel extends Model {
|
||||
return this.meta.hasEditDialog;
|
||||
}
|
||||
get hasQuickCreate() {
|
||||
return this.meta.hasQuickCreate;
|
||||
return Boolean(this.meta.quickCreate);
|
||||
}
|
||||
get isDateHidden() {
|
||||
return this.meta.isDateHidden;
|
||||
@@ -136,7 +136,8 @@ export class CalendarModel extends Model {
|
||||
}
|
||||
|
||||
get quickCreateFormViewId() {
|
||||
return this.meta.quickCreateFormViewId;
|
||||
const quickCreate = parseInt(this.meta.quickCreate);
|
||||
return quickCreate ? quickCreate : false;
|
||||
}
|
||||
|
||||
get defaultFilterLabel() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Dialog size="'sm'" title="dialogTitle">
|
||||
<div class="o-calendar-quick-create mb-3">
|
||||
<label for="title" class="col-form-label o_form_label">
|
||||
Meeting Subject:
|
||||
Name:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -34,8 +34,7 @@ QUnit.test("defaults", (assert) => {
|
||||
filtersInfo: {},
|
||||
formViewId: false,
|
||||
hasEditDialog: false,
|
||||
hasQuickCreate: true,
|
||||
quickCreateFormViewId: false,
|
||||
quickCreate: true,
|
||||
isDateHidden: false,
|
||||
isTimeHidden: false,
|
||||
popoverFields: {},
|
||||
@@ -88,14 +87,15 @@ QUnit.test("hasEditDialog", (assert) => {
|
||||
check(assert, "event_open_popup", "0", "hasEditDialog", false);
|
||||
});
|
||||
|
||||
QUnit.test("hasQuickCreate", (assert) => {
|
||||
check(assert, "quick_add", "", "hasQuickCreate", true);
|
||||
check(assert, "quick_add", "true", "hasQuickCreate", true);
|
||||
check(assert, "quick_add", "True", "hasQuickCreate", true);
|
||||
check(assert, "quick_add", "1", "hasQuickCreate", true);
|
||||
check(assert, "quick_add", "false", "hasQuickCreate", false);
|
||||
check(assert, "quick_add", "False", "hasQuickCreate", false);
|
||||
check(assert, "quick_add", "0", "hasQuickCreate", false);
|
||||
QUnit.test("quickCreate", (assert) => {
|
||||
check(assert, "quick_add", "", "quickCreate", true);
|
||||
check(assert, "quick_add", "true", "quickCreate", true);
|
||||
check(assert, "quick_add", "True", "quickCreate", true);
|
||||
check(assert, "quick_add", "1", "quickCreate", true);
|
||||
check(assert, "quick_add", "false", "quickCreate", false);
|
||||
check(assert, "quick_add", "False", "quickCreate", false);
|
||||
check(assert, "quick_add", "0", "quickCreate", false);
|
||||
check(assert, "quick_add", "12", "quickCreate", 12);
|
||||
});
|
||||
|
||||
QUnit.test("isDateHidden", (assert) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerCleanup } from "../../helpers/cleanup";
|
||||
import { defaultLocalization } from "../../helpers/mock_services";
|
||||
import { defaultLocalization, makeFakeDialogService } from "../../helpers/mock_services";
|
||||
import {
|
||||
click,
|
||||
editInput,
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
selectTimeRange,
|
||||
toggleFilter,
|
||||
toggleSectionFilter,
|
||||
clickAllDaySlot,
|
||||
} from "../../views/calendar/helpers";
|
||||
import { makeView, setupViewRegistries } from "../../views/helpers";
|
||||
import { createWebClient, doAction } from "../../webclient/helpers";
|
||||
@@ -4738,4 +4739,31 @@ QUnit.module("Views", ({ beforeEach }) => {
|
||||
// test would fail here if we went to week mode
|
||||
assert.containsOnce(target, ".fc-dayGridMonth-view");
|
||||
});
|
||||
|
||||
QUnit.test("calendar rendering with form view id being passed in quick_add", async (assert) => {
|
||||
serviceRegistry.add(
|
||||
"dialog",
|
||||
makeFakeDialogService((className, props) => {
|
||||
assert.equal(props.viewId, 2);
|
||||
return () => {};
|
||||
}),
|
||||
{ force: true }
|
||||
);
|
||||
await makeView({
|
||||
type: "calendar",
|
||||
resModel: "event",
|
||||
serverData,
|
||||
arch: `
|
||||
<calendar date_start="start" date_stop="stop" all_day="allday" mode="month" quick_add="2">
|
||||
<field name="name"/>
|
||||
</calendar>
|
||||
`,
|
||||
});
|
||||
const date = target.querySelector(".fc-day-grid td");
|
||||
await clickAllDaySlot(target, date.dataset.date);
|
||||
const datepicker = document.querySelector("#ui-datepicker-div");
|
||||
if (datepicker) {
|
||||
datepicker.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -230,7 +230,7 @@ function makeFakeModelState() {
|
||||
isTimeHidden: false,
|
||||
hasAllDaySlot: true,
|
||||
hasEditDialog: false,
|
||||
hasQuickCreate: false,
|
||||
quickCreate: false,
|
||||
popoverFields: {
|
||||
name: Field.parseFieldNode(fakeFieldNode, fakeModels, "event", "calendar"),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user