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