Add bulk enable invite access to user directory
This commit is contained in:
@@ -15,6 +15,7 @@ type AdminUser = {
|
||||
lastLoginAt?: string | null
|
||||
isBlocked?: boolean
|
||||
autoSearchEnabled?: boolean
|
||||
inviteManagementEnabled?: boolean
|
||||
profileId?: number | null
|
||||
expiresAt?: string | null
|
||||
isExpired?: boolean
|
||||
@@ -88,6 +89,8 @@ export default function UsersPage() {
|
||||
const [jellyseerrSyncBusy, setJellyseerrSyncBusy] = useState(false)
|
||||
const [jellyseerrResyncBusy, setJellyseerrResyncBusy] = useState(false)
|
||||
const [bulkAutoSearchBusy, setBulkAutoSearchBusy] = useState(false)
|
||||
const [bulkInvitesBusy, setBulkInvitesBusy] = useState(false)
|
||||
const [inviteStatus, setInviteStatus] = useState<string | null>(null)
|
||||
|
||||
const loadUsers = async () => {
|
||||
try {
|
||||
@@ -116,6 +119,7 @@ export default function UsersPage() {
|
||||
lastLoginAt: user.last_login_at ?? null,
|
||||
isBlocked: Boolean(user.is_blocked),
|
||||
autoSearchEnabled: Boolean(user.auto_search_enabled ?? true),
|
||||
inviteManagementEnabled: Boolean(user.invite_management_enabled),
|
||||
profileId:
|
||||
user.profile_id == null || Number.isNaN(Number(user.profile_id))
|
||||
? null
|
||||
@@ -192,6 +196,25 @@ export default function UsersPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const enableInvitesForEveryone = async () => {
|
||||
if (bulkInvitesBusy || !window.confirm('Enable invite access for all existing non-admin users, including users outside the current search? Existing invite limits, account blocks and expiry dates will not change.')) return
|
||||
setBulkInvitesBusy(true)
|
||||
setInviteStatus(null)
|
||||
try {
|
||||
const response = await authFetch(`${getApiBase()}/admin/users/invite-access/bulk`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled: true }),
|
||||
})
|
||||
if (!response.ok) throw new Error('Invite access update failed')
|
||||
const data = await response.json()
|
||||
setInviteStatus(`Invite access enabled for ${data.updated ?? 0} non-admin accounts. Existing limits are unchanged.`)
|
||||
await loadUsers()
|
||||
} catch {
|
||||
setInviteStatus('Could not enable invites. Please reload the list to check the current permissions, then try again.')
|
||||
} finally { setBulkInvitesBusy(false) }
|
||||
}
|
||||
|
||||
const bulkUpdateAutoSearch = async (enabled: boolean) => {
|
||||
setBulkAutoSearchBusy(true)
|
||||
setJellyseerrSyncStatus(null)
|
||||
@@ -233,6 +256,7 @@ export default function UsersPage() {
|
||||
|
||||
const nonAdminUsers = users.filter((user) => user.role !== 'admin')
|
||||
const autoSearchEnabledCount = nonAdminUsers.filter((user) => user.autoSearchEnabled !== false).length
|
||||
const inviteEnabledCount = nonAdminUsers.filter((user) => user.inviteManagementEnabled).length
|
||||
const blockedCount = users.filter((user) => user.isBlocked).length
|
||||
const expiredCount = users.filter((user) => user.isExpired).length
|
||||
const adminCount = users.filter((user) => user.role === 'admin').length
|
||||
@@ -348,7 +372,7 @@ export default function UsersPage() {
|
||||
<div>
|
||||
<h2>Bulk controls</h2>
|
||||
<p className="lede">
|
||||
Auto search/download can be enabled or disabled for all non-admin users.
|
||||
Manage permissions for all existing non-admin users, not just the current search results.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -378,6 +402,21 @@ export default function UsersPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-panel user-directory-bulk-panel">
|
||||
<div className="user-bulk-toolbar">
|
||||
<div className="user-bulk-summary">
|
||||
<strong>Invite access</strong>
|
||||
<span>{inviteEnabledCount} of {nonAdminUsers.length} non-admin users enabled</span>
|
||||
<span>Admins already have access. Existing invite limits, blocked accounts and expiry dates stay unchanged.</span>
|
||||
</div>
|
||||
<div className="user-bulk-actions">
|
||||
<button type="button" onClick={enableInvitesForEveryone} disabled={bulkInvitesBusy || nonAdminUsers.length === 0 || inviteEnabledCount === nonAdminUsers.length}>
|
||||
{bulkInvitesBusy ? 'Enabling invites...' : inviteEnabledCount === nonAdminUsers.length && nonAdminUsers.length > 0 ? 'Invites enabled for everyone' : 'Enable invites for all users'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{inviteStatus && <p role="status">{inviteStatus}</p>}
|
||||
</div>
|
||||
<div className="admin-panel user-directory-search-panel">
|
||||
<div className="user-directory-panel-header">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user