Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 3 additions & 0 deletions src/common/string/is_date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const regexp = /^\d{4}-(0[1-9]|1[0-2])-([12]\d|0[1-9]|3[01])$/;

export const isDate = (input: string): boolean => regexp.test(input);
10 changes: 10 additions & 0 deletions src/common/string/is_timestamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// https://stackoverflow.com/a/14322189/1947205
// Changes:
// 1. Do not allow a plus or minus at the start.
// 2. Enforce that we have a "T" or a blank after the date portion
// to ensure we have a timestamp and not only a date.
// 3. Disallow dates based on week number.
// 4. Disallow dates only consisting of a year.
const regexp = /^\d{4}-(0[1-9]|1[0-2])-([12]\d|0[1-9]|3[01])[T| ](((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)(\8[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)$/;

export const isTimestamp = (input: string): boolean => regexp.test(input);
52 changes: 40 additions & 12 deletions src/components/ha-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,23 @@ import {
TemplateResult,
} from "lit-element";
import { until } from "lit-html/directives/until";
import checkValidDate from "../common/datetime/check_valid_date";
import { formatDate } from "../common/datetime/format_date";
import { formatDateTimeWithSeconds } from "../common/datetime/format_date_time";
import { isDate } from "../common/string/is_date";
import { isTimestamp } from "../common/string/is_timestamp";
import { haStyle } from "../resources/styles";
import { HomeAssistant } from "../types";
import hassAttributeUtil, {
formatAttributeName,
} from "../util/hass-attributes-util";
import { haStyle } from "../resources/styles";

let jsYamlPromise: Promise<typeof import("js-yaml")>;

@customElement("ha-attributes")
class HaAttributes extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property() public stateObj?: HassEntity;

@property({ attribute: "extra-filters" }) public extraFilters?: string;
Expand Down Expand Up @@ -105,6 +113,7 @@ class HaAttributes extends LitElement {
if (value === null) {
return "-";
}

// YAML handling
if (
(Array.isArray(value) && value.some((val) => val instanceof Object)) ||
Expand All @@ -116,19 +125,38 @@ class HaAttributes extends LitElement {
const yaml = jsYamlPromise.then((jsYaml) => jsYaml.safeDump(value));
return html` <pre>${until(yaml, "")}</pre> `;
}
// URL handling
if (typeof value === "string" && value.startsWith("http")) {
try {
// If invalid URL, exception will be raised
const url = new URL(value);
if (url.protocol === "http:" || url.protocol === "https:")
return html`<a target="_blank" rel="noreferrer" href="${value}"
>${value}</a
>`;
} catch (_) {
// Nothing to do here

if (typeof value === "string") {
// URL handling
if (value.startsWith("http")) {
try {
// If invalid URL, exception will be raised
const url = new URL(value);
if (url.protocol === "http:" || url.protocol === "https:")
return html`<a target="_blank" rel="noreferrer" href="${value}"
>${value}</a
>`;
} catch (_) {
// Nothing to do here
}
}
// Timestamp handling
if (isTimestamp(value)) {
const date = new Date(value);
if (checkValidDate(date)) {
return formatDateTimeWithSeconds(date, this.hass.locale);
}
}

// Date handling
if (isDate(value)) {
Comment thread
spacegaier marked this conversation as resolved.
Outdated
const date = new Date(value);
if (checkValidDate(date)) {
return formatDate(date, this.hass.locale);
}
}
}

return Array.isArray(value) ? value.join(", ") : value;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-cover.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class MoreInfoCover extends LocalizeMixin(PolymerElement) {
</div>
</div>
<ha-attributes
hass="[[hass]]"
state-obj="[[stateObj]]"
extra-filters="current_position,current_tilt_position"
></ha-attributes>
Expand Down
5 changes: 4 additions & 1 deletion src/dialogs/more-info/controls/more-info-default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ class MoreInfoDefault extends LitElement {
return html``;
}

return html` <ha-attributes .stateObj=${this.stateObj}></ha-attributes> `;
return html`<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
></ha-attributes>`;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-fan.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class MoreInfoFan extends LocalizeMixin(EventsMixin(PolymerElement)) {
</div>

<ha-attributes
hass="[[hass]]"
state-obj="[[stateObj]]"
extra-filters="percentage_step,speed,preset_mode,preset_modes,speed_list,percentage,oscillating,direction"
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ class MoreInfoLight extends LitElement {
`
: ""}
<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
extra-filters="brightness,color_temp,white_value,effect_list,effect,hs_color,rgb_color,rgbw_color,rgbww_color,xy_color,min_mireds,max_mireds,entity_id,supported_color_modes,color_mode"
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class MoreInfoLock extends LocalizeMixin(PolymerElement) {
>
</template>
<ha-attributes
hass="[[hass]]"
state-obj="[[stateObj]]"
extra-filters="code_format"
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MoreInfoPerson extends LitElement {

return html`
<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
extra-filters="id,user_id,editable"
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class MoreInfoRemote extends LitElement {
: ""}

<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
.extraFilters=${filterExtraAttributes}
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class MoreInfoTimer extends LitElement {

return html`
<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
extra-filters="remaining"
></ha-attributes>
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/controls/more-info-vacuum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class MoreInfoVacuum extends LitElement {
: ""}

<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
.extraFilters=${filterExtraAttributes}
></ha-attributes>
Expand Down