fix
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 38s

This commit is contained in:
2026-03-16 16:30:17 -04:00
parent 1500254db7
commit d7ddbbbb70
6 changed files with 208 additions and 5 deletions

110
TITLE.md Normal file
View File

@@ -0,0 +1,110 @@
# HR Title Display Mapping
This change adds standardized display names for HR user titles and applies them consistently in the UI.
## What Was Added
- A centralized title mapping constant and formatter:
- `client/src/shared/constants/hr-title.constant.js`
- `HR_TITLE_DISPLAY_MAP`
- `getHrTitleDisplayName(titleValue)`
- Shared export:
- `client/src/shared/constants/index.js`
## Where It Is Used
- Top-right user profile title:
- `client/src/components/home/layout.js`
- HR user title column on **All Employees**:
- `client/src/components/employees/EmployeeList.js`
- HR user title column on **Add New Employee From HR System**:
- `client/src/components/employees/ExternalEmployeesImport.js`
## Behavior
- Known HR title codes (e.g. `IT_SPECIALIST`) are displayed as mapped names (e.g. `IT Specialist`).
- Unknown underscore-based codes fall back to a readable format (e.g. `CUSTOM_CODE_NAME` -> `Custom Code Name`).
- Empty title values remain empty.
## Title Mapping List
```text
ACTIVITY_ASSISTANT:Activity Assistant
ACTIVITY_COORDINATOR:Activity Coordinator
ACTIVITY_DIRECTOR:Activity Manager
ACTIVITY_SPECIALIST:Activity Specialist
ADMINISTRATION_ASSISTANT:Administration Assistant
ADMINISTRATOR:Administrator
ASSISTANT_PROGRAM_DIRECTOR:Assistant Program Director
BILLING_MANAGER:Billing Manager
BUILDING_ENGINEER:Building Engineer
BUSINESS_DEVELOPMENT_SPECIALIST:Business Development Specialist
BUSINESS_INTELLIGENCE_ANALYST:Business Intelligence Analyst
CAREGIVER:Caregiver
CENTER_COORDINATOR:Center Coordinator
CERTIFIED_MEDICATION_TECHNICIAN:Certified Medication Technician
CERTIFIED_NURSE_ASSISTANT:CNA
CEO:CEO
CFO:CFO
CHEF:Chef
CHEF_ASSISTANT:Chef Assistant
COMPLIANCE_MANAGER:Compliance Manager
COO:COO
DEPUTY_CENTER_DIRECTOR:Deputy Center Director
DIRECTOR_OF_ACCOUNTING:Director of Accounting
DIRECTOR_OF_OPERATIONS:Director of Operations
DRIVER:Driver
DRIVER_TEAM_LEAD:Driver Team Lead
EXECUTIVE_ASSISTANT:Executive Assistant
EXECUTIVE_CHEF:Executive Chef
FINANCE_ADMIN_MANAGER:Finance & Administration Manager
FINANCIAL_ANALYST:Financial Analyst
FLEET_MANAGEMENT_SPECIALIST:Fleet Management Specialist
FLEET_MANAGER:Fleet Manager
FOOD_SERVICE_DIRECTOR:Food Service Director
FOOD_SERVICES_COORDINATOR:Food Service Coordinator
HANDYMAN:Handyman
HEAD_NURSE:Nursing Manager
HR:HR
HR_AND_ADMINISTRATIVE_COORDINATOR:HR & Administrative Coordinator
INTERN:Intern
IT_SPECIALIST:IT Specialist
IT_SUPPORT:IT Support
JANITOR:Janitor
KITCHEN_ASSISTANT:Kitchen Staff
KITCHEN_HELPER:Kitchen Helper
KITCHEN_MANAGER:Kitchen Manager
LOBBY_ASSISTANT:Lobby Assistant
LOBBY_MANAGER:Lobby Manager
MARKETING_SPECIALIST:Marketing Specialist
MEDICAL_APPOINTMENT_COORDINATOR:Medical Appointment Coordinator
MEDICAL_APPOINTMENT_SCHEDULER:Medical Appointment Scheduler
MEDICAL_DRIVER:Medical Driver
NURSING_DIRECTOR:Nursing Director
OFFICE_MANAGER:Office Manager
OPRATIONS_DIRECTOR:Center Director
PASTRY_CHEF:Pastry Chef
PRESIDENT:President
PROCESS_ASSISTANT:Program Assistant
PROGRAM_ASSISTANT:Program Assistant
PROGRAM_ASSISTANT_DRIVER:Program Assistant - Driver
PROGRAM_ASSISTANT_MEDICAL_DRIVER:Program Assistant - Medical Driver
PROGRAM_ASSISTANT_MEDICAL_DRIVER_LEAD:Program Assistant - Medical Driver Lead
PROGRAM_DIRECTOR:Program Director
PROJECT_ASSISTANT:Project Assistant
PROJECT_DIRECTOR:Project Director
QUALITY_CONTROL_SPECIALIST:Quality Control Specialist
REGISTERED_NURSE:Registered Nurse
SOCIAL_AND_COMMUNITY_SERVICE_MANAGER:Social and Community Service Manager
SOCIAL_WORK:Social Work
SOCIAL_WORK_ASSISTANT:Social Work Assistant
SOCIAL_WORK_DIRECTOR:Social Work Director
SOCIAL_WORKER_MANAGER:Social Work Manager
SPIRITUAL_CARE_SPECIALIST:Spiritual Care Specialist
TRANSPORTATION_COORDINATOR:Transportation Coordinator
TRANSPORTATION_DIRECTOR:Transportation Manager
VP:VP
```

