Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date-range-picker Design to use Prev and Next Buttons in History and Logbook on mobiles #23228

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 85 additions & 127 deletions src/components/ha-date-range-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { mdiCalendar } from "@mdi/js";
import {
addDays,
addMonths,
addYears,
endOfDay,
endOfMonth,
endOfWeek,
Expand All @@ -19,21 +18,27 @@ import {
addMilliseconds,
subMilliseconds,
roundToNearestHours,
isFirstDayOfMonth,
isLastDayOfMonth,
subMonths,
differenceInMonths,
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 { 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";

Expand Down Expand Up @@ -141,9 +146,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(
Expand All @@ -168,28 +170,6 @@ export class HaDateRangePicker extends LitElement {
}
),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.last_month"
bramkragten marked this conversation as resolved.
Show resolved Hide resolved
)]: [
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"
)]: [
Expand All @@ -206,28 +186,6 @@ export class HaDateRangePicker extends LitElement {
weekStartsOn,
}),
],
[this.hass.localize(
"ui.components.date-range-picker.ranges.last_year"
bramkragten marked this conversation as resolved.
Show resolved Hide resolved
)]: [
calcDate(
addYears(today, -1),
startOfYear,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
calcDate(
addYears(today, -1),
endOfYear,
this.hass.locale,
this.hass.config,
{
weekStartsOn,
}
),
],
}
: {}),
};
Expand Down Expand Up @@ -261,51 +219,44 @@ 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
mobile2multiline
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel like this should be part of ha-textarea. Also use mobile-multiline as a name otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed a way to display it in one-line, my solution was to add "white-space: nowrap;" for desktops: this ignores the nextline \n in the datestring. Have not found a better way change css for ha-textarea from outside

.value=${(isThisYear(this.startDate)
? formatShortDateTime(
this.startDate,
this.hass.locale,
this.hass.config
)
: formatDate(
: formatShortDateTimeWithYear(
this.startDate,
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(
)) +
" - \n" +
(isThisYear(this.endDate)
? formatShortDateTime(
this.endDate,
this.hass.locale,
this.hass.config
)
: formatDate(
: formatShortDateTimeWithYear(
this.endDate,
this.hass.locale,
this.hass.config
)}
))}
.label=${this.hass.localize(
"ui.components.date-range-picker.end_date"
"ui.components.selectors.selector.types.datetime"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use the translation key of another selector, you can reference its value though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or use the already existing start_date and end_date? "Start date - End date" would be more explaining as "Date Time" for the range

)}
.disabled=${this.disabled}
@click=${this._handleInputClick}
readonly
></ha-textfield>
></ha-textarea>
<ha-icon-button-prev
.label=${this.hass.localize("ui.common.previous")}
class="prev"
boern99 marked this conversation as resolved.
Show resolved Hide resolved
@click=${this._handlePrev}
>
</ha-icon-button-prev>
<ha-icon-button-next
.label=${this.hass.localize("ui.common.next")}
class="next"
boern99 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -343,39 +294,64 @@ 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)
let dateRange: [Date, Date];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets extract the next and prev functions from hui-energy-period-selector and make them helper functions we can use here too.

Copy link
Contributor Author

@boern99 boern99 Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new functions can deal with any-ranges and also shorter than one day. If selected a week the range is 7 days: so Week is not needed. Extra logic is only needed for month, as the timespans can be different. And the month-Logic can also shift between years without problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still they share the same logic right? So we can combine them into 1 function we use in both places?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, took now a detailed look at it: you are right: we can combine them. Will upload a draft: hopefully that's the way it should be done ..

if (isFirstDayOfMonth(this.startDate) && isLastDayOfMonth(this.endDate)) {
dateRange = [
roundToNearestHours(this.endDate),
subMilliseconds(
addMonths(
roundToNearestHours(this.endDate),
differenceInMonths(addMilliseconds(this.endDate, 1), this.startDate)
),
1
),
];
} else {
dateRange = [
roundToNearestHours(this.endDate),
subMilliseconds(
roundToNearestHours(
addMilliseconds(
this.endDate,
Math.max(
3600000,
differenceInMilliseconds(this.endDate, this.startDate)
)
)
)
),
1
),
1
),
];
];
}
const dateRangePicker = this._dateRangePicker;
dateRangePicker.clickRange(dateRange);
dateRangePicker.clickedApply();
}

private _handlePrev(): void {
const dateRange = [
roundToNearestHours(
subMilliseconds(
let dateRange: [Date, Date];
if (isFirstDayOfMonth(this.startDate) && isLastDayOfMonth(this.endDate)) {
dateRange = [
subMonths(
this.startDate,
Math.max(
3600000,
differenceInMilliseconds(this.endDate, this.startDate)
differenceInMonths(addMilliseconds(this.endDate, 1), this.startDate)
),
subMilliseconds(roundToNearestHours(this.startDate), 1),
];
} else {
dateRange = [
roundToNearestHours(
subMilliseconds(
this.startDate,
Math.max(
3600000,
differenceInMilliseconds(this.endDate, this.startDate)
)
)
)
),
subMilliseconds(roundToNearestHours(this.startDate), 1),
];
),
subMilliseconds(roundToNearestHours(this.startDate), 1),
];
}
const dateRangePicker = this._dateRangePicker;
dateRangePicker.clickRange(dateRange);
dateRangePicker.clickedApply();
Expand Down Expand Up @@ -430,11 +406,8 @@ 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-prev {
margin-right:8px;
boern99 marked this conversation as resolved.
Show resolved Hide resolved
}

ha-icon-button {
Expand All @@ -457,17 +430,14 @@ 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;
margin-right: 8px;
boern99 marked this conversation as resolved.
Show resolved Hide resolved
}

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) {
Expand All @@ -476,18 +446,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;
}
}
`;
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/components/ha-textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([mobile2multiline]) .mdc-text-field__input {
white-space: nowrap;
max-height: 16px;
}
}
`,
];
}
Expand Down
2 changes: 1 addition & 1 deletion src/panels/history/ha-panel-history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,10 +772,10 @@ class HaPanelHistory extends LitElement {
flex-direction: column;
}
ha-date-range-picker {
margin-right: 0;
margin-inline-end: 0;
margin-inline-start: initial;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove margin-right, you should also remove these 2

width: 100%;
margin-bottom: 8px;
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/panels/logbook/ha-panel-logbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading