diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.xml b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.xml
index 12a717b2ebd..ce3d2ea5361 100644
--- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.xml
+++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_renderer.xml
@@ -5,6 +5,12 @@
+
+
+
-
+
+ ,
+
diff --git a/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js b/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js
index f10523ed32c..e4e23d4ea07 100644
--- a/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js
+++ b/addons/web/static/src/views/calendar/calendar_common/calendar_common_renderer.js
@@ -115,6 +115,11 @@ export class CalendarCommonRenderer extends Component {
return record.start.toFormat(timeFormat);
}
+ getEndTime(record) {
+ const timeFormat = is24HourFormat() ? "HH:mm" : "hh:mm a";
+ return record.end.toFormat(timeFormat);
+ }
+
computeEventSelector(event) {
return `[data-event-id="${event.id}"]`;
}
@@ -132,15 +137,17 @@ export class CalendarCommonRenderer extends Component {
return Object.values(this.props.model.records).map((r) => this.convertRecordToEvent(r));
}
convertRecordToEvent(record) {
+ const allDay = record.isAllDay || record.end.diff(record.start, "hours").hours >= 24;
return {
id: record.id,
title: record.title,
start: record.start.toISO(),
end:
- ["week", "month"].includes(this.props.model.scale) && record.isAllDay
+ ["week", "month"].includes(this.props.model.scale) && (record.isAllDay || allDay &&
+ record.end.toMillis() !== record.end.startOf('day').toMillis())
? record.end.plus({ days: 1 }).toISO()
: record.end.toISO(),
- allDay: record.isAllDay,
+ allDay: allDay ,
};
}
getPopoverProps(record) {
@@ -202,6 +209,7 @@ export class CalendarCommonRenderer extends Component {
const injectedContentStr = renderToString(this.constructor.eventTemplate, {
...record,
startTime: this.getStartTime(record),
+ endTime: this.getEndTime(record),
});
const domParser = new DOMParser();
const { children } = domParser.parseFromString(injectedContentStr, "text/html").body;
@@ -222,6 +230,9 @@ export class CalendarCommonRenderer extends Component {
if (record.isStriked) {
el.classList.add("o_event_striked");
}
+ if (record.duration <= 0.25 ) {
+ el.classList.add("o_event_oneliner");
+ }
}
if (!el.querySelector(".fc-bg")) {
diff --git a/addons/web/static/src/views/calendar/calendar_renderer.scss b/addons/web/static/src/views/calendar/calendar_renderer.scss
index d4f0de18de7..cc689a53d45 100644
--- a/addons/web/static/src/views/calendar/calendar_renderer.scss
+++ b/addons/web/static/src/views/calendar/calendar_renderer.scss
@@ -193,7 +193,7 @@
// Prevent events with similar color to visually overlap each other
box-shadow: 0 0 0 1px white;
- &.fc-event:not(.fc-h-event) {
+ &.fc-event:not(.fc-h-event):not(.o_event_oneliner) {
border-width: 3px 0 0;
&.fc-not-start {
@@ -204,6 +204,16 @@
}
}
}
+
+ &.o_event_oneliner {
+ padding-top: 0;
+ padding-bottom: 0;
+ .fc-content {
+ margin-top: 0;
+ font-size: 11px !important;
+ line-height: 0.9;
+ }
+ }
}
// Reset position to keep the "nowIndicator" line visible
diff --git a/addons/web/static/tests/views/calendar/calendar_view_tests.js b/addons/web/static/tests/views/calendar/calendar_view_tests.js
index ecb4269e55f..b4d24006a3d 100644
--- a/addons/web/static/tests/views/calendar/calendar_view_tests.js
+++ b/addons/web/static/tests/views/calendar/calendar_view_tests.js
@@ -104,6 +104,7 @@ QUnit.module("Views", ({ beforeEach }) => {
start: { string: "start datetime", type: "datetime" },
stop: { string: "stop datetime", type: "datetime" },
delay: { string: "delay", type: "float" },
+ duration: { string: "Duration", type:"float", default: 1},
allday: { string: "allday", type: "boolean" },
partner_ids: {
string: "attendees",
@@ -306,7 +307,7 @@ QUnit.module("Views", ({ beforeEach }) => {
QUnit.module("CalendarView");
QUnit.test(`simple calendar rendering`, async (assert) => {
- assert.expect(24);
+ assert.expect(25);
serverData.models.event.records.push({
id: 8,
@@ -318,6 +319,17 @@ QUnit.module("Views", ({ beforeEach }) => {
allday: false,
partner_ids: [2],
type: 1,
+ }, {
+ id: 9,
+ user_id: uid,
+ partner_id: false,
+ name: "event 8",
+ start: "2016-12-11 05:15:00",
+ stop: "2016-12-11 05:30:00",
+ allday: false,
+ partner_ids: [1, 2, 3],
+ duration: 0.25,
+ type: 1,
});
await makeView({
@@ -325,10 +337,11 @@ QUnit.module("Views", ({ beforeEach }) => {
resModel: "event",
serverData,
arch: `
-
+
+
`,
});
@@ -350,8 +363,8 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 9,
- "should display 9 events on the week (4 event + 5 days event)"
+ 6,
+ "should display 6 events on the week (4 event + 1 allday + 1 >24h allday)"
);
assert.containsN(
target,
@@ -359,6 +372,13 @@ QUnit.module("Views", ({ beforeEach }) => {
7,
"week scale should highlight 7 days in mini calendar"
);
+
+ assert.containsOnce(
+ target,
+ ".o_event_oneliner",
+ "should contain 1 oneliner event (the one we add)"
+ );
+
await click(target, ".scale_button_selection");
await click(target, ".o_scale_button_day"); // display only one day
assert.containsN(target, ".fc-event", 2, "should display 2 events on the day");
@@ -378,8 +398,8 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 7,
- "should display 7 events on the month (5 events + 2 week event - 1 'event 6' is filtered + 1 'Undefined event')"
+ 8,
+ "should display 7 events on the month (6 events + 2 week event - 1 'event 6' is filtered + 1 'Undefined event')"
);
assert.containsN(
target,
@@ -439,11 +459,11 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 7,
+ 8,
"should display 7 events ('event 5' counts for 2 because it spans two weeks and thus generate two fc-event elements)"
);
await click(target.querySelectorAll(".o_calendar_filter input[type=checkbox]")[1]); // click on partner 2
- assert.containsN(target, ".fc-event", 4, "should now only display 4 event");
+ assert.containsN(target, ".fc-event", 5, "should now only display 5 event");
await click(target.querySelectorAll(".o_calendar_filter input[type=checkbox]")[2]);
assert.containsNone(target, ".fc-event", "should not display any event anymore");
// test search bar in filter
@@ -2131,8 +2151,8 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 9,
- "should display 9 events on the week (4 event + 5 days event)"
+ 5,
+ "should display 5 events on the week (4 event + 1 >24h event)"
);
await pickDate(target, "2016-12-19");
@@ -2141,8 +2161,8 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 4,
- "should display 4 events on the week (1 event + 3 days event)"
+ 2,
+ "should display 4 events on the week (1 event + 1 >24h event)"
);
// Clicking on a day in the same week should switch to that particular day view
@@ -2165,8 +2185,8 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(
target,
".fc-event",
- 4,
- "should display 4 events on the week (1 event + 3 days event)"
+ 2,
+ "should display 4 events on the week (1 event + 1 >24h event)"
);
await pickDate(target, "2016-12-18");
@@ -2566,11 +2586,11 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.containsN(target, ".fc-event", 4, "should display 4 events on the week");
await toggleFilter(target, "partner_ids", 2);
- assert.containsN(target, ".fc-event", 9, "should display 9 events on the week");
+ assert.containsN(target, ".fc-event", 5, "should display 5 events on the week");
// Click on the "all" filter to reload all events
await toggleFilter(target, "partner_ids", "all");
- assert.containsN(target, ".fc-event", 9, "should display 9 events on the week");
+ assert.containsN(target, ".fc-event", 5, "should display 5 events on the week");
});
QUnit.test(`Add filters and specific color`, async (assert) => {
@@ -2707,7 +2727,6 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.hasClass(findEvent(target, 2), "o_calendar_color_0");
assert.hasClass(findEvent(target, 3), "o_calendar_color_0");
assert.hasClass(findEvent(target, 4), "o_calendar_color_0");
- assert.hasClass(findEvent(target, 5), "o_calendar_color_0");
assert.containsOnce(target, ".o_calendar_filter[data-name=user_id]");
assert.containsNone(
findFilterPanelSection(target, "user_id"),
@@ -2806,7 +2825,6 @@ QUnit.module("Views", ({ beforeEach }) => {
assert.hasClass(findEvent(target, 2), "o_calendar_color_-1"); // uid = -1 ...
assert.hasClass(findEvent(target, 3), "o_calendar_color_4");
assert.hasClass(findEvent(target, 4), "o_calendar_color_-1"); // uid = -1 ...
- assert.hasClass(findEvent(target, 5), "o_calendar_color_4");
assert.containsNone(
findFilterPanelSection(target, "partner_id"),
"[class*='o_cw_filter_color_']"
@@ -3059,7 +3077,7 @@ QUnit.module("Views", ({ beforeEach }) => {
await toggleFilter(target, "partner_id", 4);
await toggleFilter(target, "partner_ids", 2);
- assert.containsN(target, ".fc-event", 11, "should display all records");
+ assert.containsN(target, ".fc-event", 7, "should display all records");
});
QUnit.test(`create event with filters (no quickCreate)`, async (assert) => {
@@ -4286,7 +4304,7 @@ QUnit.module("Views", ({ beforeEach }) => {
await resizeEventToTime(target, 8, "2016-12-14 08:00:00");
const event = findEvent(target, 8);
assert.strictEqual(event.textContent, "foobar");
- assert.notOk(event.closest(".fc-day-grid"), "event should not be in the all day slots");
+ assert.ok(event.closest(".fc-day-grid"), "event should be in the all day slots");
});
QUnit.test(`correctly display year view`, async (assert) => {