useLogsUrlState.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { createParser, useQueryState } from 'nuqs'
  2. import { Filters } from '@/components/interfaces/Settings/Logs/Logs.types'
  3. interface LogsUrlState {
  4. search: string
  5. timestampStart: string
  6. timestampEnd: string
  7. selectedLogId: string | null
  8. filters: Filters
  9. }
  10. const defaultState: LogsUrlState = {
  11. search: '',
  12. timestampStart: '',
  13. timestampEnd: '',
  14. selectedLogId: null,
  15. filters: {},
  16. }
  17. const stringWithDefault = (defaultValue: string) =>
  18. createParser({
  19. parse: (v) => v ?? defaultValue,
  20. serialize: (v) => v || '',
  21. })
  22. const jsonWithDefault = <T>(defaultValue: T) =>
  23. createParser({
  24. parse: (v) => {
  25. if (!v) return defaultValue
  26. try {
  27. return JSON.parse(v) as T
  28. } catch (e) {
  29. return defaultValue
  30. }
  31. },
  32. serialize: (v) => {
  33. if (!v) return ''
  34. try {
  35. return JSON.stringify(v)
  36. } catch (e) {
  37. return ''
  38. }
  39. },
  40. })
  41. export function useLogsUrlState() {
  42. const [searchValue, setSearchValue] = useQueryState('s', stringWithDefault(defaultState.search))
  43. const [timestampStartValue, setTimestampStartValue] = useQueryState(
  44. 'its',
  45. stringWithDefault(defaultState.timestampStart)
  46. )
  47. const [timestampEndValue, setTimestampEndValue] = useQueryState(
  48. 'ite',
  49. stringWithDefault(defaultState.timestampEnd)
  50. )
  51. const [selectedLogIdValue, setSelectedLogIdValue] = useQueryState('log', stringWithDefault(''))
  52. const [filtersValue, setFiltersValue] = useQueryState(
  53. 'f',
  54. jsonWithDefault<Filters>(defaultState.filters)
  55. )
  56. // Ensure we never return null values
  57. const search = searchValue || defaultState.search
  58. const timestampStart = timestampStartValue || defaultState.timestampStart
  59. const timestampEnd = timestampEndValue || defaultState.timestampEnd
  60. const selectedLogId = selectedLogIdValue || null
  61. const filters = filtersValue || defaultState.filters
  62. const setSearch = (value: string) => {
  63. setSearchValue(value || defaultState.search)
  64. }
  65. const setTimeRange = (start: string, end: string) => {
  66. setTimestampStartValue(start || defaultState.timestampStart)
  67. setTimestampEndValue(end || defaultState.timestampEnd)
  68. }
  69. const setSelectedLogId = (value: string | null) => {
  70. setSelectedLogIdValue(value || '')
  71. }
  72. const setFilters = (value: Filters) => {
  73. setFiltersValue(value || defaultState.filters)
  74. }
  75. const updateFilter = (key: string, value: any) => {
  76. setFilters({ ...filters, [key]: value })
  77. }
  78. const reset = () => {
  79. setSearch(defaultState.search)
  80. setTimestampStartValue(defaultState.timestampStart)
  81. setTimestampEndValue(defaultState.timestampEnd)
  82. setSelectedLogIdValue('')
  83. setFiltersValue(defaultState.filters)
  84. }
  85. return {
  86. // State
  87. search,
  88. timestampStart,
  89. timestampEnd,
  90. selectedLogId,
  91. filters,
  92. // Setters
  93. setSearch,
  94. setTimeRange,
  95. setSelectedLogId,
  96. setFilters,
  97. updateFilter,
  98. reset,
  99. }
  100. }