mirror of
https://github.com/ansible/awx.git
synced 2026-02-24 14:36:00 -03:30
Merge pull request #317 from gconsidine/ui/angular-manual-init-for-locale
Implement manual initialzation for Angular app
This commit is contained in:
@@ -17,3 +17,4 @@ test
|
|||||||
!client/lib/models/**/*.js
|
!client/lib/models/**/*.js
|
||||||
!client/lib/services/**/*.js
|
!client/lib/services/**/*.js
|
||||||
!client/features/**/*.js
|
!client/features/**/*.js
|
||||||
|
!client/src/app.start.js
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module.exports = {
|
|||||||
node: true
|
node: true
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
angular: true,
|
angular: true,
|
||||||
d3: true,
|
d3: true,
|
||||||
$: true,
|
$: true,
|
||||||
_: true,
|
_: true,
|
||||||
@@ -43,6 +43,7 @@ module.exports = {
|
|||||||
'no-param-reassign': 'off',
|
'no-param-reassign': 'off',
|
||||||
'no-plusplus': 'off',
|
'no-plusplus': 'off',
|
||||||
'no-underscore-dangle': 'off',
|
'no-underscore-dangle': 'off',
|
||||||
|
'no-use-before-define': 'off',
|
||||||
'object-curly-newline': 'off',
|
'object-curly-newline': 'off',
|
||||||
'space-before-function-paren': ['error', 'always']
|
'space-before-function-paren': ['error', 'always']
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const base = {
|
|||||||
jsonlint: 'codemirror.jsonlint'
|
jsonlint: 'codemirror.jsonlint'
|
||||||
}),
|
}),
|
||||||
new ExtractTextPlugin('css/[name].[chunkhash].css'),
|
new ExtractTextPlugin('css/[name].[chunkhash].css'),
|
||||||
new CleanWebpackPlugin([STATIC_PATH, COVERAGE_PATH, LANGUAGES_PATH], {
|
new CleanWebpackPlugin([STATIC_PATH, COVERAGE_PATH], {
|
||||||
root: UI_PATH,
|
root: UI_PATH,
|
||||||
verbose: false
|
verbose: false
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
const base = require('./webpack.base');
|
const base = require('./webpack.base');
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
|
|
||||||
const STATIC_URL = '/static/';
|
const STATIC_URL = '/static/';
|
||||||
|
|
||||||
const development = require('./webpack.development');
|
const development = require('./webpack.base');
|
||||||
|
|
||||||
const test = {
|
const test = {
|
||||||
|
devtool: 'cheap-source-map',
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
$basePath: STATIC_URL
|
$basePath: STATIC_URL
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ const path = require('path');
|
|||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
|
||||||
const HardSourceWebpackPlugin = require('hard-source-webpack-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_PORT = _.get(process.env, 'npm_package_config_django_port', 8043);
|
||||||
const TARGET_HOST = _.get(process.env, 'npm_package_config_django_host', 'https://localhost');
|
const TARGET_HOST = _.get(process.env, 'npm_package_config_django_host', 'https://localhost');
|
||||||
@@ -29,6 +29,7 @@ const watch = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
new HtmlWebpackHarddiskPlugin(),
|
||||||
new HardSourceWebpackPlugin({
|
new HardSourceWebpackPlugin({
|
||||||
cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
|
cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
|
||||||
recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json',
|
recordsPath: 'node_modules/.cache/hard-source/[confighash]/records.json',
|
||||||
@@ -41,7 +42,6 @@ const watch = {
|
|||||||
files: ['package.json']
|
files: ['package.json']
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackHarddiskPlugin(),
|
|
||||||
new webpack.HotModuleReplacementPlugin()
|
new webpack.HotModuleReplacementPlugin()
|
||||||
],
|
],
|
||||||
devServer: {
|
devServer: {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import AddController from './add-credentials.controller';
|
|||||||
import EditController from './edit-credentials.controller';
|
import EditController from './edit-credentials.controller';
|
||||||
import CredentialsStrings from './credentials.strings';
|
import CredentialsStrings from './credentials.strings';
|
||||||
|
|
||||||
|
const MODULE_NAME = 'at.features.credentials';
|
||||||
|
|
||||||
const addEditTemplate = require('~features/credentials/add-edit-credentials.view.html');
|
const addEditTemplate = require('~features/credentials/add-edit-credentials.view.html');
|
||||||
|
|
||||||
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType, Organization) {
|
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType, Organization) {
|
||||||
@@ -51,12 +53,8 @@ CredentialsResolve.$inject = [
|
|||||||
'OrganizationModel'
|
'OrganizationModel'
|
||||||
];
|
];
|
||||||
|
|
||||||
function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvider) {
|
function CredentialsRun ($stateExtender, legacy, strings) {
|
||||||
const stateExtender = $stateExtenderProvider.$get();
|
$stateExtender.addState({
|
||||||
const legacy = legacyProvider.$get();
|
|
||||||
const strings = stringProvider.$get();
|
|
||||||
|
|
||||||
stateExtender.addState({
|
|
||||||
name: 'credentials.add',
|
name: 'credentials.add',
|
||||||
route: '/add',
|
route: '/add',
|
||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
@@ -78,7 +76,7 @@ function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvid
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stateExtender.addState({
|
$stateExtender.addState({
|
||||||
name: 'credentials.edit',
|
name: 'credentials.edit',
|
||||||
route: '/:credential_id',
|
route: '/:credential_id',
|
||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
@@ -101,25 +99,27 @@ function CredentialsConfig ($stateExtenderProvider, legacyProvider, stringProvid
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stateExtender.addState(legacy.getStateConfiguration('list'));
|
$stateExtender.addState(legacy.getStateConfiguration('list'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('edit-permissions'));
|
$stateExtender.addState(legacy.getStateConfiguration('edit-permissions'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('add-permissions'));
|
$stateExtender.addState(legacy.getStateConfiguration('add-permissions'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('add-organization'));
|
$stateExtender.addState(legacy.getStateConfiguration('add-organization'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('edit-organization'));
|
$stateExtender.addState(legacy.getStateConfiguration('edit-organization'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('add-credential-type'));
|
$stateExtender.addState(legacy.getStateConfiguration('add-credential-type'));
|
||||||
stateExtender.addState(legacy.getStateConfiguration('edit-credential-type'));
|
$stateExtender.addState(legacy.getStateConfiguration('edit-credential-type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
CredentialsConfig.$inject = [
|
CredentialsRun.$inject = [
|
||||||
'$stateExtenderProvider',
|
'$stateExtender',
|
||||||
'LegacyCredentialsServiceProvider',
|
'LegacyCredentialsService',
|
||||||
'CredentialsStringsProvider'
|
'CredentialsStrings'
|
||||||
];
|
];
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.features.credentials', [])
|
.module(MODULE_NAME, [])
|
||||||
.config(CredentialsConfig)
|
|
||||||
.controller('AddController', AddController)
|
.controller('AddController', AddController)
|
||||||
.controller('EditController', EditController)
|
.controller('EditController', EditController)
|
||||||
.service('LegacyCredentialsService', LegacyCredentials)
|
.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', [
|
import atFeaturesCredentials from '~features/credentials';
|
||||||
'at.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>
|
<!DOCTYPE html>
|
||||||
<html lang="en" ng-app="awApp">
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" ng-app="awApp">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import atLibServices from '~services';
|
||||||
|
|
||||||
import actionGroup from '~components/action/action-group.directive';
|
import actionGroup from '~components/action/action-group.directive';
|
||||||
import divider from '~components/utility/divider.directive';
|
import divider from '~components/utility/divider.directive';
|
||||||
import form from '~components/form/form.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 BaseInputController from '~components/input/base.controller';
|
||||||
import ComponentsStrings from '~components/components.strings';
|
import ComponentsStrings from '~components/components.strings';
|
||||||
|
|
||||||
|
const MODULE_NAME = 'at.lib.components';
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.lib.components', [])
|
.module(MODULE_NAME, [
|
||||||
|
atLibServices
|
||||||
|
])
|
||||||
.directive('atActionGroup', actionGroup)
|
.directive('atActionGroup', actionGroup)
|
||||||
.directive('atDivider', divider)
|
.directive('atDivider', divider)
|
||||||
.directive('atForm', form)
|
.directive('atForm', form)
|
||||||
@@ -58,3 +64,5 @@ angular
|
|||||||
.directive('atTruncate', truncate)
|
.directive('atTruncate', truncate)
|
||||||
.service('BaseInputController', BaseInputController)
|
.service('BaseInputController', BaseInputController)
|
||||||
.service('ComponentsStrings', ComponentsStrings);
|
.service('ComponentsStrings', ComponentsStrings);
|
||||||
|
|
||||||
|
export default MODULE_NAME;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import atLibServices from '~services';
|
||||||
|
|
||||||
import Base from '~models/Base';
|
import Base from '~models/Base';
|
||||||
import Config from '~models/Config';
|
import Config from '~models/Config';
|
||||||
import Credential from '~models/Credential';
|
import Credential from '~models/Credential';
|
||||||
@@ -5,11 +7,17 @@ import CredentialType from '~models/CredentialType';
|
|||||||
import Me from '~models/Me';
|
import Me from '~models/Me';
|
||||||
import Organization from '~models/Organization';
|
import Organization from '~models/Organization';
|
||||||
|
|
||||||
|
const MODULE_NAME = 'at.lib.models';
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.lib.models', [])
|
.module(MODULE_NAME, [
|
||||||
|
atLibServices
|
||||||
|
])
|
||||||
.service('BaseModel', Base)
|
.service('BaseModel', Base)
|
||||||
.service('ConfigModel', Config)
|
.service('ConfigModel', Config)
|
||||||
.service('CredentialModel', Credential)
|
.service('CredentialModel', Credential)
|
||||||
.service('CredentialTypeModel', CredentialType)
|
.service('CredentialTypeModel', CredentialType)
|
||||||
.service('MeModel', Me)
|
.service('MeModel', Me)
|
||||||
.service('OrganizationModel', Organization);
|
.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 CacheService from '~services/cache.service';
|
||||||
import EventService from '~services/event.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
|
angular
|
||||||
.module('at.lib.services', [])
|
.module(MODULE_NAME, [
|
||||||
|
'I18N'
|
||||||
|
])
|
||||||
.service('AppStrings', AppStrings)
|
.service('AppStrings', AppStrings)
|
||||||
.service('BaseStringService', BaseStringService)
|
.service('BaseStringService', BaseStringService)
|
||||||
.service('CacheService', CacheService)
|
.service('CacheService', CacheService)
|
||||||
.service('EventService', EventService);
|
.service('EventService', EventService);
|
||||||
|
|
||||||
|
export default MODULE_NAME;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Configuration dependencies
|
// Configuration dependencies
|
||||||
global.$AnsibleConfig = null;
|
global.$AnsibleConfig = null;
|
||||||
// Provided via Webpack DefinePlugin in webpack.config.js
|
// Provided via Webpack DefinePlugin in webpack.config.js
|
||||||
global.$ENV = {} ;
|
global.$ENV = {};
|
||||||
// ui-router debugging
|
// ui-router debugging
|
||||||
if ($ENV['route-debug']){
|
if ($ENV['route-debug']){
|
||||||
let trace = angular.module('ui.router').trace;
|
let trace = angular.module('ui.router').trace;
|
||||||
@@ -14,7 +14,8 @@ if ($basePath) {
|
|||||||
urlPrefix = `${$basePath}`;
|
urlPrefix = `${$basePath}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modules
|
import start from './app.start';
|
||||||
|
|
||||||
import portalMode from './portal-mode/main';
|
import portalMode from './portal-mode/main';
|
||||||
import systemTracking from './system-tracking/main';
|
import systemTracking from './system-tracking/main';
|
||||||
import inventoriesHosts from './inventories-hosts/main';
|
import inventoriesHosts from './inventories-hosts/main';
|
||||||
@@ -46,71 +47,76 @@ import access from './access/main';
|
|||||||
import scheduler from './scheduler/main';
|
import scheduler from './scheduler/main';
|
||||||
import instanceGroups from './instance-groups/main';
|
import instanceGroups from './instance-groups/main';
|
||||||
|
|
||||||
import '../lib/components';
|
import atFeatures from '~features';
|
||||||
import '../lib/models';
|
import atLibComponents from '~components';
|
||||||
import '../lib/services';
|
import atLibModels from '~models';
|
||||||
import '../features';
|
import atLibServices from '~services';
|
||||||
|
|
||||||
angular.module('awApp', [
|
start.bootstrap(() => {
|
||||||
'I18N',
|
angular.bootstrap(document.body, ['awApp']);
|
||||||
'AngularCodeMirrorModule',
|
});
|
||||||
'angular-duration-format',
|
|
||||||
'angularMoment',
|
|
||||||
'AngularScheduler',
|
|
||||||
'angular-md5',
|
|
||||||
'dndLists',
|
|
||||||
'ncy-angular-breadcrumb',
|
|
||||||
'ngSanitize',
|
|
||||||
'ngCookies',
|
|
||||||
'ngToast',
|
|
||||||
'gettext',
|
|
||||||
'Timezones',
|
|
||||||
'ui.router',
|
|
||||||
'ui.router.state.events',
|
|
||||||
'lrInfiniteScroll',
|
|
||||||
|
|
||||||
about.name,
|
angular
|
||||||
access.name,
|
.module('awApp', [
|
||||||
license.name,
|
'I18N',
|
||||||
RestServices.name,
|
'AngularCodeMirrorModule',
|
||||||
browserData.name,
|
'angular-duration-format',
|
||||||
configuration.name,
|
'angularMoment',
|
||||||
systemTracking.name,
|
'AngularScheduler',
|
||||||
inventoriesHosts.name,
|
'angular-md5',
|
||||||
inventoryScripts.name,
|
'dndLists',
|
||||||
credentials.name,
|
'ncy-angular-breadcrumb',
|
||||||
credentialTypes.name,
|
'ngSanitize',
|
||||||
organizations.name,
|
'ngCookies',
|
||||||
managementJobs.name,
|
'ngToast',
|
||||||
breadCrumb.name,
|
'gettext',
|
||||||
home.name,
|
'Timezones',
|
||||||
login.name,
|
'ui.router',
|
||||||
activityStream.name,
|
'ui.router.state.events',
|
||||||
workflowResults.name,
|
'lrInfiniteScroll',
|
||||||
jobResults.name,
|
|
||||||
jobSubmission.name,
|
|
||||||
notifications.name,
|
|
||||||
standardOut.name,
|
|
||||||
Templates.name,
|
|
||||||
portalMode.name,
|
|
||||||
jobs.name,
|
|
||||||
teams.name,
|
|
||||||
users.name,
|
|
||||||
projects.name,
|
|
||||||
scheduler.name,
|
|
||||||
instanceGroups.name,
|
|
||||||
|
|
||||||
'Utilities',
|
about.name,
|
||||||
'templates',
|
access.name,
|
||||||
'PromptDialog',
|
license.name,
|
||||||
'AWDirectives',
|
RestServices.name,
|
||||||
'features',
|
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',
|
'Utilities',
|
||||||
'at.lib.models',
|
'templates',
|
||||||
'at.lib.services',
|
'PromptDialog',
|
||||||
'at.features',
|
'AWDirectives',
|
||||||
])
|
'features',
|
||||||
|
|
||||||
|
atFeatures,
|
||||||
|
atLibComponents,
|
||||||
|
atLibModels,
|
||||||
|
atLibServices
|
||||||
|
])
|
||||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||||
.constant('AngularScheduler.useTimezone', true)
|
.constant('AngularScheduler.useTimezone', true)
|
||||||
.constant('AngularScheduler.showUTCField', true)
|
.constant('AngularScheduler.showUTCField', true)
|
||||||
@@ -171,13 +177,13 @@ angular.module('awApp', [
|
|||||||
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
||||||
'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
||||||
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
||||||
'FeaturesService', '$filter', 'SocketService', 'AppStrings', 'I18NInit',
|
'FeaturesService', '$filter', 'SocketService', 'AppStrings',
|
||||||
function($stateExtender, $q, $compile, $cookies, $rootScope, $log, $stateParams,
|
function($stateExtender, $q, $compile, $cookies, $rootScope, $log, $stateParams,
|
||||||
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
||||||
LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
||||||
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
||||||
$filter, SocketService, AppStrings, I18NInit) {
|
$filter, SocketService, AppStrings) {
|
||||||
I18NInit();
|
|
||||||
$rootScope.$state = $state;
|
$rootScope.$state = $state;
|
||||||
$rootScope.$state.matches = function(stateName) {
|
$rootScope.$state.matches = function(stateName) {
|
||||||
return $state.current.name.search(stateName) > 0;
|
return $state.current.name.search(stateName) > 0;
|
||||||
|
|||||||
87
awx/ui/client/src/app.start.js
Normal file
87
awx/ui/client/src/app.start.js
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
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 = getNormalizedLocaleCode();
|
||||||
|
|
||||||
|
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 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grabs the language off of navigator for browser compatibility.
|
||||||
|
* If the language isn't set, then it falls back to the DEFAULT_LOCALE. The
|
||||||
|
* locale code is normalized to be lowercase and 2 characters in length.
|
||||||
|
*/
|
||||||
|
function getNormalizedLocaleCode () {
|
||||||
|
let code;
|
||||||
|
|
||||||
|
if (navigator.languages && navigator.languages[0]) {
|
||||||
|
[code] = navigator.languages;
|
||||||
|
} else if (navigator.language) {
|
||||||
|
code = navigator.language;
|
||||||
|
} else {
|
||||||
|
code = navigator.userLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
code = code.split('-')[0].toLowerCase();
|
||||||
|
} catch (error) {
|
||||||
|
code = DEFAULT_LOCALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code.substring(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
function I18n (gettextCatalog) {
|
||||||
let defaultLanguage = 'en_US';
|
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) {
|
export function N_(s) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default
|
export default angular
|
||||||
angular.module('I18N', [])
|
.module('I18N', [
|
||||||
.factory('I18NInit', ['$window', 'gettextCatalog',
|
'gettext'
|
||||||
function ($window, gettextCatalog) {
|
])
|
||||||
return function() {
|
.factory('i18n', I18n)
|
||||||
var langInfo = ($window.navigator.languages || [])[0] ||
|
.run(run);
|
||||||
$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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}]);
|
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ module.exports = function(config) {
|
|||||||
reporters: ['progress', 'coverage', 'junit'],
|
reporters: ['progress', 'coverage', 'junit'],
|
||||||
files:[
|
files:[
|
||||||
'./client/src/vendor.js',
|
'./client/src/vendor.js',
|
||||||
'./client/src/app.js',
|
|
||||||
'./node_modules/angular-mocks/angular-mocks.js',
|
'./node_modules/angular-mocks/angular-mocks.js',
|
||||||
{ pattern: './tests/**/*-test.js' },
|
'./client/src/app.js',
|
||||||
'client/src/**/*.html'
|
'./tests/**/*-test.js',
|
||||||
|
'./client/src/**/*.html'
|
||||||
],
|
],
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
'./client/src/vendor.js': ['webpack', 'sourcemap'],
|
'./client/src/vendor.js': ['webpack'],
|
||||||
'./client/src/app.js': ['webpack', 'sourcemap'],
|
'./client/src/app.js': ['webpack'],
|
||||||
'./tests/**/*-test.js': ['webpack', 'sourcemap'],
|
'./tests/**/*-test.js': ['webpack'],
|
||||||
'client/src/**/*.html': ['html2js']
|
'./client/src/**/*.html': ['html2js']
|
||||||
},
|
},
|
||||||
webpack: webpackTestConfig,
|
webpack: webpackTestConfig,
|
||||||
webpackMiddleware: {
|
webpackMiddleware: {
|
||||||
|
|||||||
Reference in New Issue
Block a user