From 5c3589ebe729c520ed97069be69549ead6db1431 Mon Sep 17 00:00:00 2001 From: Florian Damhaut Date: Thu, 5 Jan 2023 14:56:50 +0000 Subject: [PATCH] [IMP] web, calendar: make odoo calendar google again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR change generic calendar view to make it behave more like google calendar. These changes includes : - Scss rules for small event(<15 minutes) so that the title is always readable. On top of that, the top border of a darker color has been removed for these even to allow more space. - Event longer than 24h are now shown in the all day column independent of their 'allday' status - Time is now added in the event description, if the event is shorter than 30 minutes, only the start time is displayed at the end of the line. If the event is longer, the start time and end time are displayed on a new line. task-id : 3114155 closes odoo/odoo#109736 Signed-off-by: Michaƫl Mattiello --- .../attendee_calendar_common_renderer.xml | 6 ++ .../calendar_common_renderer.js | 15 ++++- .../src/views/calendar/calendar_renderer.scss | 12 +++- .../views/calendar/calendar_view_tests.js | 58 ++++++++++++------- 4 files changed, 68 insertions(+), 23 deletions(-) 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) => {