github.com/hernad/nomad@v1.6.112/ui/app/routes/application.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 /* eslint-disable ember/no-controller-access-in-routes */ 7 import { inject as service } from '@ember/service'; 8 import { later, next } from '@ember/runloop'; 9 import Route from '@ember/routing/route'; 10 import { AbortError } from '@ember-data/adapter/error'; 11 import RSVP from 'rsvp'; 12 import { action } from '@ember/object'; 13 import classic from 'ember-classic-decorator'; 14 15 @classic 16 export default class ApplicationRoute extends Route { 17 @service config; 18 @service system; 19 @service store; 20 @service token; 21 @service router; 22 23 queryParams = { 24 region: { 25 refreshModel: true, 26 }, 27 }; 28 29 resetController(controller, isExiting) { 30 if (isExiting) { 31 controller.set('error', null); 32 } 33 } 34 35 async beforeModel(transition) { 36 let promises; 37 38 // service:router#transitionTo can cause this to rerun because of refreshModel on 39 // the region query parameter, this skips rerunning the detection/loading queries. 40 if (transition.queryParamsOnly) { 41 promises = Promise.resolve(true); 42 } else { 43 let exchangeOneTimeToken; 44 45 if (transition.to.queryParams.ott) { 46 exchangeOneTimeToken = this.get('token').exchangeOneTimeToken( 47 transition.to.queryParams.ott 48 ); 49 } else { 50 exchangeOneTimeToken = Promise.resolve(true); 51 } 52 53 try { 54 await exchangeOneTimeToken; 55 } catch (e) { 56 this.controllerFor('application').set('error', e); 57 } 58 59 const fetchSelfTokenAndPolicies = this.get( 60 'token.fetchSelfTokenAndPolicies' 61 ) 62 .perform() 63 .catch(); 64 65 const fetchLicense = this.get('system.fetchLicense').perform().catch(); 66 67 const checkFuzzySearchPresence = this.get( 68 'system.checkFuzzySearchPresence' 69 ) 70 .perform() 71 .catch(); 72 73 promises = await RSVP.all([ 74 this.get('system.regions'), 75 this.get('system.defaultRegion'), 76 fetchLicense, 77 fetchSelfTokenAndPolicies, 78 checkFuzzySearchPresence, 79 ]); 80 } 81 82 if (!this.get('system.shouldShowRegions')) return promises; 83 84 const queryParam = transition.to.queryParams.region; 85 const defaultRegion = this.get('system.defaultRegion.region'); 86 const currentRegion = this.get('system.activeRegion') || defaultRegion; 87 88 // Only reset the store if the region actually changed 89 if ( 90 (queryParam && queryParam !== currentRegion) || 91 (!queryParam && currentRegion !== defaultRegion) 92 ) { 93 this.store.unloadAll(); 94 } 95 96 this.set('system.activeRegion', queryParam || defaultRegion); 97 98 return promises; 99 } 100 101 // Model is being used as a way to propagate the region and 102 // one time token query parameters for use in setupController. 103 model( 104 { region }, 105 { 106 to: { 107 queryParams: { ott }, 108 }, 109 } 110 ) { 111 return { 112 region, 113 hasOneTimeToken: ott, 114 }; 115 } 116 117 setupController(controller, { region, hasOneTimeToken }) { 118 if (region === this.get('system.defaultRegion.region')) { 119 next(() => { 120 controller.set('region', null); 121 }); 122 } 123 124 super.setupController(...arguments); 125 126 if (hasOneTimeToken) { 127 // Hack to force clear the OTT query parameter 128 later(() => { 129 controller.set('oneTimeToken', ''); 130 }, 500); 131 } 132 } 133 134 @action 135 didTransition() { 136 if (!this.get('config.isTest')) { 137 window.scrollTo(0, 0); 138 } 139 } 140 141 @action 142 willTransition() { 143 this.controllerFor('application').set('error', null); 144 } 145 146 @action 147 error(error) { 148 if (!(error instanceof AbortError)) { 149 if ( 150 error.errors?.any( 151 (e) => 152 e.detail === 'ACL token expired' || 153 e.detail === 'ACL token not found' 154 ) 155 ) { 156 this.router.transitionTo('settings.tokens'); 157 } else { 158 this.controllerFor('application').set('error', error); 159 } 160 } 161 } 162 }