2019-08-31 20:51:14 -07:00
|
|
|
import Route from '@ember/routing/route';
|
|
|
|
import { run } from '@ember/runloop';
|
|
|
|
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
|
2020-08-26 15:44:50 -07:00
|
|
|
import { feedback } from 'datahub-web/constants';
|
|
|
|
import Configurator, { getConfig } from 'datahub-web/services/configurator';
|
2019-08-31 20:51:14 -07:00
|
|
|
import { inject as service } from '@ember/service';
|
2020-08-26 15:44:50 -07:00
|
|
|
import { UnWrapPromise } from '@datahub/utils/types/async';
|
2019-08-31 20:51:14 -07:00
|
|
|
import CurrentUser from '@datahub/shared/services/current-user';
|
2020-08-26 15:44:50 -07:00
|
|
|
import BannerService from 'datahub-web/services/banners';
|
2019-08-31 20:51:14 -07:00
|
|
|
import Controller from '@ember/controller';
|
2020-08-26 15:44:50 -07:00
|
|
|
import UnifiedTracking from '@datahub/shared/services/unified-tracking';
|
|
|
|
import DataModelsService from '@datahub/data-models/services/data-models';
|
2019-09-04 21:46:02 -07:00
|
|
|
import { IAppConfig } from '@datahub/shared/types/configurator/configurator';
|
2020-08-26 15:44:50 -07:00
|
|
|
import { NotificationEvent } from '@datahub/utils/constants/notifications';
|
|
|
|
import { IMailHeaderRecord } from '@datahub/utils/helpers/email';
|
|
|
|
import AvatarService from '@datahub/shared/services/avatar';
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Quick alias of the type of the return of the model hook
|
|
|
|
*/
|
|
|
|
type Model = UnWrapPromise<ReturnType<ApplicationRoute['model']>>;
|
|
|
|
|
2020-08-26 15:44:50 -07:00
|
|
|
const { subject, title } = feedback;
|
2019-08-31 20:51:14 -07:00
|
|
|
const { scheduleOnce } = run;
|
|
|
|
|
|
|
|
interface IApplicationRouteModel {
|
2020-08-26 15:44:50 -07:00
|
|
|
// Email attributes a user to contact support to provide feedback
|
|
|
|
feedbackMail: IMailHeaderRecord & { title: string };
|
|
|
|
// Configuration for additional help links the user can access
|
2019-08-31 20:51:14 -07:00
|
|
|
helpResources: Array<{ label: string; link: string }>;
|
2020-08-26 15:44:50 -07:00
|
|
|
// Flag for showing whether or not we are in a staging environment
|
2019-08-31 20:51:14 -07:00
|
|
|
showStagingBanner: boolean;
|
2020-08-26 15:44:50 -07:00
|
|
|
// Flag for warning a user that they are in a testing environment with access to production data
|
2019-08-31 20:51:14 -07:00
|
|
|
showLiveDataWarning: boolean;
|
2020-08-26 15:44:50 -07:00
|
|
|
// Flag for showing a banner that the app is undergoing some kind of maintenance
|
2019-08-31 20:51:14 -07:00
|
|
|
showChangeManagement: boolean;
|
2020-08-26 15:44:50 -07:00
|
|
|
// Configurations for if we have a custom banner to display
|
|
|
|
customBanner: IAppConfig['customBanner'];
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
export default class ApplicationRoute extends Route.extend(ApplicationRouteMixin) {
|
2019-09-04 21:46:02 -07:00
|
|
|
/**
|
|
|
|
* Injected service to manage the operations related to currently logged in user
|
|
|
|
* On app load, avatar creation and loading user attributes are handled via this service
|
|
|
|
*/
|
2019-08-31 20:51:14 -07:00
|
|
|
@service('current-user')
|
|
|
|
sessionUser: CurrentUser;
|
|
|
|
|
|
|
|
/**
|
2019-09-04 21:46:02 -07:00
|
|
|
* References the application tracking service which is used for analytics activation, setup, and management
|
2019-08-31 20:51:14 -07:00
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
@service('unified-tracking')
|
|
|
|
trackingService: UnifiedTracking;
|
2019-08-31 20:51:14 -07:00
|
|
|
|
2020-08-26 15:44:50 -07:00
|
|
|
/**
|
|
|
|
* Injected service to access the data models related to our various entities.
|
|
|
|
*/
|
|
|
|
@service('data-models')
|
|
|
|
dataModels: DataModelsService;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Injected service to load the avatars with necessary config information
|
|
|
|
*/
|
|
|
|
@service
|
|
|
|
avatar: AvatarService;
|
|
|
|
|
2019-08-31 20:51:14 -07:00
|
|
|
/**
|
|
|
|
* Banner alert service
|
|
|
|
*/
|
|
|
|
@service
|
|
|
|
banners: BannerService;
|
|
|
|
|
2019-09-04 21:46:02 -07:00
|
|
|
@service
|
|
|
|
configurator: Configurator;
|
|
|
|
|
2019-08-31 20:51:14 -07:00
|
|
|
/**
|
|
|
|
* Attempt to load the current user and application configuration options
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
2020-08-26 15:44:50 -07:00
|
|
|
beforeModel(...args: Array<unknown>): Promise<[void, IAppConfig]> {
|
|
|
|
super.beforeModel.apply(this, args);
|
2019-08-31 20:51:14 -07:00
|
|
|
return Promise.all([this._loadCurrentUser(), this._loadConfig()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an object containing properties for the application route
|
|
|
|
* @return {{feedbackMail: {href: string, target: string, title: string}}}
|
|
|
|
* @override
|
|
|
|
*/
|
|
|
|
model(): IApplicationRouteModel {
|
2020-08-26 15:44:50 -07:00
|
|
|
const [
|
|
|
|
showStagingBanner,
|
|
|
|
showLiveDataWarning,
|
|
|
|
showChangeManagement,
|
|
|
|
avatarEntityProps,
|
|
|
|
wikiLinks,
|
|
|
|
customBanner,
|
|
|
|
applicationSupportEmail
|
|
|
|
] = [
|
2019-08-31 20:51:14 -07:00
|
|
|
getConfig('isStagingBanner', { useDefault: true, default: false }),
|
|
|
|
getConfig('isLiveDataWarning', { useDefault: true, default: false }),
|
|
|
|
getConfig('showChangeManagement', { useDefault: true, default: false }),
|
2019-09-04 21:46:02 -07:00
|
|
|
getConfig('userEntityProps'),
|
2020-08-26 15:44:50 -07:00
|
|
|
getConfig('wikiLinks'),
|
|
|
|
getConfig('customBanner'),
|
|
|
|
getConfig('applicationSupportEmail', { useDefault: true, default: '' })
|
2019-08-31 20:51:14 -07:00
|
|
|
];
|
2020-08-26 15:44:50 -07:00
|
|
|
|
|
|
|
const { dataModels: dataModelsService, avatar: avatarService } = this;
|
|
|
|
const PersonEntityClass = dataModelsService.getModel('people');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* properties for the navigation link to allow a user to provide feedback
|
|
|
|
*/
|
|
|
|
const feedbackMail: IMailHeaderRecord & { title: string } = {
|
|
|
|
title,
|
|
|
|
subject,
|
|
|
|
to: applicationSupportEmail
|
|
|
|
};
|
|
|
|
|
|
|
|
// These properties are saved on the person entity class, but are gotten through a config so
|
|
|
|
// they need to be loaded here to be used in the future.
|
|
|
|
// Note: This is now deprecated in favor of using the Avatar class and will be removed as we
|
|
|
|
// finish implementing avatars
|
|
|
|
PersonEntityClass.aviUrlPrimary = avatarEntityProps.aviUrlPrimary;
|
|
|
|
PersonEntityClass.aviUrlFallback = avatarEntityProps.aviUrlFallback;
|
|
|
|
|
|
|
|
avatarService.initWithConfigs(avatarEntityProps);
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
return {
|
2020-08-26 15:44:50 -07:00
|
|
|
feedbackMail,
|
2019-08-31 20:51:14 -07:00
|
|
|
showStagingBanner,
|
|
|
|
showLiveDataWarning,
|
|
|
|
showChangeManagement,
|
2020-08-26 15:44:50 -07:00
|
|
|
customBanner,
|
2019-09-04 21:46:02 -07:00
|
|
|
helpResources: [{ link: wikiLinks['appHelp'], label: 'DataHub Wiki' }]
|
2019-08-31 20:51:14 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform post model operations
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
2020-08-26 15:44:50 -07:00
|
|
|
afterModel(...args: Array<unknown>): Promise<[void, false | void]> {
|
|
|
|
super.afterModel.apply(this, args);
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
return Promise.all([this._setupMetricsTrackers(), this._trackCurrentUser()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Augments sessionAuthenticated.
|
|
|
|
* @override ApplicationRouteMixin.sessionAuthenticated
|
|
|
|
*/
|
2020-08-26 15:44:50 -07:00
|
|
|
async sessionAuthenticated(...args: Array<unknown>): Promise<void> {
|
2019-08-31 20:51:14 -07:00
|
|
|
// @ts-ignore waiting for this be solved: https://github.com/simplabs/ember-simple-auth/issues/1619
|
2020-08-26 15:44:50 -07:00
|
|
|
super.sessionAuthenticated.apply(this, args);
|
2019-08-31 20:51:14 -07:00
|
|
|
await this._loadCurrentUser();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal method to invoke the currentUser service's load method
|
|
|
|
* If an exception occurs during the load for the current user,
|
|
|
|
* invalidate the session.
|
|
|
|
* @private
|
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
private async _loadCurrentUser(): Promise<void> {
|
2019-08-31 20:51:14 -07:00
|
|
|
const { sessionUser } = this;
|
2019-09-04 21:46:02 -07:00
|
|
|
|
|
|
|
try {
|
|
|
|
await sessionUser.load();
|
|
|
|
} catch {
|
|
|
|
sessionUser.invalidateSession();
|
|
|
|
}
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads the application configuration object
|
|
|
|
* @return {Promise.<any>|void}
|
|
|
|
* @private
|
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
private _loadConfig(): Promise<IAppConfig> {
|
|
|
|
return this.configurator.load();
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-09-04 21:46:02 -07:00
|
|
|
* Delegates to the tracking service methods to activate tracking adapters
|
2019-08-31 20:51:14 -07:00
|
|
|
* @private
|
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
private async _setupMetricsTrackers(): Promise<void> {
|
|
|
|
const tracking = await getConfig('tracking');
|
|
|
|
this.trackingService.setupTrackers(tracking);
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tracks the currently logged in user
|
|
|
|
* @return {Promise.<isEnabled|((feature:string)=>boolean)|*>}
|
|
|
|
* @private
|
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
private async _trackCurrentUser(): Promise<void> {
|
|
|
|
const tracking = await getConfig('tracking');
|
|
|
|
this.trackingService.setCurrentUser(tracking);
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* At a more granular level, initializing the banner before the render loop of the entire page ends will results in the
|
|
|
|
* render loop of the application breaking the css transition animation for our initial banners. This hook is being used
|
|
|
|
* to schedule banners only after initial render has taken place in order to allow users see the banner animation
|
|
|
|
* on entry
|
|
|
|
*/
|
2020-08-26 15:44:50 -07:00
|
|
|
renderTemplate(controller: Controller, model: Model): void {
|
|
|
|
super.renderTemplate.apply(this, [controller, model]);
|
|
|
|
const { showStagingBanner, showLiveDataWarning, showChangeManagement, customBanner } = model;
|
2019-08-31 20:51:14 -07:00
|
|
|
const { banners } = this;
|
2020-08-26 15:44:50 -07:00
|
|
|
scheduleOnce('afterRender', this, (): void => {
|
|
|
|
banners.appInitialBanners([showStagingBanner, showLiveDataWarning, showChangeManagement]);
|
|
|
|
if (customBanner && customBanner.showCustomBanner) {
|
|
|
|
const { content, type, icon, link } = customBanner;
|
|
|
|
banners.addCustomBanner(content, type as NotificationEvent, icon, link);
|
|
|
|
}
|
|
|
|
});
|
2019-08-31 20:51:14 -07:00
|
|
|
}
|
|
|
|
}
|