@grafana/runtime
Version:
Grafana Runtime Library
1 lines • 10.2 kB
Source Map (JSON)
{"version":3,"file":"LocationService.mjs","sources":["../../../src/services/LocationService.tsx"],"sourcesContent":["import * as H from 'history';\nimport React, { useContext } from 'react';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\nimport { deprecationWarning, UrlQueryMap, urlUtil } from '@grafana/data';\nimport { attachDebugger, createLogger } from '@grafana/ui';\n\nimport { config } from '../config';\n\nimport { 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":[],"mappings":"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"}