moved Angular routes to separate module; load Webpack bundle before other main scripts
This commit is contained in:
parent
8dc9cf21d7
commit
615e233671
14 changed files with 186 additions and 167 deletions
|
@ -166,6 +166,9 @@ def render_page_template(name, route_data=None, **kwargs):
|
||||||
file_lists = [library_styles, main_styles, library_scripts, main_scripts]
|
file_lists = [library_styles, main_styles, library_scripts, main_scripts]
|
||||||
for file_list in file_lists:
|
for file_list in file_lists:
|
||||||
file_list.sort()
|
file_list.sort()
|
||||||
|
# Ensure Webpack bundle is first script on page
|
||||||
|
if 'js/build/bundle.js' in main_scripts: main_scripts.remove('js/build/bundle.js')
|
||||||
|
main_scripts = ['js/build/bundle.js'] + main_scripts
|
||||||
else:
|
else:
|
||||||
library_styles = []
|
library_styles = []
|
||||||
main_styles = ['dist/quay-frontend.css']
|
main_styles = ['dist/quay-frontend.css']
|
||||||
|
|
|
@ -39,27 +39,9 @@ module.exports = function(config) {
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
'static/lib/ngReact/react.ngReact.min.js': ['webpack'],
|
'static/lib/ngReact/react.ngReact.min.js': ['webpack'],
|
||||||
'static/lib/angular-moment.min.js': ['webpack'],
|
'static/lib/angular-moment.min.js': ['webpack'],
|
||||||
// 'static/js/**/*.ts*': ['karma-typescript'],
|
|
||||||
'static/js/**/*.ts*': ['webpack'],
|
'static/js/**/*.ts*': ['webpack'],
|
||||||
},
|
},
|
||||||
webpack: {
|
webpack: webpackConfig,
|
||||||
resolve: webpackConfig.resolve,
|
|
||||||
externals: webpackConfig.externals,
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.tsx?$/,
|
|
||||||
loader: "ts-loader",
|
|
||||||
exclude: /node_modules/
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.scss$/,
|
|
||||||
loaders: ['style', 'css', 'sass'],
|
|
||||||
exclude: /node_modules/
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
webpackMiddleware: {
|
webpackMiddleware: {
|
||||||
stats: 'errors-only'
|
stats: 'errors-only'
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
|
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
|
||||||
"test:node": "./node_modules/.bin/jasmine-ts './static/js/**/*.spec.ts'",
|
"test:node": "JASMINE_CONFIG_PATH=static/test/jasmine.json ./node_modules/.bin/jasmine-ts './static/js/**/*.spec.ts'",
|
||||||
"build": "./node_modules/.bin/webpack --progress -p -v",
|
"build": "./node_modules/.bin/webpack --progress -p -v",
|
||||||
"watch": "./node_modules/.bin/webpack --watch"
|
"watch": "./node_modules/.bin/webpack --watch"
|
||||||
},
|
},
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/angular": "1.5.16",
|
"@types/angular": "1.5.16",
|
||||||
"@types/angular-mocks": "^1.5.8",
|
"@types/angular-mocks": "^1.5.8",
|
||||||
|
"@types/angular-route": "^1.3.3",
|
||||||
"@types/jasmine": "^2.5.41",
|
"@types/jasmine": "^2.5.41",
|
||||||
"@types/react": "0.14.39",
|
"@types/react": "0.14.39",
|
||||||
"@types/react-dom": "0.14.17",
|
"@types/react-dom": "0.14.17",
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Regex patterns to for validating account names.
|
||||||
|
*/
|
||||||
export default {
|
export default {
|
||||||
TEAM_PATTERN: '^[a-z][a-z0-9]+$',
|
TEAM_PATTERN: '^[a-z][a-z0-9]+$',
|
||||||
ROBOT_PATTERN: '^[a-z][a-z0-9_]{1,254}$',
|
ROBOT_PATTERN: '^[a-z][a-z0-9_]{1,254}$',
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
|
/**
|
||||||
|
* Manages the creation and retrieval of pages (route + controller)
|
||||||
|
* TODO: Convert to class/Angular service
|
||||||
|
*/
|
||||||
export default {
|
export default {
|
||||||
'_pages': {},
|
'_pages': {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a page.
|
||||||
|
* @param pageName The name of the page.
|
||||||
|
* @param templateName The file name of the template.
|
||||||
|
* @param opt_controller Controller for the page.
|
||||||
|
* @param opt_flags Additional flags passed to route provider.
|
||||||
|
* @param opt_profiles Available profiles.
|
||||||
|
*/
|
||||||
'create': function (pageName, templateName, opt_controller, opt_flags, opt_profiles) {
|
'create': function (pageName, templateName, opt_controller, opt_flags, opt_profiles) {
|
||||||
var profiles = opt_profiles || ['old-layout', 'layout'];
|
var profiles = opt_profiles || ['old-layout', 'layout'];
|
||||||
for (var i = 0; i < profiles.length; ++i) {
|
for (var i = 0; i < profiles.length; ++i) {
|
||||||
|
@ -13,6 +25,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a registered page.
|
||||||
|
* @param pageName The name of the page.
|
||||||
|
* @param profiles Available profiles to search.
|
||||||
|
*/
|
||||||
'get': function (pageName, profiles) {
|
'get': function (pageName, profiles) {
|
||||||
for (var i = 0; i < profiles.length; ++i) {
|
for (var i = 0; i < profiles.length; ++i) {
|
||||||
var current = profiles[i];
|
var current = profiles[i];
|
||||||
|
|
|
@ -12,8 +12,8 @@ angular.module('quay').directive('createRobotDialog', function () {
|
||||||
'info': '=info',
|
'info': '=info',
|
||||||
'robotCreated': '&robotCreated'
|
'robotCreated': '&robotCreated'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, ApiService, UserService, namePatterns) {
|
controller: function($scope, $element, ApiService, UserService, NAME_PATTERNS) {
|
||||||
$scope.ROBOT_PATTERN = namePatterns.ROBOT_PATTERN;
|
$scope.ROBOT_PATTERN = NAME_PATTERNS.ROBOT_PATTERN;
|
||||||
|
|
||||||
$scope.robotFinished = function(robot) {
|
$scope.robotFinished = function(robot) {
|
||||||
$scope.robotCreated({'robot': robot});
|
$scope.robotCreated({'robot': robot});
|
||||||
|
|
|
@ -12,8 +12,8 @@ angular.module('quay').directive('createTeamDialog', function () {
|
||||||
'info': '=info',
|
'info': '=info',
|
||||||
'teamCreated': '&teamCreated'
|
'teamCreated': '&teamCreated'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, ApiService, UserService, namePatterns) {
|
controller: function($scope, $element, ApiService, UserService, NAME_PATTERNS) {
|
||||||
$scope.TEAM_PATTERN = namePatterns.TEAM_PATTERN;
|
$scope.TEAM_PATTERN = NAME_PATTERNS.TEAM_PATTERN;
|
||||||
|
|
||||||
$scope.teamFinished = function(team) {
|
$scope.teamFinished = function(team) {
|
||||||
$scope.teamCreated({'team': team});
|
$scope.teamCreated({'team': team});
|
||||||
|
|
|
@ -15,9 +15,9 @@ angular.module('quay').directive('namespaceInput', function () {
|
||||||
|
|
||||||
'namespaceTitle': '@namespaceTitle',
|
'namespaceTitle': '@namespaceTitle',
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, namePatterns) {
|
controller: function($scope, $element, NAME_PATTERNS) {
|
||||||
$scope.USERNAME_PATTERN = namePatterns.USERNAME_PATTERN;
|
$scope.USERNAME_PATTERN = NAME_PATTERNS.USERNAME_PATTERN;
|
||||||
$scope.usernamePattern = new RegExp(namePatterns.USERNAME_PATTERN);
|
$scope.usernamePattern = new RegExp(NAME_PATTERNS.USERNAME_PATTERN);
|
||||||
|
|
||||||
$scope.$watch('binding', function(binding) {
|
$scope.$watch('binding', function(binding) {
|
||||||
if (!binding) {
|
if (!binding) {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as Raven from 'raven-js';
|
import * as Raven from 'raven-js';
|
||||||
import { RouteBuilder } from './route-builder/route-builder.service';
|
|
||||||
|
|
||||||
|
|
||||||
quayConfig.$inject = [
|
quayConfig.$inject = [
|
||||||
|
@ -7,10 +6,6 @@ quayConfig.$inject = [
|
||||||
'cfpLoadingBarProvider',
|
'cfpLoadingBarProvider',
|
||||||
'$tooltipProvider',
|
'$tooltipProvider',
|
||||||
'$compileProvider',
|
'$compileProvider',
|
||||||
'$routeProvider',
|
|
||||||
'$locationProvider',
|
|
||||||
'pages',
|
|
||||||
'RouteBuilderProvider',
|
|
||||||
'RestangularProvider',
|
'RestangularProvider',
|
||||||
'$analyticsProvider',
|
'$analyticsProvider',
|
||||||
];
|
];
|
||||||
|
@ -20,17 +15,13 @@ export function quayConfig(
|
||||||
cfpLoadingBarProvider,
|
cfpLoadingBarProvider,
|
||||||
$tooltipProvider,
|
$tooltipProvider,
|
||||||
$compileProvider,
|
$compileProvider,
|
||||||
$routeProvider,
|
|
||||||
$locationProvider,
|
|
||||||
pages,
|
|
||||||
RouteBuilderProvider,
|
|
||||||
RestangularProvider,
|
RestangularProvider,
|
||||||
$analyticsProvider) {
|
$analyticsProvider) {
|
||||||
cfpLoadingBarProvider.includeSpinner = false;
|
cfpLoadingBarProvider.includeSpinner = false;
|
||||||
|
|
||||||
// decorate the tooltip getter
|
// decorate the tooltip getter
|
||||||
var tooltipFactory = $tooltipProvider.$get[$tooltipProvider.$get.length - 1];
|
var tooltipFactory = $tooltipProvider.$get[$tooltipProvider.$get.length - 1];
|
||||||
$tooltipProvider.$get[$tooltipProvider.$get.length - 1] = function($window) {
|
$tooltipProvider.$get[$tooltipProvider.$get.length - 1] = function($window: ng.IWindowService) {
|
||||||
if ('ontouchstart' in $window) {
|
if ('ontouchstart' in $window) {
|
||||||
var existing = tooltipFactory.apply(this, arguments);
|
var existing = tooltipFactory.apply(this, arguments);
|
||||||
return function(element) {
|
return function(element) {
|
||||||
|
@ -51,132 +42,6 @@ export function quayConfig(
|
||||||
$compileProvider.debugInfoEnabled(false);
|
$compileProvider.debugInfoEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$locationProvider.html5Mode(true);
|
|
||||||
|
|
||||||
// WARNING WARNING WARNING
|
|
||||||
// If you add a route here, you must add a corresponding route in thr endpoints/web.py
|
|
||||||
// index rule to make sure that deep links directly deep into the app continue to work.
|
|
||||||
// WARNING WARNING WARNING
|
|
||||||
|
|
||||||
var layoutProfile: string = 'layout';
|
|
||||||
|
|
||||||
var routeBuilder: RouteBuilder = new RouteBuilderProvider.$get()($routeProvider, pages, [
|
|
||||||
// Start with the old pages (if we asked for it).
|
|
||||||
{id: 'old-layout', templatePath: '/static/partials/'},
|
|
||||||
|
|
||||||
// Fallback back combined new/existing pages.
|
|
||||||
{id: 'layout', templatePath: '/static/partials/'}
|
|
||||||
], layoutProfile);
|
|
||||||
|
|
||||||
if ((<any>window).__features.SUPER_USERS) {
|
|
||||||
// QE Management
|
|
||||||
routeBuilder.route('/superuser/', 'superuser')
|
|
||||||
|
|
||||||
// QE Setup
|
|
||||||
.route('/setup/', 'setup');
|
|
||||||
}
|
|
||||||
|
|
||||||
routeBuilder
|
|
||||||
// Repository View
|
|
||||||
.route('/repository/:namespace/:name', 'repo-view')
|
|
||||||
.route('/repository/:namespace/:name/tag/:tag', 'repo-view')
|
|
||||||
|
|
||||||
// Image View
|
|
||||||
.route('/repository/:namespace/:name/image/:image', 'image-view')
|
|
||||||
|
|
||||||
// Repo Build View
|
|
||||||
.route('/repository/:namespace/:name/build/:buildid', 'build-view')
|
|
||||||
|
|
||||||
// Create repository notification
|
|
||||||
.route('/repository/:namespace/:name/create-notification', 'create-repository-notification')
|
|
||||||
|
|
||||||
// Repo List
|
|
||||||
.route('/repository/', 'repo-list')
|
|
||||||
|
|
||||||
// Organizations
|
|
||||||
.route('/organizations/', 'organizations')
|
|
||||||
|
|
||||||
// New Organization
|
|
||||||
.route('/organizations/new/', 'new-organization')
|
|
||||||
|
|
||||||
// View Organization
|
|
||||||
.route('/organization/:orgname', 'org-view')
|
|
||||||
|
|
||||||
// View Organization Team
|
|
||||||
.route('/organization/:orgname/teams/:teamname', 'team-view')
|
|
||||||
|
|
||||||
// Organization View Application
|
|
||||||
.route('/organization/:orgname/application/:clientid', 'manage-application')
|
|
||||||
|
|
||||||
// View Organization Billing
|
|
||||||
.route('/organization/:orgname/billing', 'billing')
|
|
||||||
|
|
||||||
// View Organization Billing Invoices
|
|
||||||
.route('/organization/:orgname/billing/invoices', 'invoices')
|
|
||||||
|
|
||||||
// View User
|
|
||||||
.route('/user/:username', 'user-view')
|
|
||||||
|
|
||||||
// View User Billing
|
|
||||||
.route('/user/:username/billing', 'billing')
|
|
||||||
|
|
||||||
// View User Billing Invoices
|
|
||||||
.route('/user/:username/billing/invoices', 'invoices')
|
|
||||||
|
|
||||||
// Sign In
|
|
||||||
.route('/signin/', 'signin')
|
|
||||||
|
|
||||||
// New Repository
|
|
||||||
.route('/new/', 'new-repo')
|
|
||||||
|
|
||||||
// Plans
|
|
||||||
.route('/plans/', 'plans')
|
|
||||||
|
|
||||||
// Tutorial
|
|
||||||
.route('/tutorial/', 'tutorial')
|
|
||||||
|
|
||||||
// Contact
|
|
||||||
.route('/contact/', 'contact')
|
|
||||||
|
|
||||||
// About
|
|
||||||
.route('/about/', 'about')
|
|
||||||
|
|
||||||
// Security
|
|
||||||
.route('/security/', 'security')
|
|
||||||
|
|
||||||
// TOS
|
|
||||||
.route('/tos', 'tos')
|
|
||||||
|
|
||||||
// Privacy
|
|
||||||
.route('/privacy', 'privacy')
|
|
||||||
|
|
||||||
// Change username
|
|
||||||
.route('/updateuser', 'update-user')
|
|
||||||
|
|
||||||
// Landing Page
|
|
||||||
.route('/', 'landing')
|
|
||||||
|
|
||||||
// Tour
|
|
||||||
.route('/tour/', 'tour')
|
|
||||||
.route('/tour/features', 'tour')
|
|
||||||
.route('/tour/organizations', 'tour')
|
|
||||||
.route('/tour/enterprise', 'tour')
|
|
||||||
|
|
||||||
// Confirm Invite
|
|
||||||
.route('/confirminvite', 'confirm-invite')
|
|
||||||
|
|
||||||
// Enterprise marketing page
|
|
||||||
.route('/enterprise', 'enterprise')
|
|
||||||
|
|
||||||
// Public Repo Experiments
|
|
||||||
.route('/__exp/publicRepo', 'public-repo-exp')
|
|
||||||
|
|
||||||
// 404/403
|
|
||||||
.route('/:catchall', 'error-view')
|
|
||||||
.route('/:catch/:all', 'error-view')
|
|
||||||
.route('/:catch/:all/:things', 'error-view')
|
|
||||||
.route('/:catch/:all/:things/:here', 'error-view');
|
|
||||||
|
|
||||||
// Configure compile provider to add additional URL prefixes to the sanitization list. We use
|
// Configure compile provider to add additional URL prefixes to the sanitization list. We use
|
||||||
// these on the Contact page.
|
// these on the Contact page.
|
||||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|irc):/);
|
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|irc):/);
|
||||||
|
|
|
@ -4,7 +4,8 @@ import quayPages from './quay-pages.module';
|
||||||
import quayRun from './quay.run';
|
import quayRun from './quay.run';
|
||||||
import { angularViewArrayFactory } from './services/angular-view-array/angular-view-array';
|
import { angularViewArrayFactory } from './services/angular-view-array/angular-view-array';
|
||||||
import { routeBuilderFactory } from './route-builder/route-builder.service.impl';
|
import { routeBuilderFactory } from './route-builder/route-builder.service.impl';
|
||||||
import namePatterns from './constants/name-patterns.constant';
|
import NAME_PATTERNS from './constants/name-patterns.constant';
|
||||||
|
import { routeConfig } from './quay.routes';
|
||||||
|
|
||||||
|
|
||||||
var quayDependencies: string[] = [
|
var quayDependencies: string[] = [
|
||||||
|
@ -46,7 +47,8 @@ if ((<any>window).__config && (<any>window).__config.RECAPTCHA_SITE_KEY) {
|
||||||
export default angular
|
export default angular
|
||||||
.module('quay', quayDependencies)
|
.module('quay', quayDependencies)
|
||||||
.config(quayConfig)
|
.config(quayConfig)
|
||||||
.constant('namePatterns', namePatterns)
|
.config(routeConfig)
|
||||||
|
.constant('NAME_PATTERNS', NAME_PATTERNS)
|
||||||
.factory('RouteBuilder', routeBuilderFactory)
|
.factory('RouteBuilder', routeBuilderFactory)
|
||||||
.factory('AngularViewArray', angularViewArrayFactory)
|
.factory('AngularViewArray', angularViewArrayFactory)
|
||||||
.run(quayRun)
|
.run(quayRun)
|
||||||
|
|
141
static/js/quay.routes.ts
Normal file
141
static/js/quay.routes.ts
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
import { RouteBuilder } from './route-builder/route-builder.service';
|
||||||
|
import pages from './constants/pages.constant';
|
||||||
|
|
||||||
|
|
||||||
|
routeConfig.$inject = [
|
||||||
|
'pages',
|
||||||
|
'RouteBuilderProvider',
|
||||||
|
'$routeProvider',
|
||||||
|
'$locationProvider',
|
||||||
|
];
|
||||||
|
|
||||||
|
export function routeConfig(
|
||||||
|
pages: any,
|
||||||
|
RouteBuilderProvider: any,
|
||||||
|
$routeProvider: ng.route.IRouteProvider,
|
||||||
|
$locationProvider: ng.ILocationProvider) {
|
||||||
|
$locationProvider.html5Mode(true);
|
||||||
|
|
||||||
|
// WARNING WARNING WARNING
|
||||||
|
// If you add a route here, you must add a corresponding route in thr endpoints/web.py
|
||||||
|
// index rule to make sure that deep links directly deep into the app continue to work.
|
||||||
|
// WARNING WARNING WARNING
|
||||||
|
|
||||||
|
var layoutProfile: string = 'layout';
|
||||||
|
|
||||||
|
var routeBuilder: RouteBuilder = new RouteBuilderProvider.$get()($routeProvider, pages, [
|
||||||
|
// Start with the old pages (if we asked for it).
|
||||||
|
{id: 'old-layout', templatePath: '/static/partials/'},
|
||||||
|
|
||||||
|
// Fallback back combined new/existing pages.
|
||||||
|
{id: 'layout', templatePath: '/static/partials/'}
|
||||||
|
], layoutProfile);
|
||||||
|
|
||||||
|
if ((<any>window).__features.SUPER_USERS) {
|
||||||
|
// QE Management
|
||||||
|
routeBuilder.route('/superuser/', 'superuser')
|
||||||
|
// QE Setup
|
||||||
|
.route('/setup/', 'setup');
|
||||||
|
}
|
||||||
|
|
||||||
|
routeBuilder
|
||||||
|
// Repository View
|
||||||
|
.route('/repository/:namespace/:name', 'repo-view')
|
||||||
|
.route('/repository/:namespace/:name/tag/:tag', 'repo-view')
|
||||||
|
|
||||||
|
// Image View
|
||||||
|
.route('/repository/:namespace/:name/image/:image', 'image-view')
|
||||||
|
|
||||||
|
// Repo Build View
|
||||||
|
.route('/repository/:namespace/:name/build/:buildid', 'build-view')
|
||||||
|
|
||||||
|
// Create repository notification
|
||||||
|
.route('/repository/:namespace/:name/create-notification', 'create-repository-notification')
|
||||||
|
|
||||||
|
// Repo List
|
||||||
|
.route('/repository/', 'repo-list')
|
||||||
|
|
||||||
|
// Organizations
|
||||||
|
.route('/organizations/', 'organizations')
|
||||||
|
|
||||||
|
// New Organization
|
||||||
|
.route('/organizations/new/', 'new-organization')
|
||||||
|
|
||||||
|
// View Organization
|
||||||
|
.route('/organization/:orgname', 'org-view')
|
||||||
|
|
||||||
|
// View Organization Team
|
||||||
|
.route('/organization/:orgname/teams/:teamname', 'team-view')
|
||||||
|
|
||||||
|
// Organization View Application
|
||||||
|
.route('/organization/:orgname/application/:clientid', 'manage-application')
|
||||||
|
|
||||||
|
// View Organization Billing
|
||||||
|
.route('/organization/:orgname/billing', 'billing')
|
||||||
|
|
||||||
|
// View Organization Billing Invoices
|
||||||
|
.route('/organization/:orgname/billing/invoices', 'invoices')
|
||||||
|
|
||||||
|
// View User
|
||||||
|
.route('/user/:username', 'user-view')
|
||||||
|
|
||||||
|
// View User Billing
|
||||||
|
.route('/user/:username/billing', 'billing')
|
||||||
|
|
||||||
|
// View User Billing Invoices
|
||||||
|
.route('/user/:username/billing/invoices', 'invoices')
|
||||||
|
|
||||||
|
// Sign In
|
||||||
|
.route('/signin/', 'signin')
|
||||||
|
|
||||||
|
// New Repository
|
||||||
|
.route('/new/', 'new-repo')
|
||||||
|
|
||||||
|
// Plans
|
||||||
|
.route('/plans/', 'plans')
|
||||||
|
|
||||||
|
// Tutorial
|
||||||
|
.route('/tutorial/', 'tutorial')
|
||||||
|
|
||||||
|
// Contact
|
||||||
|
.route('/contact/', 'contact')
|
||||||
|
|
||||||
|
// About
|
||||||
|
.route('/about/', 'about')
|
||||||
|
|
||||||
|
// Security
|
||||||
|
.route('/security/', 'security')
|
||||||
|
|
||||||
|
// TOS
|
||||||
|
.route('/tos', 'tos')
|
||||||
|
|
||||||
|
// Privacy
|
||||||
|
.route('/privacy', 'privacy')
|
||||||
|
|
||||||
|
// Change username
|
||||||
|
.route('/updateuser', 'update-user')
|
||||||
|
|
||||||
|
// Landing Page
|
||||||
|
.route('/', 'landing')
|
||||||
|
|
||||||
|
// Tour
|
||||||
|
.route('/tour/', 'tour')
|
||||||
|
.route('/tour/features', 'tour')
|
||||||
|
.route('/tour/organizations', 'tour')
|
||||||
|
.route('/tour/enterprise', 'tour')
|
||||||
|
|
||||||
|
// Confirm Invite
|
||||||
|
.route('/confirminvite', 'confirm-invite')
|
||||||
|
|
||||||
|
// Enterprise marketing page
|
||||||
|
.route('/enterprise', 'enterprise')
|
||||||
|
|
||||||
|
// Public Repo Experiments
|
||||||
|
.route('/__exp/publicRepo', 'public-repo-exp')
|
||||||
|
|
||||||
|
// 404/403
|
||||||
|
.route('/:catchall', 'error-view')
|
||||||
|
.route('/:catch/:all', 'error-view')
|
||||||
|
.route('/:catch/:all/:things', 'error-view')
|
||||||
|
.route('/:catch/:all/:things/:here', 'error-view');
|
||||||
|
}
|
6
static/test/jasmine.json
Normal file
6
static/test/jasmine.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"spec_dir": "./static/js",
|
||||||
|
"spec_files": [
|
||||||
|
"**/*.spec.js"
|
||||||
|
]
|
||||||
|
}
|
|
@ -64,8 +64,6 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<script src="/static/js/build/bundle.js"></script>
|
|
||||||
|
|
||||||
{% for script_path, cache_buster in main_scripts %}
|
{% for script_path, cache_buster in main_scripts %}
|
||||||
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
<script src="/static/{{ script_path }}?v={{ cache_buster }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -13,6 +13,7 @@ var config = {
|
||||||
"sass": path.resolve('./static/css/directives/components/pages/')
|
"sass": path.resolve('./static/css/directives/components/pages/')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Use window.angular to maintain compatibility with non-Webpack components
|
||||||
externals: {
|
externals: {
|
||||||
"angular": "angular",
|
"angular": "angular",
|
||||||
},
|
},
|
||||||
|
|
Reference in a new issue