mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 12:41:19 -03:30
Implement manual initialzation for Angular app
Manual initialization allows for some asynchronous work to finish ahead of Angular's startup. The initial motivation is to be able to guarantee translation files have been fetched before rendering content that needs translation. If a locale isn't supported or if the request to get a json file fails, the i18n service falls back to en. Signed-off-by: gconsidine <gconsidi@redhat.com>
This commit is contained in:
parent
bd5e33c2f4
commit
297904462d
@ -17,3 +17,4 @@ test
|
||||
!client/lib/models/**/*.js
|
||||
!client/lib/services/**/*.js
|
||||
!client/features/**/*.js
|
||||
!client/src/app.start.js
|
||||
|
||||
@ -20,7 +20,7 @@ module.exports = {
|
||||
node: true
|
||||
},
|
||||
globals: {
|
||||
angular: true,
|
||||
angular: true,
|
||||
d3: true,
|
||||
$: true,
|
||||
_: true,
|
||||
@ -43,6 +43,7 @@ module.exports = {
|
||||
'no-param-reassign': 'off',
|
||||
'no-plusplus': 'off',
|
||||
'no-underscore-dangle': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'object-curly-newline': 'off',
|
||||
'space-before-function-paren': ['error', 'always']
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ const base = {
|
||||
jsonlint: 'codemirror.jsonlint'
|
||||
}),
|
||||
new ExtractTextPlugin('css/[name].[chunkhash].css'),
|
||||
new CleanWebpackPlugin([STATIC_PATH, COVERAGE_PATH, LANGUAGES_PATH], {
|
||||
new CleanWebpackPlugin([STATIC_PATH, COVERAGE_PATH], {
|
||||
root: UI_PATH,
|
||||
verbose: false
|
||||
}),
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
const path = require('path');
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const base = require('./webpack.base');
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
const path = require('path');
|
||||
|
||||
const _ = require('lodash');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const STATIC_URL = '/static/';
|
||||
|
||||
const development = require('./webpack.development');
|
||||
const development = require('./webpack.base');
|
||||
|
||||
const test = {
|
||||
devtool: 'cheap-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
$basePath: STATIC_URL
|
||||
|
||||
@ -2,8 +2,8 @@ const path = require('path');
|
||||
|
||||
const _ = require('lodash');
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
||||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
||||
|
||||
const TARGET_PORT = _.get(process.env, 'npm_package_config_django_port', 8043);
|
||||
const TARGET_HOST = _.get(process.env, 'npm_package_config_django_host', 'https://localhost');
|
||||
@ -29,6 +29,7 @@ const watch = {
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackHarddiskPlugin(),
|
||||
new HardSourceWebpackPlugin({
|
||||
cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
|
||||
recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json',
|
||||
@ -41,7 +42,6 @@ const watch = {
|
||||
files: ['package.json']
|
||||
}
|
||||
}),
|
||||
new HtmlWebpackHarddiskPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin()
|
||||
],
|
||||
devServer: {
|
||||
|
||||
@ -3,6 +3,8 @@ import AddController from './add-credentials.controller';
|
||||
import EditController from './edit-credentials.controller';
|
||||
import CredentialsStrings from './credentials.strings';
|
||||
|
||||
const MODULE_NAME = 'at.features.credentials';
|
||||
|
||||
const addEditTemplate = require('~features/credentials/add-edit-credentials.view.html');
|
||||
|
||||
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType, Organization) {
|
||||
@ -51,12 +53,8 @@ CredentialsResolve.$inject = [
|
||||
'OrganizationModel'
|
||||
];
|
||||
|
||||
function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvider) {
|
||||
const stateExtender = $stateExtenderProvider.$get();
|
||||
const legacy = legacyProvider.$get();
|
||||
const strings = stringProvider.$get();
|
||||
|
||||
stateExtender.addState({
|
||||
function CredentialsRun ($stateExtender, legacy, strings) {
|
||||
$stateExtender.addState({
|
||||
name: 'credentials.add',
|
||||
route: '/add',
|
||||
ncyBreadcrumb: {
|
||||
@ -78,7 +76,7 @@ function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvid
|
||||
}
|
||||
});
|
||||
|
||||
stateExtender.addState({
|
||||
$stateExtender.addState({
|
||||
name: 'credentials.edit',
|
||||
route: '/:credential_id',
|
||||
ncyBreadcrumb: {
|
||||
@ -101,25 +99,27 @@ function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvid
|
||||
}
|
||||
});
|
||||
|
||||
stateExtender.addState(legacy.getStateConfiguration('list'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('edit-permissions'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('add-permissions'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('add-organization'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('edit-organization'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('add-credential-type'));
|
||||
stateExtender.addState(legacy.getStateConfiguration('edit-credential-type'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('list'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('edit-permissions'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('add-permissions'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('add-organization'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('edit-organization'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('add-credential-type'));
|
||||
$stateExtender.addState(legacy.getStateConfiguration('edit-credential-type'));
|
||||
}
|
||||
|
||||
CredentialsConfig.$inject = [
|
||||
'$stateExtenderProvider',
|
||||
'LegacyCredentialsServiceProvider',
|
||||
'CredentialsStringsProvider'
|
||||
CredentialsRun.$inject = [
|
||||
'$stateExtender',
|
||||
'LegacyCredentialsService',
|
||||
'CredentialsStrings'
|
||||
];
|
||||
|
||||
angular
|
||||
.module('at.features.credentials', [])
|
||||
.config(CredentialsConfig)
|
||||
.module(MODULE_NAME, [])
|
||||
.controller('AddController', AddController)
|
||||
.controller('EditController', EditController)
|
||||
.service('LegacyCredentialsService', LegacyCredentials)
|
||||
.service('CredentialsStrings', CredentialsStrings);
|
||||
.service('CredentialsStrings', CredentialsStrings)
|
||||
.run(CredentialsRun);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,5 +1,16 @@
|
||||
import '~features/credentials';
|
||||
import atLibServices from '~services';
|
||||
import atLibComponents from '~components';
|
||||
import atLibModels from '~models';
|
||||
|
||||
angular.module('at.features', [
|
||||
'at.features.credentials'
|
||||
import atFeaturesCredentials from '~features/credentials';
|
||||
|
||||
const MODULE_NAME = 'at.features';
|
||||
|
||||
angular.module(MODULE_NAME, [
|
||||
atLibServices,
|
||||
atLibComponents,
|
||||
atLibModels,
|
||||
atFeaturesCredentials
|
||||
]);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="awApp">
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="awApp">
|
||||
<html>
|
||||
<head>
|
||||
{% load staticfiles %}
|
||||
<meta charset="utf-8">
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import atLibServices from '~services';
|
||||
|
||||
import actionGroup from '~components/action/action-group.directive';
|
||||
import divider from '~components/utility/divider.directive';
|
||||
import form from '~components/form/form.directive';
|
||||
@ -28,8 +30,12 @@ import truncate from '~components/truncate/truncate.directive';
|
||||
import BaseInputController from '~components/input/base.controller';
|
||||
import ComponentsStrings from '~components/components.strings';
|
||||
|
||||
const MODULE_NAME = 'at.lib.components';
|
||||
|
||||
angular
|
||||
.module('at.lib.components', [])
|
||||
.module(MODULE_NAME, [
|
||||
atLibServices
|
||||
])
|
||||
.directive('atActionGroup', actionGroup)
|
||||
.directive('atDivider', divider)
|
||||
.directive('atForm', form)
|
||||
@ -58,3 +64,5 @@ angular
|
||||
.directive('atTruncate', truncate)
|
||||
.service('BaseInputController', BaseInputController)
|
||||
.service('ComponentsStrings', ComponentsStrings);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import atLibServices from '~services';
|
||||
|
||||
import Base from '~models/Base';
|
||||
import Config from '~models/Config';
|
||||
import Credential from '~models/Credential';
|
||||
@ -5,11 +7,17 @@ import CredentialType from '~models/CredentialType';
|
||||
import Me from '~models/Me';
|
||||
import Organization from '~models/Organization';
|
||||
|
||||
const MODULE_NAME = 'at.lib.models';
|
||||
|
||||
angular
|
||||
.module('at.lib.models', [])
|
||||
.module(MODULE_NAME, [
|
||||
atLibServices
|
||||
])
|
||||
.service('BaseModel', Base)
|
||||
.service('ConfigModel', Config)
|
||||
.service('CredentialModel', Credential)
|
||||
.service('CredentialTypeModel', CredentialType)
|
||||
.service('MeModel', Me)
|
||||
.service('OrganizationModel', Organization);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
import AppStrings from '~services/app.strings';
|
||||
import BaseStringService from '~services/base-string.service';
|
||||
import CacheService from '~services/cache.service';
|
||||
import EventService from '~services/event.service';
|
||||
import BaseStringService from '~services/base-string.service';
|
||||
import AppStrings from '~services/app.strings';
|
||||
|
||||
const MODULE_NAME = 'at.lib.services';
|
||||
|
||||
angular
|
||||
.module('at.lib.services', [])
|
||||
.module(MODULE_NAME, [
|
||||
'I18N'
|
||||
])
|
||||
.service('AppStrings', AppStrings)
|
||||
.service('BaseStringService', BaseStringService)
|
||||
.service('CacheService', CacheService)
|
||||
.service('EventService', EventService);
|
||||
|
||||
export default MODULE_NAME;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Configuration dependencies
|
||||
global.$AnsibleConfig = null;
|
||||
// Provided via Webpack DefinePlugin in webpack.config.js
|
||||
global.$ENV = {} ;
|
||||
global.$ENV = {};
|
||||
// ui-router debugging
|
||||
if ($ENV['route-debug']){
|
||||
let trace = angular.module('ui.router').trace;
|
||||
@ -14,7 +14,8 @@ if ($basePath) {
|
||||
urlPrefix = `${$basePath}`;
|
||||
}
|
||||
|
||||
// Modules
|
||||
import start from './app.start';
|
||||
|
||||
import portalMode from './portal-mode/main';
|
||||
import systemTracking from './system-tracking/main';
|
||||
import inventoriesHosts from './inventories-hosts/main';
|
||||
@ -46,71 +47,76 @@ import access from './access/main';
|
||||
import scheduler from './scheduler/main';
|
||||
import instanceGroups from './instance-groups/main';
|
||||
|
||||
import '../lib/components';
|
||||
import '../lib/models';
|
||||
import '../lib/services';
|
||||
import '../features';
|
||||
import atFeatures from '~features';
|
||||
import atLibComponents from '~components';
|
||||
import atLibModels from '~models';
|
||||
import atLibServices from '~services';
|
||||
|
||||
angular.module('awApp', [
|
||||
'I18N',
|
||||
'AngularCodeMirrorModule',
|
||||
'angular-duration-format',
|
||||
'angularMoment',
|
||||
'AngularScheduler',
|
||||
'angular-md5',
|
||||
'dndLists',
|
||||
'ncy-angular-breadcrumb',
|
||||
'ngSanitize',
|
||||
'ngCookies',
|
||||
'ngToast',
|
||||
'gettext',
|
||||
'Timezones',
|
||||
'ui.router',
|
||||
'ui.router.state.events',
|
||||
'lrInfiniteScroll',
|
||||
start.bootstrap(() => {
|
||||
angular.bootstrap(document.body, ['awApp']);
|
||||
});
|
||||
|
||||
about.name,
|
||||
access.name,
|
||||
license.name,
|
||||
RestServices.name,
|
||||
browserData.name,
|
||||
configuration.name,
|
||||
systemTracking.name,
|
||||
inventoriesHosts.name,
|
||||
inventoryScripts.name,
|
||||
credentials.name,
|
||||
credentialTypes.name,
|
||||
organizations.name,
|
||||
managementJobs.name,
|
||||
breadCrumb.name,
|
||||
home.name,
|
||||
login.name,
|
||||
activityStream.name,
|
||||
workflowResults.name,
|
||||
jobResults.name,
|
||||
jobSubmission.name,
|
||||
notifications.name,
|
||||
standardOut.name,
|
||||
Templates.name,
|
||||
portalMode.name,
|
||||
jobs.name,
|
||||
teams.name,
|
||||
users.name,
|
||||
projects.name,
|
||||
scheduler.name,
|
||||
instanceGroups.name,
|
||||
angular
|
||||
.module('awApp', [
|
||||
'I18N',
|
||||
'AngularCodeMirrorModule',
|
||||
'angular-duration-format',
|
||||
'angularMoment',
|
||||
'AngularScheduler',
|
||||
'angular-md5',
|
||||
'dndLists',
|
||||
'ncy-angular-breadcrumb',
|
||||
'ngSanitize',
|
||||
'ngCookies',
|
||||
'ngToast',
|
||||
'gettext',
|
||||
'Timezones',
|
||||
'ui.router',
|
||||
'ui.router.state.events',
|
||||
'lrInfiniteScroll',
|
||||
|
||||
'Utilities',
|
||||
'templates',
|
||||
'PromptDialog',
|
||||
'AWDirectives',
|
||||
'features',
|
||||
about.name,
|
||||
access.name,
|
||||
license.name,
|
||||
RestServices.name,
|
||||
browserData.name,
|
||||
configuration.name,
|
||||
systemTracking.name,
|
||||
inventoriesHosts.name,
|
||||
inventoryScripts.name,
|
||||
credentials.name,
|
||||
credentialTypes.name,
|
||||
organizations.name,
|
||||
managementJobs.name,
|
||||
breadCrumb.name,
|
||||
home.name,
|
||||
login.name,
|
||||
activityStream.name,
|
||||
workflowResults.name,
|
||||
jobResults.name,
|
||||
jobSubmission.name,
|
||||
notifications.name,
|
||||
standardOut.name,
|
||||
Templates.name,
|
||||
portalMode.name,
|
||||
jobs.name,
|
||||
teams.name,
|
||||
users.name,
|
||||
projects.name,
|
||||
scheduler.name,
|
||||
instanceGroups.name,
|
||||
|
||||
'at.lib.components',
|
||||
'at.lib.models',
|
||||
'at.lib.services',
|
||||
'at.features',
|
||||
])
|
||||
'Utilities',
|
||||
'templates',
|
||||
'PromptDialog',
|
||||
'AWDirectives',
|
||||
'features',
|
||||
|
||||
atFeatures,
|
||||
atLibComponents,
|
||||
atLibModels,
|
||||
atLibServices
|
||||
])
|
||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||
.constant('AngularScheduler.useTimezone', true)
|
||||
.constant('AngularScheduler.showUTCField', true)
|
||||
@ -171,13 +177,13 @@ angular.module('awApp', [
|
||||
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
||||
'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
||||
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
||||
'FeaturesService', '$filter', 'SocketService', 'AppStrings', 'I18NInit',
|
||||
'FeaturesService', '$filter', 'SocketService', 'AppStrings',
|
||||
function($stateExtender, $q, $compile, $cookies, $rootScope, $log, $stateParams,
|
||||
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
||||
LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
||||
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
||||
$filter, SocketService, AppStrings, I18NInit) {
|
||||
I18NInit();
|
||||
$filter, SocketService, AppStrings) {
|
||||
|
||||
$rootScope.$state = $state;
|
||||
$rootScope.$state.matches = function(stateName) {
|
||||
return $state.current.name.search(stateName) > 0;
|
||||
|
||||
72
awx/ui/client/src/app.start.js
Normal file
72
awx/ui/client/src/app.start.js
Normal file
@ -0,0 +1,72 @@
|
||||
const SUPPORTED_LOCALES = ['en', 'es', 'fr', 'ja', 'nl'];
|
||||
const DEFAULT_LOCALE = 'en';
|
||||
const BASE_PATH = global.$basePath ? `${global.$basePath}languages/` : '/static/languages/';
|
||||
|
||||
/**
|
||||
* The Angular app is manually initialized in order to complete some
|
||||
* asynchronous work up front. This function returns a callback so app.js can
|
||||
* call `angular.bootstrap` when the work is complete.
|
||||
*
|
||||
* @argument {function} - Callback.
|
||||
*/
|
||||
function bootstrap (callback) {
|
||||
fetchLocaleStrings((locale) => {
|
||||
if (locale) {
|
||||
angular.module('I18N').constant('LOCALE', locale);
|
||||
}
|
||||
|
||||
angular.element(document).ready(() => callback());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* GET the localized JSON strings file or fall back to the default language
|
||||
* if the locale isn't supported or if the request fails.
|
||||
*
|
||||
* @argument {function} - Callback.
|
||||
*
|
||||
* @returns {object=} - Locale data if it exists.
|
||||
*/
|
||||
function fetchLocaleStrings (callback) {
|
||||
const code = normalizeLocaleCode(navigator.language || navigator.userLanguage);
|
||||
|
||||
if (isDefaultLocale(code) || !isSupportedLocale(code)) {
|
||||
callback({ code });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const request = $.ajax(`${BASE_PATH}${code}.json`);
|
||||
|
||||
request.done(res => {
|
||||
if (res[code]) {
|
||||
callback({ code, strings: res[code] });
|
||||
} else {
|
||||
callback({ code: DEFAULT_LOCALE });
|
||||
}
|
||||
});
|
||||
|
||||
request.fail(() => callback({ code: DEFAULT_LOCALE }));
|
||||
}
|
||||
|
||||
function normalizeLocaleCode (code) {
|
||||
try {
|
||||
code = code.split('-')[0].toLowerCase();
|
||||
} catch (error) {
|
||||
code = DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
function isSupportedLocale (code) {
|
||||
return SUPPORTED_LOCALES.includes(code);
|
||||
}
|
||||
|
||||
function isDefaultLocale (code) {
|
||||
return code === DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
export default {
|
||||
bootstrap
|
||||
};
|
||||
@ -1,52 +1,36 @@
|
||||
/* jshint ignore:start */
|
||||
import { sprintf } from 'sprintf-js';
|
||||
|
||||
var sprintf = require('sprintf-js').sprintf;
|
||||
let defaultLanguage = 'en_US';
|
||||
function I18n (gettextCatalog) {
|
||||
return {
|
||||
N_,
|
||||
sprintf,
|
||||
_: s => gettextCatalog.getString(s),
|
||||
translate: (singular, context) => gettextCatalog.getString(singular, context),
|
||||
translatePlural: (count, singular, plural, context) => {
|
||||
return gettextCatalog.getPlural(count, singular, plural, context);
|
||||
},
|
||||
hasTranslation: () => gettextCatalog.strings[gettextCatalog.currentLanguage] !== undefined
|
||||
};
|
||||
}
|
||||
|
||||
I18n.$inject = ['gettextCatalog'];
|
||||
|
||||
function run (LOCALE, gettextCatalog) {
|
||||
if (LOCALE.code && LOCALE.strings) {
|
||||
gettextCatalog.setCurrentLanguage(LOCALE.code);
|
||||
gettextCatalog.setStrings(LOCALE.code, LOCALE.strings);
|
||||
}
|
||||
}
|
||||
|
||||
run.$inject = ['LOCALE', 'gettextCatalog'];
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name function:i18n#N_
|
||||
* @methodOf function:N_
|
||||
* @description this function marks the translatable string with N_
|
||||
* for 'grunt nggettext_extract'
|
||||
*
|
||||
*/
|
||||
export function N_(s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
export default
|
||||
angular.module('I18N', [])
|
||||
.factory('I18NInit', ['$window', 'gettextCatalog',
|
||||
function ($window, gettextCatalog) {
|
||||
return function() {
|
||||
var langInfo = ($window.navigator.languages || [])[0] ||
|
||||
$window.navigator.language ||
|
||||
$window.navigator.userLanguage ||
|
||||
'';
|
||||
var langUrl = langInfo.replace('-', '_');
|
||||
|
||||
if (langUrl === defaultLanguage) {
|
||||
return;
|
||||
}
|
||||
|
||||
// gettextCatalog.debug = true;
|
||||
gettextCatalog.setCurrentLanguage(langInfo);
|
||||
gettextCatalog.loadRemote('/static/languages/' + langUrl + '.json');
|
||||
};
|
||||
}])
|
||||
.factory('i18n', ['gettextCatalog',
|
||||
function (gettextCatalog) {
|
||||
return {
|
||||
_: function (s) { return gettextCatalog.getString (s); },
|
||||
N_: N_,
|
||||
translate: (singular, context) => gettextCatalog.getString(singular, context),
|
||||
translatePlural: (count, singular, plural, context) => {
|
||||
return gettextCatalog.getPlural(count, singular, plural, context);
|
||||
},
|
||||
sprintf: sprintf,
|
||||
hasTranslation: function () {
|
||||
return gettextCatalog.strings[gettextCatalog.currentLanguage] !== undefined;
|
||||
}
|
||||
};
|
||||
}]);
|
||||
export default angular
|
||||
.module('I18N', [
|
||||
'gettext'
|
||||
])
|
||||
.factory('i18n', I18n)
|
||||
.run(run);
|
||||
|
||||
@ -16,16 +16,16 @@ module.exports = function(config) {
|
||||
reporters: ['progress', 'coverage', 'junit'],
|
||||
files:[
|
||||
'./client/src/vendor.js',
|
||||
'./client/src/app.js',
|
||||
'./node_modules/angular-mocks/angular-mocks.js',
|
||||
{ pattern: './tests/**/*-test.js' },
|
||||
'client/src/**/*.html'
|
||||
'./client/src/app.js',
|
||||
'./tests/**/*-test.js',
|
||||
'./client/src/**/*.html'
|
||||
],
|
||||
preprocessors: {
|
||||
'./client/src/vendor.js': ['webpack', 'sourcemap'],
|
||||
'./client/src/app.js': ['webpack', 'sourcemap'],
|
||||
'./tests/**/*-test.js': ['webpack', 'sourcemap'],
|
||||
'client/src/**/*.html': ['html2js']
|
||||
'./client/src/vendor.js': ['webpack'],
|
||||
'./client/src/app.js': ['webpack'],
|
||||
'./tests/**/*-test.js': ['webpack'],
|
||||
'./client/src/**/*.html': ['html2js']
|
||||
},
|
||||
webpack: webpackTestConfig,
|
||||
webpackMiddleware: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user