diff --git a/inventory/static/js/table.js b/inventory/static/js/table.js index 3b5d52b..d4a3380 100644 --- a/inventory/static/js/table.js +++ b/inventory/static/js/table.js @@ -1,31 +1,115 @@ function Table(cfg) { - return { - id: cfg.id, - refreshUrl: cfg.refreshUrl, - headers: cfg.headers || [], - perPage: cfg.perPage || 10, - offset: cfg.offset || 0, - fields: cfg.fields || [], + return { + id: cfg.id, + refreshUrl: cfg.refreshUrl, + headers: cfg.headers || [], + fields: cfg.fields || [], + // external API + perPage: cfg.perPage || 10, + offset: cfg.offset || 0, - init() { - if (this.refreshUrl) this.refresh(); - }, + // derived + server-fed state + page: Math.floor((cfg.offset || 0) / (cfg.perPage || 10)) + 1, + total: 0, + pages: 0, - buildRefreshUrl() { - if (!this.refreshUrl) return null; - const u = new URL(this.refreshUrl, window.location.origin); - u.search = new URLSearchParams({ view: 'table', offset: this.offset, 'limit': this.perPage, 'fields': this.fields }).toString(); - return u.toString(); - }, + init() { + if (this.refreshUrl) this.refresh(); + }, - async refresh() { - const url = this.buildRefreshUrl(); - if (!url) return; - const res = await fetch(url, { headers: { 'HX-Request': 'true' } }); - const text = await res.text(); - if (this.$refs.body) { - this.$refs.body.innerHTML = text; - } - } - }; -} \ No newline at end of file + buildRefreshUrl() { + if (!this.refreshUrl) return null; + const u = new URL(this.refreshUrl, window.location.origin); + + // We want server-side pagination with page/per_page + u.searchParams.set('view', 'table'); + u.searchParams.set('page', this.page); + u.searchParams.set('per_page', this.perPage); + + // Send requested fields in the way your backend expects + // If your route supports &field=... repeaters, do this: + this.fields.forEach(f => u.searchParams.append('field', f)); + // If your route only supports "fields=a,b,c", then use: + // if (this.fields.length) u.searchParams.set('fields', this.fields.join(',')); + + return u.toString(); + }, + + async refresh() { + const url = this.buildRefreshUrl(); + if (!url) return; + const res = await fetch(url, { headers: { 'X-Requested-With': 'fetch' } }); + const html = await res.text(); + + // Dump the server-rendered rows into the tbody + if (this.$refs.body) this.$refs.body.innerHTML = html; + + // Read pagination metadata from headers + const toInt = (v, d=0) => { + const n = parseInt(v ?? '', 10); + return Number.isFinite(n) ? n : d; + }; + + const total = toInt(res.headers.get('X-Total')); + const pages = toInt(res.headers.get('X-Pages')); + const page = toInt(res.headers.get('X-Page'), this.page); + const per = toInt(res.headers.get('X-Per-Page'), this.perPage); + + // Update local state + this.total = total; + this.pages = pages; + this.page = page; + this.perPage = per; + this.offset = (this.page - 1) * this.perPage; + + // Update pager UI (if you put