From e9d3ebcd5297d87bbf1f668ee2d9959ab6e7ddc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Lambert=20=28belam=29?= Date: Mon, 11 May 2026 10:33:55 +0200 Subject: [PATCH] [IMP] hr_holidays: Accrual UX Created a days_in_month selection widget The widget takes a parameters as field_name, read the field value (month as integer) and returns a selection of valid day numbers for that month. If nothing is selected : should return [1..31] (inclusive) If Februari is selected (month=2), should return [1..29] (incl.) Etc. --- .../days_in_month_selection.js | 41 +++++++++++++++++++ .../views/hr_leave_accrual_views.xml | 4 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 addons/hr_holidays/static/src/components/days_in_month_selection/days_in_month_selection.js diff --git a/addons/hr_holidays/static/src/components/days_in_month_selection/days_in_month_selection.js b/addons/hr_holidays/static/src/components/days_in_month_selection/days_in_month_selection.js new file mode 100644 index 00000000000000..cb3fd713661f2a --- /dev/null +++ b/addons/hr_holidays/static/src/components/days_in_month_selection/days_in_month_selection.js @@ -0,0 +1,41 @@ +/** @odoo-module **/ +import { registry } from "@web/core/registry"; +import { SelectionField, selectionField } from "@web/views/fields/selection/selection_field"; + +export class DaysInMonthSelection extends SelectionField { + + static props = { + ...SelectionField.props, + monthField: { type: String, optional: true }, + }; + + get options() { + const monthFieldName = this.props.monthField; + const monthValue = this.props.record.data[monthFieldName] ?? null; + const maxDay = this.getDaysRange(monthValue); + return [...Array(maxDay).keys()].map(i => [String(i + 1), String(i + 1)]); + } + + getDaysRange(month) { + if (!month) return 31; + const luxonMonth = luxon.DateTime.fromObject({year: 2024, month: parseInt(month)}); //2024 is leap year - this will enforce 29 for February + return luxonMonth.isValid ? luxonMonth.daysInMonth : 31; + } + + onChange(value) { + this.props.record.update({ [this.props.name]: value }, { save: this.props.autosave }); + } +} + +export const daysInMonthSelection = { + ...selectionField, + component: DaysInMonthSelection, + supportedTypes: ["selection", "integer"], + extractProps({ options, viewType }, dynamicInfo) { + const props = selectionField.extractProps(...arguments); + props.monthField = options.month; + return props; + }, +}; + +registry.category("fields").add("daysInMonthSelection", daysInMonthSelection); diff --git a/addons/hr_holidays/views/hr_leave_accrual_views.xml b/addons/hr_holidays/views/hr_leave_accrual_views.xml index a097fdbec8f74b..31090c1b8bd8c3 100644 --- a/addons/hr_holidays/views/hr_leave_accrual_views.xml +++ b/addons/hr_holidays/views/hr_leave_accrual_views.xml @@ -46,7 +46,7 @@ on the - + of @@ -196,6 +196,8 @@ : the of