diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js index 0f0fccd3..45db2f13 100644 --- a/frontend/src/api/index.js +++ b/frontend/src/api/index.js @@ -273,6 +273,12 @@ export const locationsApi = { list(params = {}) { return api.get('/locations', { params }) }, + // Every location, paged past the backend's 100-row cap. Location selector + // dropdowns must use this: list() with a large perpage is clamped to 100 and + // still returns a success response, so the tail simply goes missing. + listAll(params = {}) { + return fetchAllPages('/locations', params) + }, get(id) { return api.get(`/locations/${id}`) }, diff --git a/frontend/src/views/reports/ReportsIndex.vue b/frontend/src/views/reports/ReportsIndex.vue index 34457c3d..676a930b 100644 --- a/frontend/src/views/reports/ReportsIndex.vue +++ b/frontend/src/views/reports/ReportsIndex.vue @@ -266,8 +266,10 @@ async function loadFilterOptions(fields) { filterOptions.value.assettypes = response.data.data || [] } if (fields.includes('location') && !filterOptions.value.locations.length) { - const response = await locationsApi.list({ perpage: 100 }) - filterOptions.value.locations = response.data.data || [] + // listAll: 100 is the server-side cap, not a generous limit, and the + // location list is past it - a report filtered by a late-alphabet + // location could not be built. + filterOptions.value.locations = await locationsApi.listAll() } if (fields.includes('application') && !filterOptions.value.applications.length) { // listAll: 100 is the server-side cap, not a generous limit, and the diff --git a/plugins/computers/frontend/views/PCForm.vue b/plugins/computers/frontend/views/PCForm.vue index e1b84148..ea7c8581 100644 --- a/plugins/computers/frontend/views/PCForm.vue +++ b/plugins/computers/frontend/views/PCForm.vue @@ -472,7 +472,7 @@ onMounted(async () => { assetsApi.statuses.list(), vendorsApi.list({ perpage: 100 }), modelsApi.listAll({ category: 'PC' }), // backend caps perpage at 100; page through all - locationsApi.list({ perpage: 100 }), + locationsApi.listAll(), // backend caps perpage at 100; page through all operatingsystemsApi.list({ perpage: 100 }), computersApi.protocols.list(), // Handles its own failure: a site without printers still gets a form. @@ -482,7 +482,7 @@ onMounted(async () => { statuses.value = statusRes.data.data || [] vendors.value = vendorRes.data.data || [] models.value = allModels - locations.value = locRes.data.data || [] + locations.value = locRes || [] operatingsystems.value = osRes.data.data || [] protocols.value = protoRes.data.data || [] diff --git a/plugins/machines/frontend/views/MachineForm.vue b/plugins/machines/frontend/views/MachineForm.vue index ef012ff0..646a5795 100644 --- a/plugins/machines/frontend/views/MachineForm.vue +++ b/plugins/machines/frontend/views/MachineForm.vue @@ -512,7 +512,7 @@ onMounted(async () => { machinesApi.types.list(), assetsApi.statuses.list(), vendorsApi.list({ perpage: 500 }), - locationsApi.list({ perpage: 500 }), + locationsApi.listAll(), // backend caps perpage at 100; page through all modelsApi.listAll({ category: 'Equipment' }), // backend caps perpage at 100; page through all businessunitsApi.list({ perpage: 500 }), computersApi.listAll(), // backend caps perpage at 100; page through all @@ -522,7 +522,7 @@ onMounted(async () => { machineTypes.value = typesRes.data.data || [] statuses.value = statusRes.data.data || [] vendors.value = vendorRes.data.data || [] - locations.value = locRes.data.data || [] + locations.value = locRes || [] models.value = allModels businessunits.value = buRes.data.data || [] // listAll resolves to the ARRAY, not a response: fetchAllPages already diff --git a/plugins/measuringtools/frontend/views/MeasuringToolForm.vue b/plugins/measuringtools/frontend/views/MeasuringToolForm.vue index 8f922299..bb26a61b 100644 --- a/plugins/measuringtools/frontend/views/MeasuringToolForm.vue +++ b/plugins/measuringtools/frontend/views/MeasuringToolForm.vue @@ -181,13 +181,13 @@ onMounted(async () => { const [typesResponse, statusResponse, locResponse, buResponse, assetTypesResponse] = await Promise.all([ measuringtoolsApi.types.list({ perpage: 200 }), assetsApi.statuses.list(), - locationsApi.list({ perpage: 500 }), + locationsApi.listAll(), // backend caps perpage at 100; page through all businessunitsApi.list({ perpage: 500 }), assetsApi.types.list(), ]) types.value = typesResponse.data.data || [] statuses.value = statusResponse.data.data || [] - locations.value = locResponse.data.data || [] + locations.value = locResponse || [] businessunits.value = buResponse.data.data || [] const assetType = (assetTypesResponse.data.data || []).find(a => a.assettype === 'measuring_tool') diff --git a/plugins/network/frontend/views/NetworkDeviceForm.vue b/plugins/network/frontend/views/NetworkDeviceForm.vue index 3559b7e2..ff6c6ef1 100644 --- a/plugins/network/frontend/views/NetworkDeviceForm.vue +++ b/plugins/network/frontend/views/NetworkDeviceForm.vue @@ -460,8 +460,8 @@ async function loadVendors() { async function loadLocations() { try { - const response = await locationsApi.list({ perpage: 100 }) - locations.value = response.data.data || [] + const items = await locationsApi.listAll() // backend caps perpage at 100; page through all + locations.value = items || [] } catch (err) { console.error('Error loading locations:', err) } diff --git a/plugins/network/frontend/views/NetworkDevicesList.vue b/plugins/network/frontend/views/NetworkDevicesList.vue index e6e5719f..efcfd68d 100644 --- a/plugins/network/frontend/views/NetworkDevicesList.vue +++ b/plugins/network/frontend/views/NetworkDevicesList.vue @@ -197,8 +197,8 @@ async function loadVendors() { async function loadLocations() { try { - const response = await locationsApi.list({ perpage: 100 }) - locations.value = response.data.data || [] + const items = await locationsApi.listAll() // backend caps perpage at 100; page through all + locations.value = items || [] } catch (error) { console.error('Error loading locations:', error) } diff --git a/plugins/network/frontend/views/SubnetsList.vue b/plugins/network/frontend/views/SubnetsList.vue index 5dd2967a..5fb092fd 100644 --- a/plugins/network/frontend/views/SubnetsList.vue +++ b/plugins/network/frontend/views/SubnetsList.vue @@ -352,8 +352,8 @@ async function loadVLANs() { async function loadLocations() { try { - const response = await locationsApi.list({ perpage: 100 }) - locations.value = response.data.data || [] + const items = await locationsApi.listAll() // backend caps perpage at 100; page through all + locations.value = items || [] } catch (err) { console.error('Error loading locations:', err) } diff --git a/plugins/printers/frontend/views/PrinterForm.vue b/plugins/printers/frontend/views/PrinterForm.vue index 316dbe74..caa8084a 100644 --- a/plugins/printers/frontend/views/PrinterForm.vue +++ b/plugins/printers/frontend/views/PrinterForm.vue @@ -505,14 +505,14 @@ onMounted(async () => { assetsApi.statuses.list(), vendorsApi.list({ perpage: 100 }), modelsApi.listAll({ category: 'Printer' }), - locationsApi.list({ perpage: 100 }) + locationsApi.listAll() // backend caps perpage at 100; page through all ]) printerTypes.value = mtRes.data.data || [] statuses.value = statusRes.data.data || [] vendors.value = vendorRes.data.data || [] models.value = allModels - locations.value = locRes.data.data || [] + locations.value = locRes || [] // Load printer if editing if (isEdit.value) {