View File

@@ -2,7 +2,7 @@ import React, { useMemo, useState, useEffect } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Button, Modal, Spinner } from "react-bootstrap"; import { Button, Modal, Spinner } from "react-bootstrap";
import { AuthService, EmployeeService, EventsService } from "../../services"; import { AuthService, EmployeeService, EventsService } from "../../services";
import { EMPLOYEE_PERMISSION_GROUPS } from "../../shared"; import { EMPLOYEE_PERMISSION_GROUPS, getHrTitleDisplayName } from "../../shared";
const SYSTEM_ACCESS_PERMISSION = "System Access"; const SYSTEM_ACCESS_PERMISSION = "System Access";
@@ -248,7 +248,7 @@ const EmployeeList = () => {
<tr key={`${externalUserId}-${hrUser?.allow_site}`}> <tr key={`${externalUserId}-${hrUser?.allow_site}`}>
<td>{hrUser?.username}</td> <td>{hrUser?.username}</td>
<td>{hrUser?.name}</td> <td>{hrUser?.name}</td>
<td>{hrUser?.title || '-'}</td> <td>{getHrTitleDisplayName(hrUser?.title || '-')}</td>
<td>{hrUser?.allow_site || currentSite}</td> <td>{hrUser?.allow_site || currentSite}</td>
<td>{configuredPermissions.length > 0 ? configuredPermissions.join(', ') : '-'}</td> <td>{configuredPermissions.length > 0 ? configuredPermissions.join(', ') : '-'}</td>
<td> <td>

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Button, Modal, Spinner } from "react-bootstrap"; import { Button, Modal, Spinner } from "react-bootstrap";
import { AuthService, EmployeeService, EventsService } from "../../services"; import { AuthService, EmployeeService, EventsService } from "../../services";
import { EMPLOYEE_PERMISSION_GROUPS } from "../../shared"; import { EMPLOYEE_PERMISSION_GROUPS, getHrTitleDisplayName } from "../../shared";
const SYSTEM_ACCESS_PERMISSION = "System Access"; const SYSTEM_ACCESS_PERMISSION = "System Access";
@@ -219,7 +219,7 @@ const ExternalEmployeesImport = () => {
<tr key={`${item?.employee_id}-${item?.site}`}> <tr key={`${item?.employee_id}-${item?.site}`}>
<td>{item?.username}</td> <td>{item?.username}</td>
<td>{item?.name}</td> <td>{item?.name}</td>
<td>{item?.title}</td> <td>{getHrTitleDisplayName(item?.title)}</td>
<td>{item?.site}</td> <td>{item?.site}</td>
<td> <td>
{(() => { {(() => {

View File

@@ -1,6 +1,7 @@
import { Bell, ChevronDown, PersonCircle } from 'react-bootstrap-icons'; import { Bell, ChevronDown, PersonCircle } from 'react-bootstrap-icons';
import { Outlet, useLocation, Navigate } from 'react-router-dom'; import { Outlet, useLocation, Navigate } from 'react-router-dom';
import { AuthService } from '../../services'; import { AuthService } from '../../services';
import { getHrTitleDisplayName } from '../../shared';
import SideMenu from './menu'; import SideMenu from './menu';
import { Dropdown } from "react-bootstrap"; import { Dropdown } from "react-bootstrap";
@@ -9,7 +10,7 @@ function Layout() {
const showMenu = location.pathname !== '/login' && location.pathname !== '/landing'; // Example: Hide menu on login page const showMenu = location.pathname !== '/login' && location.pathname !== '/landing'; // Example: Hide menu on login page
const userRaw = localStorage.getItem('user'); const userRaw = localStorage.getItem('user');
const user = userRaw ? JSON.parse(userRaw) : null; const user = userRaw ? JSON.parse(userRaw) : null;
const displayTitle = (user?.title || user?.roles?.[0] || '').toString(); const displayTitle = getHrTitleDisplayName((user?.title || user?.roles?.[0] || '').toString());
const getLogoSuffix = () => { const getLogoSuffix = () => {
return (window.location.hostname.includes('worldshine2.mayo.llc') || window.location.hostname.includes('site2') || window.location.host.includes('ws2') ||window.location.hostname.includes('localhost')) ? "Care LLC" : ((window.location.hostname.includes('worldshine3.mayo.llc') ||window.location.hostname.includes('site3') || window.location.hostname.includes('ws3')) ? "Cloverleaf LLC" : "International LLC"); return (window.location.hostname.includes('worldshine2.mayo.llc') || window.location.hostname.includes('site2') || window.location.host.includes('ws2') ||window.location.hostname.includes('localhost')) ? "Care LLC" : ((window.location.hostname.includes('worldshine3.mayo.llc') ||window.location.hostname.includes('site3') || window.location.hostname.includes('ws3')) ? "Cloverleaf LLC" : "International LLC");
} }

View File

@@ -0,0 +1,91 @@
export const HR_TITLE_DISPLAY_MAP = {
ACTIVITY_ASSISTANT: "Activity Assistant",
ACTIVITY_COORDINATOR: "Activity Coordinator",
ACTIVITY_DIRECTOR: "Activity Manager",
ACTIVITY_SPECIALIST: "Activity Specialist",
ADMINISTRATION_ASSISTANT: "Administration Assistant",
ADMINISTRATOR: "Administrator",
ASSISTANT_PROGRAM_DIRECTOR: "Assistant Program Director",
BILLING_MANAGER: "Billing Manager",
BUILDING_ENGINEER: "Building Engineer",
BUSINESS_DEVELOPMENT_SPECIALIST: "Business Development Specialist",
BUSINESS_INTELLIGENCE_ANALYST: "Business Intelligence Analyst",
CAREGIVER: "Caregiver",
CENTER_COORDINATOR: "Center Coordinator",
CERTIFIED_MEDICATION_TECHNICIAN: "Certified Medication Technician",
CERTIFIED_NURSE_ASSISTANT: "CNA",
CEO: "CEO",
CFO: "CFO",
CHEF: "Chef",
CHEF_ASSISTANT: "Chef Assistant",
COMPLIANCE_MANAGER: "Compliance Manager",
COO: "COO",
DEPUTY_CENTER_DIRECTOR: "Deputy Center Director",
DIRECTOR_OF_ACCOUNTING: "Director of Accounting",
DIRECTOR_OF_OPERATIONS: "Director of Operations",
DRIVER: "Driver",
DRIVER_TEAM_LEAD: "Driver Team Lead",
EXECUTIVE_ASSISTANT: "Executive Assistant",
EXECUTIVE_CHEF: "Executive Chef",
FINANCE_ADMIN_MANAGER: "Finance & Administration Manager",
FINANCIAL_ANALYST: "Financial Analyst",
FLEET_MANAGEMENT_SPECIALIST: "Fleet Management Specialist",
FLEET_MANAGER: "Fleet Manager",
FOOD_SERVICE_DIRECTOR: "Food Service Director",
FOOD_SERVICES_COORDINATOR: "Food Service Coordinator",
HANDYMAN: "Handyman",
HEAD_NURSE: "Nursing Manager",
HR: "HR",
HR_AND_ADMINISTRATIVE_COORDINATOR: "HR & Administrative Coordinator",
INTERN: "Intern",
IT_SPECIALIST: "IT Specialist",
IT_SUPPORT: "IT Support",
JANITOR: "Janitor",
KITCHEN_ASSISTANT: "Kitchen Staff",
KITCHEN_HELPER: "Kitchen Helper",
KITCHEN_MANAGER: "Kitchen Manager",
LOBBY_ASSISTANT: "Lobby Assistant",
LOBBY_MANAGER: "Lobby Manager",
MARKETING_SPECIALIST: "Marketing Specialist",
MEDICAL_APPOINTMENT_COORDINATOR: "Medical Appointment Coordinator",
MEDICAL_APPOINTMENT_SCHEDULER: "Medical Appointment Scheduler",
MEDICAL_DRIVER: "Medical Driver",
NURSING_DIRECTOR: "Nursing Director",
OFFICE_MANAGER: "Office Manager",
OPRATIONS_DIRECTOR: "Center Director",
PASTRY_CHEF: "Pastry Chef",
PRESIDENT: "President",
PROCESS_ASSISTANT: "Program Assistant",
PROGRAM_ASSISTANT: "Program Assistant",
PROGRAM_ASSISTANT_DRIVER: "Program Assistant - Driver",
PROGRAM_ASSISTANT_MEDICAL_DRIVER: "Program Assistant - Medical Driver",
PROGRAM_ASSISTANT_MEDICAL_DRIVER_LEAD: "Program Assistant - Medical Driver Lead",
PROGRAM_DIRECTOR: "Program Director",
PROJECT_ASSISTANT: "Project Assistant",
PROJECT_DIRECTOR: "Project Director",
QUALITY_CONTROL_SPECIALIST: "Quality Control Specialist",
REGISTERED_NURSE: "Registered Nurse",
SOCIAL_AND_COMMUNITY_SERVICE_MANAGER: "Social and Community Service Manager",
SOCIAL_WORK: "Social Work",
SOCIAL_WORK_ASSISTANT: "Social Work Assistant",
SOCIAL_WORK_DIRECTOR: "Social Work Director",
SOCIAL_WORKER_MANAGER: "Social Work Manager",
SPIRITUAL_CARE_SPECIALIST: "Spiritual Care Specialist",
TRANSPORTATION_COORDINATOR: "Transportation Coordinator",
TRANSPORTATION_DIRECTOR: "Transportation Manager",
VP: "VP"
};
export const getHrTitleDisplayName = (titleValue) => {
const raw = `${titleValue || ""}`.trim();
if (!raw) return "";
if (HR_TITLE_DISPLAY_MAP[raw]) return HR_TITLE_DISPLAY_MAP[raw];
if (raw.includes("_")) {
return raw
.toLowerCase()
.split("_")
.map((part) => (part ? part[0].toUpperCase() + part.slice(1) : ""))
.join(" ");
}
return raw;
};

View File

@@ -1,6 +1,7 @@
export * from "./customer.constant"; export * from "./customer.constant";
export * from "./route-status.constant"; export * from "./route-status.constant";
export * from "./employee.constant"; export * from "./employee.constant";
export * from "./hr-title.constant";
export * from "./report.constant"; export * from "./report.constant";
export * from "./vehicle.constant"; export * from "./vehicle.constant";
export * from "./resource.constant"; export * from "./resource.constant";