fix: page past the 100-row cap in batch label sheets and asset pickers
Some checks failed
CI / backend (push) Failing after 7s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 9s
CI / migrations-mysql (push) Failing after 6s

Follow-up to the application-picker fix. Three of these were already wrong on
data that exists today, not merely latent.

Batch label printing is the worst of them: AssetLabelBatch asked for 500
machines or PCs, got 100, and printed a sheet that looked complete. With 262
machines and 290 PCs in the catalogue that is a physically short run with no
error anywhere - the operator finds out at the label printer, or later at the
bay with no label on it. PrinterQRBatch, USBLabelBatch and PrintedPartsLabels
had the same shape and are fixed alongside it, before their tables cross 100
too.

MachineForm's "controls" PC dropdown offered the first 100 of 290, so a
machine could not be linked to a PC sorting late in the list. NetworkDeviceForm
had it for models, which are already past 100 - and the same file already
called modelsApi.listAll() correctly two lines away.

Adds listAll() to the machines, computers, printers, network, measuring-tools,
USB and printed-parts APIs, all delegating to fetchAllPages().

Still outstanding: callers of vendors, locations, business units and the type
catalogues that ask for more than 100. Those tables are all well under the cap
today, so they are correct for now and wrong the day they are not.
This commit is contained in:
cproudlock
2026-08-17 14:10:08 -04:00
parent 9c1c6c5729
commit 62f4a42210
7 changed files with 64 additions and 11 deletions

View File

@@ -101,6 +101,13 @@ export const machinesApi = {
list(params = {}) {
return api.get('/machines', { params })
},
// Every machine, paged past the backend's 100-row cap. Batch label printing
// and "pick any record" 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('/machines', params)
},
get(id) {
return api.get(`/machines/${id}`)
},
@@ -144,6 +151,13 @@ export const computersApi = {
list(params = {}) {
return api.get('/computers', { params })
},
// Every PC, paged past the backend's 100-row cap. Batch label printing
// and "pick any record" 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('/computers', params)
},
displayKiosks() {
return api.get('/computers/display-kiosks')
},
@@ -292,6 +306,13 @@ export const printersApi = {
list(params = {}) {
return api.get('/printers', { params })
},
// Every printer, paged past the backend's 100-row cap. Batch label printing
// and "pick any record" 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('/printers', params)
},
get(id) {
return api.get(`/printers/${id}`)
},
@@ -732,6 +753,13 @@ export const usbApi = {
list(params = {}) {
return api.get('/usb', { params })
},
// Every USB device, paged past the backend's 100-row cap. Batch label printing
// and "pick any record" 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('/usb', params)
},
get(id) {
return api.get(`/usb/${id}`)
},
@@ -1065,6 +1093,13 @@ export const networkApi = {
list(params = {}) {
return api.get('/network', { params })
},
// Every network device, paged past the backend's 100-row cap. Batch label
// printing and "pick any record" 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('/network', params)
},
get(id) {
return api.get(`/network/${id}`)
},
@@ -1211,6 +1246,13 @@ export const measuringtoolsApi = {
list(params = {}) {
return api.get('/measuringtools', { params })
},
// Every measuring tool, paged past the backend's 100-row cap. Batch label printing
// and "pick any record" 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('/measuringtools', params)
},
get(id) {
return api.get(`/measuringtools/${id}`)
},
@@ -1254,6 +1296,11 @@ export const printedpartsApi = {
list(params = {}) {
return api.get('/printedparts/items', { params })
},
// Every printed item, paged past the backend's 100-row cap. The label sheet
// must print the whole selection, not the first page of it.
listAll(params = {}) {
return fetchAllPages('/printedparts/items', params)
},
get(printeditemid) {
return api.get(`/printedparts/items/${printeditemid}`)
},

View File

@@ -295,8 +295,10 @@ onMounted(async () => {
codetype.value = (await getSetting('label_default_codetype', 'qr')) === 'barcode' ? 'barcode' : 'qr'
encodes.value = await resolveDefaultEncodes(assettype)
try {
const response = await config.api.list({ perpage: 500 })
assets.value = response.data.data || []
// listAll, not list: perpage is clamped to 100 server-side, so a batch
// sheet built from list() silently omitted every asset past the first
// 100 and printed a short run that looked complete.
assets.value = await config.api.listAll()
} catch (err) {
console.error('Error loading assets:', err)
} finally {