{
const target = ev.target;
if (target.checked) {
@@ -281,6 +301,7 @@ class DialogPersonDetail extends LitElement {
this._user = user;
this._userId = user.id;
this._isAdmin = user.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
+ this._localOnly = user.local_only;
this._params?.refreshUsers();
}
},
@@ -373,13 +394,16 @@ class DialogPersonDetail extends LitElement {
try {
if (
(this._userId && this._name !== this._params!.entry?.name) ||
- this._isAdmin !== this._user?.group_ids.includes(SYSTEM_GROUP_ID_ADMIN)
+ this._isAdmin !==
+ this._user?.group_ids.includes(SYSTEM_GROUP_ID_ADMIN) ||
+ this._localOnly !== this._user?.local_only
) {
await updateUser(this.hass!, this._userId!, {
name: this._name.trim(),
group_ids: [
this._isAdmin ? SYSTEM_GROUP_ID_ADMIN : SYSTEM_GROUP_ID_USER,
],
+ local_only: this._localOnly,
});
this._params?.refreshUsers();
}
diff --git a/src/panels/config/users/dialog-add-user.ts b/src/panels/config/users/dialog-add-user.ts
index 462dd46fde..65d11ac262 100644
--- a/src/panels/config/users/dialog-add-user.ts
+++ b/src/panels/config/users/dialog-add-user.ts
@@ -48,6 +48,8 @@ export class DialogAddUser extends LitElement {
@state() private _isAdmin?: boolean;
+ @state() private _localOnly?: boolean;
+
@state() private _allowChangeName = true;
public showDialog(params: AddUserDialogParams) {
@@ -57,6 +59,7 @@ export class DialogAddUser extends LitElement {
this._password = "";
this._passwordConfirm = "";
this._isAdmin = false;
+ this._localOnly = false;
this._error = undefined;
this._loading = false;
@@ -153,14 +156,32 @@ export class DialogAddUser extends LitElement {
"ui.panel.config.users.add_user.password_not_match"
)}
>
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
${!this._isAdmin
? html`
@@ -218,6 +239,10 @@ export class DialogAddUser extends LitElement {
this._isAdmin = ev.target.checked;
}
+ private _localOnlyChanged(ev): void {
+ this._localOnly = ev.target.checked;
+ }
+
private async _createUser(ev) {
ev.preventDefault();
if (!this._name || !this._username || !this._password) {
@@ -229,9 +254,12 @@ export class DialogAddUser extends LitElement {
let user: User;
try {
- const userResponse = await createUser(this.hass, this._name, [
- this._isAdmin ? SYSTEM_GROUP_ID_ADMIN : SYSTEM_GROUP_ID_USER,
- ]);
+ const userResponse = await createUser(
+ this.hass,
+ this._name,
+ [this._isAdmin ? SYSTEM_GROUP_ID_ADMIN : SYSTEM_GROUP_ID_USER],
+ this._localOnly
+ );
user = userResponse.user;
} catch (err: any) {
this._loading = false;
@@ -266,8 +294,9 @@ export class DialogAddUser extends LitElement {
--mdc-dialog-max-width: 500px;
--dialog-z-index: 10;
}
- ha-switch {
- margin-top: 8px;
+ .row {
+ display: flex;
+ padding: 8px 0;
}
`,
];
diff --git a/src/panels/config/users/dialog-user-detail.ts b/src/panels/config/users/dialog-user-detail.ts
index f90f9c979d..3809131a65 100644
--- a/src/panels/config/users/dialog-user-detail.ts
+++ b/src/panels/config/users/dialog-user-detail.ts
@@ -30,6 +30,8 @@ class DialogUserDetail extends LitElement {
@state() private _isAdmin?: boolean;
+ @state() private _localOnly?: boolean;
+
@state() private _isActive?: boolean;
@state() private _error?: string;
@@ -43,6 +45,7 @@ class DialogUserDetail extends LitElement {
this._error = undefined;
this._name = params.entry.name || "";
this._isAdmin = params.entry.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
+ this._localOnly = params.entry.local_only;
this._isActive = params.entry.is_active;
await this.updateComplete;
}
@@ -95,6 +98,20 @@ class DialogUserDetail extends LitElement {
@value-changed=${this._nameChanged}
label=${this.hass!.localize("ui.panel.config.users.editor.name")}
>
+
+
+
+
+
+
{
+ private _adminChanged(ev): void {
this._isAdmin = ev.target.checked;
}
- private async _activeChanged(ev): Promise {
+ private _localOnlyChanged(ev): void {
+ this._localOnly = ev.target.checked;
+ }
+
+ private _activeChanged(ev): void {
this._isActive = ev.target.checked;
}
@@ -215,6 +236,7 @@ class DialogUserDetail extends LitElement {
group_ids: [
this._isAdmin ? SYSTEM_GROUP_ID_ADMIN : SYSTEM_GROUP_ID_USER,
],
+ local_only: this._localOnly,
});
this._close();
} catch (err: any) {
diff --git a/src/panels/config/users/ha-config-users.ts b/src/panels/config/users/ha-config-users.ts
index 84b0ca9f11..dfff21062c 100644
--- a/src/panels/config/users/ha-config-users.ts
+++ b/src/panels/config/users/ha-config-users.ts
@@ -90,7 +90,7 @@ export class HaConfigUsers extends LitElement {
width: "80px",
template: (is_active) =>
is_active
- ? html` `
+ ? html``
: "",
},
system_generated: {
@@ -103,9 +103,20 @@ export class HaConfigUsers extends LitElement {
width: "160px",
template: (generated) =>
generated
- ? html` `
+ ? html``
: "",
},
+ local_only: {
+ title: this.hass.localize(
+ "ui.panel.config.users.picker.headers.local"
+ ),
+ type: "icon",
+ sortable: true,
+ filterable: true,
+ width: "160px",
+ template: (local) =>
+ local ? html`` : "",
+ },
};
return columns;
diff --git a/src/translations/en.json b/src/translations/en.json
index bd2574bde1..b6c5d18cd8 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2297,6 +2297,7 @@
"update": "Update",
"confirm_delete_user": "Are you sure you want to delete the user account for {name}? You can still track the user, but the person will no longer be able to login.",
"admin": "[%key:ui::panel::config::users::editor::admin%]",
+ "local_only": "[%key:ui::panel::config::users::editor::local_only%]",
"allow_login": "Allow person to login"
}
},
@@ -2456,7 +2457,8 @@
"group": "Group",
"system": "System generated",
"is_active": "Active",
- "is_owner": "Owner"
+ "is_owner": "Owner",
+ "local": "Local only"
},
"add_user": "Add user"
},
@@ -2476,6 +2478,7 @@
"admin": "Administrator",
"group": "Group",
"active": "Active",
+ "local_only": "Can only login from the local network",
"system_generated": "System generated",
"system_generated_users_not_removable": "Unable to remove system generated users.",
"system_generated_users_not_editable": "Unable to update system generated users.",
@@ -2488,6 +2491,7 @@
"password": "Password",
"password_confirm": "Confirm Password",
"password_not_match": "Passwords don't match",
+ "local_only": "Local only",
"create": "Create"
}
},