Merge pull request 'fix(대무자): COMPANY_ADMIN + SQL + UI select' from johngreen into main
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m24s
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m24s
This commit is contained in:
@@ -6,12 +6,20 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import {
|
||||
getSubstituteList,
|
||||
createSubstitute,
|
||||
deleteSubstitute,
|
||||
checkSubstituteOverlap,
|
||||
} from "@/lib/api/substitute";
|
||||
import { getUserList } from "@/lib/api/user";
|
||||
|
||||
/**
|
||||
* 사용자별 대무자(代務者) 관리 섹션.
|
||||
@@ -39,6 +47,10 @@ export function SubstituteSection({ originalUserId, originalUserName }: Substitu
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
// 같은 회사 활성 사용자 목록 (대무자 후보) — 본인/SUPER_ADMIN/비활성 제외
|
||||
const [candidates, setCandidates] = useState<Record<string, any>[]>([]);
|
||||
const [candidatesLoading, setCandidatesLoading] = useState(false);
|
||||
|
||||
const [form, setForm] = useState({
|
||||
proxy_user_id: "",
|
||||
start_date: "",
|
||||
@@ -63,10 +75,29 @@ export function SubstituteSection({ originalUserId, originalUserName }: Substitu
|
||||
load();
|
||||
}, [load]);
|
||||
|
||||
// 대무자 후보 사용자 목록 로드 (다이얼로그 열릴 때 한번)
|
||||
const loadCandidates = useCallback(async () => {
|
||||
setCandidatesLoading(true);
|
||||
const res = await getUserList({ status: "active", limit: 1000 });
|
||||
if (res?.success && Array.isArray(res.data?.list)) {
|
||||
const filtered = (res.data.list as Record<string, any>[]).filter(
|
||||
(u) =>
|
||||
u.user_id !== originalUserId &&
|
||||
u.user_type !== "SUPER_ADMIN" &&
|
||||
u.status === "active",
|
||||
);
|
||||
setCandidates(filtered);
|
||||
} else {
|
||||
setCandidates([]);
|
||||
}
|
||||
setCandidatesLoading(false);
|
||||
}, [originalUserId]);
|
||||
|
||||
const openDialog = () => {
|
||||
setForm({ proxy_user_id: "", start_date: "", end_date: "", reason: "" });
|
||||
setError(null);
|
||||
setDialogOpen(true);
|
||||
loadCandidates();
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
@@ -215,16 +246,36 @@ export function SubstituteSection({ originalUserId, originalUserName }: Substitu
|
||||
|
||||
<div className="space-y-3 py-2 text-sm">
|
||||
<div>
|
||||
<Label htmlFor="proxy_user_id">대무자 사용자 ID</Label>
|
||||
<Input
|
||||
id="proxy_user_id"
|
||||
<Label htmlFor="proxy_user_id">대무자</Label>
|
||||
<Select
|
||||
value={form.proxy_user_id}
|
||||
onChange={(e) => setForm({ ...form, proxy_user_id: e.target.value })}
|
||||
placeholder="예: hjkim"
|
||||
autoFocus
|
||||
/>
|
||||
onValueChange={(v) => setForm({ ...form, proxy_user_id: v })}
|
||||
>
|
||||
<SelectTrigger id="proxy_user_id" autoFocus>
|
||||
<SelectValue
|
||||
placeholder={
|
||||
candidatesLoading
|
||||
? "사용자 목록 불러오는 중..."
|
||||
: candidates.length === 0
|
||||
? "지정 가능한 사용자가 없습니다"
|
||||
: "대무자를 선택하세요"
|
||||
}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{candidates.map((u) => (
|
||||
<SelectItem key={u.user_id} value={u.user_id}>
|
||||
{u.user_name || u.user_id}
|
||||
<span className="ml-1 text-muted-foreground">
|
||||
({u.user_id}
|
||||
{u.dept_name ? ` · ${u.dept_name}` : ""})
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="mt-1 text-[0.7rem] text-muted-foreground">
|
||||
같은 회사 사용자만 지정 가능. SUPER_ADMIN 은 지정 불가.
|
||||
같은 회사 활성 사용자만 표시. 본인·SUPER_ADMIN 자동 제외.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user