diff --git a/src/data/user.ts b/src/data/user.ts
index bd35ff1896..ea295dc6db 100644
--- a/src/data/user.ts
+++ b/src/data/user.ts
@@ -9,6 +9,7 @@ export const GROUPS = [SYSTEM_GROUP_ID_USER, SYSTEM_GROUP_ID_ADMIN];
export interface User {
id: string;
+ username: string | null;
name: string;
is_owner: boolean;
is_active: boolean;
diff --git a/src/panels/config/users/dialog-add-user.ts b/src/panels/config/users/dialog-add-user.ts
index 7d291e9307..f88d4a476a 100644
--- a/src/panels/config/users/dialog-add-user.ts
+++ b/src/panels/config/users/dialog-add-user.ts
@@ -98,7 +98,7 @@ export class DialogAddUser extends LitElement {
class="name"
name="name"
.label=${this.hass.localize(
- "ui.panel.config.users.add_user.name"
+ "ui.panel.config.users.editor.name"
)}
.value=${this._name}
required
@@ -113,7 +113,7 @@ export class DialogAddUser extends LitElement {
class="username"
name="username"
.label=${this.hass.localize(
- "ui.panel.config.users.add_user.username"
+ "ui.panel.config.users.editor.username"
)}
.value=${this._username}
required
@@ -259,6 +259,7 @@ export class DialogAddUser extends LitElement {
return;
}
+ user.username = this._username;
this._params!.userAddedCallback(user);
this._close();
}
diff --git a/src/panels/config/users/dialog-user-detail.ts b/src/panels/config/users/dialog-user-detail.ts
index e773364652..d46a4cf24b 100644
--- a/src/panels/config/users/dialog-user-detail.ts
+++ b/src/panels/config/users/dialog-user-detail.ts
@@ -67,7 +67,10 @@ class DialogUserDetail extends LitElement {
${this._error ? html`
${this._error}
` : ""}
- ${this.hass.localize("ui.panel.config.users.editor.id")}: ${user.id}
+ ${this.hass.localize("ui.panel.config.users.editor.id")}:
+ ${user.id}
+ ${this.hass.localize("ui.panel.config.users.editor.username")}:
+ ${user.username}
${user.is_owner
diff --git a/src/panels/config/users/ha-config-users.ts b/src/panels/config/users/ha-config-users.ts
index 496d634200..c870804c7f 100644
--- a/src/panels/config/users/ha-config-users.ts
+++ b/src/panels/config/users/ha-config-users.ts
@@ -35,14 +35,15 @@ export class HaConfigUsers extends LitElement {
@property() public route!: Route;
private _columns = memoizeOne(
- (_language): DataTableColumnContainer => {
- return {
+ (narrow: boolean, _language): DataTableColumnContainer => {
+ const columns: DataTableColumnContainer = {
name: {
title: this.hass.localize(
"ui.panel.config.users.picker.headers.name"
),
sortable: true,
filterable: true,
+ width: "25%",
direction: "asc",
grows: true,
template: (name) => html`
@@ -50,32 +51,45 @@ export class HaConfigUsers extends LitElement {
this.hass!.localize("ui.panel.config.users.editor.unnamed_user")}
`,
},
+ username: {
+ title: this.hass.localize(
+ "ui.panel.config.users.picker.headers.username"
+ ),
+ sortable: true,
+ filterable: true,
+ width: "20%",
+ direction: "asc",
+ template: (username) => html`
+ ${username ||
+ this.hass!.localize("ui.panel.config.users.editor.unnamed_user")}
+ `,
+ },
group_ids: {
title: this.hass.localize(
"ui.panel.config.users.picker.headers.group"
),
sortable: true,
filterable: true,
- width: "30%",
+ width: "20%",
template: (groupIds) => html`
${this.hass.localize(`groups.${groupIds[0]}`)}
`,
},
- system_generated: {
+ };
+ if (!narrow) {
+ columns.system_generated = {
title: this.hass.localize(
"ui.panel.config.users.picker.headers.system"
),
type: "icon",
- width: "80px",
sortable: true,
filterable: true,
- template: (generated) => html`
- ${generated
- ? html` `
- : ""}
- `,
- },
- };
+ width: "160px",
+ template: (generated) =>
+ generated ? html` ` : "",
+ };
+ }
+ return columns;
}
);
@@ -92,7 +106,7 @@ export class HaConfigUsers extends LitElement {
.route=${this.route}
backPath="/config"
.tabs=${configSections.persons}
- .columns=${this._columns(this.hass.language)}
+ .columns=${this._columns(this.narrow, this.hass.language)}
.data=${this._users}
@row-click=${this._editUser}
hasFab
@@ -112,6 +126,12 @@ export class HaConfigUsers extends LitElement {
private async _fetchUsers() {
this._users = await fetchUsers(this.hass);
+
+ this._users.forEach(function (user) {
+ if (user.is_owner) {
+ user.group_ids.unshift("owner");
+ }
+ });
}
private _editUser(ev: HASSDomEvent) {
diff --git a/src/translations/en.json b/src/translations/en.json
index f3fb442eac..df894c5333 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -89,6 +89,7 @@
}
},
"groups": {
+ "owner": "Owner",
"system-admin": "Administrators",
"system-users": "Users",
"system-read-only": "Read-Only Users"
@@ -1991,15 +1992,19 @@
"users_privileges_note": "The user group feature is a work in progress. The user will be unable to administer the instance via the UI. We're still auditing all management API endpoints to ensure that they correctly limit access to administrators.",
"picker": {
"headers": {
- "name": "Name",
+ "name": "Display name",
+ "username": "Username",
"group": "Group",
- "system": "System"
+ "system": "System generated",
+ "is_active": "Active",
+ "is_owner": "Owner"
},
"add_user": "Add user"
},
"editor": {
"caption": "View user",
- "name": "Name",
+ "name": "Display name",
+ "username": "Username",
"change_password": "Change password",
"new_password": "New Password",
"password_changed": "Password was changed successfully",
@@ -2020,8 +2025,6 @@
},
"add_user": {
"caption": "Add user",
- "name": "Name",
- "username": "Username",
"password": "Password",
"password_confirm": "Confirm Password",
"password_not_match": "Passwords don't match",