{"version":3,"file":"LocationService.cjs","sources":["../../../src/services/LocationService.tsx"],"sourcesContent":["import * as H from 'history';\nimport React, { useContext } from 'react';\nimport { BehaviorSubject, type Observable } from 'rxjs';\n\nimport { deprecationWarning, type UrlQueryMap, urlUtil } from '@grafana/data';\nimport { attachDebugger, createLogger } from '@grafana/ui';\n\nimport { config } from '../config';\n\nimport { type LocationUpdate } from './LocationSrv';\n\n/**\n * @public\n * A wrapper to help work with browser location and history\n */\nexport interface LocationService {\n  partial: (query: Record<string, any>, replace?: boolean) => void;\n  push: (location: H.Path | H.LocationDescriptor<any>) => void;\n  replace: (location: H.Path | H.LocationDescriptor<any>) => void;\n  reload: () => void;\n  getLocation: () => H.Location;\n  getHistory: () => H.History;\n  getSearch: () => URLSearchParams;\n  getSearchObject: () => UrlQueryMap;\n  getLocationObservable: () => Observable<H.Location>;\n\n  /**\n   * This is from the old LocationSrv interface\n   * @deprecated use partial, push or replace instead */\n  update: (update: LocationUpdate) => void;\n}\n\n/** @internal */\nexport class HistoryWrapper implements LocationService {\n  private readonly history: H.History;\n  private locationObservable: BehaviorSubject<H.Location>;\n\n  constructor(history?: H.History) {\n    // If no history passed create an in memory one if being called from test\n    this.history =\n      history ||\n      (process.env.NODE_ENV === 'test'\n        ? H.createMemoryHistory({ initialEntries: ['/'] })\n        : H.createBrowserHistory({ basename: config.appSubUrl ?? '/' }));\n\n    this.locationObservable = new BehaviorSubject(this.history.location);\n\n    this.history.listen((location) => {\n      this.locationObservable.next(location);\n    });\n\n    this.partial = this.partial.bind(this);\n    this.push = this.push.bind(this);\n    this.replace = this.replace.bind(this);\n    this.getSearch = this.getSearch.bind(this);\n    this.getHistory = this.getHistory.bind(this);\n    this.getLocation = this.getLocation.bind(this);\n  }\n\n  getLocationObservable() {\n    return this.locationObservable.asObservable();\n  }\n\n  getHistory() {\n    return this.history;\n  }\n\n  getSearch() {\n    return new URLSearchParams(this.history.location.search);\n  }\n\n  partial(query: Record<string, any>, replace?: boolean) {\n    const currentLocation = this.history.location;\n    const newQuery = this.getSearchObject();\n\n    for (const key in query) {\n      // removing params with null | undefined\n      if (query[key] === null || query[key] === undefined) {\n        delete newQuery[key];\n      } else {\n        newQuery[key] = query[key];\n      }\n    }\n\n    const updatedUrl = urlUtil.renderUrl(currentLocation.pathname, newQuery);\n\n    if (replace) {\n      this.history.replace(updatedUrl, this.history.location.state);\n    } else {\n      this.history.push(updatedUrl, this.history.location.state);\n    }\n  }\n\n  push(location: H.Path | H.LocationDescriptor) {\n    this.history.push(location);\n  }\n\n  replace(location: H.Path | H.LocationDescriptor) {\n    this.history.replace(location);\n  }\n\n  reload() {\n    const prevState = (this.history.location.state as any)?.routeReloadCounter;\n    this.history.replace({\n      ...this.history.location,\n      state: { routeReloadCounter: prevState ? prevState + 1 : 1 },\n    });\n  }\n\n  getLocation() {\n    return this.history.location;\n  }\n\n  getSearchObject() {\n    return locationSearchToObject(this.history.location.search);\n  }\n\n  /** @deprecated use partial, push or replace instead */\n  update(options: LocationUpdate) {\n    deprecationWarning('LocationSrv', 'update', 'partial, push or replace');\n    if (options.partial && options.query) {\n      this.partial(options.query, options.partial);\n    } else {\n      const newLocation: H.LocationDescriptor = {\n        pathname: options.path,\n      };\n      if (options.query) {\n        newLocation.search = urlUtil.toUrlParams(options.query);\n      }\n      if (options.replace) {\n        this.replace(newLocation);\n      } else {\n        this.push(newLocation);\n      }\n    }\n  }\n}\n\n/**\n * @public\n * Parses a location search string to an object\n * */\nexport function locationSearchToObject(search: string | number): UrlQueryMap {\n  let queryString = typeof search === 'number' ? String(search) : search;\n\n  if (queryString.length > 0) {\n    if (queryString.startsWith('?')) {\n      return urlUtil.parseKeyValue(queryString.substring(1));\n    }\n    return urlUtil.parseKeyValue(queryString);\n  }\n\n  return {};\n}\n\n/**\n * @public\n */\nexport let locationService: LocationService = new HistoryWrapper();\n\n/**\n * Used for tests only\n * @internal\n */\nexport const setLocationService = (location: LocationService) => {\n  if (process.env.NODE_ENV !== 'test') {\n    throw new Error('locationService can be only overriden in test environment');\n  }\n  locationService = location;\n};\n\nconst navigationLog = createLogger('Router');\n\n/** @internal */\nexport const navigationLogger = navigationLog.logger;\n\n// For debugging purposes the location service is attached to global _debug variable\nattachDebugger('location', locationService, navigationLog);\n\n// Simple context so the location service can be used without being a singleton\nconst LocationServiceContext = React.createContext<LocationService | undefined>(undefined);\n\nexport function useLocationService(): LocationService {\n  const service = useContext(LocationServiceContext);\n  if (!service) {\n    throw new Error('useLocationService must be used within a LocationServiceProvider');\n  }\n  return service;\n}\n\nexport const LocationServiceProvider: React.FC<{ service: LocationService; children: React.ReactNode }> = ({\n  service,\n  children,\n}) => {\n  return <LocationServiceContext.Provider value={service}>{children}</LocationServiceContext.Provider>;\n};\n"],"names":["H","config","BehaviorSubject","urlUtil","deprecationWarning","locationService","createLogger","attachDebugger","React","useContext"],"mappings":"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"}