import axios from 'axios' const api = axios.create({ baseURL: '/api', headers: { 'Content-Type': 'application/json' } }) // Add auth token and normalize pagination params api.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } // Send both perpage and per_page for backend compatibility if (config.params?.perpage) { config.params.per_page = config.params.perpage } return config }) // Handle 401 errors (token expired) - only redirect if user was logged in api.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { const hadToken = localStorage.getItem('token') localStorage.removeItem('token') localStorage.removeItem('user') // Only redirect if user was previously logged in (session expired) if (hadToken) { window.location.href = '/login' } } return Promise.reject(error) } ) export default api // Auth API export const authApi = { login(username, password) { return api.post('/auth/login', { username, password }) }, logout() { return api.post('/auth/logout') }, me() { return api.get('/auth/me') }, refresh() { const refreshToken = localStorage.getItem('refreshToken') return api.post('/auth/refresh', {}, { headers: { Authorization: `Bearer ${refreshToken}` } }) } } // Equipment API (plugin) export const equipmentApi = { list(params = {}) { return api.get('/equipment', { params }) }, get(id) { return api.get(`/equipment/${id}`) }, getByAsset(assetId) { return api.get(`/equipment/by-asset/${assetId}`) }, create(data) { return api.post('/equipment', data) }, update(id, data) { return api.put(`/equipment/${id}`, data) }, delete(id) { return api.delete(`/equipment/${id}`) }, dashboardSummary() { return api.get('/equipment/dashboard/summary') }, // Equipment types types: { list(params = {}) { return api.get('/equipment/types', { params }) }, get(id) { return api.get(`/equipment/types/${id}`) }, create(data) { return api.post('/equipment/types', data) }, update(id, data) { return api.put(`/equipment/types/${id}`, data) } } } // Computers API (plugin) export const computersApi = { list(params = {}) { return api.get('/computers', { params }) }, get(id) { return api.get(`/computers/${id}`) }, getByAsset(assetId) { return api.get(`/computers/by-asset/${assetId}`) }, getByHostname(hostname) { return api.get(`/computers/by-hostname/${hostname}`) }, create(data) { return api.post('/computers', data) }, update(id, data) { return api.put(`/computers/${id}`, data) }, delete(id) { return api.delete(`/computers/${id}`) }, dashboardSummary() { return api.get('/computers/dashboard/summary') }, // Computer types types: { list(params = {}) { return api.get('/computers/types', { params }) }, get(id) { return api.get(`/computers/types/${id}`) }, create(data) { return api.post('/computers/types', data) }, update(id, data) { return api.put(`/computers/types/${id}`, data) } } } // Relationship Types API export const relationshipTypesApi = { list() { return api.get('/assets/relationshiptypes') }, create(data) { return api.post('/assets/relationshiptypes', data) } } // Machine Types API export const machinetypesApi = { list(params = {}) { return api.get('/machinetypes', { params }) }, create(data) { return api.post('/machinetypes', data) }, update(id, data) { return api.put(`/machinetypes/${id}`, data) }, delete(id) { return api.delete(`/machinetypes/${id}`) } } // Vendors API export const vendorsApi = { list(params = {}) { return api.get('/vendors', { params }) }, get(id) { return api.get(`/vendors/${id}`) }, create(data) { return api.post('/vendors', data) }, update(id, data) { return api.put(`/vendors/${id}`, data) }, delete(id) { return api.delete(`/vendors/${id}`) } } // Locations API export const locationsApi = { list(params = {}) { return api.get('/locations', { params }) }, get(id) { return api.get(`/locations/${id}`) }, create(data) { return api.post('/locations', data) }, update(id, data) { return api.put(`/locations/${id}`, data) }, delete(id) { return api.delete(`/locations/${id}`) }, types: { list() { return api.get('/locations/types') } } } // Printers API export const printersApi = { list(params = {}) { return api.get('/printers', { params }) }, get(id) { return api.get(`/printers/${id}`) }, // create/update write asset core + printer extension in one call (the // printers plugin owns both). Use these instead of the legacy machinesApi. create(data) { return api.post('/printers', data) }, update(id, data) { return api.put(`/printers/${id}`, data) }, updateExtension(id, data) { return api.put(`/printers/${id}/printerdata`, data) }, // printer sub-types (Laser, Inkjet, Label, Card, Wide Format, ...) types: { list(params = {}) { return api.get('/printers/types', { params }) }, create(data) { return api.post('/printers/types', data) } }, updateCommunication(id, data) { return api.put(`/printers/${id}/communication`, data) }, getSupplies(id) { return api.get(`/printers/${id}/supplies`) }, getDrivers(id) { return api.get(`/printers/${id}/drivers`) }, lowSupplies() { return api.get('/printers/lowsupplies') }, refreshSupplies() { return api.post('/printers/supplies/refresh') }, lookup({ ip, fqdn } = {}) { return api.get('/printers/lookup', { params: { ip, fqdn } }) }, dashboardSummary() { return api.get('/printers/dashboard/summary') }, drivers: { list() { return api.get('/printers/drivers') }, create(data) { return api.post('/printers/drivers', data) }, update(id, data) { return api.put(`/printers/drivers/${id}`, data) }, delete(id) { return api.delete(`/printers/drivers/${id}`) } }, supplyTypes: { list() { return api.get('/printers/supplytypes') }, create(data) { return api.post('/printers/supplytypes', data) } }, // model -> toner/drum/waste part-number management modelSupplies: { meta() { return api.get('/printers/supplies/meta') }, listModels(params = {}) { return api.get('/printers/models', { params }) }, list(modelnumberid) { return api.get(`/printers/models/${modelnumberid}/supplies`) }, create(modelnumberid, data) { return api.post(`/printers/models/${modelnumberid}/supplies`, data) }, update(modelsupplyid, data) { return api.put(`/printers/supplies/${modelsupplyid}`, data) }, delete(modelsupplyid) { return api.delete(`/printers/supplies/${modelsupplyid}`) } } } // Dashboard API export const dashboardApi = { summary() { return api.get('/dashboard/summary') }, navigation() { return api.get('/dashboard/navigation') } } // Models API export const modelsApi = { list(params = {}) { return api.get('/models', { params }) }, // Backend caps perpage at 100, so page through every model. Returns the // full array directly (not an axios response). Use in forms whose model // dropdown must include the editing record's model regardless of page. async listAll() { const first = await api.get('/models', { params: { perpage: 100, page: 1 } }) let items = first.data.data || [] const totalpages = first.data.meta?.pagination?.totalpages || 1 if (totalpages > 1) { const rest = await Promise.all( Array.from({ length: totalpages - 1 }, (_, i) => api.get('/models', { params: { perpage: 100, page: i + 2 } }) ) ) rest.forEach(r => { items = items.concat(r.data.data || []) }) } return items }, get(id) { return api.get(`/models/${id}`) }, create(data) { return api.post('/models', data) }, update(id, data) { return api.put(`/models/${id}`, data) }, delete(id) { return api.delete(`/models/${id}`) } } // Operating Systems API export const operatingsystemsApi = { list(params = {}) { return api.get('/operatingsystems', { params }) }, get(id) { return api.get(`/operatingsystems/${id}`) }, create(data) { return api.post('/operatingsystems', data) }, update(id, data) { return api.put(`/operatingsystems/${id}`, data) }, delete(id) { return api.delete(`/operatingsystems/${id}`) } } // Business Units API export const businessunitsApi = { list(params = {}) { return api.get('/businessunits', { params }) }, get(id) { return api.get(`/businessunits/${id}`) }, create(data) { return api.post('/businessunits', data) }, update(id, data) { return api.put(`/businessunits/${id}`, data) }, delete(id) { return api.delete(`/businessunits/${id}`) } } // Applications API export const applicationsApi = { list(params = {}) { return api.get('/applications', { params }) }, get(id) { return api.get(`/applications/${id}`) }, create(data) { return api.post('/applications', data) }, update(id, data) { return api.put(`/applications/${id}`, data) }, delete(id) { return api.delete(`/applications/${id}`) }, // Versions getVersions(appId) { return api.get(`/applications/${appId}/versions`) }, createVersion(appId, data) { return api.post(`/applications/${appId}/versions`, data) }, // Get PCs that have this app installed getInstalledOn(appId) { return api.get(`/applications/${appId}/installed`) }, // Machine applications (installed apps) getMachineApps(machineId) { return api.get(`/applications/machines/${machineId}`) }, installApp(machineId, data) { return api.post(`/applications/machines/${machineId}`, data) }, uninstallApp(machineId, appId) { return api.delete(`/applications/machines/${machineId}/${appId}`) }, updateInstalledApp(machineId, appId, data) { return api.put(`/applications/machines/${machineId}/${appId}`, data) }, // Support teams getSupportTeams() { return api.get('/applications/supportteams') }, createSupportTeam(data) { return api.post('/applications/supportteams', data) }, // App owners getAppOwners() { return api.get('/applications/appowners') }, createAppOwner(data) { return api.post('/applications/appowners', data) } } // Search API export const searchApi = { search(query, params = {}) { return api.get('/search', { params: { q: query, ...params } }) } } // Knowledge Base API export const knowledgebaseApi = { list(params = {}) { return api.get('/knowledgebase', { params }) }, get(id) { return api.get(`/knowledgebase/${id}`) }, create(data) { return api.post('/knowledgebase', data) }, update(id, data) { return api.put(`/knowledgebase/${id}`, data) }, delete(id) { return api.delete(`/knowledgebase/${id}`) }, trackClick(id) { return api.post(`/knowledgebase/${id}/click`) }, getStats() { return api.get('/knowledgebase/stats') } } // Assets API (unified) export const assetsApi = { list(params = {}) { return api.get('/assets', { params }) }, get(id) { return api.get(`/assets/${id}`) }, create(data) { return api.post('/assets', data) }, update(id, data) { return api.put(`/assets/${id}`, data) }, delete(id) { return api.delete(`/assets/${id}`) }, getMap(params = {}) { return api.get('/assets/map', { params }) }, // Relationships getRelationships(id) { return api.get(`/assets/${id}/relationships`) }, createRelationship(data) { return api.post('/assets/relationships', data) }, deleteRelationship(relationshipId) { return api.delete(`/assets/relationships/${relationshipId}`) }, // Search assets (for relationship picker) search(query, params = {}) { return api.get('/assets', { params: { search: query, ...params } }) }, // Lookup asset by asset/machine number lookup(assetnumber) { return api.get(`/assets/lookup/${encodeURIComponent(assetnumber)}`) }, types: { list() { return api.get('/assets/types') }, get(id) { return api.get(`/assets/types/${id}`) } }, statuses: { list(params = {}) { return api.get('/assets/statuses', { params }) }, create(data) { return api.post('/assets/statuses', data) }, update(id, data) { return api.put(`/assets/statuses/${id}`, data) }, delete(id) { return api.delete(`/assets/statuses/${id}`) } } } // Notifications API export const notificationsApi = { list(params = {}) { return api.get('/notifications', { params }) }, get(id) { return api.get(`/notifications/${id}`) }, create(data) { return api.post('/notifications', data) }, update(id, data) { return api.put(`/notifications/${id}`, data) }, delete(id) { return api.delete(`/notifications/${id}`) }, getActive() { return api.get('/notifications/active') }, getCalendar(params = {}) { return api.get('/notifications/calendar', { params }) }, dashboardSummary() { return api.get('/notifications/dashboard/summary') }, getShopfloor(params = {}) { return api.get('/notifications/shopfloor', { params }) }, getEmployeeRecognitions(sso) { return api.get(`/notifications/employee/${sso}`) }, types: { list() { return api.get('/notifications/types') }, create(data) { return api.post('/notifications/types', data) } } } // USB Devices API export const usbApi = { list(params = {}) { return api.get('/usb', { params }) }, get(id) { return api.get(`/usb/${id}`) }, create(data) { return api.post('/usb', data) }, update(id, data) { return api.put(`/usb/${id}`, data) }, delete(id) { return api.delete(`/usb/${id}`) }, checkout(id, data) { return api.post(`/usb/${id}/checkout`, data) }, checkin(id, data = {}) { return api.post(`/usb/${id}/checkin`, data) }, getHistory(id, params = {}) { return api.get(`/usb/${id}/history`, { params }) }, getAvailable() { return api.get('/usb/available') }, getCheckedOut() { return api.get('/usb/checkedout') }, getUserCheckouts(userId) { return api.get(`/usb/user/${userId}`) }, dashboardSummary() { return api.get('/usb/dashboard/summary') }, types: { list() { return api.get('/usb/types') }, create(data) { return api.post('/usb/types', data) } } } // Reports API export const reportsApi = { list() { return api.get('/reports') }, equipmentByType(params = {}) { return api.get('/reports/equipment-by-type', { params }) }, assetsByStatus(params = {}) { return api.get('/reports/assets-by-status', { params }) }, kbPopularity(params = {}) { return api.get('/reports/kb-popularity', { params }) }, warrantyStatus(params = {}) { return api.get('/reports/warranty-status', { params }) }, softwareCompliance(params = {}) { return api.get('/reports/software-compliance', { params }) }, assetInventory(params = {}) { return api.get('/reports/asset-inventory', { params }) }, pcRelationships(params = {}) { return api.get('/reports/pc-relationships', { params }) } } // Employees API (wjf_employees database) export const employeesApi = { search(query, limit = 10) { return api.get('/employees/search', { params: { q: query, limit } }) }, lookup(sso) { return api.get(`/employees/lookup/${sso}`) }, lookupMultiple(ssoList) { return api.get('/employees/lookup', { params: { sso: ssoList } }) } } // Alias for different casing export const businessUnitsApi = businessunitsApi // Dashboard defaults: visitor-IP -> business-unit mapping for kiosks export const dashboardDefaultsApi = { list() { return api.get('/dashboarddefaults') }, create(data) { return api.post('/dashboarddefaults', data) }, update(id, data) { return api.put(`/dashboarddefaults/${id}`, data) }, delete(id) { return api.delete(`/dashboarddefaults/${id}`) }, // Resolve the calling display's business unit by its IP visitorLocation() { return api.get('/dashboarddefaults/visitor-location') } } // System Settings API export const pluginsApi = { list() { return api.get('/plugins') }, setEnabled(name, enabled) { return api.put(`/plugins/${name}`, { enabled }) } } export const settingsApi = { list(params = {}) { return api.get('/settings', { params }) }, get(key) { return api.get(`/settings/${key}`) }, update(key, value) { return api.put(`/settings/${key}`, { value }) }, create(data) { return api.post('/settings', data) } } // Audit Logs API export const auditLogsApi = { list(params = {}) { return api.get('/auditlogs', { params }) }, getEntityHistory(entitytype, entityid) { return api.get(`/auditlogs/entity/${entitytype}/${entityid}`) }, getStats() { return api.get('/auditlogs/stats') } } // Users API export const usersApi = { list() { return api.get('/users') }, get(id) { return api.get(`/users/${id}`) }, create(data) { return api.post('/users', data) }, update(id, data) { return api.put(`/users/${id}`, data) }, delete(id) { return api.delete(`/users/${id}`) }, // Permissions permissions: { list() { return api.get('/users/permissions') } }, // Roles roles: { list() { return api.get('/users/roles') }, create(data) { return api.post('/users/roles', data) }, update(id, data) { return api.put(`/users/roles/${id}`, data) }, delete(id) { return api.delete(`/users/roles/${id}`) } } } // Network API (devices, subnets, and VLANs) export const networkApi = { // Network devices list(params = {}) { return api.get('/network', { params }) }, get(id) { return api.get(`/network/${id}`) }, getByAsset(assetId) { return api.get(`/network/by-asset/${assetId}`) }, getByHostname(hostname) { return api.get(`/network/by-hostname/${hostname}`) }, create(data) { return api.post('/network', data) }, update(id, data) { return api.put(`/network/${id}`, data) }, delete(id) { return api.delete(`/network/${id}`) }, dashboardSummary() { return api.get('/network/dashboard/summary') }, // Network device types types: { list(params = {}) { return api.get('/network/types', { params }) }, get(id) { return api.get(`/network/types/${id}`) }, create(data) { return api.post('/network/types', data) }, update(id, data) { return api.put(`/network/types/${id}`, data) } }, // VLANs vlans: { list(params = {}) { return api.get('/network/vlans', { params }) }, get(id) { return api.get(`/network/vlans/${id}`) }, create(data) { return api.post('/network/vlans', data) }, update(id, data) { return api.put(`/network/vlans/${id}`, data) }, delete(id) { return api.delete(`/network/vlans/${id}`) } }, // Subnets subnets: { list(params = {}) { return api.get('/network/subnets', { params }) }, get(id) { return api.get(`/network/subnets/${id}`) }, create(data) { return api.post('/network/subnets', data) }, update(id, data) { return api.put(`/network/subnets/${id}`, data) }, delete(id) { return api.delete(`/network/subnets/${id}`) } } }