[FIX] web: give enough space to display datepicker on small screens
Before this commit, the datepicker was not displayed entirely on small screens if the current view wasn't tall enough. This commit adds a margin (supposedly) big enough to render the entire picker even on small screens. Task 3585878 closes odoo/odoo#149510 X-original-commit: 47c0627d218bd846596c9deb84720fc289047365 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
This commit is contained in:
@@ -67,6 +67,10 @@ export const datetimePickerService = {
|
||||
updateValueFromInputs();
|
||||
apply();
|
||||
setFocusClass(null);
|
||||
if (restoreTargetMargin) {
|
||||
restoreTargetMargin();
|
||||
restoreTargetMargin = null;
|
||||
}
|
||||
},
|
||||
});
|
||||
// Hook methods
|
||||
@@ -238,7 +242,14 @@ export const datetimePickerService = {
|
||||
if (!popover.isOpen) {
|
||||
const popoverTarget = getPopoverTarget();
|
||||
if (env.isSmall) {
|
||||
const { marginBottom } = popoverTarget.style;
|
||||
// Adds enough space for the popover to be displayed below the target
|
||||
// even on small screens.
|
||||
popoverTarget.style.marginBottom = `100vh`;
|
||||
popoverTarget.scrollIntoView(true);
|
||||
restoreTargetMargin = async () => {
|
||||
popoverTarget.style.marginBottom = marginBottom;
|
||||
};
|
||||
}
|
||||
popover.open(popoverTarget, { pickerProps });
|
||||
}
|
||||
@@ -416,6 +427,8 @@ export const datetimePickerService = {
|
||||
/** @type {DateTimePickerProps | null} */
|
||||
let lastInitialProps = null;
|
||||
let lastIsRange = pickerProps.range;
|
||||
/** @type {(() => void) | null} */
|
||||
let restoreTargetMargin = null;
|
||||
let shouldFocus = false;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Component, xml } from "@odoo/owl";
|
||||
import { clearRegistryWithCleanup, makeTestEnv } from "@web/../tests/helpers/mock_env";
|
||||
import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services";
|
||||
import { click, getFixture, mount } from "@web/../tests/helpers/utils";
|
||||
import { DateTimeInput } from "@web/core/datetime/datetime_input";
|
||||
import { datetimePickerService } from "@web/core/datetime/datetimepicker_service";
|
||||
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
|
||||
import { popoverService } from "@web/core/popover/popover_service";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { uiService } from "@web/core/ui/ui_service";
|
||||
|
||||
const { DateTime } = luxon;
|
||||
|
||||
/**
|
||||
* @typedef {import("@web/core/datetime/datetime_input").DateTimeInputProps} DateTimeInputProps
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {DateTimeInputProps} props
|
||||
*/
|
||||
const mountInput = async (props) => {
|
||||
const env = await makeTestEnv();
|
||||
await mount(Root, getFixture(), { env, props });
|
||||
return getFixture().querySelector(".o_datetime_input");
|
||||
};
|
||||
|
||||
class Root extends Component {
|
||||
static components = { DateTimeInput };
|
||||
|
||||
static template = xml`
|
||||
<div class="d-flex">
|
||||
<DateTimeInput t-props="props" />
|
||||
</div>
|
||||
<t t-foreach="mainComponentEntries" t-as="comp" t-key="comp[0]">
|
||||
<t t-component="comp[1].Component" t-props="comp[1].props" />
|
||||
</t>
|
||||
`;
|
||||
|
||||
setup() {
|
||||
this.mainComponentEntries = mainComponentRegistry.getEntries();
|
||||
}
|
||||
}
|
||||
|
||||
const mainComponentRegistry = registry.category("main_components");
|
||||
const serviceRegistry = registry.category("services");
|
||||
|
||||
QUnit.module("Components", ({ beforeEach }) => {
|
||||
beforeEach(() => {
|
||||
clearRegistryWithCleanup(mainComponentRegistry);
|
||||
|
||||
serviceRegistry
|
||||
.add("datetime_picker", datetimePickerService)
|
||||
.add("hotkey", hotkeyService)
|
||||
.add(
|
||||
"localization",
|
||||
makeFakeLocalizationService({
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateTimeFormat: "dd/MM/yyyy HH:mm:ss",
|
||||
})
|
||||
)
|
||||
.add("popover", popoverService)
|
||||
.add("ui", uiService);
|
||||
});
|
||||
|
||||
QUnit.module("DateTimeInput (date)");
|
||||
|
||||
QUnit.test("popover should have enough space to be displayed", async (assert) => {
|
||||
const { parentElement: parent } = await mountInput({
|
||||
value: DateTime.fromFormat("09/01/1997", "dd/MM/yyyy"),
|
||||
type: "date",
|
||||
});
|
||||
|
||||
const initialParentRect = parent.getBoundingClientRect();
|
||||
|
||||
await click(parent, ".o_datetime_input");
|
||||
|
||||
const pickerRect = getFixture().querySelector(".o_datetime_picker").getBoundingClientRect();
|
||||
const finalParentRect = parent.getBoundingClientRect();
|
||||
|
||||
assert.ok(
|
||||
initialParentRect.height < pickerRect.height,
|
||||
"initial height shouldn't be big enough to display the picker"
|
||||
);
|
||||
assert.ok(
|
||||
finalParentRect.height > pickerRect.height,
|
||||
"initial height should be big enough to display the picker"
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user