fix(users): fieldValues в реальном обработчике /api/users/list + горизонтальный скролл таблицы
Причина «поля профиля не отображаются»: /api/users/list обслуживает СТАРЫЙ обработчик в auth.users.routes.ts (зарегистрирован раньше дубля handleListUsers в user.routes.ts — проверено: в ответе нет total/pageSize). includeFieldValues добавлен в оба, но реальный — теперь тоже отдаёт fieldValues. Плюс overflow-x-auto на контейнере таблицы — прокрутка при переполнении колонок.
This commit is contained in:
@@ -1091,7 +1091,7 @@ const UsersPage = () => {
|
|||||||
<ActiveFilterBadges filters={filters} sort={sort} columnLabels={userColumnLabels} onRemoveFilter={clearFilter} onRemoveSort={clearSort} onClearAll={clearAll} />
|
<ActiveFilterBadges filters={filters} sort={sort} columnLabels={userColumnLabels} onRemoveFilter={clearFilter} onRemoveSort={clearSort} onClearAll={clearAll} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="p-3">
|
<div className="p-3 overflow-x-auto">
|
||||||
<div className="flex justify-end mb-2">
|
<div className="flex justify-end mb-2">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { authService } from "../services/auth.service";
|
|||||||
import { authenticateToken, requirePermission, type AuthenticatedRequest } from "../middleware/auth.middleware";
|
import { authenticateToken, requirePermission, type AuthenticatedRequest } from "../middleware/auth.middleware";
|
||||||
import { tenantIsolation } from "../middleware/tenant.middleware";
|
import { tenantIsolation } from "../middleware/tenant.middleware";
|
||||||
import { validateRequest } from "../middleware/validation.middleware";
|
import { validateRequest } from "../middleware/validation.middleware";
|
||||||
|
import { db } from "../db";
|
||||||
|
import { inArray } from "drizzle-orm";
|
||||||
|
import { userProfileFieldValues } from "@shared/schema";
|
||||||
import {
|
import {
|
||||||
createUserCustomFieldSchema, updateUserCustomFieldSchema,
|
createUserCustomFieldSchema, updateUserCustomFieldSchema,
|
||||||
setUserCustomValueSchema,
|
setUserCustomValueSchema,
|
||||||
@@ -198,6 +201,22 @@ export function registerUserManagementRoutes(router: Router): void {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Значения кастомных полей профиля — для реестра пользователей (выбор колонок).
|
||||||
|
// ВНИМАНИЕ: этот обработчик /api/users/list фактически обслуживает запросы
|
||||||
|
// (зарегистрирован раньше дубля в user.routes.ts handleListUsers).
|
||||||
|
const includeFieldValues = req.query.includeFieldValues === '1';
|
||||||
|
const fieldValuesMap = new Map<number, Record<number, unknown>>();
|
||||||
|
if (includeFieldValues && users.length > 0) {
|
||||||
|
const fvRows = await db
|
||||||
|
.select({ userId: userProfileFieldValues.userId, fieldId: userProfileFieldValues.fieldId, value: userProfileFieldValues.value })
|
||||||
|
.from(userProfileFieldValues)
|
||||||
|
.where(inArray(userProfileFieldValues.userId, users.map(u => u.id)));
|
||||||
|
for (const row of fvRows) {
|
||||||
|
if (!fieldValuesMap.has(row.userId)) fieldValuesMap.set(row.userId, {});
|
||||||
|
fieldValuesMap.get(row.userId)![row.fieldId] = row.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let safeUsers = users.map(user => ({
|
let safeUsers = users.map(user => ({
|
||||||
id: user.id,
|
id: user.id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
@@ -212,6 +231,7 @@ export function registerUserManagementRoutes(router: Router): void {
|
|||||||
lastActivityAt: user.lastActivityAt,
|
lastActivityAt: user.lastActivityAt,
|
||||||
createdAt: user.createdAt,
|
createdAt: user.createdAt,
|
||||||
organizationalRoles: roleMembersMap.get(user.id) || [],
|
organizationalRoles: roleMembersMap.get(user.id) || [],
|
||||||
|
...(includeFieldValues ? { fieldValues: fieldValuesMap.get(user.id) || {} } : {}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Object.entries(filtersObj).forEach(([col, val]) => {
|
Object.entries(filtersObj).forEach(([col, val]) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user