feat: 实现LDAP创建OU和用户(LDAP Add)+弹框风格统一
This commit is contained in:
1 parent
7b5f95e702
commit
c51f619a7d
2 files changed
+167
-49
No files matched your search
@@ -6,7 +6,7 @@ import { toast } from '@/hooks/useToast';
|
||||
import {
|
||||
Save, ChevronRight, ChevronDown, RefreshCw,
|
||||
CheckCircle, XCircle, Trash2, KeyRound, FolderOpen, Users,
|
||||
Shield, AlertTriangle, Import,
|
||||
Shield, AlertTriangle, Import, UserPlus,
|
||||
} from 'lucide-react';
|
||||
|
||||
/* ── types ── */
|
||||
@@ -613,19 +613,22 @@ export default function LdapConfigPage() {
|
||||
|
||||
{/* ── 创建 OU 弹框 ── */}
|
||||
{showCreateOu && (
|
||||
<ModalOverlay open={true} onClose={() => setShowCreateOu(false)} width="w-[460px]">
|
||||
<div className="bg-[var(--dg-bg-secondary)] rounded-xl shadow-2xl">
|
||||
<div className="flex items-center justify-between px-5 py-4">
|
||||
<h3 className="text-sm font-semibold">新建组织单元 (OU)</h3>
|
||||
<button onClick={() => setShowCreateOu(false)} className="text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]">✕</button>
|
||||
<ModalOverlay open={true} onClose={() => setShowCreateOu(false)} width="max-w-md">
|
||||
<div className="w-full bg-[var(--dg-bg-secondary)] border border-[var(--dg-border)] rounded-xl p-5 shadow-xl">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<FolderOpen className="w-4 h-4 text-blue-400" />
|
||||
<h3 className="text-sm font-semibold text-[var(--dg-text-primary)]">新建组织单元 (OU)</h3>
|
||||
</div>
|
||||
<button onClick={() => setShowCreateOu(false)} className="text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)] transition-colors">✕</button>
|
||||
</div>
|
||||
<div className="px-5 space-y-4">
|
||||
<div className="space-y-3 mb-4">
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">OU 名称 *</label>
|
||||
<input
|
||||
value={newOuName}
|
||||
onChange={e => setNewOuName(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="如: devops, engineering"
|
||||
/>
|
||||
</div>
|
||||
@@ -634,7 +637,7 @@ export default function LdapConfigPage() {
|
||||
<select
|
||||
value={newOuParent}
|
||||
onChange={e => setNewOuParent(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
>
|
||||
<option value="">根: {config.base_dn}</option>
|
||||
{ouList.map(ou => <option key={ou.dn} value={ou.dn}>{ou.dn}</option>)}
|
||||
@@ -645,17 +648,17 @@ export default function LdapConfigPage() {
|
||||
<input
|
||||
value={newOuDesc}
|
||||
onChange={e => setNewOuDesc(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="可选,如: 研发团队"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-3 px-5 py-4">
|
||||
<button onClick={() => setShowCreateOu(false)} className="px-4 py-2 text-sm text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]">取消</button>
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={() => setShowCreateOu(false)} className="px-4 py-2 text-sm text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)] transition-colors">取消</button>
|
||||
<button
|
||||
onClick={handleCreateOu}
|
||||
disabled={creatingOu || !newOuName.trim()}
|
||||
className="px-4 py-2 text-sm font-medium rounded-lg bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50"
|
||||
className="px-4 py-2 text-sm font-medium rounded-lg bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
{creatingOu ? '创建中…' : '创建 OU'}
|
||||
</button>
|
||||
@@ -666,41 +669,42 @@ export default function LdapConfigPage() {
|
||||
|
||||
{/* ── 添加用户弹框 ── */}
|
||||
{showAddUser && (
|
||||
<ModalOverlay open={true} onClose={() => setShowAddUser(false)} width="w-[500px]">
|
||||
<div className="bg-[var(--dg-bg-secondary)] rounded-xl shadow-2xl">
|
||||
<div className="flex items-center justify-between px-5 py-4">
|
||||
<h3 className="text-sm font-semibold">添加用户到 LDAP</h3>
|
||||
<button onClick={() => setShowAddUser(false)} className="text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]">✕</button>
|
||||
</div>
|
||||
<div className="px-5 space-y-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">用户名 *</label>
|
||||
<input
|
||||
value={addUsername}
|
||||
onChange={e => setAddUsername(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
placeholder="登录名,如 zhangsan"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">密码 *</label>
|
||||
<input
|
||||
type="password"
|
||||
value={addPassword}
|
||||
onChange={e => setAddPassword(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
placeholder="初始密码"
|
||||
/>
|
||||
</div>
|
||||
<ModalOverlay open={true} onClose={() => setShowAddUser(false)} width="max-w-md">
|
||||
<div className="w-full bg-[var(--dg-bg-secondary)] border border-[var(--dg-border)] rounded-xl p-5 shadow-xl">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserPlus className="w-4 h-4 text-emerald-400" />
|
||||
<h3 className="text-sm font-semibold text-[var(--dg-text-primary)]">添加用户到 LDAP</h3>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<button onClick={() => setShowAddUser(false)} className="text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)] transition-colors">✕</button>
|
||||
</div>
|
||||
<div className="space-y-3 mb-4">
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">用户名 *</label>
|
||||
<input
|
||||
value={addUsername}
|
||||
onChange={e => setAddUsername(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="登录名,如 zhangsan"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">密码 *</label>
|
||||
<input
|
||||
type="password"
|
||||
value={addPassword}
|
||||
onChange={e => setAddPassword(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="初始密码"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="text-xs text-[var(--dg-text-muted)] mb-1 block">显示名称</label>
|
||||
<input
|
||||
value={addDisplayName}
|
||||
onChange={e => setAddDisplayName(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="如: 张三"
|
||||
/>
|
||||
</div>
|
||||
@@ -709,7 +713,7 @@ export default function LdapConfigPage() {
|
||||
<input
|
||||
value={addEmail}
|
||||
onChange={e => setAddEmail(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
placeholder="可选"
|
||||
/>
|
||||
</div>
|
||||
@@ -719,20 +723,21 @@ export default function LdapConfigPage() {
|
||||
<select
|
||||
value={addOuDn}
|
||||
onChange={e => setAddOuDn(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm"
|
||||
className="w-full px-3 py-2 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-400 transition-colors"
|
||||
>
|
||||
<option value="">根: {config.base_dn}</option>
|
||||
{ouList.map(ou => <option key={ou.dn} value={ou.dn}>{ou.name} ({ou.dn})</option>)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-3 px-5 py-4">
|
||||
<button onClick={() => setShowAddUser(false)} className="px-4 py-2 text-sm text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]">取消</button>
|
||||
<div className="flex justify-end gap-2">
|
||||
<button onClick={() => setShowAddUser(false)} className="px-4 py-2 text-sm text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)] transition-colors">取消</button>
|
||||
<button
|
||||
onClick={handleAddUser}
|
||||
disabled={addingUser || !addUsername.trim() || !addPassword.trim()}
|
||||
className="px-4 py-2 text-sm font-medium rounded-lg bg-emerald-500 text-white hover:bg-emerald-600 disabled:opacity-50"
|
||||
className="flex items-center gap-1.5 px-4 py-2 text-sm font-medium rounded-lg bg-emerald-500 text-white hover:bg-emerald-600 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<UserPlus className="w-3.5 h-3.5" />
|
||||
{addingUser ? '创建中…' : '创建用户'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user