UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1 lines • 118 kB
{"version":3,"file":"c8y-ngx-components-upgrade.mjs","sources":["../../upgrade/absolute-date.service.ts","../../upgrade/ng1/views.provider.ts","../../upgrade/bridge.service.ts","../../upgrade/action-bar.factory.ts","../../upgrade/action.factory.ts","../../upgrade/auth-bridge.service.ts","../../upgrade/breadcrumb.factory.ts","../../upgrade/docs.factory.ts","../../upgrade/nodes.factory.ts","../../upgrade/smart-rules.service.ts","../../upgrade/tabs.factory.ts","../../upgrade/upgrade.module.ts","../../upgrade/ng1/alert.decorator.ts","../../upgrade/ng1/downgraded.components.ts","../../upgrade/ng1/serverMessages.service.ts","../../upgrade/ng1/downgraded.services.ts","../../upgrade/ng1/gettextCatalog.decorator.ts","../../upgrade/ng1/groupsHierarchyNavigator.decorator.ts","../../upgrade/ng1/http.interceptor.ts","../../upgrade/ng1/navigator-node-root-legacy.ts","../../upgrade/ng1/navigator.provider.ts","../../upgrade/ng1/root.component.ts","../../upgrade/ng1/title.decorator.ts","../../upgrade/ng1/index.ts","../../upgrade/hybrid-app.module.ts","../../upgrade/upgrade.routes.ts","../../upgrade/dashboard/dashboard-bridge.service.ts","../../upgrade/dashboard/widget.component.ts","../../upgrade/dashboard/device-selector.component.ts","../../upgrade/dashboard/component.factory.ts","../../upgrade/dashboard/dashboard-upgrade.module.ts","../../upgrade/c8y-ngx-components-upgrade.ts"],"sourcesContent":["import { DatePipe } from '@c8y/ngx-components';\n\nexport class AbsoluteDateService {\n constructor(private datePipe: DatePipe) {}\n getFilter() {\n return (value: any, format = 'medium', timezone?: string, locale?: string) =>\n this.datePipe.transform(value, format, timezone, locale);\n }\n}\nexport function absoluteDateServiceFactory(datePipe: DatePipe) {\n return new AbsoluteDateService(datePipe).getFilter();\n}\nexport const absoluteDateServiceProvider = {\n provide: AbsoluteDateService,\n useFactory: absoluteDateServiceFactory,\n deps: [DatePipe]\n};\n","import { ViewContext } from '@c8y/ngx-components';\nimport { find, forEach, map, startsWith, unary } from 'lodash-es';\nimport { ReplaySubject } from 'rxjs';\n\nexport enum ViewContextLegacyParameter {\n Device = 'deviceId',\n Group = 'groupId',\n User = 'userId',\n Application = 'applicationId',\n Microservice = 'applicationId',\n SubscribedApplications = 'applicationId',\n Tenant = 'tenantId',\n Service = 'deviceId', // use 'deviceId' as parameter name so that device views (Measurements, Events, Alarms) can be reused for service\n Simulators = 'deviceId' // required to hook the Alarms tab to a Simulator view\n}\n\nfunction c8yViewsProvider($routeProvider, c8yTabsProvider, c8yPathUtils) {\n 'ngInject';\n\n const viewMap = {};\n const contextViews = new ReplaySubject();\n\n return {\n when,\n $get() {\n return {\n contextViews,\n when(path, cfg) {\n return when(path, cfg, true);\n },\n getByPath,\n prefixWithSlash\n };\n }\n };\n\n /**\n * @ngdoc function\n * @name when\n * @methodOf c8y.ui.provider:c8yViewsProvider\n *\n * @description\n * Defines a view for given route.\n * If multiple views are defined for a single route then there will be a separate tab for each view available when user visits that route.\n *\n * @param path Target route.\n * @param cfg View configuration object with the following properties:\n *\n * - **name** - `string` - View's name (in case of multiple views at single route this will be displayed as tab's title).\n * - **priority** - `integer` - View's priority (in case of multiple views at single route this will determine the position of view's tab in the tabs stack).\n * - **icon** - `string` - Font Awesome icon name for the view (displayed on the tab's header).\n * - **showIf** - `function` - Function returning boolean value indicating whether to show a tab for the view or not.\n * - **templateUrl** - `string` - Path to the template to use for displaying the view.\n *\n * You can also provide other view options - the same as available for standard {@link https://docs.angularjs.org/api/ngRoute/provider/$routeProvider $routeProvider} in AngularJS.\n *\n * ```html\n * The following example demonstrates how to add a new view to device details route\n * (which will be displayed as a tab if other views are assigned to the same route):\n * <pre>\n * c8yViewsProvider.when('/device/:deviceId', {\n * name: 'Tracking',\n * templateUrl: ':::PLUGIN_PATH:::/views/index.html',\n * icon: 'crosshairs',\n * showIf: ['$routeParams', 'c8yDevices', function ($routeParams, c8yDevices) {\n * var deviceId = $routeParams.deviceId;\n * return c8yDevices.detailCached(deviceId).then(function (res) {\n * var device = res.data;\n * return device && (device.c8y_MotionTracking || device.c8y_Geofence);\n * });\n * }]\n * });\n * </pre>\n * ```\n */\n function when(path, cfg, runPhase) {\n const newPath = prefixWithSlash(path);\n cfg.resolve = cfg.resolve || {};\n // eslint-disable-next-line no-underscore-dangle\n cfg.resolve.__c8y_locales = [\n 'c8yLocales',\n c8yLocales => {\n return c8yLocales.initDone;\n }\n ];\n\n let currentCfg = viewMap[newPath];\n const originalPath = newPath;\n\n if (!cfg.name) {\n // console.warn('View name not defined');\n }\n\n if (!currentCfg) {\n viewMap[newPath] = [];\n currentCfg = viewMap[newPath];\n }\n\n const upgradedContext = Object.keys(ViewContext)\n .map(key => ({\n key,\n isUpgrade:\n prefixWithSlash(ViewContext[key].replace('id', ViewContextLegacyParameter[key])) === path\n }))\n .find(({ isUpgrade }) => isUpgrade);\n\n if (upgradedContext) {\n currentCfg.push(cfg);\n cfg.path = newPath;\n\n const p = c8yPathUtils.appendSegment(originalPath.replace(path, ''), cfg.name);\n contextViews.next({\n ...cfg,\n path: cfg.name ? p.substring(1) : '',\n contextKey: upgradedContext.key,\n runPhase\n });\n cfg.showIf = undefined;\n if (cfg.name) {\n cfg.path = c8yPathUtils.appendSegment(originalPath, cfg.name);\n }\n } else {\n if (currentCfg.length === 1) {\n const [existingConfig] = currentCfg;\n existingConfig.path = c8yPathUtils.appendSegment(originalPath, existingConfig.name);\n existingConfig.tab = createTab(originalPath, existingConfig);\n $routeProvider.when(existingConfig.path, existingConfig);\n }\n\n currentCfg.push(cfg);\n cfg.path = newPath;\n\n if (currentCfg.length > 1) {\n cfg.path = c8yPathUtils.appendSegment(originalPath, cfg.name);\n createTab(originalPath, cfg);\n\n $routeProvider.when(prefixWithSlash(originalPath), {\n resolveRedirectTo($route, $q, c8yUiUtil, c8yTabs, gettextCatalog) {\n 'ngInject';\n\n const sortedCurrentCfg = c8yTabsProvider.sortTabsViews(currentCfg, gettextCatalog);\n const params = $route.current.pathParams;\n\n return $q\n .all(map(sortedCurrentCfg, unary(c8yUiUtil.configureVisibility)))\n .then(views => {\n const first = find(views, 'show');\n let url = first.path;\n forEach(params, (val, key) => {\n url = url.replace(`:${key}`, val);\n });\n c8yTabs.redirectedViewPath = url;\n return url;\n });\n }\n });\n }\n }\n return $routeProvider.when(prefixWithSlash(cfg.path), cfg);\n }\n\n function getByPath(path) {\n return viewMap[prefixWithSlash(path)];\n }\n\n function createTab(path, cfg) {\n c8yTabsProvider.addTab(path, cfg);\n }\n\n function prefixWithSlash(path) {\n const prefix = startsWith(path, '/') ? '' : '/';\n return prefix + path;\n }\n}\n\nexport { c8yViewsProvider };\n","import {\n Action,\n ActionBarItem,\n ActionService,\n AppStateService,\n Breadcrumb,\n BreadcrumbItem,\n DocLink,\n EmptyComponent,\n gettext,\n PluginsResolveService,\n RouterService,\n Search,\n Tab,\n ViewContext\n} from '@c8y/ngx-components';\nimport { isArray } from 'lodash-es';\nimport {\n BehaviorSubject,\n combineLatest,\n from,\n fromEventPattern,\n merge,\n Observable,\n of,\n Subject\n} from 'rxjs';\nimport { debounceTime, filter, map, startWith, switchMap, take } from 'rxjs/operators';\n\nimport { NgZone } from '@angular/core';\nimport { ActivatedRouteSnapshot, ActivationEnd, ResolveEnd, Router } from '@angular/router';\nimport { ViewContextLegacyParameter } from './ng1/views.provider';\n\nexport class BridgeService {\n $routeChanges: Observable<any>;\n $ng1RouteChangeSuccess: Observable<any>;\n $ng1RouteChangeStart: Observable<any>;\n $liveTabs: Subject<Tab[]> = new BehaviorSubject([]);\n navigationNodes$: Observable<any>;\n constructor(\n public injector: any,\n private appState: AppStateService,\n public router: Router,\n private ngZone: NgZone,\n private routerService: RouterService,\n private actionService: ActionService,\n plugins: PluginsResolveService\n ) {\n this.fixE2eIssues();\n this.$ng1RouteChangeSuccess = this.fromNg1Event(\n this.injector.get('$rootScope'),\n '$routeChangeSuccess'\n );\n this.$ng1RouteChangeStart = this.fromNg1Event(\n this.injector.get('$rootScope'),\n '$routeChangeStart'\n );\n this.hookLanguage();\n this.hookTab();\n this.hookNavigator();\n this.hookUserMenu();\n this.hookViewProvider();\n this.hookRoute();\n plugins.allPluginsLoaded$\n .pipe(\n filter(tmp => !!tmp),\n take(1)\n )\n .subscribe(() => {\n this.router.initialNavigation();\n });\n this.ng1Routes();\n }\n\n /**\n * Ensure that angularjs routes are not using any\n * secondary router outlets\n */\n hookRoute() {\n this.router.events\n .pipe(\n filter(event => event instanceof ResolveEnd),\n map((event: ResolveEnd) => event.state.root.firstChild),\n filter(route => route && route.routeConfig && route.routeConfig.path === '**')\n )\n .subscribe((event: ActivatedRouteSnapshot) => {\n if (event.root.children.length > 1) {\n window.location.hash = event.root.children[0].url.toString();\n }\n });\n }\n\n hookViewProvider() {\n const c8yViews = this.injector.get('c8yViews');\n // fix to trigger an angularjs route change success\n // event on context route match to make legacy\n // view-providers resolve.\n c8yViews.when('/device/:id', {\n template: ''\n });\n c8yViews.when('/group/:id', {\n template: ''\n });\n c8yViews.contextViews.subscribe(cfg => this.addRoute(cfg));\n }\n\n addRoute(cfg) {\n this.routerService.addRoute({\n label: cfg.label || cfg.name,\n path: cfg.path,\n icon: cfg.icon,\n context: ViewContext[cfg.contextKey] as ViewContext,\n priority: cfg.priority,\n component: EmptyComponent,\n data: {\n showIf: cfg.showIf\n ? ngxRoute => {\n const params = {\n ...ngxRoute.params,\n [ViewContextLegacyParameter[cfg.contextKey]]: ngxRoute.params.id\n };\n const showIfResult = this.injector.invoke(cfg.showIf, undefined, {\n $routeParams: params\n });\n // make sure showIf result is a promise with boolean result:\n return this.injector.get('$q').when(showIfResult).then(Boolean);\n }\n : undefined\n },\n ...(cfg.featureId && { featureId: cfg.featureId })\n });\n\n if (cfg.runPhase) {\n this.routerService.refresh();\n }\n }\n\n ng1Routes() {\n const template = '';\n const fallbackRoutes = [];\n\n // tslint:disable-next-line: forin\n for (const context in ViewContext) {\n const path = ViewContext[context].match(/(\\w+)\\//)[1];\n const regexp = new RegExp(`^/${path}/(?:([^/]+)).*$`);\n fallbackRoutes.push({\n keys: [{ name: ViewContextLegacyParameter[context], optional: false }],\n regexp,\n template\n });\n }\n\n /**\n * When asset detail routes (/device/:id, /group/:id) are matched in Angular Router, ngRoute in\n * angular.js must also have matching generic routes so that the ids can be extracted from the paths and\n * injected in multiple calls (showIf, c8yActions, etc) as properties of $routeParams.\n *\n * The function in src/ngRoute/route.js (angular.js) where the routes are matched is called parseRoute(). This\n * function calls angular.forEach and in turn this function checks for the presence of a forEach method before\n * trying object key iteration.\n * By attaching a non enumerable forEach method to the routes object we guarantee that the fallback generic routes\n * are only matched after any other registered through $routeProvider.when.\n */\n const $route = this.injector.get('$route');\n Object.defineProperty($route.routes, 'forEach', {\n // make non enumerable\n value: function forEach(iterator, context) {\n // tslint:disable-next-line: forin\n for (const key in this) {\n iterator.call(context, this[key], key, this);\n }\n fallbackRoutes.forEach(r => iterator.call(context, r));\n },\n configurable: true\n });\n\n /**\n * Some functions use the current context. As some parts are upgraded and some not, the following updates the\n * angularjs getContext function to resolve always the right context.\n */\n const c8yUiUtil = this.injector.get('c8yUiUtil');\n const _getContext = c8yUiUtil.getContext;\n this.router.events\n .pipe(filter(event => event instanceof ActivationEnd))\n .subscribe((event: ActivationEnd) => {\n if (event.snapshot.routeConfig.path === '**') {\n c8yUiUtil.getContext = _getContext;\n } else if (event.snapshot.data && event.snapshot.data.context) {\n c8yUiUtil.getContext = () => {\n return {\n context: event.snapshot.data.context.replace('/:id', ''),\n id: event.snapshot.data.contextData.id,\n contextData: event.snapshot.data.contextData\n };\n };\n } else {\n c8yUiUtil.getContext = () => ({ context: null, id: null });\n }\n });\n }\n\n fixE2eIssues() {\n try {\n const { ngZone } = this;\n const { Utils } = (window as any).org.cometd;\n const timeoutFn = Utils.setTimeout;\n // tslint:disable-next-line:only-arrow-functions\n Utils.setTimeout = function (...args) {\n return ngZone.runOutsideAngular(() => timeoutFn.apply(Utils, args));\n };\n } catch (e) {\n // do nothing\n }\n\n try {\n const { ace } = window as any;\n const editFn = ace.edit;\n const { ngZone } = this;\n // tslint:disable-next-line:only-arrow-functions\n ace.edit = function (...args) {\n return ngZone.runOutsideAngular(() => editFn.apply(ace, args));\n };\n } catch (e) {\n // do nothing\n }\n }\n\n hookLanguage() {\n let first = true;\n this.appState\n .map(store => store.lang)\n .subscribe(lang => {\n this.injector.get('c8yLocales').switchToLanguage(lang);\n if (!first) {\n this.injector.get('$rootScope').$apply();\n }\n first = false;\n });\n }\n\n hookTab() {\n // Just for instantiation of the c8yAction service\n this.injector.get('c8yActions');\n const $location = this.injector.get('$location');\n const c8yTabs = this.injector.get('c8yTabs');\n let liveTabs = [];\n c8yTabs.addTab = tab => {\n liveTabs.push({\n ...tab,\n label: tab.label || tab.name,\n path: decodeURIComponent(tab.path)\n });\n this.$liveTabs.next(liveTabs);\n };\n this.$ng1RouteChangeStart.subscribe(() => {\n liveTabs = [];\n this.$liveTabs.next(liveTabs);\n });\n this.$ng1RouteChangeSuccess.subscribe(() => {\n const path = $location.path();\n if (this.router.url !== path) {\n this.router.navigate(path === '/' ? '' : path.split('/'), {\n queryParams: $location.search(),\n skipLocationChange: true\n });\n }\n if (this.actionService) {\n this.actionService.refresh();\n }\n });\n this.$routeChanges = merge(\n this.$ng1RouteChangeSuccess,\n this.fromNg1Event(c8yTabs, c8yTabs.EVENT_UPDATE),\n of(1)\n ).pipe(debounceTime(100));\n }\n\n hookNavigator() {\n this.navigationNodes$ = this.injector.get('c8yNavigator').rootNodes$;\n }\n\n getTabs(): Observable<any> {\n const onlyVisible = ({ show }) => show;\n const upgradeTab = tab => ({\n ...tab,\n label: tab.label || tab.name,\n path: decodeURIComponent(tab.path)\n });\n const routeTabs = this.$routeChanges.pipe(\n switchMap(() => {\n const routes = this.injector.get('c8yTabs').routeTabs;\n const visibilityPromise = Promise.all(\n routes.map(({ checkingVisibility }) => checkingVisibility)\n );\n return visibilityPromise.then(() => routes.filter(onlyVisible).map(upgradeTab));\n }),\n startWith([])\n );\n return combineLatest([routeTabs, this.$liveTabs]).pipe(\n map(([route, live]) => route.concat(live))\n );\n }\n\n getQuickLinks(): Promise<DocLink[]> {\n const c8yQuickLinks = this.injector.get('c8yQuickLinks');\n return c8yQuickLinks.list();\n }\n\n getActionBarItems(): Observable<ActionBarItem> {\n const c8yActionBar = this.injector.get('c8yActionBar');\n const $rootScope = this.injector.get('$rootScope');\n const getActionBarElements = () =>\n c8yActionBar.elements.map(element => ({\n priority: element.getAttribute('action-bar-priority') || 0,\n template: element,\n placement: element.getAttribute('action-bar-position') || 'right'\n }));\n return this.fromNg1Event($rootScope, 'c8yActionBarChanged').pipe(\n startWith(1),\n map(getActionBarElements)\n );\n }\n\n getBreadcrumbs(): Observable<Breadcrumb[]> {\n const $location = this.injector.get('$location');\n const c8yBreadcrumbs = this.injector.get('c8yBreadcrumbs');\n const breadcrumbsUpdate$ = new Observable(subscriber =>\n c8yBreadcrumbs.$on('update', () => subscriber.next())\n );\n return breadcrumbsUpdate$.pipe(\n startWith(0),\n switchMap(() => {\n const path = $location.path();\n const breadcrumbs = c8yBreadcrumbs.get(path) || {};\n const breadcrumbsData = this.resolveBreadcrumbsData(breadcrumbs.data);\n return from(breadcrumbsData).pipe(\n map((value: any[]) => {\n const liveBreadcrumbs = c8yBreadcrumbs.getLiveBreadcrumbs();\n value = value.concat(liveBreadcrumbs);\n return value.map(items => ({ items: items as BreadcrumbItem[] }) as Breadcrumb);\n })\n );\n })\n );\n }\n\n resolveBreadcrumbsData(data): Observable<any[]> {\n try {\n return this.injector.invoke(data);\n } catch (ex) {\n // empty\n }\n if (isArray(data)) {\n return of([data]);\n }\n return of([]);\n }\n\n getSearch(): Search[] {\n const c8ySearch = this.injector.get('c8ySearch');\n return c8ySearch.list().map(item => {\n return {\n icon: 'search',\n name: item.name,\n term: '',\n onSearch() {\n if (this.term) {\n c8ySearch.search(this.term);\n }\n }\n } as Search;\n });\n }\n\n getActions(): Observable<Action> {\n const registeredActions = this.injector.get('c8yActions').registeredActions;\n return of(\n registeredActions\n .filter(action => !action.hidden)\n .map(action => ({\n // The priority was reversed: Aligned it to dashboard, high first, low last.\n priority: (action.priority || 0) * -1,\n label: action.text,\n icon: action.icon,\n disabled: action.disabled,\n action: () => {\n this.injector.invoke(action.action, action);\n }\n }))\n );\n }\n\n fromNg1Event(obj, evt) {\n let stopListening;\n function add(handler) {\n stopListening = obj.$on(evt, handler);\n }\n return fromEventPattern(add, () => stopListening());\n }\n\n private hookUserMenu() {\n const userMenuService = this.injector.get('c8yUserMenuService');\n const c8yAccessDenied = this.injector.get('c8yAccessDenied');\n userMenuService.add({\n icon: 'access',\n priority: 10,\n label: gettext('Access denied requests'),\n click: c8yAccessDenied.showAccessDeniedRequestsList\n });\n }\n}\n\nexport function bridgeServiceFactory(\n injector: any,\n appState: AppStateService,\n router: Router,\n ngZone: NgZone,\n routerService: RouterService,\n actionService: ActionService,\n plugins: PluginsResolveService\n) {\n return new BridgeService(\n injector,\n appState,\n router,\n ngZone,\n routerService,\n actionService,\n plugins\n );\n}\n\nexport const bridgeServiceProvider = {\n provide: BridgeService,\n useFactory: bridgeServiceFactory,\n deps: [\n '$injector',\n AppStateService,\n Router,\n NgZone,\n RouterService,\n ActionService,\n PluginsResolveService\n ]\n};\n","import { Injectable } from '@angular/core';\nimport { ActionBarFactory, ActionBarItem } from '@c8y/ngx-components';\nimport { BridgeService } from './bridge.service';\nimport { Observable } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\n\n@Injectable()\nexport class Ng1ActionBarFactoryService implements ActionBarFactory {\n routeChanges$: Observable<any>;\n $ng1RouteChangeSuccess: Observable<any>;\n constructor(private bridge: BridgeService) {\n this.routeChanges$ = bridge.$routeChanges;\n this.$ng1RouteChangeSuccess = bridge.$ng1RouteChangeSuccess;\n }\n\n get(): Observable<ActionBarItem> {\n return this.routeChanges$.pipe(\n switchMap(() => {\n return this.bridge.getActionBarItems();\n })\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { ActionFactory, TabsService } from '@c8y/ngx-components';\nimport { BridgeService } from './bridge.service';\nimport { Observable } from 'rxjs';\n\n@Injectable()\nexport class Ng1ActionFactoryService implements ActionFactory {\n routeChanges$: Observable<any>;\n $location: any;\n constructor(private bridge: BridgeService, private tabs: TabsService) {\n this.routeChanges$ = bridge.$routeChanges;\n this.$location = bridge.injector.get('$location');\n this.tabs.items$.subscribe(newTabs => this.handleTabsRedirect(newTabs));\n }\n\n handleTabsRedirect(tabs) {\n /**\n * This function is doing the same process as function redirect in the file\n * modules/core/ui/navigation/tabs.provider.js\n * That function is not run because bridge.service.ts overrides the method addTab where the redirect() was called.\n */\n const redirectedTab = tabs.find(tab => tab.redirectedTo);\n const [topPriorityTab] = tabs;\n if (redirectedTab && !topPriorityTab.redirectedTo) {\n this.$location.replace();\n this.$location.path(topPriorityTab.path);\n topPriorityTab.redirectedTo = true;\n redirectedTab.redirectedTo = false;\n }\n }\n\n get() {\n return this.bridge.getActions();\n }\n}\n","import { AppStateService, TenantUiService } from '@c8y/ngx-components';\nimport { BasicAuth, FetchClient, ICredentials } from '@c8y/client';\n\nexport class AuthBridgeService {\n constructor(\n public injector: any,\n private basicAuth: BasicAuth,\n private fetchClient: FetchClient,\n private appState: AppStateService,\n private tenantUiService: TenantUiService\n ) {\n this.hookAuth();\n }\n\n updateBasicAuth(credentials: ICredentials) {\n const { headers } = this.fetchClient.getFetchOptions({});\n if (headers.Authorization) {\n const token = headers.Authorization.match(/basic\\s(.*)$/i)[1];\n if (token) {\n this.basicAuth.updateCredentials(credentials);\n this.fetchClient.setAuth(this.basicAuth);\n }\n }\n }\n\n hookAuth() {\n this.appState.currentUser.subscribe(user => {\n if (!user) {\n this.injector.get('$rootScope').$emit('authStateChange', { hasAuth: false });\n return;\n }\n this.injector.get('c8yAuth').headers = () => this.fetchClient.getFetchOptions({}).headers;\n const { headers } = this.fetchClient.getFetchOptions({});\n const authorizationHeader = headers.Authorization;\n if (typeof authorizationHeader === 'string' && authorizationHeader.startsWith('Basic')) {\n const matches = authorizationHeader.match(/basic\\s(.*)$/i);\n const token = matches && matches[1];\n if (token) {\n this.setToken(token, headers.tfatoken);\n }\n } else if (\n typeof authorizationHeader === 'string' &&\n authorizationHeader.startsWith('Bearer')\n ) {\n this.setToken(undefined, headers.tfatoken, 'Bearer');\n } else {\n this.setToken(undefined, headers.tfatoken, 'Oauth');\n }\n this.injector.get('$rootScope').$emit('authStateChange', { hasAuth: true });\n });\n }\n\n setToken(token?: string, tfa?: string, type = 'Basic') {\n const c8yAuth = this.injector.get('c8yAuth');\n if (type === 'Basic') {\n c8yAuth.onSetToken({ token, type });\n if (tfa) {\n c8yAuth.setTFAToken(tfa);\n }\n } else {\n c8yAuth.authReady();\n }\n }\n\n getPreferredLoginOption() {\n return this.tenantUiService.getPreferredLoginOption(this.appState.state.loginOptions);\n }\n}\n\nexport function authBridgeServiceFactory(\n injector: any,\n basicAuth: BasicAuth,\n fetchClient: FetchClient,\n appState: AppStateService,\n tenantUiService: TenantUiService\n) {\n return new AuthBridgeService(injector, basicAuth, fetchClient, appState, tenantUiService);\n}\n\nexport const authBridgeServiceProvider = {\n provide: AuthBridgeService,\n useFactory: authBridgeServiceFactory,\n deps: ['$injector', BasicAuth, FetchClient, AppStateService, TenantUiService]\n};\n","import { Injectable } from '@angular/core';\nimport { BreadcrumbFactory } from '@c8y/ngx-components';\nimport { ReplaySubject } from 'rxjs';\nimport { debounceTime, switchMap } from 'rxjs/operators';\nimport { BridgeService } from './bridge.service';\n\n@Injectable()\nexport class Ng1BreadcrumbFactoryService implements BreadcrumbFactory {\n private trigger: any = new ReplaySubject(1);\n private breadcrumbs = this.trigger.pipe(\n debounceTime(100),\n switchMap(() => {\n return this.bridge.getBreadcrumbs();\n })\n );\n constructor(private bridge: BridgeService) {}\n\n get() {\n this.trigger.next();\n return this.breadcrumbs;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { DocLink, ExtensionFactory } from '@c8y/ngx-components';\nimport { BridgeService } from './bridge.service';\n\n@Injectable()\nexport class Ng1DocsFactoryService implements ExtensionFactory<DocLink> {\n private links: Promise<DocLink[]>;\n constructor(private bridge: BridgeService) {\n this.links = this.bridge.getQuickLinks();\n this.links.then(list => {\n list.map(el => {\n el.type = el.type || 'quicklink';\n return el;\n });\n });\n }\n\n get() {\n return this.links;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { NavigatorNodeFactory } from '@c8y/ngx-components';\nimport { BridgeService } from './bridge.service';\n\n@Injectable()\nexport class Ng1NodesFactoryService implements NavigatorNodeFactory {\n constructor(private bridge: BridgeService) {}\n\n get() {\n return this.bridge.navigationNodes$;\n }\n}\n","export abstract class Ng1SmartRulesService {\n abstract permissionsCfgs;\n abstract addNewForOutputOperationWithUI(operation);\n abstract addNewForInputAlarmAndOutputUserWithUI(alarm, user);\n}\n\nexport function SmartRulesServiceFactory(injector: any) {\n return injector.get('smartRulesSvc');\n}\n\nexport const smartRulesServiceProvider = {\n provide: Ng1SmartRulesService,\n useFactory: SmartRulesServiceFactory,\n deps: ['$injector']\n};\n","import { Injectable } from '@angular/core';\nimport { TabFactory } from '@c8y/ngx-components';\nimport { BridgeService } from './bridge.service';\n\n@Injectable()\nexport class Ng1TabsFactoryService implements TabFactory {\n tabsObservable;\n constructor(private bridge: BridgeService) {\n this.tabsObservable = bridge.getTabs();\n }\n get() {\n return this.tabsObservable;\n }\n}\n","import { NgModule } from '@angular/core';\nimport { setAngularJSGlobal } from '@angular/upgrade/static';\nimport {\n hookAction,\n hookActionBar,\n hookBreadcrumb,\n hookDocs,\n hookNavigator,\n hookTab,\n RouterModule\n} from '@c8y/ngx-components';\nimport { UpgradedServicesModule } from '@c8y/ngx-components/upgrade/upgraded-services';\nimport * as angular from 'angular';\nimport { absoluteDateServiceProvider } from './absolute-date.service';\nimport { Ng1ActionBarFactoryService } from './action-bar.factory';\nimport { Ng1ActionFactoryService } from './action.factory';\nimport { authBridgeServiceProvider } from './auth-bridge.service';\nimport { Ng1BreadcrumbFactoryService } from './breadcrumb.factory';\nimport { bridgeServiceProvider } from './bridge.service';\nimport { Ng1DocsFactoryService } from './docs.factory';\nimport { Ng1NodesFactoryService } from './nodes.factory';\nimport { smartRulesServiceProvider } from './smart-rules.service';\nimport { Ng1TabsFactoryService } from './tabs.factory';\n\nsetAngularJSGlobal(angular);\n\n@NgModule({\n imports: [RouterModule, UpgradedServicesModule],\n exports: [],\n providers: [\n absoluteDateServiceProvider,\n bridgeServiceProvider,\n authBridgeServiceProvider,\n smartRulesServiceProvider,\n hookNavigator(Ng1NodesFactoryService),\n hookTab(Ng1TabsFactoryService),\n hookActionBar(Ng1ActionBarFactoryService),\n hookAction(Ng1ActionFactoryService),\n hookBreadcrumb(Ng1BreadcrumbFactoryService),\n hookDocs(Ng1DocsFactoryService)\n ]\n})\nexport class UpgradeModule {}\n","function c8yAlertDecorator($delegate, $rootScope, $injector) {\r\n 'ngInject';\r\n\r\n $delegate.add = alert => {\r\n $delegate.addAlert(transformAlert(alert));\r\n };\r\n\r\n $rootScope.$on('alert', (evt, alert) => {\r\n $delegate.addAlert(transformAlert(alert));\r\n });\r\n\r\n $rootScope.$on('message', (evt, alert) => {\r\n $delegate.addAlert(transformAlert(alert));\r\n });\r\n\r\n /**\r\n * Solution based on the: https://stackoverflow.com/questions/40102148/how-to-iterate-over-all-properties-in-objects-prototype-chain.\r\n * Problem came after switching to ES6, as all prototype properties of classes are non-enumerable.\r\n */\r\n const allNames = new Set();\r\n for (let o = $delegate; o !== Object.prototype; o = Object.getPrototypeOf(o)) {\r\n for (const name of Object.getOwnPropertyNames(o)) {\r\n allNames.add(name);\r\n }\r\n }\r\n Array.from(allNames).forEach((property: string) => {\r\n if (typeof $delegate[property] === 'function') {\r\n $delegate[property] = $delegate[property].bind($delegate);\r\n }\r\n });\r\n\r\n function transformAlert(alert: any) {\r\n const newAlert: any = { ...alert };\r\n if (alert.onClose) {\r\n newAlert.onClose = () => {\r\n $injector.invoke(alert.onClose);\r\n };\r\n }\r\n if (alert.onDetail) {\r\n newAlert.onDetail = () => {\r\n $injector.invoke(alert.onDetail);\r\n };\r\n }\r\n return newAlert;\r\n }\r\n\r\n return $delegate;\r\n}\r\n\r\nexport { c8yAlertDecorator };\r\n","import { downgradeComponent } from '@angular/upgrade/static';\nimport {\n BootstrapComponent,\n DataGridComponent,\n UserTotpRevokeComponent,\n LoadingComponent,\n HighlightComponent,\n EmptyStateComponent,\n PasswordInputComponent\n} from '@c8y/ngx-components';\nimport { AppLogsAutoRefreshComponent } from '@c8y/ngx-components/app-logs';\nimport { RangeDisplayComponent } from '@c8y/ngx-components';\nimport { HelpComponent } from '@c8y/ngx-components';\nimport { DatapointSelectionListComponent } from '@c8y/ngx-components/datapoint-selector';\nimport { PaginationComponent } from 'ngx-bootstrap/pagination';\nimport { RolesAssetTreeComponent } from '@c8y/ngx-components/user-roles';\nimport { PlatformConfigurationFormComponent } from '@c8y/ngx-components/platform-configuration';\n\nexport const bootstrapComponentDowngradedComponent = downgradeComponent({\n component: BootstrapComponent\n});\nexport const userTotpComponentDowngradedComponent = downgradeComponent({\n component: UserTotpRevokeComponent\n});\nexport const appLogsAutoRefreshComponentDowngradedComponent = downgradeComponent({\n component: AppLogsAutoRefreshComponent\n});\nexport const dataGridComponentDowngradedComponent = downgradeComponent({\n component: DataGridComponent\n});\nexport const loadingComponentDowngradedComponent = downgradeComponent({\n component: LoadingComponent\n});\nexport const rangeDisplayComponentDowngradedComponent = downgradeComponent({\n component: RangeDisplayComponent\n});\nexport const helpComponentDowngradedComponent = downgradeComponent({ component: HelpComponent });\nexport const highlightComponentDowngradedComponent = downgradeComponent({\n component: HighlightComponent,\n inputs: ['pattern', 'text']\n});\nexport const emptyStateComponentDowngradedComponent = downgradeComponent({\n component: EmptyStateComponent\n});\nexport const datapointSelectionListComponentDowngradedComponent = downgradeComponent({\n component: DatapointSelectionListComponent\n});\n\nexport const paginationComponentDowngradedComponent = downgradeComponent({\n component: PaginationComponent\n});\nexport const rolesAssetTreeComponentDowngradedComponent = downgradeComponent({\n component: RolesAssetTreeComponent\n});\nexport const passwordInputComponentDowngradedComponent = downgradeComponent({\n component: PasswordInputComponent\n});\nexport const platformConfigurationFormDowngradedComponent = downgradeComponent({\n component: PlatformConfigurationFormComponent\n});\n","import { Injectable, Inject } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { HOOK_PATTERN_MESSAGES } from '@c8y/ngx-components';\n\n@Injectable()\nexport class ServerMessagesService {\n MESSAGE_PATTERNS: any;\n constructor(private translateService: TranslateService, @Inject(HOOK_PATTERN_MESSAGES) patterns) {\n this.MESSAGE_PATTERNS = patterns;\n }\n\n translate(s: string) {\n return this.translateService.instant(s);\n }\n}\n","import { downgradeInjectable } from '@angular/upgrade/static';\nimport {\n AlertService,\n AppStateService,\n AssetLinkPipe,\n CachedLocaleDictionaryService,\n DocsService,\n FilesService,\n GainsightService,\n GlobalConfigService,\n HeaderService,\n ModalService,\n PasswordService,\n PropertyValueTransformService,\n ServiceRegistry,\n UserMenuService\n} from '@c8y/ngx-components';\nimport { ApiService } from '@c8y/ngx-components/api';\nimport { DeviceGridService } from '@c8y/ngx-components/device-grid';\nimport { DeviceTypeDetailEditedService } from '@c8y/ngx-components/device-protocols';\nimport { TranslateService } from '@ngx-translate/core';\nimport { AbsoluteDateService } from '../absolute-date.service';\nimport { AuthBridgeService } from '../auth-bridge.service';\nimport { BridgeService } from '../bridge.service';\nimport { ServerMessagesService } from './serverMessages.service';\nimport { DatapointSelectorService } from '@c8y/ngx-components/datapoint-selector';\n\nexport const absoluteDateServiceDowngradedInjectable = downgradeInjectable(AbsoluteDateService);\nexport const bridgeServiceDowngradedInjectable = downgradeInjectable(BridgeService);\nexport const authBridgeServiceDowngradedInjectable = downgradeInjectable(AuthBridgeService);\nexport const appStateServiceDowngradedInjectable = downgradeInjectable(AppStateService);\nexport const headerServiceDowngradedInjectable = downgradeInjectable(HeaderService);\nexport const alertsServiceDowngradedInjectable = downgradeInjectable(AlertService);\nexport const userMenuServiceDowngradedInjectable = downgradeInjectable(UserMenuService);\nexport const apiServiceDowngradedInjectable = downgradeInjectable(ApiService);\nexport const docsServiceDowngradedInjectable = downgradeInjectable(DocsService);\nexport const passwordServiceDowngradedInjectable = downgradeInjectable(PasswordService);\nexport const translateServiceDowngradedInjectable = downgradeInjectable(TranslateService);\nexport const cachedLocaleDictionaryServiceDowngradedInjectable = downgradeInjectable(\n CachedLocaleDictionaryService\n);\nexport const globalConfigServiceDowngradedInjectable = downgradeInjectable(GlobalConfigService);\nexport const serverMessagesServiceDowngradedInjectable = downgradeInjectable(ServerMessagesService);\nexport const modalServiceDowngradedInjectable = downgradeInjectable(ModalService);\nexport const gainsightServiceDowngradedInjectable = downgradeInjectable(GainsightService);\nexport const filesServiceDowngradedInjectable = downgradeInjectable(FilesService);\nexport const deviceTypeDetailEditedServiceDowngradedInjectable = downgradeInjectable(\n DeviceTypeDetailEditedService\n);\nexport const deviceGridServiceDowngradedInjectable = downgradeInjectable(DeviceGridService);\nexport const serviceRegistryInjectable = downgradeInjectable(ServiceRegistry);\nexport const assetLinkPipeDowngradedInjectable = downgradeInjectable(AssetLinkPipe);\nexport const propertyValueTransformServiceDowngradedInjectable = downgradeInjectable(\n PropertyValueTransformService\n);\nexport const datapointSelectorServiceDowngradedInjectable =\n downgradeInjectable(DatapointSelectorService);\n","import * as angular from 'angular';\n\nfunction gettextCatalogDecorator($delegate, $interpolate, c8yTranslate) {\n 'ngInject';\n\n const gettextCatalog = $delegate;\n const originalGetString = angular.bind(gettextCatalog, gettextCatalog.getString);\n\n function newGetString(input, scope, context) {\n if (typeof input === 'string') {\n const translatedString = originalGetString(input, scope, context);\n const interpolatedString = scope ? $interpolate(input)(scope) : input;\n\n let stringToReturn = translatedString;\n\n if (translatedString && translatedString === interpolatedString) {\n const translatedServerMessage = c8yTranslate.instant(interpolatedString);\n stringToReturn = translatedServerMessage;\n }\n\n return stringToReturn;\n }\n\n return input;\n }\n\n gettextCatalog.getString = newGetString;\n\n return gettextCatalog;\n}\n\nexport { gettextCatalogDecorator };\n","function groupTypesHierarchyNavigatorDecorator($delegate, $q) {\n 'ngInject';\n $delegate.loadAll = () => $q.when();\n $delegate.addGroupNavigation = () => $q.when();\n return $delegate;\n}\n\nexport { groupTypesHierarchyNavigatorDecorator };\n","function c8yNg1HttpInterceptor($q, c8yLoadingIndicator, c8yApiService) {\r\n 'ngInject';\r\n\r\n function request(config) {\r\n const { url, method } = config;\r\n c8yApiService.onStart({ url, method, options: config });\r\n return config;\r\n }\r\n\r\n function requestError(rejection) {\r\n finishRequest(rejection);\r\n return $q.reject(rejection);\r\n }\r\n\r\n function response(res) {\r\n finishRequest(res);\r\n return res;\r\n }\r\n\r\n function responseError(rejection) {\r\n finishRequest(rejection);\r\n c8yLoadingIndicator.responseError(rejection);\r\n return $q.reject(rejection);\r\n }\r\n\r\n function finishRequest(res) {\r\n const { url, method } = res.config;\r\n c8yApiService.onFinish({\r\n url,\r\n method,\r\n response: res,\r\n options: res.config\r\n });\r\n }\r\n\r\n return {\r\n request,\r\n requestError,\r\n response,\r\n responseError\r\n };\r\n}\r\n\r\nexport { c8yNg1HttpInterceptor };\r\n","import { NavigatorNodeRoot, NavigatorNode } from '@c8y/ngx-components';\nimport { assign } from 'lodash-es';\n\nexport class NavigatorNodeRootLegacy extends NavigatorNodeRoot {\n addRoot(nodeData): NavigatorNode {\n let duplicate;\n if (nodeData.path === '') {\n nodeData.path = '/';\n }\n nodeData.label = nodeData.name;\n if (typeof nodeData.parent === 'object') {\n nodeData.parent.label = nodeData.parent.name;\n }\n\n if (nodeData.preventDuplicates) {\n duplicate = this.find(({ path, parents, label }) => {\n return (\n path === nodeData.path &&\n label === nodeData.label &&\n parents.some(p => p.label === nodeData.parent)\n );\n });\n if (duplicate) {\n duplicate.routerLinkExact = false;\n }\n }\n\n return duplicate || super.addRoot(nodeData);\n }\n\n createNode(node) {\n const newNode = super.createNode(node);\n const update = newNode.update.bind(newNode);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const root = this;\n return Object.defineProperties(\n assign(newNode, {\n realName: (newNode as any).name || newNode.label,\n _parent: true, // just use it to detect if it has been deleted\n update(data) {\n if (this._parent === undefined) {\n // _parent was deleted somene instead to put this in root\n root.addRoot(this);\n // put it back so it can be deleted again\n this._parent = true;\n }\n update(data);\n },\n addChild(nodeChild) {\n this.add(root.createNode(nodeChild));\n }\n }),\n {\n label: {\n get() {\n return this.realName || '';\n },\n set(name) {\n this.realName = name;\n }\n },\n name: {\n get() {\n return this.realName || '';\n },\n set(name) {\n this.realName = name;\n }\n },\n show: {\n get() {\n return !this.hidden;\n },\n set(show) {\n this.hidden = !show;\n },\n configurable: true\n }\n }\n );\n }\n}\n","import { NavigatorNode } from '@c8y/ngx-components';\nimport { Observable, Subject, defer, of } from 'rxjs';\nimport { merge } from 'rxjs/operators';\nimport { pick, map, property, some, every } from 'lodash-es';\nimport { NavigatorNodeRootLegacy } from './navigator-node-root-legacy';\n\n// Just to hook into the bridge service\nexport function c8yNavigatorProvider() {\n const root = new NavigatorNodeRootLegacy();\n const rootNodesSubject: Subject<NavigatorNode[]> = new Subject();\n const conditionalNodes = [];\n const rootNodes$: Observable<NavigatorNode[]> = rootNodesSubject.pipe(\n merge(defer(() => of(root.children)))\n );\n\n function addNavigation(nodes) {\n const nodeList = Array.isArray(nodes) ? nodes : [nodes];\n nodeList.forEach(node => {\n if (isConditional(node)) {\n node.hidden = undefined;\n conditionalNodes.push(node);\n }\n node.navNode = root.addRoot(node);\n });\n rootNodesSubject.next(root.children);\n }\n\n function removeNavigation(node) {\n const found = root.find(n => n === node);\n if (found) {\n found.parents.forEach(p => p.remove(found));\n rootNodesSubject.next(root.children);\n }\n }\n\n function findNode(node) {\n return root.find(node);\n }\n\n function isConditional(node) {\n return node.showIf || node.showIfPermissions || node.showIfContainsVisibleViews;\n }\n\n function $get($q, $injector) {\n 'ngInject';\n\n // This avoids the circular dependency\n setTimeout(() => conditionalNodes.forEach(processShowIf));\n\n function processShowIf(node) {\n const c8yUiUtil = $injector.get('c8yUiUtil');\n const visibilityPromises = [];\n const { showIf, showIfPermissions, showIfContainsVisibleViews } = node;\n\n if (showIf) {\n visibilityPromises.push($injector.invoke(showIf));\n }\n if (showIfContainsVisibleViews) {\n visibilityPromises.push(viewsConditionalVisibility(node));\n }\n\n c8yUiUtil\n .configureVisibility(\n {\n showIf: () => $q.all(visibilityPromises).then(every),\n showIfPermissions\n },\n 'visible'\n )\n .then(({ visible }) => {\n if (visible) {\n node.navNode.update({\n hidden: false,\n showIf: null,\n showIfPermission: null,\n showIfContainsVisibleViews: null\n });\n } else {\n node.navNode.update({\n hidden: true\n });\n }\n });\n }\n\n function viewsConditionalVisibility(node) {\n const c8yUiUtil = $injector.get('c8yUiUtil');\n const c8yViews = $injector.get('c8yViews');\n const views = c8yViews.getByPath(node.path);\n return $q\n .all(\n map(views, view =>\n c8yUiUtil\n .configureVisibility(pick(view, ['showIf', 'showIfPermissions']), 'show', false)\n .then(property('show'))\n )\n )\n .then(some);\n }\n\n return {\n rootNodes() {\n return root.children;\n },\n findNode,\n addNavigation,\n removeNavigation,\n rootNodes$\n };\n }\n\n return {\n $get,\n addNavigation,\n removeNavigation\n };\n}\n","const rootComponent = {\n template: `\n <c8y-bootstrap>\n <div id=\"c8y-legacy-view\">\n <div ng-view ng-if=\"vm.widthSet && vm.authState.hasAuth\"></div>\n </div>\n </c8y-bootstrap>`,\n controller: c8yUiRootController,\n controllerAs: 'vm'\n};\n\nfunction c8yUiRootController(\n $rootScope,\n $timeout,\n c8yBase,\n c8yNavigator,\n c8yApplication,\n c8yHeaderService\n) {\n 'ngInject';\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const vm = this;\n\n Object.assign(vm, {\n $onInit,\n navOpen: false\n });\n\n ////////////\n\n function $onInit() {\n c8yHeaderService\n .map(states => states.nav.open)\n .subscribe(isOpen => {\n vm.navOpen = isOpen;\n });\n c8yHeaderService.configNavigator({ canToggle: true });\n $rootScope.$on('authStateChange', onAuthStateChange);\n vm.rootNodes = c8yNavigator.rootNodes;\n c8yApplication.currentAppCached().then(onAppInfo);\n vm.navHiddenOnStartup = c8yBase.appOption('hide_navigator');\n checkReady();\n }\n\n function onAuthStateChange(evt, data) {\n vm.authState = data;\n }\n\n function onAppInfo() {\n vm.tabsHorizontal = c8yBase.appOption('tabsHorizontal');\n }\n\n function checkReady() {\n const element = document.querySelector('#c8y-legacy-view');\n const hasWidth = element && element.clientWidth;\n if (hasWidth) {\n vm.widthSet = true;\n } else {\n $timeout(checkReady);\n }\n }\n}\nexport { rootComponent };\n","import * as angular from 'angular';\n\nfunction c8yTitleDecorator(\n $q,\n $delegate,\n $injector,\n $rootScope,\n $location,\n $templateCache,\n $compile,\n c8yHeaderService\n) {\n 'ngInject';\n\n $delegate.changeTitle = changeTitle;\n $delegate.setTitleElement = setTitleElement;\n\n $rootScope.$on('$routeChangeStart', () => {\n changeTitle({});\n });\n\n $rootScope.$on('$routeChangeSuccess', event => {\n resolveTitle(event);\n });\n\n $rootScope.$on('$routeUpdate', event => {\n resolveTitle(event);\n });\n\n function resolveTitle(event: any) {\n const title = $delegate.get($location.path());\n if (title) {\n const titleData = $q.when(title.data ? $injector.invoke(title.data) : {});\n titleData.then(data => {\n const { templateUrl } = data;\n if (templateUrl) {\n const template = $templateCache.get(templateUrl);\n setTitleElement($compile(template)(event.targetScope));\n } else {\n changeTitle(data);\n }\n });\n }\n }\n\n function changeTitle(\n newTitleSubtitleObjOrPromise,\n options = { skipTitleTranslation: false, skipSubtitleTranslation: false }\n ) {\n $q.when(newTitleSubtitleObjOrPromise).then(newTitleSubtitleObj =>\n changeTitleInAngular(translate(newTitleSubtitleObj, options))\n );\n }\n\n function translate(\n { title = '', subtitle = '' },\n { skipTitleTranslation = false, skipSubtitleTranslation = false }\n ) {\n const titleTemplate = skipTitleTranslation ? '{{ title }}' : '{{ title | translate }}';\n const subtitleTemplate = skipSubtitleTranslation\n ? '{{ subtitle }}'\n : '{{ subtitle | translate }}';\n const template = `\n <h1 class=\"text-truncate\">${titleTemplate}\n <small>${subtitleTemplate}</small></h1>\n `;\n\n const isolatedScope = $rootScope.$new(true);\n isolatedScope.title = title;\n isolatedScope.subtitle = subtitle;\n\n return $compile(angular.element(template))(isolatedScope)[0];\n }\n\n function changeTitleInAngular(domElement) {\n c8yHeaderService.changeTitle(domElement);\n }\n\n function setTitleElement($element) {\n $element.show();\n changeTitleInAngular($element[0]);\n }\n\n return $delegate;\n}\n\nexport { c8yTitleDecorator };\n","import { NgZone } from '@angular/core';\nimport { downgradeInjectable } from '@angular/upgrade/static';\nimp