mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 04:16:34 +00:00
Date-range-picker Design to use Prev and Next Buttons in History and Logbook on mobiles (#23228)
* date-range-picker prev and next design * correct width and margins * logbook width correction * Update src/components/ha-date-range-picker.ts Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com> * Update src/components/ha-date-range-picker.ts Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com> * Update src/components/ha-date-range-picker.ts Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com> * changes from comments * share date-range logic for energy and history / logbook * switch to energy-dashboard timespan-function * changed shiftDateRange to differenceInMilliseconds * used gap instead margin-right --------- Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
parent
ad1c32a880
commit
6f8ba6afac
@ -1,3 +1,12 @@
|
||||
import {
|
||||
addMilliseconds,
|
||||
addMonths,
|
||||
isFirstDayOfMonth,
|
||||
isLastDayOfMonth,
|
||||
differenceInMilliseconds,
|
||||
differenceInMonths,
|
||||
endOfMonth,
|
||||
} from "date-fns";
|
||||
import { toZonedTime, fromZonedTime } from "date-fns-tz";
|
||||
import type { HassConfig } from "home-assistant-js-websocket";
|
||||
import type { FrontendLocaleData } from "../../data/translation";
|
||||
@ -55,3 +64,55 @@ export const calcDateDifferenceProperty = (
|
||||
? toZonedTime(startDate, config.time_zone)
|
||||
: startDate
|
||||
);
|
||||
|
||||
export const shiftDateRange = (
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
forward: boolean,
|
||||
locale: FrontendLocaleData,
|
||||
config: any
|
||||
): { start: Date; end: Date } => {
|
||||
let start: Date;
|
||||
let end: Date;
|
||||
if (
|
||||
(calcDateProperty(
|
||||
startDate,
|
||||
isFirstDayOfMonth,
|
||||
locale,
|
||||
config
|
||||
) as boolean) &&
|
||||
(calcDateProperty(endDate, isLastDayOfMonth, locale, config) as boolean)
|
||||
) {
|
||||
const difference =
|
||||
((calcDateDifferenceProperty(
|
||||
endDate,
|
||||
startDate,
|
||||
differenceInMonths,
|
||||
locale,
|
||||
config
|
||||
) as number) +
|
||||
1) *
|
||||
(forward ? 1 : -1);
|
||||
start = calcDate(startDate, addMonths, locale, config, difference);
|
||||
end = calcDate(
|
||||
calcDate(endDate, addMonths, locale, config, difference),
|
||||
endOfMonth,
|
||||
locale,
|
||||
config
|
||||
);
|
||||
} else {
|
||||
const difference =
|
||||
((calcDateDifferenceProperty(
|
||||
endDate,
|
||||
startDate,
|
||||
differenceInMilliseconds,
|
||||
locale,
|
||||
config
|
||||
) as number) +
|
||||
1) *
|
||||
(forward ? 1 : -1);
|
||||
start = calcDate(startDate, addMilliseconds, locale, config, difference);
|
||||
end = calcDate(endDate, addMilliseconds, locale, config, difference);
|
||||
}
|
||||
return { start, end };
|
||||
};
|
||||
|
@ -5,8 +5,6 @@ import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiCalendar } from "@mdi/js";
|
||||
import {
|
||||
addDays,
|
||||
addMonths,
|
||||
addYears,
|
||||
endOfDay,
|
||||
endOfMonth,
|
||||
endOfWeek,
|
||||
@ -15,25 +13,23 @@ import {
|
||||
startOfMonth,
|
||||
startOfWeek,
|
||||
startOfYear,
|
||||
differenceInMilliseconds,
|
||||
addMilliseconds,
|
||||
subMilliseconds,
|
||||
roundToNearestHours,
|
||||
isThisYear,
|
||||
} from "date-fns";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { calcDate } from "../common/datetime/calc_date";
|
||||
import { calcDate, shiftDateRange } from "../common/datetime/calc_date";
|
||||
import { firstWeekdayIndex } from "../common/datetime/first_weekday";
|
||||
import { formatDate } from "../common/datetime/format_date";
|
||||
import { formatDateTime } from "../common/datetime/format_date_time";
|
||||
import {
|
||||
formatShortDateTimeWithYear,
|
||||
formatShortDateTime,
|
||||
} from "../common/datetime/format_date_time";
|
||||
import { useAmPm } from "../common/datetime/use_am_pm";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./date-range-picker";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-svg-icon";
|
||||
import "./ha-textfield";
|
||||
import "./ha-textarea";
|
||||
import "./ha-icon-button-next";
|
||||
import "./ha-icon-button-prev";
|
||||
|
||||
@ -141,9 +137,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
[this.hass.localize(
|
||||
"ui.components.date-range-picker.ranges.this_week"
|
||||
)]: [weekStart, weekEnd],
|
||||
[this.hass.localize(
|
||||
"ui.components.date-range-picker.ranges.last_week"
|
||||
)]: [addDays(weekStart, -7), addDays(weekEnd, -7)],
|
||||
...(this.extendedPresets
|
||||
? {
|
||||
[this.hass.localize(
|
||||
@ -168,28 +161,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
}
|
||||
),
|
||||
],
|
||||
[this.hass.localize(
|
||||
"ui.components.date-range-picker.ranges.last_month"
|
||||
)]: [
|
||||
calcDate(
|
||||
addMonths(today, -1),
|
||||
startOfMonth,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
{
|
||||
weekStartsOn,
|
||||
}
|
||||
),
|
||||
calcDate(
|
||||
addMonths(today, -1),
|
||||
endOfMonth,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
{
|
||||
weekStartsOn,
|
||||
}
|
||||
),
|
||||
],
|
||||
[this.hass.localize(
|
||||
"ui.components.date-range-picker.ranges.this_year"
|
||||
)]: [
|
||||
@ -206,28 +177,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
weekStartsOn,
|
||||
}),
|
||||
],
|
||||
[this.hass.localize(
|
||||
"ui.components.date-range-picker.ranges.last_year"
|
||||
)]: [
|
||||
calcDate(
|
||||
addYears(today, -1),
|
||||
startOfYear,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
{
|
||||
weekStartsOn,
|
||||
}
|
||||
),
|
||||
calcDate(
|
||||
addYears(today, -1),
|
||||
endOfYear,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
{
|
||||
weekStartsOn,
|
||||
}
|
||||
),
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
@ -261,54 +210,49 @@ export class HaDateRangePicker extends LitElement {
|
||||
>
|
||||
<div slot="input" class="date-range-inputs" @click=${this._handleClick}>
|
||||
${!this.minimal
|
||||
? html`<ha-svg-icon .path=${mdiCalendar}></ha-svg-icon>
|
||||
<ha-icon-button-prev
|
||||
.label=${this.hass.localize("ui.common.previous")}
|
||||
class="prev"
|
||||
@click=${this._handlePrev}
|
||||
>
|
||||
</ha-icon-button-prev>
|
||||
<ha-textfield
|
||||
.value=${this.timePicker
|
||||
? formatDateTime(
|
||||
? html`<ha-textarea
|
||||
mobile-multiline
|
||||
.value=${(isThisYear(this.startDate)
|
||||
? formatShortDateTime(
|
||||
this.startDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: formatDate(
|
||||
: formatShortDateTimeWithYear(
|
||||
this.startDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)}
|
||||
)) +
|
||||
" - \n" +
|
||||
(isThisYear(this.endDate)
|
||||
? formatShortDateTime(
|
||||
this.endDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: formatShortDateTimeWithYear(
|
||||
this.endDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
))}
|
||||
.label=${this.hass.localize(
|
||||
"ui.components.date-range-picker.start_date"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._handleInputClick}
|
||||
readonly
|
||||
></ha-textfield>
|
||||
<ha-textfield
|
||||
.value=${this.timePicker
|
||||
? formatDateTime(
|
||||
this.endDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)
|
||||
: formatDate(
|
||||
this.endDate,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
)}
|
||||
.label=${this.hass.localize(
|
||||
) +
|
||||
" - " +
|
||||
this.hass.localize(
|
||||
"ui.components.date-range-picker.end_date"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._handleInputClick}
|
||||
readonly
|
||||
></ha-textfield>
|
||||
></ha-textarea>
|
||||
<ha-icon-button-prev
|
||||
.label=${this.hass.localize("ui.common.previous")}
|
||||
@click=${this._handlePrev}
|
||||
>
|
||||
</ha-icon-button-prev>
|
||||
<ha-icon-button-next
|
||||
.label=${this.hass.localize("ui.common.next")}
|
||||
class="next"
|
||||
@click=${this._handleNext}
|
||||
>
|
||||
</ha-icon-button-next>`
|
||||
@ -342,40 +286,28 @@ export class HaDateRangePicker extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleNext(): void {
|
||||
const dateRange = [
|
||||
roundToNearestHours(this.endDate),
|
||||
subMilliseconds(
|
||||
roundToNearestHours(
|
||||
addMilliseconds(
|
||||
this.endDate,
|
||||
Math.max(
|
||||
3600000,
|
||||
differenceInMilliseconds(this.endDate, this.startDate)
|
||||
)
|
||||
)
|
||||
),
|
||||
1
|
||||
),
|
||||
];
|
||||
const dateRangePicker = this._dateRangePicker;
|
||||
dateRangePicker.clickRange(dateRange);
|
||||
dateRangePicker.clickedApply();
|
||||
private _handleNext(ev: MouseEvent): void {
|
||||
if (ev && ev.stopPropagation) ev.stopPropagation();
|
||||
this._shift(true);
|
||||
}
|
||||
|
||||
private _handlePrev(): void {
|
||||
const dateRange = [
|
||||
roundToNearestHours(
|
||||
subMilliseconds(
|
||||
private _handlePrev(ev: MouseEvent): void {
|
||||
if (ev && ev.stopPropagation) ev.stopPropagation();
|
||||
this._shift(false);
|
||||
}
|
||||
|
||||
private _shift(forward: boolean) {
|
||||
if (!this.startDate) return;
|
||||
const { start, end } = shiftDateRange(
|
||||
this.startDate,
|
||||
Math.max(
|
||||
3600000,
|
||||
differenceInMilliseconds(this.endDate, this.startDate)
|
||||
)
|
||||
)
|
||||
),
|
||||
subMilliseconds(roundToNearestHours(this.startDate), 1),
|
||||
];
|
||||
this.endDate,
|
||||
forward,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
);
|
||||
this.startDate = start;
|
||||
this.endDate = end;
|
||||
const dateRange = [start, end];
|
||||
const dateRangePicker = this._dateRangePicker;
|
||||
dateRangePicker.clickRange(dateRange);
|
||||
dateRangePicker.clickedApply();
|
||||
@ -430,12 +362,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
ha-svg-icon {
|
||||
margin-right: 8px;
|
||||
margin-inline-end: 8px;
|
||||
margin-inline-start: initial;
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
ha-icon-button {
|
||||
direction: var(--direction);
|
||||
@ -444,6 +370,7 @@ export class HaDateRangePicker extends LitElement {
|
||||
.date-range-inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.date-range-ranges {
|
||||
@ -457,17 +384,13 @@ export class HaDateRangePicker extends LitElement {
|
||||
border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
ha-textfield {
|
||||
ha-textarea {
|
||||
display: inline-block;
|
||||
max-width: 250px;
|
||||
min-width: 220px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
ha-textfield:last-child {
|
||||
margin-left: 8px;
|
||||
margin-inline-start: 8px;
|
||||
margin-inline-end: initial;
|
||||
direction: var(--direction);
|
||||
@media only screen and (max-width: 460px) {
|
||||
ha-textarea {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@ -476,18 +399,6 @@ export class HaDateRangePicker extends LitElement {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 500px) {
|
||||
ha-textfield {
|
||||
min-width: inherit;
|
||||
}
|
||||
|
||||
ha-svg-icon,
|
||||
.prev,
|
||||
.next {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,12 @@ export class HaTextArea extends TextAreaBase {
|
||||
inset-inline-end: initial !important;
|
||||
transform-origin: var(--float-start) top;
|
||||
}
|
||||
@media only screen and (min-width: 459px) {
|
||||
:host([mobile-multiline]) .mdc-text-field__input {
|
||||
white-space: nowrap;
|
||||
max-height: 16px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -772,10 +772,8 @@ class HaPanelHistory extends LitElement {
|
||||
flex-direction: column;
|
||||
}
|
||||
ha-date-range-picker {
|
||||
margin-right: 0;
|
||||
margin-inline-end: 0;
|
||||
margin-inline-start: initial;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,6 +305,12 @@ export class HaPanelLogbook extends LitElement {
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
@media all and (max-width: 870px) {
|
||||
ha-date-range-picker {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:host([narrow]) ha-date-range-picker {
|
||||
margin-right: 0;
|
||||
margin-inline-end: 0;
|
||||
|
@ -2,8 +2,6 @@ import "@material/mwc-button/mwc-button";
|
||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import {
|
||||
addDays,
|
||||
addMonths,
|
||||
differenceInDays,
|
||||
differenceInMonths,
|
||||
endOfDay,
|
||||
@ -30,6 +28,7 @@ import {
|
||||
calcDate,
|
||||
calcDateProperty,
|
||||
calcDateDifferenceProperty,
|
||||
shiftDateRange,
|
||||
} from "../../../common/datetime/calc_date";
|
||||
import { firstWeekdayIndex } from "../../../common/datetime/first_weekday";
|
||||
import {
|
||||
@ -512,84 +511,15 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
|
||||
|
||||
private _shift(forward: boolean) {
|
||||
if (!this._startDate) return;
|
||||
|
||||
let start: Date;
|
||||
let end: Date;
|
||||
if (
|
||||
(calcDateProperty(
|
||||
const { start, end } = shiftDateRange(
|
||||
this._startDate,
|
||||
isFirstDayOfMonth,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
) as boolean) &&
|
||||
(calcDateProperty(
|
||||
this._endDate!,
|
||||
isLastDayOfMonth,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
) as boolean)
|
||||
) {
|
||||
// Shift date range with respect to month/year selection
|
||||
const difference =
|
||||
((calcDateDifferenceProperty(
|
||||
this._endDate!,
|
||||
this._startDate,
|
||||
differenceInMonths,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
) as number) +
|
||||
1) *
|
||||
(forward ? 1 : -1);
|
||||
start = calcDate(
|
||||
this._startDate,
|
||||
addMonths,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
difference
|
||||
);
|
||||
end = calcDate(
|
||||
calcDate(
|
||||
this._endDate!,
|
||||
addMonths,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
difference
|
||||
),
|
||||
endOfMonth,
|
||||
forward,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
);
|
||||
} else {
|
||||
// Shift date range by period length
|
||||
const difference =
|
||||
((calcDateDifferenceProperty(
|
||||
this._endDate!,
|
||||
this._startDate,
|
||||
differenceInDays,
|
||||
this.hass.locale,
|
||||
this.hass.config
|
||||
) as number) +
|
||||
1) *
|
||||
(forward ? 1 : -1);
|
||||
start = calcDate(
|
||||
this._startDate,
|
||||
addDays,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
difference
|
||||
);
|
||||
end = calcDate(
|
||||
this._endDate!,
|
||||
addDays,
|
||||
this.hass.locale,
|
||||
this.hass.config,
|
||||
difference
|
||||
);
|
||||
}
|
||||
|
||||
this._startDate = start;
|
||||
this._endDate = end;
|
||||
|
||||
this._updateCollectionPeriod();
|
||||
}
|
||||
|
||||
|
@ -802,12 +802,9 @@
|
||||
"today": "Today",
|
||||
"yesterday": "Yesterday",
|
||||
"this_week": "This week",
|
||||
"last_week": "Last week",
|
||||
"this_quarter": "This quarter",
|
||||
"this_month": "This month",
|
||||
"last_month": "Last month",
|
||||
"this_year": "This year",
|
||||
"last_year": "Last year"
|
||||
"this_year": "This year"
|
||||
}
|
||||
},
|
||||
"grid-size-picker": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user