Skip to content

Commit

Permalink
various improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsfaber committed Jul 29, 2024
1 parent 54b2931 commit 3ec525b
Show file tree
Hide file tree
Showing 34 changed files with 693 additions and 262 deletions.
297 changes: 176 additions & 121 deletions dist/scheduler-card.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"homepage": "https://github.com/nielsfaber/scheduler-card#readme",
"dependencies": {
"@formatjs/intl-utils": "^3.8.4",
"@mdi/js": "^7.4.47",
"fecha": "^4.2.3",
"home-assistant-js-websocket": "^8.0.1",
Expand All @@ -42,4 +43,4 @@
"@rollup/plugin-dynamic-import-vars": "^2.1.2",
"parcel": "^2.8.3"
}
}
}
11 changes: 9 additions & 2 deletions src/components/collapsible-section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ class CollapsibleSection extends LitElement {
margin: 8px 0px;
position: relative;
}
.header {
display: flex;
width: 100%;
Expand All @@ -105,11 +104,14 @@ class CollapsibleSection extends LitElement {
:host([disabled]) .header {
cursor: default;
}
.header .title {
font-weight: 600;
padding: 0px 8px;
}
.header ::slotted(span) {
display: flex;
margin-right: 32px;
}
.header.focused {
background: var(--input-fill-color);
}
Expand Down Expand Up @@ -143,6 +145,11 @@ class CollapsibleSection extends LitElement {
.container.expanded {
height: auto;
}
@media all and (max-width: 450px) {
.container {
padding: 0px;
}
}
`;
}
}
Expand Down
54 changes: 45 additions & 9 deletions src/components/combo-selector.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { customElement, property, state } from "lit/decorators";
import { NumberSelector, SelectOption, Selector, SelectSelector, StringSelector } from "../lib/selector";
import { HomeAssistant } from "../lib/types";
import { fireEvent } from "../lib/fire_event";
Expand Down Expand Up @@ -36,6 +36,9 @@ export class ComboSelector extends LitElement {

const filteredItems = (): SelectOption[] => {
let options: (string | SelectOption)[] = [...config?.options];
let selectedValue = [this.value || []].flat().map(String);
options = [...options, ...selectedValue.filter(e => !options.find(f => typeof f === 'object' ? f.value == e : f == e))];

if (Array.isArray(this.value)) options = options.filter(e => typeof e === 'object' ? !values.includes(e.value) : !values.includes(e));

const computeItemLabel = (value: string) => {
Expand All @@ -53,12 +56,12 @@ export class ComboSelector extends LitElement {
}

return html`
<div class="select-wrapper">
${config.multiple ? html`
<div class="chips">
${renderChips()}
</div>
`
: ''}
` : ''}
<ha-combo-box
.hass=${this.hass}
label=""
Expand All @@ -72,22 +75,42 @@ export class ComboSelector extends LitElement {
?allow-custom-value=${config.custom_value}
>
</ha-combo-box>
</div>
`;
}
else if ((this.config as NumberSelector).number) {
const config = (this.config as NumberSelector).number!;
let min = config.min || 0;
let max = config.max || 255;
let value = typeof this.value == 'number' ? this.value : min;

if (typeof config.scale_factor == 'number') value = parseFloat((value / config.scale_factor).toPrecision(12));
if (typeof config?.step === 'number') value = Math.round(value / config.step) * config.step;

const valueChanged = (ev: Event) => {
let value = Number((ev.target as HTMLInputElement).value);

if (typeof config.scale_factor == 'number')
value = value * config.scale_factor;

if (typeof config?.step === 'number') value = Math.round(value / config.step) * config.step;
value = parseFloat(value.toFixed(2));

this._valueChanged(new CustomEvent('value-changed', { detail: { value: value } }));
}

return html`
<div class="slider-wrapper">
<ha-slider
labeled
.min=${config.min}
.max=${config.max}
.step=${config.step}
.value=${this.value || config.min}
@change=${this._valueChanged}
.min=${min}
.max=${max}
.step=${config.step || 1}
.value=${value}
@change=${valueChanged}
?disabled=${this.disabled}
></ha-slider>
<span class="value">${this.value || config.min}${config.unit_of_measurement || ''}</span>
<span class="value">${value}${config.unit_of_measurement || ''}</span>
</div>
`
}
Expand All @@ -106,19 +129,32 @@ export class ComboSelector extends LitElement {
}

static styles = css`
:host {
display: flex;
width: 100%;
}
div.slider-wrapper {
display: flex;
flex-direction: row;
width: 100%;
}
div.slider-wrapper > * {
display: flex;
}
div.slider-wrapper ha-slider {
flex: 1;
}
div.slider-wrapper span {
justify-content: center;
align-self: center;
min-width: 45px;
text-align: end;
}
div.select-wrapper {
display: flex;
flex-direction: column;
width: 100%;
}
div.chip {
height: 32px;
border-radius: 16px;
Expand Down
35 changes: 20 additions & 15 deletions src/components/entity-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { sortByName } from "../lib/sort";
import { matchPattern } from "../lib/patterns";
import { HomeAssistant } from "../lib/types";
import { fireEvent } from "../lib/fire_event";
import { mdiExpandAll, mdiMinus, mdiPlus, mdiUnfoldLessHorizontal, mdiUnfoldLessVertical, mdiUnfoldMoreHorizontal, mdiUnfoldMoreVertical } from "@mdi/js";
import { mdiUnfoldLessHorizontal, mdiUnfoldMoreHorizontal } from "@mdi/js";

interface TRowItem {
entity_id: string;
Expand Down Expand Up @@ -60,7 +60,6 @@ export class SchedulerEntityPicker extends LitElement {
@filter-changed=${this._filterChanged}
@value-changed=${this._valueChanged}
.value=${this.value || ""}
allow-custom-value
>
</ha-combo-box>
</div>
Expand All @@ -74,12 +73,12 @@ export class SchedulerEntityPicker extends LitElement {
const stateObj = this.hass.states[entityId];
return html`
<div class="chip">
<ha-state-icon
.stateObj=${stateObj}
.hass=${this.hass}
></ha-state-icon>
${stateObj
? html`<ha-state-icon .stateObj=${stateObj} .hass=${this.hass} class="icon"></ha-state-icon>`
: html`<ha-icon icon="mdi:help-circle-outline" class="icon"></ha-icon>`
}
<span class="label">${friendlyName(entityId, this.hass.states[entityId]?.attributes)}</span>
<ha-icon icon="mdi:close" @click=${() => this._removeValue(entityId)} ></ha-icon>
<ha-icon icon="mdi:close" @click=${() => this._removeValue(entityId)} class="marker"></ha-icon>
</div>
`;
}
Expand All @@ -94,11 +93,10 @@ export class SchedulerEntityPicker extends LitElement {
rowRenderer = (item: HassEntityWithCachedName) =>
html`
<mwc-list-item graphic="avatar" twoline>
<state-badge
slot="graphic"
.stateObj=${item}
.hass=${this.hass}
></state-badge>
${item.state
? html`<state-badge slot="graphic" .stateObj=${item} .hass=${this.hass} color="var(--icon-primary-color)"></state-badge>`
: html`<ha-icon slot="graphic" icon="mdi:help-circle-outline"></ha-icon>`
}
<span>${item.friendly_name}</span>
<span slot="secondary">${item.entity_id}</span>
</mwc-list-item>
Expand Down Expand Up @@ -145,7 +143,7 @@ export class SchedulerEntityPicker extends LitElement {
entityIds = [...entityIds, this.initialValue];
}

let entities: HassEntityWithCachedName[] = entityIds.map(e => Object({ ...this.hass.states[e], friendly_name: friendlyName(e, this.hass.states[e]?.attributes) }));
let entities: HassEntityWithCachedName[] = entityIds.map(e => Object({ ...this.hass.states[e], entity_id: e, friendly_name: friendlyName(e, this.hass.states[e]?.attributes) }));
entities.sort((a, b) => sortByName(a.friendly_name, b.friendly_name));
return entities;
}
Expand All @@ -170,6 +168,13 @@ export class SchedulerEntityPicker extends LitElement {
}

static styles = css`
:host {
display: flex;
flex-direction: column;
}
div.chips {
flex: 1 0 auto;
}
div.chip {
height: 32px;
border-radius: 16px;
Expand All @@ -183,7 +188,7 @@ export class SchedulerEntityPicker extends LitElement {
box-sizing: border-box;
margin: 4px;
}
div.chip ha-state-icon {
div.chip .icon {
vertical-align: middle;
outline: none;
display: flex;
Expand All @@ -198,7 +203,7 @@ export class SchedulerEntityPicker extends LitElement {
div.chip .label {
margin: 0px 4px;
}
div.chip ha-icon {
div.chip .marker {
cursor: pointer;
background: var(--secondary-text-color);
border-radius: 50%;
Expand Down
24 changes: 22 additions & 2 deletions src/components/item-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { computeActionIcon } from "../data/format/compute_action_icon";
import { HomeAssistant } from "../lib/types";
import { computeScheduleDisplay } from "../data/format/compute_schedule_display";

import './scheduler-relative-time';

@customElement("schedule-item-row")
export class ScheduleItemRow extends LitElement {

Expand All @@ -15,12 +17,13 @@ export class ScheduleItemRow extends LitElement {

render() {
const stateObj = this.hass.states[this.schedule.entity_id!];
if (!stateObj) return html``;
const disabled = stateObj.state == 'off';
const nextAction = this.schedule.entries[0].slots[this.schedule.next_entries![0]].actions[0];
const nextAction = this.schedule.entries[0].slots[this.schedule.next_entries[0] || 0].actions[0];

return html`
<ha-icon
icon="${computeActionIcon(nextAction, this.hass)}"
icon="${computeActionIcon(nextAction, this.config.customize)}"
>
</ha-icon>
Expand Down Expand Up @@ -111,6 +114,23 @@ export class ScheduleItemRow extends LitElement {
--state-icon-color: var(--disabled-text-color);
color: var(--disabled-text-color);
}
div.tags {
display: flex;
gap: 5px;
flex-wrap: wrap;
}
span.tag {
height: 28px;
border-radius: 14px;
background: rgba(var(--rgb-primary-color), 0.40);
color: var(--primary-text-color);
line-height: 1.25rem;
font-size: 0.875rem;
padding: 0px 12px;
display: flex;
align-items: center;
box-sizing: border-box;
}
`;
}
}
Loading

0 comments on commit 3ec525b

Please sign in to comment.