UNPKG

@elastic-suite/gally-admin-shared

Version:
215 lines (193 loc) 5.95 kB
import { currentPage, defaultPageSize, pageSize, rangeSeparator, searchParameter, usePagination, } from '../constants' import { ISearchParameters } from '../types' import { removeEmptyParameters } from './api' function formatDateParameterForUrl(param: Date): string { // We force the dd/MM/yyyy HH:mm:ss to we can guess a param in url is a date without knowing anything else const date = param.toLocaleDateString('en-GB').replace(/-/g, '/') const time = param.toLocaleTimeString('en-GB', { hour12: false }) return `${date} ${time}` } function getRangeParameterFromUrl(param: string): (string | Date)[] { return param.split(rangeSeparator).map((v) => { // Date parameters always follow the dd/MM/yyyy HH:mm:ss regardless of locale const datePattern = /^(\d{2})\/(\d{2})\/(\d{4})\s(\d{2}):(\d{2}):(\d{2})$/ const match = v.match(datePattern) if (match) { const [, day, month, year, hours, minutes, seconds] = match // Create date from dd/MM/yyyy HH:mm:ss format return new Date( Number(year), Number(month) - 1, Number(day), Number(hours), Number(minutes), Number(seconds) ) } return v }) } function formatRangeParameterForUrl( value: ISearchParameters[keyof ISearchParameters] ): string { if (Array.isArray(value)) { return value .map((v) => v instanceof Date ? formatDateParameterForUrl(v) : String(v ?? '') ) .join(rangeSeparator) } return String(value) } function isValidRange(value: (string | number | Date)[]): boolean { return value.some((v) => v !== '' && v !== null) } export function getUrl( urlParam: string | URL, searchParameters: ISearchParameters = {} ): URL { const url: URL = urlParam instanceof URL ? urlParam : new URL(urlParam) Object.entries(searchParameters).forEach(([key, value]) => { if (key.endsWith('[between]')) { value = value as (string | number | Date)[] if (isValidRange(value as (string | number | Date)[])) { url.searchParams.append(key, formatRangeParameterForUrl(value)) } } else if (value instanceof Array) { value.forEach((value) => url.searchParams.append(key, String(value))) } else { url.searchParams.append(key, String(value)) } }) return url } export function clearParameters(url: URL): URL { ;[...url.searchParams.entries()].forEach(([key]) => url.searchParams.delete(key) ) return url } export function getListParameters( page: number | false = 0, searchParameters: ISearchParameters = {}, searchValue = '', prefix?: string ): ISearchParameters { const pageKey = prefix ? `${prefix}_${currentPage}` : currentPage const searchKey = prefix ? `${prefix}_${searchParameter}` : searchParameter const prefixedSearchParameters = prefix && searchParameters ? Object.fromEntries( Object.entries(searchParameters).map(([key, value]) => [ `${prefix}_${key}`, value, ]) ) : searchParameters if (typeof page === 'number') { return removeEmptyParameters({ ...prefixedSearchParameters, [pageKey]: page === 0 ? '' : page, // If page=0, remove parameter from URL [searchKey]: searchValue, }) } return removeEmptyParameters({ ...searchParameters, [searchKey]: searchValue, }) } export function getListApiParameters( page: number | false = 0, rowsPerPage: number = defaultPageSize, searchParameters: ISearchParameters = {}, searchValue = '' ): ISearchParameters { if (typeof page === 'number') { return removeEmptyParameters({ ...searchParameters, [currentPage]: page + 1, [usePagination]: true, [pageSize]: rowsPerPage, [searchParameter]: searchValue, }) } return removeEmptyParameters({ ...searchParameters, [usePagination]: false, [searchParameter]: searchValue, }) } export function getRouterUrl(path: string): URL { return new URL(`${window.location.origin}${path}`) } export function getRouterPath(path: string): string { const url = getRouterUrl(path) return clearParameters(url).pathname } export function getAppUrl( path: string, page: number | false = 0, activeFilters?: ISearchParameters, searchValue?: string, prefix?: string ): URL { const parameters = getListParameters(page, activeFilters, searchValue, prefix) const url = getRouterUrl(path) return getUrl(clearParameters(url), parameters) } export function getParametersFromUrl( url: URL, prefix?: string ): ISearchParameters { return Object.fromEntries( [...url.searchParams.entries()].reduce((acc, [key, value]) => { // If prefix is provided, only include parameters that start with the prefix if (prefix) { const prefixPattern = `${prefix}_` if (!key.startsWith(prefixPattern)) { return acc } // Remove the prefix from the key key = key.substring(prefixPattern.length) } if (key.endsWith('[between]')) { acc.push([key, getRangeParameterFromUrl(value)]) } else if (key.endsWith('[]')) { const existingValue = acc.find(([accKey]) => accKey === key)?.[1] if (existingValue) { existingValue.push(value) } else { acc.push([key, [value]]) } } else { acc.push([key, value]) } return acc }, []) ) } export function getPageParameter( parameters: ISearchParameters, prefix?: string ): number { const pageEntry = Object.entries(parameters).find( ([key]) => key.replace(`${prefix}_`, '') === currentPage ) return Number(pageEntry?.[1] ?? 0) } export function getSearchParameter( parameters: ISearchParameters, prefix?: string ): string { const pageEntry = Object.entries(parameters).find( ([key]) => key.replace(`${prefix}_`, '') === searchParameter ) return String(pageEntry?.[1] ?? '') }