From 222b9c6fc8f9e74b8b55b28f35dfeb2f25766823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Gr=C3=BCssing?= Date: Tue, 2 Jun 2026 12:22:24 +0200 Subject: [PATCH] Add: Ticket Benutzer-Filter, Dropdown-Styling, User Model Felder fix --- backend/src/models/User.js | 4 ++ backend/src/services/graph.service.js | 2 +- frontend/src/pages/TicketsPage.jsx | 16 ++++- frontend/src/pages/UserManagementPage.jsx | 4 +- frontend/src/styles/App.css | 77 +++++++++++++++++++++++ 5 files changed, 99 insertions(+), 4 deletions(-) diff --git a/backend/src/models/User.js b/backend/src/models/User.js index 05a39c3..54297e7 100644 --- a/backend/src/models/User.js +++ b/backend/src/models/User.js @@ -8,6 +8,8 @@ class User { u.id, u.username, u.email, u.first_name, u.last_name, u.is_active, u.must_change_password, u.email_notifications, u.last_login, u.created_at, u.updated_at, u.role_id, u.azure_id, + u.department, u.position, u.phone, u.location, u.manager_id, + u.cost_center, u.employment_type, u.work_hours, u.joined_date, u.avatar_url, r.name as role_name, r.description as role_description FROM users u LEFT JOIN roles r ON u.role_id = r.id @@ -23,6 +25,8 @@ class User { u.id, u.username, u.email, u.first_name, u.last_name, u.is_active, u.must_change_password, u.email_notifications, u.last_login, u.created_at, u.updated_at, u.role_id, u.azure_id, + u.department, u.position, u.phone, u.location, u.manager_id, + u.cost_center, u.employment_type, u.work_hours, u.joined_date, u.avatar_url, r.name as role_name, r.description as role_description FROM users u LEFT JOIN roles r ON u.role_id = r.id diff --git a/backend/src/services/graph.service.js b/backend/src/services/graph.service.js index 7ab5438..dcaaa3e 100644 --- a/backend/src/services/graph.service.js +++ b/backend/src/services/graph.service.js @@ -1250,4 +1250,4 @@ async function invalidateUserSessions(azureId) { return true; } -module.exports = { pollMailbox, pollMonitoringMailbox, pollMdoAlerts, getTeamsAllChannels, getIntuneManagedDevices, getAzureGroups, getAzureGroupMembers, getEntraSubscribedSkus, getEntraLicenseUsers, getDepartmentManager, searchEntraUserByName, syncItTopicsToPlanner, getPlannerBuckets, getSecureScore, getRiskyUsers, getDefenderAlerts, getNonCompliantDevices, getUsersWithoutMfa, getEntraUsers, getAllMfaRegistrationDetails, getEntraUserGroups, getDirectoryRolesWithMembers, addGroupMember, removeGroupMember, getUserEntraProfile, getUserLicenseDetails, getUserSignInActivity, getUserSignInRisk, getConditionalAccessPolicies, invalidateUserSessions }; +module.exports = { getClientToken, pollMailbox, pollMonitoringMailbox, pollMdoAlerts, getTeamsAllChannels, getIntuneManagedDevices, getAzureGroups, getAzureGroupMembers, getEntraSubscribedSkus, getEntraLicenseUsers, getDepartmentManager, searchEntraUserByName, syncItTopicsToPlanner, getPlannerBuckets, getSecureScore, getRiskyUsers, getDefenderAlerts, getNonCompliantDevices, getUsersWithoutMfa, getEntraUsers, getAllMfaRegistrationDetails, getEntraUserGroups, getDirectoryRolesWithMembers, addGroupMember, removeGroupMember, getUserEntraProfile, getUserLicenseDetails, getUserSignInActivity, getUserSignInRisk, getConditionalAccessPolicies, invalidateUserSessions }; diff --git a/frontend/src/pages/TicketsPage.jsx b/frontend/src/pages/TicketsPage.jsx index 1109cd6..f5d3eb0 100644 --- a/frontend/src/pages/TicketsPage.jsx +++ b/frontend/src/pages/TicketsPage.jsx @@ -172,6 +172,8 @@ const TicketsPage = () => { const [statusFilter, setStatusFilter] = useState(''); const [priorityFilter, setPriorityFilter] = useState(''); const [categoryFilter, setCategoryFilter] = useState(''); + const [userFilter, setUserFilter] = useState(''); + const [allUsers, setAllUsers] = useState([]); const [viewMode, setViewMode] = useState(() => localStorage.getItem('ticketsViewMode') || 'table'); // Drag & Drop @@ -195,7 +197,10 @@ const TicketsPage = () => { }); const [formLoading, setFormLoading] = useState(false); - useEffect(() => { loadAll(); }, [statusFilter, priorityFilter, categoryFilter, searchTerm]); + useEffect(() => { loadAll(); }, [statusFilter, priorityFilter, categoryFilter, searchTerm, userFilter]); + useEffect(() => { + userService.getAll().then(setAllUsers).catch(() => {}); + }, []); // Auto-refresh alle 30 Sekunden useEffect(() => { @@ -233,6 +238,7 @@ const TicketsPage = () => { priority: priorityFilter || undefined, category: categoryFilter || undefined, search: searchTerm || undefined, + assigned_to: userFilter || undefined, }), ticketService.getStats(), ]); @@ -417,6 +423,14 @@ const TicketsPage = () => { ))} + setForm(p => ({...p, employment_type: e.target.value}))}> + @@ -985,7 +985,7 @@ const EditModal = ({ user, allUsers, onClose, onSaved }) => {
- setForm(p => ({...p, manager_id: e.target.value}))}> {allUsers.filter(u => u.id !== user.id).map(u => ( diff --git a/frontend/src/styles/App.css b/frontend/src/styles/App.css index c53c1ce..a605fb4 100644 --- a/frontend/src/styles/App.css +++ b/frontend/src/styles/App.css @@ -4056,3 +4056,80 @@ html[data-theme="light"] .ap-pill:hover { color: #1d1d1f; border-color: #94a3b8; .ap-left-panel { display: none; } .ap-right-panel { padding: 16px; } } + +/* ── Global Select Styling ── */ +select, .form-select, select.form-control { + background-color: #1e293b !important; + color: #f1f5f9 !important; + border: 1px solid rgba(255,255,255,0.1) !important; + border-radius: 8px !important; + padding: 8px 12px !important; + font-size: 14px !important; + outline: none !important; + cursor: pointer !important; + appearance: none !important; + -webkit-appearance: none !important; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important; + background-repeat: no-repeat !important; + background-position: right 12px center !important; + padding-right: 36px !important; + transition: border-color 0.2s !important; +} +select:focus, .form-select:focus, select.form-control:focus { + border-color: #0d9488 !important; + box-shadow: 0 0 0 2px rgba(13,148,136,0.15) !important; +} +select option { + background-color: #1e293b !important; + color: #f1f5f9 !important; +} +select:hover { + border-color: rgba(255,255,255,0.2) !important; +} + +/* ── AP Form Select (AssetsPage) ── */ +.ap-form-input[type="text"], .ap-form-input, select.ap-form-input { + background-color: #1e293b !important; + color: #f1f5f9 !important; + border: 1px solid rgba(255,255,255,0.1) !important; +} + +/* ── BV Modal Select (Benutzerverwaltung) ── */ +.bv-modal-select, .bv-form-select { + background-color: #1e293b; + color: #f1f5f9; + border: 1px solid rgba(255,255,255,0.1); + border-radius: 8px; + padding: 8px 36px 8px 12px; + font-size: 14px; + width: 100%; + outline: none; + cursor: pointer; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 12px center; +} +.bv-modal-select:focus { + border-color: #0d9488; + box-shadow: 0 0 0 2px rgba(13,148,136,0.15); +} + +/* Light Theme Overrides für Global Selects */ +html[data-theme="light"] select, +html[data-theme="light"] .form-select, +html[data-theme="light"] select.form-control { + background-color: #ffffff !important; + color: #0f172a !important; + border-color: #e2e8f0 !important; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important; +} +html[data-theme="light"] select option { + background-color: #ffffff !important; + color: #0f172a !important; +} +html[data-theme="light"] .bv-modal-select { + background-color: #ffffff; + color: #0f172a; + border-color: #e2e8f0; +}