Add checked item section to shopping-list-card (#2005)

* Add checked item section to shopping-list-card

* Not getting value back from `this.localize`? at line 109

* Alignment of label

* Address review comment

* Address review comments

* Address review comment and fix Travis errors

* Address review comments

* Hide checked label when empty

* Address review comment
This commit is contained in:
Ian Richardson 2018-11-09 03:13:44 -06:00 committed by Paulus Schoutsen
parent cb640c2e71
commit 9c2b85dd6e
2 changed files with 87 additions and 21 deletions

View File

@ -22,40 +22,36 @@ interface Config extends LovelaceConfig {
class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement) class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
implements LovelaceCard { implements LovelaceCard {
private _hass?: HomeAssistant; public hass?: HomeAssistant;
private _config?: Config; private _config?: Config;
private _items?: ShoppingListItem[]; private _uncheckedItems?: ShoppingListItem[];
private _checkedItems?: ShoppingListItem[];
private _unsubEvents?: Promise<() => Promise<void>>; private _unsubEvents?: Promise<() => Promise<void>>;
static get properties() { static get properties() {
return { return {
_config: {}, _config: {},
_items: {}, _uncheckedItems: {},
_checkedItems: {},
}; };
} }
set hass(hass: HomeAssistant) {
this._hass = hass;
}
public getCardSize(): number { public getCardSize(): number {
return ( return (this._config ? (this._config.title ? 1 : 0) : 0) + 3;
(this._config ? (this._config.title ? 1 : 0) : 0) +
(this._items ? this._items.length : 3)
);
} }
public setConfig(config: Config): void { public setConfig(config: Config): void {
this._config = config; this._config = config;
this._items = []; this._uncheckedItems = [];
this._checkedItems = [];
this._fetchData(); this._fetchData();
} }
public connectedCallback(): void { public connectedCallback(): void {
super.connectedCallback(); super.connectedCallback();
if (this._hass) { if (this.hass) {
this._unsubEvents = this._hass.connection.subscribeEvents( this._unsubEvents = this.hass.connection.subscribeEvents(
() => this._fetchData(), () => this._fetchData(),
"shopping_list_updated" "shopping_list_updated"
); );
@ -72,7 +68,7 @@ class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this._config || !this._hass) { if (!this._config || !this.hass) {
return html``; return html``;
} }
@ -81,7 +77,7 @@ class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
<ha-card .header="${this._config.title}"> <ha-card .header="${this._config.title}">
${ ${
repeat( repeat(
this._items!, this._uncheckedItems!,
(item) => item.id, (item) => item.id,
(item, index) => (item, index) =>
html` html`
@ -97,7 +93,7 @@ class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
<paper-item-body> <paper-item-body>
<paper-input <paper-input
no-label-float no-label-float
.value="${item.name}" value="${item.name}"
.itemId="${item.id}" .itemId="${item.id}"
@change="${this._saveEdit}" @change="${this._saveEdit}"
></paper-input> ></paper-input>
@ -106,6 +102,47 @@ class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
` `
) )
} }
${
this._checkedItems!.length > 0
? html`
<div class="divider"></div>
<div class="label">
${
this.localize(
"ui.panel.lovelace.cards.shopping-list.checked_items"
)
}
</div>
${
repeat(
this._checkedItems!,
(item) => item.id,
(item, index) =>
html`
<div class="editRow">
<paper-checkbox
slot="item-icon"
id="${index}"
?checked="${item.complete}"
.itemId="${item.id}"
@click="${this._completeItem}"
tabindex="0"
></paper-checkbox>
<paper-item-body>
<paper-input
no-label-float
value="${item.name}"
.itemId="${item.id}"
@change="${this._saveEdit}"
></paper-input>
</paper-item-body>
</div>
`
)
}
`
: ""
}
</ha-card> </ha-card>
`; `;
} }
@ -133,24 +170,46 @@ class HuiShoppingListCard extends hassLocalizeLitMixin(LitElement)
position: relative; position: relative;
top: 1px; top: 1px;
} }
.label {
color: var(--primary-color);
margin-left: 17px;
margin-bottom: 11px;
margin-top: 11px;
}
.divider {
height: 1px;
background-color: var(--divider-color);
margin: 10px;
}
</style> </style>
`; `;
} }
private async _fetchData(): Promise<void> { private async _fetchData(): Promise<void> {
if (this._hass) { if (this.hass) {
this._items = await fetchItems(this._hass); const checkedItems: ShoppingListItem[] = [];
const uncheckedItems: ShoppingListItem[] = [];
const items = await fetchItems(this.hass);
for (const key in items) {
if (items[key].complete) {
checkedItems.push(items[key]);
} else {
uncheckedItems.push(items[key]);
}
}
this._checkedItems = checkedItems;
this._uncheckedItems = uncheckedItems;
} }
} }
private _completeItem(ev): void { private _completeItem(ev): void {
completeItem(this._hass!, ev.target.itemId, ev.target.checked).catch(() => completeItem(this.hass!, ev.target.itemId, ev.target.checked).catch(() =>
this._fetchData() this._fetchData()
); );
} }
private _saveEdit(ev): void { private _saveEdit(ev): void {
saveEdit(this._hass!, ev.target.itemId, ev.target.value).catch(() => saveEdit(this.hass!, ev.target.itemId, ev.target.value).catch(() =>
this._fetchData() this._fetchData()
); );

View File

@ -757,6 +757,13 @@
"logbook": { "logbook": {
"showing_entries": "[%key:ui::panel::history::showing_entries%]" "showing_entries": "[%key:ui::panel::history::showing_entries%]"
}, },
"lovelace": {
"cards": {
"shopping-list": {
"checked_items": "Checked items"
}
}
},
"mailbox": { "mailbox": {
"empty": "You do not have any messages", "empty": "You do not have any messages",
"playback_title": "Message playback", "playback_title": "Message playback",