-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add user condition to conditional card (#18265)
* Add user condition to conditional card * Refactor user fetch * Add validate ui * Use ha-check-list-item
- Loading branch information
Showing
5 changed files
with
162 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import { mdiResponsive, mdiStateMachine } from "@mdi/js"; | ||
import { mdiAccount, mdiResponsive, mdiStateMachine } from "@mdi/js"; | ||
import { Condition } from "./validate-condition"; | ||
|
||
export const ICON_CONDITION: Record<Condition["condition"], string> = { | ||
state: mdiStateMachine, | ||
screen: mdiResponsive, | ||
user: mdiAccount, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
src/panels/lovelace/editor/conditions/types/ha-card-condition-user.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import "@material/mwc-list"; | ||
import { LitElement, PropertyValues, css, html } from "lit"; | ||
import { customElement, property, state } from "lit/decorators"; | ||
import memoizeOne from "memoize-one"; | ||
import { array, assert, literal, object, string } from "superstruct"; | ||
import { fireEvent } from "../../../../../common/dom/fire_event"; | ||
import { stringCompare } from "../../../../../common/string/compare"; | ||
import "../../../../../components/ha-check-list-item"; | ||
import "../../../../../components/ha-switch"; | ||
import "../../../../../components/user/ha-user-badge"; | ||
import { User, fetchUsers } from "../../../../../data/user"; | ||
import type { HomeAssistant } from "../../../../../types"; | ||
import { UserCondition } from "../../../common/validate-condition"; | ||
|
||
const userConditionStruct = object({ | ||
condition: literal("user"), | ||
users: array(string()), | ||
}); | ||
|
||
@customElement("ha-card-condition-user") | ||
export class HaCardConditionUser extends LitElement { | ||
@property({ attribute: false }) public hass!: HomeAssistant; | ||
|
||
@property({ attribute: false }) public condition!: UserCondition; | ||
|
||
@property({ type: Boolean }) public disabled = false; | ||
|
||
public static get defaultConfig(): UserCondition { | ||
return { condition: "user", users: [] }; | ||
} | ||
|
||
@state() private _users: User[] = []; | ||
|
||
protected static validateUIConfig(condition: UserCondition) { | ||
return assert(condition, userConditionStruct); | ||
} | ||
|
||
private _sortedUsers = memoizeOne((users: User[]) => | ||
users.sort((a, b) => | ||
stringCompare(a.name, b.name, this.hass.locale.language) | ||
) | ||
); | ||
|
||
protected async firstUpdated(changedProps: PropertyValues) { | ||
super.firstUpdated(changedProps); | ||
this._fetchUsers(); | ||
} | ||
|
||
private async _fetchUsers() { | ||
const users = await fetchUsers(this.hass); | ||
this._users = users.filter((user) => !user.system_generated); | ||
} | ||
|
||
protected render() { | ||
const selectedUsers = this.condition.users ?? []; | ||
|
||
return html` | ||
<mwc-list> | ||
${this._sortedUsers(this._users).map( | ||
(user) => html` | ||
<ha-check-list-item | ||
graphic="avatar" | ||
hasMeta | ||
.userId=${user.id} | ||
.selected=${selectedUsers.includes(user.id)} | ||
@request-selected=${this._userChanged} | ||
> | ||
<ha-user-badge | ||
slot="graphic" | ||
.hass=${this.hass} | ||
.user=${user} | ||
></ha-user-badge> | ||
<span>${user.name}</span> | ||
</ha-check-list-item> | ||
` | ||
)} | ||
</mwc-list> | ||
`; | ||
} | ||
|
||
private _userChanged(ev) { | ||
ev.stopPropagation(); | ||
const selectedUsers = this.condition.users ?? []; | ||
const userId = ev.currentTarget.userId as string; | ||
const checked = ev.detail.selected as boolean; | ||
|
||
if (checked === selectedUsers.includes(userId)) { | ||
return; | ||
} | ||
|
||
let users = selectedUsers; | ||
if (checked) { | ||
users = [...users, userId]; | ||
} else { | ||
users = users.filter((user) => user !== userId); | ||
} | ||
|
||
const condition: UserCondition = { | ||
...this.condition, | ||
users, | ||
}; | ||
|
||
fireEvent(this, "value-changed", { value: condition }); | ||
} | ||
|
||
static get styles() { | ||
return css` | ||
:host { | ||
display: block; | ||
} | ||
mwc-list { | ||
--mdc-list-vertical-padding: 0; | ||
} | ||
`; | ||
} | ||
} | ||
|
||
declare global { | ||
interface HTMLElementTagNameMap { | ||
"ha-card-condition-user": HaCardConditionUser; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters