@fleetbase/ember-core 0.2.16 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,119 +3,36 @@ import Evented from '@ember/object/evented';
3
3
  import { inject as service } from '@ember/service';
4
4
  import { tracked } from '@glimmer/tracking';
5
5
  import { dasherize } from '@ember/string';
6
- import { computed, get, action } from '@ember/object';
6
+ import { computed, get } from '@ember/object';
7
7
  import { isBlank } from '@ember/utils';
8
8
  import { alias } from '@ember/object/computed';
9
9
  import { storageFor } from 'ember-local-storage';
10
10
 
11
11
  export default class CurrentUserService extends Service.extend(Evented) {
12
- /**
13
- * Inject the `session` service
14
- *
15
- * @var {Service}
16
- */
17
12
  @service session;
18
-
19
- /**
20
- * Inject the `store` service
21
- *
22
- * @var {Service}
23
- */
24
13
  @service store;
25
-
26
- /**
27
- * Inject the `fetch` service
28
- *
29
- * @var {Service}
30
- */
31
14
  @service fetch;
32
-
33
- /**
34
- * Inject the `theme` service
35
- *
36
- * @var {Service}
37
- */
38
15
  @service theme;
39
-
40
- /**
41
- * Inject the `notifications` service
42
- *
43
- * @var {Service}
44
- */
45
16
  @service notifications;
17
+ @service intl;
46
18
 
47
- /**
48
- * Property to hold loaded user.
49
- *
50
- * @var {UserModel|Object}
51
- * @memberof CurrentUserService
52
- */
53
- @tracked user = {
54
- id: 'anon',
55
- };
56
-
57
- /**
58
- * The current users permissions.
59
- *
60
- * @memberof CurrentUserService
61
- */
19
+ @tracked user = { id: 'anon' };
20
+ @tracked company = {};
62
21
  @tracked permissions = [];
22
+ @tracked organizations = [];
23
+ @tracked whoisData = {};
24
+ @tracked locale = 'en-us';
63
25
 
64
- /**
65
- * User options in localStorage
66
- *
67
- * @var StorageObject
68
- */
69
26
  @storageFor('user-options') options;
70
-
71
- /**
72
- * Alias for current user id
73
- *
74
- * @var {String}
75
- */
76
27
  @alias('user.id') id;
77
-
78
- /**
79
- * Alias for current user name
80
- *
81
- * @var {String}
82
- */
83
28
  @alias('user.name') name;
84
-
85
- /**
86
- * Alias for current user phone
87
- *
88
- * @var {String}
89
- */
90
29
  @alias('user.phone') phone;
91
-
92
- /**
93
- * Alias for current user phone
94
- *
95
- * @var {String}
96
- */
97
30
  @alias('user.email') email;
98
-
99
- /**
100
- * Alias for current user's company id
101
- *
102
- * @var {String}
103
- */
104
- @alias('user.company_uuid') companyId;
105
-
106
- /**
107
- * Alias for if user is admin.
108
- *
109
- * @var {Boolean}
110
- * @memberof CurrentUserService
111
- */
31
+ @alias('user.avatar_url') avatarUrl;
112
32
  @alias('user.is_admin') isAdmin;
33
+ @alias('user.company_uuid') companyId;
34
+ @alias('user.company_name') companyName;
113
35
 
114
- /**
115
- * The prefix for this user options
116
- *
117
- * @var {String}
118
- */
119
36
  @computed('id') get optionsPrefix() {
120
37
  return `${this.id}:`;
121
38
  }
@@ -140,71 +57,115 @@ export default class CurrentUserService extends Service.extend(Evented) {
140
57
  return this.whois('country_code');
141
58
  }
142
59
 
143
- /**
144
- * Loads the current authenticated user
145
- *
146
- * @return Promise<UserModel>|null
147
- */
148
60
  async load() {
149
61
  if (this.session.isAuthenticated) {
150
- let user = await this.store.findRecord('user', 'me');
62
+ const user = await this.store.findRecord('user', 'me');
151
63
  this.set('user', user);
152
64
  this.trigger('user.loaded', user);
153
65
 
154
66
  // Set permissions
155
67
  this.permissions = this.getUserPermissions(user);
156
68
 
69
+ // Load preferences
70
+ await this.loadPreferences();
71
+
157
72
  return user;
158
73
  }
159
74
 
160
75
  return null;
161
76
  }
162
77
 
163
- /**
164
- * Resolves a user model.
165
- *
166
- * @return {Promise<User>}
167
- */
168
- @action promiseUser(options = {}) {
78
+ async promiseUser(options = {}) {
169
79
  const NoUserAuthenticatedError = new Error('Failed to authenticate user.');
80
+ if (!this.session.isAuthenticated) {
81
+ throw NoUserAuthenticatedError;
82
+ }
170
83
 
171
- return new Promise((resolve, reject) => {
172
- if (this.session.isAuthenticated) {
173
- try {
174
- this.store.queryRecord('user', { me: true }).then((user) => {
175
- // set the `current user`
176
- this.set('user', user);
177
- this.trigger('user.loaded', user);
178
-
179
- // Set permissions
180
- this.permissions = this.getUserPermissions(user);
181
-
182
- // set environment from user option
183
- this.theme.setEnvironment();
184
-
185
- // @TODO Create an event dispatch for when an authenticated user is resolved from the server
186
- if (typeof options?.onUserResolved === 'function') {
187
- options.onUserResolved(user);
188
- }
189
-
190
- resolve(user);
191
- });
192
- } catch (error) {
193
- reject(NoUserAuthenticatedError);
194
- }
195
- } else {
196
- reject(NoUserAuthenticatedError);
84
+ try {
85
+ const user = await this.store.queryRecord('user', { me: true });
86
+
87
+ // Set current user
88
+ this.set('user', user);
89
+ this.trigger('user.loaded', user);
90
+
91
+ // Set permissions
92
+ this.permissions = this.getUserPermissions(user);
93
+
94
+ // Set environment from user option
95
+ this.theme.setEnvironment();
96
+
97
+ // Load user preferces
98
+ await this.loadPreferences();
99
+
100
+ // Optional callback
101
+ if (typeof options?.onUserResolved === 'function') {
102
+ options.onUserResolved(user);
197
103
  }
198
- });
104
+
105
+ return user;
106
+ } catch (error) {
107
+ console.log(error.message);
108
+ throw error;
109
+ }
110
+ }
111
+
112
+ async loadPreferences() {
113
+ await this.loadLocale();
114
+ await this.loadWhois();
115
+ await this.loadOrganizations();
116
+ }
117
+
118
+ async loadLocale() {
119
+ try {
120
+ const { locale } = await this.fetch.get('users/locale');
121
+ this.setOption('locale', locale);
122
+ this.intl.setLocale(locale);
123
+ this.locale = locale;
124
+
125
+ return locale;
126
+ } catch (error) {
127
+ this.notifications.serverError(error);
128
+ }
129
+ }
130
+
131
+ async loadOrganizations() {
132
+ try {
133
+ const organizations = await this.fetch.get('auth/organizations', {}, { normalizeToEmberData: true, normalizeModelType: 'company' });
134
+ this.setOption('organizations', organizations);
135
+ this.organizations = organizations;
136
+
137
+ return organizations;
138
+ } catch (error) {
139
+ this.notifications.serverError(error);
140
+ }
141
+ }
142
+
143
+ async loadWhois() {
144
+ this.fetch.shouldResetCache();
145
+
146
+ try {
147
+ const whois = await this.fetch.cachedGet(
148
+ 'lookup/whois',
149
+ {},
150
+ {
151
+ expirationInterval: 60,
152
+ expirationIntervalUnit: 'minutes',
153
+ }
154
+ );
155
+ this.setOption('whois', whois);
156
+ this.whoisData = whois;
157
+
158
+ return whois;
159
+ } catch (error) {
160
+ this.notifications.serverError(error);
161
+ }
162
+ }
163
+
164
+ getCompany() {
165
+ this.company = this.store.peekRecord('company', this.user.company_uuid);
166
+ return this.company;
199
167
  }
200
168
 
201
- /**
202
- * Gets all user permissions.
203
- *
204
- * @param {UserModel} user
205
- * @return {Array}
206
- * @memberof CurrentUserService
207
- */
208
169
  getUserPermissions(user) {
209
170
  const permissions = [];
210
171
 
@@ -242,25 +203,11 @@ export default class CurrentUserService extends Service.extend(Evented) {
242
203
  return permissions;
243
204
  }
244
205
 
245
- /**
246
- * Alias to get a user's whois property
247
- *
248
- * @param {String} key
249
- * @return {Mixed}
250
- * @memberof CurrentUserService
251
- */
252
- @action whois(key) {
206
+ whois(key) {
253
207
  return this.getWhoisProperty(key);
254
208
  }
255
209
 
256
- /**
257
- * Sets a user's option in local storage
258
- *
259
- * @param {String} key
260
- * @param {Mixed} value
261
- * @return {CurrentUserService}
262
- */
263
- @action setOption(key, value) {
210
+ setOption(key, value) {
264
211
  key = `${this.optionsPrefix}${dasherize(key)}`;
265
212
 
266
213
  this.options.set(key, value);
@@ -268,26 +215,14 @@ export default class CurrentUserService extends Service.extend(Evented) {
268
215
  return this;
269
216
  }
270
217
 
271
- /**
272
- * Retrieves a user option from local storage
273
- *
274
- * @param {String} key
275
- * @return {Mixed}
276
- */
277
- @action getOption(key, defaultValue = null) {
218
+ getOption(key, defaultValue = null) {
278
219
  key = `${this.optionsPrefix}${dasherize(key)}`;
279
220
 
280
221
  const value = this.options.get(key);
281
222
  return value !== undefined ? value : defaultValue;
282
223
  }
283
224
 
284
- /**
285
- * Retrieves a user option from local storage
286
- *
287
- * @param {String} key
288
- * @return {Mixed}
289
- */
290
- @action getWhoisProperty(prop) {
225
+ getWhoisProperty(prop) {
291
226
  const whois = this.getOption('whois');
292
227
 
293
228
  if (!whois || typeof whois !== 'object') {
@@ -297,23 +232,11 @@ export default class CurrentUserService extends Service.extend(Evented) {
297
232
  return get(whois, prop);
298
233
  }
299
234
 
300
- /**
301
- * Checks if an option exists in users local storage
302
- *
303
- * @param {String} key
304
- * @return {Boolean}
305
- */
306
- @action hasOption(key) {
235
+ hasOption(key) {
307
236
  return this.getOption(key) !== undefined;
308
237
  }
309
238
 
310
- /**
311
- * Checks if an option exists in users local storage
312
- *
313
- * @param {String} key
314
- * @return {Boolean}
315
- */
316
- @action filledOption(key) {
239
+ filledOption(key) {
317
240
  return !isBlank(this.getOption(key));
318
241
  }
319
242
  }
@@ -2,29 +2,14 @@ import SimpleAuthSessionService from 'ember-simple-auth/services/session';
2
2
  import { tracked } from '@glimmer/tracking';
3
3
  import { inject as service } from '@ember/service';
4
4
  import { later } from '@ember/runloop';
5
+ import { debug } from '@ember/debug';
5
6
  import getWithDefault from '../utils/get-with-default';
6
7
 
7
8
  export default class SessionService extends SimpleAuthSessionService {
8
- /**
9
- * Inject the router service
10
- *
11
- * @var {Service}
12
- */
13
9
  @service router;
14
-
15
- /**
16
- * Inject the current user service
17
- *
18
- * @var {Service}
19
- */
20
10
  @service currentUser;
21
-
22
- /**
23
- * Inject the current user service
24
- *
25
- * @var {Service}
26
- */
27
11
  @service fetch;
12
+ @service notifications;
28
13
 
29
14
  /**
30
15
  * Set where to transition to
@@ -69,23 +54,26 @@ export default class SessionService extends SimpleAuthSessionService {
69
54
  }
70
55
 
71
56
  const loaderNode = this.showLoader('Starting session...');
72
-
57
+ const removeLoaderNode = () => {
58
+ later(
59
+ this,
60
+ () => {
61
+ // remove node from body
62
+ document.body.removeChild(loaderNode);
63
+ this.isLoaderNodeOpen = false;
64
+ },
65
+ 600 * 3
66
+ );
67
+ };
73
68
  this.isLoaderNodeOpen = true;
74
69
 
75
- this.router
76
- .transitionTo(this.redirectTo)
77
- .finally(() => {
78
- later(
79
- this,
80
- () => {
81
- // remove node from body
82
- document.body.removeChild(loaderNode);
83
- this.isLoaderNodeOpen = false;
84
- },
85
- 600 * 6
86
- );
87
- })
88
- .catch((error) => console.log(error));
70
+ try {
71
+ await this.router.transitionTo(this.redirectTo);
72
+ } catch (error) {
73
+ debug(`Session's handleAuthentication() failed to transition: ${error.message}`);
74
+ }
75
+
76
+ removeLoaderNode();
89
77
  }
90
78
 
91
79
  /**
@@ -113,31 +101,29 @@ export default class SessionService extends SimpleAuthSessionService {
113
101
  * @param {Transition} transition
114
102
  * @void
115
103
  */
116
- promiseCurrentUser(transition = null) {
104
+ async promiseCurrentUser(transition = null) {
117
105
  const invalidateWithLoader = this.invalidateWithLoader.bind(this);
118
106
 
119
- return new Promise((resolve, reject) => {
120
- return this.currentUser
121
- .promiseUser()
122
- .then((user) => {
123
- if (!user) {
124
- if (transition !== null) {
125
- transition.abort();
126
- }
127
-
128
- reject(invalidateWithLoader('Session authentication failed...'));
129
- }
130
-
131
- resolve(user);
132
- })
133
- .catch((error) => {
134
- if (transition !== null) {
135
- transition.abort();
136
- }
137
-
138
- reject(invalidateWithLoader(error.message ?? `Session authentication failed...`));
139
- });
140
- });
107
+ try {
108
+ const user = await this.currentUser.promiseUser();
109
+ if (!user) {
110
+ if (transition) {
111
+ transition.abort();
112
+ }
113
+
114
+ await invalidateWithLoader('Session authentication failed...');
115
+ throw new Error('Session authentication failed...');
116
+ }
117
+
118
+ return user;
119
+ } catch (error) {
120
+ if (transition) {
121
+ transition.abort();
122
+ }
123
+
124
+ await invalidateWithLoader(error.message ?? 'Session authentication failed...');
125
+ throw error;
126
+ }
141
127
  }
142
128
 
143
129
  /**
@@ -175,8 +161,7 @@ export default class SessionService extends SimpleAuthSessionService {
175
161
  }
176
162
 
177
163
  const loaderNode = this.showLoader(loadingMessage);
178
-
179
- this.isLoaderNodeOpen = false;
164
+ this.isLoaderNodeOpen = true;
180
165
 
181
166
  return this.session.invalidate().then(() => {
182
167
  later(
@@ -15,7 +15,7 @@ export default class ThemeService extends Service {
15
15
  */
16
16
  get router() {
17
17
  const owner = getOwner(this);
18
- const router = owner.lookup('service:router');
18
+ const router = owner.lookup('router:main');
19
19
 
20
20
  return router;
21
21
  }
@@ -213,7 +213,7 @@ export default class ThemeService extends Service {
213
213
  * @void
214
214
  */
215
215
  setEnvironment() {
216
- const isSandbox = this.currentUser.getOption('sandbox') || false;
216
+ const isSandbox = this.currentUser.getOption('sandbox', false);
217
217
 
218
218
  if (isSandbox) {
219
219
  document.body.classList.add('sandbox-console');