feat: add monitor-ai permissions to user management page
This commit is contained in:
parent
b851fbbda8
commit
727269c877
|
|
@ -33,8 +33,10 @@ export default function AdminUsersPage() {
|
||||||
const [email, setEmail] = useState('')
|
const [email, setEmail] = useState('')
|
||||||
const [assetsRole, setAssetsRole] = useState('viewer')
|
const [assetsRole, setAssetsRole] = useState('viewer')
|
||||||
const [issueRole, setIssueRole] = useState('viewer')
|
const [issueRole, setIssueRole] = useState('viewer')
|
||||||
|
const [monitorRole, setMonitorRole] = useState('viewer')
|
||||||
const [assetsRoles, setAssetsRoles] = useState<Role[]>([])
|
const [assetsRoles, setAssetsRoles] = useState<Role[]>([])
|
||||||
const [issueRoles, setIssueRoles] = useState<Role[]>([])
|
const [issueRoles, setIssueRoles] = useState<Role[]>([])
|
||||||
|
const [monitorRoles, setMonitorRoles] = useState<Role[]>([])
|
||||||
const [users, setUsers] = useState<LdapUser[]>([])
|
const [users, setUsers] = useState<LdapUser[]>([])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [result, setResult] = useState<{ ok: boolean; msg: string } | null>(null)
|
const [result, setResult] = useState<{ ok: boolean; msg: string } | null>(null)
|
||||||
|
|
@ -57,6 +59,7 @@ export default function AdminUsersPage() {
|
||||||
])
|
])
|
||||||
if (rolesR.assets?.length) setAssetsRoles(rolesR.assets)
|
if (rolesR.assets?.length) setAssetsRoles(rolesR.assets)
|
||||||
if (rolesR.issue?.length) setIssueRoles(rolesR.issue)
|
if (rolesR.issue?.length) setIssueRoles(rolesR.issue)
|
||||||
|
if (rolesR.monitor?.length) setMonitorRoles(rolesR.monitor)
|
||||||
if (usersR.users?.length) setUsers(usersR.users)
|
if (usersR.users?.length) setUsers(usersR.users)
|
||||||
} catch {}
|
} catch {}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
@ -81,7 +84,7 @@ export default function AdminUsersPage() {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/admin/create-user', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, displayName, assetsRole, issueRole, email: email || undefined }) })
|
const res = await fetch('/api/admin/create-user', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, displayName, assetsRole, issueRole, monitorRole, email: email || undefined }) })
|
||||||
const d = await res.json()
|
const d = await res.json()
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
if (d.password) { setGeneratedPwd(d.password); setPwdUser(username); setPwdName(displayName || username); setShowPwd(true); setCopied(false) }
|
if (d.password) { setGeneratedPwd(d.password); setPwdUser(username); setPwdName(displayName || username); setShowPwd(true); setCopied(false) }
|
||||||
|
|
@ -206,6 +209,12 @@ export default function AdminUsersPage() {
|
||||||
{issueRoles.map(r => <option key={r.name} value={r.name}>{r.display_name}({r.name})</option>)}
|
{issueRoles.map(r => <option key={r.name} value={r.name}>{r.display_name}({r.name})</option>)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||||
|
<label style={s.label}>告警监控</label>
|
||||||
|
<select value={monitorRole} onChange={e => setMonitorRole(e.target.value)} style={s.select}>
|
||||||
|
{monitorRoles.map(r => <option key={r.name} value={r.name}>{r.display_name}({r.name})</option>)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" disabled={loading} style={{ ...s.btn, background: loading ? '#93c5fd' : '#2563eb', cursor: loading ? 'not-allowed' : 'pointer' }}>
|
<button type="submit" disabled={loading} style={{ ...s.btn, background: loading ? '#93c5fd' : '#2563eb', cursor: loading ? 'not-allowed' : 'pointer' }}>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { useState, useEffect, useCallback } from 'react'
|
||||||
|
|
||||||
interface SiteUser { username: string; display_name: string; role: string }
|
interface SiteUser { username: string; display_name: string; role: string }
|
||||||
interface RoleData {
|
interface RoleData {
|
||||||
assetsUsers: SiteUser[]; issueUsers: SiteUser[]
|
assetsUsers: SiteUser[]; issueUsers: SiteUser[]; monitorUsers: SiteUser[]
|
||||||
assetsRoles: string[]; issueRoles: string[]
|
assetsRoles: string[]; issueRoles: string[]; monitorRoles: string[]
|
||||||
emails: Record<string, string>
|
emails: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default function RoleManager({ setResult, onUserUpdated }: Props) {
|
||||||
const fetchRoleData = useCallback(async () => {
|
const fetchRoleData = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/admin/user-roles'); const d = await res.json()
|
const res = await fetch('/api/admin/user-roles'); const d = await res.json()
|
||||||
if (d.users) setRoleData({ assetsUsers: d.users.assets || [], issueUsers: d.users.issue || [], assetsRoles: d.assetsRoles || [], issueRoles: d.issueRoles || [], emails: d.emails || {} })
|
if (d.users) setRoleData({ assetsUsers: d.users.assets || [], issueUsers: d.users.issue || [], monitorUsers: d.users.monitor || [], assetsRoles: d.assetsRoles || [], issueRoles: d.issueRoles || [], monitorRoles: d.monitorRoles || [], emails: d.emails || {} })
|
||||||
} catch {}
|
} catch {}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -101,9 +101,10 @@ export default function RoleManager({ setResult, onUserUpdated }: Props) {
|
||||||
|
|
||||||
if (!roleData) return <p style={{ fontSize: 13, color: 'var(--text-muted)', textAlign: 'center', padding: 40 }}>加载中...</p>
|
if (!roleData) return <p style={{ fontSize: 13, color: 'var(--text-muted)', textAlign: 'center', padding: 40 }}>加载中...</p>
|
||||||
|
|
||||||
const userMap = new Map<string, { displayName: string; email: string; assetsRole: string; issueRole: string }>()
|
const userMap = new Map<string, { displayName: string; email: string; assetsRole: string; issueRole: string; monitorRole: string }>()
|
||||||
roleData.assetsUsers.forEach(u => userMap.set(u.username, { displayName: u.display_name, email: roleData.emails[u.username] || '', assetsRole: u.role, issueRole: '—' }))
|
roleData.assetsUsers.forEach(u => userMap.set(u.username, { displayName: u.display_name, email: roleData.emails[u.username] || '', assetsRole: u.role, issueRole: '—', monitorRole: '—' }))
|
||||||
roleData.issueUsers.forEach(u => { const e = userMap.get(u.username); if (e) e.issueRole = u.role; else userMap.set(u.username, { displayName: u.display_name, email: roleData.emails[u.username] || '', assetsRole: '—', issueRole: u.role }) })
|
roleData.issueUsers.forEach(u => { const e = userMap.get(u.username); if (e) e.issueRole = u.role; else userMap.set(u.username, { displayName: u.display_name, email: roleData.emails[u.username] || '', assetsRole: '—', issueRole: u.role, monitorRole: '—' }) })
|
||||||
|
roleData.monitorUsers.forEach(u => { const e = userMap.get(u.username); if (e) e.monitorRole = u.role; else userMap.set(u.username, { displayName: u.display_name, email: roleData.emails[u.username] || '', assetsRole: '—', issueRole: '—', monitorRole: u.role }) })
|
||||||
const users = Array.from(userMap.entries())
|
const users = Array.from(userMap.entries())
|
||||||
const changed = Object.keys(pending).length
|
const changed = Object.keys(pending).length
|
||||||
|
|
||||||
|
|
@ -119,7 +120,7 @@ export default function RoleManager({ setResult, onUserUpdated }: Props) {
|
||||||
<div style={{ overflowX: 'auto' }}><table style={ss.table}>
|
<div style={{ overflowX: 'auto' }}><table style={ss.table}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style={ss.th}>用户名</th><th style={ss.th}>显示名</th><th style={ss.th}>邮箱</th><th style={ss.th}>资产管理</th><th style={ss.th}>工单跟踪</th>
|
<th style={ss.th}>用户名</th><th style={ss.th}>显示名</th><th style={ss.th}>邮箱</th><th style={ss.th}>资产管理</th><th style={ss.th}>工单跟踪</th><th style={ss.th}>告警监控</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -162,6 +163,7 @@ export default function RoleManager({ setResult, onUserUpdated }: Props) {
|
||||||
</td>
|
</td>
|
||||||
<td style={ss.td}><RoleCell site="assets" username={uname} originalRole={info.assetsRole} roles={roleData.assetsRoles} pending={pending} onSelect={handleSelect} getCurrentRole={getCurrentRole} /></td>
|
<td style={ss.td}><RoleCell site="assets" username={uname} originalRole={info.assetsRole} roles={roleData.assetsRoles} pending={pending} onSelect={handleSelect} getCurrentRole={getCurrentRole} /></td>
|
||||||
<td style={ss.td}><RoleCell site="issue" username={uname} originalRole={info.issueRole} roles={roleData.issueRoles} pending={pending} onSelect={handleSelect} getCurrentRole={getCurrentRole} /></td>
|
<td style={ss.td}><RoleCell site="issue" username={uname} originalRole={info.issueRole} roles={roleData.issueRoles} pending={pending} onSelect={handleSelect} getCurrentRole={getCurrentRole} /></td>
|
||||||
|
<td style={ss.td}><RoleCell site="monitor" username={uname} originalRole={info.monitorRole} roles={roleData.monitorRoles} pending={pending} onSelect={handleSelect} getCurrentRole={getCurrentRole} /></td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue