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) => {