Files
digifi-bko/src/_digifi/helpers/crud-helper/helpers.tsx
T
2024-05-03 10:48:00 +01:00

125 lines
3.2 KiB
TypeScript

import {createContext, Dispatch, SetStateAction, useEffect, useState} from 'react'
import qs from 'qs'
import {ID, QueryResponseContextProps, QueryState} from './models'
function createResponseContext<T>(initialState: QueryResponseContextProps<T>) {
return createContext(initialState)
}
function isNotEmpty(obj: unknown) {
return obj !== undefined && obj !== null && obj !== ''
}
// Example: page=1&items_per_page=10&sort=id&order=desc&search=a&filter_name=a&filter_online=false
function stringifyRequestQuery(state: QueryState): string {
const pagination = qs.stringify(state, {filter: ['page', 'items_per_page'], skipNulls: true})
const sort = qs.stringify(state, {filter: ['sort', 'order'], skipNulls: true})
const search = isNotEmpty(state.search)
? qs.stringify(state, {filter: ['search'], skipNulls: true})
: ''
const filter = state.filter
? Object.entries(state.filter)
.filter((obj) => isNotEmpty(obj[1]))
.map((obj) => {
return `filter_${obj[0]}=${obj[1]}`
})
.join('&')
: ''
return [pagination, sort, search, filter]
.filter((f) => f)
.join('&')
.toLowerCase()
}
function parseRequestQuery(query: string): QueryState {
const cache: unknown = qs.parse(query)
return cache as QueryState
}
function calculatedGroupingIsDisabled<T>(isLoading: boolean, data: Array<T> | undefined): boolean {
if (isLoading) {
return true
}
return !data || !data.length
}
function calculateIsAllDataSelected<T>(data: Array<T> | undefined, selected: Array<ID>): boolean {
if (!data) {
return false
}
return data.length > 0 && data.length === selected.length
}
function groupingOnSelect(
id: ID,
selected: Array<ID>,
setSelected: Dispatch<SetStateAction<Array<ID>>>
) {
if (!id) {
return
}
if (selected.includes(id)) {
setSelected(selected.filter((itemId) => itemId !== id))
} else {
const updatedSelected = [...selected]
updatedSelected.push(id)
setSelected(updatedSelected)
}
}
function groupingOnSelectAll<T>(
isAllSelected: boolean,
setSelected: Dispatch<SetStateAction<Array<ID>>>,
data?: Array<T & {uid?: ID}>
) {
if (isAllSelected) {
setSelected([])
return
}
if (!data || !data.length) {
return
}
setSelected(data.filter((item) => item.uid).map((item) => item.uid))
}
// Hook
function useDebounce(value: string | undefined, delay: number) {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value)
useEffect(
() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler)
}
},
[value, delay] // Only re-call effect if value or delay changes
)
return debouncedValue
}
export {
createResponseContext,
stringifyRequestQuery,
parseRequestQuery,
calculatedGroupingIsDisabled,
calculateIsAllDataSelected,
groupingOnSelect,
groupingOnSelectAll,
useDebounce,
isNotEmpty,
}