mirror of
https://github.com/ansible/awx.git
synced 2024-10-30 22:21:13 +03:00
commit
bf301ec130
40
Makefile
40
Makefile
@ -81,7 +81,7 @@ SETUP_TAR_CHECKSUM=$(NAME)-setup-CHECKSUM
|
||||
|
||||
# DEB build parameters
|
||||
DEBUILD_BIN ?= debuild
|
||||
DEBUILD_OPTS =
|
||||
DEBUILD_OPTS =
|
||||
DPUT_BIN ?= dput
|
||||
DPUT_OPTS ?= -c .dput.cf -u
|
||||
REPREPRO_BIN ?= reprepro
|
||||
@ -506,6 +506,43 @@ test_jenkins : test_coverage
|
||||
# UI TASKS
|
||||
# --------------------------------------
|
||||
|
||||
HAVE_PO := $(shell ls awx/ui/po/*.po 2>/dev/null)
|
||||
check-po:
|
||||
ifdef HAVE_PO
|
||||
# Should be 'Language: zh-CN' but not 'Language: zh_CN' in zh_CN.po
|
||||
for po in awx/ui/po/*.po ; do \
|
||||
echo $$po; \
|
||||
mo="awx/ui/po/`basename $$po .po`.mo"; \
|
||||
msgfmt --check --verbose $$po -o $$mo; \
|
||||
if test "$$?" -ne 0 ; then \
|
||||
exit -1; \
|
||||
fi; \
|
||||
rm $$mo; \
|
||||
name=`echo "$$po" | grep '-'`; \
|
||||
if test "x$$name" != x ; then \
|
||||
right_name=`echo $$language | sed -e 's/-/_/'`; \
|
||||
echo "ERROR: WRONG $$name CORRECTION: $$right_name"; \
|
||||
exit -1; \
|
||||
fi; \
|
||||
language=`grep '^"Language:' "$$po" | grep '_'`; \
|
||||
if test "x$$language" != x ; then \
|
||||
right_language=`echo $$language | sed -e 's/_/-/'`; \
|
||||
echo "ERROR: WRONG $$language CORRECTION: $$right_language in $$po"; \
|
||||
exit -1; \
|
||||
fi; \
|
||||
done;
|
||||
else
|
||||
@echo No PO files
|
||||
endif
|
||||
|
||||
# generate l10n .json
|
||||
languages: $(UI_DEPS_FLAG_FILE) check-po
|
||||
$(NPM_BIN) --prefix awx/ui run languages
|
||||
|
||||
# generate .pot
|
||||
pot: $(UI_DEPS_FLAG_FILE)
|
||||
$(NPM_BIN) --prefix awx/ui run pot
|
||||
|
||||
ui-deps: $(UI_DEPS_FLAG_FILE)
|
||||
|
||||
$(UI_DEPS_FLAG_FILE): awx/ui/package.json
|
||||
@ -520,6 +557,7 @@ ui-docker: $(UI_DEPS_FLAG_FILE)
|
||||
|
||||
ui-release: $(UI_RELEASE_FLAG_FILE)
|
||||
|
||||
# todo: include languages target when .po deliverables are added to source control
|
||||
$(UI_RELEASE_FLAG_FILE): $(UI_DEPS_FLAG_FILE)
|
||||
$(NPM_BIN) --prefix awx/ui run build-release
|
||||
touch $(UI_RELEASE_FLAG_FILE)
|
||||
|
@ -16,6 +16,7 @@ module.exports = function(grunt) {
|
||||
// Project configuration.
|
||||
grunt.initConfig(configs);
|
||||
grunt.loadNpmTasks('grunt-newer');
|
||||
grunt.loadNpmTasks('grunt-angular-gettext');
|
||||
|
||||
// writes environment variables for development. current manages:
|
||||
// browser-sync + websocket proxy
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default
|
||||
['$scope', '$state', 'ConfigService', function($scope, $state, ConfigService){
|
||||
['$scope', '$state', 'ConfigService', 'i18n',
|
||||
function($scope, $state, ConfigService, i18n){
|
||||
var processVersion = function(version){
|
||||
// prettify version & calculate padding
|
||||
// e,g 3.0.0-0.git201602191743/ -> 3.0.0
|
||||
@ -20,6 +21,7 @@ export default
|
||||
.then(function(config){
|
||||
$scope.subscription = config.license_info.subscription_name;
|
||||
$scope.version = processVersion(config.version);
|
||||
$scope.version_str = i18n._("Version");
|
||||
$('#about-modal').modal('show');
|
||||
});
|
||||
};
|
||||
|
@ -11,7 +11,7 @@
|
||||
<!-- Don't indent this properly, you'll break the cow -->
|
||||
<pre class="About-cowsay--code">
|
||||
________________
|
||||
/ Tower Version \\
|
||||
/ Tower {{version_str}} \\
|
||||
\\<span>{{version}}</span>/
|
||||
----------------
|
||||
\\ ^__^
|
||||
|
@ -7,6 +7,7 @@
|
||||
// Vendor dependencies
|
||||
import 'jquery';
|
||||
import 'angular';
|
||||
import 'angular-gettext';
|
||||
import 'bootstrap';
|
||||
import 'jquery-ui';
|
||||
import 'bootstrap-datepicker';
|
||||
@ -79,6 +80,7 @@ import config from './shared/config/main';
|
||||
import './login/authenticationServices/pendo/ng-pendo';
|
||||
import footer from './footer/main';
|
||||
import scheduler from './scheduler/main';
|
||||
import {N_} from './i18n';
|
||||
|
||||
var tower = angular.module('Tower', [
|
||||
// how to add CommonJS / AMD third-party dependencies:
|
||||
@ -203,6 +205,8 @@ var tower = angular.module('Tower', [
|
||||
scheduler.name,
|
||||
'ApiModelHelper',
|
||||
'ActivityStreamHelper',
|
||||
'gettext',
|
||||
'I18N',
|
||||
])
|
||||
|
||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||
@ -237,6 +241,10 @@ var tower = angular.module('Tower', [
|
||||
$state.go('dashboard');
|
||||
});
|
||||
|
||||
/* Mark translatable strings with N_() and
|
||||
* extract them by 'grunt nggettext_extract'
|
||||
* but angular.config() cannot get gettextCatalog.
|
||||
*/
|
||||
$stateProvider.
|
||||
state('teams', {
|
||||
url: '/teams',
|
||||
@ -248,7 +256,7 @@ var tower = angular.module('Tower', [
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: 'setup',
|
||||
label: 'TEAMS'
|
||||
label: N_("TEAMS")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -258,7 +266,7 @@ var tower = angular.module('Tower', [
|
||||
controller: TeamsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "teams",
|
||||
label: "CREATE TEAM"
|
||||
label: N_("CREATE TEAM")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -333,7 +341,7 @@ var tower = angular.module('Tower', [
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: 'setup',
|
||||
label: 'CREDENTIALS'
|
||||
label: N_("CREDENTIALS")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -343,7 +351,7 @@ var tower = angular.module('Tower', [
|
||||
controller: CredentialsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "credentials",
|
||||
label: "CREATE CREDENTIAL"
|
||||
label: N_("CREATE CREDENTIAL")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -370,7 +378,7 @@ var tower = angular.module('Tower', [
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: 'setup',
|
||||
label: 'USERS'
|
||||
label: N_("USERS")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -380,7 +388,7 @@ var tower = angular.module('Tower', [
|
||||
controller: UsersAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "users",
|
||||
label: "CREATE USER"
|
||||
label: N_("CREATE USER")
|
||||
}
|
||||
}).
|
||||
|
||||
@ -420,7 +428,7 @@ var tower = angular.module('Tower', [
|
||||
templateUrl: urlPrefix + 'partials/sockets.html',
|
||||
controller: SocketsController,
|
||||
ncyBreadcrumb: {
|
||||
label: 'SOCKETS'
|
||||
label: N_("SOCKETS")
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -443,13 +451,14 @@ var tower = angular.module('Tower', [
|
||||
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
||||
'ClearScope', 'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
||||
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
||||
'FeaturesService', '$filter', 'SocketService',
|
||||
'FeaturesService', '$filter', 'SocketService', 'I18NInit',
|
||||
function($stateExtender, $q, $compile, $cookieStore, $rootScope, $log,
|
||||
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
||||
ClearScope, LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
||||
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
||||
$filter, SocketService) {
|
||||
$filter, SocketService, I18NInit) {
|
||||
|
||||
I18NInit();
|
||||
$stateExtender.addState({
|
||||
name: 'dashboard',
|
||||
url: '/home',
|
||||
@ -466,7 +475,7 @@ var tower = angular.module('Tower', [
|
||||
refreshButton: true
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
label: "DASHBOARD"
|
||||
label: N_("DASHBOARD")
|
||||
},
|
||||
resolve: {
|
||||
graphData: ['$q', 'jobStatusGraphData', '$rootScope',
|
||||
@ -487,7 +496,7 @@ var tower = angular.module('Tower', [
|
||||
templateUrl: urlPrefix + 'partials/jobs.html',
|
||||
controller: JobsListController,
|
||||
ncyBreadcrumb: {
|
||||
label: "JOBS"
|
||||
label: N_("JOBS")
|
||||
},
|
||||
params: {
|
||||
search: {
|
||||
@ -512,7 +521,7 @@ var tower = angular.module('Tower', [
|
||||
activityStreamTarget: 'project'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
label: "PROJECTS"
|
||||
label: N_("PROJECTS")
|
||||
},
|
||||
socket: {
|
||||
"groups":{
|
||||
@ -528,7 +537,7 @@ var tower = angular.module('Tower', [
|
||||
controller: ProjectsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "projects",
|
||||
label: "CREATE PROJECT"
|
||||
label: N_("CREATE PROJECT")
|
||||
},
|
||||
socket: {
|
||||
"groups":{
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="BreadCrumb-menuLinkHolder">
|
||||
<div class="BreadCrumb-menuLink"
|
||||
id="bread_crumb_refresh"
|
||||
aw-tool-tip="Refresh the page"
|
||||
aw-tool-tip="{{'Refresh the page'|translate}}"
|
||||
data-placement="left"
|
||||
data-trigger="hover"
|
||||
data-container="body"
|
||||
|
@ -15,7 +15,8 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
Rest, Alert, ProjectList, GenerateList, Prompt, SearchInit,
|
||||
PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath,
|
||||
SelectionInit, ProjectUpdate, Refresh, Wait, GetChoices, Empty,
|
||||
Find, GetProjectIcon, GetProjectToolTip, $filter, $state, rbacUiControlService) {
|
||||
Find, GetProjectIcon, GetProjectToolTip, $filter, $state, rbacUiControlService,
|
||||
i18n) {
|
||||
ClearScope();
|
||||
|
||||
$scope.canAdd = false;
|
||||
@ -57,16 +58,16 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
$scope.projects.forEach(function(project, i) {
|
||||
$scope.projects[i].statusIcon = GetProjectIcon(project.status);
|
||||
$scope.projects[i].statusTip = GetProjectToolTip(project.status);
|
||||
$scope.projects[i].scm_update_tooltip = "Start an SCM update";
|
||||
$scope.projects[i].scm_schedule_tooltip = "Schedule future SCM updates";
|
||||
$scope.projects[i].scm_update_tooltip = i18n._("Start an SCM update");
|
||||
$scope.projects[i].scm_schedule_tooltip = i18n._("Schedule future SCM updates");
|
||||
$scope.projects[i].scm_type_class = "";
|
||||
|
||||
if (project.status === 'failed' && project.summary_fields.last_update && project.summary_fields.last_update.status === 'canceled') {
|
||||
$scope.projects[i].statusTip = 'Canceled. Click for details';
|
||||
$scope.projects[i].statusTip = i18n._('Canceled. Click for details');
|
||||
}
|
||||
|
||||
if (project.status === 'running' || project.status === 'updating') {
|
||||
$scope.projects[i].scm_update_tooltip = "SCM update currently running";
|
||||
$scope.projects[i].scm_update_tooltip = i18n._("SCM update currently running");
|
||||
$scope.projects[i].scm_type_class = "btn-disabled";
|
||||
}
|
||||
|
||||
@ -74,10 +75,10 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
if (type.value === project.scm_type) {
|
||||
$scope.projects[i].scm_type = type.label;
|
||||
if (type.label === 'Manual') {
|
||||
$scope.projects[i].scm_update_tooltip = 'Manual projects do not require an SCM update';
|
||||
$scope.projects[i].scm_schedule_tooltip = 'Manual projects do not require a schedule';
|
||||
$scope.projects[i].scm_update_tooltip = i18n._('Manual projects do not require an SCM update');
|
||||
$scope.projects[i].scm_schedule_tooltip = i18n._('Manual projects do not require a schedule');
|
||||
$scope.projects[i].scm_type_class = 'btn-disabled';
|
||||
$scope.projects[i].statusTip = 'Not configured for SCM';
|
||||
$scope.projects[i].statusTip = i18n._('Not configured for SCM');
|
||||
$scope.projects[i].statusIcon = 'none';
|
||||
}
|
||||
}
|
||||
@ -215,8 +216,8 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
$state.go('scmUpdateStdout', {id: id});
|
||||
|
||||
} else {
|
||||
Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' +
|
||||
' completed. If you have not already done so, start an update for this project.', 'alert-info');
|
||||
Alert(i18n._('No Updates Available'), i18n._('There is no SCM update information available for this project. An update has not yet been ' +
|
||||
' completed. If you have not already done so, start an update for this project.'), 'alert-info');
|
||||
}
|
||||
});
|
||||
|
||||
@ -224,8 +225,8 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
// Refresh the project list
|
||||
var project = Find({ list: $scope.projects, key: 'id', val: id });
|
||||
if (Empty(project.scm_type) || project.scm_type === 'Manual') {
|
||||
Alert('No SCM Configuration', 'The selected project is not configured for SCM. To configure for SCM, edit the project and provide SCM settings, ' +
|
||||
'and then run an update.', 'alert-info');
|
||||
Alert(i18n._('No SCM Configuration'), i18n._('The selected project is not configured for SCM. To configure for SCM, edit the project and provide SCM settings, ' +
|
||||
'and then run an update.'), 'alert-info');
|
||||
} else {
|
||||
// Refresh what we have in memory to insure we're accessing the most recent status record
|
||||
Rest.setUrl(project.url);
|
||||
@ -234,8 +235,8 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
$scope.$emit('GoToJobDetails', data);
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Project lookup failed. GET returned: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'),
|
||||
msg: i18n._('Project lookup failed. GET returned: ') + status });
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -255,14 +256,14 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'),
|
||||
msg: i18n.format(i18n._('Call to %s failed. DELETE returned status: '), url) + status });
|
||||
});
|
||||
};
|
||||
|
||||
Prompt({
|
||||
hdr: 'Delete',
|
||||
body: '<div class="Prompt-bodyQuery">Are you sure you want to delete the project below?</div><div class="Prompt-bodyTarget">' + $filter('sanitize')(name) + '</div>',
|
||||
hdr: i18n._('Delete'),
|
||||
body: i18n._('<div class="Prompt-bodyQuery">Are you sure you want to delete the project below?</div>') + '<div class="Prompt-bodyTarget">' + $filter('sanitize')(name) + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
@ -276,11 +277,11 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
Rest.setUrl(url);
|
||||
Rest.post()
|
||||
.success(function () {
|
||||
Alert('SCM Update Cancel', 'Your request to cancel the update was submitted to the task manager.', 'alert-info');
|
||||
Alert(i18n._('SCM Update Cancel'), i18n._('Your request to cancel the update was submitted to the task manager.'), 'alert-info');
|
||||
$scope.refresh();
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n.format(i18n._('Call to %s failed. POST status: '), url) + status });
|
||||
});
|
||||
});
|
||||
|
||||
@ -296,12 +297,12 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
if (data.can_cancel) {
|
||||
$scope.$emit('Cancel_Update', url);
|
||||
} else {
|
||||
Alert('Cancel Not Allowed', '<div>Either you do not have access or the SCM update process completed. ' +
|
||||
'Click the <em>Refresh</em> button to view the latest status.</div>', 'alert-info', null, null, null, null, true);
|
||||
Alert(i18n._('Cancel Not Allowed'), i18n._('<div>Either you do not have access or the SCM update process completed. ' +
|
||||
'Click the <em>Refresh</em> button to view the latest status.</div>'), 'alert-info', null, null, null, null, true);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. GET status: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'), msg: i18n.format(i18n._('Call to %s failed. GET status: '), url) + status });
|
||||
});
|
||||
});
|
||||
|
||||
@ -316,17 +317,17 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $stateParams,
|
||||
$scope.$emit('Check_Cancel', data);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + data.related.current_update + ' failed. GET status: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'),
|
||||
msg: i18n.format(i18n._('Call to %s failed. GET status: '), data.related.current_update) + status });
|
||||
});
|
||||
} else {
|
||||
Alert('Update Not Found', '<div>An SCM update does not appear to be running for project: ' + $filter('sanitize')(name) + '. Click the <em>Refresh</em> ' +
|
||||
'button to view the latest status.</div>', 'alert-info',undefined,undefined,undefined,undefined,true);
|
||||
Alert(i18n._('Update Not Found'), i18n.format(i18n._('<div>An SCM update does not appear to be running for project: %s. Click the <em>Refresh</em> ' +
|
||||
'button to view the latest status.</div>'), $filter('sanitize')(name)), 'alert-info',undefined,undefined,undefined,undefined,true);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to get project failed. GET status: ' + status });
|
||||
ProcessErrors($scope, data, status, null, { hdr: i18n._('Error!'),
|
||||
msg: i18n._('Call to get project failed. GET status: ') + status });
|
||||
});
|
||||
};
|
||||
|
||||
@ -371,7 +372,8 @@ ProjectsList.$inject = ['$scope', '$rootScope', '$location', '$log',
|
||||
'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'SelectionInit', 'ProjectUpdate',
|
||||
'Refresh', 'Wait', 'GetChoices', 'Empty', 'Find',
|
||||
'GetProjectIcon', 'GetProjectToolTip', '$filter', '$state', 'rbacUiControlService'
|
||||
'GetProjectIcon', 'GetProjectToolTip', '$filter', '$state', 'rbacUiControlService',
|
||||
'i18n'
|
||||
];
|
||||
|
||||
|
||||
@ -379,7 +381,7 @@ export function ProjectsAdd(Refresh, $scope, $rootScope, $compile, $location, $l
|
||||
$stateParams, ProjectsForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, ReturnToCaller, GetProjectPath, LookUpInit,
|
||||
OrganizationList, CredentialList, GetChoices, DebugForm, Wait, $state,
|
||||
CreateSelect2) {
|
||||
CreateSelect2, i18n) {
|
||||
|
||||
Rest.setUrl(GetBasePath('projects'));
|
||||
Rest.options()
|
||||
@ -504,8 +506,8 @@ export function ProjectsAdd(Refresh, $scope, $rootScope, $compile, $location, $l
|
||||
})
|
||||
.error(function (data, status) {
|
||||
Wait('stop');
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||
msg: 'Failed to create new project. POST returned status: ' + status });
|
||||
ProcessErrors($scope, data, status, form, { hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to create new project. POST returned status: ') + status });
|
||||
});
|
||||
};
|
||||
|
||||
@ -521,27 +523,27 @@ export function ProjectsAdd(Refresh, $scope, $rootScope, $compile, $location, $l
|
||||
if($scope.scm_type.value) {
|
||||
switch ($scope.scm_type.value) {
|
||||
case 'git':
|
||||
$scope.urlPopover = '<p>Example URLs for GIT SCM include:</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for GIT SCM include:</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||
'<li>git@github.com:ansible/ansible.git</li><li>git://servername.example.com/ansible.git</li></ul>' +
|
||||
'<p><strong>Note:</strong> When using SSH protocol for GitHub or Bitbucket, enter an SSH key only, ' +
|
||||
'do not enter a username (other than git). Additionally, GitHub and Bitbucket do not support password authentication when using ' +
|
||||
'SSH. GIT read only protocol (git://) does not use username or password information.';
|
||||
'SSH. GIT read only protocol (git://) does not use username or password information.');
|
||||
break;
|
||||
case 'svn':
|
||||
$scope.urlPopover = '<p>Example URLs for Subversion SCM include:</p>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for Subversion SCM include:</p>' +
|
||||
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
||||
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
||||
'<li>svn+ssh://servername.example.com/path</li></ul>');
|
||||
break;
|
||||
case 'hg':
|
||||
$scope.urlPopover = '<p>Example URLs for Mercurial SCM include:</p>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for Mercurial SCM include:</p>' +
|
||||
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
||||
'<li>ssh://server.example.com/path</li></ul>' +
|
||||
'<p><strong>Note:</strong> Mercurial does not support password authentication for SSH. ' +
|
||||
'Do not put the username and key in the URL. ' +
|
||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.';
|
||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.');
|
||||
break;
|
||||
default:
|
||||
$scope.urlPopover = '<p> URL popover text';
|
||||
$scope.urlPopover = i18n._('<p> URL popover text');
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +558,7 @@ ProjectsAdd.$inject = ['Refresh', '$scope', '$rootScope', '$compile', '$location
|
||||
'$stateParams', 'ProjectsForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ReturnToCaller',
|
||||
'GetProjectPath', 'LookUpInit', 'OrganizationList', 'CredentialList',
|
||||
'GetChoices', 'DebugForm', 'Wait', '$state', 'CreateSelect2'
|
||||
'GetChoices', 'DebugForm', 'Wait', '$state', 'CreateSelect2', 'i18n'
|
||||
];
|
||||
|
||||
|
||||
@ -566,7 +568,7 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
ReturnToCaller, GetProjectPath, Authorization, CredentialList, LookUpInit,
|
||||
GetChoices, Empty, DebugForm, Wait, SchedulesControllerInit,
|
||||
SchedulesListInit, SchedulesList, ProjectUpdate, $state, CreateSelect2,
|
||||
OrganizationList, NotificationsListInit, ToggleNotification) {
|
||||
OrganizationList, NotificationsListInit, ToggleNotification, i18n) {
|
||||
|
||||
ClearScope('htmlTemplate');
|
||||
|
||||
@ -769,8 +771,8 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
$scope.$emit('projectLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve project: ' + id + '. GET status: ' + status
|
||||
ProcessErrors($scope, data, status, form, { hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to retrieve project: ') + id + i18n._('. GET status: ') + status
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -871,8 +873,8 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
};
|
||||
|
||||
Prompt({
|
||||
hdr: 'Delete',
|
||||
body: '<div class="Prompt-bodyQuery">Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
hdr: i18n._('Delete'),
|
||||
body: i18n.format(i18n._('<div class="Prompt-bodyQuery">Are you sure you want to remove the %s below from %s?</div>'), title, $scope.name) + '<div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
@ -889,27 +891,27 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
if($scope.scm_type.value) {
|
||||
switch ($scope.scm_type.value) {
|
||||
case 'git':
|
||||
$scope.urlPopover = '<p>Example URLs for GIT SCM include:</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for GIT SCM include:</p><ul class=\"no-bullets\"><li>https://github.com/ansible/ansible.git</li>' +
|
||||
'<li>git@github.com:ansible/ansible.git</li><li>git://servername.example.com/ansible.git</li></ul>' +
|
||||
'<p><strong>Note:</strong> When using SSH protocol for GitHub or Bitbucket, enter an SSH key only, ' +
|
||||
'do not enter a username (other than git). Additionally, GitHub and Bitbucket do not support password authentication when using ' +
|
||||
'SSH. GIT read only protocol (git://) does not use username or password information.';
|
||||
'SSH. GIT read only protocol (git://) does not use username or password information.');
|
||||
break;
|
||||
case 'svn':
|
||||
$scope.urlPopover = '<p>Example URLs for Subversion SCM include:</p>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for Subversion SCM include:</p>' +
|
||||
'<ul class=\"no-bullets\"><li>https://github.com/ansible/ansible</li><li>svn://servername.example.com/path</li>' +
|
||||
'<li>svn+ssh://servername.example.com/path</li></ul>';
|
||||
'<li>svn+ssh://servername.example.com/path</li></ul>');
|
||||
break;
|
||||
case 'hg':
|
||||
$scope.urlPopover = '<p>Example URLs for Mercurial SCM include:</p>' +
|
||||
$scope.urlPopover = i18n._('<p>Example URLs for Mercurial SCM include:</p>' +
|
||||
'<ul class=\"no-bullets\"><li>https://bitbucket.org/username/project</li><li>ssh://hg@bitbucket.org/username/project</li>' +
|
||||
'<li>ssh://server.example.com/path</li></ul>' +
|
||||
'<p><strong>Note:</strong> Mercurial does not support password authentication for SSH. ' +
|
||||
'Do not put the username and key in the URL. ' +
|
||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.';
|
||||
'If using Bitbucket and SSH, do not supply your Bitbucket username.');
|
||||
break;
|
||||
default:
|
||||
$scope.urlPopover = '<p> URL popover text';
|
||||
$scope.urlPopover = i18n._('<p> URL popover text');
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -918,7 +920,7 @@ export function ProjectsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
if ($scope.project_obj.scm_type === "Manual" || Empty($scope.project_obj.scm_type)) {
|
||||
// ignore
|
||||
} else if ($scope.project_obj.status === 'updating' || $scope.project_obj.status === 'running' || $scope.project_obj.status === 'pending') {
|
||||
Alert('Update in Progress', 'The SCM update process is running.', 'alert-info');
|
||||
Alert('Update in Progress', i18n._('The SCM update process is running.'), 'alert-info');
|
||||
} else {
|
||||
ProjectUpdate({ scope: $scope, project_id: $scope.project_obj.id });
|
||||
}
|
||||
@ -936,5 +938,5 @@ ProjectsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log',
|
||||
'Authorization', 'CredentialList', 'LookUpInit', 'GetChoices', 'Empty',
|
||||
'DebugForm', 'Wait', 'SchedulesControllerInit', 'SchedulesListInit',
|
||||
'SchedulesList', 'ProjectUpdate', '$state', 'CreateSelect2',
|
||||
'OrganizationList', 'NotificationsListInit', 'ToggleNotification'
|
||||
'OrganizationList', 'NotificationsListInit', 'ToggleNotification', 'i18n'
|
||||
];
|
||||
|
@ -10,10 +10,12 @@
|
||||
* @description This controller's the Users page
|
||||
*/
|
||||
|
||||
import {N_} from "../i18n";
|
||||
|
||||
const user_type_options = [
|
||||
{type: 'normal' , label: 'Normal User' },
|
||||
{type: 'system_auditor' , label: 'System Auditor' },
|
||||
{type: 'system_administrator', label: 'System Administrator' },
|
||||
{type: 'normal' , label: N_('Normal User') },
|
||||
{type: 'system_auditor' , label: N_('System Auditor') },
|
||||
{type: 'system_administrator', label: N_('System Administrator') },
|
||||
];
|
||||
|
||||
function user_type_sync($scope) {
|
||||
@ -34,7 +36,12 @@ function user_type_sync($scope) {
|
||||
export function UsersList($scope, $rootScope, $location, $log, $stateParams,
|
||||
Rest, Alert, UserList, GenerateList, Prompt, SearchInit, PaginateInit,
|
||||
ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit,
|
||||
Wait, $state, Refresh, $filter, rbacUiControlService) {
|
||||
Wait, $state, Refresh, $filter, rbacUiControlService, i18n) {
|
||||
|
||||
for (var i = 0; i < user_type_options.length; i++) {
|
||||
user_type_options[i].label = i18n._(user_type_options[i].label);
|
||||
}
|
||||
|
||||
ClearScope();
|
||||
|
||||
$scope.canAdd = false;
|
||||
@ -142,7 +149,7 @@ UsersList.$inject = ['$scope', '$rootScope', '$location', '$log',
|
||||
'$stateParams', 'Rest', 'Alert', 'UserList', 'generateList', 'Prompt',
|
||||
'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'SelectionInit', 'Wait', '$state',
|
||||
'Refresh', '$filter', 'rbacUiControlService'
|
||||
'Refresh', '$filter', 'rbacUiControlService', 'i18n'
|
||||
];
|
||||
|
||||
|
||||
@ -152,7 +159,11 @@ UsersList.$inject = ['$scope', '$rootScope', '$location', '$log',
|
||||
export function UsersAdd($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
ReturnToCaller, ClearScope, GetBasePath, LookUpInit, OrganizationList,
|
||||
ResetForm, Wait, CreateSelect2, $state) {
|
||||
ResetForm, Wait, CreateSelect2, $state, i18n) {
|
||||
|
||||
for (var i = 0; i < user_type_options.length; i++) {
|
||||
user_type_options[i].label = i18n._(user_type_options[i].label);
|
||||
}
|
||||
|
||||
Rest.setUrl(GetBasePath('users'));
|
||||
Rest.options()
|
||||
@ -268,14 +279,19 @@ export function UsersAdd($scope, $rootScope, $compile, $location, $log,
|
||||
UsersAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log',
|
||||
'$stateParams', 'UserForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
|
||||
'LookUpInit', 'OrganizationList', 'ResetForm', 'Wait', 'CreateSelect2', '$state'
|
||||
'LookUpInit', 'OrganizationList', 'ResetForm', 'Wait', 'CreateSelect2', '$state',
|
||||
'i18n'
|
||||
];
|
||||
|
||||
|
||||
export function UsersEdit($scope, $rootScope, $location,
|
||||
$stateParams, UserForm, GenerateForm, Rest, ProcessErrors,
|
||||
RelatedSearchInit, RelatedPaginateInit, ClearScope,
|
||||
GetBasePath, ResetForm, Wait, CreateSelect2 ,$state) {
|
||||
GetBasePath, ResetForm, Wait, CreateSelect2 ,$state, i18n) {
|
||||
|
||||
for (var i = 0; i < user_type_options.length; i++) {
|
||||
user_type_options[i].label = i18n._(user_type_options[i].label);
|
||||
}
|
||||
|
||||
ClearScope();
|
||||
|
||||
@ -439,5 +455,5 @@ export function UsersEdit($scope, $rootScope, $location,
|
||||
UsersEdit.$inject = ['$scope', '$rootScope', '$location',
|
||||
'$stateParams', 'UserForm', 'GenerateForm', 'Rest', 'ProcessErrors',
|
||||
'RelatedSearchInit', 'RelatedPaginateInit', 'ClearScope', 'GetBasePath',
|
||||
'ResetForm', 'Wait', 'CreateSelect2', '$state'
|
||||
'ResetForm', 'Wait', 'CreateSelect2', '$state', 'i18n'
|
||||
];
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* jshint unused: vars */
|
||||
export default
|
||||
[ 'templateUrl',
|
||||
function(templateUrl) {
|
||||
'i18n',
|
||||
function(templateUrl, i18n) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
@ -35,34 +36,34 @@ export default
|
||||
{
|
||||
url: "/#/home/hosts",
|
||||
number: scope.data.hosts.total,
|
||||
label: "Hosts"
|
||||
label: i18n._("Hosts")
|
||||
},
|
||||
{
|
||||
url: "/#/home/hosts?active-failures=true",
|
||||
number: scope.data.hosts.failed,
|
||||
label: "Failed Hosts",
|
||||
label: i18n._("Failed Hosts"),
|
||||
isFailureCount: true
|
||||
},
|
||||
{
|
||||
url: "/#/inventories",
|
||||
number: scope.data.inventories.total,
|
||||
label: "Inventories",
|
||||
label: i18n._("Inventories"),
|
||||
},
|
||||
{
|
||||
url: "/#/inventories?status=sync-failed",
|
||||
number: scope.data.inventories.inventory_failed,
|
||||
label: "Inventory Sync Failures",
|
||||
label: i18n._("Inventory Sync Failures"),
|
||||
isFailureCount: true
|
||||
},
|
||||
{
|
||||
url: "/#/projects",
|
||||
number: scope.data.projects.total,
|
||||
label: "Projects"
|
||||
label: i18n._("Projects")
|
||||
},
|
||||
{
|
||||
url: "/#/projects?status=failed,canceled",
|
||||
number: scope.data.projects.failed,
|
||||
label: "Project Sync Failures",
|
||||
label: i18n._("Project Sync Failures"),
|
||||
isFailureCount: true
|
||||
}
|
||||
], function(val) { return addFailureToCount(val); });
|
||||
|
@ -1,68 +1,68 @@
|
||||
<div class="DashboardGraphs">
|
||||
<div class="DashboardGraphs-headerSection">
|
||||
<h3 class="DashboardGraphs-headerText">
|
||||
JOB STATUS
|
||||
<translate>JOB STATUS</translate>
|
||||
</h3>
|
||||
<div class="DashboardGraphs-graphToolbar" ng-show="!hostStatusSelected">
|
||||
<div class="DashboardGraphs-filteringDropdowns">
|
||||
<div class="DashboardGraphs-filterLabel">Period</div>
|
||||
<div class="DashboardGraphs-filterLabel" translate>Period</div>
|
||||
<div class="DashboardGraphs-periodDropdown">
|
||||
<a id="period-dropdown" role="button"
|
||||
data-toggle="dropdown"
|
||||
data-target="#"
|
||||
href="/page.html"
|
||||
class="DashboardGraphs-filterDropdownText">
|
||||
Past Month <i class="fa fa-chevron-down DashboardGraphs-filterIcon"></i>
|
||||
<translate>Past Month</translate> <i class="fa fa-chevron-down DashboardGraphs-filterIcon"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu DashboardGraphs-filterDropdownItems
|
||||
DashboardGraphs-filterDropdownItems--period" role="menu" aria-labelledby="period-dropdown">
|
||||
<li>
|
||||
<a class="n" id="day" >Past 24 Hours </a>
|
||||
<a class="n" id="day" translate>Past 24 Hours </a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="n" id="week">Past Week</a>
|
||||
<a class="n" id="week" translate>Past Week</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="n" id="month">Past Month</a>
|
||||
<a class="n" id="month" translate>Past Month</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="DashboardGraphs-filteringDropdowns">
|
||||
<div class="DashboardGraphs-filterLabel">Job Type</div>
|
||||
<div class="DashboardGraphs-filterLabel" translate>Job Type</div>
|
||||
<div class="DashboardGraphs-jobTypeDropdown">
|
||||
|
||||
<a id="type-dropdown" role="button" data-toggle="dropdown" data-target="#" class="DashboardGraphs-filterDropdownText"
|
||||
href="/page.html">
|
||||
All <i class="fa fa-chevron-down DashboardGraphs-filterIcon"></i>
|
||||
<translate>All</translate> <i class="fa fa-chevron-down DashboardGraphs-filterIcon"></i>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu DashboardGraphs-filterDropdownItems
|
||||
DashboardGraphs-filterDropdownItems--jobType" role="menu" aria-labelledby="type-dropdown">
|
||||
<li>
|
||||
<a class="m" id="all">All</a>
|
||||
<a class="m" id="all" translate>All</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="m" id="inv_sync">Inventory Sync</a>
|
||||
<a class="m" id="inv_sync" translate>Inventory Sync</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="m" id="scm_update">SCM Update</a>
|
||||
<a class="m" id="scm_update" translate>SCM Update</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="m" id="playbook_run">Playbook Run</a>
|
||||
<a class="m" id="playbook_run" translate>Playbook Run</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="DashboardGraphs-filteringDropdowns">
|
||||
<div class="DashboardGraphs-filterLabel">View</div>
|
||||
<div class="DashboardGraphs-filterLabel" translate>View</div>
|
||||
<div class="DashboardGraphs-statusDropdown">
|
||||
<a id="status-dropdown" role="button"
|
||||
data-toggle="dropdown"
|
||||
data-target="#"
|
||||
href="/page.html"
|
||||
class="DashboardGraphs-filterDropdownText">
|
||||
All
|
||||
<translate>All</translate>
|
||||
<i class="fa fa-chevron-down
|
||||
DashboardGraphs-filterIcon">
|
||||
</i>
|
||||
@ -71,13 +71,13 @@
|
||||
<ul class="dropdown-menu DashboardGraphs-filterDropdownItems
|
||||
DashboardGraphs-filterDropdownItems--status" role="menu" aria-labelledby="status-dropdown">
|
||||
<li>
|
||||
<a class="o" id="both" >All</a>
|
||||
<a class="o" id="both" translate>All</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="o" id="failed">Successful</a>
|
||||
<a class="o" id="failed" translate>Successful</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="o" id="successful">Failed</a>
|
||||
<a class="o" id="successful" translate>Failed</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -13,10 +13,11 @@
|
||||
'adjustGraphSize',
|
||||
'jobStatusGraphData',
|
||||
'templateUrl',
|
||||
'i18n',
|
||||
JobStatusGraph
|
||||
];
|
||||
|
||||
function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService, templateUrl) {
|
||||
function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustGraphSize, graphDataService, templateUrl, i18n) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
@ -60,10 +61,10 @@ function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustG
|
||||
|
||||
var timeFormat, graphData = [
|
||||
{ "color": "#5CB85C",
|
||||
"key": "SUCCESSFUL",
|
||||
"key": i18n._("SUCCESSFUL"),
|
||||
"values": data.jobs.successful
|
||||
},
|
||||
{ "key" : "FAILED" ,
|
||||
{ "key" : i18n._("FAILED") ,
|
||||
"color" : "#D9534F",
|
||||
"values": data.jobs.failed
|
||||
}
|
||||
@ -102,14 +103,14 @@ function JobStatusGraph($rootScope, $compile , $location, $window, Wait, adjustG
|
||||
job_status_chart.interactiveLayer.tooltip.distance(-1); //distance from interactive line to tooltip
|
||||
|
||||
job_status_chart.xAxis
|
||||
.axisLabel("TIME")//.showMaxMin(true)
|
||||
.axisLabel(i18n._("TIME"))//.showMaxMin(true)
|
||||
.tickFormat(function(d) {
|
||||
var dx = graphData[0].values[d] && graphData[0].values[d].x || 0;
|
||||
return dx ? d3.time.format(timeFormat)(new Date(Number(dx+'000'))) : '';
|
||||
});
|
||||
|
||||
job_status_chart.yAxis //Chart y-axis settings
|
||||
.axisLabel('JOBS')
|
||||
.axisLabel(i18n._('JOBS'))
|
||||
.tickFormat(d3.format('.f'));
|
||||
|
||||
d3.select(element.find('svg')[0])
|
||||
|
@ -5,17 +5,17 @@
|
||||
*************************************************/
|
||||
|
||||
|
||||
export default function(){
|
||||
export default [ 'i18n', function(i18n){
|
||||
return {
|
||||
name: 'hosts',
|
||||
iterator: 'host',
|
||||
selectTitle: 'Add Existing Hosts',
|
||||
selectTitle: i18n._('Add Existing Hosts'),
|
||||
editTitle: 'Hosts',
|
||||
listTitle: 'Hosts',
|
||||
index: false,
|
||||
hover: true,
|
||||
well: true,
|
||||
emptyListText: 'NO HOSTS FOUND',
|
||||
emptyListText: i18n._('NO HOSTS FOUND'),
|
||||
fields: {
|
||||
status: {
|
||||
basePath: 'unified_jobs',
|
||||
@ -91,4 +91,4 @@ export default function(){
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -1,23 +1,23 @@
|
||||
<div class="DashboardList" ng-hide="noJobTemplates">
|
||||
<div class="DashboardList-header">
|
||||
<h3 class="DashboardList-headerText">
|
||||
RECENTLY USED JOB TEMPLATES
|
||||
<translate>RECENTLY USED JOB TEMPLATES</translate>
|
||||
</h3>
|
||||
<a href="/#/job_templates" class="DashboardList-viewAll">
|
||||
VIEW ALL
|
||||
<translate>VIEW ALL</translate>
|
||||
</a>
|
||||
</div>
|
||||
<div class="DashboardList-container">
|
||||
<table class="List-table">
|
||||
<tr class="List-tableHeaderRow">
|
||||
<th class="List-tableHeader DashboardList-tableHeader--name">
|
||||
Name
|
||||
<translate>Name</translate>
|
||||
</th>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--activity">
|
||||
Activity
|
||||
<translate>Activity</translate>
|
||||
</th>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--actions">
|
||||
Actions
|
||||
<translate>Actions</translate>
|
||||
</th>
|
||||
</tr>
|
||||
<tr class="List-tableRow"
|
||||
@ -49,11 +49,11 @@
|
||||
<div class="DashboardList" ng-show="noJobTemplates">
|
||||
<div class="DashboardList-header">
|
||||
<h3 class="DashboardList-headerText">
|
||||
RECENTLY USED JOB TEMPLATES
|
||||
<translate>RECENTLY USED JOB TEMPLATES</translate>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="DashboardList-container">
|
||||
<p class="DashboardList-noJobs">No job templates were recently used.<br />
|
||||
<p class="DashboardList-noJobs" translate>No job templates were recently used.<br />
|
||||
You can create a job template <a href="#/job_templates/add">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,17 +1,17 @@
|
||||
<div class="DashboardList" ng-hide="noJobs">
|
||||
<div class="DashboardList-header">
|
||||
<h3 class="DashboardList-headerText">
|
||||
RECENT JOB RUNS
|
||||
<translate>RECENT JOB RUNS</translate>
|
||||
</h3>
|
||||
<a href="/#/jobs" class="DashboardList-viewAll">
|
||||
VIEW ALL
|
||||
<translate>VIEW ALL</translate>
|
||||
</a>
|
||||
</div>
|
||||
<div class="DashboardList-container">
|
||||
<table class="List-table">
|
||||
<tr>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--name">Name</th>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--time">Time</th>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--name" translate>Name</th>
|
||||
<th class="List-tableHeader DashboardList-tableHeader--time" translate>Time</th>
|
||||
</tr>
|
||||
<tr class="List-tableRow"
|
||||
ng-class-odd="'List-tableRow--oddRow'"
|
||||
@ -39,10 +39,10 @@
|
||||
<div class="DashboardList" ng-show="noJobs">
|
||||
<div class="DashboardList-header">
|
||||
<h3 class="DashboardList-headerText">
|
||||
RECENTLY RUN JOBS
|
||||
<translate>RECENTLY RUN JOBS</translate>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="DashboardList-container">
|
||||
<p class="DashboardList-noJobs">No jobs were recently run.</p>
|
||||
<p class="DashboardList-noJobs" translate>No jobs were recently run.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,14 +12,15 @@
|
||||
|
||||
export default
|
||||
angular.module('CredentialFormDefinition', [])
|
||||
.value('CredentialForm', {
|
||||
.factory('CredentialForm', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'Create Credential', //Legend in add mode
|
||||
addTitle: i18n._('Create Credential'), //Legend in add mode
|
||||
editTitle: '{{ name }}', //Legend in edit mode
|
||||
name: 'credential',
|
||||
forceListeners: true,
|
||||
subFormTitles: {
|
||||
credentialSubForm: 'Type Details',
|
||||
credentialSubForm: i18n._('Type Details'),
|
||||
},
|
||||
|
||||
actions: {
|
||||
@ -28,7 +29,7 @@ export default
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -36,7 +37,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
@ -46,26 +47,26 @@ export default
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngShow: 'canShareCredential',
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
ngClick: 'lookUpOrganization()',
|
||||
awPopOver: "<p>If no organization is given, the credential can only be used by the user that creates the credential. Organization admins and system administrators can assign an organization so that roles for the credential can be assigned to users and teams in that organization.</p>",
|
||||
dataTitle: 'Organization ',
|
||||
awPopOver: i18n._("<p>If no organization is given, the credential can only be used by the user that creates the credential. Organization admins and system administrators can assign an organization so that roles for the credential can be assigned to users and teams in that organization.</p>"),
|
||||
dataTitle: i18n._('Organization') + ' ',
|
||||
dataPlacement: 'bottom',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
kind: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
excludeModal: true,
|
||||
type: 'select',
|
||||
ngOptions: 'kind.label for kind in credential_kind_options track by kind.value', // select as label for value in array 'kind.label for kind in credential_kind_options',
|
||||
ngChange: 'kindChange()',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
awPopOver:'<dl>\n' +
|
||||
awPopOver: i18n._('<dl>\n' +
|
||||
'<dt>Machine</dt>\n' +
|
||||
'<dd>Authentication for remote machine access. This can include SSH keys, usernames, passwords, ' +
|
||||
'and sudo information. Machine credentials are used when submitting jobs to run playbooks against ' +
|
||||
@ -82,15 +83,15 @@ export default
|
||||
'<dd>Usernames, passwords, and access keys for authenticating to the specified cloud or infrastructure ' +
|
||||
'provider. These are used for dynamic inventory sources and for cloud provisioning and deployment ' +
|
||||
'in playbook runs.</dd>\n' +
|
||||
'</dl>\n',
|
||||
dataTitle: 'Type',
|
||||
'</dl>\n'),
|
||||
dataTitle: i18n._('Type'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
hasSubForm: true,
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
access_key: {
|
||||
label: 'Access Key',
|
||||
label: i18n._('Access Key'),
|
||||
type: 'text',
|
||||
ngShow: "kind.value == 'aws'",
|
||||
awRequiredWhen: {
|
||||
@ -103,7 +104,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
secret_key: {
|
||||
label: 'Secret Key',
|
||||
label: i18n._('Secret Key'),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'aws'",
|
||||
ngDisabled: "secret_key_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
|
||||
@ -118,14 +119,14 @@ export default
|
||||
subForm: 'credentialSubForm'
|
||||
},
|
||||
security_token: {
|
||||
label: 'STS Token',
|
||||
label: i18n._('STS Token'),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'aws'",
|
||||
autocomplete: false,
|
||||
apiField: 'security_token',
|
||||
awPopOver: "<div>Security Token Service (STS) is a web service that enables you to request temporary, limited-privilege credentials for AWS Identity and Access Management (IAM) users.</div><div style='padding-top: 10px'>To learn more about the IAM STS Token, refer to the <a href='http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html' target='_blank'>Amazon documentation</a>.</div>",
|
||||
awPopOver: i18n._("<div>Security Token Service (STS) is a web service that enables you to request temporary, limited-privilege credentials for AWS Identity and Access Management (IAM) users.</div><div style='padding-top: 10px'>To learn more about the IAM STS Token, refer to the <a href='http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html' target='_blank'>Amazon documentation</a>.</div>"),
|
||||
hasShowInputButton: true,
|
||||
dataTitle: 'STS Token',
|
||||
dataTitle: i18n._('STS Token'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subForm: 'credentialSubForm',
|
||||
@ -136,8 +137,8 @@ export default
|
||||
type: 'text',
|
||||
ngShow: "kind.value == 'vmware' || kind.value == 'openstack' || kind.value === 'satellite6' || kind.value === 'cloudforms'",
|
||||
awPopOverWatch: "hostPopOver",
|
||||
awPopOver: "set in helpers/credentials",
|
||||
dataTitle: 'Host',
|
||||
awPopOver: i18n._("set in helpers/credentials"),
|
||||
dataTitle: i18n._('Host'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
autocomplete: false,
|
||||
@ -149,7 +150,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
"subscription": {
|
||||
label: "Subscription ID",
|
||||
label: i18n._("Subscription ID"),
|
||||
type: 'text',
|
||||
ngShow: "kind.value == 'azure' || kind.value == 'azure_rm'",
|
||||
awRequiredWhen: {
|
||||
@ -159,8 +160,8 @@ export default
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
autocomplete: false,
|
||||
awPopOver: '<p>Subscription ID is an Azure construct, which is mapped to a username.</p>',
|
||||
dataTitle: 'Subscription ID',
|
||||
awPopOver: i18n._('<p>Subscription ID is an Azure construct, which is mapped to a username.</p>'),
|
||||
dataTitle: i18n._('Subscription ID'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subForm: 'credentialSubForm',
|
||||
@ -188,15 +189,15 @@ export default
|
||||
init: false
|
||||
},
|
||||
autocomplete: false,
|
||||
awPopOver: '<p>The email address assigned to the Google Compute Engine <b><i>service account.</b></i></p>',
|
||||
dataTitle: 'Email',
|
||||
awPopOver: i18n._('<p>The email address assigned to the Google Compute Engine <b><i>service account.</b></i></p>'),
|
||||
dataTitle: i18n._('Email'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subForm: 'credentialSubForm',
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
"api_key": {
|
||||
label: 'API Key',
|
||||
label: i18n._('API Key'),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'rax'",
|
||||
awRequiredWhen: {
|
||||
@ -224,7 +225,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
"ssh_password": {
|
||||
label: 'Password',
|
||||
label: i18n._('Password'),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'ssh'",
|
||||
ngDisabled: "ssh_password_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
|
||||
@ -232,7 +233,7 @@ export default
|
||||
editRequired: false,
|
||||
subCheckbox: {
|
||||
variable: 'ssh_password_ask',
|
||||
text: 'Ask at runtime?',
|
||||
text: i18n._('Ask at runtime?'),
|
||||
ngChange: 'ask(\'ssh_password\', \'undefined\')'
|
||||
},
|
||||
hasShowInputButton: true,
|
||||
@ -254,16 +255,16 @@ export default
|
||||
editRequired: false,
|
||||
awDropFile: true,
|
||||
rows: 10,
|
||||
awPopOver: "SSH key description",
|
||||
awPopOver: i18n._("SSH key description"),
|
||||
awPopOverWatch: "key_description",
|
||||
dataTitle: 'Private Key',
|
||||
dataTitle: i18n._('Private Key'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subForm: "credentialSubForm",
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
"ssh_key_unlock": {
|
||||
label: 'Private Key Passphrase',
|
||||
label: i18n._('Private Key Passphrase'),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'ssh' || kind.value == 'scm'",
|
||||
addRequired: false,
|
||||
@ -272,7 +273,7 @@ export default
|
||||
subCheckbox: {
|
||||
variable: 'ssh_key_unlock_ask',
|
||||
ngShow: "kind.value == 'ssh'",
|
||||
text: 'Ask at runtime?',
|
||||
text: i18n._('Ask at runtime?'),
|
||||
ngChange: 'ask(\'ssh_key_unlock\', \'undefined\')',
|
||||
ngDisabled: "keyEntered === false"
|
||||
},
|
||||
@ -280,15 +281,15 @@ export default
|
||||
subForm: 'credentialSubForm'
|
||||
},
|
||||
"become_method": {
|
||||
label: "Privilege Escalation",
|
||||
label: i18n._("Privilege Escalation"),
|
||||
// hintText: "If your playbooks use privilege escalation (\"sudo: true\", \"su: true\", etc), you can specify the username to become, and the password to use here.",
|
||||
type: 'select',
|
||||
ngShow: "kind.value == 'ssh'",
|
||||
dataTitle: 'Privilege Escalation',
|
||||
dataTitle: i18n._('Privilege Escalation'),
|
||||
ngOptions: 'become.label for become in become_options track by become.value',
|
||||
awPopOver: "<p>Specify a method for 'become' operations. " +
|
||||
awPopOver: i18n._("<p>Specify a method for 'become' operations. " +
|
||||
"This is equivalent to specifying the <code>--become-method=BECOME_METHOD</code> parameter, where <code>BECOME_METHOD</code> could be "+
|
||||
"<code>sudo | su | pbrun | pfexec | runas</code> <br>(defaults to <code>sudo</code>)</p>",
|
||||
"<code>sudo | su | pbrun | pfexec | runas</code> <br>(defaults to <code>sudo</code>)</p>"),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subForm: 'credentialSubForm',
|
||||
@ -313,7 +314,7 @@ export default
|
||||
editRequired: false,
|
||||
subCheckbox: {
|
||||
variable: 'become_password_ask',
|
||||
text: 'Ask at runtime?',
|
||||
text: i18n._('Ask at runtime?'),
|
||||
ngChange: 'ask(\'become_password\', \'undefined\')'
|
||||
},
|
||||
hasShowInputButton: true,
|
||||
@ -322,7 +323,7 @@ export default
|
||||
},
|
||||
client:{
|
||||
type: 'text',
|
||||
label: 'Client ID',
|
||||
label: i18n._('Client ID'),
|
||||
subForm: 'credentialSubForm',
|
||||
ngShow: "kind.value === 'azure_rm'",
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
@ -331,20 +332,20 @@ export default
|
||||
type: 'sensitive',
|
||||
hasShowInputButton: true,
|
||||
autocomplete: false,
|
||||
label: 'Client Secret',
|
||||
label: i18n._('Client Secret'),
|
||||
subForm: 'credentialSubForm',
|
||||
ngShow: "kind.value === 'azure_rm'",
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
tenant: {
|
||||
type: 'text',
|
||||
label: 'Tenant ID',
|
||||
label: i18n._('Tenant ID'),
|
||||
subForm: 'credentialSubForm',
|
||||
ngShow: "kind.value === 'azure_rm'",
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
authorize: {
|
||||
label: 'Authorize',
|
||||
label: i18n._('Authorize'),
|
||||
type: 'checkbox',
|
||||
ngChange: "toggleCallback('host_config_key')",
|
||||
subForm: 'credentialSubForm',
|
||||
@ -352,7 +353,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
authorize_password: {
|
||||
label: 'Authorize Password',
|
||||
label: i18n._('Authorize Password'),
|
||||
type: 'sensitive',
|
||||
hasShowInputButton: true,
|
||||
autocomplete: false,
|
||||
@ -365,8 +366,8 @@ export default
|
||||
type: 'text',
|
||||
ngShow: "kind.value == 'gce' || kind.value == 'openstack'",
|
||||
awPopOverWatch: "projectPopOver",
|
||||
awPopOver: "set in helpers/credentials",
|
||||
dataTitle: 'Project Name',
|
||||
awPopOver: i18n._("set in helpers/credentials"),
|
||||
dataTitle: i18n._('Project Name'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
addRequired: false,
|
||||
@ -382,12 +383,12 @@ export default
|
||||
labelBind: 'domainLabel',
|
||||
type: 'text',
|
||||
ngShow: "kind.value == 'openstack'",
|
||||
awPopOver: "<p>OpenStack domains define administrative " +
|
||||
awPopOver: i18n._("<p>OpenStack domains define administrative " +
|
||||
"boundaries. It is only needed for Keystone v3 authentication URLs. " +
|
||||
"Common scenarios include:<ul><li><b>v2 URLs</b> - leave blank</li>" +
|
||||
"<li><b>v3 default</b> - set to 'default'</br></li>" +
|
||||
"<li><b>v3 multi-domain</b> - your domain name</p></li></ul></p>",
|
||||
dataTitle: 'Domain Name',
|
||||
"<li><b>v3 multi-domain</b> - your domain name</p></li></ul></p>"),
|
||||
dataTitle: i18n._('Domain Name'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
addRequired: false,
|
||||
@ -396,7 +397,7 @@ export default
|
||||
ngDisabled: '!(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
"vault_password": {
|
||||
label: "Vault Password",
|
||||
label: i18n._("Vault Password"),
|
||||
type: 'sensitive',
|
||||
ngShow: "kind.value == 'ssh'",
|
||||
ngDisabled: "vault_password_ask || !(credential_obj.summary_fields.user_capabilities.edit || canAdd)",
|
||||
@ -404,7 +405,7 @@ export default
|
||||
editRequired: false,
|
||||
subCheckbox: {
|
||||
variable: 'vault_password_ask',
|
||||
text: 'Ask at runtime?',
|
||||
text: i18n._('Ask at runtime?'),
|
||||
ngChange: 'ask(\'vault_password\', \'undefined\')'
|
||||
},
|
||||
hasShowInputButton: true,
|
||||
@ -438,7 +439,7 @@ export default
|
||||
dataPlacement: 'top',
|
||||
basePath: 'credentials/:id/access_list/',
|
||||
type: 'collection',
|
||||
title: 'Permissions',
|
||||
title: i18n._('Permissions'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -447,9 +448,9 @@ export default
|
||||
add: {
|
||||
ngClick: "addPermission",
|
||||
label: 'Add',
|
||||
awToolTip: 'Add a permission',
|
||||
awToolTip: i18n._('Add a permission'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
@ -457,19 +458,19 @@ export default
|
||||
fields: {
|
||||
username: {
|
||||
key: true,
|
||||
label: 'User',
|
||||
label: i18n._('User'),
|
||||
linkBase: 'users',
|
||||
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
type: 'role',
|
||||
noSort: true,
|
||||
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
|
||||
searchable: false
|
||||
},
|
||||
team_roles: {
|
||||
label: 'Team Roles',
|
||||
label: i18n._('Team Roles'),
|
||||
type: 'team_roles',
|
||||
noSort: true,
|
||||
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
|
||||
@ -487,4 +488,4 @@ export default
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -12,9 +12,10 @@
|
||||
|
||||
export default
|
||||
angular.module('InventoryFormDefinition', ['ScanJobsListDefinition'])
|
||||
.value('InventoryFormObject', {
|
||||
.factory('InventoryFormObject', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Inventory',
|
||||
addTitle: i18n._('New Inventory'),
|
||||
editTitle: '{{ inventory_name }}',
|
||||
name: 'inventory',
|
||||
tabs: true,
|
||||
@ -22,7 +23,7 @@ export default
|
||||
fields: {
|
||||
inventory_name: {
|
||||
realName: 'name',
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -31,14 +32,14 @@ export default
|
||||
},
|
||||
inventory_description: {
|
||||
realName: 'description',
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -50,21 +51,21 @@ export default
|
||||
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
variables: {
|
||||
label: 'Variables',
|
||||
label: i18n._('Variables'),
|
||||
type: 'textarea',
|
||||
class: 'Form-formGroup--fullWidth',
|
||||
addRequired: false,
|
||||
editRequird: false,
|
||||
rows: 6,
|
||||
"default": "---",
|
||||
awPopOver: "<p>Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||
awPopOver: i18n._("<p>Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two.</p>" +
|
||||
"JSON:<br />\n" +
|
||||
"<blockquote>{<br /> \"somevar\": \"somevalue\",<br /> \"password\": \"magic\"<br /> }</blockquote>\n" +
|
||||
"YAML:<br />\n" +
|
||||
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n" +
|
||||
'<p>View JSON examples at <a href="http://www.json.org" target="_blank">www.json.org</a></p>' +
|
||||
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>',
|
||||
dataTitle: 'Inventory Variables',
|
||||
'<p>View YAML examples at <a href="http://docs.ansible.com/YAMLSyntax.html" target="_blank">docs.ansible.com</a></p>'),
|
||||
dataTitle: i18n._('Inventory Variables'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: 'body',
|
||||
ngDisabled: '!(inventory_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
|
||||
@ -89,11 +90,11 @@ export default
|
||||
|
||||
related: {
|
||||
permissions: {
|
||||
awToolTip: 'Please save before assigning permissions',
|
||||
awToolTip: i18n._('Please save before assigning permissions'),
|
||||
dataPlacement: 'top',
|
||||
basePath: 'inventories/:id/access_list/',
|
||||
type: 'collection',
|
||||
title: 'Permissions',
|
||||
title: i18n._('Permissions'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -102,9 +103,9 @@ export default
|
||||
add: {
|
||||
ngClick: "addPermission",
|
||||
label: 'Add',
|
||||
awToolTip: 'Add a permission',
|
||||
awToolTip: i18n._('Add a permission'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: '(inventory_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
@ -112,19 +113,19 @@ export default
|
||||
fields: {
|
||||
username: {
|
||||
key: true,
|
||||
label: 'User',
|
||||
label: i18n._('User'),
|
||||
linkBase: 'users',
|
||||
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
type: 'role',
|
||||
noSort: true,
|
||||
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
|
||||
noSearch: true
|
||||
},
|
||||
team_roles: {
|
||||
label: 'Team Roles',
|
||||
label: i18n._('Team Roles'),
|
||||
type: 'team_roles',
|
||||
noSort: true,
|
||||
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
|
||||
@ -143,7 +144,7 @@ export default
|
||||
};
|
||||
}
|
||||
|
||||
})
|
||||
};}])
|
||||
.factory('InventoryForm', ['InventoryFormObject', 'ScanJobsList',
|
||||
function(InventoryFormObject, ScanJobsList) {
|
||||
return function() {
|
||||
|
@ -10,12 +10,14 @@
|
||||
* @description This form is for adding/editing a Job Template
|
||||
*/
|
||||
|
||||
|
||||
export default
|
||||
angular.module('JobTemplateFormDefinition', [ 'CompletedJobsDefinition'])
|
||||
|
||||
.value ('JobTemplateFormObject', {
|
||||
.factory('JobTemplateFormObject', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Job Template',
|
||||
addTitle: i18n._('New Job Template'),
|
||||
editTitle: '{{ name }}',
|
||||
name: 'job_templates',
|
||||
base: 'job_templates',
|
||||
@ -23,7 +25,7 @@ export default
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -31,7 +33,7 @@ export default
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
@ -39,7 +41,7 @@ export default
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
job_type: {
|
||||
label: 'Job Type',
|
||||
label: i18n._('Job Type'),
|
||||
type: 'select',
|
||||
ngOptions: 'type.label for type in job_type_options track by type.value',
|
||||
ngChange: 'jobTypeChange()',
|
||||
@ -47,22 +49,22 @@ export default
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 1,
|
||||
awPopOver: "<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks " +
|
||||
awPopOver: i18n._("<p>When this template is submitted as a job, setting the type to <em>run</em> will execute the playbook, running tasks " +
|
||||
" on the selected hosts.</p> <p>Setting the type to <em>check</em> will not execute the playbook. Instead, <code>ansible</code> will check playbook " +
|
||||
" syntax, test environment setup and report problems.</p> <p>Setting the type to <em>scan</em> will execute the playbook and store any " +
|
||||
" scanned facts for use with Tower's System Tracking feature.</p>",
|
||||
dataTitle: 'Job Type',
|
||||
" scanned facts for use with Tower's System Tracking feature.</p>"),
|
||||
dataTitle: i18n._('Job Type'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_job_type_on_launch',
|
||||
ngShow: "!job_type.value || job_type.value !== 'scan'",
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
inventory: {
|
||||
label: 'Inventory',
|
||||
label: i18n._('Inventory'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'inventory',
|
||||
sourceField: 'name',
|
||||
@ -73,19 +75,19 @@ export default
|
||||
},
|
||||
requiredErrorMsg: "Please select an Inventory or check the Prompt on launch option.",
|
||||
column: 1,
|
||||
awPopOver: "<p>Select the inventory containing the hosts you want this job to manage.</p>",
|
||||
dataTitle: 'Inventory',
|
||||
awPopOver: i18n._("<p>Select the inventory containing the hosts you want this job to manage.</p>"),
|
||||
dataTitle: i18n._('Inventory'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_inventory_on_launch',
|
||||
ngShow: "!job_type.value || job_type.value !== 'scan'",
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
project: {
|
||||
label: 'Project',
|
||||
label: i18n._('Project'),
|
||||
labelAction: {
|
||||
label: 'RESET',
|
||||
ngClick: 'resetProjectToDefault()',
|
||||
@ -100,14 +102,14 @@ export default
|
||||
init: "true"
|
||||
},
|
||||
column: 1,
|
||||
awPopOver: "<p>Select the project containing the playbook you want this job to execute.</p>",
|
||||
dataTitle: 'Project',
|
||||
awPopOver: i18n._("<p>Select the project containing the playbook you want this job to execute.</p>"),
|
||||
dataTitle: i18n._('Project'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
playbook: {
|
||||
label: 'Playbook',
|
||||
label: i18n._('Playbook'),
|
||||
type:'select',
|
||||
ngOptions: 'book for book in playbook_options track by book',
|
||||
ngDisabled: "(job_type.value === 'scan' && project_name === 'Default') || !(job_template_obj.summary_fields.user_capabilities.edit || canAdd)",
|
||||
@ -117,14 +119,14 @@ export default
|
||||
init: "true"
|
||||
},
|
||||
column: 1,
|
||||
awPopOver: "<p>Select the playbook to be executed by this job.</p>",
|
||||
dataTitle: 'Playbook',
|
||||
awPopOver: i18n._("<p>Select the playbook to be executed by this job.</p>"),
|
||||
dataTitle: i18n._('Playbook'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
includePlaybookNotFoundError: true
|
||||
},
|
||||
credential: {
|
||||
label: 'Machine Credential',
|
||||
label: i18n._('Machine Credential'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'credential',
|
||||
sourceField: 'name',
|
||||
@ -135,19 +137,19 @@ export default
|
||||
},
|
||||
requiredErrorMsg: "Please select a Machine Credential or check the Prompt on launch option.",
|
||||
column: 1,
|
||||
awPopOver: "<p>Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing " +
|
||||
" the username and SSH key or password that Ansible will need to log into the remote hosts.</p>",
|
||||
dataTitle: 'Credential',
|
||||
awPopOver: i18n._("<p>Select the credential you want the job to use when accessing the remote hosts. Choose the credential containing " +
|
||||
" the username and SSH key or password that Ansible will need to log into the remote hosts.</p>"),
|
||||
dataTitle: i18n._('Credential'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_credential_on_launch',
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
cloud_credential: {
|
||||
label: 'Cloud Credential',
|
||||
label: i18n._('Cloud Credential'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'cloud_credential',
|
||||
sourceField: 'name',
|
||||
@ -155,15 +157,15 @@ export default
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
column: 1,
|
||||
awPopOver: "<p>Selecting an optional cloud credential in the job template will pass along the access credentials to the " +
|
||||
"running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.</p>",
|
||||
dataTitle: 'Cloud Credential',
|
||||
awPopOver: i18n._("<p>Selecting an optional cloud credential in the job template will pass along the access credentials to the " +
|
||||
"running playbook, allowing provisioning into the cloud without manually passing parameters to the included modules.</p>"),
|
||||
dataTitle: i18n._('Cloud Credential'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
network_credential: {
|
||||
label: 'Network Credential',
|
||||
label: i18n._('Network Credential'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'network_credential',
|
||||
sourceField: 'name',
|
||||
@ -171,14 +173,14 @@ export default
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
column: 1,
|
||||
awPopOver: "<p>Network credentials are used by Ansible networking modules to connect to and manage networking devices.</p>",
|
||||
dataTitle: 'Network Credential',
|
||||
awPopOver: i18n._("<p>Network credentials are used by Ansible networking modules to connect to and manage networking devices.</p>"),
|
||||
dataTitle: i18n._('Network Credential'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
forks: {
|
||||
label: 'Forks',
|
||||
label: i18n._('Forks'),
|
||||
id: 'forks-number',
|
||||
type: 'number',
|
||||
integer: true,
|
||||
@ -189,121 +191,121 @@ export default
|
||||
editRequired: false,
|
||||
'class': "input-small",
|
||||
column: 1,
|
||||
awPopOver: '<p>The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies ' +
|
||||
awPopOver: i18n._('<p>The number of parallel or simultaneous processes to use while executing the playbook. 0 signifies ' +
|
||||
'the default value from the <a id="ansible_forks_docs" href=\"http://docs.ansible.com/intro_configuration.html#the-ansible-configuration-file\" ' +
|
||||
' target=\"_blank\">ansible configuration file</a>.</p>',
|
||||
dataTitle: 'Forks',
|
||||
' target=\"_blank\">ansible configuration file</a>.</p>'),
|
||||
dataTitle: i18n._('Forks'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
|
||||
},
|
||||
limit: {
|
||||
label: 'Limit',
|
||||
label: i18n._('Limit'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
column: 1,
|
||||
awPopOver: "<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. " +
|
||||
awPopOver: i18n._("<p>Provide a host pattern to further constrain the list of hosts that will be managed or affected by the playbook. " +
|
||||
"Multiple patterns can be separated by ; : or ,</p><p>For more information and examples see " +
|
||||
"<a href=\"http://docs.ansible.com/intro_patterns.html\" target=\"_blank\">the Patterns topic at docs.ansible.com</a>.</p>",
|
||||
dataTitle: 'Limit',
|
||||
"<a href=\"http://docs.ansible.com/intro_patterns.html\" target=\"_blank\">the Patterns topic at docs.ansible.com</a>.</p>"),
|
||||
dataTitle: i18n._('Limit'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_limit_on_launch',
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
verbosity: {
|
||||
label: 'Verbosity',
|
||||
label: i18n._('Verbosity'),
|
||||
type: 'select',
|
||||
ngOptions: 'v.label for v in verbosity_options track by v.value',
|
||||
"default": 1,
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
column: 1,
|
||||
awPopOver: "<p>Control the level of output ansible will produce as the playbook executes.</p>",
|
||||
dataTitle: 'Verbosity',
|
||||
awPopOver: i18n._("<p>Control the level of output ansible will produce as the playbook executes.</p>"),
|
||||
dataTitle: i18n._('Verbosity'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
job_tags: {
|
||||
label: 'Job Tags',
|
||||
label: i18n._('Job Tags'),
|
||||
type: 'textarea',
|
||||
rows: 5,
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
'elementClass': 'Form-textInput',
|
||||
column: 2,
|
||||
awPopOver: "<p>Provide a comma separated list of tags.</p>\n" +
|
||||
awPopOver: i18n._("<p>Provide a comma separated list of tags.</p>\n" +
|
||||
"<p>Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.</p>" +
|
||||
"<p>Consult the Ansible documentation for further details on the usage of tags.</p>",
|
||||
dataTitle: "Job Tags",
|
||||
"<p>Consult the Ansible documentation for further details on the usage of tags.</p>"),
|
||||
dataTitle: i18n._("Job Tags"),
|
||||
dataPlacement: "right",
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_tags_on_launch',
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
skip_tags: {
|
||||
label: 'Skip Tags',
|
||||
label: i18n._('Skip Tags'),
|
||||
type: 'textarea',
|
||||
rows: 5,
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
'elementClass': 'Form-textInput',
|
||||
column: 2,
|
||||
awPopOver: "<p>Provide a comma separated list of tags.</p>\n" +
|
||||
awPopOver: i18n._("<p>Provide a comma separated list of tags.</p>\n" +
|
||||
"<p>Skip tags are useful when you have a large playbook, and you want to skip specific parts of a play or task.</p>" +
|
||||
"<p>Consult the Ansible documentation for further details on the usage of tags.</p>",
|
||||
dataTitle: "Skip Tags",
|
||||
"<p>Consult the Ansible documentation for further details on the usage of tags.</p>"),
|
||||
dataTitle: i18n._("Skip Tags"),
|
||||
dataPlacement: "right",
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_skip_tags_on_launch',
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
checkbox_group: {
|
||||
label: 'Options',
|
||||
label: i18n._('Options'),
|
||||
type: 'checkbox_group',
|
||||
fields: [{
|
||||
name: 'become_enabled',
|
||||
label: 'Enable Privilege Escalation',
|
||||
label: i18n._('Enable Privilege Escalation'),
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequird: false,
|
||||
column: 2,
|
||||
awPopOver: "<p>If enabled, run this playbook as an administrator. This is the equivalent of passing the <code>--become</code> option to the <code>ansible-playbook</code> command. </p>",
|
||||
awPopOver: i18n._("<p>If enabled, run this playbook as an administrator. This is the equivalent of passing the <code>--become</code> option to the <code>ansible-playbook</code> command. </p>"),
|
||||
dataPlacement: 'right',
|
||||
dataTitle: 'Become Privilege Escalation',
|
||||
dataTitle: i18n._('Become Privilege Escalation'),
|
||||
dataContainer: "body",
|
||||
labelClass: 'stack-inline',
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}, {
|
||||
name: 'allow_callbacks',
|
||||
label: 'Allow Provisioning Callbacks',
|
||||
label: i18n._('Allow Provisioning Callbacks'),
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequird: false,
|
||||
ngChange: "toggleCallback('host_config_key')",
|
||||
column: 2,
|
||||
awPopOver: "<p>Enables creation of a provisioning callback URL. Using the URL a host can contact Tower and request a configuration update " +
|
||||
"using this job template.</p>",
|
||||
awPopOver: i18n._("<p>Enables creation of a provisioning callback URL. Using the URL a host can contact Tower and request a configuration update " +
|
||||
"using this job template.</p>"),
|
||||
dataPlacement: 'right',
|
||||
dataTitle: 'Allow Provisioning Callbacks',
|
||||
dataTitle: i18n._('Allow Provisioning Callbacks'),
|
||||
dataContainer: "body",
|
||||
labelClass: 'stack-inline',
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}]
|
||||
},
|
||||
callback_url: {
|
||||
label: 'Provisioning Callback URL',
|
||||
label: i18n._('Provisioning Callback URL'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
@ -313,12 +315,12 @@ export default
|
||||
awPopOver: "callback_help",
|
||||
awPopOverWatch: "callback_help",
|
||||
dataPlacement: 'top',
|
||||
dataTitle: 'Provisioning Callback URL',
|
||||
dataTitle: i18n._('Provisioning Callback URL'),
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
host_config_key: {
|
||||
label: 'Host Config Key',
|
||||
label: i18n._('Host Config Key'),
|
||||
type: 'text',
|
||||
ngShow: "allow_callbacks && allow_callbacks !== 'false'",
|
||||
ngChange: "configKeyChange()",
|
||||
@ -327,26 +329,26 @@ export default
|
||||
awPopOver: "callback_help",
|
||||
awPopOverWatch: "callback_help",
|
||||
dataPlacement: 'right',
|
||||
dataTitle: "Host Config Key",
|
||||
dataTitle: i18n._("Host Config Key"),
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
labels: {
|
||||
label: 'Labels',
|
||||
label: i18n._('Labels'),
|
||||
type: 'select',
|
||||
class: 'Form-formGroup--fullWidth',
|
||||
ngOptions: 'label.label for label in labelOptions track by label.value',
|
||||
multiSelect: true,
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
dataTitle: 'Labels',
|
||||
dataTitle: i18n._('Labels'),
|
||||
dataPlacement: 'right',
|
||||
awPopOver: "<p>Optional labels that describe this job template, such as 'dev' or 'test'. Labels can be used to group and filter job templates and completed jobs in the Tower display.</p>",
|
||||
awPopOver: i18n._("<p>Optional labels that describe this job template, such as 'dev' or 'test'. Labels can be used to group and filter job templates and completed jobs in the Tower display.</p>"),
|
||||
dataContainer: 'body',
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
variables: {
|
||||
label: 'Extra Variables',
|
||||
label: i18n._('Extra Variables'),
|
||||
type: 'textarea',
|
||||
class: 'Form-textAreaLabel Form-formGroup--fullWidth',
|
||||
rows: 6,
|
||||
@ -354,18 +356,18 @@ export default
|
||||
editRequired: false,
|
||||
"default": "---",
|
||||
column: 2,
|
||||
awPopOver: "<p>Pass extra command line variables to the playbook. This is the <code>-e</code> or <code>--extra-vars</code> command line parameter " +
|
||||
awPopOver: i18n._("<p>Pass extra command line variables to the playbook. This is the <code>-e</code> or <code>--extra-vars</code> command line parameter " +
|
||||
"for <code>ansible-playbook</code>. Provide key/value pairs using either YAML or JSON.</p>" +
|
||||
"JSON:<br />\n" +
|
||||
"<blockquote>{<br /> \"somevar\": \"somevalue\",<br /> \"password\": \"magic\"<br /> }</blockquote>\n" +
|
||||
"YAML:<br />\n" +
|
||||
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n",
|
||||
dataTitle: 'Extra Variables',
|
||||
"<blockquote>---<br />somevar: somevalue<br />password: magic<br /></blockquote>\n"),
|
||||
dataTitle: i18n._('Extra Variables'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
subCheckbox: {
|
||||
variable: 'ask_variables_on_launch',
|
||||
text: 'Prompt on launch'
|
||||
text: i18n._('Prompt on launch')
|
||||
},
|
||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
|
||||
}
|
||||
@ -409,11 +411,11 @@ export default
|
||||
include: "CompletedJobsList"
|
||||
},
|
||||
permissions: {
|
||||
awToolTip: 'Please save before assigning permissions',
|
||||
awToolTip: i18n._('Please save before assigning permissions'),
|
||||
dataPlacement: 'top',
|
||||
basePath: 'job_templates/:id/access_list/',
|
||||
type: 'collection',
|
||||
title: 'Permissions',
|
||||
title: i18n._('Permissions'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -473,7 +475,7 @@ export default
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
};}])
|
||||
|
||||
.factory('JobTemplateForm', ['JobTemplateFormObject', 'NotificationsList', 'CompletedJobsList',
|
||||
function(JobTemplateFormObject, NotificationsList, CompletedJobsList) {
|
||||
|
@ -12,16 +12,17 @@
|
||||
|
||||
export default
|
||||
angular.module('OrganizationFormDefinition', [])
|
||||
.value('OrganizationFormObject', {
|
||||
.factory('OrganizationFormObject', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Organization', //Title in add mode
|
||||
addTitle: i18n._('New Organization'), //Title in add mode
|
||||
editTitle: '{{ name }}', //Title in edit mode
|
||||
name: 'organization', //entity or model name in singular form
|
||||
tabs: true,
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -29,7 +30,7 @@ export default
|
||||
ngDisabled: '!(organization_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
@ -56,10 +57,10 @@ export default
|
||||
related: {
|
||||
permissions: {
|
||||
basePath: 'organizations/:id/access_list/',
|
||||
awToolTip: 'Please save before assigning permissions',
|
||||
awToolTip: i18n._('Please save before assigning permissions'),
|
||||
dataPlacement: 'top',
|
||||
type: 'collection',
|
||||
title: 'Permissions',
|
||||
title: i18n._('Permissions'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -68,9 +69,9 @@ export default
|
||||
add: {
|
||||
ngClick: "addPermission",
|
||||
label: 'Add',
|
||||
awToolTip: 'Add a permission',
|
||||
awToolTip: i18n._('Add a permission'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: '(organization_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
@ -78,19 +79,19 @@ export default
|
||||
fields: {
|
||||
username: {
|
||||
key: true,
|
||||
label: 'User',
|
||||
label: i18n._('User'),
|
||||
linkBase: 'users',
|
||||
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
type: 'role',
|
||||
noSort: true,
|
||||
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
|
||||
searchable: false
|
||||
},
|
||||
team_roles: {
|
||||
label: 'Team Roles',
|
||||
label: i18n._('Team Roles'),
|
||||
type: 'team_roles',
|
||||
noSort: true,
|
||||
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4',
|
||||
@ -116,7 +117,7 @@ export default
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
};}])
|
||||
|
||||
.factory('OrganizationForm', ['OrganizationFormObject', 'NotificationsList',
|
||||
function(OrganizationFormObject, NotificationsList) {
|
||||
|
@ -12,21 +12,22 @@
|
||||
|
||||
export default
|
||||
angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
.value('ProjectsFormObject', {
|
||||
.factory('ProjectsFormObject', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Project',
|
||||
addTitle: i18n._('New Project'),
|
||||
editTitle: '{{ name }}',
|
||||
name: 'project',
|
||||
forceListeners: true,
|
||||
tabs: true,
|
||||
subFormTitles: {
|
||||
sourceSubForm: 'Source Details',
|
||||
sourceSubForm: i18n._('Source Details'),
|
||||
},
|
||||
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -34,14 +35,14 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -50,13 +51,13 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
reqExpression: "organizationrequired",
|
||||
init: "true"
|
||||
},
|
||||
dataTitle: 'Organization',
|
||||
dataTitle: i18n._('Organization'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
scm_type: {
|
||||
label: 'SCM Type',
|
||||
label: i18n._('SCM Type'),
|
||||
type: 'select',
|
||||
class: 'Form-dropDown--scmType',
|
||||
ngOptions: 'type.label for type in scm_type_options track by type.value',
|
||||
@ -76,21 +77,21 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
closeable: false
|
||||
},
|
||||
base_dir: {
|
||||
label: 'Project Base Path',
|
||||
label: i18n._('Project Base Path'),
|
||||
type: 'text',
|
||||
class: 'Form-textUneditable',
|
||||
showonly: true,
|
||||
ngShow: "scm_type.value == 'manual' " ,
|
||||
awPopOver: '<p>Base path used for locating playbooks. Directories found inside this path will be listed in the playbook directory drop-down. ' +
|
||||
awPopOver: i18n._('<p>Base path used for locating playbooks. Directories found inside this path will be listed in the playbook directory drop-down. ' +
|
||||
'Together the base path and selected playbook directory provide the full path used to locate playbooks.</p>' +
|
||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
||||
dataTitle: 'Project Base Path',
|
||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>'),
|
||||
dataTitle: i18n._('Project Base Path'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
local_path: {
|
||||
label: 'Playbook Directory',
|
||||
label: i18n._('Playbook Directory'),
|
||||
type: 'select',
|
||||
id: 'local-path-select',
|
||||
ngOptions: 'path.label for path in project_local_paths',
|
||||
@ -99,10 +100,10 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
init: false
|
||||
},
|
||||
ngShow: "scm_type.value == 'manual' && !showMissingPlaybooksAlert",
|
||||
awPopOver: '<p>Select from the list of directories found in the base path.' +
|
||||
awPopOver: i18n._('<p>Select from the list of directories found in the base path.' +
|
||||
'Together the base path and the playbook directory provide the full path used to locate playbooks.</p>' +
|
||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>',
|
||||
dataTitle: 'Project Path',
|
||||
'<p>Use PROJECTS_ROOT in your environment settings file to determine the base path value.</p>'),
|
||||
dataTitle: i18n._('Project Path'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
@ -134,7 +135,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
credential: {
|
||||
label: 'SCM Credential',
|
||||
label: i18n._('SCM Credential'),
|
||||
type: 'lookup',
|
||||
ngShow: "scm_type && scm_type.value !== 'manual'",
|
||||
sourceModel: 'credential',
|
||||
@ -146,43 +147,43 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
checkbox_group: {
|
||||
label: 'SCM Update Options',
|
||||
label: i18n._('SCM Update Options'),
|
||||
type: 'checkbox_group',
|
||||
ngShow: "scm_type && scm_type.value !== 'manual'",
|
||||
subForm: 'sourceSubForm',
|
||||
fields: [{
|
||||
name: 'scm_clean',
|
||||
label: 'Clean',
|
||||
label: i18n._('Clean'),
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
awPopOver: '<p>Remove any local modifications prior to performing an update.</p>',
|
||||
dataTitle: 'SCM Clean',
|
||||
awPopOver: i18n._('<p>Remove any local modifications prior to performing an update.</p>'),
|
||||
dataTitle: i18n._('SCM Clean'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
labelClass: 'checkbox-options stack-inline',
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}, {
|
||||
name: 'scm_delete_on_update',
|
||||
label: 'Delete on Update',
|
||||
label: i18n._('Delete on Update'),
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
awPopOver: '<p>Delete the local repository in its entirety prior to performing an update.</p><p>Depending on the size of the ' +
|
||||
'repository this may significantly increase the amount of time required to complete an update.</p>',
|
||||
dataTitle: 'SCM Delete',
|
||||
awPopOver: i18n._('<p>Delete the local repository in its entirety prior to performing an update.</p><p>Depending on the size of the ' +
|
||||
'repository this may significantly increase the amount of time required to complete an update.</p>'),
|
||||
dataTitle: i18n._('SCM Delete'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
labelClass: 'checkbox-options stack-inline',
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}, {
|
||||
name: 'scm_update_on_launch',
|
||||
label: 'Update on Launch',
|
||||
label: i18n._('Update on Launch'),
|
||||
type: 'checkbox',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
awPopOver: '<p>Each time a job runs using this project, perform an update to the local repository prior to starting the job.</p>',
|
||||
dataTitle: 'SCM Update',
|
||||
awPopOver: i18n._('<p>Each time a job runs using this project, perform an update to the local repository prior to starting the job.</p>'),
|
||||
dataTitle: i18n._('SCM Update'),
|
||||
dataContainer: 'body',
|
||||
dataPlacement: 'right',
|
||||
labelClass: 'checkbox-options stack-inline',
|
||||
@ -190,7 +191,7 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
}]
|
||||
},
|
||||
scm_update_cache_timeout: {
|
||||
label: 'Cache Timeout<span class=\"small-text\"> (seconds)</span>',
|
||||
label: i18n._('Cache Timeout<span class=\"small-text\"> (seconds)</span>'),
|
||||
id: 'scm-cache-timeout',
|
||||
type: 'number',
|
||||
integer: true,
|
||||
@ -200,10 +201,10 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
"default": '0',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
awPopOver: '<p>Time in seconds to consider a project to be current. During job runs and callbacks the task system will ' +
|
||||
awPopOver: i18n._('<p>Time in seconds to consider a project to be current. During job runs and callbacks the task system will ' +
|
||||
'evaluate the timestamp of the latest project update. If it is older than Cache Timeout, it is not considered current, ' +
|
||||
'and a new project update will be performed.</p>',
|
||||
dataTitle: 'Cache Timeout',
|
||||
'and a new project update will be performed.</p>'),
|
||||
dataTitle: i18n._('Cache Timeout'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)' // TODO: get working
|
||||
@ -228,11 +229,11 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
|
||||
related: {
|
||||
permissions: {
|
||||
awToolTip: 'Please save before assigning permissions',
|
||||
awToolTip: i18n._('Please save before assigning permissions'),
|
||||
dataPlacement: 'top',
|
||||
basePath: 'projects/:id/access_list/',
|
||||
type: 'collection',
|
||||
title: 'Permissions',
|
||||
title: i18n._('Permissions'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -241,9 +242,9 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
add: {
|
||||
ngClick: "addPermission",
|
||||
label: 'Add',
|
||||
awToolTip: 'Add a permission',
|
||||
awToolTip: i18n._('Add a permission'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: '(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
@ -289,9 +290,10 @@ angular.module('ProjectFormDefinition', ['SchedulesListDefinition'])
|
||||
};
|
||||
}
|
||||
|
||||
})
|
||||
};}])
|
||||
|
||||
.factory('ProjectsForm', ['ProjectsFormObject', 'NotificationsList', function(ProjectsFormObject, NotificationsList) {
|
||||
.factory('ProjectsForm', ['ProjectsFormObject', 'NotificationsList',
|
||||
function(ProjectsFormObject, NotificationsList) {
|
||||
return function() {
|
||||
var itm;
|
||||
for (itm in ProjectsFormObject.related) {
|
||||
|
@ -12,16 +12,17 @@
|
||||
|
||||
export default
|
||||
angular.module('TeamFormDefinition', [])
|
||||
.value('TeamForm', {
|
||||
.factory('TeamForm', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Team', //Legend in add mode
|
||||
addTitle: i18n._('New Team'), //Legend in add mode
|
||||
editTitle: '{{ name }}', //Legend in edit mode
|
||||
name: 'team',
|
||||
tabs: true,
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -29,14 +30,14 @@ export default
|
||||
ngDisabled: '!(team_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngDisabled: '!(team_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -70,10 +71,10 @@ export default
|
||||
related: {
|
||||
access_list: {
|
||||
dataPlacement: 'top',
|
||||
awToolTip: 'Please save before adding users',
|
||||
awToolTip: i18n._('Please save before adding users'),
|
||||
basePath: 'teams/:id/access_list/',
|
||||
type: 'collection',
|
||||
title: 'Users',
|
||||
title: i18n._('Users'),
|
||||
iterator: 'permission',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -82,9 +83,9 @@ export default
|
||||
add: {
|
||||
ngClick: "addPermissionWithoutTeamTab",
|
||||
label: 'Add',
|
||||
awToolTip: 'Add user to team',
|
||||
awToolTip: i18n._('Add user to team'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: '(team_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}
|
||||
},
|
||||
@ -92,12 +93,12 @@ export default
|
||||
fields: {
|
||||
username: {
|
||||
key: true,
|
||||
label: 'User',
|
||||
label: i18n._('User'),
|
||||
linkBase: 'users',
|
||||
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
type: 'role',
|
||||
noSort: true,
|
||||
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4',
|
||||
@ -108,40 +109,40 @@ export default
|
||||
roles: {
|
||||
hideSearchAndActions: true,
|
||||
dataPlacement: 'top',
|
||||
awToolTip: 'Please save before assigning permissions',
|
||||
awToolTip: i18n._('Please save before assigning permissions'),
|
||||
basePath: 'teams/:id/roles/',
|
||||
type: 'collection',
|
||||
title: 'Granted Permissions',
|
||||
title: i18n._('Granted Permissions'),
|
||||
iterator: 'role',
|
||||
open: false,
|
||||
index: false,
|
||||
actions: {},
|
||||
emptyListText: 'No permissions have been granted',
|
||||
emptyListText: i18n._('No permissions have been granted'),
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
ngBind: 'role.summary_fields.resource_name',
|
||||
linkTo: '{{convertApiUrl(role.related[role.summary_fields.resource_type])}}',
|
||||
noSort: true
|
||||
},
|
||||
type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
ngBind: 'role.summary_fields.resource_type_display_name',
|
||||
noSort: true
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
ngBind: 'role.name',
|
||||
noSort: true
|
||||
}
|
||||
},
|
||||
fieldActions: {
|
||||
"delete": {
|
||||
label: 'Remove',
|
||||
label: i18n._('Remove'),
|
||||
ngClick: 'deletePermissionFromTeam(team_id, team_obj.name, role.name, role.summary_fields.resource_name, role.related.teams)',
|
||||
'class': "List-actionButton--delete",
|
||||
iconClass: 'fa fa-times',
|
||||
awToolTip: 'Dissasociate permission from team',
|
||||
awToolTip: i18n._('Dissasociate permission from team'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'permission.summary_fields.user_capabilities.unattach'
|
||||
}
|
||||
@ -149,4 +150,4 @@ export default
|
||||
hideOnSuperuser: true
|
||||
}
|
||||
},
|
||||
}); //InventoryForm
|
||||
};}]); //InventoryForm
|
||||
|
@ -12,9 +12,10 @@
|
||||
|
||||
export default
|
||||
angular.module('UserFormDefinition', [])
|
||||
.value('UserForm', {
|
||||
.factory('UserForm', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New User',
|
||||
addTitle: i18n._('New User'),
|
||||
editTitle: '{{ username }}',
|
||||
name: 'user',
|
||||
forceListeners: true,
|
||||
@ -22,7 +23,7 @@ export default
|
||||
|
||||
fields: {
|
||||
first_name: {
|
||||
label: 'First Name',
|
||||
label: i18n._('First Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -30,7 +31,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
last_name: {
|
||||
label: 'Last Name',
|
||||
label: i18n._('Last Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -38,7 +39,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
email: {
|
||||
label: 'Email',
|
||||
label: i18n._('Email'),
|
||||
type: 'email',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -46,7 +47,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
username: {
|
||||
label: 'Username',
|
||||
label: i18n._('Username'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "not_ldap_user && external_account === null",
|
||||
@ -56,7 +57,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -71,7 +72,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
password: {
|
||||
label: 'Password',
|
||||
label: i18n._('Password'),
|
||||
type: 'sensitive',
|
||||
hasShowInputButton: true,
|
||||
ngShow: 'ldap_user == false && socialAuthUser === false && external_account === null',
|
||||
@ -83,7 +84,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
password_confirm: {
|
||||
label: 'Confirm Password',
|
||||
label: i18n._('Confirm Password'),
|
||||
type: 'sensitive',
|
||||
hasShowInputButton: true,
|
||||
ngShow: 'ldap_user == false && socialAuthUser === false && external_account === null',
|
||||
@ -95,7 +96,7 @@ export default
|
||||
ngDisabled: '!(user_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
user_type: {
|
||||
label: 'User Type',
|
||||
label: i18n._('User Type'),
|
||||
type: 'select',
|
||||
ngOptions: 'item as item.label for item in user_type_options track by item.type',
|
||||
disableChooseOption: true,
|
||||
@ -124,10 +125,10 @@ export default
|
||||
related: {
|
||||
organizations: {
|
||||
basePath: 'users/:id/organizations',
|
||||
awToolTip: 'Please save before assigning to organizations',
|
||||
awToolTip: i18n._('Please save before assigning to organizations'),
|
||||
dataPlacement: 'top',
|
||||
type: 'collection',
|
||||
title: 'Organizations',
|
||||
title: i18n._('Organizations'),
|
||||
iterator: 'organization',
|
||||
index: false,
|
||||
open: false,
|
||||
@ -147,10 +148,10 @@ export default
|
||||
},
|
||||
teams: {
|
||||
basePath: 'users/:id/teams',
|
||||
awToolTip: 'Please save before assigning to teams',
|
||||
awToolTip: i18n._('Please save before assigning to teams'),
|
||||
dataPlacement: 'top',
|
||||
type: 'collection',
|
||||
title: 'Teams',
|
||||
title: i18n._('Teams'),
|
||||
iterator: 'team',
|
||||
open: false,
|
||||
index: false,
|
||||
@ -168,39 +169,39 @@ export default
|
||||
hideOnSuperuser: true
|
||||
},
|
||||
roles: {
|
||||
awToolTip: 'Please save before assigning to organizations',
|
||||
awToolTip: i18n._('Please save before assigning to organizations'),
|
||||
dataPlacement: 'top',
|
||||
hideSearchAndActions: true,
|
||||
type: 'collection',
|
||||
title: 'Granted permissions',
|
||||
title: i18n._('Granted permissions'),
|
||||
iterator: 'permission',
|
||||
open: false,
|
||||
index: false,
|
||||
emptyListText: 'No permissions have been granted',
|
||||
emptyListText: i18n._('No permissions have been granted'),
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
ngBind: 'permission.summary_fields.resource_name',
|
||||
linkTo: '{{convertApiUrl(permission.related[permission.summary_fields.resource_type])}}',
|
||||
noSort: true
|
||||
},
|
||||
type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
ngBind: 'permission.summary_fields.resource_type_display_name',
|
||||
noSort: true
|
||||
},
|
||||
role: {
|
||||
label: 'Role',
|
||||
label: i18n._('Role'),
|
||||
ngBind: 'permission.name',
|
||||
noSort: true
|
||||
},
|
||||
},
|
||||
fieldActions: {
|
||||
"delete": {
|
||||
label: 'Remove',
|
||||
label: i18n._('Remove'),
|
||||
ngClick: 'deletePermissionFromUser(user_id, username, permission.name, permission.summary_fields.resource_name, permission.related.users)',
|
||||
iconClass: 'fa fa-times',
|
||||
awToolTip: 'Dissasociate permission from user',
|
||||
awToolTip: i18n._('Dissasociate permission from user'),
|
||||
ngShow: 'permission.summary_fields.user_capabilities.unattach'
|
||||
}
|
||||
},
|
||||
@ -208,4 +209,4 @@ export default
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};}]);
|
||||
|
@ -13,8 +13,8 @@
|
||||
export default
|
||||
angular.module('CredentialsHelper', ['Utilities'])
|
||||
|
||||
.factory('KindChange', ['Empty',
|
||||
function (Empty) {
|
||||
.factory('KindChange', ['Empty', 'i18n',
|
||||
function (Empty, i18n) {
|
||||
return function (params) {
|
||||
var scope = params.scope,
|
||||
reset = params.reset,
|
||||
@ -29,20 +29,20 @@ angular.module('CredentialsHelper', ['Utilities'])
|
||||
$(this).hide();
|
||||
});
|
||||
// Put things in a default state
|
||||
scope.usernameLabel = 'Username';
|
||||
scope.usernameLabel = i18n._('Username');
|
||||
scope.aws_required = false;
|
||||
scope.email_required = false;
|
||||
scope.rackspace_required = false;
|
||||
scope.sshKeyDataLabel = 'Private Key';
|
||||
scope.sshKeyDataLabel = i18n._('Private Key');
|
||||
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
|
||||
scope.key_required = false; // JT -- doing the same for key and project
|
||||
scope.project_required = false;
|
||||
scope.subscription_required = false;
|
||||
scope.key_description = "Paste the contents of the SSH private key file.<div class=\"popover-footer\"><span class=\"key\">esc</span> or click to close</div>";
|
||||
scope.key_description = i18n._("Paste the contents of the SSH private key file.<div class=\"popover-footer\"><span class=\"key\">esc</span> or click to close</div>");
|
||||
scope.host_required = false;
|
||||
scope.password_required = false;
|
||||
scope.hostLabel = '';
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
|
||||
$('.popover').each(function() {
|
||||
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
|
||||
@ -53,26 +53,26 @@ angular.module('CredentialsHelper', ['Utilities'])
|
||||
$(this).hide();
|
||||
});
|
||||
// Put things in a default state
|
||||
scope.usernameLabel = 'Username';
|
||||
scope.usernameLabel = i18n._('Username');
|
||||
scope.aws_required = false;
|
||||
scope.email_required = false;
|
||||
scope.rackspace_required = false;
|
||||
scope.sshKeyDataLabel = 'Private Key';
|
||||
scope.sshKeyDataLabel = i18n._('Private Key');
|
||||
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
|
||||
scope.key_required = false; // JT -- doing the same for key and project
|
||||
scope.project_required = false;
|
||||
scope.domain_required = false;
|
||||
scope.subscription_required = false;
|
||||
scope.key_description = "Paste the contents of the SSH private key file.";
|
||||
scope.key_description = i18n._("Paste the contents of the SSH private key file.");
|
||||
scope.host_required = false;
|
||||
scope.password_required = false;
|
||||
scope.hostLabel = '';
|
||||
scope.projectLabel = '';
|
||||
scope.domainLabel = '';
|
||||
scope.project_required = false;
|
||||
scope.passwordLabel = 'Password (API Key)';
|
||||
scope.projectPopOver = "<p>The project value</p>";
|
||||
scope.hostPopOver = "<p>The host value</p>";
|
||||
scope.passwordLabel = i18n._('Password (API Key)');
|
||||
scope.projectPopOver = i18n._("<p>The project value</p>");
|
||||
scope.hostPopOver = i18n._("<p>The host value</p>");
|
||||
scope.ssh_key_data_api_error = '';
|
||||
if (!Empty(scope.kind)) {
|
||||
// Apply kind specific settings
|
||||
@ -85,38 +85,38 @@ angular.module('CredentialsHelper', ['Utilities'])
|
||||
scope.username_required = true;
|
||||
break;
|
||||
case 'ssh':
|
||||
scope.usernameLabel = 'Username'; //formally 'SSH Username'
|
||||
scope.becomeUsernameLabel = 'Privilege Escalation Username';
|
||||
scope.becomePasswordLabel = 'Privilege Escalation Password';
|
||||
scope.usernameLabel = i18n._('Username'); //formally 'SSH Username'
|
||||
scope.becomeUsernameLabel = i18n._('Privilege Escalation Username');
|
||||
scope.becomePasswordLabel = i18n._('Privilege Escalation Password');
|
||||
break;
|
||||
case 'scm':
|
||||
scope.sshKeyDataLabel = 'SCM Private Key';
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.sshKeyDataLabel = i18n._('SCM Private Key');
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
break;
|
||||
case 'gce':
|
||||
scope.usernameLabel = 'Service Account Email Address';
|
||||
scope.sshKeyDataLabel = 'RSA Private Key';
|
||||
scope.usernameLabel = i18n._('Service Account Email Address');
|
||||
scope.sshKeyDataLabel = i18n._('RSA Private Key');
|
||||
scope.email_required = true;
|
||||
scope.key_required = true;
|
||||
scope.project_required = true;
|
||||
scope.key_description = 'Paste the contents of the PEM file associated with the service account email.';
|
||||
scope.projectLabel = "Project";
|
||||
scope.key_description = i18n._('Paste the contents of the PEM file associated with the service account email.');
|
||||
scope.projectLabel = i18n._("Project");
|
||||
scope.project_required = false;
|
||||
scope.projectPopOver = "<p>The Project ID is the " +
|
||||
scope.projectPopOver = i18n._("<p>The Project ID is the " +
|
||||
"GCE assigned identification. It is constructed as " +
|
||||
"two words followed by a three digit number. Such " +
|
||||
"as: </p><p>adjective-noun-000</p>";
|
||||
"as: </p><p>adjective-noun-000</p>");
|
||||
break;
|
||||
case 'azure':
|
||||
scope.sshKeyDataLabel = 'Management Certificate';
|
||||
scope.sshKeyDataLabel = i18n._('Management Certificate');
|
||||
scope.subscription_required = true;
|
||||
scope.key_required = true;
|
||||
scope.key_description = "Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.";
|
||||
scope.key_description = i18n._("Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.");
|
||||
break;
|
||||
case 'azure_rm':
|
||||
scope.usernameLabel = "Username";
|
||||
scope.usernameLabel = i18n._("Username");
|
||||
scope.subscription_required = true;
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.azure_rm_required = true;
|
||||
break;
|
||||
case 'vmware':
|
||||
@ -124,46 +124,46 @@ angular.module('CredentialsHelper', ['Utilities'])
|
||||
scope.host_required = true;
|
||||
scope.password_required = true;
|
||||
scope.hostLabel = "vCenter Host";
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.hostPopOver = "Enter the hostname or IP address which corresponds to your VMware vCenter.";
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.hostPopOver = i18n._("Enter the hostname or IP address which corresponds to your VMware vCenter.");
|
||||
break;
|
||||
case 'openstack':
|
||||
scope.hostLabel = "Host (Authentication URL)";
|
||||
scope.projectLabel = "Project (Tenant Name)";
|
||||
scope.domainLabel = "Domain Name";
|
||||
scope.hostLabel = i18n._("Host (Authentication URL)");
|
||||
scope.projectLabel = i18n._("Project (Tenant Name)");
|
||||
scope.domainLabel = i18n._("Domain Name");
|
||||
scope.password_required = true;
|
||||
scope.project_required = true;
|
||||
scope.host_required = true;
|
||||
scope.username_required = true;
|
||||
scope.projectPopOver = "<p>This is the tenant name. " +
|
||||
scope.projectPopOver = i18n._("<p>This is the tenant name. " +
|
||||
" This value is usually the same " +
|
||||
" as the username.</p>";
|
||||
scope.hostPopOver = "<p>The host to authenticate with." +
|
||||
"<br />For example, https://openstack.business.com/v2.0/";
|
||||
" as the username.</p>");
|
||||
scope.hostPopOver = i18n._("<p>The host to authenticate with." +
|
||||
"<br />For example, https://openstack.business.com/v2.0/");
|
||||
break;
|
||||
case 'satellite6':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = "Satellite 6 Host";
|
||||
scope.hostPopOver = "Enter the hostname or IP address name which <br />" +
|
||||
"corresponds to your Red Hat Satellite 6 server.";
|
||||
scope.hostLabel = i18n._("Satellite 6 Host");
|
||||
scope.hostPopOver = i18n._("Enter the hostname or IP address name which <br />" +
|
||||
"corresponds to your Red Hat Satellite 6 server.");
|
||||
break;
|
||||
case 'cloudforms':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = "CloudForms Host";
|
||||
scope.hostPopOver = "Enter the hostname or IP address for the virtual <br />" +
|
||||
" machine which is hosting the CloudForm appliance.";
|
||||
scope.hostLabel = i18n._("CloudForms Host");
|
||||
scope.hostPopOver = i18n._("Enter the hostname or IP address for the virtual <br />" +
|
||||
" machine which is hosting the CloudForm appliance.");
|
||||
break;
|
||||
case 'net':
|
||||
scope.username_required = true;
|
||||
scope.password_required = false;
|
||||
scope.passwordLabel = 'Password';
|
||||
scope.sshKeyDataLabel = 'SSH Key';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.sshKeyDataLabel = i18n._('SSH Key');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
100
awx/ui/client/src/i18n.js
Normal file
100
awx/ui/client/src/i18n.js
Normal file
@ -0,0 +1,100 @@
|
||||
function isString(arg) {
|
||||
return typeof arg === 'string';
|
||||
}
|
||||
|
||||
function isNull(arg) {
|
||||
return arg === null;
|
||||
}
|
||||
|
||||
function isObject(arg) {
|
||||
return typeof arg === 'object' && arg !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
// Copied format() from util/util.js. util.js includes "require()".
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name function:i18n#format
|
||||
* @methodOf function:format
|
||||
* @description this function provides C-style's formatted sprintf().
|
||||
*
|
||||
*/
|
||||
export function format(f) {
|
||||
var i;
|
||||
var formatRegExp = /%[sdj%]/g;
|
||||
if (!isString(f)) {
|
||||
var objects = [];
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
objects.push(JSON.stringify(arguments[i]));
|
||||
}
|
||||
return objects.join(' ');
|
||||
}
|
||||
|
||||
i = 1;
|
||||
var args = arguments;
|
||||
var len = args.length;
|
||||
var str = String(f).replace(formatRegExp, function(x) {
|
||||
if (x === '%%') return '%';
|
||||
if (i >= len) return x;
|
||||
switch (x) {
|
||||
case '%s': return String(args[i++]);
|
||||
case '%d': return Number(args[i++]);
|
||||
case '%j':
|
||||
case '%j':
|
||||
try {
|
||||
return JSON.stringify(args[i++]);
|
||||
} catch (_) {
|
||||
return '[Circular]';
|
||||
}
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
});
|
||||
for (var x = args[i]; i < len; x = args[++i]) {
|
||||
if (isNull(x) || !isObject(x)) {
|
||||
str += ' ' + x;
|
||||
} else {
|
||||
str += ' ' + JSON.stringify(x);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export default
|
||||
angular.module('I18N', [])
|
||||
.factory('I18NInit', ['$window', 'gettextCatalog',
|
||||
function ($window, gettextCatalog) {
|
||||
return function() {
|
||||
var langInfo = $window.navigator.language ||
|
||||
$window.navigator.userLanguage;
|
||||
var langUrl = langInfo.replace('-', '_');
|
||||
//gettextCatalog.debug = true;
|
||||
gettextCatalog.setCurrentLanguage(langInfo);
|
||||
// TODO: the line below is commented out temporarily until
|
||||
// the .po files are received from the i18n team, in order to avoid
|
||||
// 404 file not found console errors in dev
|
||||
// gettextCatalog.loadRemote('/static/languages/' + langUrl + '.json');
|
||||
};
|
||||
}])
|
||||
.factory('i18n', ['gettextCatalog',
|
||||
function (gettextCatalog) {
|
||||
return {
|
||||
_: function (s) { return gettextCatalog.getString (s); },
|
||||
N_: N_,
|
||||
format: format,
|
||||
hasTranslation: function () {
|
||||
return gettextCatalog.strings[gettextCatalog.currentLanguage] !== undefined;
|
||||
}
|
||||
};
|
||||
}]);
|
@ -10,17 +10,17 @@
|
||||
* @description This form is for adding/editing an organization
|
||||
*/
|
||||
|
||||
export default function() {
|
||||
export default ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Custom Inventory',
|
||||
addTitle: i18n._('New Custom Inventory'),
|
||||
editTitle: '{{ name }}',
|
||||
name: 'custom_inventory',
|
||||
showActions: true,
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -28,14 +28,14 @@ export default function() {
|
||||
ngDisabled: '!(inventory_script_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngDisabled: '!(inventory_script_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "orgrequired",
|
||||
@ -47,7 +47,7 @@ export default function() {
|
||||
ngDisabled: '!(inventory_script_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
script: {
|
||||
label: 'Custom Script',
|
||||
label: i18n._('Custom Script'),
|
||||
type: 'textarea',
|
||||
class: 'Form-formGroup--fullWidth',
|
||||
elementClass: 'Form-monospace',
|
||||
@ -56,9 +56,9 @@ export default function() {
|
||||
awDropFile: true,
|
||||
ngDisabled: '!(inventory_script_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||
rows: 10,
|
||||
awPopOver: "<p>Drag and drop your custom inventory script file here or create one in the field to import your custom inventory. " +
|
||||
"<br><br> Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python</p>",
|
||||
dataTitle: 'Custom Script',
|
||||
awPopOver: i18n._("<p>Drag and drop your custom inventory script file here or create one in the field to import your custom inventory. " +
|
||||
"<br><br> Script must begin with a hashbang sequence: i.e.... #!/usr/bin/env python</p>"),
|
||||
dataTitle: i18n._('Custom Script'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body"
|
||||
},
|
||||
@ -80,4 +80,4 @@ export default function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
|
||||
|
||||
export default function(){
|
||||
export default ['i18n', function(i18n){
|
||||
return {
|
||||
name: 'inventory_scripts' ,
|
||||
listTitle: 'Inventory Scripts',
|
||||
listTitle: i18n._('Inventory Scripts'),
|
||||
iterator: 'inventory_script',
|
||||
index: false,
|
||||
hover: false,
|
||||
@ -17,17 +17,17 @@ export default function(){
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-3 col-sm-9 col-xs-9',
|
||||
modalColumnClass: 'col-md-8'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
excludeModal: true,
|
||||
columnClass: 'col-md-4 hidden-sm hidden-xs'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
ngBind: 'inventory_script.summary_fields.organization.name',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -40,9 +40,9 @@ export default function(){
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addCustomInv()',
|
||||
awToolTip: 'Create a new custom inventory',
|
||||
awToolTip: i18n._('Create a new custom inventory'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -54,29 +54,29 @@ export default function(){
|
||||
edit: {
|
||||
ngClick: "editCustomInv(inventory_script.id)",
|
||||
icon: 'fa-edit',
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Edit inventory script',
|
||||
awToolTip: i18n._('Edit inventory script'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'inventory_script.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
view: {
|
||||
ngClick: "editCustomInv(inventory_script.id)",
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'View inventory script',
|
||||
awToolTip: i18n._('View inventory script'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!inventory_script.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
ngClick: "deleteCustomInv(inventory_script.id, inventory_script.name)",
|
||||
icon: 'fa-trash',
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Delete inventory script',
|
||||
awToolTip: i18n._('Delete inventory script'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'inventory_script.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -5,6 +5,7 @@
|
||||
*************************************************/
|
||||
|
||||
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||
import {N_} from "../../i18n";
|
||||
|
||||
export default {
|
||||
name: 'jobTemplates.add',
|
||||
@ -13,7 +14,7 @@ export default {
|
||||
controller: 'JobTemplatesAdd',
|
||||
ncyBreadcrumb: {
|
||||
parent: "jobTemplates",
|
||||
label: "CREATE JOB TEMPLATE"
|
||||
label: N_("CREATE JOB TEMPLATE")
|
||||
},
|
||||
socket:{
|
||||
"groups":{
|
||||
|
@ -4,13 +4,15 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import {N_} from "../i18n";
|
||||
|
||||
export default
|
||||
['Wait', '$state', '$scope', '$rootScope', '$location', 'GetBasePath',
|
||||
'Rest', 'ProcessErrors', 'CheckLicense', 'moment','$window',
|
||||
'ConfigService', 'FeaturesService', 'pendoService',
|
||||
'ConfigService', 'FeaturesService', 'pendoService', 'i18n',
|
||||
function( Wait, $state, $scope, $rootScope, $location, GetBasePath, Rest,
|
||||
ProcessErrors, CheckLicense, moment, $window, ConfigService,
|
||||
FeaturesService, pendoService){
|
||||
FeaturesService, pendoService, i18n){
|
||||
$scope.getKey = function(event){
|
||||
// Mimic HTML5 spec, show filename
|
||||
$scope.fileName = event.target.files[0].name;
|
||||
@ -90,8 +92,9 @@ export default
|
||||
};
|
||||
|
||||
var init = function(){
|
||||
$scope.fileName = "No file selected.";
|
||||
$scope.title = $rootScope.licenseMissing ? "Tower License" : "License Management";
|
||||
// license/license.partial.html compares fileName
|
||||
$scope.fileName = N_("No file selected.");
|
||||
$scope.title = $rootScope.licenseMissing ? ("Tower " + i18n._("License")) : i18n._("License Management");
|
||||
Wait('start');
|
||||
ConfigService.getConfig().then(function(config){
|
||||
$scope.license = config;
|
||||
|
@ -2,91 +2,91 @@
|
||||
ng-class="{'License-container--missing': licenseMissing}">
|
||||
<div class="License-details" ng-hide="licenseMissing">
|
||||
<div class="Panel">
|
||||
<div class="License-titleText">Details</div>
|
||||
<div class="License-titleText" translate>Details</div>
|
||||
<div class="License-fields">
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">License</div>
|
||||
<div class="License-field--label" translate>License</div>
|
||||
<div class="License-field--content">
|
||||
<span class="License-greenText" ng-show='compliant'><i class="fa fa-circle License-greenText"></i>Valid License</span>
|
||||
<span class="License-redText" ng-show='!compliant'><i class="fa fa-circle License-redText"></i>Invalid License</span>
|
||||
<span class="License-greenText" ng-show='compliant'><i class="fa fa-circle License-greenText"></i><translate>Valid License</translate></span>
|
||||
<span class="License-redText" ng-show='!compliant'><i class="fa fa-circle License-redText"></i><translate>Invalid License</transalte></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Version</div>
|
||||
<div class="License-field--label" translate>Version</div>
|
||||
<div class="License-field--content">
|
||||
{{license.version}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">License Type</div>
|
||||
<div class="License-field--label" translate>License Type</div>
|
||||
<div class="License-field--content">
|
||||
{{license.license_info.license_type}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Subscription</div>
|
||||
<div class="License-field--label" translate>Subscription</div>
|
||||
<div class="License-field--content">
|
||||
{{license.license_info.subscription_name}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">License Key</div>
|
||||
<div class="License-field--label" translate>License Key</div>
|
||||
<div class="License-field--content License-field--key">
|
||||
{{license.license_info.license_key}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Expires On</div>
|
||||
<div class="License-field--label" translate>Expires On</div>
|
||||
<div class="License-field--content">
|
||||
{{time.expiresOn}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Time Remaining</div>
|
||||
<div class="License-field--label" translate>Time Remaining</div>
|
||||
<div class="License-field--content"
|
||||
ng-class="{'License-redText': time.remaining=='0 Days'}">
|
||||
{{time.remaining}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Hosts Available</div>
|
||||
<div class="License-field--label" translate>Hosts Available</div>
|
||||
<div class="License-field--content">
|
||||
{{license.license_info.available_instances}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<div class="License-field--label">Hosts Used</div>
|
||||
<div class="License-field--label" translate>Hosts Used</div>
|
||||
<div class="License-field--content">
|
||||
{{license.license_info.current_instances}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-field License-greenText">
|
||||
<div class="License-field--label">Hosts Remaining</div>
|
||||
<div class="License-field--label" translate>Hosts Remaining</div>
|
||||
<div class="License-field--content">
|
||||
{{license.license_info.free_instances}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-upgradeText">If you are ready to upgrade, please contact us by clicking the button below</div>
|
||||
<a href="https://www.ansible.com/renew" target="_blank"><button class="btn btn-primary">Upgrade</button></a>
|
||||
<div class="License-upgradeText" translate>If you are ready to upgrade, please contact us by clicking the button below</div>
|
||||
<a href="https://www.ansible.com/renew" target="_blank"><button class="btn btn-primary" translate>Upgrade</button></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-management" ng-class="{'License-management--missingLicense' : licenseMissing}">
|
||||
<div class="Panel">
|
||||
<div class="License-titleText">{{title}}</div>
|
||||
<div class="License-body">
|
||||
<div class="License-helperText" ng-if="licenseMissing">Welcome to Ansible Tower! Please complete the steps below to acquire a license.</div>
|
||||
<div class="License-helperText" ng-if="licenseMissing" translate>Welcome to Ansible Tower! Please complete the steps below to acquire a license.</div>
|
||||
<div class="AddPermissions-directions" ng-if="licenseMissing">
|
||||
<span class="AddPermissions-directionNumber">
|
||||
1
|
||||
</span>
|
||||
<span class="License-helperText">
|
||||
Please click the button below to visit Ansible's website to get a Tower license key.
|
||||
<translate>Please click the button below to visit Ansible's website to get a Tower license key.</translate>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button class="License-downloadLicenseButton btn btn-primary" ng-if="licenseMissing" ng-click="downloadLicense()">
|
||||
Request License
|
||||
<translate>Request License</translate>
|
||||
</button>
|
||||
|
||||
<div class="AddPermissions-directions">
|
||||
@ -94,18 +94,18 @@
|
||||
2
|
||||
</span>
|
||||
<span class="License-helperText">
|
||||
Choose your license file, agree to the End User License Agreement, and click submit.
|
||||
<translate>Choose your license file, agree to the End User License Agreement, and click submit.</translate>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<form id="License-form" name="license">
|
||||
<div class="License-subTitleText prepend-asterisk"> License File</div>
|
||||
<div class="License-subTitleText prepend-asterisk"> <translate>License File</translate></div>
|
||||
<div class="input-group License-file--container">
|
||||
<span class="btn btn-primary" ng-click="fakeClick()">Browse</span>
|
||||
<span class="License-fileName" ng-class="{'License-helperText' : fileName == 'No file selected.'}">{{fileName}}</span>
|
||||
<span class="btn btn-primary" ng-click="fakeClick()" translate>Browse</span>
|
||||
<span class="License-fileName" ng-class="{'License-helperText' : fileName == 'No file selected.'}">{{fileName|translate}}</span>
|
||||
<input id="License-file" class="form-control" type="file" file-on-change="getKey"/>
|
||||
</div>
|
||||
<div class="License-subTitleText prepend-asterisk"> End User License Agreement
|
||||
<div class="License-subTitleText prepend-asterisk"> <translate>End User License Agreement</translate>
|
||||
</div>
|
||||
<div id="eula_notice"
|
||||
class="License-eulaNotice">{{ license.eula }}</div>
|
||||
@ -113,13 +113,13 @@
|
||||
<div class="checkbox">
|
||||
<label class="License-details--label">
|
||||
<input type="checkbox" ng-model="newLicense.eula" required>
|
||||
I agree to the End User License Agreement
|
||||
<translate>I agree to the End User License Agreement</translate>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="License-submit--container">
|
||||
<button ng-click="submit()" class="btn btn-success pull-right" ng-disabled="newLicense.file.license_key == null || newLicense.eula == null">Submit</button>
|
||||
<span ng-show="success == true" class="License-greenText License-submit--success pull-right">Save successful!</span>
|
||||
<button ng-click="submit()" class="btn btn-success pull-right" ng-disabled="newLicense.file.license_key == null || newLicense.eula == null" translate>Submit</button>
|
||||
<span ng-show="success == true" class="License-greenText License-submit--success pull-right" translate>Save successful!</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -5,22 +5,21 @@
|
||||
*************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
export default
|
||||
angular.module('CompletedJobsDefinition', ['sanitizeFilter'])
|
||||
.value( 'CompletedJobsList', {
|
||||
.factory('CompletedJobsList', ['i18n', function(i18n) {
|
||||
return {
|
||||
// These tooltip fields are consumed to build disabled related tabs tooltips in the form > add view
|
||||
awToolTip: 'Please save and run a job to view',
|
||||
awToolTip: i18n._('Please save and run a job to view'),
|
||||
dataPlacement: 'top',
|
||||
name: 'completed_jobs',
|
||||
basePath: 'job_templates/:id/jobs/?or__status=successful&or__status=failed&or__status=error&or__status=canceled',
|
||||
iterator: 'completed_job',
|
||||
editTitle: 'Completed Jobs',
|
||||
editTitle: i18n._('Completed Jobs'),
|
||||
index: false,
|
||||
hover: true,
|
||||
well: false,
|
||||
emptyListText: 'No completed jobs',
|
||||
emptyListText: i18n._('No completed jobs'),
|
||||
|
||||
fields: {
|
||||
status: {
|
||||
@ -53,7 +52,7 @@ export default
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-6',
|
||||
searchable: false,
|
||||
ngClick: "viewJobDetails(completed_job)",
|
||||
@ -61,7 +60,7 @@ export default
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
ngBind: 'completed_job.type_label',
|
||||
link: false,
|
||||
columnClass: "col-lg-2 col-md-2 hidden-sm hidden-xs",
|
||||
@ -70,7 +69,7 @@ export default
|
||||
searchOptions: [] // populated via GetChoices() in controller
|
||||
},
|
||||
finished: {
|
||||
label: 'Finished',
|
||||
label: i18n._('Finished'),
|
||||
noLink: true,
|
||||
searchable: false,
|
||||
filter: "longDate",
|
||||
@ -79,7 +78,7 @@ export default
|
||||
desc: true
|
||||
},
|
||||
failed: {
|
||||
label: 'Job failed?',
|
||||
label: i18n._('Job failed?'),
|
||||
searchSingleValue: true,
|
||||
searchType: 'boolean',
|
||||
searchValue: 'true',
|
||||
@ -110,4 +109,4 @@ export default
|
||||
ngShow: 'completed_job.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -9,33 +9,34 @@
|
||||
|
||||
export default
|
||||
angular.module('CredentialsListDefinition', [])
|
||||
.value('CredentialList', {
|
||||
.factory('CredentialList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'credentials',
|
||||
iterator: 'credential',
|
||||
selectTitle: 'Add Credentials',
|
||||
editTitle: 'Credentials',
|
||||
listTitle: 'Credentials',
|
||||
selectTitle: i18n._('Add Credentials'),
|
||||
editTitle: i18n._('Credentials'),
|
||||
listTitle: i18n._('Credentials'),
|
||||
selectInstructions: "<p>Select existing credentials by clicking each credential or checking the related checkbox. When " +
|
||||
"finished, click the blue <em>Select</em> button, located bottom right.</p> <p>Create a brand new credential by clicking ",
|
||||
index: false,
|
||||
hover: true,
|
||||
emptyListText: 'No Credentials Have Been Created',
|
||||
emptyListText: i18n._('No Credentials Have Been Created'),
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-3 col-sm-9 col-xs-9',
|
||||
modalColumnClass: 'col-md-11'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
excludeModal: true,
|
||||
columnClass: 'col-md-3 hidden-sm hidden-xs'
|
||||
},
|
||||
kind: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
searchType: 'select',
|
||||
searchOptions: [], // will be set by Options call to credentials resource
|
||||
excludeModal: true,
|
||||
@ -43,7 +44,7 @@ export default
|
||||
columnClass: 'col-md-2 hidden-sm hidden-xs'
|
||||
},
|
||||
owners: {
|
||||
label: 'Owners',
|
||||
label: i18n._('Owners'),
|
||||
type: 'owners',
|
||||
searchable: false,
|
||||
nosort: true,
|
||||
@ -56,9 +57,9 @@ export default
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addCredential()',
|
||||
awToolTip: 'Create a new credential',
|
||||
awToolTip: i18n._('Create a new credential'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD'
|
||||
buttonContent: i18n._('+ ADD')
|
||||
}
|
||||
},
|
||||
|
||||
@ -69,18 +70,18 @@ export default
|
||||
edit: {
|
||||
ngClick: "editCredential(credential.id)",
|
||||
icon: 'fa-edit',
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Edit credential',
|
||||
awToolTip: i18n._('Edit credential'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'credential.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
|
||||
view: {
|
||||
ngClick: "editCredential(credential.id)",
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'View credential',
|
||||
awToolTip: i18n._('View credential'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!credential.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
@ -88,11 +89,11 @@ export default
|
||||
"delete": {
|
||||
ngClick: "deleteCredential(credential.id, credential.name)",
|
||||
icon: 'fa-trash',
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Delete credential',
|
||||
awToolTip: i18n._('Delete credential'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'credential.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,13 +7,14 @@
|
||||
|
||||
export default
|
||||
angular.module('InventoriesListDefinition', [])
|
||||
.value('InventoryList', {
|
||||
.factory('InventoryList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'inventories',
|
||||
iterator: 'inventory',
|
||||
selectTitle: 'Add Inventories',
|
||||
editTitle: 'Inventories',
|
||||
listTitle: 'Inventories',
|
||||
selectTitle: i18n._('Add Inventories'),
|
||||
editTitle: i18n._('Inventories'),
|
||||
listTitle: i18n._('Inventories'),
|
||||
selectInstructions: "Click on a row to select it, and click Finished when done. Click the <i class=\"icon-plus\"></i> " +
|
||||
"button to create a new inventory.",
|
||||
index: false,
|
||||
@ -43,13 +44,13 @@ export default
|
||||
},
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-5 col-sm-5 col-xs-8 List-staticColumnAdjacent',
|
||||
modalColumnClass: 'col-md-11',
|
||||
linkTo: '/#/inventories/{{inventory.id}}/manage'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
ngBind: 'inventory.summary_fields.organization.name',
|
||||
linkTo: '/#/organizations/{{ inventory.organization }}',
|
||||
sourceModel: 'organization',
|
||||
@ -58,27 +59,27 @@ export default
|
||||
columnClass: 'col-md-5 col-sm-3 hidden-xs'
|
||||
},
|
||||
has_inventory_sources: {
|
||||
label: 'Cloud sourced?',
|
||||
label: i18n._('Cloud sourced?'),
|
||||
searchSingleValue: true,
|
||||
searchType: 'boolean',
|
||||
searchValue: 'true',
|
||||
searchOnly: true
|
||||
},
|
||||
has_active_failures: {
|
||||
label: 'Failed hosts?',
|
||||
label: i18n._('Failed hosts?'),
|
||||
searchSingleValue: true,
|
||||
searchType: 'boolean',
|
||||
searchValue: 'true',
|
||||
searchOnly: true
|
||||
},
|
||||
inventory_sources_with_failures: {
|
||||
label: 'Sync failures?',
|
||||
label: i18n._('Sync failures?'),
|
||||
searchType: 'select',
|
||||
searchOptions: [{
|
||||
label: 'Yes',
|
||||
label: i18n._('Yes'),
|
||||
value: 'inventory_sources_with_failures__gt=0'
|
||||
}, {
|
||||
label: 'No',
|
||||
label: i18n._('No'),
|
||||
value: 'inventory_sources_with_failures__lte=0'
|
||||
}],
|
||||
searchOnly: true
|
||||
@ -89,9 +90,9 @@ export default
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addInventory()',
|
||||
awToolTip: 'Create a new inventory',
|
||||
awToolTip: i18n._('Create a new inventory'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -101,25 +102,25 @@ export default
|
||||
columnClass: 'col-md-2 col-sm-4 col-xs-4',
|
||||
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
ngClick: 'editInventory(inventory.id)',
|
||||
awToolTip: 'Edit inventory',
|
||||
awToolTip: i18n._('Edit inventory'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'inventory.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
view: {
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
ngClick: 'editInventory(inventory.id)',
|
||||
awToolTip: 'View inventory',
|
||||
awToolTip: i18n._('View inventory'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!inventory.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
ngClick: "deleteInventory(inventory.id, inventory.name)",
|
||||
awToolTip: 'Delete inventory',
|
||||
awToolTip: i18n._('Delete inventory'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'inventory.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,13 +7,14 @@
|
||||
|
||||
export default
|
||||
angular.module('JobTemplatesListDefinition', [])
|
||||
.value('JobTemplateList', {
|
||||
.factory('JobTemplateList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'job_templates',
|
||||
iterator: 'job_template',
|
||||
selectTitle: 'Add Job Template',
|
||||
editTitle: 'Job Templates',
|
||||
listTitle: 'Job Templates',
|
||||
selectTitle: i18n._('Add Job Template'),
|
||||
editTitle: i18n._('Job Templates'),
|
||||
listTitle: i18n._('Job Templates'),
|
||||
selectInstructions: "Click on a row to select it, and click Finished when done. Use the <i class=\"icon-plus\"></i> " +
|
||||
"button to create a new job template.",
|
||||
index: false,
|
||||
@ -22,15 +23,15 @@ export default
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-2 col-md-2 col-sm-4 col-xs-9'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
columnClass: 'col-lg-2 hidden-md hidden-sm hidden-xs'
|
||||
},
|
||||
smart_status: {
|
||||
label: 'Activity',
|
||||
label: i18n._('Activity'),
|
||||
columnClass: 'List-tableCell col-lg-2 col-md-2 hidden-sm hidden-xs',
|
||||
searchable: false,
|
||||
nosort: true,
|
||||
@ -38,7 +39,7 @@ export default
|
||||
type: 'template'
|
||||
},
|
||||
labels: {
|
||||
label: 'Labels',
|
||||
label: i18n._('Labels'),
|
||||
type: 'labels',
|
||||
nosort: true,
|
||||
columnClass: 'List-tableCell col-lg-4 col-md-4 hidden-sm hidden-xs',
|
||||
@ -53,9 +54,9 @@ export default
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addJobTemplate()',
|
||||
basePaths: ['job_templates'],
|
||||
awToolTip: 'Create a new template',
|
||||
awToolTip: i18n._('Create a new template'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -65,52 +66,52 @@ export default
|
||||
columnClass: 'col-lg-2 col-md-3 col-sm-3 col-xs-3',
|
||||
|
||||
submit: {
|
||||
label: 'Launch',
|
||||
label: i18n._('Launch'),
|
||||
mode: 'all',
|
||||
ngClick: 'submitJob(job_template.id)',
|
||||
awToolTip: 'Start a job using this template',
|
||||
awToolTip: i18n._('Start a job using this template'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'job_template.summary_fields.user_capabilities.start'
|
||||
},
|
||||
schedule: {
|
||||
label: 'Schedule',
|
||||
label: i18n._('Schedule'),
|
||||
mode: 'all',
|
||||
ngClick: 'scheduleJob(job_template.id)',
|
||||
awToolTip: 'Schedule future job template runs',
|
||||
awToolTip: i18n._('Schedule future job template runs'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'job_template.summary_fields.user_capabilities.schedule'
|
||||
},
|
||||
copy: {
|
||||
label: 'Copy',
|
||||
label: i18n._('Copy'),
|
||||
'ui-sref': 'jobTemplates.copy({id: job_template.id})',
|
||||
"class": 'btn-danger btn-xs',
|
||||
awToolTip: 'Copy template',
|
||||
awToolTip: i18n._('Copy template'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'job_template.summary_fields.user_capabilities.copy'
|
||||
},
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
ngClick: "editJobTemplate(job_template.id)",
|
||||
awToolTip: 'Edit template',
|
||||
awToolTip: i18n._('Edit template'),
|
||||
"class": 'btn-default btn-xs',
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'job_template.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
view: {
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
ngClick: "editJobTemplate(job_template.id)",
|
||||
awToolTip: 'View template',
|
||||
awToolTip: i18n._('View template'),
|
||||
"class": 'btn-default btn-xs',
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!job_template.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
ngClick: "deleteJobTemplate(job_template.id, job_template.name)",
|
||||
"class": 'btn-danger btn-xs',
|
||||
awToolTip: 'Delete template',
|
||||
awToolTip: i18n._('Delete template'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'job_template.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,26 +7,27 @@
|
||||
|
||||
export default
|
||||
angular.module('PortalJobTemplatesListDefinition', [])
|
||||
.value('PortalJobTemplateList', {
|
||||
.factory('PortalJobTemplateList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'job_templates',
|
||||
iterator: 'job_template',
|
||||
editTitle: 'Job Templates',
|
||||
listTitle: 'Job Templates',
|
||||
editTitle: i18n._('Job Templates'),
|
||||
listTitle: i18n._('Job Templates'),
|
||||
index: false,
|
||||
hover: true,
|
||||
well: true,
|
||||
emptyListText: 'There are no job templates to display at this time',
|
||||
emptyListText: i18n._('There are no job templates to display at this time'),
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-5 col-md-5 col-sm-9 col-xs-8',
|
||||
linkTo: '/#/job_templates/{{job_template.id}}',
|
||||
searchDefault: true
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
columnClass: 'col-lg-4 col-md-4 hidden-sm hidden-xs'
|
||||
}
|
||||
},
|
||||
@ -36,11 +37,11 @@ export default
|
||||
|
||||
fieldActions: {
|
||||
submit: {
|
||||
label: 'Launch',
|
||||
label: i18n._('Launch'),
|
||||
mode: 'all',
|
||||
ngClick: 'submitJob(job_template.id)',
|
||||
awToolTip: 'Start a job using this template',
|
||||
awToolTip: i18n._('Start a job using this template'),
|
||||
dataPlacement: 'top'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,16 +7,17 @@
|
||||
|
||||
export default
|
||||
angular.module('PortalJobsListDefinition', [])
|
||||
.value( 'PortalJobsList', {
|
||||
.factory('PortalJobsList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'jobs',
|
||||
iterator: 'job',
|
||||
editTitle: 'Jobs',
|
||||
editTitle: i18n._('Jobs'),
|
||||
index: false,
|
||||
hover: true,
|
||||
well: true,
|
||||
listTitle: 'Jobs',
|
||||
emptyListText: 'There are no jobs to display at this time',
|
||||
listTitle: i18n._('Jobs'),
|
||||
emptyListText: i18n._('There are no jobs to display at this time'),
|
||||
|
||||
fields: {
|
||||
status: {
|
||||
@ -32,14 +33,14 @@ export default
|
||||
searchLabel: 'Status'
|
||||
},
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-4 col-md-4 col-sm-4 col-xs-6 List-staticColumnAdjacent',
|
||||
defaultSearchField: true,
|
||||
linkTo: '/#/jobs/{{job.id}}',
|
||||
searchDefault: true
|
||||
},
|
||||
finished: {
|
||||
label: 'Finished',
|
||||
label: i18n._('Finished'),
|
||||
noLink: true,
|
||||
searchable: false,
|
||||
filter: "longDate",
|
||||
@ -50,4 +51,4 @@ export default
|
||||
},
|
||||
|
||||
actions: { }
|
||||
});
|
||||
};}]);
|
||||
|
@ -4,16 +4,16 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
|
||||
export default
|
||||
angular.module('ProjectsListDefinition', [])
|
||||
.value('ProjectList', {
|
||||
.factory('ProjectList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'projects',
|
||||
iterator: 'project',
|
||||
selectTitle: 'Add Project',
|
||||
editTitle: 'Projects',
|
||||
listTitle: 'Projects',
|
||||
selectTitle: i18n._('Add Project'),
|
||||
editTitle: i18n._('Projects'),
|
||||
listTitle: i18n._('Projects'),
|
||||
selectInstructions: '<p>Select existing projects by clicking each project or checking the related checkbox. When finished, click the blue ' +
|
||||
'<em>Select</em> button, located bottom right.</p><p>Create a new project by clicking the <i class=\"fa fa-plus\"></i> button.</p>',
|
||||
index: false,
|
||||
@ -38,19 +38,19 @@ export default
|
||||
name: {
|
||||
key: true,
|
||||
searchDefault: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: "col-lg-4 col-md-4 col-sm-5 col-xs-7 List-staticColumnAdjacent",
|
||||
modalColumnClass: 'col-md-8'
|
||||
},
|
||||
scm_type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
searchType: 'select',
|
||||
searchOptions: [], // will be set by Options call to projects resource
|
||||
excludeModal: true,
|
||||
columnClass: 'col-lg-3 col-md-2 col-sm-3 hidden-xs'
|
||||
},
|
||||
last_updated: {
|
||||
label: 'Last Updated',
|
||||
label: i18n._('Last Updated'),
|
||||
filter: "longDate",
|
||||
columnClass: "col-lg-3 col-md-3 hidden-sm hidden-xs",
|
||||
excludeModal: true,
|
||||
@ -63,18 +63,18 @@ export default
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addProject()',
|
||||
awToolTip: 'Create a new project',
|
||||
awToolTip: i18n._('Create a new project'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: "canAdd"
|
||||
},
|
||||
refresh: {
|
||||
mode: 'all',
|
||||
awToolTip: "Refresh the page",
|
||||
awToolTip: i18n._("Refresh the page"),
|
||||
ngClick: "refresh()",
|
||||
ngShow: "socketStatus == 'error'",
|
||||
actionClass: 'btn List-buttonDefault',
|
||||
buttonContent: 'REFRESH'
|
||||
buttonContent: i18n._('REFRESH')
|
||||
}
|
||||
},
|
||||
|
||||
@ -100,28 +100,28 @@ export default
|
||||
},
|
||||
edit: {
|
||||
ngClick: "editProject(project.id)",
|
||||
awToolTip: 'Edit the project',
|
||||
awToolTip: i18n._('Edit the project'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: "project.summary_fields.user_capabilities.edit"
|
||||
},
|
||||
view: {
|
||||
ngClick: "editProject(project.id)",
|
||||
awToolTip: 'View the project',
|
||||
awToolTip: i18n._('View the project'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: "!project.summary_fields.user_capabilities.edit",
|
||||
icon: 'fa-eye',
|
||||
},
|
||||
"delete": {
|
||||
ngClick: "deleteProject(project.id, project.name)",
|
||||
awToolTip: 'Delete the project',
|
||||
awToolTip: i18n._('Delete the project'),
|
||||
ngShow: "(project.status !== 'updating' && project.status !== 'running' && project.status !== 'pending') && project.summary_fields.user_capabilities.delete",
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
cancel: {
|
||||
ngClick: "cancelUpdate(project.id, project.name)",
|
||||
awToolTip: 'Cancel the SCM update',
|
||||
awToolTip: i18n._('Cancel the SCM update'),
|
||||
ngShow: "(project.status == 'updating' || project.status == 'running' || project.status == 'pending') && project.summary_fields.user_capabilities.start",
|
||||
dataPlacement: 'top'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,14 +7,15 @@
|
||||
|
||||
export default
|
||||
angular.module('ScheduledJobsDefinition', ['sanitizeFilter'])
|
||||
.value( 'ScheduledJobsList', {
|
||||
.factory('ScheduledJobsList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'schedules',
|
||||
iterator: 'schedule',
|
||||
editTitle: 'Scheduled Jobs',
|
||||
editTitle: i18n._('Scheduled Jobs'),
|
||||
hover: true,
|
||||
well: false,
|
||||
emptyListText: 'No schedules exist',
|
||||
emptyListText: i18n._('No schedules exist'),
|
||||
|
||||
fields: {
|
||||
enabled: {
|
||||
@ -29,7 +30,7 @@ export default
|
||||
dataPlacement: 'top'
|
||||
},
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-4 col-md-5 col-sm-5 col-xs-7 List-staticColumnAdjacent',
|
||||
sourceModel: 'unified_job_template',
|
||||
sourceField: 'name',
|
||||
@ -40,7 +41,7 @@ export default
|
||||
defaultSearchField: true
|
||||
},
|
||||
type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
noLink: true,
|
||||
columnClass: "col-lg-2 col-md-2 hidden-sm hidden-xs",
|
||||
sourceModel: 'unified_job_template',
|
||||
@ -52,15 +53,15 @@ export default
|
||||
searchable: true,
|
||||
searchType: 'select',
|
||||
searchOptions: [
|
||||
{ value: 'inventorysource', label: 'Inventory Sync' },
|
||||
{ value: 'jobtemplate', label: 'Playbook Run' },
|
||||
{ value: 'project', label: 'SCM Update' },
|
||||
{ value: 'systemjobtemplate', label: 'Management Job'}
|
||||
{ value: 'inventorysource', label: i18n._('Inventory Sync') },
|
||||
{ value: 'jobtemplate', label: i18n._('Playbook Run') },
|
||||
{ value: 'project', label: i18n._('SCM Update') },
|
||||
{ value: 'systemjobtemplate', label: i18n._('Management Job')}
|
||||
|
||||
]
|
||||
},
|
||||
next_run: {
|
||||
label: 'Next Run',
|
||||
label: i18n._('Next Run'),
|
||||
noLink: true,
|
||||
searchable: false,
|
||||
columnClass: "col-lg-3 col-md-2 col-sm-3 hidden-xs",
|
||||
@ -77,23 +78,23 @@ export default
|
||||
"edit": {
|
||||
mode: "all",
|
||||
ngClick: "editSchedule(schedule)",
|
||||
awToolTip: "Edit the schedule",
|
||||
awToolTip: i18n._("Edit the schedule"),
|
||||
dataPlacement: "top",
|
||||
ngShow: 'schedule.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"view": {
|
||||
mode: "all",
|
||||
ngClick: "editSchedule(schedule)",
|
||||
awToolTip: "View the schedule",
|
||||
awToolTip: i18n._("View the schedule"),
|
||||
dataPlacement: "top",
|
||||
ngShow: '!schedule.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
mode: 'all',
|
||||
ngClick: 'deleteSchedule(schedule.id)',
|
||||
awToolTip: 'Delete the schedule',
|
||||
awToolTip: i18n._('Delete the schedule'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'schedule.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,13 +7,14 @@
|
||||
|
||||
export default
|
||||
angular.module('TeamsListDefinition', [])
|
||||
.value('TeamList', {
|
||||
.factory('TeamList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'teams',
|
||||
iterator: 'team',
|
||||
selectTitle: 'Add Team',
|
||||
editTitle: 'Teams',
|
||||
listTitle: 'Teams',
|
||||
selectTitle: i18n._('Add Team'),
|
||||
editTitle: i18n._('Teams'),
|
||||
listTitle: i18n._('Teams'),
|
||||
selectInstructions: "Click on a row to select it, and click Finished when done. Click the <i class=\"icon-plus\"></i> " +
|
||||
"button to create a new team.",
|
||||
index: false,
|
||||
@ -22,17 +23,17 @@ export default
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-lg-3 col-md-4 col-sm-9 col-xs-9',
|
||||
modalColumnClass: 'col-md-8'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
columnClass: 'col-lg-3 col-md-3 hidden-sm hidden-xs',
|
||||
excludeModal: true
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
ngBind: 'team.organization_name',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -45,9 +46,9 @@ export default
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addTeam()',
|
||||
awToolTip: 'Create a new team',
|
||||
awToolTip: i18n._('Create a new team'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -57,30 +58,30 @@ export default
|
||||
columnClass: 'col-lg-3 col-md-2 col-sm-3 col-xs-3',
|
||||
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
ngClick: "editTeam(team.id)",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
awToolTip: 'Edit team',
|
||||
awToolTip: i18n._('Edit team'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'team.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
view: {
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
ngClick: "editTeam(team.id)",
|
||||
"class": 'btn-xs btn-default',
|
||||
awToolTip: 'View team',
|
||||
awToolTip: i18n._('View team'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!team.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
ngClick: "deleteTeam(team.id, team.name)",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
awToolTip: 'Delete team',
|
||||
awToolTip: i18n._('Delete team'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'team.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -7,13 +7,14 @@
|
||||
|
||||
export default
|
||||
angular.module('UserListDefinition', [])
|
||||
.value('UserList', {
|
||||
.factory('UserList', ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
name: 'users',
|
||||
iterator: 'user',
|
||||
selectTitle: 'Add Users',
|
||||
editTitle: 'Users',
|
||||
listTitle: 'Users',
|
||||
selectTitle: i18n._('Add Users'),
|
||||
editTitle: i18n._('Users'),
|
||||
listTitle: i18n._('Users'),
|
||||
selectInstructions: '<p>Select existing users by clicking each user or checking the related checkbox. When finished, click the blue ' +
|
||||
'<em>Select</em> button, located bottom right.</p> <p>When available, a brand new user can be created by clicking the ' +
|
||||
'<i class=\"fa fa-plus\"></i> button.</p>',
|
||||
@ -23,15 +24,15 @@ export default
|
||||
fields: {
|
||||
username: {
|
||||
key: true,
|
||||
label: 'Username',
|
||||
label: i18n._('Username'),
|
||||
columnClass: 'col-md-3 col-sm-3 col-xs-9'
|
||||
},
|
||||
first_name: {
|
||||
label: 'First Name',
|
||||
label: i18n._('First Name'),
|
||||
columnClass: 'col-md-3 col-sm-3 hidden-xs'
|
||||
},
|
||||
last_name: {
|
||||
label: 'Last Name',
|
||||
label: i18n._('Last Name'),
|
||||
columnClass: 'col-md-3 col-sm-3 hidden-xs'
|
||||
}
|
||||
},
|
||||
@ -42,9 +43,9 @@ export default
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addUser()',
|
||||
basePaths: ['organizations', 'users'], // base path must be in list, or action not available
|
||||
awToolTip: 'Create a new user',
|
||||
awToolTip: i18n._('Create a new user'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -54,32 +55,32 @@ export default
|
||||
columnClass: 'col-md-3 col-sm-3 col-xs-3',
|
||||
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
ngClick: "editUser(user.id)",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
awToolTip: 'Edit user',
|
||||
awToolTip: i18n._('Edit user'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'user.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
|
||||
view: {
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
ngClick: "editUser(user.id)",
|
||||
"class": 'btn-xs btn-default',
|
||||
awToolTip: 'View user',
|
||||
awToolTip: i18n._('View user'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!user.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
ngClick: "deleteUser(user.id, user.username)",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
awToolTip: 'Delete user',
|
||||
awToolTip: i18n._('Delete user'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'user.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
});
|
||||
};}]);
|
||||
|
@ -10,7 +10,7 @@
|
||||
ng-src="/static/assets/{{ customLogo }}" >
|
||||
</div>
|
||||
<div class="LoginModal-body">
|
||||
<div class="LoginModal-alert" ng-show="!sessionExpired && !sessionLimitExpired && !attemptFailed && !thirdPartyAttemptFailed">
|
||||
<div class="LoginModal-alert" ng-show="!sessionExpired && !sessionLimitExpired && !attemptFailed && !thirdPartyAttemptFailed" translate>
|
||||
Welcome to Ansible Tower! Please sign in.
|
||||
</div>
|
||||
<div class="LoginModal-alert LoginModal-alert--error" ng-show="sessionExpired">
|
||||
@ -43,7 +43,7 @@
|
||||
autocomplete="off" novalidate>
|
||||
<div class="form-group LoginModal-formGroup">
|
||||
<label class="LoginModal-label
|
||||
col-md-12">USERNAME
|
||||
col-md-12" translate>USERNAME
|
||||
</label>
|
||||
<div class="col-md-12">
|
||||
<input type="text" name="login_username"
|
||||
@ -62,7 +62,7 @@
|
||||
</div>
|
||||
<div class="form-group LoginModal-formGroup">
|
||||
<label class="LoginModal-label
|
||||
col-md-12">PASSWORD
|
||||
col-md-12" translate>PASSWORD
|
||||
</label>
|
||||
<div class="col-md-12">
|
||||
<input type="password"
|
||||
@ -92,7 +92,7 @@
|
||||
LoginModal-footerBlock--submit">
|
||||
<button ng-click="systemLogin(login_username, login_password)"
|
||||
id="login-button"
|
||||
class="btn LoginModal-signInButton">
|
||||
class="btn LoginModal-signInButton" translate>
|
||||
SIGN IN
|
||||
</button>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
href="/#/projects"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('projects')}">
|
||||
<span class="MainMenu-itemText">
|
||||
PROJECTS
|
||||
<translate>PROJECTS</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -24,7 +24,7 @@
|
||||
href="/#/inventories"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('inventories')}">
|
||||
<span class="MainMenu-itemText">
|
||||
INVENTORIES
|
||||
<translate>INVENTORIES</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -32,7 +32,7 @@
|
||||
href="/#/job_templates"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobTemplates')}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOB TEMPLATES
|
||||
<translate>JOB TEMPLATES</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -40,7 +40,7 @@
|
||||
href="/#/jobs"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobs')}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOBS
|
||||
<translate>JOBS</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -48,7 +48,7 @@
|
||||
ng-href="/#/users/{{ $root.current_user.id }}"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('users.edit')}">
|
||||
<span class="MainMenu-itemText">
|
||||
VIEW USER PAGE FOR {{ $root.current_user.username | uppercase }}
|
||||
<translate>VIEW USER PAGE FOR {{ $root.current_user.username | uppercase }}</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -56,7 +56,7 @@
|
||||
ng-href="/#/setup"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('setup')}">
|
||||
<span class="MainMenu-itemText">
|
||||
SETTINGS
|
||||
<translate>SETTINGS</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -64,7 +64,7 @@
|
||||
ui-sref="portalMode"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('portalMode')}">
|
||||
<span class="MainMenu-itemText">
|
||||
PORTAL MODE
|
||||
<translate>PORTAL MODE</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -72,7 +72,7 @@
|
||||
ng-href="http://docs.ansible.com/ansible-tower/"
|
||||
target="_blank">
|
||||
<span class="MainMenu-itemText">
|
||||
VIEW DOCUMENTATION
|
||||
<translate>VIEW DOCUMENTATION</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item"
|
||||
@ -80,7 +80,7 @@
|
||||
ng-href="/#/logout"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('logout')}">
|
||||
<span class="MainMenu-itemText">
|
||||
LOG OUT
|
||||
<translate>LOG OUT</translate>
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
@ -92,7 +92,7 @@
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('projects'), 'is-loggedOut' : !current_user || !current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
PROJECTS
|
||||
<translate>PROJECTS</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
|
||||
@ -101,7 +101,7 @@
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('inventories'), 'is-loggedOut' : !current_user || !current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
INVENTORIES
|
||||
<translate>INVENTORIES</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left"
|
||||
@ -110,7 +110,7 @@
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobTemplates'), 'is-loggedOut' : !current_user || !current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOB TEMPLATES
|
||||
<translate>JOB TEMPLATES</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--left MainMenu-item--lastLeft"
|
||||
@ -119,7 +119,7 @@
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('jobs'), 'is-loggedOut' : !current_user || !current_user.username}">
|
||||
<span class="MainMenu-itemText">
|
||||
JOBS
|
||||
<translate>JOBS</translate>
|
||||
</span>
|
||||
</a>
|
||||
<a class="MainMenu-item MainMenu-item--notMobile MainMenu-item--user MainMenu-item--right"
|
||||
@ -144,7 +144,7 @@
|
||||
ng-href="/#/setup"
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('setup'), 'is-loggedOut' : !current_user || !current_user.username}"
|
||||
aw-tool-tip="Settings"
|
||||
aw-tool-tip="{{'Settings'|translate}}"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
data-container="body">
|
||||
@ -157,7 +157,7 @@
|
||||
ng-href="/#/portal"
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-currentRoute' : isCurrentState('portalMode'), 'is-loggedOut' : !current_user || !current_user.username}"
|
||||
aw-tool-tip="My View"
|
||||
aw-tool-tip="{{'My View'|translate}}"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
data-container="body">
|
||||
@ -170,7 +170,7 @@
|
||||
ng-href="http://docs.ansible.com/ansible-tower/"
|
||||
ng-hide="licenseMissing"
|
||||
ng-class="{'is-loggedOut' : !current_user || !current_user.username}"
|
||||
aw-tool-tip="View Documentation"
|
||||
aw-tool-tip="{{'View Documentation'|translate}}"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
data-container="body"
|
||||
@ -185,7 +185,7 @@
|
||||
ng-class="{'is-currentRoute' : isCurrentState('logout'),
|
||||
'is-loggedOut' : !current_user || !current_user.username,
|
||||
'MainMenu-item--licenseMissing' : licenseMissing}"
|
||||
aw-tool-tip="Log Out"
|
||||
aw-tool-tip="{{'Log Out'|translate}}"
|
||||
data-placement="bottom"
|
||||
data-trigger="hover"
|
||||
data-container="body"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div ui-view></div>
|
||||
<div class="tab-pane Panel" id="management_jobs">
|
||||
<div class="List-title">
|
||||
<div class="List-titleText">
|
||||
<div class="List-titleText" translate>
|
||||
Management Jobs
|
||||
</div>
|
||||
<span class="badge List-titleBadge ng-binding">
|
||||
@ -18,18 +18,18 @@
|
||||
<button class="MgmtCards-actionItem List-actionButton"
|
||||
ng-click='chooseRunJob(card.id, card.name)'
|
||||
ng-show='current_user.is_superuser'
|
||||
data-placement="top" aw-tool-tip="Launch Management Job" data-original-title="" title="">
|
||||
data-placement="top" aw-tool-tip="{{'Launch Management Job'|translate}}" data-original-title="" title="">
|
||||
<i class="MgmtCards-actionItemIcon icon-launch"></i>
|
||||
</button>
|
||||
<button class="MgmtCards-actionItem List-actionButton"
|
||||
ng-click='configureSchedule(card.id)'
|
||||
data-placement="top" aw-tool-tip="Schedule Management Job" data-original-title="" title="">
|
||||
data-placement="top" aw-tool-tip="{{'Schedule Management Job'|translate}}" data-original-title="" title="">
|
||||
<i class="MgmtCards-actionItemIcon fa fa-calendar"></i>
|
||||
</button>
|
||||
<button class="MgmtCards-actionItem List-actionButton"
|
||||
ng-click='goToNotifications(card, card.id)'
|
||||
ng-show='current_user.is_superuser'
|
||||
data-placement="top" aw-tool-tip="Configure Notifications" data-original-title="" title="" ng-class="{'List-editButton--selected': activeCard === card.id && cardAction === 'notifications'}">
|
||||
data-placement="top" aw-tool-tip="{{'Configure Notifications'|translate}}" data-original-title="" title="" ng-class="{'List-editButton--selected': activeCard === card.id && cardAction === 'notifications'}">
|
||||
<i class="MgmtCards-actionItemIcon fa fa-bell-o"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -10,20 +10,20 @@
|
||||
* @description This form is for adding/editing an organization
|
||||
*/
|
||||
|
||||
export default function() {
|
||||
export default ['i18n', function(i18n) {
|
||||
return {
|
||||
|
||||
addTitle: 'New Notification Template',
|
||||
addTitle: i18n._('New Notification Template'),
|
||||
editTitle: '{{ name }}',
|
||||
name: 'notification_template',
|
||||
showActions: true,
|
||||
subFormTitles: {
|
||||
typeSubForm: 'Type Details',
|
||||
typeSubForm: i18n._('Type Details'),
|
||||
},
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
type: 'text',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -31,14 +31,14 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
description: {
|
||||
label: 'Description',
|
||||
label: i18n._('Description'),
|
||||
type: 'text',
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
organization: {
|
||||
label: 'Organization',
|
||||
label: i18n._('Organization'),
|
||||
type: 'lookup',
|
||||
sourceModel: 'organization',
|
||||
sourceField: 'name',
|
||||
@ -50,7 +50,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
notification_type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
type: 'select',
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
@ -61,7 +61,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
username: {
|
||||
label: 'Username',
|
||||
label: i18n._('Username'),
|
||||
type: 'text',
|
||||
ngShow: "notification_type.value == 'email' ",
|
||||
subForm: 'typeSubForm',
|
||||
@ -69,7 +69,7 @@ export default function() {
|
||||
},
|
||||
|
||||
host: {
|
||||
label: 'Host',
|
||||
label: i18n._('Host'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "email_required",
|
||||
@ -80,7 +80,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
sender: {
|
||||
label: 'Sender Email',
|
||||
label: i18n._('Sender Email'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "email_required",
|
||||
@ -91,12 +91,12 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
recipients: {
|
||||
label: 'Recipient List',
|
||||
label: i18n._('Recipient List'),
|
||||
type: 'textarea',
|
||||
rows: 3,
|
||||
awPopOver: '<p>Type an option on each line.</p>'+
|
||||
'<p>For example:<br>alias1@email.com<br>\n alias2@email.com<br>\n',
|
||||
dataTitle: 'Recipient List',
|
||||
awPopOver: i18n._('<p>Type an option on each line.</p>'+
|
||||
'<p>For example:<br>alias1@email.com<br>\n alias2@email.com<br>\n'),
|
||||
dataTitle: i18n._('Recipient List'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
awRequiredWhen: {
|
||||
@ -135,12 +135,12 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
channels: {
|
||||
label: 'Destination Channels',
|
||||
label: i18n._('Destination Channels'),
|
||||
type: 'textarea',
|
||||
rows: 3,
|
||||
awPopOver: '<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>engineering<br>\n #support<br>\n',
|
||||
dataTitle: 'Destination Channels',
|
||||
awPopOver: i18n._('<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>engineering<br>\n #support<br>\n'),
|
||||
dataTitle: i18n._('Destination Channels'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
awRequiredWhen: {
|
||||
@ -152,12 +152,12 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
rooms: {
|
||||
label: 'Destination Channels',
|
||||
label: i18n._('Destination Channels'),
|
||||
type: 'textarea',
|
||||
rows: 3,
|
||||
awPopOver: '<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>engineering<br>\n #support<br>\n',
|
||||
dataTitle: 'Destination Channels',
|
||||
awPopOver: i18n._('<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>engineering<br>\n #support<br>\n'),
|
||||
dataTitle: i18n._('Destination Channels'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
awRequiredWhen: {
|
||||
@ -181,7 +181,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
account_token: {
|
||||
label: 'Account Token',
|
||||
label: i18n._('Account Token'),
|
||||
type: 'sensitive',
|
||||
hasShowInputButton: true,
|
||||
awRequiredWhen: {
|
||||
@ -193,10 +193,10 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
from_number: {
|
||||
label: 'Source Phone Number',
|
||||
label: i18n._('Source Phone Number'),
|
||||
type: 'text',
|
||||
awPopOver: '<p>Number associated with the "Messaging Service" in Twilio.</p>'+
|
||||
'<p>This must be of the form <code>+18005550199</code>.</p>',
|
||||
awPopOver: i18n._('<p>Number associated with the "Messaging Service" in Twilio.</p>'+
|
||||
'<p>This must be of the form <code>+18005550199</code>.</p>'),
|
||||
awRequiredWhen: {
|
||||
reqExpression: "twilio_required",
|
||||
init: "false"
|
||||
@ -206,12 +206,12 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
to_numbers: {
|
||||
label: 'Destination SMS Number',
|
||||
label: i18n._('Destination SMS Number'),
|
||||
type: 'textarea',
|
||||
rows: 3,
|
||||
awPopOver: '<p>Type an option on each line.</p>'+
|
||||
'<p>For example:<br><code>+12125552368</code><br>\n<code>+19105556162</code><br>\n',
|
||||
dataTitle: 'Destination SMS Number',
|
||||
awPopOver: i18n._('<p>Type an option on each line.</p>'+
|
||||
'<p>For example:<br><code>+12125552368</code><br>\n<code>+19105556162</code><br>\n'),
|
||||
dataTitle: i18n._('Destination SMS Number'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
awRequiredWhen: {
|
||||
@ -223,7 +223,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
account_sid: {
|
||||
label: 'Account SID',
|
||||
label: i18n._('Account SID'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "twilio_required",
|
||||
@ -234,7 +234,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
subdomain: {
|
||||
label: 'Pagerduty subdomain',
|
||||
label: i18n._('Pagerduty subdomain'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "pagerduty_required",
|
||||
@ -245,7 +245,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
service_key: {
|
||||
label: 'API Service/Integration Key',
|
||||
label: i18n._('API Service/Integration Key'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "pagerduty_required",
|
||||
@ -256,7 +256,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
client_name: {
|
||||
label: 'Client Identifier',
|
||||
label: i18n._('Client Identifier'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "pagerduty_required",
|
||||
@ -267,7 +267,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
message_from: {
|
||||
label: 'Label to be shown with notification',
|
||||
label: i18n._('Label to be shown with notification'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "hipchat_required",
|
||||
@ -290,10 +290,10 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
color: {
|
||||
label: 'Notification Color',
|
||||
label: i18n._('Notification Color'),
|
||||
type: 'text',
|
||||
awPopOver: '<p>Color can be one of <code>yellow</code>, <code>green</code>, <code>red</code>, ' +
|
||||
'<code>purple</code>, <code>gray</code>, or <code>random</code>.\n',
|
||||
awPopOver: i18n._('<p>Color can be one of <code>yellow</code>, <code>green</code>, <code>red</code>, ' +
|
||||
'<code>purple</code>, <code>gray</code>, or <code>random</code>.\n'),
|
||||
awRequiredWhen: {
|
||||
reqExpression: "hipchat_required",
|
||||
init: "false"
|
||||
@ -303,14 +303,14 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
notify: {
|
||||
label: 'Notify Channel',
|
||||
label: i18n._('Notify Channel'),
|
||||
type: 'checkbox',
|
||||
ngShow: "notification_type.value == 'hipchat' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
url: {
|
||||
label: 'Target URL',
|
||||
label: i18n._('Target URL'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "webhook_required",
|
||||
@ -321,7 +321,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
headers: {
|
||||
label: 'HTTP Headers',
|
||||
label: i18n._('HTTP Headers'),
|
||||
type: 'textarea',
|
||||
rows: 5,
|
||||
'class': 'Form-formGroup--fullWidth',
|
||||
@ -329,20 +329,20 @@ export default function() {
|
||||
reqExpression: "webhook_required",
|
||||
init: "false"
|
||||
},
|
||||
awPopOver: '<p>Specify HTTP Headers in JSON format</p>' +
|
||||
awPopOver: i18n._('<p>Specify HTTP Headers in JSON format</p>' +
|
||||
'<p>For example:<br><pre>\n' +
|
||||
'{\n' +
|
||||
' "X-Auth-Token": "828jf0",\n' +
|
||||
' "X-Ansible": "Is great!"\n' +
|
||||
'}\n' +
|
||||
'</pre></p>',
|
||||
'</pre></p>'),
|
||||
dataPlacement: 'right',
|
||||
ngShow: "notification_type.value == 'webhook' ",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
server: {
|
||||
label: 'IRC Server Address',
|
||||
label: i18n._('IRC Server Address'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "irc_required",
|
||||
@ -353,7 +353,7 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
nickname: {
|
||||
label: 'IRC Nick',
|
||||
label: i18n._('IRC Nick'),
|
||||
type: 'text',
|
||||
awRequiredWhen: {
|
||||
reqExpression: "irc_required",
|
||||
@ -364,12 +364,12 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
targets: {
|
||||
label: 'Destination Channels or Users',
|
||||
label: i18n._('Destination Channels or Users'),
|
||||
type: 'textarea',
|
||||
rows: 3,
|
||||
awPopOver: '<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>#support or support<br>\n @username or username<br>\n',
|
||||
dataTitle: 'Destination Channels',
|
||||
awPopOver: i18n._('<p>Type an option on each line. The pound symbol (#) is not required.</p>'+
|
||||
'<p>For example:<br>#support or support<br>\n @username or username<br>\n'),
|
||||
dataTitle: i18n._('Destination Channels'),
|
||||
dataPlacement: 'right',
|
||||
dataContainer: "body",
|
||||
awRequiredWhen: {
|
||||
@ -381,27 +381,27 @@ export default function() {
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
use_ssl: {
|
||||
label: 'SSL Connection',
|
||||
label: i18n._('SSL Connection'),
|
||||
type: 'checkbox',
|
||||
ngShow: "notification_type.value == 'irc'",
|
||||
subForm: 'typeSubForm',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
},
|
||||
checkbox_group: {
|
||||
label: 'Options',
|
||||
label: i18n._('Options'),
|
||||
type: 'checkbox_group',
|
||||
subForm: 'typeSubForm',
|
||||
ngShow: "notification_type.value == 'email'",
|
||||
fields: [{
|
||||
name: 'use_tls',
|
||||
label: 'Use TLS',
|
||||
label: i18n._('Use TLS'),
|
||||
type: 'checkbox',
|
||||
ngShow: "notification_type.value == 'email' ",
|
||||
labelClass: 'checkbox-options stack-inline',
|
||||
ngDisabled: '!(notification_template.summary_fields.user_capabilities.edit || canAdd)'
|
||||
}, {
|
||||
name: 'use_ssl',
|
||||
label: 'Use SSL',
|
||||
label: i18n._('Use SSL'),
|
||||
type: 'checkbox',
|
||||
ngShow: "notification_type.value == 'email'",
|
||||
labelClass: 'checkbox-options stack-inline',
|
||||
@ -426,4 +426,4 @@ export default function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -8,10 +8,10 @@
|
||||
* off of the settings page
|
||||
*/
|
||||
|
||||
export default function(){
|
||||
export default ['i18n', function(i18n){
|
||||
return {
|
||||
name: 'notification_templates' ,
|
||||
listTitle: 'Notification Templates',
|
||||
listTitle: i18n._('Notification Templates'),
|
||||
iterator: 'notification_template',
|
||||
index: false,
|
||||
hover: false,
|
||||
@ -30,12 +30,12 @@ export default function(){
|
||||
},
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-3 col-sm-9 col-xs-9',
|
||||
linkTo: '/#/notification_templates/{{notification_template.id}}'
|
||||
},
|
||||
notification_type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
searchType: 'select',
|
||||
searchOptions: [],
|
||||
excludeModal: true,
|
||||
@ -47,9 +47,9 @@ export default function(){
|
||||
add: {
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addNotification()',
|
||||
awToolTip: 'Create a new custom inventory',
|
||||
awToolTip: i18n._('Create a new custom inventory'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD',
|
||||
buttonContent: i18n._('+ ADD'),
|
||||
ngShow: 'canAdd'
|
||||
}
|
||||
},
|
||||
@ -60,38 +60,38 @@ export default function(){
|
||||
test: {
|
||||
ngClick: "testNotification(notification_template.id)",
|
||||
icon: 'fa-bell-o',
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Test notification',
|
||||
awToolTip: i18n._('Test notification'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'notification_template.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
edit: {
|
||||
ngClick: "editNotification(notification_template.id)",
|
||||
icon: 'fa-edit',
|
||||
label: 'Edit',
|
||||
label: i18n._('Edit'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Edit notification',
|
||||
awToolTip: i18n._('Edit notification'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'notification_template.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
view: {
|
||||
ngClick: "editNotification(notification_template.id)",
|
||||
label: 'View',
|
||||
label: i18n._('View'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'View notification',
|
||||
awToolTip: i18n._('View notification'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: '!notification_template.summary_fields.user_capabilities.edit'
|
||||
},
|
||||
"delete": {
|
||||
ngClick: "deleteNotification(notification_template.id, notification_template.name)",
|
||||
icon: 'fa-trash',
|
||||
label: 'Delete',
|
||||
label: i18n._('Delete'),
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Delete notification',
|
||||
awToolTip: i18n._('Delete notification'),
|
||||
dataPlacement: 'top',
|
||||
ngShow: 'notification_template.summary_fields.user_capabilities.delete'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -8,13 +8,13 @@
|
||||
* used in the related tabs
|
||||
*/
|
||||
|
||||
export default function(){
|
||||
export default ['i18n', function(i18n){
|
||||
return {
|
||||
// These tooltip fields are consumed to build disabled related tabs tooltips in the form > add view
|
||||
dataPlacement: 'top',
|
||||
awToolTip: 'Please save before adding notifications',
|
||||
awToolTip: i18n._('Please save before adding notifications'),
|
||||
name: 'notifications' ,
|
||||
title: 'Notifications',
|
||||
title: i18n._('Notifications'),
|
||||
iterator: 'notification',
|
||||
index: false,
|
||||
hover: false,
|
||||
@ -23,19 +23,19 @@ export default function(){
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'Name',
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-3 col-sm-9 col-xs-9',
|
||||
linkTo: '/#/notification_templates/{{notifier.id}}',
|
||||
},
|
||||
notification_type: {
|
||||
label: 'Type',
|
||||
label: i18n._('Type'),
|
||||
searchType: 'select',
|
||||
searchOptions: [],
|
||||
excludeModal: true,
|
||||
columnClass: 'col-md-4 hidden-sm hidden-xs'
|
||||
},
|
||||
notification_templates_success: {
|
||||
label: 'Success',
|
||||
label: i18n._('Success'),
|
||||
flag: 'notification_templates_success',
|
||||
type: "toggle",
|
||||
ngClick: "toggleNotification($event, notification.id, \"notification_templates_success\")",
|
||||
@ -46,7 +46,7 @@ export default function(){
|
||||
nosort: true,
|
||||
},
|
||||
notification_templates_error: {
|
||||
label: 'Failure',
|
||||
label: i18n._('Failure'),
|
||||
columnClass: 'NotifierList-lastColumn',
|
||||
flag: 'notification_templates_error',
|
||||
type: "toggle",
|
||||
@ -63,12 +63,12 @@ export default function(){
|
||||
label: 'Add Notification',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addNotificationTemplate()',
|
||||
awToolTip: 'Create a new notification template',
|
||||
awToolTip: i18n._('Create a new notification template'),
|
||||
actionClass: 'btn List-buttonSubmit',
|
||||
buttonContent: '+ ADD NOTIFICATION TEMPLATE',
|
||||
buttonContent: i18n._('+ ADD NOTIFICATION TEMPLATE'),
|
||||
ngShow: 'current_user.is_superuser || (current_user_admin_orgs && current_user_admin_orgs.length > 0)'
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
@ -4,8 +4,8 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default [
|
||||
function () {
|
||||
export default ['i18n',
|
||||
function (i18n) {
|
||||
return{
|
||||
getDetailFields: function(type) {
|
||||
var obj = {};
|
||||
@ -24,20 +24,20 @@ function () {
|
||||
obj.room_required = false;
|
||||
switch (type) {
|
||||
case 'email':
|
||||
obj.portLabel = ' Port';
|
||||
obj.passwordLabel = ' Password';
|
||||
obj.portLabel = ' ' + i18n._('Port');
|
||||
obj.passwordLabel = ' ' + i18n._('Password');
|
||||
obj.email_required = true;
|
||||
obj.port_required = true;
|
||||
obj.password_required = false;
|
||||
break;
|
||||
case 'slack':
|
||||
obj.tokenLabel =' Token';
|
||||
obj.tokenLabel =' ' + i18n._('Token');
|
||||
obj.slack_required = true;
|
||||
obj.token_required = true;
|
||||
obj.channel_required = true;
|
||||
break;
|
||||
case 'hipchat':
|
||||
obj.tokenLabel = ' Token';
|
||||
obj.tokenLabel = ' ' + i18n._('Token');
|
||||
obj.hipchat_required = true;
|
||||
obj.room_required = true;
|
||||
obj.token_required = true;
|
||||
@ -49,13 +49,13 @@ function () {
|
||||
obj.webhook_required = true;
|
||||
break;
|
||||
case 'pagerduty':
|
||||
obj.tokenLabel = ' API Token';
|
||||
obj.tokenLabel = ' ' + i18n._('API Token');
|
||||
obj.pagerduty_required = true;
|
||||
obj.token_required = true;
|
||||
break;
|
||||
case 'irc':
|
||||
obj.portLabel = ' IRC Server Port';
|
||||
obj.passwordLabel = ' IRC Server Password';
|
||||
obj.portLabel = ' ' + i18n._('IRC Server Port');
|
||||
obj.passwordLabel = ' ' + i18n._('IRC Server Password');
|
||||
obj.irc_required = true;
|
||||
obj.password_required = true;
|
||||
obj.port_required = true;
|
||||
|
@ -3,18 +3,19 @@
|
||||
<div ng-cloak id="htmlTemplate" class="Panel">
|
||||
<div class="List-header">
|
||||
<div class="List-title">
|
||||
<div class="List-titleText">
|
||||
organizations
|
||||
<div class="List-titleText" translate>
|
||||
ORGANIZATIONS
|
||||
</div>
|
||||
<span class="badge List-titleBadge">
|
||||
{{ orgCount }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="List-actions">
|
||||
<!-- + ADD -->
|
||||
<button class="btn List-buttonSubmit"
|
||||
aw-tool-tip="Create a new organization"
|
||||
aw-tool-tip="{{'Create a new organization'|translate}}"
|
||||
ng-show="canAdd"
|
||||
ng-click="addOrganization()">
|
||||
ng-click="addOrganization()" translate>
|
||||
+ ADD
|
||||
</button>
|
||||
</div>
|
||||
@ -22,7 +23,7 @@
|
||||
<div class="List-well">
|
||||
<div class="OrgCards-search" ng-hide="organizationLoading == false && organization_active_search == false && organization_total_rows < 1">
|
||||
</div>
|
||||
<div class="List-noItems" ng-show="organizationLoading == false && organization_active_search == false && organization_total_rows < 1">PLEASE ADD ITEMS TO THIS LIST</div>
|
||||
<div class="List-noItems" ng-show="organizationLoading == false && organization_active_search == false && organization_total_rows < 1" translate>PLEASE ADD ITEMS TO THIS LIST</div>
|
||||
<div class="OrgCards" id="OrgCards">
|
||||
<div class="OrgCards-card"
|
||||
ng-class="{'OrgCards-card--selected': activeCard === card.id || card.isActiveCard }"
|
||||
|
@ -1,8 +1,8 @@
|
||||
<ol class="BreadCrumb-list">
|
||||
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:(steps.length-1)">
|
||||
<a href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a>
|
||||
<a href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel|translate}}</a>
|
||||
</li>
|
||||
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:-1" class="active">
|
||||
<span>{{step.ncyBreadcrumbLabel}}</span>
|
||||
<span>{{step.ncyBreadcrumbLabel|translate}}</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
@ -7,17 +7,17 @@
|
||||
<div class= "Form-tab is-selected" id="active_jobs_link"
|
||||
ng-class="{'is-selected': jobsSelected }"
|
||||
ng-click="toggleTab('jobs')">
|
||||
Jobs
|
||||
<translate>Jobs</translate>
|
||||
</div>
|
||||
<div id="scheduled_jobs_link" class="Form-tab"
|
||||
ng-class="{'is-selected': schedulesSelected }"
|
||||
ng-click="toggleTab('scheduled')">
|
||||
Schedules
|
||||
<translate>Schedules</translate>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Form-tabActions">
|
||||
<button id="refresh_btn" ng-show="socketStatus === 'error'" aw-tool-tip="Refresh the page" data-placement="top" class="btn List-buttonDefault" ng-click="refreshJobs()" toolbar="true">
|
||||
<span>REFRESH</span>
|
||||
<button id="refresh_btn" ng-show="socketStatus === 'error'" aw-tool-tip="{{'Refresh the page'|translate}}" data-placement="top" class="btn List-buttonDefault" ng-click="refreshJobs()" toolbar="true">
|
||||
<span translate>REFRESH</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,13 +3,13 @@
|
||||
<div class="btn-group PortalMode-filter">
|
||||
<button ng-class="{'btn-primary ': activeFilter == 'user',
|
||||
'btn-default' : activeFilter != 'user' }"
|
||||
ng-click='filterUser()' class="btn btn-xs">My Jobs</button>
|
||||
ng-click='filterUser()' class="btn btn-xs" translate>My Jobs</button>
|
||||
<button ng-class="{'btn-primary' : activeFilter == 'all',
|
||||
'btn-default' : activeFilter != 'all'}" ng-click='filterAll()' class="btn btn-xs btn-default">All Jobs</button>
|
||||
'btn-default' : activeFilter != 'all'}" ng-click='filterAll()' class="btn btn-xs btn-default" translate>All Jobs</button>
|
||||
</div>
|
||||
<div class="PortalMode-refresh">
|
||||
<button id="refresh_btn" aw-tool-tip="Refresh the page" data-placement="top" class="btn List-buttonDefault" ng-click="refresh()" ng-show="socketStatus == 'error'">
|
||||
<span>REFRESH</span>
|
||||
<span translate>REFRESH</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,57 +1,57 @@
|
||||
<section id="htmlTemplate" class="Container">
|
||||
<div class="SetupMenu">
|
||||
<a ui-sref="organizations" class="SetupItem">
|
||||
<h4 class="SetupItem-title ">Organizations</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title " translate>Organizations</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Group all of your content to manage permissions across departments in your company.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="users" class="SetupItem">
|
||||
<h4 class="SetupItem-title">Users</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Users</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Allow others to sign into Tower and own the content they create.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="teams" class="SetupItem">
|
||||
<h4 class="SetupItem-title">Teams</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Teams</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Split up your organization to associate content and control permissions for groups.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="credentials" class="SetupItem">
|
||||
<h4 class="SetupItem-title">Credentials</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Credentials</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Add passwords, SSH keys, etc. for Tower to use when launching jobs against machines, or when syncing inventories or projects.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="managementJobsList" class="SetupItem" ng-if="user_is_superuser || user_is_system_auditor">
|
||||
<h4 class="SetupItem-title">Management Jobs</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Management Jobs</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Manage the cleanup of old job history, activity streams, data marked for deletion, and system tracking info.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="inventoryScripts" class="SetupItem">
|
||||
<h4 class="SetupItem-title">Inventory Scripts</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Inventory Scripts</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Create and edit scripts to dynamically load hosts from any source.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="notifications" class="SetupItem"
|
||||
ng-if="orgAdmin || user_is_system_auditor || user_is_superuser">
|
||||
<h4 class="SetupItem-title">Notifications</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>Notifications</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
Create templates for sending notifications with Email, HipChat, Slack, and SMS.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="license" class="SetupItem">
|
||||
<h4 class="SetupItem-title">View Your License</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>View Your License</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
View and edit your license information.
|
||||
</p>
|
||||
</a>
|
||||
<a ui-sref="setup.about" class="SetupItem">
|
||||
<h4 class="SetupItem-title">About Tower</h4>
|
||||
<p class="SetupItem-description">
|
||||
<h4 class="SetupItem-title" translate>About Tower</h4>
|
||||
<p class="SetupItem-description" translate>
|
||||
View information about this version of Ansible Tower.
|
||||
</p>
|
||||
</a>
|
||||
|
@ -142,10 +142,11 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
.factory('GenerateForm', ['$rootScope', '$location', '$compile', 'generateList',
|
||||
'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'Column',
|
||||
'NavigationLink', 'HelpCollapse', 'DropDown', 'Empty', 'SelectIcon',
|
||||
'Store', 'ActionButton', 'getSearchHtml',
|
||||
'Store', 'ActionButton', 'getSearchHtml', 'i18n',
|
||||
function ($rootScope, $location, $compile, GenerateList, SearchWidget,
|
||||
PaginateWidget, Attr, Icon, Column, NavigationLink, HelpCollapse,
|
||||
DropDown, Empty, SelectIcon, Store, ActionButton, getSearchHtml) {
|
||||
DropDown, Empty, SelectIcon, Store, ActionButton, getSearchHtml,
|
||||
i18n) {
|
||||
return {
|
||||
|
||||
setForm: function (form) { this.form = form; },
|
||||
@ -875,20 +876,27 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
// Add error messages
|
||||
if ((options.mode === 'add' && field.addRequired) || (options.mode === 'edit' && field.editRequired) ||
|
||||
field.awRequiredWhen) {
|
||||
var error_message = i18n._("Please enter a value.");
|
||||
html += "<div class=\"error\" id=\"" + this.form.name + "-" + fld + "-required-error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
|
||||
this.form.name + '_form.' + fld + ".$error.required\">" + (field.requiredErrorMsg ? field.requiredErrorMsg : "Please enter a value.") + "</div>\n";
|
||||
this.form.name + '_form.' + fld + ".$error.required\">" + (field.requiredErrorMsg ? field.requiredErrorMsg : error_message) + "</div>\n";
|
||||
}
|
||||
if (field.type === "email") {
|
||||
var error_message = i18n._("Please enter a valid email address.");
|
||||
html += "<div class=\"error\" id=\"" + this.form.name + "-" + fld + "-email-error\" ng-show=\"" + this.form.name + '_form.' + fld + ".$dirty && " +
|
||||
this.form.name + '_form.' + fld + ".$error.email\">Please enter a valid email address.</div>\n";
|
||||
this.form.name + '_form.' + fld + ".$error.email\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if (field.awPassMatch) {
|
||||
var error_message = i18n._("This value does not match the password you entered previously. Please confirm that password.");
|
||||
html += "<div class=\"error\" id=\"" + this.form.name + "-" + fld + "-passmatch-error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.awpassmatch\">This value does not match the password you entered previously. Please confirm that password.</div>\n";
|
||||
".$error.awpassmatch\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if (field.awValidUrl) {
|
||||
var error_message = i18n._("Please enter a URL that begins with ssh, http or https. The URL may not contain the '@' character.");
|
||||
html += "<div class=\"error\" id=\"" + this.form.name + "-" + fld + "-url-error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.awvalidurl\">Please enter a URL that begins with ssh, http or https. The URL may not contain the '@' character. </div>\n";
|
||||
".$error.awvalidurl\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
|
||||
html += "<div class=\"error api-error\" id=\"" + this.form.name + "-" + fld + "-api-error\" ng-bind=\"" + fld + "_api_error\"></div>\n";
|
||||
@ -901,7 +909,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
|
||||
//fields with sensitive data that needs to be obfuscated from view
|
||||
if (field.type === 'sensitive') {
|
||||
field.showInputInnerHTML = "Show";
|
||||
field.showInputInnerHTML = i18n._("Show");
|
||||
field.inputType = "password";
|
||||
|
||||
html += "\t" + label();
|
||||
@ -918,6 +926,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
$(inputId).attr("type", "password");
|
||||
}
|
||||
};
|
||||
var tooltip = i18n._("Toggle the display of plaintext.");
|
||||
html += "\<div class='input-group";
|
||||
html += (horizontal) ? " " + getFieldWidth() : "";
|
||||
html += "'>\n";
|
||||
@ -925,7 +934,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "<span class='input-group-btn'>\n";
|
||||
html += "<button type='button' class='btn btn-default show_input_button Form-passwordButton' ";
|
||||
html += buildId(field, fld + "_show_input_button", this.form);
|
||||
html += "aw-tool-tip='Toggle the display of plaintext.' aw-tip-placement='top' ";
|
||||
html += "aw-tool-tip='" + tooltip + "' aw-tip-placement='top' ";
|
||||
html += "tabindex='-1' ";
|
||||
html += "ng-click='" + fld + "_field.toggleInput(\"#" + this.form.name + "_" + fld + "\")'";
|
||||
html += (field.ngDisabled) ? "ng-disabled='" + field.ngDisabled + "'" : "";
|
||||
@ -997,42 +1006,59 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
// Add error messages
|
||||
if ((options.mode === 'add' && field.addRequired) || (options.mode === 'edit' && field.editRequired) ||
|
||||
field.awRequiredWhen) {
|
||||
var error_message = i18n._("Please enter a value.");
|
||||
html += "<div class='error' id='" + this.form.name + "-" + fld + "-required-error' ng-show='" + this.form.name + "_form." + fld + ".$dirty && " +
|
||||
this.form.name + "_form." + fld + ".$error.required'>\n" + (field.requiredErrorMsg ? field.requiredErrorMsg : "Please enter a value.") + "\n</div>\n";
|
||||
this.form.name + "_form." + fld + ".$error.required'>\n" + (field.requiredErrorMsg ? field.requiredErrorMsg : error_message) + "\n</div>\n";
|
||||
}
|
||||
if (field.type === "email") {
|
||||
var error_message = i18n._("Please enter a valid email address.");
|
||||
html += "<div class='error' id='" + this.form.name + "-" + fld + "-email-error' ng-show='" + this.form.name + "_form." + fld + ".$dirty && " +
|
||||
this.form.name + "_form." + fld + ".$error.email'>\nPlease enter a valid email address.\n</div>\n";
|
||||
this.form.name + "_form." + fld + ".$error.email'>\n" +
|
||||
error_message + "\n</div>\n";
|
||||
}
|
||||
if (field.awPassMatch) {
|
||||
var error_message = i18n._("This value does not match the password you entered previously. Please confirm that password.");
|
||||
html += "<div class='error' id='" + this.form.name + "-" + fld + "-passmatch-error' ng-show='" + this.form.name + "_form." + fld +
|
||||
".$error.awpassmatch'>\nThis value does not match the password you entered previously. Please confirm that password.\n</div>\n";
|
||||
".$error.awpassmatch'>\n" +
|
||||
error_message + "\n</div>\n";
|
||||
}
|
||||
if (field.awValidUrl) {
|
||||
var error_message = i18n._("Please enter a URL that begins with ssh, http or https. The URL may not contain the '@' character.");
|
||||
html += "<div class='error' id='" + this.form.name + "-" + fld + "-url-error' ng-show='" + this.form.name + "_form." + fld +
|
||||
".$error.awvalidurl'>\nPlease enter a URL that begins with ssh, http or https. The URL may not contain the '@' character.\n</div>\n";
|
||||
".$error.awvalidurl'>\n" +
|
||||
error_message + "\n</div>\n";
|
||||
}
|
||||
if (field.chkPass && $AnsibleConfig) {
|
||||
// password strength
|
||||
if ($AnsibleConfig.password_length) {
|
||||
var error_message = i18n.format(i18n._("Your password must be %d characters long."), $AnsibleConfig.password_length);
|
||||
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.password_length\">Your password must be " + $AnsibleConfig.password_length + " characters long.</div>\n";
|
||||
".$error.password_length\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if ($AnsibleConfig.password_hasLowercase) {
|
||||
var error_message = i18n._("Your password must contain a lowercase letter.");
|
||||
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.hasLowercase\">Your password must contain a lowercase letter.</div>\n";
|
||||
".$error.hasLowercase\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if ($AnsibleConfig.password_hasUppercase) {
|
||||
var error_message = i18n._("Your password must contain an uppercase letter.");
|
||||
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.hasUppercase\">Your password must contain an uppercase letter.</div>\n";
|
||||
".$error.hasUppercase\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if ($AnsibleConfig.password_hasNumber) {
|
||||
var error_message = i18n._("Your password must contain a number.");
|
||||
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.hasNumber\">Your password must contain a number.</div>\n";
|
||||
".$error.hasNumber\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
if ($AnsibleConfig.password_hasSymbol) {
|
||||
var error_message = i18n.format(i18n._("Your password must contain one of the following characters: %s"), "`~!@#$%^&*()_-+=|}\]{\[;:\"\'?\/>.<,");
|
||||
html += "<div class=\"error\" ng-show=\"" + this.form.name + '_form.' + fld +
|
||||
".$error.hasSymbol\">Your password must contain one of the following characters: `~!@#$%^&*()_-+=|}\]{\[;:\"\'?\/>.<,</div>\n";
|
||||
".$error.hasSymbol\">" +
|
||||
error_message + "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1136,7 +1162,13 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
if(!field.multiSelect && !field.disableChooseOption){
|
||||
html += "<option value=\"\">";
|
||||
// Add a custom default select 'value' (default text)
|
||||
html += (field.defaultText) ? field.defaultText : "Choose a " + field.label.toLowerCase();
|
||||
if (field.defaultText) {
|
||||
html += field.defaultText;
|
||||
} else {
|
||||
// i18n is used with src/forms/Projects.js
|
||||
html += i18n.format(i18n._("Choose a %s"),
|
||||
field.label.toLowerCase());
|
||||
}
|
||||
html += "</option>\n";
|
||||
}
|
||||
|
||||
@ -1488,10 +1520,14 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
html += "<div class=\"Form-title\">";
|
||||
html += (options.mode === 'edit') ? this.form.editTitle : this.form.addTitle;
|
||||
if(this.form.name === "user"){
|
||||
var user_str = i18n._("Admin");
|
||||
html+= "<span class=\"Form-title--is_superuser\" "+
|
||||
"ng-show='is_superuser'>Admin</span>";
|
||||
"ng-show='is_superuser'>" +
|
||||
user_str + "</span>";
|
||||
user_str = i18n._("Auditor");
|
||||
html+= "<span class=\"Form-title--is_system_auditor\" "+
|
||||
"ng-show='is_system_auditor'>Auditor</span>";
|
||||
"ng-show='is_system_auditor'>" +
|
||||
user_str + "</span>";
|
||||
html+= "<span class=\"Form-title--is_ldap_user\" "+
|
||||
"ng-show='ldap_user'>LDAP</span>";
|
||||
html+= "<span class=\"Form-title--is_external_account\" "+
|
||||
@ -1521,13 +1557,16 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
|
||||
if (!_.isEmpty(this.form.related)) {
|
||||
var collection;
|
||||
// i18n is used with src/forms/Projects.js
|
||||
var details = i18n._("Details");
|
||||
html += "<div class=\"Form-tabHolder\">";
|
||||
|
||||
if(this.mode === "edit"){
|
||||
html += "<div id=\"" + this.form.name + "_tab\""+
|
||||
"class=\"Form-tab\" "+
|
||||
"ng-click=\"toggleFormTabs($event)\"" +
|
||||
"ng-class=\"{'is-selected': " + this.form.name + "Selected }\">Details</div>";
|
||||
"ng-class=\"{'is-selected': " + this.form.name + "Selected }\">" +
|
||||
details + "</div>";
|
||||
|
||||
for (itm in this.form.related) {
|
||||
collection = this.form.related[itm];
|
||||
@ -1548,7 +1587,8 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
}
|
||||
else if(this.mode === "add"){
|
||||
html += "<div id=\"" + this.form.name + "_tab\""+
|
||||
"class=\"Form-tab is-selected\">Details</div>";
|
||||
"class=\"Form-tab is-selected\">" +
|
||||
details + "</div>";
|
||||
|
||||
for (itm in this.form.related) {
|
||||
collection = this.form.related[itm];
|
||||
@ -1693,31 +1733,31 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
|
||||
|
||||
// Set default color and label for Save and Reset
|
||||
if (btn === 'save') {
|
||||
button.label = 'Save';
|
||||
button.label = i18n._('Save');
|
||||
button['class'] = 'Form-saveButton';
|
||||
}
|
||||
if (btn === 'cancel') {
|
||||
button.label = 'Cancel';
|
||||
button.label = i18n._('Cancel');
|
||||
button['class'] = 'Form-cancelButton';
|
||||
}
|
||||
if (btn === 'close') {
|
||||
button.label = 'Close';
|
||||
button.label = i18n._('Close');
|
||||
button['class'] = 'Form-cancelButton';
|
||||
}
|
||||
if (btn === 'launch') {
|
||||
button.label = 'Launch';
|
||||
button.label = i18n._('Launch');
|
||||
button['class'] = 'Form-launchButton';
|
||||
}
|
||||
if (btn === 'add_survey') {
|
||||
button.label = 'Add Survey';
|
||||
button.label = i18n._('Add Survey');
|
||||
button['class'] = 'Form-surveyButton';
|
||||
}
|
||||
if (btn === 'edit_survey') {
|
||||
button.label = 'Edit Survey';
|
||||
button.label = i18n._('Edit Survey');
|
||||
button['class'] = 'Form-surveyButton';
|
||||
}
|
||||
if (btn === 'view_survey') {
|
||||
button.label = 'View Survey';
|
||||
button.label = i18n._('View Survey');
|
||||
button['class'] = 'Form-surveyButton';
|
||||
}
|
||||
|
||||
|
@ -100,8 +100,9 @@ import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||
|
||||
export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'getSearchHtml',
|
||||
'Column', 'DropDown', 'NavigationLink', 'SelectIcon', 'ActionButton',
|
||||
'i18n',
|
||||
function ($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, getSearchHtml, Column, DropDown, NavigationLink,
|
||||
SelectIcon, ActionButton) {
|
||||
SelectIcon, ActionButton, i18n) {
|
||||
return {
|
||||
|
||||
setList: function (list) {
|
||||
@ -310,7 +311,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
||||
|
||||
if (list.listTitle) {
|
||||
|
||||
html += "<div class=\"List-titleText\">" + list.listTitle + "</div>";
|
||||
html += "<div class=\"List-titleText\"><translate>" + list.listTitle + "</translate></div>";
|
||||
// We want to show the list title badge by default and only hide it when the list config specifically passes a false flag
|
||||
list.listTitleBadge = (typeof list.listTitleBadge === 'boolean' && list.listTitleBadge === false) ? false : true;
|
||||
if(list.listTitleBadge) {
|
||||
@ -411,7 +412,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
||||
|
||||
// Show the "no items" box when loading is done and the user isn't actively searching and there are no results
|
||||
html += "<div class=\"List-noItems\" ng-show=\"" + list.iterator + "Loading == false && " + list.iterator + "_active_search == false && " + list.iterator + "_total_rows < 1\">";
|
||||
html += (list.emptyListText) ? list.emptyListText : "PLEASE ADD ITEMS TO THIS LIST";
|
||||
html += (list.emptyListText) ? list.emptyListText : i18n._("PLEASE ADD ITEMS TO THIS LIST");
|
||||
html += "</div>";
|
||||
|
||||
// Add a title and optionally a close button (used on Inventory->Groups)
|
||||
@ -580,7 +581,9 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
||||
|
||||
// Message for loading
|
||||
innerTable += "<tr class=\"loading-info\" ng-show=\"" + list.iterator + "Loading == true\">\n";
|
||||
innerTable += "<td colspan=\"" + cnt + "\" class=\"List-tableCell\"><div class=\"loading-info\">Loading...</div></td>\n";
|
||||
var loading = i18n._("Loading...");
|
||||
innerTable += "<td colspan=\"" + cnt + "\" class=\"List-tableCell\"><div class=\"loading-info\">" +
|
||||
loading + "</div></td>\n";
|
||||
innerTable += "</tr>\n";
|
||||
|
||||
// End List
|
||||
@ -684,7 +687,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
||||
html += "<th class=\"List-tableHeader List-tableHeader--actions actions-column";
|
||||
html += (list.fieldActions && list.fieldActions.columnClass) ? " " + list.fieldActions.columnClass : "";
|
||||
html += "\">";
|
||||
html += (list.fieldActions.label === undefined || list.fieldActions.label) ? "Actions" : "";
|
||||
html += (list.fieldActions.label === undefined || list.fieldActions.label) ? i18n._("Actions") : "";
|
||||
html += "</th>\n";
|
||||
}
|
||||
html += "</tr>\n";
|
||||
|
@ -5,8 +5,8 @@
|
||||
*************************************************/
|
||||
import ReconnectingWebSocket from 'reconnectingwebsocket';
|
||||
export default
|
||||
['$rootScope', '$location', '$log','$state', '$q',
|
||||
function ($rootScope, $location, $log, $state, $q) {
|
||||
['$rootScope', '$location', '$log','$state', '$q', 'i18n',
|
||||
function ($rootScope, $location, $log, $state, $q, i18n) {
|
||||
var needsResubscribing = false,
|
||||
socketPromise = $q.defer();
|
||||
return {
|
||||
@ -169,15 +169,15 @@ export default
|
||||
if(self.socket){
|
||||
if (self.socket.readyState === 0 ) {
|
||||
$rootScope.socketStatus = 'connecting';
|
||||
$rootScope.socketTip = "Live events: attempting to connect to the Tower server.";
|
||||
$rootScope.socketTip = i18n._("Live events: attempting to connect to the Tower server.");
|
||||
}
|
||||
else if (self.socket.readyState === 1){
|
||||
$rootScope.socketStatus = 'ok';
|
||||
$rootScope.socketTip = "Live events: connected. Pages containing job status information will automatically update in real-time.";
|
||||
$rootScope.socketTip = i18n._("Live events: connected. Pages containing job status information will automatically update in real-time.");
|
||||
}
|
||||
else if (self.socket.readyState === 2 || self.socket.readyState === 3 ){
|
||||
$rootScope.socketStatus = 'error';
|
||||
$rootScope.socketTip = "Live events: error connecting to the Tower server.";
|
||||
$rootScope.socketTip = i18n._("Live events: error connecting to the Tower server.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
module.exports = {
|
||||
dev: {
|
||||
tasks: ['copy:vendor', 'copy:assets', 'copy:partials', 'copy:config', 'less:dev'],
|
||||
tasks: ['copy:vendor', 'copy:assets', 'copy:partials', 'copy:languages', 'copy:config', 'less:dev'],
|
||||
},
|
||||
prod: {
|
||||
tasks: ['newer:copy:vendor', 'newer:copy:assets', 'newer:copy:partials', 'newer:copy:config', 'newer:less:prod']
|
||||
tasks: ['newer:copy:vendor', 'newer:copy:assets', 'newer:copy:partials', 'newer:copy:languages', 'newer:copy:config', 'newer:less:prod']
|
||||
},
|
||||
watch: {
|
||||
tasks: ['watch:css', 'watch:partials', 'watch:assets', ['webpack:dev', 'watch:config']],
|
||||
|
@ -43,6 +43,14 @@ module.exports = {
|
||||
dest: 'static/partials/'
|
||||
}]
|
||||
},
|
||||
languages: {
|
||||
files: [{
|
||||
cwd: 'client/',
|
||||
expand: true,
|
||||
src: 'languages/*.json',
|
||||
dest: 'static/'
|
||||
}]
|
||||
},
|
||||
config: {
|
||||
files: { 'static/config.js': ['client/src/config.js'] }
|
||||
}
|
||||
|
15
awx/ui/grunt-tasks/nggettext_compile.js
Normal file
15
awx/ui/grunt-tasks/nggettext_compile.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
all: {
|
||||
options: {
|
||||
format: 'json'
|
||||
},
|
||||
files: [ {
|
||||
expand: true,
|
||||
dot: true,
|
||||
dest: 'client/languages',
|
||||
cwd: 'po',
|
||||
ext: '.json',
|
||||
src: ['*.po']
|
||||
} ]
|
||||
}
|
||||
};
|
11
awx/ui/grunt-tasks/nggettext_extract.js
Normal file
11
awx/ui/grunt-tasks/nggettext_extract.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
all: {
|
||||
options: {
|
||||
markerNames: ['_', 'N_']
|
||||
},
|
||||
files: {
|
||||
'po/ansible-tower.pot': ['client/src/**/*.js',
|
||||
'client/src/**/*.html']
|
||||
}
|
||||
},
|
||||
};
|
@ -18,6 +18,8 @@
|
||||
"scripts": {
|
||||
"build-docker-machine": "ip=$(docker-machine ip $DOCKER_MACHINE_NAME); npm set ansible-tower:django_host ${ip}; grunt dev",
|
||||
"build-docker-cid": "ip=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $DOCkER_CID` | npm set config ansible-tower:django_host ${ip}; grunt dev",
|
||||
"pot": "grunt nggettext_extract",
|
||||
"languages": "grunt nggettext_compile",
|
||||
"build-release": "grunt release",
|
||||
"pretest": "grunt clean:coverage",
|
||||
"test": "karma start karma.conf.js",
|
||||
@ -34,6 +36,7 @@
|
||||
"browser-sync": "^2.14.0",
|
||||
"expose-loader": "^0.7.1",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-angular-gettext": "^2.2.3",
|
||||
"grunt-browser-sync": "^2.2.0",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-concurrent": "^2.3.0",
|
||||
@ -75,6 +78,7 @@
|
||||
"angular-codemirror": "chouseknecht/angular-codemirror#1.0.4",
|
||||
"angular-cookies": "^1.4.3",
|
||||
"angular-drag-and-drop-lists": "leigh-johnson/angular-drag-and-drop-lists#1.4.0",
|
||||
"angular-gettext": "^2.3.5",
|
||||
"angular-md5": "^0.1.8",
|
||||
"angular-moment": "^0.10.1",
|
||||
"angular-resource": "^1.4.3",
|
||||
|
2041
awx/ui/po/ansible-tower.pot
Normal file
2041
awx/ui/po/ansible-tower.pot
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@ var vendorPkgs = [
|
||||
'angular-codemirror',
|
||||
'angular-cookies',
|
||||
'angular-drag-and-drop-lists',
|
||||
'angular-gettext',
|
||||
'angular-md5',
|
||||
'angular-moment',
|
||||
'angular-sanitize',
|
||||
|
Loading…
Reference in New Issue
Block a user