refactor(frontend): remove department member search
This commit is contained in:
parent
5e317c30f9
commit
fbdc49aa5b
@ -9,7 +9,6 @@ import {
|
||||
Crown,
|
||||
PencilLine,
|
||||
Plus,
|
||||
Search,
|
||||
Settings2,
|
||||
Trash2,
|
||||
UserPlus,
|
||||
@ -76,6 +75,7 @@ function DepartmentMemberRow({
|
||||
const isHead = currentHeadId === member.employee.id;
|
||||
const isRemoving = pendingKey === `member-remove-${member.employee.id}`;
|
||||
const isRoleBusy = pendingKey === `member-role-${member.employee.id}`;
|
||||
const subtitle = member.employee.position?.name || null;
|
||||
const managementMode = canAssignRoles || canChangeHead || canManage;
|
||||
const roleLabel = member.role?.name || "Без роли";
|
||||
const personName = displayUserName(member.employee);
|
||||
@ -89,15 +89,20 @@ function DepartmentMemberRow({
|
||||
|
||||
if (!managementMode) {
|
||||
const personBubble = (
|
||||
<span className="app-badge inline-flex max-w-full items-center gap-2 rounded-full px-2.5 py-1 text-xs font-medium">
|
||||
<span className="app-badge inline-flex max-w-full items-center gap-2 rounded-full px-2 py-1.5">
|
||||
<RequestAvatar
|
||||
alt={personName}
|
||||
fallback={fallback}
|
||||
size="sm"
|
||||
size="lg"
|
||||
src={member.employee.avatar}
|
||||
/>
|
||||
<span className="truncate text-[var(--foreground)]">
|
||||
{personName}
|
||||
<span className="min-w-0">
|
||||
<span className="block truncate text-sm font-medium text-[var(--foreground)]">
|
||||
{personName}
|
||||
</span>
|
||||
{subtitle ? (
|
||||
<span className="app-text-muted block truncate text-xs">{subtitle}</span>
|
||||
) : null}
|
||||
</span>
|
||||
{member.role ? (
|
||||
<span className="app-surface inline-flex max-w-full items-center rounded-full px-2.5 py-1 text-xs font-medium text-[var(--muted-foreground)]">
|
||||
@ -131,7 +136,7 @@ function DepartmentMemberRow({
|
||||
<DepartmentPersonChip
|
||||
currentUserId={currentUserId}
|
||||
person={member.employee}
|
||||
subtitle={member.employee.position?.name || null}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
|
||||
<span className="app-badge inline-flex max-w-full items-center rounded-full px-2.5 py-1 text-xs font-medium">
|
||||
@ -563,21 +568,6 @@ export default function DepartmentDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="app-surface-muted mb-4 flex flex-col gap-3 rounded-xl p-3 md:flex-row md:items-center">
|
||||
<div className="relative min-w-0 flex-1">
|
||||
<Search
|
||||
size={16}
|
||||
className="app-text-muted pointer-events-none absolute left-3 top-1/2 -translate-y-1/2"
|
||||
/>
|
||||
<input
|
||||
value={h.membersQuery}
|
||||
onChange={(event) => h.setMembersQuery(event.target.value)}
|
||||
placeholder="Поиск по участникам, почте, должности или роли"
|
||||
className="app-input w-full rounded-lg py-2.5 pl-9 pr-3 text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
isManagementMode
|
||||
|
||||
@ -42,7 +42,6 @@ export type DepartmentPageController = {
|
||||
headCandidates: Array<{ id: number; name: string }>;
|
||||
loading: boolean;
|
||||
members: DepartmentMemberLink[];
|
||||
membersQuery: string;
|
||||
pendingKey: SavingKey | null;
|
||||
roleDraft: DepartmentRoleDraft;
|
||||
roleEditorOpen: boolean;
|
||||
@ -62,7 +61,6 @@ export type DepartmentPageController = {
|
||||
refreshPage: () => Promise<void>;
|
||||
saveDepartment: () => Promise<void>;
|
||||
saveRole: () => Promise<void>;
|
||||
setMembersQuery: (value: string) => void;
|
||||
setRoleDraft: (next: DepartmentRoleDraft | ((current: DepartmentRoleDraft) => DepartmentRoleDraft)) => void;
|
||||
setSelectedHeadId: (id: number | null) => void;
|
||||
setSelectedMemberId: (id: number | null) => void;
|
||||
@ -129,7 +127,6 @@ export function useDepartmentPage(departmentId: number): DepartmentPageControlle
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [pendingKey, setPendingKey] = useState<SavingKey | null>(null);
|
||||
const [membersQuery, setMembersQuery] = useState("");
|
||||
|
||||
const [editDepartmentOpen, setEditDepartmentOpen] = useState(false);
|
||||
const [departmentDraft, setDepartmentDraft] = useState({ name: "", description: "" });
|
||||
@ -228,32 +225,13 @@ export function useDepartmentPage(departmentId: number): DepartmentPageControlle
|
||||
}, [allEmployees.length, loadEmployeesDirectory, userPerms]);
|
||||
|
||||
const filteredMembers = useMemo(() => {
|
||||
const q = membersQuery.trim().toLowerCase();
|
||||
|
||||
return members.filter((item) => {
|
||||
if (!item.is_active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!q) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const employeeName = `${item.employee.last_name || ""} ${item.employee.first_name || ""} ${item.employee.patronymic || ""}`
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
const email = item.employee.email?.toLowerCase() || "";
|
||||
const position = item.employee.position?.name?.toLowerCase() || "";
|
||||
const roleName = item.role?.name?.toLowerCase() || "";
|
||||
|
||||
return (
|
||||
employeeName.includes(q) ||
|
||||
email.includes(q) ||
|
||||
position.includes(q) ||
|
||||
roleName.includes(q)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
}, [members, membersQuery]);
|
||||
}, [members]);
|
||||
|
||||
const selectableEmployees = useMemo(() => {
|
||||
const activeIds = new Set(
|
||||
@ -530,7 +508,6 @@ export function useDepartmentPage(departmentId: number): DepartmentPageControlle
|
||||
headCandidates,
|
||||
loading,
|
||||
members,
|
||||
membersQuery,
|
||||
pendingKey,
|
||||
roleDraft,
|
||||
roleEditorOpen,
|
||||
@ -550,7 +527,6 @@ export function useDepartmentPage(departmentId: number): DepartmentPageControlle
|
||||
refreshPage,
|
||||
saveDepartment,
|
||||
saveRole,
|
||||
setMembersQuery,
|
||||
setRoleDraft,
|
||||
setSelectedHeadId,
|
||||
setSelectedMemberId,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user