[IMP] web: add show weekends to calendar

This commit adds the "show weekends" functionality to calendar which
allows the user to choose whether weekends should be shown in the calendar
or not (defaults to false).

task-3425523

closes odoo/odoo#129107

Signed-off-by: Luca Vitali (luvi) <luvi@odoo.com>
This commit is contained in:
Julien Carion (juca)
2023-08-02 13:20:07 +02:00
parent 07cf57b2dd
commit 6da48dbc95
8 changed files with 58 additions and 12 deletions
@@ -96,6 +96,7 @@ export class CalendarCommonRenderer extends Component {
unselectAuto: false,
weekLabel:
this.props.model.scale === "month" && this.env.isSmall ? "" : this.env._t("Week"),
weekends: this.props.isWeekendVisible,
weekNumberCalculation: "ISO",
weekNumbers: true,
weekNumbersWithinDays: !this.env.isSmall,
@@ -158,7 +159,7 @@ export class CalendarCommonRenderer extends Component {
this.popover.open(
target,
this.getPopoverProps(record),
`o_cw_popover o_calendar_color_${typeof(color) === "number" ? color : 0}`
`o_cw_popover o_calendar_color_${typeof color === "number" ? color : 0}`
);
}
updateSize() {
@@ -16,6 +16,7 @@ import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { ViewScaleSelector } from "@web/views/view_components/view_scale_selector";
import { CogMenu } from "@web/search/cog_menu/cog_menu";
import { browser } from "@web/core/browser/browser";
import { Component, useState } from "@odoo/owl";
@@ -43,20 +44,28 @@ export class CalendarController extends Component {
this.orm = useService("orm");
this.displayDialog = useUniqueDialog();
this.model = useModelWithSampleData(this.props.Model, {
...this.props.archInfo,
resModel: this.props.resModel,
domain: this.props.domain,
fields: this.props.fields,
}, {
onWillStart: this.onWillStartModel.bind(this),
});
this.model = useModelWithSampleData(
this.props.Model,
{
...this.props.archInfo,
resModel: this.props.resModel,
domain: this.props.domain,
fields: this.props.fields,
},
{
onWillStart: this.onWillStartModel.bind(this),
}
);
useSetupView({
getLocalState: () => this.model.exportedState,
});
this.state = useState({
isWeekendVisible:
browser.localStorage.getItem("calendar.isWeekendVisible") != null
? JSON.parse(browser.localStorage.getItem("calendar.isWeekendVisible"))
: true,
showSideBar: !this.env.isSmall,
});
@@ -66,6 +75,7 @@ export class CalendarController extends Component {
get rendererProps() {
return {
model: this.model,
isWeekendVisible: this.model.scale === "day" || this.state.isWeekendVisible,
createRecord: this.createRecord.bind(this),
deleteRecord: this.deleteRecord.bind(this),
editRecord: this.editRecord.bind(this),
@@ -216,7 +226,7 @@ export class CalendarController extends Component {
}
onWillStartModel() {}
async setDate(move) {
let date = null;
switch (move) {
@@ -242,6 +252,11 @@ export class CalendarController extends Component {
async setScale(scale) {
await this.model.load({ scale });
}
toggleWeekendVisibility() {
this.state.isWeekendVisible = !this.state.isWeekendVisible;
browser.localStorage.setItem("calendar.isWeekendVisible", this.state.isWeekendVisible);
}
}
CalendarController.components = {
DatePicker: CalendarDatePicker,
@@ -33,7 +33,7 @@
aria-label="Previous"
t-on-click.stop="() => this.setDate('previous')"
><i class="oi oi-arrow-left"/></button>
<ViewScaleSelector scales="scales" currentScale="model.scale" setScale.bind="setScale" />
<ViewScaleSelector scales="scales" currentScale="model.scale" isWeekendVisible="state.isWeekendVisible" setScale.bind="setScale" toggleWeekendVisibility.bind="toggleWeekendVisibility" />
<button
class="o_calendar_button_next btn btn-secondary btn-sm d-none d-md-block"
title="Next"
@@ -10,6 +10,7 @@ import {
onPatched,
onWillStart,
onWillUnmount,
onWillUpdateProps,
useComponent,
useExternalListener,
useRef,
@@ -124,8 +125,14 @@ export function useFullCalendar(refName, params) {
throw new Error(`Cannot instantiate FullCalendar\n${e.message}`);
}
});
let isWeekendVisible = params.isWeekendVisible;
onWillUpdateProps((np) => {
isWeekendVisible = np.isWeekendVisible;
});
onPatched(() => {
instance.refetchEvents();
instance.setOption("weekends", isWeekendVisible);
});
onWillUnmount(() => {
instance.destroy();
@@ -13,7 +13,9 @@ export class ViewScaleSelector extends Component {
static props = {
scales: { type: Object },
currentScale: { type: String },
isWeekendVisible: { type: Boolean, optional: true },
setScale: { type: Function },
toggleWeekendVisibility: { type: Function, optional: true },
};
get scales() {
return Object.entries(this.props.scales).map(([key, value]) => ({ key, ...value }));
@@ -15,6 +15,14 @@
<t t-esc="scale.description" />
</DropdownItem>
</t>
<div t-if="this.props.isWeekendVisible !== undefined" class="dropdown-divider" role="separator"/>
<DropdownItem
t-if="this.props.isWeekendVisible !== undefined"
class="`${props.isWeekendVisible ? 'active' : ''}`"
onSelected="props.toggleWeekendVisibility"
>
Show weekends
</DropdownItem>
</Dropdown>
</t>
@@ -2688,7 +2688,10 @@ QUnit.module("Views", ({ beforeEach }) => {
</calendar>
`,
});
const colorClass = Array.from(findEvent(target, 1).classList).find(className => className.startsWith("o_calendar_color_"));
const colorClass = Array.from(findEvent(target, 1).classList).find((className) =>
className.startsWith("o_calendar_color_")
);
assert.notOk(isNaN(Number(colorClass.split("_").at(-1))));
await clickEvent(target, 1);
assert.hasClass(target.querySelector(".o_cw_popover"), colorClass);
@@ -45,10 +45,14 @@ QUnit.module("ViewComponents", (hooks) => {
description: "Yearly",
},
},
isWeekendVisible: true,
setScale: (scale) => {
this.state.scale = scale;
assert.step(scale);
},
toggleWeekendVisibility: () => {
assert.step("toggleWeekendVisibility");
},
currentScale: this.state.scale,
};
}
@@ -89,6 +93,10 @@ QUnit.module("ViewComponents", (hooks) => {
"Daily",
"the right text is displayed on the toggler"
);
await click(target, ".scale_button_selection");
await click(target, ".dropdown-item:last-child");
assert.verifySteps(["toggleWeekendVisibility"]);
});
QUnit.test("ViewScaleSelector with only one scale available", async (assert) => {
@@ -110,6 +118,8 @@ QUnit.module("ViewComponents", (hooks) => {
},
},
setScale: () => {},
isWeekendVisible: false,
toggleWeekendVisibility: () => {},
currentScale: this.state.scale,
};
}