feat: admin controls

This commit is contained in:
Zoe
2026-10-15 10:07:41 -05:00
parent b6f4d85ed7
commit ff7797d3f8
41 changed files with 612 additions and 427 deletions
+8 -10
View File
@@ -131,7 +131,7 @@ const setRole = (user: UserRow, role: 'admin' | 'user') => {
confirmThen({
title: `Make ${user.name} an admin?`,
message: 'Admins can create, disable and delete accounts, change roles and change who can register. They never see anyone else\'s chats, files or API keys.',
message: 'Admins can create, disable and delete accounts, change roles and change who can register.',
confirmLabel: 'Make admin',
}, change);
};
@@ -141,8 +141,6 @@ const signOutEverywhere = (user: UserRow) => run(user, `${user.name} could not b
return !error;
});
// The dialog makes the link and shows it, nothing in the list changes. For an
// account that has no password yet it is a new setup link instead.
const recoverAccount = (user: UserRow) => {
openDialog(DialogType.RecoverAccount, undefined, { user });
};
@@ -268,9 +266,11 @@ const openCreateUser = () => {
<span class="flex flex-col min-w-0">
<span class="font-medium whitespace-nowrap overflow-hidden text-ellipsis">
{{ u.name }}
<span v-if="u.id === me?.id" class="font-normal text-[var(--text-secondary)]">(you)</span>
<span v-if="u.id === me?.id"
class="font-normal text-[var(--text-secondary)]">(you)</span>
</span>
<span class="text-xs text-[var(--text-secondary)] whitespace-nowrap overflow-hidden text-ellipsis">
<span
class="text-xs text-[var(--text-secondary)] whitespace-nowrap overflow-hidden text-ellipsis">
{{ u.email }}
</span>
</span>
@@ -308,7 +308,6 @@ const openCreateUser = () => {
<span class="i-svg-spinners-180-ring-with-bg text-4 text-[var(--text-secondary)]"></span>
</span>
<!-- your own account is managed from Profile and Security -->
<Dropdown v-else-if="u.id !== me?.id" placement="bottom-end" dropdownClass="w-60">
<template #default="{ setRef, isOpen, toggle }">
<button :ref="setRef" type="button" :aria-label="`Actions for ${u.name}`"
@@ -376,10 +375,9 @@ const openCreateUser = () => {
</div>
<p class="mt-4 max-w-190 text-[13px] leading-relaxed text-[var(--text-secondary)]">
Admins manage accounts, not content: chats, agents, files and API keys of other users are never
shown here. Invited accounts have no password until their owner opens the setup link. Disabled
accounts can't sign in and nothing of theirs is deleted. Your own account is
managed from Profile and Security, and you can't remove your own admin role.
Invited accounts have no password until their owner opens the setup link.
you manage your account from Profile and Security, you can't remove
your own admin role.
</p>
</div>
</template>