From 08756fc941dd157efd3c94099ac211791253cb67 Mon Sep 17 00:00:00 2001 From: Lixian Zhou Date: Mon, 16 Mar 2026 15:46:37 -0400 Subject: [PATCH] fix --- app/controllers/employee.controller.js | 84 ++++++++++--------- .../src/components/employees/EmployeeList.js | 39 ++++----- .../employees/ExternalEmployeesImport.js | 10 +-- 3 files changed, 60 insertions(+), 73 deletions(-) diff --git a/app/controllers/employee.controller.js b/app/controllers/employee.controller.js index d5524e0..9f502b8 100644 --- a/app/controllers/employee.controller.js +++ b/app/controllers/employee.controller.js @@ -326,31 +326,49 @@ exports.getExternalEmployeesList = async (req, res) => { timeout: 15000, httpsAgent: HR_INSECURE_HTTPS_AGENT }; - const currentSite = splitSite.findSiteNumber(req); - const requestBodies = [ - { - username: HR_INTEGRATION_USERNAME, - password: HR_INTEGRATION_PASSWORD, - site: currentSite, - status: "active" - }, - { - username: HR_INTEGRATION_USERNAME, - password: HR_INTEGRATION_PASSWORD, - site: currentSite - }, - { - username: HR_INTEGRATION_USERNAME, - password: HR_INTEGRATION_PASSWORD, - status: "active" - }, - { - username: HR_INTEGRATION_USERNAME, - password: HR_INTEGRATION_PASSWORD - } - ]; + const requestedSite = Number(req.query?.site || req.body?.site); + const hasRequestedSite = Number.isInteger(requestedSite) && requestedSite > 0; + const requestBodies = hasRequestedSite + ? [ + { + username: HR_INTEGRATION_USERNAME, + password: HR_INTEGRATION_PASSWORD, + site: requestedSite, + status: "active" + }, + { + username: HR_INTEGRATION_USERNAME, + password: HR_INTEGRATION_PASSWORD, + site: requestedSite + } + ] + : [ + { + username: HR_INTEGRATION_USERNAME, + password: HR_INTEGRATION_PASSWORD, + status: "active" + }, + { + username: HR_INTEGRATION_USERNAME, + password: HR_INTEGRATION_PASSWORD + } + ]; const normalizeEmployeesList = (raw) => { if (Array.isArray(raw)) return raw; + if (typeof raw === "string") { + const trimmed = raw.trim(); + if (!trimmed) return []; + try { + const parsed = JSON.parse(trimmed); + if (Array.isArray(parsed)) return parsed; + if (Array.isArray(parsed?.data)) return parsed.data; + if (Array.isArray(parsed?.employees)) return parsed.employees; + if (Array.isArray(parsed?.result)) return parsed.result; + if (Array.isArray(parsed?.results)) return parsed.results; + } catch (_err) { + return []; + } + } if (Array.isArray(raw?.data)) return raw.data; if (Array.isArray(raw?.employees)) return raw.employees; if (Array.isArray(raw?.result)) return raw.result; @@ -362,35 +380,19 @@ exports.getExternalEmployeesList = async (req, res) => { let bestResponseData = null; for (const requestBody of requestBodies) { try { - console.log("[HR Integration] Requesting employee list from:", HR_EMPLOYEE_LIST_ENDPOINT, "payload:", requestBody); const response = await axios.post(HR_EMPLOYEE_LIST_ENDPOINT, requestBody, requestOptions); const list = normalizeEmployeesList(response?.data); - console.log( - "[HR Integration] employee list response meta:", - { endpoint: HR_EMPLOYEE_LIST_ENDPOINT, count: list.length, responseType: typeof response?.data } - ); - console.log("[HR Integration] raw employee list response:", response?.data); bestResponseData = response?.data; if (list.length > 0) { return res.send(list); } - } catch (attemptError) { - console.log("[HR Integration] employee list attempt failed:", { - endpoint: HR_EMPLOYEE_LIST_ENDPOINT, - payload: requestBody, - status: attemptError?.response?.status, - data: attemptError?.response?.data, - message: attemptError?.message - }); + } catch (_attemptError) { + // Try next payload variant. } } const emptyList = normalizeEmployeesList(bestResponseData); - console.log("[HR Integration] all attempts completed; returning list length:", emptyList.length); return res.send(emptyList); } catch (err) { - console.log("[HR Integration] /employees/list error status:", err?.response?.status); - console.log("[HR Integration] /employees/list error data:", err?.response?.data); - console.log("[HR Integration] /employees/list error message:", err?.message); res.status(500).send({ message: err?.response?.data?.message || err.message || "Failed to fetch employees from HR system." }); diff --git a/client/src/components/employees/EmployeeList.js b/client/src/components/employees/EmployeeList.js index dfa2495..19636ea 100644 --- a/client/src/components/employees/EmployeeList.js +++ b/client/src/components/employees/EmployeeList.js @@ -8,6 +8,7 @@ const SYSTEM_ACCESS_PERMISSION = "System Access"; const EmployeeList = () => { const navigate = useNavigate(); + const currentSite = EventsService.site || 3; const [employees, setEmployees] = useState([]); const [keyword, setKeyword] = useState(''); const [showInactive, setShowInactive] = useState(false); @@ -15,7 +16,6 @@ const EmployeeList = () => { const [isHrLoading, setIsHrLoading] = useState(false); const [isSavingHrPermission, setIsSavingHrPermission] = useState(false); const [hrKeyword, setHrKeyword] = useState(''); - const [hrSiteFilter, setHrSiteFilter] = useState(EventsService.site || 3); const [hrPermissionMap, setHrPermissionMap] = useState({}); const [editingHrUser, setEditingHrUser] = useState(undefined); const [showHrPermissionModal, setShowHrPermissionModal] = useState(false); @@ -31,25 +31,16 @@ const EmployeeList = () => { setEmployees(data.data) ); loadHrUsers(); + loadHrPermissionsBySite(currentSite); }, []); - useEffect(() => { - loadHrPermissionsBySite(hrSiteFilter); - }, [hrSiteFilter]); - const loadHrUsers = () => { setIsHrLoading(true); EmployeeService.getExternalEmployeesList() .then((response) => { - console.log('[HR Debug][EmployeeList] backend /employees/external/list response:', response?.data); setHrUsers(Array.isArray(response?.data) ? response.data : []); }) .catch((error) => { - console.log('[HR Debug][EmployeeList] /employees/external/list error:', { - status: error?.response?.status, - data: error?.response?.data, - message: error?.message - }); window.alert(error?.response?.data?.message || 'Failed to load HR users.'); }) .finally(() => { @@ -95,9 +86,12 @@ const EmployeeList = () => { } const filteredHrUsers = useMemo(() => { - const site = Number(hrSiteFilter); return (hrUsers || []) - .filter((item) => Number(item?.site) === site) + .filter((item) => Number(item?.site) === Number(currentSite)) + .filter((item) => { + const configuredPermissions = hrPermissionMap?.[item?.employee_id] || []; + return configuredPermissions.length > 0; + }) .filter((item) => { if (!hrKeyword) return true; const key = hrKeyword.toLowerCase(); @@ -107,7 +101,7 @@ const EmployeeList = () => { (item?.title || '').toLowerCase().includes(key) ); }); - }, [hrUsers, hrKeyword, hrSiteFilter]); + }, [hrUsers, hrKeyword, hrPermissionMap, currentSite]); const openHrPermissionModal = (hrUser) => { setEditingHrUser(hrUser); @@ -141,7 +135,7 @@ const EmployeeList = () => { username: editingHrUser.username || '', name: editingHrUser.name || '', email: editingHrUser.email || '', - allow_site: Number(hrSiteFilter), + allow_site: Number(currentSite), permissions: selectedHrPermissions }) .then(() => { @@ -161,10 +155,10 @@ const EmployeeList = () => { const revokeHrPermissions = (hrUser) => { if (!hrUser?.employee_id) return; - if (!window.confirm(`Revoke all permissions for ${hrUser?.username || 'this HR user'} on Site ${hrSiteFilter}?`)) { + if (!window.confirm(`Revoke all permissions for ${hrUser?.username || 'this HR user'} on Site ${currentSite}?`)) { return; } - EmployeeService.revokeExternalUserPermission(hrUser.employee_id, Number(hrSiteFilter)) + EmployeeService.revokeExternalUserPermission(hrUser.employee_id, Number(currentSite)) .then(() => { setHrPermissionMap((prev) => { const next = { ...prev }; @@ -202,18 +196,13 @@ const EmployeeList = () => {
HR System Users
-
@@ -299,7 +288,7 @@ const EmployeeList = () => {
- Allow Site: {hrSiteFilter} + Allow Site: {currentSite}
{Object.entries(EMPLOYEE_PERMISSION_GROUPS).map(([groupName, permissionItems]) => (
diff --git a/client/src/components/employees/ExternalEmployeesImport.js b/client/src/components/employees/ExternalEmployeesImport.js index a167b2e..1c4b61c 100644 --- a/client/src/components/employees/ExternalEmployeesImport.js +++ b/client/src/components/employees/ExternalEmployeesImport.js @@ -11,7 +11,7 @@ const ExternalEmployeesImport = () => { const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [employees, setEmployees] = useState([]); - const [siteFilter, setSiteFilter] = useState('all'); + const [siteFilter, setSiteFilter] = useState(EventsService.site || 3); const [keyword, setKeyword] = useState(""); const [showPermissionModal, setShowPermissionModal] = useState(false); const [selectedEmployee, setSelectedEmployee] = useState(undefined); @@ -32,15 +32,9 @@ const ExternalEmployeesImport = () => { setLoading(true); EmployeeService.getExternalEmployeesList() .then((response) => { - console.log("[HR Debug][ExternalEmployeesImport] backend /employees/external/list response:", response?.data); setEmployees(Array.isArray(response?.data) ? response.data : []); }) .catch((error) => { - console.log("[HR Debug][ExternalEmployeesImport] /employees/external/list error:", { - status: error?.response?.status, - data: error?.response?.data, - message: error?.message - }); window.alert(error?.response?.data?.message || "Failed to load employees from HR system."); }) .finally(() => { @@ -146,6 +140,8 @@ const ExternalEmployeesImport = () => { + +