Persist list pagination and search in the URL
List pages kept the current page in local state, so clicking into an asset and hitting Back remounted the list at page 1. A shared useListQuery composable now mirrors the page (and search term) into the URL query via router.replace across all 18 list pages, so Back restores the page you were on and lists are deep-linkable. Page 1 with no search stays a bare path; changing a filter resets to page 1; unrelated query keys are preserved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,10 @@ ADR-007 and ADR-002.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- List pages keep the current page (and search term) in the URL query, so
|
||||||
|
paging to page 9, opening an item, and hitting browser Back returns to page 9
|
||||||
|
instead of resetting to page 1. Applies to all 18 list views via a shared
|
||||||
|
useListQuery composable; page 1 with no search stays a bare path.
|
||||||
- PC detail Installed Applications no longer 500s and silently disappears on
|
- PC detail Installed Applications no longer 500s and silently disappears on
|
||||||
real PCs (ComputerInstalledApp had no to_dict); the section renders app
|
real PCs (ComputerInstalledApp had no to_dict); the section renders app
|
||||||
name, version, and description again.
|
name, version, and description again.
|
||||||
|
|||||||
102
frontend/src/composables/listQuery.js
Normal file
102
frontend/src/composables/listQuery.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
// Keep a list page's current page and search term in the URL query so the
|
||||||
|
// browser Back button restores them. Without this a list keeps page in local
|
||||||
|
// state and remounts at page 1 after visiting a detail page and going Back.
|
||||||
|
//
|
||||||
|
// Usage in a list view:
|
||||||
|
// const { page, search, setPage, setSearch } = useListQuery({ onChange: loadRows })
|
||||||
|
// goToPage(p) -> setPage(p); loadRows()
|
||||||
|
// debouncedSearch -> setSearch(search.value); loadRows()
|
||||||
|
// filter reset -> setPage(1); loadRows()
|
||||||
|
//
|
||||||
|
// Options:
|
||||||
|
// onChange callback run when the query changes from outside (Back/Forward,
|
||||||
|
// deep link) so the list reloads at the restored page.
|
||||||
|
// extraKeys optional extra query keys to persist (e.g. ['typeid']); each
|
||||||
|
// gets a ref exposed under the returned `extras` object.
|
||||||
|
export function useListQuery(options = {}) {
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const onChange = options.onChange || (() => {})
|
||||||
|
const extraKeys = options.extraKeys || []
|
||||||
|
|
||||||
|
const page = ref(parseInt(route.query.page, 10) || 1)
|
||||||
|
const search = ref(route.query.q || '')
|
||||||
|
|
||||||
|
const extras = {}
|
||||||
|
for (const key of extraKeys) {
|
||||||
|
extras[key] = ref(route.query[key] || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the next query. Keep unrelated keys intact. Write page only when > 1
|
||||||
|
// and search only when non-empty so the clean state is a bare path.
|
||||||
|
function buildQuery() {
|
||||||
|
const query = { ...route.query }
|
||||||
|
if (page.value > 1) query.page = String(page.value)
|
||||||
|
else delete query.page
|
||||||
|
if (search.value) query.q = search.value
|
||||||
|
else delete query.q
|
||||||
|
for (const key of extraKeys) {
|
||||||
|
if (extras[key].value) query[key] = String(extras[key].value)
|
||||||
|
else delete query[key]
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace (not push) so paging does not spam history; Back leaves the list.
|
||||||
|
function syncUrl() {
|
||||||
|
const query = buildQuery()
|
||||||
|
const current = route.query
|
||||||
|
const keys = new Set([...Object.keys(query), ...Object.keys(current)])
|
||||||
|
let same = true
|
||||||
|
for (const key of keys) {
|
||||||
|
if (String(query[key] ?? '') !== String(current[key] ?? '')) {
|
||||||
|
same = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!same) router.replace({ query })
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPage(newPage) {
|
||||||
|
page.value = newPage
|
||||||
|
syncUrl()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changing the search resets to page 1.
|
||||||
|
function setSearch(term) {
|
||||||
|
search.value = term
|
||||||
|
page.value = 1
|
||||||
|
syncUrl()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changing an extra filter resets to page 1.
|
||||||
|
function setExtra(key, value) {
|
||||||
|
extras[key].value = value
|
||||||
|
page.value = 1
|
||||||
|
syncUrl()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-sync refs when the query changes from outside (Back/Forward, deep link).
|
||||||
|
// Fire onChange only when page/search/extras actually changed so a self
|
||||||
|
// syncUrl() call does not trigger a redundant reload.
|
||||||
|
watch(() => route.query, (newQuery) => {
|
||||||
|
const newPage = parseInt(newQuery.page, 10) || 1
|
||||||
|
const newSearch = newQuery.q || ''
|
||||||
|
let changed = false
|
||||||
|
if (newPage !== page.value) { page.value = newPage; changed = true }
|
||||||
|
if (newSearch !== search.value) { search.value = newSearch; changed = true }
|
||||||
|
for (const key of extraKeys) {
|
||||||
|
const newValue = newQuery[key] || ''
|
||||||
|
if (newValue !== String(extras[key].value || '')) {
|
||||||
|
extras[key].value = newValue
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) onChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
return { page, search, extras, setPage, setSearch, setExtra }
|
||||||
|
}
|
||||||
@@ -101,12 +101,12 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { applicationsApi } from '../../api'
|
import { applicationsApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const applications = ref([])
|
const applications = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadApplications })
|
||||||
const filter = ref('installable')
|
const filter = ref('installable')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -145,19 +145,19 @@ async function loadApplications() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadApplications()
|
loadApplications()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadApplications()
|
loadApplications()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadApplications()
|
loadApplications()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -111,15 +111,15 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { knowledgebaseApi, applicationsApi } from '../../api'
|
import { knowledgebaseApi, applicationsApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const articles = ref([])
|
const articles = ref([])
|
||||||
const topics = ref([])
|
const topics = ref([])
|
||||||
const stats = ref(null)
|
const stats = ref(null)
|
||||||
const page = ref(1)
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadArticles })
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const search = ref('')
|
|
||||||
const topicFilter = ref('')
|
const topicFilter = ref('')
|
||||||
const sort = ref('clicks')
|
const sort = ref('clicks')
|
||||||
const order = ref('desc')
|
const order = ref('desc')
|
||||||
@@ -177,19 +177,19 @@ async function loadStats() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadArticles()
|
loadArticles()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadArticles()
|
loadArticles()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadArticles()
|
loadArticles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { colorStyle } from "@/utils/colorStyle"
|
import { colorStyle } from "@/utils/colorStyle"
|
||||||
import { machinesApi } from '../../api'
|
import { machinesApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const machines = ref([])
|
const machines = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadMachines })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -123,19 +123,19 @@ async function loadMachines() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadMachines()
|
loadMachines()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadMachines()
|
loadMachines()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadMachines()
|
loadMachines()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -96,14 +96,14 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { colorStyle } from '@/utils/colorStyle'
|
import { colorStyle } from '@/utils/colorStyle'
|
||||||
import { measuringtoolsApi } from '../../api'
|
import { measuringtoolsApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const tools = ref([])
|
const tools = ref([])
|
||||||
const types = ref([])
|
const types = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadTools })
|
||||||
const typeid = ref('')
|
const typeid = ref('')
|
||||||
const calibrationstatus = ref('')
|
const calibrationstatus = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -142,23 +142,26 @@ async function loadTools() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadTools()
|
loadTools()
|
||||||
}
|
}
|
||||||
|
|
||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(reload, 300)
|
searchTimeout = setTimeout(() => {
|
||||||
|
setSearch(search.value)
|
||||||
|
loadTools()
|
||||||
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadTools()
|
loadTools()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadTools()
|
loadTools()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -121,17 +121,17 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { colorStyle } from "@/utils/colorStyle"
|
import { colorStyle } from "@/utils/colorStyle"
|
||||||
import { networkApi, vendorsApi, locationsApi } from '../../api'
|
import { networkApi, vendorsApi, locationsApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const devices = ref([])
|
const devices = ref([])
|
||||||
const deviceTypes = ref([])
|
const deviceTypes = ref([])
|
||||||
const vendors = ref([])
|
const vendors = ref([])
|
||||||
const locations = ref([])
|
const locations = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadDevices })
|
||||||
const selectedType = ref(null)
|
const selectedType = ref(null)
|
||||||
const vendorFilter = ref('')
|
const vendorFilter = ref('')
|
||||||
const locationFilter = ref('')
|
const locationFilter = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(25)
|
const perPage = ref(25)
|
||||||
const totalCount = ref(0)
|
const totalCount = ref(0)
|
||||||
@@ -217,28 +217,28 @@ async function loadDevices() {
|
|||||||
|
|
||||||
function selectType(typeId) {
|
function selectType(typeId) {
|
||||||
selectedType.value = typeId
|
selectedType.value = typeId
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
if (p >= 1 && p <= totalPages.value) {
|
if (p >= 1 && p <= totalPages.value) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,14 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { notificationsApi } from '@/api'
|
import { notificationsApi } from '@/api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const notifications = ref([])
|
const notifications = ref([])
|
||||||
const types = ref([])
|
const types = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const searchQuery = ref('')
|
const { page, search: searchQuery, setPage, setSearch } = useListQuery({ onChange: loadNotifications })
|
||||||
const selectedType = ref('')
|
const selectedType = ref('')
|
||||||
const currentFilter = ref('')
|
const currentFilter = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
@@ -152,19 +152,19 @@ async function loadNotifications() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(searchQuery.value)
|
||||||
loadNotifications()
|
loadNotifications()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadNotifications()
|
loadNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadNotifications()
|
loadNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { computersApi } from '../../api'
|
import { computersApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { colorStyle } from '@/utils/colorStyle'
|
import { colorStyle } from '@/utils/colorStyle'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const computers = ref([])
|
const computers = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadComputers })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -126,19 +126,19 @@ async function loadComputers() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadComputers()
|
loadComputers()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadComputers()
|
loadComputers()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadComputers()
|
loadComputers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,13 +90,13 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { printersApi } from '../../api'
|
import { printersApi } from '../../api'
|
||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
|
|
||||||
const printers = ref([])
|
const printers = ref([])
|
||||||
const printerTypes = ref([])
|
const printerTypes = ref([])
|
||||||
const typeFilter = ref('')
|
const typeFilter = ref('')
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadPrinters })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -135,24 +135,24 @@ async function loadPrinters() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadPrinters()
|
loadPrinters()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFilterChange() {
|
function onFilterChange() {
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadPrinters()
|
loadPrinters()
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadPrinters()
|
loadPrinters()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadPrinters()
|
loadPrinters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,11 +103,12 @@ import { businessunitsApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const items = ref([])
|
const items = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const page = ref(1)
|
const { page, setPage } = useListQuery({ onChange: loadData })
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -136,11 +137,11 @@ async function loadData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) { page.value = p; loadData() }
|
function goToPage(p) { setPage(p); loadData() }
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,14 +213,14 @@ import { locationsApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const locations = ref([])
|
const locations = ref([])
|
||||||
const locationTypes = ref([])
|
const locationTypes = ref([])
|
||||||
const allLocations = ref([])
|
const allLocations = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadLocations })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -286,19 +286,19 @@ async function loadLocations() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadLocations()
|
loadLocations()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadLocations()
|
loadLocations()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadLocations()
|
loadLocations()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,11 +147,12 @@ import { modeltypesApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const modelTypes = ref([])
|
const modelTypes = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const page = ref(1)
|
const { page, setPage } = useListQuery({ onChange: loadTypes })
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -192,13 +193,13 @@ async function loadTypes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadTypes()
|
loadTypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadTypes()
|
loadTypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,15 +209,15 @@ import { modelsApi, vendorsApi, modeltypesApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const models = ref([])
|
const models = ref([])
|
||||||
const vendors = ref([])
|
const vendors = ref([])
|
||||||
const modelTypes = ref([])
|
const modelTypes = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadModels })
|
||||||
const vendorFilter = ref('')
|
const vendorFilter = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -290,19 +290,19 @@ async function loadModelTypes() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadModels()
|
loadModels()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadModels()
|
loadModels()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadModels()
|
loadModels()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,11 +121,12 @@ import { operatingsystemsApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const items = ref([])
|
const items = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const page = ref(1)
|
const { page, setPage } = useListQuery({ onChange: loadData })
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -154,11 +155,11 @@ async function loadData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) { page.value = p; loadData() }
|
function goToPage(p) { setPage(p); loadData() }
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,11 +141,12 @@ import PaginationBar from '../../components/PaginationBar.vue'
|
|||||||
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'
|
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const statuses = ref([])
|
const statuses = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const page = ref(1)
|
const { page, setPage } = useListQuery({ onChange: loadStatuses })
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -186,13 +187,13 @@ async function loadStatuses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadStatuses()
|
loadStatuses()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadStatuses()
|
loadStatuses()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ import { networkApi, locationsApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -295,10 +296,9 @@ const subnets = ref([])
|
|||||||
const vlans = ref([])
|
const vlans = ref([])
|
||||||
const locations = ref([])
|
const locations = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadSubnets })
|
||||||
const vlanFilter = ref('')
|
const vlanFilter = ref('')
|
||||||
const typeFilter = ref('')
|
const typeFilter = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -383,19 +383,19 @@ async function loadSubnets() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadSubnets()
|
loadSubnets()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadSubnets()
|
loadSubnets()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadSubnets()
|
loadSubnets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,13 +189,13 @@ import { networkApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const vlans = ref([])
|
const vlans = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadVLANs })
|
||||||
const typeFilter = ref('')
|
const typeFilter = ref('')
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -243,19 +243,19 @@ async function loadVLANs() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadVLANs()
|
loadVLANs()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadVLANs()
|
loadVLANs()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadVLANs()
|
loadVLANs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,12 +149,12 @@ import EmployeeSearch from '../../components/EmployeeSearch.vue'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const devices = ref([])
|
const devices = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadDevices })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
const showAvailableOnly = ref(false)
|
const showAvailableOnly = ref(false)
|
||||||
@@ -195,19 +195,19 @@ async function loadDevices() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
frontend/src/views/vendors/VendorsList.vue
vendored
10
frontend/src/views/vendors/VendorsList.vue
vendored
@@ -188,12 +188,12 @@ import { vendorsApi } from '../../api'
|
|||||||
import PaginationBar from '../../components/PaginationBar.vue'
|
import PaginationBar from '../../components/PaginationBar.vue'
|
||||||
import { useToast } from '../../composables/toast'
|
import { useToast } from '../../composables/toast'
|
||||||
import { apiError } from '../../utils/apiError'
|
import { apiError } from '../../utils/apiError'
|
||||||
|
import { useListQuery } from '@/composables/listQuery'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const vendors = ref([])
|
const vendors = ref([])
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const search = ref('')
|
const { page, search, setPage, setSearch } = useListQuery({ onChange: loadVendors })
|
||||||
const page = ref(1)
|
|
||||||
const totalPages = ref(1)
|
const totalPages = ref(1)
|
||||||
const perPage = ref(20)
|
const perPage = ref(20)
|
||||||
|
|
||||||
@@ -243,19 +243,19 @@ async function loadVendors() {
|
|||||||
function debouncedSearch() {
|
function debouncedSearch() {
|
||||||
clearTimeout(searchTimeout)
|
clearTimeout(searchTimeout)
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
page.value = 1
|
setSearch(search.value)
|
||||||
loadVendors()
|
loadVendors()
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(p) {
|
function goToPage(p) {
|
||||||
page.value = p
|
setPage(p)
|
||||||
loadVendors()
|
loadVendors()
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePerPage(newPerPage) {
|
function changePerPage(newPerPage) {
|
||||||
perPage.value = newPerPage
|
perPage.value = newPerPage
|
||||||
page.value = 1
|
setPage(1)
|
||||||
loadVendors()
|
loadVendors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user