Merge pull request #2081 from jaredevantabor/i18n

UI i18n Audit
This commit is contained in:
Jared Tabor
2018-06-13 14:13:12 -04:00
committed by GitHub
46 changed files with 393 additions and 214 deletions

View File

@@ -299,10 +299,11 @@ class BaseSerializer(serializers.ModelSerializer):
'system_job': _('Management Job'), 'system_job': _('Management Job'),
'workflow_job': _('Workflow Job'), 'workflow_job': _('Workflow Job'),
'workflow_job_template': _('Workflow Template'), 'workflow_job_template': _('Workflow Template'),
'job_template': _('Job Template')
} }
choices = [] choices = []
for t in self.get_types(): for t in self.get_types():
name = type_name_map.get(t, force_text(get_model_for_type(t)._meta.verbose_name).title()) name = _(type_name_map.get(t, force_text(get_model_for_type(t)._meta.verbose_name).title()))
choices.append((t, name)) choices.append((t, name))
return choices return choices

View File

@@ -16,23 +16,23 @@
<div class="HostEvent-details"> <div class="HostEvent-details">
<div class="HostEvent-field"> <div class="HostEvent-field">
<span class="HostEvent-field--label">CREATED</span> <span class="HostEvent-field--label">{{strings.get('host_event_modal.CREATED')}}</span>
<span class="HostEvent-field--content">{{(event.created | longDate) || "No result found"}}</span> <span class="HostEvent-field--content">{{(event.created | longDate) || "No result found"}}</span>
</div> </div>
<div class="HostEvent-field"> <div class="HostEvent-field">
<span class="HostEvent-field--label">ID</span> <span class="HostEvent-field--label">{{strings.get('host_event_modal.ID')}}</span>
<span class="HostEvent-field--content">{{event.id || "No result found"}}</span> <span class="HostEvent-field--content">{{event.id || "No result found"}}</span>
</div> </div>
<div class="HostEvent-field"> <div class="HostEvent-field">
<span class="HostEvent-field--label">PLAY</span> <span class="HostEvent-field--label">{{strings.get('host_event_modal.PLAY')}}</span>
<span class="HostEvent-field--content">{{event.play || "No result found"}}</span> <span class="HostEvent-field--content">{{event.play || "No result found"}}</span>
</div> </div>
<div class="HostEvent-field"> <div class="HostEvent-field">
<span class="HostEvent-field--label">TASK</span> <span class="HostEvent-field--label">{{strings.get('host_event_modal.TASK')}}</span>
<span class="HostEvent-field--content">{{event.task || "No result found"}}</span> <span class="HostEvent-field--content">{{event.task || "No result found"}}</span>
</div> </div>
<div class="HostEvent-field"> <div class="HostEvent-field">
<span class="HostEvent-field--label">MODULE</span> <span class="HostEvent-field--label">{{strings.get('host_event_modal.MODULE')}}</span>
<span class="HostEvent-field--content HostEvent-field--monospaceContent">{{module_name}}</span> <span class="HostEvent-field--content HostEvent-field--monospaceContent">{{module_name}}</span>
</div> </div>
</div> </div>
@@ -48,12 +48,12 @@
<button ng-if="stdout" ui-sref="output.host-event.stdout" <button ng-if="stdout" ui-sref="output.host-event.stdout"
type="button" class="btn btn-sm btn-default HostEvent-tab" type="button" class="btn btn-sm btn-default HostEvent-tab"
ng-class="{'HostEvent-tab--selected' : isActiveState('output.host-event.stdout')}"> ng-class="{'HostEvent-tab--selected' : isActiveState('output.host-event.stdout')}">
Standard Out {{strings.get('host_event_modal.STANDARD_OUT')}}
</button> </button>
<button ng-if="stderr" ui-sref="output.host-event.stderr" <button ng-if="stderr" ui-sref="output.host-event.stderr"
type="button" class="btn btn-sm btn-default HostEvent-tab" type="button" class="btn btn-sm btn-default HostEvent-tab"
ng-class="{'HostEvent-tab--selected' : isActiveState('output.host-event.stderr')}"> ng-class="{'HostEvent-tab--selected' : isActiveState('output.host-event.stderr')}">
Standard Error {{strings.get('host_event_modal.STANDARD_ERROR')}}
</button> </button>
</div> </div>
@@ -64,7 +64,7 @@
<!-- controls --> <!-- controls -->
<div class="HostEvent-controls"> <div class="HostEvent-controls">
<button ng-click="closeHostEvent()" class="btn btn-sm btn-default HostEvent-close">Close</button> <button ng-click="closeHostEvent()" class="btn btn-sm btn-default HostEvent-close">{{strings.get('CLOSE')}}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -2,14 +2,15 @@ function HostEventsController (
$scope, $scope,
$state, $state,
HostEventService, HostEventService,
hostEvent hostEvent,
OutputStrings
) { ) {
$scope.processEventStatus = HostEventService.processEventStatus; $scope.processEventStatus = HostEventService.processEventStatus;
$scope.processResults = processResults; $scope.processResults = processResults;
$scope.isActiveState = isActiveState; $scope.isActiveState = isActiveState;
$scope.getActiveHostIndex = getActiveHostIndex; $scope.getActiveHostIndex = getActiveHostIndex;
$scope.closeHostEvent = closeHostEvent; $scope.closeHostEvent = closeHostEvent;
$scope.strings = OutputStrings;
function init () { function init () {
hostEvent.event_name = hostEvent.event; hostEvent.event_name = hostEvent.event;
$scope.event = _.cloneDeep(hostEvent); $scope.event = _.cloneDeep(hostEvent);
@@ -165,6 +166,7 @@ HostEventsController.$inject = [
'$state', '$state',
'HostEventService', 'HostEventService',
'hostEvent', 'hostEvent',
'OutputStrings'
]; ];
module.exports = HostEventsController; module.exports = HostEventsController;

View File

@@ -87,11 +87,25 @@ function OutputStrings (BaseString) {
ns.stats = { ns.stats = {
ELAPSED: t.s('Elapsed'), ELAPSED: t.s('Elapsed'),
PLAYS: t.s('Plays'),
TASKS: t.s('Tasks'),
HOSTS: t.s('Hosts')
}; };
ns.stdout = { ns.stdout = {
BACK_TO_TOP: t.s('Back to Top'), BACK_TO_TOP: t.s('Back to Top'),
}; };
ns.host_event_modal = {
CREATED: t.s('CREATED'),
ID: t.s('ID'),
PLAY: t.s('PLAY'),
TASK: t.s('TASK'),
MODULE: t.s('MODULE'),
NO_RESULT_FOUND: t.s('No result found'),
STANDARD_OUT: t.s('Standard Out'),
STANDARD_ERROR: t.s('Standard Error')
};
} }
OutputStrings.$inject = ['BaseStringService']; OutputStrings.$inject = ['BaseStringService'];

View File

@@ -8,7 +8,7 @@
<span ng-show="!vm.tasks" class="at-Panel-headingTitleBadge">...</span> <span ng-show="!vm.tasks" class="at-Panel-headingTitleBadge">...</span>
<span ng-show="vm.tasks" class="at-Panel-headingTitleBadge">{{ vm.tasks }}</span> <span ng-show="vm.tasks" class="at-Panel-headingTitleBadge">{{ vm.tasks }}</span>
<span class="at-Panel-label">hosts</span> <span class="at-Panel-label">{{:: vm.strings.get('stats.HOSTS')}}</span>
<span ng-show="!vm.hosts" class="at-Panel-headingTitleBadge">...</span> <span ng-show="!vm.hosts" class="at-Panel-headingTitleBadge">...</span>
<span ng-show="vm.hosts" class="at-Panel-headingTitleBadge">{{ vm.hosts }}</span> <span ng-show="vm.hosts" class="at-Panel-headingTitleBadge">{{ vm.hosts }}</span>

View File

@@ -23,6 +23,7 @@ function TemplatesStrings (BaseString) {
ns.prompt = { ns.prompt = {
INVENTORY: t.s('Inventory'), INVENTORY: t.s('Inventory'),
CREDENTIAL: t.s('Credential'), CREDENTIAL: t.s('Credential'),
PROMPT: t.s('PROMPT'),
OTHER_PROMPTS: t.s('Other Prompts'), OTHER_PROMPTS: t.s('Other Prompts'),
SURVEY: t.s('Survey'), SURVEY: t.s('Survey'),
PREVIEW: t.s('Preview'), PREVIEW: t.s('Preview'),
@@ -96,6 +97,31 @@ function TemplatesStrings (BaseString) {
INVALID_JOB_TEMPLATE: t.s('This Job Template is missing a default inventory or project. This must be addressed in the Job Template form before this node can be saved.'), INVALID_JOB_TEMPLATE: t.s('This Job Template is missing a default inventory or project. This must be addressed in the Job Template form before this node can be saved.'),
CREDENTIAL_WITH_PASS: t.s('This Job Template has a credential that requires a password. Credentials requiring passwords on launch are not permitted on workflow nodes.') CREDENTIAL_WITH_PASS: t.s('This Job Template has a credential that requires a password. Credentials requiring passwords on launch are not permitted on workflow nodes.')
}; };
ns.workflow_maker = {
DELETE_NODE_PROMPT_TEXT: t.s('Are you sure you want to delete this workflow node?'),
KEY: t.s('KEY'),
ON_SUCCESS: t.s('On Success'),
ON_FAILURE: t.s('On Failure'),
ALWAYS: t.s('Always'),
PROJECT_SYNC: t.s('Project Sync'),
INVENTORY_SYNC: t.s('Inventory Sync'),
WARNING: t.s('Warning'),
TOTAL_TEMPLATES: t.s('TOTAL TEMPLATES'),
ADD_A_TEMPLATE: t.s('ADD A TEMPLATE'),
EDIT_TEMPLATE: t.s('EDIT TEMPLATE'),
JOBS: t.s('JOBS'),
PLEASE_CLICK_THE_START_BUTTON: t.s('Please click the start button to build your workflow.'),
PLEASE_HOVER_OVER_A_TEMPLATE: t.s('Please hover over a template for additional options.'),
RUN: t.s('RUN'),
CHECK: t.s('CHECK'),
SELECT: t.s('SELECT'),
EDGE_CONFLICT: t.s('EDGE CONFLICT'),
DELETED: t.s('DELETED'),
START: t.s('START'),
DETAILS: t.s('DETAILS')
}
} }
TemplatesStrings.$inject = ['BaseStringService']; TemplatesStrings.$inject = ['BaseStringService'];

View File

@@ -68,7 +68,7 @@ function ComponentsStrings (BaseString) {
DASHBOARD: t.s('Dashboard'), DASHBOARD: t.s('Dashboard'),
JOBS: t.s('Jobs'), JOBS: t.s('Jobs'),
SCHEDULES: t.s('Schedules'), SCHEDULES: t.s('Schedules'),
PORTAL_MODE: t.s('Portal Mode'), MY_VIEW: t.s('My View'),
PROJECTS: t.s('Projects'), PROJECTS: t.s('Projects'),
CREDENTIALS: t.s('Credentials'), CREDENTIALS: t.s('Credentials'),
CREDENTIAL_TYPES: t.s('Credential Types'), CREDENTIAL_TYPES: t.s('Credential Types'),

View File

@@ -42,7 +42,7 @@
</at-side-nav-item> </at-side-nav-item>
<at-side-nav-item icon-class="fa-calendar" route="jobs.schedules" name="SCHEDULES"> <at-side-nav-item icon-class="fa-calendar" route="jobs.schedules" name="SCHEDULES">
</at-side-nav-item> </at-side-nav-item>
<at-side-nav-item icon-class="fa-columns" route="portalMode.myJobs" name="PORTAL_MODE"> <at-side-nav-item icon-class="fa-columns" route="portalMode.myJobs" name="MY_VIEW">
</at-side-nav-item> </at-side-nav-item>
<div class="at-Layout-sideNavSpacer"> <div class="at-Layout-sideNavSpacer">
<span class="at-Layout-sideNavHeader"> <span class="at-Layout-sideNavHeader">

View File

@@ -71,6 +71,7 @@ function BaseStringService (namespace) {
this.DELETE = t.s('DELETE'); this.DELETE = t.s('DELETE');
this.COPY = t.s('COPY'); this.COPY = t.s('COPY');
this.YES = t.s('YES'); this.YES = t.s('YES');
this.CLOSE = t.s('CLOSE');
this.deleteResource = { this.deleteResource = {
HEADER: t.s('Delete'), HEADER: t.s('Delete'),

View File

@@ -6,10 +6,10 @@
export default ['Rest', 'Wait', export default ['Rest', 'Wait',
'CredentialTypesForm', 'ProcessErrors', 'GetBasePath', 'CredentialTypesForm', 'ProcessErrors', 'GetBasePath',
'GenerateForm', '$scope', '$state', 'Alert', 'GetChoices', 'ParseTypeChange', 'ToJSON', 'CreateSelect2', 'GenerateForm', '$scope', '$state', 'Alert', 'GetChoices', 'ParseTypeChange', 'ToJSON', 'CreateSelect2', 'i18n',
function(Rest, Wait, function(Rest, Wait,
CredentialTypesForm, ProcessErrors, GetBasePath, CredentialTypesForm, ProcessErrors, GetBasePath,
GenerateForm, $scope, $state, Alert, GetChoices, ParseTypeChange, ToJSON, CreateSelect2 GenerateForm, $scope, $state, Alert, GetChoices, ParseTypeChange, ToJSON, CreateSelect2, i18n
) { ) {
var form = CredentialTypesForm, var form = CredentialTypesForm,
url = GetBasePath('credential_types'); url = GetBasePath('credential_types');
@@ -38,7 +38,7 @@ export default ['Rest', 'Wait',
}); });
const docs_url = 'https://docs.ansible.com/ansible-tower/latest/html/userguide/credential_types.html#getting-started-with-credential-types'; const docs_url = 'https://docs.ansible.com/ansible-tower/latest/html/userguide/credential_types.html#getting-started-with-credential-types';
const docs_help_text = `<br><br><a href=${docs_url}>Getting Started with Credential Types</a>`; const docs_help_text = `<br><br><a href=${docs_url}>${i18n._('Getting Started with Credential Types')}</a>`;
const api_inputs_help_text = _.get(options, 'actions.POST.inputs.help_text', "Specification for credential type inputs."); const api_inputs_help_text = _.get(options, 'actions.POST.inputs.help_text', "Specification for credential type inputs.");
const api_injectors_help_text = _.get(options, 'actions.POST.injectors.help_text', "Specification for credential type injector."); const api_injectors_help_text = _.get(options, 'actions.POST.injectors.help_text', "Specification for credential type injector.");

View File

@@ -3,7 +3,8 @@ export default
[ '$filter', [ '$filter',
'templateUrl', 'templateUrl',
'$location', '$location',
function JobsList($filter, templateUrl, $location) { 'i18n',
function JobsList($filter, templateUrl, $location, i18n) {
return { return {
restrict: 'E', restrict: 'E',
link: link, link: link,
@@ -29,7 +30,7 @@ export default
// detailsUrl, status, name, time // detailsUrl, status, name, time
scope.jobs = _.map(list, function(job){ scope.jobs = _.map(list, function(job){
let detailsUrl; let detailsUrl, tooltip;
if (job.type === 'workflow_job') { if (job.type === 'workflow_job') {
detailsUrl = `/#/workflows/${job.id}`; detailsUrl = `/#/workflows/${job.id}`;
@@ -37,12 +38,20 @@ export default
detailsUrl = `/#/jobs/playbook/${job.id}`; detailsUrl = `/#/jobs/playbook/${job.id}`;
} }
if(_.has(job, 'status') && job.status === 'successful'){
tooltip = i18n._('Job successful. Click for details.');
}
else if(_.has(job, 'status') && job.status === 'failed'){
tooltip = i18n._('Job failed. Click for details.');
}
return { return {
detailsUrl, detailsUrl,
status: job.status, status: job.status,
name: job.name, name: job.name,
id: job.id, id: job.id,
time: $filter('longDate')(job.finished) time: $filter('longDate')(job.finished),
tooltip: tooltip
}; }); }; });
} }

View File

@@ -16,10 +16,10 @@
<tr class="List-tableRow" <tr class="List-tableRow"
ng-repeat = "job in jobs"> ng-repeat = "job in jobs">
<td class="DashboardList-nameCell"> <td class="DashboardList-nameCell">
<a href="{{ job.detailsUrl }}" ng-if="isSuccessful(job.status)" aw-tool-tip="Job successful. Click for details." aw-tip-placement="right"> <a href="{{ job.detailsUrl }}" ng-if="isSuccessful(job.status)" aw-tool-tip="{{job.tooltip}}" aw-tip-placement="right" data-tip-watch="job.tooltip">
<i class="fa DashboardList-status DashboardList-status--success icon-job-successful"></i> <i class="fa DashboardList-status DashboardList-status--success icon-job-successful"></i>
</a> </a>
<a href="{{ job.detailsUrl }}" ng-if="!isSuccessful(job.status)" aw-tool-tip="Job failed. Click for details." aw-tip-placement="right"> <a href="{{ job.detailsUrl }}" ng-if="!isSuccessful(job.status)" aw-tool-tip="{{job.tooltip}}" aw-tip-placement="right" data-tip-watch="job.tooltip">
<i class="fa DashboardList-status DashboardList-status--failed icon-job-failed"></i> <i class="fa DashboardList-status DashboardList-status--failed icon-job-failed"></i>
</a> </a>
<a href="{{ job.detailsUrl }}" class="DashboardList-nameContainer"> <a href="{{ job.detailsUrl }}" class="DashboardList-nameContainer">

View File

@@ -34,7 +34,8 @@ function InstanceGroupsStrings (BaseString) {
ns.capacityBar = { ns.capacityBar = {
IS_OFFLINE: t.s('Unavailable to run jobs.'), IS_OFFLINE: t.s('Unavailable to run jobs.'),
IS_OFFLINE_LABEL: t.s('Unavailable') IS_OFFLINE_LABEL: t.s('Unavailable'),
USED_CAPACITY: t.s('Used Capacity')
}; };
ns.capacityAdjuster = { ns.capacityAdjuster = {
@@ -43,7 +44,8 @@ function InstanceGroupsStrings (BaseString) {
}; };
ns.jobs = { ns.jobs = {
PANEL_TITLE: t.s('Jobs') PANEL_TITLE: t.s('Jobs'),
RUNNING_JOBS: t.s('Running Jobs')
}; };
ns.error = { ns.error = {

View File

@@ -31,9 +31,8 @@ export default {
} }
}, },
resolve: { resolve: {
ListDefinition: ['CredentialList', 'i18n', function(CredentialList, i18n) { ListDefinition: ['CredentialList', function(CredentialList) {
let list = _.cloneDeep(CredentialList); let list = _.cloneDeep(CredentialList);
list.lookupConfirmText = i18n._('SELECT');
return list; return list;
}], }],
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',

View File

@@ -11,7 +11,7 @@
dy=".3em" dy=".3em"
text-anchor="left">{{contextMenuButton.name}} text-anchor="left">{{contextMenuButton.name}}
</text> </text>
<text ng-show="contextMenuButton.name ==='Remove'" ng-attr-class="{{contextMenuButton.is_pressed ? 'NetworkUI__contextMenuRemoveButtonText-pressed' : contextMenuButton.mouse_over ? 'NetworkUI__contextMenuRemoveButtonText-hover' : 'NetworkUI__contextMenuRemoveButtonText'}}" <text ng-show="contextMenuButton.type ==='remove'" ng-attr-class="{{contextMenuButton.is_pressed ? 'NetworkUI__contextMenuRemoveButtonText-pressed' : contextMenuButton.mouse_over ? 'NetworkUI__contextMenuRemoveButtonText-hover' : 'NetworkUI__contextMenuRemoveButtonText'}}"
x=15 x=15
ng-attr-y="{{(contextMenuButton.height * $parent.$index) + 18}}" ng-attr-y="{{(contextMenuButton.height * $parent.$index) + 18}}"
dy=".3em" dy=".3em"

View File

@@ -303,7 +303,7 @@ ContextMenu.prototype.is_selected = function (x, y) {
}; };
function ContextMenuButton(name, x, y, width, height, callback, tracer) { function ContextMenuButton(name, x, y, width, height, callback, tracer, type) {
this.name = name; this.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -313,6 +313,7 @@ function ContextMenuButton(name, x, y, width, height, callback, tracer) {
this.is_pressed = false; this.is_pressed = false;
this.mouse_over = false; this.mouse_over = false;
this.enabled = true; this.enabled = true;
this.type = type;
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer); this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
} }
exports.ContextMenuButton = ContextMenuButton; exports.ContextMenuButton = ContextMenuButton;

View File

@@ -5,8 +5,8 @@
*************************************************/ *************************************************/
export default export default
['$scope', 'HostsService', ['$scope', 'HostsService', 'awxNetStrings',
function($scope, HostsService){ function($scope, HostsService, strings){
function codemirror () { function codemirror () {
return { return {
@@ -17,6 +17,8 @@
$scope.formCancel = function(){ $scope.formCancel = function(){
$scope.$parent.$broadcast('awxNet-closeDetailsPanel'); $scope.$parent.$broadcast('awxNet-closeDetailsPanel');
}; };
$scope.strings = strings;
$scope.hostPopover = `<p>${$scope.strings.get('details.HOST_POPOVER')}</p><blockquote>myserver.domain.com<br/>127.0.0.1<br />10.1.0.140:25<br />server.example.com:25</blockquote>`;
$scope.formSave = function(){ $scope.formSave = function(){
var host = { var host = {

View File

@@ -11,9 +11,9 @@
<div ng-show="item.host_id"> <div ng-show="item.host_id">
<form class="Form Networking-form ng-pristine ng-valid ng-valid-required" name="host_form" id="host_form" autocomplete="off" novalidate=""> <form class="Form Networking-form ng-pristine ng-valid ng-valid-required" name="host_form" id="host_form" autocomplete="off" novalidate="">
<div class="form-group Form-formGroup Form-formGroup--fullWidth"> <div class="form-group Form-formGroup Form-formGroup--fullWidth">
<label class="Form-inputLabelContainer" for="name"> <label class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span> <span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel" translate="">Host Name</span><a id="awp-name" href="" aw-pop-over="<p>Provide a host name, ip address, or ip address:port. Examples include:</p><blockquote>myserver.domain.com<br/>127.0.0.1<br />10.1.0.140:25<br />server.example.com:25</blockquote>" data-placement="right" data-container="body" over-title="Host Name" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a> <span class="Form-inputLabel"> {{strings.get('details.HOST_NAME')}}</span><a id="awp-name" href="" aw-pop-over="{{hostPopover}}" data-placement="right" data-tip-watch="hostPopover" data-container="body" over-title="{{strings.get('details.HOST_NAME')}}" class="help-link" data-original-title="" title="" tabindex="-1"><i class="fa fa-question-circle"></i></a>
</label> </label>
<div> <div>
<input readonly type="text" ng-model="item.name" name="name" id="host_name" class="form-control Form-textInput Networking-input ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-required" required="" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)"> <input readonly type="text" ng-model="item.name" name="name" id="host_name" class="form-control Form-textInput Networking-input ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-required" required="" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)">
@@ -22,8 +22,8 @@
</div> </div>
</div> </div>
<div class="form-group Form-formGroup Form-formGroup--fullWidth"> <div class="form-group Form-formGroup Form-formGroup--fullWidth">
<label class="Form-inputLabelContainer" for="description"> <label class="Form-inputLabelContainer">
<span class="Form-inputLabel" translate="">Description</span> <span class="Form-inputLabel">{{strings.get('details.DESCRIPTION')}}</span>
</label> </label>
<div> <div>
<input readonly type="text" ng-model="item.description" name="description" id="host_description" class="form-control Form-textInput Networking-input" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)"> <input readonly type="text" ng-model="item.description" name="description" id="host_description" class="form-control Form-textInput Networking-input" ng-disabled="!(item.summary_fields.user_capabilities.edit || canAdd)">
@@ -40,9 +40,9 @@
</div> </div>
</form> </form>
<div class="buttons Form-buttons" id="host_controls"> <div class="buttons Form-buttons" id="host_controls">
<button type="button" class="btn btn-sm Form-cancelButton" id="host_cancel_btn" ng-click="formCancel()"> Cancel</button> <button type="button" class="btn btn-sm Form-cancelButton" id="host_cancel_btn" ng-click="formCancel()"> {{strings.get('details.CANCEL')}}</button>
</div> </div>
<div class="Networking-saveConfirmation" ng-show="saveConfirmed"> <div class="Networking-saveConfirmation" ng-show="saveConfirmed">
Save Complete <i class="fa fa-check-circle"></i> {{strings.get('details.SAVE_COMPLETE')}} <i class="fa fa-check-circle"></i>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,4 @@
import NetworkingController from './network.nav.controller'; import NetworkingController from './network.nav.controller';
import NetworkingStrings from './network.nav.strings';
const MODULE_NAME = 'at.features.networking'; const MODULE_NAME = 'at.features.networking';
@@ -45,12 +44,11 @@ function NetworkingRun ($stateExtender, strings) {
NetworkingRun.$inject = [ NetworkingRun.$inject = [
'$stateExtender', '$stateExtender',
'NetworkingStrings' 'awxNetStrings'
]; ];
angular angular
.module(MODULE_NAME, []) .module(MODULE_NAME, [])
.service('NetworkingStrings', NetworkingStrings)
.run(NetworkingRun); .run(NetworkingRun);
export default MODULE_NAME; export default MODULE_NAME;

View File

@@ -164,6 +164,7 @@
font-weight: bold; font-weight: bold;
display: flex; display: flex;
align-items: center; align-items: center;
text-transform: uppercase;
} }
.Networking-keyContainer{ .Networking-keyContainer{
@@ -205,7 +206,8 @@
.Networking-keySymbolLabel{ .Networking-keySymbolLabel{
font-size: 12px; font-size: 12px;
padding-left: 15px; padding-left: 15px;
color: @default-stdout-txt color: @default-stdout-txt;
text-transform: uppercase;
} }
.Networking-toolboxPanelToolbarIcon--selected{ .Networking-toolboxPanelToolbarIcon--selected{

View File

@@ -33,26 +33,42 @@ function NetworkingController (models, $state, $scope, strings) {
$scope.$on('awxNet-instatiateSelect', (e, devices) => { $scope.$on('awxNet-instatiateSelect', (e, devices) => {
for(var i = 0; i < devices.length; i++){ for(var i = 0; i < devices.length; i++){
let device = devices[i]; let device = devices[i];
let grouping;
switch (device.type){
case 'host':
grouping = strings.get('search.HOST');
break;
case 'switch':
grouping = strings.get('search.SWITCH');
break;
case 'router':
grouping = strings.get('search.ROUTER');
break;
default:
grouping = strings.get('search.UNKNOWN');
}
$scope.devices.push({ $scope.devices.push({
value: device.id, value: device.id,
text: device.name, text: device.name,
label: device.name, label: device.name,
id: device.id, id: device.id,
type: device.type type: device.type,
group_type: grouping
}); });
} }
$("#networking-search").select2({ $("#networking-search").select2({
width:'400px', width:'400px',
containerCssClass: 'Form-dropDown', containerCssClass: 'Form-dropDown',
placeholder: 'SEARCH', placeholder: strings.get('search.SEARCH'),
dropdownParent: $('.Networking-toolbar'), dropdownParent: $('.Networking-toolbar'),
}); });
$("#networking-actionsDropdown").select2({ $("#networking-actionsDropdown").select2({
width:'400px', width:'400px',
containerCssClass: 'Form-dropDown', containerCssClass: 'Form-dropDown',
minimumResultsForSearch: -1, minimumResultsForSearch: -1,
placeholder: 'ACTIONS', placeholder: strings.get('actions.ACTIONS'),
dropdownParent: $('.Networking-toolbar'), dropdownParent: $('.Networking-toolbar'),
}); });
}); });
@@ -118,7 +134,7 @@ NetworkingController.$inject = [
'resolvedModels', 'resolvedModels',
'$state', '$state',
'$scope', '$scope',
'NetworkingStrings', 'awxNetStrings',
'CreateSelect2' 'CreateSelect2'
]; ];

View File

@@ -1,19 +0,0 @@
function NetworkingStrings (BaseString) {
BaseString.call(this, 'networking');
const { t } = this;
const ns = this.networking;
ns.state = {
BREADCRUMB_LABEL: t.s('INVENTORIES'),
};
ns.actions = {
EXPAND_PANEL: t.s('Expand Panel'),
COLLAPSE_PANEL: t.s('Collapse Panel')
};
}
NetworkingStrings.$inject = ['BaseStringService'];
export default NetworkingStrings;

View File

@@ -16,8 +16,8 @@
<select id="networking-actionsDropdown" <select id="networking-actionsDropdown"
style="width:400px"> style="width:400px">
<option></option> <option></option>
<option value="Export" title="Export">Export SVG</option> <option value="Export" title="Export">{{ vm.strings.get('actions.EXPORT') }} SVG</option>
<option value="ExportYaml" title="ExportYaml">Export YAML</option> <option value="ExportYaml" title="ExportYaml">{{ vm.strings.get('actions.EXPORT') }} YAML</option>
</select> </select>
</div> </div>
</div> </div>
@@ -33,26 +33,26 @@
</button> </button>
<div class="Networking-keyDropDownPanel" ng-if="vm.keyPanelExpanded"> <div class="Networking-keyDropDownPanel" ng-if="vm.keyPanelExpanded">
<div class="Networking-dropdownPanelTitle"> <div class="Networking-dropdownPanelTitle">
KEY {{ vm.strings.get('key.KEY') }}
</div> </div>
<div class="Networking-keyPanelOption"> <div class="Networking-keyPanelOption">
<div class="Networking-keySymbol">d</div> <div class="Networking-keySymbol">d</div>
<div class="Networking-keySymbolLabel">DEBUG MODE</div> <div class="Networking-keySymbolLabel">{{ vm.strings.get('key.DEBUG_MODE') }}</div>
</div> </div>
<div class="Networking-keyPanelOption"> <div class="Networking-keyPanelOption">
<div class="Networking-keySymbol">i</div> <div class="Networking-keySymbol">i</div>
<div class="Networking-keySymbolLabel">HIDE INTERFACES</div> <div class="Networking-keySymbolLabel">{{ vm.strings.get('key.HIDE_INTERFACES') }}</div>
</div> </div>
<div class="Networking-keyPanelOption"> <div class="Networking-keyPanelOption">
<div class="Networking-keySymbol">0</div> <div class="Networking-keySymbol">0</div>
<div class="Networking-keySymbolLabel">RESET ZOOM</div> <div class="Networking-keySymbolLabel">{{ vm.strings.get('key.RESET_ZOOM') }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="Networking-searchBarContainer"> <div class="Networking-searchBarContainer">
<select id="networking-search" <select id="networking-search"
ng-model="device" ng-model="device"
ng-options="device.label group by device.type | capitalize for device in devices | orderBy:'label' " ng-options="device.label group by device.group_type for device in devices | orderBy:'label' "
style="width:400px"> style="width:400px">
<option></option> <option></option>
</select> </select>

View File

@@ -3,6 +3,7 @@
import atFeaturesNetworking from './network-nav/main'; import atFeaturesNetworking from './network-nav/main';
import networkDetailsDirective from './network-details/main'; import networkDetailsDirective from './network-details/main';
import networkZoomWidget from './zoom-widget/main'; import networkZoomWidget from './zoom-widget/main';
import awxNetStrings from './network.ui.strings';
//console.log = function () { }; //console.log = function () { };
var NetworkUIController = require('./network.ui.controller.js'); var NetworkUIController = require('./network.ui.controller.js');
@@ -40,4 +41,5 @@ export default
.directive('awxNetQuadrants', quadrants.quadrants) .directive('awxNetQuadrants', quadrants.quadrants)
.directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox) .directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox)
.directive('awxNetTestResults', test_results.test_results) .directive('awxNetTestResults', test_results.test_results)
.directive('awxNetworkUi', awxNetworkUI.awxNetworkUI); .directive('awxNetworkUi', awxNetworkUI.awxNetworkUI)
.service('awxNetStrings', awxNetStrings);

View File

@@ -28,7 +28,8 @@ var NetworkUIController = function($scope,
$log, $log,
ProcessErrors, ProcessErrors,
ConfigService, ConfigService,
rbacUiControlService) { rbacUiControlService,
awxNetStrings) {
window.scope = $scope; window.scope = $scope;
@@ -153,6 +154,7 @@ var NetworkUIController = function($scope,
to_x: 0, to_x: 0,
to_y: 0}; to_y: 0};
$scope.canEdit = $scope.$parent.$resolve.resolvedModels.canEdit; $scope.canEdit = $scope.$parent.$resolve.resolvedModels.canEdit;
$scope.strings = awxNetStrings;
$scope.send_trace_message = function (message) { $scope.send_trace_message = function (message) {
if (!$scope.recording) { if (!$scope.recording) {
return; return;
@@ -265,7 +267,7 @@ var NetworkUIController = function($scope,
}; };
//Inventory Toolbox Setup //Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 0, toolboxTopMargin, 200, toolboxHeight); $scope.inventory_toolbox = new models.ToolBox(0, $scope.strings.get('toolbox.INVENTORY'), 'device', 0, toolboxTopMargin, 200, toolboxHeight);
if (!$scope.disconnected) { if (!$scope.disconnected) {
$scope.for_each_page('/api/v2/inventories/' + $scope.inventory_id + '/hosts/', $scope.for_each_page('/api/v2/inventories/' + $scope.inventory_id + '/hosts/',
function(all_results) { function(all_results) {
@@ -920,8 +922,8 @@ var NetworkUIController = function($scope,
const contextMenuButtonHeight = 26; const contextMenuButtonHeight = 26;
let contextMenuHeight = 64; let contextMenuHeight = 64;
$scope.context_menu_buttons = [ $scope.context_menu_buttons = [
new models.ContextMenuButton("Details", 236, 231, 160, contextMenuButtonHeight, $scope.onDetailsContextButton, $scope), new models.ContextMenuButton($scope.strings.get('context_menu.DETAILS'), 236, 231, 160, contextMenuButtonHeight, $scope.onDetailsContextButton, $scope, 'details'),
new models.ContextMenuButton("Remove", 256, 231, 160, contextMenuButtonHeight, $scope.onDeleteContextMenu, $scope) new models.ContextMenuButton($scope.strings.get('context_menu.REMOVE'), 256, 231, 160, contextMenuButtonHeight, $scope.onDeleteContextMenu, $scope, 'remove')
]; ];
if(!$scope.canEdit){ if(!$scope.canEdit){
$scope.context_menu_buttons.pop(); $scope.context_menu_buttons.pop();

View File

@@ -0,0 +1,56 @@
function awxNetStrings (BaseString) {
BaseString.call(this, 'awxNet');
const { t } = this;
const ns = this.awxNet;
ns.state = {
BREADCRUMB_LABEL: t.s('INVENTORIES')
};
ns.toolbox = {
INVENTORY: t.s('Inventory')
};
ns.actions = {
ACTIONS: t.s('Actions'),
EXPORT: t.s('Export'),
EXPAND_PANEL: t.s('Expand Panel'),
COLLAPSE_PANEL: t.s('Collapse Panel')
};
ns.key = {
KEY: t.s('Key'),
DEBUG_MODE: t.s('Debug Mode'),
HIDE_CURSOR: t.s('Hide Cursor'),
HIDE_BUTTONS: t.s('Hide Buttons'),
HIDE_INTERFACES: t.s('Hide Interfaces'),
RESET_ZOOM: t.s('Reset Zoom')
};
ns.search = {
SEARCH: t.s('Search'),
HOST: t.s('Host'),
SWITCH: t.s('Switch'),
ROUTER: t.s('Router'),
UNKNOWN: t.s('Unknown')
};
ns.context_menu = {
DETAILS: t.s('Details'),
REMOVE: t.s('Remove')
};
ns.details = {
HOST_NAME: t.s('Host Name'),
DESCRIPTION: t.s('Description'),
HOST_POPOVER: t.s('Provide a host name, ip address, or ip address:port. Examples include:'),
SAVE_COMPLETE: t.s('Save Complete'),
CANCEL: t.s('Cancel')
};
}
awxNetStrings.$inject = ['BaseStringService'];
export default awxNetStrings;

View File

@@ -1,4 +1,4 @@
<div class="List-action--notificationAdd"> <div class="List-action--notificationAdd">
<div>GO TO <a ui-sref="notifications.add">NOTIFICATIONS</a> TO</div> <div translate>GO TO <a ui-sref="notifications.add" translate>NOTIFICATIONS</a translate> TO</div>
<div>ADD A NEW TEMPLATE</div> <div translate>ADD A NEW TEMPLATE</div>
</div> </div>

View File

@@ -108,7 +108,7 @@ let lists = [{
delete list.fieldActions.delete; delete list.fieldActions.delete;
list.listTitle = N_('Teams') + ` | {{ name }}`; list.listTitle = N_('Teams') + ` | {{ name }}`;
list.basePath = `${GetBasePath('organizations')}${$stateParams.organization_id}/teams`; list.basePath = `${GetBasePath('organizations')}${$stateParams.organization_id}/teams`;
list.emptyListText = "This list is populated by teams added from the&nbsp;<a ui-sref='teams.add'>Teams</a>&nbsp;section"; list.emptyListText = `${N_('This list is populated by teams added from the')}&nbsp;<a ui-sref='teams.add'>${N_('Teams')}</a>&nbsp;${N_('section')}`;
return list; return list;
}], }],
OrgTeamsDataset: ['OrgTeamList', 'QuerySet', '$stateParams', 'GetBasePath', OrgTeamsDataset: ['OrgTeamList', 'QuerySet', '$stateParams', 'GetBasePath',

View File

@@ -57,17 +57,17 @@
<i>{{question.question_description}}</i> <i>{{question.question_description}}</i>
</div> </div>
<div class="SurveyMaker-previewInputRow"> <div class="SurveyMaker-previewInputRow">
<span dnd-handle class="SurveyMaker-reorderButton" data-placement="top" aw-tool-tip="Drag to reorder question" data-container="#survey-modal-dialog" data-original-title="" title="" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <span dnd-handle class="SurveyMaker-reorderButton" data-placement="top" aw-tool-tip="dragQuestionTooltip" data-tip-watch="dragQuestionTooltip" data-container="#survey-modal-dialog" data-original-title="" title="" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<i class="fa fa-ellipsis-v"></i> <i class="fa fa-ellipsis-v"></i>
<span>&nbsp;</span> <span>&nbsp;</span>
<i class="fa fa-ellipsis-v"></i> <i class="fa fa-ellipsis-v"></i>
</span> </span>
<survey-question class="SurveyMaker-previewInput" preview="true" question="question" ng-required="question.required" ng-disabled=true></survey-question> <survey-question class="SurveyMaker-previewInput" preview="true" question="question" ng-required="question.required" ng-disabled=true></survey-question>
<div class="SurveyMaker-previewActions" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)"> <div class="SurveyMaker-previewActions" ng-show="(job_template_obj.summary_fields.user_capabilities.edit || workflow_job_template_obj.summary_fields.user_capabilities.edit || canAdd)">
<button class="List-actionButton" data-placement="top" ng-class="{'SurveyMaker-previewActions--selected' : editQuestionIndex == $index}" ng-click="editQuestion($index)" aw-tool-tip="Edit question" data-container="#survey-modal-dialog" data-original-title="" title=""> <button class="List-actionButton" data-placement="top" ng-class="{'SurveyMaker-previewActions--selected' : editQuestionIndex == $index}" ng-click="editQuestion($index)" aw-tool-tip="{{editQuestionTooltip}}" data-tip-watch="editQuestionTooltip" data-container="#survey-modal-dialog" data-original-title="" title="">
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</button> </button>
<button class="List-actionButton List-actionButton--delete" data-placement="top" ng-click="showDeleteQuestion($index)" aw-tool-tip="Delete question" data-container="#survey-modal-dialog" data-original-title="" title=""> <button class="List-actionButton List-actionButton--delete" data-placement="top" ng-click="showDeleteQuestion($index)" aw-tool-tip="deleteQuestionTooltip" data-tip-watch="deleteQuestionTooltip" data-container="#survey-modal-dialog" data-original-title="" title="">
<i class="fa fa-trash-o"></i> <i class="fa fa-trash-o"></i>
</button> </button>
</div> </div>

View File

@@ -14,6 +14,7 @@ import SchedulePost from './factories/schedule-post.factory';
import ToggleSchedule from './factories/toggle-schedule.factory'; import ToggleSchedule from './factories/toggle-schedule.factory';
import SchedulesList from './schedules.list'; import SchedulesList from './schedules.list';
import ScheduledJobsList from './scheduled-jobs.list'; import ScheduledJobsList from './scheduled-jobs.list';
import SchedulerStrings from './scheduler.strings';
export default export default
angular.module('scheduler', []) angular.module('scheduler', [])
@@ -26,4 +27,5 @@ export default
.factory('ToggleSchedule', ToggleSchedule) .factory('ToggleSchedule', ToggleSchedule)
.factory('SchedulesList', SchedulesList) .factory('SchedulesList', SchedulesList)
.factory('ScheduledJobsList', ScheduledJobsList) .factory('ScheduledJobsList', ScheduledJobsList)
.directive('schedulerDatePicker', schedulerDatePicker); .directive('schedulerDatePicker', schedulerDatePicker)
.service('SchedulerStrings', SchedulerStrings);

View File

@@ -0,0 +1,61 @@
function SchedulerStrings (BaseString) {
BaseString.call(this, 'scheduler');
const { t } = this;
const ns = this.scheduler;
ns.state = {
CREATE_SCHEDULE: t.s('CREATE SCHEDULE'),
EDIT_SCHEDULE: t.s('EDIT SCHEDULE')
};
ns.form = {
NAME: t.s('Name'),
NAME_REQUIRED_MESSAGE: t.s('A schedule name is required.'),
START_DATE: t.s('Start Date'),
START_TIME: t.s('Start Time'),
START_TIME_ERROR_MESSAGE: t.s('The time must be in HH24:MM:SS format.'),
LOCAL_TIME_ZONE: t.s('Local Time Zone'),
REPEAT_FREQUENCY: t.s('Repeat frequency'),
FREQUENCY_DETAILS: t.s('Frequency Details'),
EVERY: t.s('Every'),
REPEAT_FREQUENCY_ERROR_MESSAGE: t.s('Please provide a value between 1 and 999.'),
ON_DAY: t.s('on day'),
MONTH_DAY_ERROR_MESSAGE: t.s('The day must be between 1 and 31.'),
ON_THE: t.s('on the'),
ON: t.s('on'),
ON_DAYS: t.s('on days'),
SUN: t.s('Sun'),
MON: t.s('Mon'),
TUE: t.s('Tue'),
WED: t.s('Wed'),
THU: t.s('Thu'),
FRI: t.s('Fri'),
SAT: t.s('Sat'),
WEEK_DAY_ERROR_MESSAGE: t.s('Please select one or more days.'),
END: t.s('End'),
OCCURENCES: t.s('Occurrences'),
END_DATE: t.s('End Date'),
PROVIDE_VALID_DATE: t.s('Please provide a valid date.'),
END_TIME: t.s('End Time'),
SCHEDULER_OPTIONS_ARE_INVALID: t.s('The scheduler options are invalid, incomplete, or a date is in the past.'),
SCHEDULE_DESCRIPTION: t.s('Schedule Description'),
LIMITED_TO_FIRST_TEN: t.s('Limited to first 10'),
DATE_FORMAT: t.s('Date format'),
EXTRA_VARIABLES: t.s('Extra Variables'),
PROMPT: t.s('Prompt'),
CLOSE: t.s('Close'),
CANCEL: t.s('Cancel'),
SAVE: t.s('Save'),
WARNING: t.s('Warning'),
CREDENTIAL_REQUIRES_PASSWORD_WARNING: t.s('This Job Template has a default credential that requires a password before launch. Adding or editing schedules is prohibited while this credential is selected. To add or edit a schedule, credentials that require a password must be removed from the Job Template.')
};
ns.prompt = {
CONFIRM: t.s('CONFIRM')
};
}
SchedulerStrings.$inject = ['BaseStringService'];
export default SchedulerStrings;

View File

@@ -8,12 +8,12 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait',
'$scope', '$rootScope', 'CreateSelect2', 'ParseTypeChange', 'GetBasePath', '$scope', '$rootScope', 'CreateSelect2', 'ParseTypeChange', 'GetBasePath',
'Rest', 'ParentObject', 'JobTemplateModel', '$q', 'Empty', 'SchedulePost', 'Rest', 'ParentObject', 'JobTemplateModel', '$q', 'Empty', 'SchedulePost',
'ProcessErrors', 'SchedulerInit', '$location', 'PromptService', 'RRuleToAPI', 'moment', 'ProcessErrors', 'SchedulerInit', '$location', 'PromptService', 'RRuleToAPI', 'moment',
'WorkflowJobTemplateModel', 'TemplatesStrings', 'rbacUiControlService', 'Alert', 'i18n', 'WorkflowJobTemplateModel', 'SchedulerStrings', 'rbacUiControlService', 'Alert',
function($filter, $state, $stateParams, $http, Wait, function($filter, $state, $stateParams, $http, Wait,
$scope, $rootScope, CreateSelect2, ParseTypeChange, GetBasePath, $scope, $rootScope, CreateSelect2, ParseTypeChange, GetBasePath,
Rest, ParentObject, JobTemplate, $q, Empty, SchedulePost, Rest, ParentObject, JobTemplate, $q, Empty, SchedulePost,
ProcessErrors, SchedulerInit, $location, PromptService, RRuleToAPI, moment, ProcessErrors, SchedulerInit, $location, PromptService, RRuleToAPI, moment,
WorkflowJobTemplate, TemplatesStrings, rbacUiControlService, Alert, i18n WorkflowJobTemplate, SchedulerStrings, rbacUiControlService, Alert
) { ) {
var base = $scope.base || $location.path().replace(/^\//, '').split('/')[0], var base = $scope.base || $location.path().replace(/^\//, '').split('/')[0],
@@ -46,7 +46,7 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait',
}; };
$scope.preventCredsWithPasswords = true; $scope.preventCredsWithPasswords = true;
$scope.strings = TemplatesStrings; $scope.strings = SchedulerStrings;
/* /*
* This is a workaround for the angular-scheduler library inserting `ll` into fields after an * This is a workaround for the angular-scheduler library inserting `ll` into fields after an
@@ -116,7 +116,7 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait',
launchConf.passwords_needed_to_start.length > 0 && launchConf.passwords_needed_to_start.length > 0 &&
!launchConf.ask_credential_on_launch !launchConf.ask_credential_on_launch
) { ) {
Alert(i18n._('Warning'), i18n._('This Job Template has a default credential that requires a password before launch. Adding or editing schedules is prohibited while this credential is selected. To add or edit a schedule, credentials that require a password must be removed from the Job Template.'), 'alert-info'); Alert(SchedulerStrings.get('form.WARNING'), SchedulerStrings.get('form.CREDENTIAL_REQUIRES_PASSWORD_WARNING'), 'alert-info');
$state.go('^', { reload: true }); $state.go('^', { reload: true });
} }

View File

@@ -1,11 +1,11 @@
export default ['$filter', '$state', '$stateParams', 'Wait', '$scope', 'moment', export default ['$filter', '$state', '$stateParams', 'Wait', '$scope', 'moment',
'$rootScope', '$http', 'CreateSelect2', 'ParseTypeChange', 'ParentObject', 'ProcessErrors', 'Rest', '$rootScope', '$http', 'CreateSelect2', 'ParseTypeChange', 'ParentObject', 'ProcessErrors', 'Rest',
'GetBasePath', 'SchedulerInit', 'SchedulePost', 'JobTemplateModel', '$q', 'Empty', 'PromptService', 'RRuleToAPI', 'GetBasePath', 'SchedulerInit', 'SchedulePost', 'JobTemplateModel', '$q', 'Empty', 'PromptService', 'RRuleToAPI',
'WorkflowJobTemplateModel', 'TemplatesStrings', 'scheduleResolve', 'timezonesResolve', 'Alert', 'i18n', 'WorkflowJobTemplateModel', 'SchedulerStrings', 'scheduleResolve', 'timezonesResolve', 'Alert',
function($filter, $state, $stateParams, Wait, $scope, moment, function($filter, $state, $stateParams, Wait, $scope, moment,
$rootScope, $http, CreateSelect2, ParseTypeChange, ParentObject, ProcessErrors, Rest, $rootScope, $http, CreateSelect2, ParseTypeChange, ParentObject, ProcessErrors, Rest,
GetBasePath, SchedulerInit, SchedulePost, JobTemplate, $q, Empty, PromptService, RRuleToAPI, GetBasePath, SchedulerInit, SchedulePost, JobTemplate, $q, Empty, PromptService, RRuleToAPI,
WorkflowJobTemplate, TemplatesStrings, scheduleResolve, timezonesResolve, Alert, i18n WorkflowJobTemplate, SchedulerStrings, scheduleResolve, timezonesResolve, Alert
) { ) {
let schedule, scheduler, scheduleCredentials = []; let schedule, scheduler, scheduleCredentials = [];
@@ -21,7 +21,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
$scope.hideForm = true; $scope.hideForm = true;
$scope.parseType = 'yaml'; $scope.parseType = 'yaml';
$scope.strings = TemplatesStrings; $scope.strings = SchedulerStrings;
/* /*
* Keep processSchedulerEndDt method on the $scope * Keep processSchedulerEndDt method on the $scope
@@ -255,7 +255,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
launchConf.passwords_needed_to_start.length > 0 && launchConf.passwords_needed_to_start.length > 0 &&
!launchConf.ask_credential_on_launch !launchConf.ask_credential_on_launch
) { ) {
Alert(i18n._('Warning'), i18n._('This Job Template has a default credential that requires a password before launch. Adding or editing schedules is prohibited while this credential is selected. To add or edit a schedule, credentials that require a password must be removed from the Job Template.'), 'alert-info'); Alert(SchedulerStrings.get('form.WARNING'), SchedulerStrings.get('form.CREDENTIAL_REQUIRES_PASSWORD_WARNING'), 'alert-info');
$scope.credentialRequiresPassword = true; $scope.credentialRequiresPassword = true;
} }

View File

@@ -1,7 +1,7 @@
<div id="htmlTemplate" class=" SchedulerFormPanel Panel" ng-hide="hideForm"> <div id="htmlTemplate" class=" SchedulerFormPanel Panel" ng-hide="hideForm">
<div class="Form-header"> <div class="Form-header">
<div class="Form-title" ng-show="!isEdit">{{ schedulerName || "ADD SCHEDULE"}}</div> <div class="Form-title" ng-show="!isEdit">{{ schedulerName || strings.get('state.CREATE_SCHEDULE') }}</div>
<div class="Form-title" ng-show="isEdit">{{ schedulerName || "EDIT SCHEDULE"}}</div> <div class="Form-title" ng-show="isEdit">{{ schedulerName || strings.get('state.EDIT_SCHEDULE') }}</div>
<div class="Form-header--fields"></div> <div class="Form-header--fields"></div>
<div class="Form-exitHolder"> <div class="Form-exitHolder">
<button class="Form-exit" ng-click="formCancel()"> <button class="Form-exit" ng-click="formCancel()">
@@ -18,7 +18,7 @@
<div class="form-group SchedulerForm-formGroup"> <div class="form-group SchedulerForm-formGroup">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Name {{ strings.get('form.NAME') }}
</label> </label>
<input <input
type="text" type="text"
@@ -32,13 +32,13 @@
placeholder="Schedule name"> placeholder="Schedule name">
<div class="error" <div class="error"
ng-show="scheduler_form.$dirty && scheduler_form.schedulerName.$error.required"> ng-show="scheduler_form.$dirty && scheduler_form.schedulerName.$error.required">
A schedule name is required. {{ strings.get('form.NAME_REQUIRED_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group SchedulerForm-formGroup"> <div class="form-group SchedulerForm-formGroup">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Start Date {{ strings.get('form.START_DATE') }}
</label> </label>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date"> <div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="schedulerStartDt" <scheduler-date-picker date="schedulerStartDt"
@@ -53,7 +53,7 @@
<div class="form-group SchedulerForm-formGroup"> <div class="form-group SchedulerForm-formGroup">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Start Time {{ strings.get('form.START_TIME') }}
<span class="fmt-help" <span class="fmt-help"
ng-show="schedulerShowTimeZone"> ng-show="schedulerShowTimeZone">
(HH24:MM:SS) (HH24:MM:SS)
@@ -111,14 +111,14 @@
</div> </div>
<div class="error" <div class="error"
ng-show="scheduler_startTime_error"> ng-show="scheduler_startTime_error">
The time must be in HH24:MM:SS format. {{ strings.get('form.START_TIME_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group SchedulerForm-formGroup" <div class="form-group SchedulerForm-formGroup"
ng-show="schedulerShowTimeZone"> ng-show="schedulerShowTimeZone">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Local Time Zone {{ strings.get('form.START_TIME') }}
</label> </label>
<select <select
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -134,7 +134,7 @@
<div class="form-group SchedulerForm-formGroup"> <div class="form-group SchedulerForm-formGroup">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Repeat frequency {{ strings.get('form.REPEAT_FREQUENCY') }}
</label> </label>
<select name="schedulerFrequency" <select name="schedulerFrequency"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -151,7 +151,7 @@
</div> </div>
<div class="RepeatFrequencyOptions-label" <div class="RepeatFrequencyOptions-label"
ng-show="schedulerFrequency.value && schedulerFrequency.value !== 'none'"> ng-show="schedulerFrequency.value && schedulerFrequency.value !== 'none'">
Frequency Details</div> {{ strings.get('form.FREQUENCY_DETAILS') }}</div>
<div class="RepeatFrequencyOptions Form" <div class="RepeatFrequencyOptions Form"
ng-show="schedulerFrequency.value && schedulerFrequency.value !== 'none'"> ng-show="schedulerFrequency.value && schedulerFrequency.value !== 'none'">
<div class="form-group <div class="form-group
@@ -161,7 +161,7 @@
<label class="Form-inputLabel <label class="Form-inputLabel
RepeatFrequencyOptions-everyLabel"> RepeatFrequencyOptions-everyLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Every {{ strings.get('form.EVERY') }}
</label> </label>
<input name="schedulerInterval" <input name="schedulerInterval"
id="schedulerInterval" id="schedulerInterval"
@@ -183,7 +183,7 @@
class="error class="error
RepeatFrequencyOptions-error" RepeatFrequencyOptions-error"
ng-show="$parent.scheduler_interval_error"> ng-show="$parent.scheduler_interval_error">
Please provide a value between 1 and 999. {{ strings.get('form.REPEAT_FREQUENCY_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group RepeatFrequencyOptions-formGroup" <div class="form-group RepeatFrequencyOptions-formGroup"
@@ -198,7 +198,7 @@
ng-change="monthlyRepeatChange()" ng-change="monthlyRepeatChange()"
name="monthlyRepeatOption" name="monthlyRepeatOption"
id="monthlyRepeatOption"> id="monthlyRepeatOption">
on day {{ strings.get('form.ON_DAY') }}
</label> </label>
</div> </div>
<input <input
@@ -213,7 +213,7 @@
ng-change="resetError('scheduler_monthDay_error')" > ng-change="resetError('scheduler_monthDay_error')" >
<div class="error" <div class="error"
ng-show="$parent.scheduler_monthDay_error"> ng-show="$parent.scheduler_monthDay_error">
The day must be between 1 and 31. {{ strings.get('form.MONTH_DAY_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group <div class="form-group
@@ -230,7 +230,7 @@
ng-change="monthlyRepeatChange()" ng-change="monthlyRepeatChange()"
name="monthlyRepeatOption" name="monthlyRepeatOption"
id="monthlyRepeatOption"> id="monthlyRepeatOption">
on the {{ strings.get('form.ON_THE') }}
</label> </label>
</div> </div>
<div class="RepeatFrequencyOptions-inputGroup <div class="RepeatFrequencyOptions-inputGroup
@@ -269,7 +269,7 @@
ng-change="yearlyRepeatChange()" ng-change="yearlyRepeatChange()"
name="yearlyRepeatOption" name="yearlyRepeatOption"
id="yearlyRepeatOption"> id="yearlyRepeatOption">
on {{ strings.get('form.ON') }}
</label> </label>
</div> </div>
<div class="RepeatFrequencyOptions-inputGroup <div class="RepeatFrequencyOptions-inputGroup
@@ -297,7 +297,7 @@
</div> </div>
<div class="error" <div class="error"
ng-show="$parent.scheduler_yearlyMonthDay_error"> ng-show="$parent.scheduler_yearlyMonthDay_error">
The day must be between 1 and 31. {{ strings.get('form.MONTH_DAY_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group <div class="form-group
@@ -314,7 +314,7 @@
ng-change="yearlyRepeatChange()" ng-change="yearlyRepeatChange()"
name="yearlyRepeatOption" name="yearlyRepeatOption"
id="yearlyRepeatOption"> id="yearlyRepeatOption">
on the {{ strings.get('form.ON_THE') }}
</label> </label>
</div> </div>
<div <div
@@ -361,7 +361,7 @@
ng-if="schedulerFrequency && schedulerFrequency.value == 'weekly'"> ng-if="schedulerFrequency && schedulerFrequency.value == 'weekly'">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
On Days {{ strings.get('form.ON_DAYS') }}
</label> </label>
<div class="input-group <div class="input-group
RepeatFrequencyOptions-weekButtonContainer"> RepeatFrequencyOptions-weekButtonContainer">
@@ -376,7 +376,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="SU" data-value="SU"
ng-click="$parent.setWeekday($event,'su')"> ng-click="$parent.setWeekday($event,'su')">
Sun {{ strings.get('form.SUN') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -385,7 +385,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="MO" data-value="MO"
ng-click="$parent.setWeekday($event,'mo')"> ng-click="$parent.setWeekday($event,'mo')">
Mon {{ strings.get('form.MON') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -394,7 +394,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="TU" data-value="TU"
ng-click="$parent.setWeekday($event,'tu')"> ng-click="$parent.setWeekday($event,'tu')">
Tue {{ strings.get('form.TUE') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -403,7 +403,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="WE" data-value="WE"
ng-click="$parent.setWeekday($event,'we')"> ng-click="$parent.setWeekday($event,'we')">
Wed {{ strings.get('form.WED') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -412,7 +412,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="TH" data-value="TH"
ng-click="$parent.setWeekday($event,'th')"> ng-click="$parent.setWeekday($event,'th')">
Thu {{ strings.get('form.THU') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -421,7 +421,7 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="FR" data-value="FR"
ng-click="$parent.setWeekday($event,'fr')"> ng-click="$parent.setWeekday($event,'fr')">
Fri {{ strings.get('form.FRI') }}
</button> </button>
<button type="button" <button type="button"
ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-disabled="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
@@ -430,13 +430,13 @@
RepeatFrequencyOptions-weekButton" RepeatFrequencyOptions-weekButton"
data-value="SA" data-value="SA"
ng-click="$parent.setWeekday($event,'sa')"> ng-click="$parent.setWeekday($event,'sa')">
Sat {{ strings.get('form.SAT') }}
</button> </button>
</div> </div>
</div> </div>
<div class="error" <div class="error"
ng-show="$parent.scheduler_weekDays_error"> ng-show="$parent.scheduler_weekDays_error">
Please select one or more days. {{ strings.get('form.WEEK_DAY_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group <div class="form-group
@@ -444,7 +444,7 @@
ng-if="schedulerShowInterval"> ng-if="schedulerShowInterval">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
End {{ strings.get('form.END') }}
</label> </label>
<div> <div>
<select id="schedulerEnd" <select id="schedulerEnd"
@@ -464,7 +464,7 @@
ng-if="schedulerEnd && schedulerEnd.value == 'after'"> ng-if="schedulerEnd && schedulerEnd.value == 'after'">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
Occurrence(s) {{ strings.get('form.OCCURENCES') }}
</label> </label>
<input <input
ng-name="schedulerOccurrenceCount" ng-name="schedulerOccurrenceCount"
@@ -481,14 +481,14 @@
<div class="error <div class="error
RepeatFrequencyOptions-error" RepeatFrequencyOptions-error"
ng-show="$parent.scheduler_occurrenceCount_error"> ng-show="$parent.scheduler_occurrenceCount_error">
Please provide a value between 1 and 999. {{ strings.get('form.REPEAT_FREQUENCY_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
<div class="form-group RepeatFrequencyOptions-formGroup" <div class="form-group RepeatFrequencyOptions-formGroup"
ng-if="schedulerEnd && schedulerEnd.value == 'on'"> ng-if="schedulerEnd && schedulerEnd.value == 'on'">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
End Date {{ strings.get('form.END_DATE') }}
</label> </label>
<div class="input-group Form-inputGroup SchedulerForm-inputGroup--date"> <div class="input-group Form-inputGroup SchedulerForm-inputGroup--date">
<scheduler-date-picker date="$parent.schedulerEndDt" <scheduler-date-picker date="$parent.schedulerEndDt"
@@ -497,14 +497,14 @@
</div> </div>
<div class="error" <div class="error"
ng-show="$parent.scheduler_endDt_error"> ng-show="$parent.scheduler_endDt_error">
Please provide a valid date. {{ strings.get('form.PROVIDE_VALID_DATE') }}
</div> </div>
</div> </div>
<div class="form-group SchedulerForm-formGroup" <div class="form-group SchedulerForm-formGroup"
ng-if="schedulerEnd && schedulerEnd.value == 'on'"> ng-if="schedulerEnd && schedulerEnd.value == 'on'">
<label class="Form-inputLabel"> <label class="Form-inputLabel">
<span class="red-text">*</span> <span class="red-text">*</span>
End Time {{ strings.get('form.END_TIME') }}
<span class="fmt-help" <span class="fmt-help"
ng-show="schedulerShowTimeZone"> ng-show="schedulerShowTimeZone">
(HH24:MM:SS) (HH24:MM:SS)
@@ -562,7 +562,7 @@
</div> </div>
<div class="error" <div class="error"
ng-show="scheduler_startTime_error"> ng-show="scheduler_startTime_error">
The time must be in HH24:MM:SS format. {{ strings.get('form.START_TIME_ERROR_MESSAGE') }}
</div> </div>
</div> </div>
</div> </div>
@@ -574,13 +574,13 @@
SchedulerFormDetail-container--error" SchedulerFormDetail-container--error"
ng-show="(preview_list.isEmpty && scheduler_form.$dirty) || (!schedulerIsValid && scheduler_form.$dirty)"> ng-show="(preview_list.isEmpty && scheduler_form.$dirty) || (!schedulerIsValid && scheduler_form.$dirty)">
<p class="SchedulerFormDetail-errorText"> <p class="SchedulerFormDetail-errorText">
The scheduler options are invalid, incomplete, or a date is in the past. {{ strings.get('form.SCHEDULER_OPTIONS_ARE_INVALID') }}
</p> </p>
</div> </div>
<div class="SchedulerFormDetail-container" <div class="SchedulerFormDetail-container"
ng-show="schedulerIsValid && !preview_list.isEmpty"> ng-show="schedulerIsValid && !preview_list.isEmpty">
<label class="SchedulerFormDetail-label"> <label class="SchedulerFormDetail-label">
Schedule Description {{ strings.get('form.SCHEDULE_DESCRIPTION') }}
</label> </label>
<div class="SchedulerFormDetail-nlp" ng-hide="rrule_nlp_description == 'Natural language description not available' "> <div class="SchedulerFormDetail-nlp" ng-hide="rrule_nlp_description == 'Natural language description not available' ">
{{ rrule_nlp_description }} {{ rrule_nlp_description }}
@@ -588,17 +588,17 @@
<div class="SchedulerFormDetail-occurrenceHeader"> <div class="SchedulerFormDetail-occurrenceHeader">
<label class="SchedulerFormDetail-label <label class="SchedulerFormDetail-label
SchedulerFormDetail-labelOccurrence"> SchedulerFormDetail-labelOccurrence">
Occurrences {{ strings.get('form.OCCURENCES') }}
<span <span
class="SchedulerFormDetail-labelDetail"> class="SchedulerFormDetail-labelDetail">
(Limited to first 10) ({{ strings.get('form.LIMITED_TO_FIRST_TEN') }})
</span> </span>
</label> </label>
<div id="date-choice" <div id="date-choice"
class="SchedulerFormDetail-dateFormats"> class="SchedulerFormDetail-dateFormats">
<label <label
class="SchedulerFormDetail-dateFormatsLabel"> class="SchedulerFormDetail-dateFormatsLabel">
Date format {{ strings.get('form.DATE_FORMAT') }}
</label> </label>
<label class="radio-inline <label class="radio-inline
SchedulerFormDetail-radioLabel"> SchedulerFormDetail-radioLabel">
@@ -607,7 +607,7 @@
ng-model="dateChoice" ng-model="dateChoice"
id="date-choice-local" id="date-choice-local"
value="local" > value="local" >
Local Time Zone {{ strings.get('form.LOCAL_TIME_ZONE') }}
</label> </label>
<label class="radio-inline <label class="radio-inline
SchedulerFormDetail-radioLabel"> SchedulerFormDetail-radioLabel">
@@ -639,7 +639,7 @@
<div class="form-group Form-formGroup Form-textAreaLabel Form-formGroup--fullWidth" ng-hide="noVars"> <div class="form-group Form-formGroup Form-textAreaLabel Form-formGroup--fullWidth" ng-hide="noVars">
<label for="Scheduler-extraVars"> <label for="Scheduler-extraVars">
<span class="Form-inputLabel"> <span class="Form-inputLabel">
Extra Variables {{ strings.get('form.EXTRA_VARIABLES') }}
</span> </span>
<!-- tooltip --> <!-- tooltip -->
<a aw-pop-over="<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>JSON:<br /> <a aw-pop-over="<p>Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON.</p>JSON:<br />
@@ -666,24 +666,25 @@
class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin"
id="schedule_prompt_btn" id="schedule_prompt_btn"
ng-show="showPromptButton" ng-show="showPromptButton"
ng-click="prompt()">Prompt</button> ng-click="prompt()">{{ strings.get('form.PROMPT') }}</button>
<button type="button" <button type="button"
class="btn btn-sm Form-cancelButton" class="btn btn-sm Form-cancelButton"
id="schedule_cancel_btn" id="schedule_cancel_btn"
ng-show="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword" ng-show="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd) || credentialRequiresPassword"
ng-click="formCancel()">Close</button> ng-click="formCancel()">{{ strings.get('form.CLOSE') }}</button>
<button type="button" <button type="button"
class="btn btn-sm Form-cancelButton" class="btn btn-sm Form-cancelButton"
id="schedule_cancel_btn" id="schedule_cancel_btn"
ng-show="(schedule_obj.summary_fields.user_capabilities.edit || canAdd) && !credentialRequiresPassword" ng-show="(schedule_obj.summary_fields.user_capabilities.edit || canAdd) && !credentialRequiresPassword"
ng-click="formCancel()">Cancel</button> ng-click="formCancel()">{{ strings.get('form.CANCEL') }}</button>
<div class="SchedulerForm-promptSave" ng-show="(schedule_obj.summary_fields.user_capabilities.edit || canAdd) && !credentialRequiresPassword"> <div class="SchedulerForm-promptSave" ng-show="(schedule_obj.summary_fields.user_capabilities.edit || canAdd) && !credentialRequiresPassword">
<div ng-if="promptModalMissingReqFields" class="SchedulerForm-promptSaveTooltip" aw-tool-tip="Additional information required in the Prompt area before saving" data-placement="top"></div> <div ng-if="promptModalMissingReqFields" class="SchedulerForm-promptSaveTooltip" aw-tool-tip="Additional information required in the Prompt area before saving" data-placement="top"></div>
<button type="button" <button type="button"
class="btn btn-sm Form-saveButton" class="btn btn-sm Form-saveButton"
id="schedule_save_btn" id="schedule_save_btn"
ng-click="saveSchedule()" ng-click="saveSchedule()"
ng-disabled="!schedulerIsValid || promptModalMissingReqFields || (preview_list.isEmpty && scheduler_form.$dirty) || credentialRequiresPassword"> Save</button> ng-disabled="!schedulerIsValid || promptModalMissingReqFields || (preview_list.isEmpty && scheduler_form.$dirty) || credentialRequiresPassword"> {{ strings.get('form.SAVE') }}</button>
</div> </div>
</div> </div>
<prompt prompt-data="promptData" prevent-creds-with-passwords="preventCredsWithPasswords" action-text="{{:: strings.get('prompt.CONFIRM')}}" read-only-prompts="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd)"></prompt> <prompt prompt-data="promptData" prevent-creds-with-passwords="preventCredsWithPasswords" action-text="{{:: strings.get('prompt.CONFIRM')}}" read-only-prompts="!(schedule_obj.summary_fields.user_capabilities.edit || canAdd)"></prompt>

View File

@@ -1,4 +1,4 @@
export default ['templateUrl', function(templateUrl) { export default ['templateUrl', 'i18n', function(templateUrl, i18n) {
return { return {
restrict: 'E', restrict: 'E',
replace: true, replace: true,
@@ -55,8 +55,8 @@ export default ['templateUrl', function(templateUrl) {
$scope.$watch(list.name, function(){ $scope.$watch(list.name, function(){
selectRowIfPresent(); selectRowIfPresent();
}); });
let resource = list.iterator.replace(/_/g, ' ');
$scope.modalTitle = list.iterator.replace(/_/g, ' '); $scope.modalTitle = i18n._('Select') + ' ' + i18n._(resource);
listeners = eventService.addListeners([ listeners = eventService.addListeners([
[window, 'click', clickToHide] [window, 'click', clickToHide]

View File

@@ -2,7 +2,7 @@
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header Form-header"> <div class="modal-header Form-header">
<div class="Form-title Form-title--uppercase">Select {{modalTitle}}</div> <div class="Form-title Form-title--uppercase">{{modalTitle}}</div>
<!-- optional: transclude header fields --> <!-- optional: transclude header fields -->
<div class="Form-header--fields"></div> <div class="Form-header--fields"></div>
<div class="Form-exitHolder"> <div class="Form-exitHolder">
@@ -16,8 +16,8 @@
<!-- see: lookup-modal.directive.js --> <!-- see: lookup-modal.directive.js -->
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button ng-click="cancelForm()" class="Lookup-cancel btn btn-default">Cancel</button> <button ng-click="cancelForm()" class="Lookup-cancel btn btn-default" translate>Cancel</button>
<button ng-click="saveForm()" class="Lookup-save btn btn-primary" ng-disabled="!currentSelection || !currentSelection.id" ng-bind="list.lookupConfirmText ? list.lookupConfirmText : 'Select'"></button> <button ng-click="saveForm()" class="Lookup-save btn btn-primary" ng-disabled="!currentSelection || !currentSelection.id" translate>Select</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -4,8 +4,8 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export default ['$scope', '$filter', export default ['$scope', '$filter', 'i18n',
function ($scope, $filter) { function ($scope, $filter, i18n) {
function isFailureState(status) { function isFailureState(status) {
return status === 'failed' || status === 'error' || status === 'canceled'; return status === 'failed' || status === 'error' || status === 'canceled';
@@ -40,7 +40,7 @@ export default ['$scope', '$filter',
jobId: job.id, jobId: job.id,
sortDate: job.finished || "running" + job.id, sortDate: job.finished || "running" + job.id,
finished: finished, finished: finished,
status_tip: "JOB ID: " + job.id + "<br>STATUS: " + job.status.toUpperCase() + "<br>FINISHED: " + finished, status_tip: `${i18n._('JOB ID')}: ${job.id} <br>${i18n._('STATUS')}: ${job.status.toUpperCase()} <br>${i18n._('FINISHED')}: ${finished}`,
detailsUrl: detailsBaseUrl + job.id detailsUrl: detailsBaseUrl + job.id
}; };

View File

@@ -200,18 +200,17 @@
var msg; var msg;
switch (data.status) { switch (data.status) {
case 'failed': case 'failed':
msg = "<div>The Project selected has a status of \"failed\". You must run a successful update before you can select a playbook. You will not be able to save this Job Template without a valid playbook."; msg = `<div>${i18n._('The Project selected has a status of')} \"${i18n._('failed')}\". ${i18n._('You must run a successful update before you can select a playbook. You will not be able to save this Job Template without a valid playbook.')}</div>`;
break; break;
case 'never updated': case 'never updated':
msg = "<div>The Project selected has a status of \"never updated\". You must run a successful update before you can select a playbook. You will not be able to save this Job Template without a valid playbook."; msg = `<div>${i18n._('The Project selected has a status of')} \"${i18n._('never updated')}\". ${i18n._('You must run a successful update before you can select a playbook. You will not be able to save this Job Template without a valid playbook.')}</div>`;
break; break;
case 'missing': case 'missing':
msg = '<div>The selected project has a status of \"missing\". Please check the server and make sure ' + msg = `<div>${i18n._('The selected project has a status of')} \"${i18n._('missing')}\". ${i18n._('Please check the server and make sure the directory exists and file permissions are set correctly.')}</div>`;
' the directory exists and file permissions are set correctly.</div>';
break; break;
} }
if (msg) { if (msg) {
Alert('Warning', msg, 'alert-info alert-info--noTextTransform', null, null, null, null, true); Alert(i18n._('Warning'), msg, 'alert-info alert-info--noTextTransform', null, null, null, null, true);
} }
}) })
.catch(({data, status}) => { .catch(({data, status}) => {

View File

@@ -273,7 +273,7 @@ export default ['i18n', function(i18n){
'<div>'+ '<div>'+
'<div class="input-group">'+ '<div class="input-group">'+
'<span class="input-group-btn">'+ '<span class="input-group-btn">'+
'<button type="button" class="btn btn-default show_input_button" id="default_password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="toggleInput(&quot;#default_password&quot;)" data-container="#survey-modal-dialog" data-original-title="" title="">SHOW</button>'+ '<button type="button" class="btn btn-default show_input_button" id="default_password_show_input_button" aw-tool-tip="Toggle the display of plaintext." aw-tip-placement="top" ng-click="toggleInput(&quot;#default_password&quot;)" data-container="#survey-modal-dialog" data-original-title="" title="" translate>SHOW</button>'+
'</span>'+ '</span>'+
'<input id="default_password" type="password" ng-model="default_password" name="default_password" class="form-control Form-textInput" autocomplete="false">'+ '<input id="default_password" type="password" ng-model="default_password" name="default_password" class="form-control Form-textInput" autocomplete="false">'+
'</div>'+ '</div>'+

View File

@@ -1,6 +1,6 @@
export default export default
function Init(DeleteSurvey, EditSurvey, AddSurvey, GenerateForm, SurveyQuestionForm, Wait, Alert, function Init(DeleteSurvey, EditSurvey, AddSurvey, GenerateForm, SurveyQuestionForm, Wait, Alert,
GetBasePath, Rest, ProcessErrors, EditQuestion, CreateSelect2) { GetBasePath, Rest, ProcessErrors, EditQuestion, CreateSelect2, i18n) {
return function(params) { return function(params) {
var scope = params.scope, var scope = params.scope,
id = params.id, id = params.id,
@@ -10,14 +10,18 @@ export default
scope.sce = sce; scope.sce = sce;
scope.survey_questions = []; scope.survey_questions = [];
scope.answer_types=[ scope.answer_types=[
{name: 'Text' , type: 'text'}, {name: i18n._('Text'), type: 'text'},
{name: 'Textarea', type: 'textarea'}, {name: i18n._('Textarea'), type: 'textarea'},
{name: 'Password', type: 'password'}, {name: i18n._('Password'), type: 'password'},
{name: 'Multiple Choice (single select)', type: 'multiplechoice'}, {name: i18n._('Multiple Choice (single select)'), type: 'multiplechoice'},
{name: 'Multiple Choice (multiple select)', type: 'multiselect'}, {name: i18n._('Multiple Choice (multiple select)'), type: 'multiselect'},
{name: 'Integer', type: 'integer'}, {name: i18n._('Integer'), type: 'integer'},
{name: 'Float', type: 'float'} {name: i18n._('Float'), type: 'float'}
]; ];
scope.disableSurveyTooltip = i18n._('Disble Survey');
scope.editQuestionTooltip = i18n._('Edit Question');
scope.deleteQuestionTooltip = i18n._('Delete Question');
scope.dragQuestionTooltip = i18n._('Drag to reorder question');
/* SURVEY RELATED FUNCTIONS */ /* SURVEY RELATED FUNCTIONS */
@@ -476,10 +480,10 @@ export default
inputId = id, inputId = id,
buttonInnerHTML = $(buttonId).html(); buttonInnerHTML = $(buttonId).html();
if (buttonInnerHTML.indexOf("SHOW") > -1) { if (buttonInnerHTML.indexOf("SHOW") > -1) {
$(buttonId).html("HIDE"); $(buttonId).html(i18n._("HIDE"));
$(inputId).attr("type", "text"); $(inputId).attr("type", "text");
} else { } else {
$(buttonId).html("SHOW"); $(buttonId).html(i18n._("SHOW"));
$(inputId).attr("type", "password"); $(inputId).attr("type", "password");
} }
}; };
@@ -511,7 +515,7 @@ export default
// Watcher that updates the survey enabled/disabled tooltip based on scope.survey_enabled // Watcher that updates the survey enabled/disabled tooltip based on scope.survey_enabled
scope.$watch('survey_enabled', function(newVal) { scope.$watch('survey_enabled', function(newVal) {
scope.surveyEnabledTooltip = (newVal) ? "Disable survey" : "Enable survey"; scope.surveyEnabledTooltip = (newVal) ? i18n._("Disable survey") : i18n._("Enable survey");
}); });
}; };
@@ -529,5 +533,6 @@ Init.$inject =
'Rest', 'Rest',
'ProcessErrors', 'ProcessErrors',
'editQuestion', 'editQuestion',
'CreateSelect2' 'CreateSelect2',
'i18n'
]; ];

View File

@@ -4,8 +4,8 @@
* All Rights Reserved * All Rights Reserved
*************************************************/ *************************************************/
export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'GetBasePath', 'ProcessErrors', export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'GetBasePath', 'ProcessErrors', 'TemplatesStrings',
function($state, moment, $timeout, $window, $filter, Rest, GetBasePath, ProcessErrors) { function($state, moment, $timeout, $window, $filter, Rest, GetBasePath, ProcessErrors, TemplatesStrings) {
return { return {
scope: { scope: {
@@ -280,7 +280,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
.attr("y", 30) .attr("y", 30)
.attr("dy", ".35em") .attr("dy", ".35em")
.attr("class", "WorkflowChart-startText") .attr("class", "WorkflowChart-startText")
.text(function () { return "START"; }) .text(function () { return TemplatesStrings.get('workflow_maker.START'); })
.call(add_node); .call(add_node);
} }
else { else {
@@ -333,7 +333,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
.style("font-size","0.7em") .style("font-size","0.7em")
.attr("class", "WorkflowChart-conflictText") .attr("class", "WorkflowChart-conflictText")
.html(function () { .html(function () {
return "<span class=\"WorkflowChart-conflictIcon\">\uf06a</span><span> EDGE CONFLICT</span>"; return `<span class=\"WorkflowChart-conflictIcon\">\uf06a</span><span> ${TemplatesStrings.get('workflow_maker.EDGE_CONFLICT')}</span>`;
}) })
.style("display", function(d) { return (d.edgeConflict && !d.placeholder) ? null : "none"; }); .style("display", function(d) { return (d.edgeConflict && !d.placeholder) ? null : "none"; });
@@ -344,7 +344,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
.attr("text-anchor", "middle") .attr("text-anchor", "middle")
.attr("class", "WorkflowChart-defaultText WorkflowChart-deletedText") .attr("class", "WorkflowChart-defaultText WorkflowChart-deletedText")
.html(function () { .html(function () {
return "<span>DELETED</span>"; return `<span>${TemplatesStrings.get('workflow_maker.DELETED')}</span>`;
}) })
.style("display", function(d) { return d.unifiedJobTemplate || d.placeholder ? "none" : null; }); .style("display", function(d) { return d.unifiedJobTemplate || d.placeholder ? "none" : null; });
@@ -423,7 +423,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
.attr("class", "WorkflowChart-detailsLink") .attr("class", "WorkflowChart-detailsLink")
.style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; }) .style("display", function(d){ return d.job && d.job.status && d.job.id ? null : "none"; })
.text(function () { .text(function () {
return "DETAILS"; return TemplatesStrings.get('workflow_maker.DETAILS');
}) })
.call(details); .call(details);
thisNode.append("circle") thisNode.append("circle")

View File

@@ -23,10 +23,10 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
}; };
$scope.job_type_options = [{ $scope.job_type_options = [{
label: "Run", label: $scope.strings.get('workflow_maker.RUN'),
value: "run" value: "run"
}, { }, {
label: "Check", label: $scope.strings.get('workflow_maker.CHECK'),
value: "check" value: "check"
}]; }];
@@ -36,15 +36,15 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
$scope.edgeTypeOptions = [ $scope.edgeTypeOptions = [
{ {
label: 'Always', label: $scope.strings.get('workflow_maker.ALWAYS'),
value: 'always' value: 'always'
}, },
{ {
label: 'On Success', label: $scope.strings.get('workflow_maker.ON_SUCCESS'),
value: 'success' value: 'success'
}, },
{ {
label: 'On Failure', label: $scope.strings.get('workflow_maker.ON_FAILURE'),
value: 'failure' value: 'failure'
} }
]; ];
@@ -318,17 +318,17 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
optionsToInclude.forEach((optionToInclude) => { optionsToInclude.forEach((optionToInclude) => {
if (optionToInclude === "always") { if (optionToInclude === "always") {
$scope.edgeTypeOptions.push({ $scope.edgeTypeOptions.push({
label: 'Always', label: $scope.strings.get('workflow_maker.ALWAYS'),
value: 'always' value: 'always'
}); });
} else if (optionToInclude === "success") { } else if (optionToInclude === "success") {
$scope.edgeTypeOptions.push({ $scope.edgeTypeOptions.push({
label: 'On Success', label: $scope.strings.get('workflow_maker.ON_SUCCESS'),
value: 'success' value: 'success'
}); });
} else if (optionToInclude === "failure") { } else if (optionToInclude === "failure") {
$scope.edgeTypeOptions.push({ $scope.edgeTypeOptions.push({
label: 'On Failure', label: $scope.strings.get('workflow_maker.ON_FAILURE'),
value: 'failure' value: 'failure'
}); });
} }
@@ -486,20 +486,20 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
}); });
// Set the default to success // Set the default to success
let edgeType = {label: "On Success", value: "success"}; let edgeType = {label: $scope.strings.get('workflow_maker.ON_SUCCESS'), value: "success"};
if (parent && ((betweenTwoNodes && parent.source.isStartNode) || (!betweenTwoNodes && parent.isStartNode))) { if (parent && ((betweenTwoNodes && parent.source.isStartNode) || (!betweenTwoNodes && parent.isStartNode))) {
// We don't want to give the user the option to select // We don't want to give the user the option to select
// a type as this node will always be executed // a type as this node will always be executed
updateEdgeDropdownOptions(["always"]); updateEdgeDropdownOptions(["always"]);
edgeType = {label: "Always", value: "always"}; edgeType = {label: $scope.strings.get('workflow_maker.ALWAYS'), value: "always"};
} else { } else {
if (_.includes(siblingConnectionTypes, "success") || _.includes(siblingConnectionTypes, "failure")) { if (_.includes(siblingConnectionTypes, "success") || _.includes(siblingConnectionTypes, "failure")) {
updateEdgeDropdownOptions(["success", "failure"]); updateEdgeDropdownOptions(["success", "failure"]);
edgeType = {label: "On Success", value: "success"}; edgeType = {label: $scope.strings.get('workflow_maker.ON_SUCCESS'), value: "success"};
} else if (_.includes(siblingConnectionTypes, "always")) { } else if (_.includes(siblingConnectionTypes, "always")) {
updateEdgeDropdownOptions(["always"]); updateEdgeDropdownOptions(["always"]);
edgeType = {label: "Always", value: "always"}; edgeType = {label: $scope.strings.get('workflow_maker.ALWAYS'), value: "always"};
} else { } else {
updateEdgeDropdownOptions(); updateEdgeDropdownOptions();
} }

View File

@@ -4,7 +4,7 @@
<div class="Modal-content modal-content"> <div class="Modal-content modal-content">
<div class="Modal-header"> <div class="Modal-header">
<div class="Modal-title"> <div class="Modal-title">
<span>DELETE</span> <span>{{strings.get('DELETE')}}</span>
<span class="Modal-titleResourceName" ng-bind="nodeToBeDeleted.unifiedJobTemplate.name"></span> <span class="Modal-titleResourceName" ng-bind="nodeToBeDeleted.unifiedJobTemplate.name"></span>
</div> </div>
<div class="Modal-exitHolder"> <div class="Modal-exitHolder">
@@ -14,11 +14,11 @@
</div> </div>
</div> </div>
<div class="Modal-body ng-binding"> <div class="Modal-body ng-binding">
<div class="Prompt-bodyQuery">Are you sure you want to delete this workflow node?</div> <div class="Prompt-bodyQuery">{{strings.get('workflow_maker.DELETE_NODE_PROMPT_TEXT')}}</div>
</div> </div>
<div class="Modal-footer"> <div class="Modal-footer">
<button ng-click="cancelDeleteNode()" class="btn Modal-defaultButton Modal-footerButton">CANCEL</a> <button ng-click="cancelDeleteNode()" class="btn Modal-defaultButton Modal-footerButton">{{strings.get('CANCEL')}}</a>
<button ng-click="confirmDeleteNode()" class="btn Modal-footerButton ng-binding Modal-errorButton">DELETE</a> <button ng-click="confirmDeleteNode()" class="btn Modal-footerButton ng-binding Modal-errorButton">{{strings.get('DELETE')}}</a>
</div> </div>
</div> </div>
</div> </div>
@@ -40,36 +40,36 @@
<i ng-class="{{ keyClassList }}" class="fa fa-key Key-menuIcon" ng-click="toggleKey()"></i> <i ng-class="{{ keyClassList }}" class="fa fa-key Key-menuIcon" ng-click="toggleKey()"></i>
<ul ng-show="showKey" class="Key-list noselect"> <ul ng-show="showKey" class="Key-list noselect">
<li class="Key-listItem"> <li class="Key-listItem">
<p class="Key-heading">KEY</p> <p class="Key-heading">{{strings.get('workflow_maker.KEY')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--success"></div> <div class="Key-icon Key-icon--success"></div>
<p class="Key-listItemContent">On Success</p> <p class="Key-listItemContent">{{strings.get('workflow_maker.ON_SUCCESS')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--fail"></div> <div class="Key-icon Key-icon--fail"></div>
<p class="Key-listItemContent">On Fail</p> <p class="Key-listItemContent">{{strings.get('workflow_maker.ON_FAILURE')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--always"></div> <div class="Key-icon Key-icon--always"></div>
<p class="Key-listItemContent">Always</p> <p class="Key-listItemContent">{{strings.get('workflow_maker.ALWAYS')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--circle Key-icon--default">P</div> <div class="Key-icon Key-icon--circle Key-icon--default">P</div>
<p class="Key-listItemContent Key-listItemContent--circle">Project Sync</p> <p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.PROJECT_SYNC')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--circle Key-icon--default">I</div> <div class="Key-icon Key-icon--circle Key-icon--default">I</div>
<p class="Key-listItemContent Key-listItemContent--circle">Inventory Sync</p> <p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</p>
</li> </li>
<li class="Key-listItem"> <li class="Key-listItem">
<div class="Key-icon Key-icon--circle Key-icon--warning">!</div> <div class="Key-icon Key-icon--circle Key-icon--warning">!</div>
<p class="Key-listItemContent Key-listItemContent--circle">Warning</p> <p class="Key-listItemContent Key-listItemContent--circle">{{strings.get('workflow_maker.WARNING')}}</p>
</li> </li>
</ul> </ul>
</div> </div>
<div class="WorkflowLegend-maker--right"> <div class="WorkflowLegend-maker--right">
<span class="WorkflowMaker-totalJobs">TOTAL TEMPLATES</span> <span class="WorkflowMaker-totalJobs">{{strings.get('workflow_maker.TOTAL_TEMPLATES')}}</span>
<span class="badge List-titleBadge" ng-bind="treeData.data.totalNodes"></span> <span class="badge List-titleBadge" ng-bind="treeData.data.totalNodes"></span>
<i ng-class="{'WorkflowMaker-manualControlsIcon--active': showManualControls}" class="fa fa-cog WorkflowMaker-manualControlsIcon" aria-hidden="true" alt="Controls" ng-click="toggleManualControls()"></i> <i ng-class="{'WorkflowMaker-manualControlsIcon--active': showManualControls}" class="fa fa-cog WorkflowMaker-manualControlsIcon" aria-hidden="true" alt="Controls" ng-click="toggleManualControls()"></i>
<div ng-show="showManualControls" class="WorkflowMaker-manualControls noselect"> <div ng-show="showManualControls" class="WorkflowMaker-manualControls noselect">
@@ -80,13 +80,13 @@
<workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart> <workflow-chart ng-if="modalOpen" tree-data="treeData.data" add-node="startAddNode(parent, betweenTwoNodes)" edit-node="startEditNode(nodeToEdit)" delete-node="startDeleteNode(nodeToDelete)" workflow-zoomed="workflowZoomed(zoom)" can-add-workflow-job-template="canAddWorkflowJobTemplate" workflow-job-template-obj="workflowJobTemplateObj" mode="edit" class="WorkflowMaker-chart"></workflow-chart>
</div> </div>
<div class="WorkflowMaker-contentRight"> <div class="WorkflowMaker-contentRight">
<div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : "EDIT TEMPLATE") : "ADD A TEMPLATE"}}</div> <div class="WorkflowMaker-formTitle">{{(workflowMakerFormConfig.nodeMode === 'edit' && nodeBeingEdited) ? ((nodeBeingEdited.unifiedJobTemplate && nodeBeingEdited.unifiedJobTemplate.name) ? nodeBeingEdited.unifiedJobTemplate.name : strings.get('workflow_maker.EDIT_TEMPLATE')) : strings.get('workflow_maker.ADD_A_TEMPLATE')}}</div>
<div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? 'Please click the start button to build your workflow.' : 'Please hover over a template for additional options.'"></div> <div class="WorkflowMaker-formHelp" ng-show="workflowMakerFormConfig.nodeMode === 'idle'" ng-bind="treeData.data.totalNodes === 0 ? strings.get('workflow_maker.PLEASE_CLICK_THE_START_BUTTON') : strings.get('workflow_maker.PLEASE_HOVER_OVER_A_TEMPLATE')"></div>
<div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'"> <div class="WorkflowMaker-form" ng-show="workflowMakerFormConfig.nodeMode === 'add' || workflowMakerFormConfig.nodeMode === 'edit'">
<div class="Form-tabHolder"> <div class="Form-tabHolder">
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">JOBS</div> <div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'jobs'}" ng-click="toggleFormTab('jobs')">{{strings.get('workflow_maker.JOBS')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">PROJECT SYNC</div> <div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'project_sync'}" ng-click="toggleFormTab('project_sync')">{{strings.get('workflow_maker.PROJECT_SYNC')}}</div>
<div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">INVENTORY SYNC</div> <div class="Form-tab WorkflowMaker-formTab" ng-class="{'is-selected': workflowMakerFormConfig.activeTab === 'inventory_sync'}" ng-click="toggleFormTab('inventory_sync')">{{strings.get('workflow_maker.INVENTORY_SYNC')}}</div>
</div> </div>
<div class="WorkflowMaker-formLists"> <div class="WorkflowMaker-formLists">
<div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div> <div id="workflow-jobs-list" ui-view="jobTemplateList" ng-show="workflowMakerFormConfig.activeTab === 'jobs'"></div>
@@ -112,7 +112,7 @@
<div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)"> <div class="form-group Form-formGroup Form-formGroup--singleColumn" ng-show="selectedTemplate && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)">
<label for="verbosity" class="Form-inputLabelContainer"> <label for="verbosity" class="Form-inputLabelContainer">
<span class="Form-requiredAsterisk">*</span> <span class="Form-requiredAsterisk">*</span>
<span class="Form-inputLabel">RUN</span> <span class="Form-inputLabel">{{:: strings.get('workflow_maker.RUN') }}</span>
</label> </label>
<div> <div>
<select <select
@@ -128,18 +128,18 @@
</div> </div>
</div> </div>
<div class="buttons Form-buttons" id="workflow_maker_controls"> <div class="buttons Form-buttons" id="workflow_maker_controls">
<button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> Prompt</button> <button type="button" class="btn btn-sm Form-primaryButton Form-primaryButton--noMargin" id="workflow_maker_prompt_btn" ng-show="showPromptButton" ng-click="openPromptModal()"> {{:: strings.get('prompt.PROMPT') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> Cancel</button> <button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_cancel_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CANCEL') }}</button>
<button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> Close</button> <button type="button" class="btn btn-sm Form-cancelButton" id="workflow_maker_close_btn" ng-show="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)" ng-click="cancelNodeForm()"> {{:: strings.get('CLOSE') }}</button>
<button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> Select</button> <button type="button" class="btn btn-sm Form-saveButton" id="workflow_maker_select_btn" ng-show="(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate) && !selectedTemplateInvalid && !(credentialRequiresPassword && !promptData.launchConf.ask_credential_on_launch)" ng-click="confirmNodeForm()" ng-disabled="!selectedTemplate || promptModalMissingReqFields || credentialRequiresPassword"> {{:: strings.get('workflow_maker.SELECT') }}</button>
</div> </div>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
<div class="WorkflowMaker-buttonHolder"> <div class="WorkflowMaker-buttonHolder">
<button type="button" class="btn btn-sm WorkflowMaker-cancelButton" ng-click="closeWorkflowMaker()"> Close</button> <button type="button" class="btn btn-sm WorkflowMaker-cancelButton" ng-click="closeWorkflowMaker()"> {{:: strings.get('CLOSE') }}</button>
<button type="button" class="btn btn-sm WorkflowMaker-saveButton" ng-click="saveWorkflowMaker()" ng-show="workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate" ng-disabled="edgeFlags.conflict || workflowMakerFormConfig.nodeMode === 'add'"> Save</button> <button type="button" class="btn btn-sm WorkflowMaker-saveButton" ng-click="saveWorkflowMaker()" ng-show="workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate" ng-disabled="edgeFlags.conflict || workflowMakerFormConfig.nodeMode === 'add'"> {{:: strings.get('SAVE') }}</button>
</div> </div>
<prompt prompt-data="promptData" action-text="{{:: strings.get('prompt.CONFIRM')}}" prevent-creds-with-passwords="preventCredsWithPasswords" read-only-prompts="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)"></prompt> <prompt prompt-data="promptData" action-text="{{:: strings.get('prompt.CONFIRM')}}" prevent-creds-with-passwords="preventCredsWithPasswords" read-only-prompts="!(workflowJobTemplateObj.summary_fields.user_capabilities.edit || canAddWorkflowJobTemplate)"></prompt>
</div> </div>

View File

@@ -20,11 +20,12 @@
.StandardOut-actionButton { .StandardOut-actionButton {
font-size: 16px; font-size: 16px;
height: 20px; height: 30px;
min-width: 30px; min-width: 30px;
color: @list-action-icon; color: @list-action-icon;
background-color: inherit; background-color: inherit;
border: none; border: none;
border-radius: 5px;
} }
.StandardOut-actionButton:hover { .StandardOut-actionButton:hover {

View File

@@ -49,9 +49,7 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
STARTED: i18n._('Started'), STARTED: i18n._('Started'),
FINISHED: i18n._('Finished'), FINISHED: i18n._('Finished'),
LABELS: i18n._('Labels'), LABELS: i18n._('Labels'),
STATUS: '', // re-assigned elsewhere STATUS: i18n._('Status')
JOB_TYPE: '', // re-assigned elsewhere
VERBOSITY: '', // re-assigned elsewhere
}, },
details: { details: {
HEADER: i18n._('DETAILS'), HEADER: i18n._('DETAILS'),
@@ -84,10 +82,8 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
} }
}; };
$scope.strings.labels.STATUS = getLabel('status'); $scope.workflow.statusLabel = i18n._(getLabel('status'));
$scope.strings.tooltips.STATUS = `Job ${$scope.strings.labels.STATUS}`; $scope.strings.tooltips.STATUS = `${i18n._('Job')} ${$scope.workflow.statusLabel}`;
$scope.strings.labels.JOB_TYPE = getLabel('job_type');
$scope.strings.labels.VERBOSITY = getLabel('verbosity');
}; };
var updateWorkflowJobElapsedTimer = function(time) { var updateWorkflowJobElapsedTimer = function(time) {

View File

@@ -65,13 +65,13 @@
<!-- STATUS DETAIL --> <!-- STATUS DETAIL -->
<div class="WorkflowResults-resultRow"> <div class="WorkflowResults-resultRow">
<label class="WorkflowResults-resultRowLabel"> <label class="WorkflowResults-resultRowLabel">
Status {{strings.labels.STATUS}}
</label> </label>
<div class="WorkflowResults-resultRowText"> <div class="WorkflowResults-resultRowText">
<i class="WorkflowResults-statusResultIcon <i class="WorkflowResults-statusResultIcon
fa fa
icon-job-{{ workflow.status }}"> icon-job-{{ workflow.status }}">
</i> {{ strings.labels.STATUS }} </i> {{ workflow.statusLabel }}
</div> </div>
</div> </div>