This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/static/js/quay.module.ts
2017-02-28 16:51:42 -05:00

244 lines
7.9 KiB
TypeScript

import * as angular from "angular";
import * as Raven from "raven-js";
import { ViewArrayImpl } from "./services/view-array/view-array.impl";
import { NAME_PATTERNS } from "./constants/name-patterns.constant";
import { INJECTED_CONFIG, INJECTED_FEATURES, INJECTED_ENDPOINTS } from "./constants/injected-values.constant";
import { RegexMatchViewComponent } from "./directives/ui/regex-match-view/regex-match-view.component";
import { NgModule } from "angular-ts-decorators";
import { QuayRoutes } from "./quay-routes.module";
import { DockerfilePathSelectComponent } from './directives/ui/dockerfile-path-select/dockerfile-path-select.component';
var quayDependencies: any[] = [
QuayRoutes,
'chieffancypants.loadingBar',
'cfp.hotkeys',
'angular-tour',
'restangular',
'angularMoment',
'mgcrea.ngStrap',
'ngCookies',
'ngSanitize',
'angular-md5',
'pasvaz.bindonce',
'ansiToHtml',
'core-ui',
'core-config-setup',
'infinite-scroll',
'react'
];
if (INJECTED_CONFIG && (INJECTED_CONFIG.MIXPANEL_KEY ||
INJECTED_CONFIG.MUNCHKIN_KEY ||
INJECTED_CONFIG.GOOGLE_ANALYTICS_KEY)) {
quayDependencies.push('angulartics');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.MIXPANEL_KEY) {
quayDependencies.push('angulartics.mixpanel');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.MUNCHKIN_KEY) {
quayDependencies.push('angulartics.marketo');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.GOOGLE_ANALYTICS_KEY) {
quayDependencies.push('angulartics.google.analytics');
}
if (INJECTED_CONFIG && INJECTED_CONFIG.RECAPTCHA_SITE_KEY) {
quayDependencies.push('vcRecaptcha');
}
/**
* Main application module.
*/
@NgModule({
imports: quayDependencies,
declarations: [
RegexMatchViewComponent,
DockerfilePathSelectComponent,
],
providers: [
ViewArrayImpl,
],
})
export class quay {
public config($provide: ng.auto.IProvideService,
$injector: ng.auto.IInjectorService,
INJECTED_CONFIG: any,
cfpLoadingBarProvider: any,
$tooltipProvider: any,
$compileProvider: ng.ICompileProvider,
RestangularProvider: any): void {
cfpLoadingBarProvider.includeSpinner = false;
// decorate the tooltip getter
var tooltipFactory: any = $tooltipProvider.$get[$tooltipProvider.$get.length - 1];
$tooltipProvider.$get[$tooltipProvider.$get.length - 1] = function($window: ng.IWindowService) {
if ('ontouchstart' in $window) {
var existing: any = tooltipFactory.apply(this, arguments);
return function(element) {
// Note: We only disable bs-tooltip's themselves. $tooltip is used for other things
// (such as the datepicker), so we need to be specific when canceling it.
if (element !== undefined && element.attr('bs-tooltip') == null) {
return existing.apply(this, arguments);
}
};
}
return tooltipFactory.apply(this, arguments);
};
if (!INJECTED_CONFIG['DEBUG']) {
$compileProvider.debugInfoEnabled(false);
}
// Configure compile provider to add additional URL prefixes to the sanitization list. We use
// these on the Contact page.
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|irc):/);
// Configure the API provider.
RestangularProvider.setBaseUrl('/api/v1/');
// Configure analytics.
if (INJECTED_CONFIG && INJECTED_CONFIG.MIXPANEL_KEY) {
let $analyticsProvider: any = $injector.get('$analyticsProvider');
$analyticsProvider.virtualPageviews(true);
}
// Configure sentry.
if (INJECTED_CONFIG && INJECTED_CONFIG.SENTRY_PUBLIC_DSN) {
$provide.decorator("$exceptionHandler", function($delegate) {
return function(ex, cause) {
$delegate(ex, cause);
Raven.captureException(ex, {extra: {cause: cause}});
};
});
}
}
public run($rootScope: QuayRunScope,
Restangular: any,
PlanService: any,
$http: ng.IHttpService,
CookieService: any,
Features: any,
$anchorScroll: ng.IAnchorScrollService,
MetaService: any,
INJECTED_CONFIG: any): void {
var defaultTitle = INJECTED_CONFIG['REGISTRY_TITLE'] || 'Quay Container Registry';
// Handle session security.
Restangular.setDefaultRequestParams(['post', 'put', 'remove', 'delete'],
{'_csrf_token': (<any>window).__token || ''});
// Handle session expiration.
Restangular.setErrorInterceptor(function(response) {
if (response !== undefined && response.status == 503) {
(<any>$('#cannotContactService')).modal({});
return false;
}
if (response !== undefined && response.status == 500) {
window.location.href = '/500';
return false;
}
if (response !== undefined && !response.data) {
return true;
}
var invalid_token = response.data['title'] == 'invalid_token' || response.data['error_type'] == 'invalid_token';
if (response !== undefined && response.status == 401 &&
invalid_token &&
response.data['session_required'] !== false) {
(<any>$('#sessionexpiredModal')).modal({});
return false;
}
return true;
});
// Check if we need to redirect based on a previously chosen plan.
var result = PlanService.handleNotedPlan();
// Check to see if we need to show a redirection page.
var redirectUrl = CookieService.get('quay.redirectAfterLoad');
CookieService.clear('quay.redirectAfterLoad');
if (!result && redirectUrl && redirectUrl.indexOf((<any>window).location.href) == 0) {
(<any>window).location = redirectUrl;
return;
}
$rootScope.$watch('description', function(description: string) {
if (!description) {
description = `Hosted private docker repositories. Includes full user management and history.
Free for public repositories.`;
}
// Note: We set the content of the description tag manually here rather than using Angular binding
// because we need the <meta> tag to have a default description that is not of the form "{{ description }}",
// we read by tools that do not properly invoke the Angular code.
$('#descriptionTag').attr('content', description);
});
// Listen for scope changes and update the title and description accordingly.
$rootScope.$watch(function() {
var title = MetaService.getTitle($rootScope.currentPage) || defaultTitle;
$rootScope.title = title;
var description = MetaService.getDescription($rootScope.currentPage) || '';
if ($rootScope.description != description) {
$rootScope.description = description;
}
});
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
$rootScope.current = current.$$route;
$rootScope.currentPage = current;
$rootScope.pageClass = '';
if (!current.$$route) { return; }
var pageClass = current.$$route.pageClass || '';
if (typeof pageClass != 'string') {
pageClass = pageClass(Features);
}
$rootScope.pageClass = pageClass;
$rootScope.newLayout = !!current.$$route.newLayout;
$rootScope.fixFooter = !!current.$$route.fixFooter;
$anchorScroll();
});
var initallyChecked: boolean = false;
(<any>window).__isLoading = function() {
if (!initallyChecked) {
initallyChecked = true;
return true;
}
return $http.pendingRequests.length > 0;
};
}
}
interface QuayRunScope extends ng.IRootScopeService {
currentPage: any;
current: any;
title: any;
description: string,
pageClass: any;
newLayout: any;
fixFooter: any;
}
// TODO: Move component registration to @NgModule and remove this.
angular
.module(quay.name)
.constant('NAME_PATTERNS', NAME_PATTERNS)
.constant('INJECTED_CONFIG', INJECTED_CONFIG)
.constant('INJECTED_FEATURES', INJECTED_FEATURES)
.constant('INJECTED_ENDPOINTS', INJECTED_ENDPOINTS);