This commit is contained in:
@@ -47,7 +47,6 @@ const ALL_PERMISSIONS = [
|
|||||||
'Edit_Vehicle info_Repair Records',
|
'Edit_Vehicle info_Repair Records',
|
||||||
'Add_New Vehicle',
|
'Add_New Vehicle',
|
||||||
'Archive_Vehicle',
|
'Archive_Vehicle',
|
||||||
'Delete_Vehicle',
|
|
||||||
'Export_Vehicle Report',
|
'Export_Vehicle Report',
|
||||||
'View_Transportation Schedule_Route Overview',
|
'View_Transportation Schedule_Route Overview',
|
||||||
'Create&Edit_Transportation Schedule',
|
'Create&Edit_Transportation Schedule',
|
||||||
@@ -145,4 +144,31 @@ exports.login = (req, res) => {
|
|||||||
} else {
|
} else {
|
||||||
throw(Error('email or username is required'));
|
throw(Error('email or username is required'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.me = (req, res) => {
|
||||||
|
const condition = splitSite.splitSiteGet(req, { _id: req.userId });
|
||||||
|
Employee.findOne(condition)
|
||||||
|
.then((employee) => {
|
||||||
|
if (!employee) {
|
||||||
|
return res.status(404).send({ message: "User not found" });
|
||||||
|
}
|
||||||
|
if (!isEmployeeActive(employee)) {
|
||||||
|
return res.status(403).send({ message: "User is not activated" });
|
||||||
|
}
|
||||||
|
return res.send({
|
||||||
|
username: employee.username,
|
||||||
|
email: employee.email,
|
||||||
|
roles: employee.roles,
|
||||||
|
permissions: getEffectivePermissions(employee),
|
||||||
|
id: employee.id,
|
||||||
|
name: employee.name,
|
||||||
|
name_cn: employee.name_cn
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
res.status(500).send({
|
||||||
|
message: err.message || "Failed to fetch current user"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
const auth = require("../controllers/auth.controller");
|
const auth = require("../controllers/auth.controller");
|
||||||
|
const { authJwt } = require("../middlewares");
|
||||||
app.use(function(req, res, next) {
|
app.use(function(req, res, next) {
|
||||||
res.header(
|
res.header(
|
||||||
"Access-Control-Allow-Headers",
|
"Access-Control-Allow-Headers",
|
||||||
@@ -8,4 +9,5 @@ module.exports = app => {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
app.post('/api/auth/login', auth.login);
|
app.post('/api/auth/login', auth.login);
|
||||||
|
app.get('/api/auth/me', [authJwt.verifyToken], auth.me);
|
||||||
};
|
};
|
||||||
@@ -89,6 +89,7 @@ import { AuthService } from "./services";
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [showMenu, setShowMenu] = useState(false);
|
const [showMenu, setShowMenu] = useState(false);
|
||||||
|
const [isPermissionReady, setIsPermissionReady] = useState(false);
|
||||||
// const getLogo = () => {
|
// const getLogo = () => {
|
||||||
// return (window.location.hostname.includes('worldshine2.mayo.llc') || window.location.hostname.includes('site2') || window.location.host.includes('ws2') ||window.location.hostname.includes('localhost')) ? "/images/logo2.png" : ((window.location.hostname.includes('worldshine3.mayo.llc') ||window.location.hostname.includes('site3') || window.location.hostname.includes('ws3')) ? "/images/logo3.png" : "/images/logo1.png");
|
// return (window.location.hostname.includes('worldshine2.mayo.llc') || window.location.hostname.includes('site2') || window.location.host.includes('ws2') ||window.location.hostname.includes('localhost')) ? "/images/logo2.png" : ((window.location.hostname.includes('worldshine3.mayo.llc') ||window.location.hostname.includes('site3') || window.location.hostname.includes('ws3')) ? "/images/logo3.png" : "/images/logo1.png");
|
||||||
// }
|
// }
|
||||||
@@ -158,6 +159,32 @@ function App() {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let isMounted = true;
|
||||||
|
const recheckPermissions = async () => {
|
||||||
|
try {
|
||||||
|
if (localStorage.getItem('token')) {
|
||||||
|
await AuthService.refreshCurrentUserPermissions();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Token failures are handled by axios interceptor (logout + redirect).
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
if (isMounted) {
|
||||||
|
setIsPermissionReady(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recheckPermissions();
|
||||||
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!isPermissionReady) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* <div className="logo">
|
{/* <div className="logo">
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import moment from 'moment';
|
|||||||
|
|
||||||
const InfoScreen = () => {
|
const InfoScreen = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const canEditInfoScreen = AuthService.canEditInfoScreen();
|
||||||
const canViewAppointmentCalendar = AuthService.hasPermission('View_Appointment Calendar');
|
const canViewAppointmentCalendar = AuthService.hasPermission('View_Appointment Calendar');
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [medicalEvents, setMedicalEvents] = useState([]);
|
const [medicalEvents, setMedicalEvents] = useState([]);
|
||||||
@@ -793,14 +794,16 @@ const InfoScreen = () => {
|
|||||||
<img src="/images/logo-trans.png" alt="Worldshine Logo" style={{ height: '30px', marginRight: '10px' }} />
|
<img src="/images/logo-trans.png" alt="Worldshine Logo" style={{ height: '30px', marginRight: '10px' }} />
|
||||||
<strong className="logo-worldshine" style={{ color: '#0066B1', fontSize: '16px' }}>Worldshine</strong>
|
<strong className="logo-worldshine" style={{ color: '#0066B1', fontSize: '16px' }}>Worldshine</strong>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
{canEditInfoScreen && (
|
||||||
variant="link"
|
<Button
|
||||||
className="p-0"
|
variant="link"
|
||||||
onClick={handleEditClick}
|
className="p-0"
|
||||||
style={{ color: '#666' }}
|
onClick={handleEditClick}
|
||||||
>
|
style={{ color: '#666' }}
|
||||||
<PencilSquare size={16} />
|
>
|
||||||
</Button>
|
<PencilSquare size={16} />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content Layout */}
|
{/* Content Layout */}
|
||||||
@@ -848,14 +851,16 @@ const InfoScreen = () => {
|
|||||||
{/* Header with Title and Edit Button */}
|
{/* Header with Title and Edit Button */}
|
||||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
<h6 className="text-black mb-0" style={{ fontSize: '14px', fontWeight: '500' }}>Gallery</h6>
|
<h6 className="text-black mb-0" style={{ fontSize: '14px', fontWeight: '500' }}>Gallery</h6>
|
||||||
<Button
|
{canEditInfoScreen && (
|
||||||
variant="link"
|
<Button
|
||||||
className="p-0"
|
variant="link"
|
||||||
onClick={handleCarouselEditClick}
|
className="p-0"
|
||||||
style={{ color: '#666' }}
|
onClick={handleCarouselEditClick}
|
||||||
>
|
style={{ color: '#666' }}
|
||||||
<PencilSquare size={16} />
|
>
|
||||||
</Button>
|
<PencilSquare size={16} />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Image Carousel */}
|
{/* Image Carousel */}
|
||||||
@@ -1173,9 +1178,11 @@ const InfoScreen = () => {
|
|||||||
|
|
||||||
{!isFullScreen && (
|
{!isFullScreen && (
|
||||||
<div className="list-func-panel">
|
<div className="list-func-panel">
|
||||||
<button className="btn btn-primary me-2" onClick={handleBackgroundSelect}>
|
{canEditInfoScreen && (
|
||||||
<FileImage size={16} className="me-2"></FileImage>Choose Background
|
<button className="btn btn-primary me-2" onClick={handleBackgroundSelect}>
|
||||||
</button>
|
<FileImage size={16} className="me-2"></FileImage>Choose Background
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
<button className="btn btn-primary me-2" onClick={handleFullScreen}>
|
<button className="btn btn-primary me-2" onClick={handleFullScreen}>
|
||||||
<ArrowsFullscreen size={16} className="me-2"></ArrowsFullscreen>Full Screen
|
<ArrowsFullscreen size={16} className="me-2"></ArrowsFullscreen>Full Screen
|
||||||
</button>
|
</button>
|
||||||
@@ -1185,7 +1192,7 @@ const InfoScreen = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Edit AttendanceNote Modal */}
|
{/* Edit AttendanceNote Modal */}
|
||||||
<Modal show={showEditModal} onHide={handleCloseModal} size="lg">
|
{canEditInfoScreen && <Modal show={showEditModal} onHide={handleCloseModal} size="lg">
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>Edit Attendance Note</Modal.Title>
|
<Modal.Title>Edit Attendance Note</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
@@ -1264,10 +1271,10 @@ const InfoScreen = () => {
|
|||||||
Save Changes
|
Save Changes
|
||||||
</Button>
|
</Button>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
||||||
</Modal>
|
</Modal>}
|
||||||
|
|
||||||
{/* Gallery Edit Modal */}
|
{/* Gallery Edit Modal */}
|
||||||
<Modal show={showGalleryModal} onHide={handleGalleryClose} size="lg">
|
{canEditInfoScreen && <Modal show={showGalleryModal} onHide={handleGalleryClose} size="lg">
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>Update Images</Modal.Title>
|
<Modal.Title>Update Images</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
@@ -1333,10 +1340,10 @@ const InfoScreen = () => {
|
|||||||
Save Changes
|
Save Changes
|
||||||
</Button>
|
</Button>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
||||||
</Modal>
|
</Modal>}
|
||||||
|
|
||||||
{/* Background Selection Modal */}
|
{/* Background Selection Modal */}
|
||||||
<Modal show={showBackgroundModal} onHide={handleBackgroundClose} size="md">
|
{canEditInfoScreen && <Modal show={showBackgroundModal} onHide={handleBackgroundClose} size="md">
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>Choose Background Image</Modal.Title>
|
<Modal.Title>Choose Background Image</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
@@ -1386,7 +1393,7 @@ const InfoScreen = () => {
|
|||||||
Save Background
|
Save Background
|
||||||
</Button>
|
</Button>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
||||||
</Modal>
|
</Modal>}
|
||||||
|
|
||||||
{/* Full Screen Hint */}
|
{/* Full Screen Hint */}
|
||||||
{isFullScreen && (
|
{isFullScreen && (
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'react-datepicker/dist/react-datepicker.css';
|
|||||||
|
|
||||||
const MessageList = () => {
|
const MessageList = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const canEditMessagingTemplate = AuthService.hasPermission('Create&Edit_Messaging Template');
|
||||||
const [messages, setMessages] = useState([]);
|
const [messages, setMessages] = useState([]);
|
||||||
const [activeTab, setActiveTab] = useState('allMessages');
|
const [activeTab, setActiveTab] = useState('allMessages');
|
||||||
|
|
||||||
@@ -90,6 +91,7 @@ const MessageList = () => {
|
|||||||
|
|
||||||
// ---- Custom Template CRUD ----
|
// ---- Custom Template CRUD ----
|
||||||
const openCreateTemplateModal = () => {
|
const openCreateTemplateModal = () => {
|
||||||
|
if (!canEditMessagingTemplate) return;
|
||||||
setEditingTemplate(null);
|
setEditingTemplate(null);
|
||||||
setTemplateTitle('');
|
setTemplateTitle('');
|
||||||
setTemplateChinese('');
|
setTemplateChinese('');
|
||||||
@@ -98,6 +100,7 @@ const MessageList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openEditTemplateModal = (template) => {
|
const openEditTemplateModal = (template) => {
|
||||||
|
if (!canEditMessagingTemplate) return;
|
||||||
setEditingTemplate(template);
|
setEditingTemplate(template);
|
||||||
setTemplateTitle(template.title || '');
|
setTemplateTitle(template.title || '');
|
||||||
setTemplateChinese(template.chinese || '');
|
setTemplateChinese(template.chinese || '');
|
||||||
@@ -114,6 +117,7 @@ const MessageList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveTemplate = () => {
|
const handleSaveTemplate = () => {
|
||||||
|
if (!canEditMessagingTemplate) return;
|
||||||
if (!templateTitle.trim()) { window.alert('Template Title is required.'); return; }
|
if (!templateTitle.trim()) { window.alert('Template Title is required.'); return; }
|
||||||
if (!templateChinese.trim()) { window.alert('Message Content (Chinese) is required.'); return; }
|
if (!templateChinese.trim()) { window.alert('Message Content (Chinese) is required.'); return; }
|
||||||
if (!templateEnglish.trim()) { window.alert('Message Content (English) is required.'); return; }
|
if (!templateEnglish.trim()) { window.alert('Message Content (English) is required.'); return; }
|
||||||
@@ -131,6 +135,7 @@ const MessageList = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteTemplate = (id) => {
|
const handleDeleteTemplate = (id) => {
|
||||||
|
if (!canEditMessagingTemplate) return;
|
||||||
if (window.confirm('Are you sure you want to delete this template?')) {
|
if (window.confirm('Are you sure you want to delete this template?')) {
|
||||||
MessageService.deleteCustomTemplate(id).then(() => { fetchCustomTemplates(); });
|
MessageService.deleteCustomTemplate(id).then(() => { fetchCustomTemplates(); });
|
||||||
}
|
}
|
||||||
@@ -399,7 +404,7 @@ const MessageList = () => {
|
|||||||
<th>Template Title</th>
|
<th>Template Title</th>
|
||||||
<th>Message Content (Chinese)</th>
|
<th>Message Content (Chinese)</th>
|
||||||
<th>Message Content (English)</th>
|
<th>Message Content (English)</th>
|
||||||
<th style={{ width: '80px' }}>Actions</th>
|
{canEditMessagingTemplate && <th style={{ width: '80px' }}>Actions</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -409,14 +414,14 @@ const MessageList = () => {
|
|||||||
<td>{template?.title}</td>
|
<td>{template?.title}</td>
|
||||||
<td style={{ maxWidth: '300px', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>{template?.chinese}</td>
|
<td style={{ maxWidth: '300px', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>{template?.chinese}</td>
|
||||||
<td style={{ maxWidth: '300px', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>{template?.english}</td>
|
<td style={{ maxWidth: '300px', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>{template?.english}</td>
|
||||||
<td>
|
{canEditMessagingTemplate && <td>
|
||||||
<PencilSquare size={16} className="clickable me-2" onClick={() => openEditTemplateModal(template)} />
|
<PencilSquare size={16} className="clickable me-2" onClick={() => openEditTemplateModal(template)} />
|
||||||
<Trash size={16} className="clickable" color="#dc3545" onClick={() => handleDeleteTemplate(template.id)} />
|
<Trash size={16} className="clickable" color="#dc3545" onClick={() => handleDeleteTemplate(template.id)} />
|
||||||
</td>
|
</td>}
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
{customTemplates.length === 0 && (
|
{customTemplates.length === 0 && (
|
||||||
<tr><td colSpan="5" style={{ textAlign: 'center', color: '#999', padding: '24px' }}>No templates yet. Create one to get started.</td></tr>
|
<tr><td colSpan={canEditMessagingTemplate ? 5 : 4} style={{ textAlign: 'center', color: '#999', padding: '24px' }}>No templates yet. Create one to get started.</td></tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -482,14 +487,14 @@ const MessageList = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{activeTab === 'messageTemplate' && (
|
{activeTab === 'messageTemplate' && (
|
||||||
<button className="btn btn-primary btn-sm" onClick={openCreateTemplateModal}><Plus size={16} className="me-1" />Create Message Template</button>
|
canEditMessagingTemplate && <button className="btn btn-primary btn-sm" onClick={openCreateTemplateModal}><Plus size={16} className="me-1" />Create Message Template</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Create / Edit Message Template Modal */}
|
{/* Create / Edit Message Template Modal */}
|
||||||
<Modal show={showCreateTemplateModal} onHide={closeTemplateModal} centered>
|
<Modal show={canEditMessagingTemplate && showCreateTemplateModal} onHide={closeTemplateModal} centered>
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title>{editingTemplate ? 'Edit Message Template' : 'Create New Message Template'}</Modal.Title>
|
<Modal.Title>{editingTemplate ? 'Edit Message Template' : 'Create New Message Template'}</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
const UpdateVehicle = () => {
|
const UpdateVehicle = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const canArchiveVehicle = AuthService.canArchiveVehicle();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const validTabs = ['basicInfo', 'complianceDeadlines'];
|
const validTabs = ['basicInfo', 'complianceDeadlines'];
|
||||||
@@ -209,6 +210,7 @@ const UpdateVehicle = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const triggerShowDeleteModal = () => {
|
const triggerShowDeleteModal = () => {
|
||||||
|
if (!canArchiveVehicle) return;
|
||||||
setShowDeleteModal(true);
|
setShowDeleteModal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,6 +219,7 @@ const UpdateVehicle = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deactivateVehicle = () => {
|
const deactivateVehicle = () => {
|
||||||
|
if (!canArchiveVehicle) return;
|
||||||
const data = buildVehicleData();
|
const data = buildVehicleData();
|
||||||
data.status = 'inactive';
|
data.status = 'inactive';
|
||||||
dispatch(deleteVehicle({id: params.id, data}));
|
dispatch(deleteVehicle({id: params.id, data}));
|
||||||
@@ -451,7 +454,7 @@ const UpdateVehicle = () => {
|
|||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="list-func-panel">
|
<div className="list-func-panel">
|
||||||
<button className="btn btn-primary" onClick={() => triggerShowDeleteModal()}><Archive size={16} className="me-2"></Archive>Archive</button>
|
{canArchiveVehicle && <button className="btn btn-primary" onClick={() => triggerShowDeleteModal()}><Archive size={16} className="me-2"></Archive>Archive</button>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,20 @@ const login = (data) => {
|
|||||||
return http.post('/auth/login', data);
|
return http.post('/auth/login', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCurrentUserFromServer = () => {
|
||||||
|
return http.get('/auth/me');
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshCurrentUserPermissions = async () => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
if (!token) return null;
|
||||||
|
const { data } = await getCurrentUserFromServer();
|
||||||
|
if (data) {
|
||||||
|
localStorage.setItem('user', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
const logout = (data, shouldClearSession = false) => {
|
const logout = (data, shouldClearSession = false) => {
|
||||||
if (shouldClearSession) {
|
if (shouldClearSession) {
|
||||||
localStorage.removeItem('user');
|
localStorage.removeItem('user');
|
||||||
@@ -162,10 +176,9 @@ const canViewVehicleRepairs = () => hasAnyPermission(['View_Vehicle info_Repair
|
|||||||
const canEditVehicleRepairs = () => hasPermission('Edit_Vehicle info_Repair Records');
|
const canEditVehicleRepairs = () => hasPermission('Edit_Vehicle info_Repair Records');
|
||||||
const canAddVehicle = () => hasPermission('Add_New Vehicle');
|
const canAddVehicle = () => hasPermission('Add_New Vehicle');
|
||||||
const canArchiveVehicle = () => hasPermission('Archive_Vehicle');
|
const canArchiveVehicle = () => hasPermission('Archive_Vehicle');
|
||||||
const canDeleteVehicle = () => hasPermission('Delete_Vehicle');
|
|
||||||
const canExportVehicleReport = () => hasPermission('Export_Vehicle Report');
|
const canExportVehicleReport = () => hasPermission('Export_Vehicle Report');
|
||||||
const canViewVehicleAny = () => canViewVehicleBasic() || canViewVehicleDocuments() || canViewVehicleRepairs() || canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle() || canDeleteVehicle() || canExportVehicleReport();
|
const canViewVehicleAny = () => canViewVehicleBasic() || canViewVehicleDocuments() || canViewVehicleRepairs() || canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle() || canExportVehicleReport();
|
||||||
const canEditVehicleAny = () => canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle() || canDeleteVehicle();
|
const canEditVehicleAny = () => canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle();
|
||||||
|
|
||||||
const canViewDashboard = () => {
|
const canViewDashboard = () => {
|
||||||
return hasPermission('Dashboard');
|
return hasPermission('Dashboard');
|
||||||
@@ -178,6 +191,10 @@ const canViewInfoScreen = () => {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canEditInfoScreen = () => {
|
||||||
|
return hasPermission('Edit_Info Screen');
|
||||||
|
}
|
||||||
|
|
||||||
const canViewCalendar = () => {
|
const canViewCalendar = () => {
|
||||||
return canViewAnyCalendarTab() || canEditAnyCalendarTab();
|
return canViewAnyCalendarTab() || canEditAnyCalendarTab();
|
||||||
}
|
}
|
||||||
@@ -395,10 +412,13 @@ const getLocalAccessToken = () => {
|
|||||||
|
|
||||||
export const AuthService = {
|
export const AuthService = {
|
||||||
login,
|
login,
|
||||||
|
getCurrentUserFromServer,
|
||||||
|
refreshCurrentUserPermissions,
|
||||||
logout,
|
logout,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
canViewDashboard,
|
canViewDashboard,
|
||||||
canViewInfoScreen,
|
canViewInfoScreen,
|
||||||
|
canEditInfoScreen,
|
||||||
canViewCalendarTab,
|
canViewCalendarTab,
|
||||||
canEditCalendarTab,
|
canEditCalendarTab,
|
||||||
canViewAnyCalendarTab,
|
canViewAnyCalendarTab,
|
||||||
@@ -443,7 +463,6 @@ export const AuthService = {
|
|||||||
canEditVehicleRepairs,
|
canEditVehicleRepairs,
|
||||||
canAddVehicle,
|
canAddVehicle,
|
||||||
canArchiveVehicle,
|
canArchiveVehicle,
|
||||||
canDeleteVehicle,
|
|
||||||
canExportVehicleReport,
|
canExportVehicleReport,
|
||||||
canViewVehicleAny,
|
canViewVehicleAny,
|
||||||
canEditVehicleAny,
|
canEditVehicleAny,
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ export const EMPLOYEE_PERMISSION_GROUPS = {
|
|||||||
'Edit_Vehicle info_Repair Records',
|
'Edit_Vehicle info_Repair Records',
|
||||||
'Add_New Vehicle',
|
'Add_New Vehicle',
|
||||||
'Archive_Vehicle',
|
'Archive_Vehicle',
|
||||||
'Delete_Vehicle',
|
|
||||||
'Export_Vehicle Report'
|
'Export_Vehicle Report'
|
||||||
],
|
],
|
||||||
Transportation: [
|
Transportation: [
|
||||||
|
|||||||
Reference in New Issue
Block a user