Add custom fields + warranty plugin, rework settings into two-pane shell
Feature work from the 2026-07 session: Settings IA - Replace the flat 27-card settings hub with a persistent two-pane shell (SettingsLayout.vue): grouped, searchable left rail + content pane. - Nest all settings/* routes under the shell via router post-processing; shared nav catalog in settingsNav.js. Group by asset class (PCs, Printers, Equipment, Network) so per-type settings stop scattering. Custom fields (core) - customfields + customfieldvalues tables (migration 7d14), CRUD API at /api/customfields, per-asset value get/save. - Settings management page + reusable CustomFieldsSection (detail) and CustomFieldsInputs (form) wired into all four asset types. Warranty (new plugin) - plugins/warranty: warranties + warrantyassets (migration 7d15), derived coverage status, provider abstraction (manual now; Dell/Lenovo/HP stubs). - API CRUD + per-asset panel + report buckets; WarrantyPanel on all four detail pages; Warranties management page; Warranty report + Reports card. - Seed warranty.* permissions. Printer drivers - printerdrivers table (migration 7d13) linked to printer models; drivers now surface on the matching printer's detail page. Other - PCDetail rebalanced (Network + Status + Warranty + custom fields on the right). - Rename PCs list "Features" column to "Remote Access"; fix badge hover underline. - Drop equipment islocationonly field. - Centralize asset-type label/route maps into utils/assetTypes.js. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,9 @@ export const equipmentApi = {
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/equipment/types/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/equipment/types/${id}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,6 +140,24 @@ export const computersApi = {
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/computers/types/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/computers/types/${id}`)
|
||||
}
|
||||
},
|
||||
// Remote-access protocol catalog
|
||||
protocols: {
|
||||
list(params = {}) {
|
||||
return api.get('/computers/protocols', { params })
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/computers/protocols', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/computers/protocols/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/computers/protocols/${id}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,6 +169,12 @@ export const relationshipTypesApi = {
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/assets/relationshiptypes', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/assets/relationshiptypes/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/assets/relationshiptypes/${id}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,8 +231,17 @@ export const locationsApi = {
|
||||
return api.delete(`/locations/${id}`)
|
||||
},
|
||||
types: {
|
||||
list() {
|
||||
return api.get('/locations/types')
|
||||
list(params = {}) {
|
||||
return api.get('/locations/types', { params })
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/locations/types', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/locations/types/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/locations/types/${id}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,6 +272,12 @@ export const printersApi = {
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/printers/types', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/printers/types/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/printers/types/${id}`)
|
||||
}
|
||||
},
|
||||
updateCommunication(id, data) {
|
||||
@@ -260,8 +302,8 @@ export const printersApi = {
|
||||
return api.get('/printers/dashboard/summary')
|
||||
},
|
||||
drivers: {
|
||||
list() {
|
||||
return api.get('/printers/drivers')
|
||||
list(params = {}) {
|
||||
return api.get('/printers/drivers', { params })
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/printers/drivers', data)
|
||||
@@ -521,6 +563,9 @@ export const assetsApi = {
|
||||
},
|
||||
get(id) {
|
||||
return api.get(`/assets/types/${id}`)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/assets/types/${id}`, data)
|
||||
}
|
||||
},
|
||||
statuses: {
|
||||
@@ -575,8 +620,14 @@ export const notificationsApi = {
|
||||
list() {
|
||||
return api.get('/notifications/types')
|
||||
},
|
||||
get(id) {
|
||||
return api.get(`/notifications/types/${id}`)
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/notifications/types', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/notifications/types/${id}`, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -718,6 +769,24 @@ export const settingsApi = {
|
||||
}
|
||||
}
|
||||
|
||||
// Slide manager (lobby display + shopfloor screensaver)
|
||||
export const slidesApi = {
|
||||
list(surface) {
|
||||
return api.get(`/slides/${surface}`)
|
||||
},
|
||||
upload(surface, formData) {
|
||||
return api.post(`/slides/${surface}/upload`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
},
|
||||
reorder(surface, order) {
|
||||
return api.post(`/slides/${surface}/order`, { order })
|
||||
},
|
||||
remove(surface, files) {
|
||||
return api.post(`/slides/${surface}/delete`, { files })
|
||||
}
|
||||
}
|
||||
|
||||
// Audit Logs API
|
||||
export const auditLogsApi = {
|
||||
list(params = {}) {
|
||||
@@ -811,6 +880,9 @@ export const networkApi = {
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/network/types/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/network/types/${id}`)
|
||||
}
|
||||
},
|
||||
// VLANs
|
||||
@@ -850,3 +922,55 @@ export const networkApi = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom fields: site-defined attributes per asset type.
|
||||
export const customFieldsApi = {
|
||||
// Definitions
|
||||
list(params = {}) {
|
||||
return api.get('/customfields', { params })
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/customfields', data)
|
||||
},
|
||||
update(fieldid, data) {
|
||||
return api.put(`/customfields/${fieldid}`, data)
|
||||
},
|
||||
remove(fieldid) {
|
||||
return api.delete(`/customfields/${fieldid}`)
|
||||
},
|
||||
// Per-asset values (defs merged with the asset's stored values)
|
||||
forAsset(assetid) {
|
||||
return api.get(`/customfields/asset/${assetid}`)
|
||||
},
|
||||
saveForAsset(assetid, values) {
|
||||
return api.put(`/customfields/asset/${assetid}`, { values })
|
||||
}
|
||||
}
|
||||
|
||||
// Warranty plugin: asset warranty tracking (manual + provider lookups).
|
||||
export const warrantyApi = {
|
||||
list(params = {}) {
|
||||
return api.get('/warranty', { params })
|
||||
},
|
||||
get(id) {
|
||||
return api.get(`/warranty/${id}`)
|
||||
},
|
||||
forAsset(assetid) {
|
||||
return api.get(`/warranty/asset/${assetid}`)
|
||||
},
|
||||
create(data) {
|
||||
return api.post('/warranty', data)
|
||||
},
|
||||
update(id, data) {
|
||||
return api.put(`/warranty/${id}`, data)
|
||||
},
|
||||
remove(id) {
|
||||
return api.delete(`/warranty/${id}`)
|
||||
},
|
||||
refresh(id) {
|
||||
return api.post(`/warranty/${id}/refresh`)
|
||||
},
|
||||
report() {
|
||||
return api.get('/warranty/report')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user