`;\n// Exports\nexport default code;","import { AppContextService } from 'app/services/app-context-service';\r\nimport { I18N } from 'aurelia-i18n';\r\nimport {DeviceService} from 'app/services/device-service';\r\nimport {UserSessionService} from 'app/services/user-session-service';\r\nimport {Router,NavModel} from 'aurelia-router'; // , NavModel\r\nimport {ProjectDto} from 'app/models/project-dto';\r\nimport {EventAggregator, Subscription} from 'aurelia-event-aggregator';\r\nimport * as settings from 'app-settings.json';\r\nimport {autoinject, bindable, computedFrom} from 'aurelia-framework';\r\nimport {ErrorService} from \"../../services/error-service\";\r\nimport { ProjectRole } from 'app/models/project-role';\r\nimport { ProjectTokenService } from 'app/services/project-token-service';\r\nimport { ApiClient } from 'app/services/api-client';\r\nimport { OrgRole } from 'app/models/org-role';\r\nimport { ProjectTokenInfo } from 'app/models/project-token-info';\r\nimport { OrgTokenInfo } from 'app/models/org-token-info';\r\nimport { OrgTokenService } from 'app/services/org-token-service';\r\nimport { IRouteConfig_Child, RouteConfig_Root, RouteSettingAjour } from 'app/aox/RouteTypings_Ajour'; // --RouteSettingAjour, -- MenuAccessLevel, \r\nimport { AccessLevelService } from 'app/services/access-level-service';\r\n\r\n\r\n@autoinject\r\nexport class Navigation {\r\n\t@bindable public router: Router | undefined;\r\n\t@bindable public selectedProject: ProjectDto | undefined = undefined;\r\n\tpublic navCollapsed: boolean = false;\r\n\tpublic showMobileNav: boolean = false;\r\n\tpublic isDesktop: boolean = false;\r\n\tpublic ajourLogo: string = settings.ajour.logoWhiteUrl;\r\n\tpublic egPhone: string = settings.eg.phone;\r\n\tpublic ajourEmail: string = settings.ajour.email;\r\n\tpublic egWebsite: string = settings.eg.website;\r\n\tpublic isProfileMenuOpen: boolean = false;\r\n\tprivate subscriptions: Subscription[] = [];\r\n\t\r\n\tprivate projectTokenInfo:ProjectTokenInfo = {prjId: '00000000-0000-0000-0000-000000000000', prjRole: ProjectRole.VeryUnknown, orgId:'00000000-0000-0000-0000-000000000000', orgRole: OrgRole.Unknown}\r\n\tprivate orgTokenInfo: OrgTokenInfo = {orgId: '00000000-0000-0000-0000-000000000000', orgRole: OrgRole.Unknown};\r\n\tprivate selectedOrg: {id: string, name: string} | undefined;\r\n\tprivate organizations: {id: string, name: string}[] = [];\r\n\r\n\tconstructor(private events: EventAggregator, \r\n\t\tprivate appContext: AppContextService, \r\n\t\tprivate i18n: I18N, \r\n\t\tprivate userSession: UserSessionService, \r\n\t\tprivate device: DeviceService, private errorService: ErrorService, \r\n\t\tprivate projectTokenService: ProjectTokenService, private orgTokenService: OrgTokenService,\r\n\t\tprivate apiClient: ApiClient\r\n\t) {\t\r\n\t\tconsole.log('navigation.ctor, appCtx.project says:', appContext.projectId);\r\n\t\t// This is too early, because appContext.projectId may not be set yet!\r\n\r\n\t\t//this.initAll(); // problem, that it is still async - navigation view may render before tokens are complete.\r\n\t\t//this.dumpRouter('ctor');\r\n\t}\r\n\r\n\tasync initAll() {\r\n\t\tawait this.initProjectWithToken();//in-attached.\r\n\t\tawait this.initOrgsWithToken();\r\n\t}\r\n\r\n\tactivate() { // JG: I don't think this ever triggers, for navigation.ts.\r\n\t\tconsole.log('Navigation.activate');\r\n\r\n\t\tif (Boolean(this.routeExistsInNavigationAsChild()) || Boolean(this.router?.currentInstruction.config.nav)) {\r\n\t\t\tthis.setActiveParentOnLoad();\r\n\t\t}\r\n\t\t//this.dumpRouter('activate');\r\n\t}\r\n\r\n\tasync attached() { // paa dette tidspunkt er vores view allerede blevet renderet og har kigget paa data, saa det er IKKE godt hvis vi foerst laeser data nu..\r\n\r\n\t\tthis.isDesktop = Boolean(this.device.getDeviceType() === 'desktop');\r\n\t\tconsole.log('nav.attached, appCtx.project says:', this.appContext.projectId);\r\n\r\n this.initAll(); // now in attached.\r\n\r\n\t\tthis.subscriptions = [\r\n\t\t\tthis.events.subscribe(\"project-selector:project-changed\", async () => this.handleProjectChangedEvent()),\r\n\t\t\tthis.events.subscribe(\"router:navigation:processing\", () => this.showMobileNav = false),\r\n\t\t\tthis.events.subscribe(\"overlay:clicked\", () => this.closeNav()),\r\n\t\t\tthis.events.subscribe(\"navigation:update-prj-token\", async () => await this.createAndUpdatePrjToken()),//event:\"navigation:update-prj-token\"\r\n\t\t\tthis.events.subscribe(\"navigation:update-org-token\", async (orgId: string) => await this.createAndUpdateOrgToken(orgId)),\r\n\t\t\tthis.events.subscribe('project-invitation-accepted', async() => {\r\n\t\t\t\tawait this.getOrganizations_forUser();\r\n\t\t\t\tthis.updateOrgTokenInfo(false)\r\n\t\t\t})\r\n\t\t];\r\n\t\t//this.dumpRouter('attached');\r\n\t}\r\n\r\n\tdeactivate() { this.subscriptions.forEach(subscription => ( subscription.dispose() )); }\r\n\r\n\t///////////////////////////////////////////////////////////////////////////\r\n\tprivate async updateLocalProject(force:boolean):Promise { // (typically called when we receive the event \"project-selector:project-changed\")\r\n\t\t// Beware, we only get appContext.projectId set from dashboard.activate, so too early, it might not be set yet!\r\n\r\n\t\tthis.selectedProject = this.appContext.getSelectedProject();//in-updateLocalProject\r\n\t\tconsole.log(\"updateLocalProject.. Updating selectedProject on nav object, because it possibly changed on appContext. prjId:\", this.selectedProject?.id);\r\n\t\tif (force) {\r\n\t\t\tawait this.INIT_ProjectToken(this.selectedProject?.id);//in-updateLocalProject\r\n\t\t} else {\r\n\t\t\tawait this.updateProjectToken(this.selectedProject?.id);//in-updateLocalProject\r\n\t\t}\r\n\t}\r\n\r\n\tasync createAndUpdatePrjToken(): Promise {//triggered by event \"navigation:update-prj-token\"\r\n\t\t// This is what happens when you either select an ORG from the dropdown, or change roles in the manage-prj-manage(!) screens.\r\n\r\n\t\t// (JG: This variant is weird, because it ignores 'this.selectedProject'?)\r\n\t\tlet projectId: string | undefined = this.appContext.getSelectedProject()?.id;\r\n\t\tconsole.log('createAndUpdatePrjToken, prjId:', projectId);\r\n\t\tif (projectId) {\r\n\t\t\tconst createdNew = await this.projectTokenService.createNewProjectToken(projectId, this.apiClient,'createAndUpdatePrjToken');\r\n\t\t\tconsole.log('createNew?', createdNew);\r\n\t\t\tif (createdNew) { // JG: This 'check' approach is silly, because nothing is said about what to DO, when it is NOT satisfied, so it would STILL break weirdly..?\r\n\t\t\t\tlet prjTokenInfo: ProjectTokenInfo = this.projectTokenService.getPrjTokenInfo();\r\n\t\t\t\tthis.projectTokenInfo = prjTokenInfo;//in-updatePrjTokenInfo\t\t\r\n\t\t\t\t//this.updatePrjTokenInfo();//in-createAndUpdatePrjToken\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tconsole.log('nav.createAndUpdatePrjToken, no prjId, no create..', projectId);\r\n\t\t}\r\n\t}\r\n\r\n\tasync INIT_ProjectToken(projectId: string | undefined) {\r\n\t\tconsole.log('INIT_ProjectToken', projectId);\r\n\t\t// first, make sure PTS _HAS_ a token:\r\n\t\tawait this.projectTokenService.updatePrjTokenIfNeeded(projectId, this.apiClient); \r\n\t\t// secondly, violently assign it no matter what, because we are INITIALIZING:\r\n\t\tthis.projectTokenInfo = this.projectTokenService.getPrjTokenInfo();\r\n\t}\r\n\tasync updateProjectToken(projectId: string | undefined): Promise { // (NB, updateProjectToken is only called by updateLocalProject.)\r\n\t\tconst anyFreshToken = await this.projectTokenService.anyFreshPrjToken(projectId, this.apiClient);\r\n\t\tif (anyFreshToken) { this.projectTokenInfo = anyFreshToken; }\r\n\t\t\r\n\t\tif (!anyFreshToken && this.projectTokenInfo.prjRole<0) { \r\n\t\t\tthis.projectTokenInfo = this.projectTokenService.getPrjTokenInfo(); \r\n\t\t\tconsole.warn('because token-update still lacks data, we force an update, to:', this.projectTokenInfo);\r\n\t\t}\r\n\t\tconsole.log('updateProjectToken, anyFresh?',anyFreshToken,'projectTokenInfo?', this.projectTokenInfo, this.projectTokenInfo.prjId );\r\n\t}\r\n\r\n\r\n\t///////////////////////////////////////////////////////////////////////////\r\n\tasync initProjectWithToken() { // originally part of attached.\r\n\t\tconsole.log('initProjectWithToken, which tries updateLocalProject');\r\n\t\tawait this.updateLocalProject(true);//in-initProjectWithToken\r\n\t}\r\n\tasync initOrgsWithToken():Promise {\r\n\t\tawait this.getOrganizations_forUser();\r\n\t\tthis.updateOrgTokenInfo(false); \r\n\t}\r\n\r\n\t@computedFrom('selectedProject')\r\n\tget router_navigation():NavModel[] { // JG: This hack ensures enable-disable menu-items is re-evaluated whenever selectedProject changes!\r\n\t\tconsole.log('router_navigation, we triggered a computedFrom update.');\r\n\t\treturn this.router?.navigation!; \r\n\t}\r\n\r\n\t// JG: We can't do it on this level, because that is an inner nested loop, not a direct property of Navigation:\r\n\t//@computedFrom('selectedProject')\r\n\troute_settings_children(route:NavModel): IRouteConfig_Child[] { \r\n\t\tconst settings:RouteSettingAjour = route.settings;\r\n\t\tconst children:IRouteConfig_Child[] = settings.children!;\r\n\t\treturn route.settings.children; \r\n\t}\r\n\r\n\t\r\n\tstatic dumpRoutes:boolean = false;\r\n\tdumpRouter(who:string) {\r\n\t\tif (!Navigation.dumpRoutes) { return; }\r\n\t\tconsole.log('dumpRouter', who);\r\n\t\tconsole.log('token1', this.projectTokenInfo);\r\n\t\tconsole.log('token2', this.orgTokenInfo);\r\n\t\t//projectTokenInfo, orgTokenInfo\r\n\r\n\t\tif (!this.router) { return; } // console.log('no router?', this.router);\r\n\r\n\t\tfor (let route of this.router!.navigation) {\r\n\t\t\tconsole.log('route:', route.config.name, route);\r\n\t\t\tconsole.log('#children:', route.settings.children.length);\r\n\t\t\tfor (let item of route.settings.children) {\r\n\t\t\t\tconsole.log('a-item:', item);\r\n\t\t\t\tconsole.log('menuAccessLevel:', item.menuAccessLevel);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t\r\n\r\n\r\n\tstatic emptyCount=0;\r\n\tisItemEmpty(item: any): boolean {\r\n\t\tconst isEmpty:boolean = (Object.keys(item).length === 0);\r\n\t\t// we will hide this log again, we are just debugging.\r\n\t\tif (isEmpty) { \r\n\t\t\t//console.warn('another empty:', ++Navigation.emptyCount, item); \r\n\t\t}\r\n\t\treturn isEmpty;\r\n\t}\r\n\r\n //////////////////////////// ORG-TOKEN STUFF ///////////////////////////\r\n\tasync getOrganizations_forUser(): Promise {\r\n\t\tthis.organizations = await this.apiClient.global.get(\"UserInfo/GetUserOrganizations\").jsonResult();\r\n\t\tif (this.organizations.length == 1) {\r\n\t\t\tawait this.orgTokenService.createNewOrgToken(this.organizations[0].id, this.apiClient);\r\n\t\t} // why is updateOrgTokenInfo not required in THIS case?\r\n\t}\r\n\r\n\tasync createAndUpdateOrgToken(orgId: string): Promise {\r\n\t\tif (await this.orgTokenService.createNewOrgToken(orgId,this.apiClient)) { this.updateOrgTokenInfo(true); }\r\n\t}\r\n\r\n\tupdateOrgTokenInfo(shouldSendEvent: boolean): void {\r\n\t\tlet orgTokenInfo: OrgTokenInfo = this.orgTokenService.getOrgTokenInfo();\r\n\t\tthis.orgTokenInfo = orgTokenInfo;\r\n\t\tthis.selectedOrg = this.organizations.find(org => org.id == orgTokenInfo.orgId);\r\n\t\tconsole.log(\"orgTokenInfo \" , this.orgTokenInfo);\r\n\t\tif (shouldSendEvent) {\r\n\t\t\tthis.events.publish(\"global:org-changed\");\r\n\t\t}\r\n\t}\r\n ////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n\tpublic hasAccess(route:IRouteConfig_Child | RouteConfig_Root, projectTokenInfo: ProjectTokenInfo, orgTokenInfo: OrgTokenInfo): boolean {\r\n\t\t//projectTokenInfo and orgTokenInfo parameter is a hack to reevaluate function whenever project or org has changed.\r\n\t\tconst show = true;\r\n\t\tconst access = AccessLevelService.hasAccess(this.appContext, route, projectTokenInfo, orgTokenInfo, show);\t\t\r\n\t\t//console.log('hasAccess:', access,route);\r\n\t\treturn access;\r\n\t}\r\n\t\r\n\tprivate routeExistsInNavigationAsChild(): Boolean {\r\n\t\tconst navChildren: any[] = [];\r\n\t\tthis.router?.navigation.forEach((section: any) => {\r\n\t\t\tsection.settings.children.forEach((children: any) => {\r\n\t\t\t\tnavChildren.push(children);\r\n\t\t\t});\r\n\t\t});\r\n\t\treturn Boolean(navChildren.some(child => child.title === this.router?.currentInstruction.config.title));\r\n\t}\r\n\r\n\tpublic toggleNav() { //For opening and closing menu.\r\n\t\tconsole.log('Navigation.toggleNav');\r\n\t\tif (this.isDesktop) { // Desktop\r\n\t\t\tthis.navCollapsed = !this.navCollapsed;\r\n\t\t\tthis.events.publish(\"nav-collapsed\", this.navCollapsed);\r\n\t\t} else { // Not Desktop\r\n\t\t\tthis.showMobileNav = !this.showMobileNav;\r\n\t\t\tthis.events.publish(\"show-overlay\", !this.showMobileNav ? false : true);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic closeNav() {\r\n\t\tconsole.log('Navigation.closeNav');\r\n\t\tif (!this.isDesktop) {\r\n\t\t\tthis.showMobileNav = false;\r\n\t\t\tthis.events.publish(\"show-overlay\", false);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic toggleSubMenu(event: any) {//Handle opening and closing of menu items\r\n\t\tconsole.log('Navigation.toggleSubMenu, event:', event); //event.target);\r\n\t\t//this.dumpRouter('toggleSubMenu');\r\n\r\n\t\tconst eventTarget:Element = event.target;\r\n\r\n\t\tlet ALL_navListItems = document.querySelectorAll('.nav-list__item');\r\n\t\tlet anyClicked_NavList_Item_:Element|null = eventTarget.closest('.nav-list__item'); // (We are looking for a close ANCESTOR with that class)\r\n\t\tlet curClicked_NavList_Item:Element = anyClicked_NavList_Item_!; // We expect it to ALWAYS be there..\r\n\t\tconsole.log('any navList-item clicked?', curClicked_NavList_Item);\r\n\r\n\t\tif (curClicked_NavList_Item.classList.contains('expanded')) {\r\n\t\t\t// If the clicked navList item was already expanded, de-expand it:\r\n\t\t\tconsole.log(\"Removing class 'expanded' from currently expanded navlist-Item\", curClicked_NavList_Item);\r\n\t\t\tcurClicked_NavList_Item.classList.remove('expanded');\r\n\t\t} else {\r\n\t\t\tconsole.log(\"removing class 'expanded' from EACH navListItem, numbering #\", ALL_navListItems.length);\r\n\t\t\tALL_navListItems.forEach((item) => { // Closes all/any currently opened sub-menus.\r\n\t\t\t\titem.classList.remove('expanded');\r\n\t\t\t});\r\n\t\t\t// Then, ONLY open the one we just clicked:\r\n\t\t\tcurClicked_NavList_Item.classList.add('expanded');\r\n\t\t\tconsole.log(\".. then, ADDING class 'expanded' to currently clicked navList-Item\", curClicked_NavList_Item);\r\n\t\t\tconsole.log(\"classList now:\", curClicked_NavList_Item.classList);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic toggleSubSubMenu(event: any) {\r\n\t\tconsole.log('Navigation.toggleSubSubMenu', event);\r\n\t\tlet navListItems = document.querySelectorAll('.sub-menu-list__sub-list');\r\n\t\tlet target = event.target.closest('.sub-menu-list__sub-list');\r\n\r\n\t\tif (target.classList.contains('expanded')) {\r\n\t\t\ttarget.classList.remove('expanded');\r\n\t\t} else {\r\n\t\t\tnavListItems.forEach((item) => { item.classList.remove('expanded'); });//Closes any currently opened sub-sub-menus\r\n\t\t\ttarget.classList.add('expanded');\r\n\t\t}\r\n\t}\r\n\r\n\tprivate setActiveParentOnLoad() {\r\n\t\tconsole.log('Navigation.setActiveParentOnLoad');\r\n\t\tconst classList = document.querySelector('.nav-link.active')?.parentElement?.parentElement?.parentElement?.classList;\r\n\t\tclassList!.add('active');\r\n\t\tclassList!.add('expanded');\r\n\t\tconsole.log('setActiveParentOnLoad');\r\n\t}\r\n\r\n\tpublic async handleNavigateEventForSubItem(baseUrl: string, href: string, event: any) { \r\n\t\tconsole.log('Navigation.handleNavigateEventForSubItem');\r\n\t\t// console.log(href.substring(0, 7));\r\n\t\tlet sub = href.substring(0, Navigation.PROJECT_PART.length);\r\n\t\tif (await this.handleNoSelectedProject(sub, href)) {//in-handleNavigateEventForSubSubItem\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tlet parent: HTMLElement = event.target.parentElement.parentElement.parentElement;\r\n\t\tthis.closeSubNavList();\r\n\t\t\r\n\t\tif (parent.classList.contains('active') === false) {\r\n\t\t\tthis.highlightParent(parent);\r\n\t\t}\r\n\t\tthis.navigateToRoute(sub, baseUrl, href);\r\n\t}\r\n\r\n\tpublic async handleNavigateEventForSubSubItem(baseUrl: string, href: string, event: any) {\r\n\t\tconsole.log('handleNavigateEventForSubSubItem, baseUrl:', baseUrl, 'href:', href, 'event:', event);\r\n\t\t// console.log(href.substring(0, 7));\r\n\t\tlet sub = href.substring(0, Navigation.PROJECT_PART.length); //7);\r\n\t\tif (await this.handleNoSelectedProject(sub, href)) {//in-handleNavigateEventForSubSubItem\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tlet parent: HTMLElement = event.target.parentElement.parentElement;\r\n\t\tthis.closeSubNavList();\r\n\t\t\r\n\t\tthis.highlightParent(parent);\r\n\t\tthis.handleParentsParent(parent);\r\n\r\n\t\tthis.navigateToRoute(sub, baseUrl, href);\r\n\t}\r\n\r\n\tpublic static PROJECT_PART = 'project';\r\n\r\n\tasync handleNoSelectedProject(sub: string, href: string):Promise {\r\n\t\tconsole.log('Navigation.handleNoSelectedProject');\r\n\r\n\t\tif (sub === Navigation.PROJECT_PART && !Boolean(this.appContext.projectId) && href !== \"project/overview\") {\r\n\t\t\tawait this.errorService.noProjectSelected();//in-handleNoSelectedProject\r\n\t\t\tthis.appContext.setExpectedRoute(href);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\thandleParentsParent(parent: HTMLElement) {\r\n\t\tconsole.log('Navigation.handleParentsParent');\r\n\t\tparent.parentElement?.parentElement?.parentElement?.classList.add('active');\r\n\t\tparent.parentElement?.parentElement?.parentElement?.classList.add('expanded');\r\n\t}\r\n\r\n\tcloseSubNavList() {\r\n\t\tconsole.log('Navigation.closeSubNavList');\r\n\t\tlet subNavList = document.querySelectorAll('.sub-menu-list__sub-list');\r\n\t\tsubNavList.forEach((item) => {\r\n\t\t\titem.classList.remove('active');\r\n\t\t\titem.classList.remove('expanded');\r\n\t\t});\r\n\t}\r\n\r\n\thighlightParent(parent: HTMLElement) {\r\n\t\tconsole.log('Navigation.highlightParent');\r\n\t\tdocument.querySelectorAll('.nav-list__item').forEach((item) => {\r\n\t\t\titem.classList.remove('active');\r\n\t\t\titem.classList.remove('expanded');\r\n\t\t});\r\n\t\tparent.classList.add('active');\r\n\t\tparent.classList.add('expanded');\r\n\t}\r\n\t\r\n\tnavigateToRoute(sub: string, baseUrl: string, href: string) {\r\n\t\tconsole.log('Navigation.navigateToRoute');\r\n\t\t/* JG: Beware that this kludge requires views to have this project-bla-bla prefix to work correctly,\r\n\t\tin order to get this 'support'/helping-hand. */\r\n\t\tif (sub === \"project\" && href !== \"project/overview\") {\r\n\t\t\t// (muligvis er det længden på ordet /project'? - se 'PROJECT_PART'.)\r\n\t\t\t// JG: Hvad er det for en masse underlige hardcodede 7 og 8 taller..?\r\n\t\t\t//let url = '#' + baseUrl + sub + \"/\" + this.appContext.projectId + \"/\" + href.substring(8);\r\n\t\t\tlet newroute = `#${baseUrl}${sub}/${this.prjId()}/${href.substring(8)}`;\r\n\t\t\tconsole.log('navigateToRoute, project newroute:', newroute);\r\n\t\t\tthis.router?.navigate(newroute);\r\n\t\t} else {\r\n\t\t\tthis.router?.navigate('#' + baseUrl + href);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic toggleProfileMenu() { this.isProfileMenuOpen = !this.isProfileMenuOpen; } //console.log('Navigation.toggleProfileMenu');\r\n\tpublic openNotifications() { this.events.publish(\"notification-center:toggle\"); }//console.log('Navigation.openNotifications');\r\n\tpublic signOut() { this.appContext.switchProjectLogic(\"\", 'signout,new-nav'); this.userSession.logOut(); } // console.log('Navigation.signOut');\r\n\r\n\thasProjectId(): boolean | string {\r\n\t\tlet prjId = this.appContext.projectId;\r\n\t\treturn prjId && (prjId != AppContextService.NO_PROJECT);\r\n\t}\r\n\r\n\tprjId():string { return this.appContext.projectId ? this.appContext.projectId : AppContextService.NO_PROJECT; }\r\n\t\r\n\tgoToProjectOverview(event: Event): boolean {\r\n\t\tevent.stopPropagation();\r\n\t\tthis.router?.navigateToRoute(\"project/overview\");\r\n\t\treturn true;\r\n\t}\r\n\r\n\tasync selectOrg(org: {id: string, name: string}): Promise {\r\n\t\tlet updated = await this.orgTokenService.updateOrgTokenIfNeeded(org.id,this.apiClient);\r\n\t\tif (updated) { this.updateOrgTokenInfo(true); }\r\n\t}\r\n\r\n\tprivate async handleProjectChangedEvent() { // (reacts on EVENT \"project-selector:project-changed\")\r\n\t\tconsole.log('handleProjectChangedEvent triggered');\r\n\t\t// typically triggered by project-selector.selectProject().\r\n\t\tawait this.updateLocalProject(false);//in-handleProjectChangedEvent\r\n\t\tconsole.log('handleProjectChangedEvent', this.selectedProject?.name);\r\n\r\n\t\tawait this.extraProjectChangeHackStuff(); // JG: I isolated this bit.\r\n\t}\r\n\r\n\tprivate async extraProjectChangeHackStuff() { // was part of handleProjectChangedEvent.\r\n\r\n\t\t/* JG: Answer for Andreas: I seem to vaguely recall what this crap was used for.\r\n\t\tThere is/was some way of navigating, where some properties that would NORMALLY be filled out/populated,\r\n\t\twould be empty when doing the weird navigation thing.\r\n\t\t The below stuff was then the band-aid that fixed that.\r\n\t\tPossibly, it has to do with how routing-sourced parameter fields are filled out\r\n\t\t(e.g. when a parameter is sourced from the url path as xyz/:someValue/xyz ).\r\n\t\t*/\r\n\r\n\t\t// AEP: I don't see what this is used for. It routes anyways when selecting a new project.\r\n\r\n\t\t/*\r\n\t\tif (Boolean(this.appContext.expectedRoute)) {\r\n\t\t\tlet sub: string | undefined = this.appContext.expectedRoute?.substring(0, Navigation.PROJECT_PART.length); //7);\r\n\r\n\t\t\tif (sub === \"project\" && this.appContext.expectedRoute !== \"project/overview\") {\r\n\t\t\t\t//let url = '#' + this.router.baseUrl + sub + \"/\" + this.appContext.projectId + \"/\" + this.appContext.expectedRoute.substring(8);\r\n\t\t\t\tlet newroute = `#${this.router?.baseUrl}${sub}/${this.prjId()}/${this.appContext.expectedRoute?.substring(8)}`; // this.appContext.projectId\r\n\t\t\t\tconsole.log('handleProjectChangedEvent, project newroute:', newroute);\r\n\t\t\t\tthis.router?.navigate(newroute);\r\n\t\t\t} else {\r\n\t\t\t\tthis.router?.navigate('#' + this.router.baseUrl + this.appContext.expectedRoute);\r\n\t\t\t}\r\n\r\n\t\t\tthis.appContext.expectedRoute = null;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Temporary fix for updating view data when project changes\r\n\t\tlet instruction: any = this.router?.currentInstruction.config.name;\r\n\t\tlet subroutes: any = { // maps instructions to subroutes.\r\n\t\t 'project-building-parts': \t\t\t\t'building-parts',\r\n\t\t 'project/materials': \t\t\t\t'materials',\r\n\t\t 'project/parameters': \t\t\t\t'parameters',\r\n \t\t 'project/parameters/bulk-parameters': \t'bulk-parameters',\r\n\t\t 'project/manual-entry': \t\t\t\t'manual-entry',\r\n\t\t 'project/ifc-import': \t\t\t\t'ifc-import', // JG: the left part, the 'instruction', seems to be the HREF in aox.ts?\r\n\t\t 'project/ifc-fun': \t\t\t\t 'ifc-fun', // JG: the left part, the 'instruction', seems to be the HREF in aox.ts?\r\n\t\t 'project/openbim-testbed': \t\t\t'openbim-testbed', // JG: the left part, the 'instruction', seems to be the HREF in aox.ts?\r\n\t\t 'project/value-lists': \t\t\t\t'value-lists',\r\n\t\t 'project/categories': \t\t\t\t'categories',\r\n\t\t 'project/summing': \t\t\t\t'summing',\r\n\t\t 'project-whitelist': \t\t\t\t'whitelist',\r\n\t\t 'project/changelog': \t\t\t\t'changelog',\r\n\t\t 'lca-export': \t\t\t\t'lcabyg/export',\r\n\t\t 'project/model-revision': \t\t\t\t'model-revision',\t\t\r\n\t\t 'project/work-area': \t\t\t\t'work-area',\r\n\t\t 'project/tender-list': \t\t\t\t'tender-list', // YES same subroute twice!\r\n\t\t 'project/tender-settings': \t\t\t\t'tender-list', // YES same subroute twice!\r\n\t\t 'project/quantity-views': \t\t\t\t'quantity-views',\r\n\t\t 'project/quantity-filters':\t\t\t\t'quantity-filters', // den siger den ikke kan finde denne?\r\n\t\t 'project/quantity-grid': \t\t\t\t'quantity-grid',\r\n\t\t 'project/pivot-grid': \t\t\t\t'pivot-grid',\r\n\t\t 'project/quantity-takeoff': \t\t\t\t'quantity-takeoff',\r\n\t\t 'project/test-model-revision': \t\t\t'test-model-revision',\r\n\t\t 'project/dashboard': \t\t\t\t\t\t'dashboard'\r\n\t\t}\r\n\t\tlet subroute:string = subroutes[instruction];\r\n\t\tif (subroute) {\r\n\t\t\tlet newroute = `project/${this.prjId()}/${subroute}/`;\r\n\t\t\tconsole.log('handleProjectChangedEvent, newroute:', newroute);\r\n\t\t\tthis.router?.navigate(newroute);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t */\r\n\t}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\t/* SHARED waiting for a resource-promise, gotten from Andreas and google-gemini;\r\n\t\t\tcould be used to initialize project-token:\r\n ..\r\n\tlet tokenPromise: Promise | null = null;\r\n\tlet isTokenBeingFetched = false;\r\n\t\t\r\n\tasync function getToken(): Promise {\r\n\t\tif (tokenPromise && !isTokenBeingFetched) {\r\n\t\t\t// Token fetch already in progress, wait for it\r\n\t\t\treturn await tokenPromise;\r\n\t\t}\r\n\t\t\r\n\t\tisTokenBeingFetched = true; // Mark fetching in progress\r\n\t\t\r\n\t\ttry {\r\n\t\t\tconst token = await fetchTokenFromServer(); // Your server-side token fetching logic\r\n\t\t\ttokenPromise = Promise.resolve(token); // Update promise with resolved token\r\n\t\t\treturn token;\r\n\t\t} finally {\r\n\t\t\tisTokenBeingFetched = false; // Release the flag after fetching or error\r\n\t\t}\r\n\t}\r\n\t..\r\n\t*/\r\n}\r\n\r\n\r\n\r\n\r\n\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","Navigation","constructor","events","appContext","i18n","userSession","device","errorService","projectTokenService","orgTokenService","apiClient","selectedProject","undefined","navCollapsed","showMobileNav","isDesktop","ajourLogo","logoWhiteUrl","egPhone","phone","ajourEmail","email","egWebsite","website","isProfileMenuOpen","subscriptions","projectTokenInfo","prjId","prjRole","VeryUnknown","orgId","orgRole","Unknown","orgTokenInfo","organizations","console","log","projectId","initAll","this","initProjectWithToken","initOrgsWithToken","activate","Boolean","routeExistsInNavigationAsChild","router","currentInstruction","config","nav","setActiveParentOnLoad","attached","getDeviceType","subscribe","async","handleProjectChangedEvent","closeNav","createAndUpdatePrjToken","createAndUpdateOrgToken","getOrganizations_forUser","updateOrgTokenInfo","deactivate","forEach","subscription","dispose","updateLocalProject","force","getSelectedProject","INIT_ProjectToken","updateProjectToken","createdNew","createNewProjectToken","prjTokenInfo","getPrjTokenInfo","updatePrjTokenIfNeeded","anyFreshToken","anyFreshPrjToken","warn","router_navigation","navigation","route_settings_children","route","settings","children","dumpRouter","who","dumpRoutes","name","length","item","menuAccessLevel","isItemEmpty","Object","keys","global","get","jsonResult","createNewOrgToken","shouldSendEvent","getOrgTokenInfo","selectedOrg","find","org","publish","hasAccess","navChildren","section","some","child","title","toggleNav","toggleSubMenu","event","eventTarget","target","ALL_navListItems","document","querySelectorAll","curClicked_NavList_Item","closest","classList","contains","remove","add","toggleSubSubMenu","navListItems","querySelector","parentElement","handleNavigateEventForSubItem","baseUrl","href","sub","substring","PROJECT_PART","handleNoSelectedProject","parent","closeSubNavList","highlightParent","navigateToRoute","handleNavigateEventForSubSubItem","handleParentsParent","noProjectSelected","setExpectedRoute","newroute","navigate","toggleProfileMenu","openNotifications","signOut","switchProjectLogic","logOut","hasProjectId","NO_PROJECT","goToProjectOverview","stopPropagation","selectOrg","updateOrgTokenIfNeeded","extraProjectChangeHackStuff","emptyCount","bindable","computedFrom","autoinject","EventAggregator","I18N"],"sourceRoot":""}