| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /**
- * Navigation Utilities
- *
- * Provides helper functions for consistent navigation behavior throughout the application,
- * specifically for preserving query parameters when navigating between related pages.
- */
-
- /**
- * Creates a navigation path that preserves current URL query parameters
- *
- * @param basePath - The base path to navigate to (e.g., '/datasets/123/documents')
- * @param preserveParams - Whether to preserve current query parameters (default: true)
- * @returns The complete navigation path with preserved query parameters
- *
- * @example
- * // Current URL: /datasets/123/documents/456?page=3&limit=10&keyword=test
- * const backPath = createNavigationPath('/datasets/123/documents')
- * // Returns: '/datasets/123/documents?page=3&limit=10&keyword=test'
- *
- * @example
- * // Navigate without preserving params
- * const cleanPath = createNavigationPath('/datasets/123/documents', false)
- * // Returns: '/datasets/123/documents'
- */
- export function createNavigationPath(basePath: string, preserveParams: boolean = true): string {
- if (!preserveParams)
- return basePath
-
- try {
- const searchParams = new URLSearchParams(window.location.search)
- const queryString = searchParams.toString()
- const separator = queryString ? '?' : ''
- return `${basePath}${separator}${queryString}`
- }
- catch (error) {
- // Fallback to base path if there's any error accessing location
- console.warn('Failed to preserve query parameters:', error)
- return basePath
- }
- }
-
- /**
- * Creates a back navigation function that preserves query parameters
- *
- * @param router - Next.js router instance
- * @param basePath - The base path to navigate back to
- * @param preserveParams - Whether to preserve current query parameters (default: true)
- * @returns A function that navigates back with preserved parameters
- *
- * @example
- * const router = useRouter()
- * const backToPrev = createBackNavigation(router, `/datasets/${datasetId}/documents`)
- *
- * // Later, when user clicks back:
- * backToPrev()
- */
- export function createBackNavigation(
- router: { push: (path: string) => void },
- basePath: string,
- preserveParams: boolean = true,
- ): () => void {
- return () => {
- const navigationPath = createNavigationPath(basePath, preserveParams)
- router.push(navigationPath)
- }
- }
-
- /**
- * Extracts specific query parameters from current URL
- *
- * @param paramNames - Array of parameter names to extract
- * @returns Object with extracted parameters
- *
- * @example
- * // Current URL: /page?page=3&limit=10&keyword=test&other=value
- * const params = extractQueryParams(['page', 'limit', 'keyword'])
- * // Returns: { page: '3', limit: '10', keyword: 'test' }
- */
- export function extractQueryParams(paramNames: string[]): Record<string, string> {
- try {
- const searchParams = new URLSearchParams(window.location.search)
- const extracted: Record<string, string> = {}
-
- paramNames.forEach((name) => {
- const value = searchParams.get(name)
- if (value !== null)
- extracted[name] = value
- })
-
- return extracted
- }
- catch (error) {
- console.warn('Failed to extract query parameters:', error)
- return {}
- }
- }
-
- /**
- * Creates a navigation path with specific query parameters
- *
- * @param basePath - The base path
- * @param params - Object of query parameters to include
- * @returns Navigation path with specified parameters
- *
- * @example
- * const path = createNavigationPathWithParams('/datasets/123/documents', {
- * page: '1',
- * limit: '25',
- * keyword: 'search term'
- * })
- * // Returns: '/datasets/123/documents?page=1&limit=25&keyword=search+term'
- */
- export function createNavigationPathWithParams(
- basePath: string,
- params: Record<string, string | number>,
- ): string {
- try {
- const searchParams = new URLSearchParams()
-
- Object.entries(params).forEach(([key, value]) => {
- if (value !== undefined && value !== null && value !== '')
- searchParams.set(key, String(value))
- })
-
- const queryString = searchParams.toString()
- const separator = queryString ? '?' : ''
- return `${basePath}${separator}${queryString}`
- }
- catch (error) {
- console.warn('Failed to create navigation path with params:', error)
- return basePath
- }
- }
-
- /**
- * Merges current query parameters with new ones
- *
- * @param newParams - New parameters to add or override
- * @param preserveExisting - Whether to preserve existing parameters (default: true)
- * @returns URLSearchParams object with merged parameters
- *
- * @example
- * // Current URL: /page?page=3&limit=10
- * const merged = mergeQueryParams({ keyword: 'test', page: '1' })
- * // Results in: page=1&limit=10&keyword=test (page overridden, limit preserved, keyword added)
- */
- export function mergeQueryParams(
- newParams: Record<string, string | number | null | undefined>,
- preserveExisting: boolean = true,
- ): URLSearchParams {
- const searchParams = preserveExisting
- ? new URLSearchParams(window.location.search)
- : new URLSearchParams()
-
- Object.entries(newParams).forEach(([key, value]) => {
- if (value === null || value === undefined)
- searchParams.delete(key)
- else if (value !== '')
- searchParams.set(key, String(value))
- })
-
- return searchParams
- }
-
- /**
- * Navigation utilities for common dataset/document patterns
- */
- export const datasetNavigation = {
- /**
- * Creates navigation back to dataset documents list with preserved state
- */
- backToDocuments: (router: { push: (path: string) => void }, datasetId: string) => {
- return createBackNavigation(router, `/datasets/${datasetId}/documents`)
- },
-
- /**
- * Creates navigation to document detail
- */
- toDocumentDetail: (router: { push: (path: string) => void }, datasetId: string, documentId: string) => {
- return () => router.push(`/datasets/${datasetId}/documents/${documentId}`)
- },
-
- /**
- * Creates navigation to document settings
- */
- toDocumentSettings: (router: { push: (path: string) => void }, datasetId: string, documentId: string) => {
- return () => router.push(`/datasets/${datasetId}/documents/${documentId}/settings`)
- },
- }
|