From 1a8b5426f8f8660b3d9eb5f16fa54a6bea91e573 Mon Sep 17 00:00:00 2001 From: Jared Tabor Date: Thu, 31 May 2018 19:06:51 -0700 Subject: [PATCH] UI i18n Audit: Translates strings throughout the UI Translations for dashboard lists -> tooltips Changing "Portal Mode" to "My View," in part due to translations. Adding "Job Template" to strings to be translated from OPTIONS on API Marking translations for JT that has a project that needs to be re-synced. Marking translations for survey maker Marking translations for lookup modal directive Marking translations for empty, "Go To Notifications To Add Template" Adds strings service for scheduler, and marking strings for translation Translations for teams linkout from orgs, as well as cred types Translations for instance groups Marks translations for the Network UI Translates strings on the workflow editor Translations for workflow results Translations for host event modal and some missing translations on the stdout page. --- awx/api/serializers.py | 3 +- .../host-event/host-event-modal.partial.html | 16 ++-- .../host-event/host-event.controller.js | 6 +- .../client/features/output/output.strings.js | 14 +++ .../client/features/output/stats.partial.html | 2 +- .../features/templates/templates.strings.js | 26 ++++++ .../lib/components/components.strings.js | 2 +- .../lib/components/layout/layout.partial.html | 2 +- .../lib/services/base-string.service.js | 1 + .../credential-types/add/add.controller.js | 6 +- .../lists/jobs/jobs-list.directive.js | 15 ++- .../lists/jobs/jobs-list.partial.html | 4 +- .../instance-groups.strings.js | 6 +- .../adhoc/adhoc-credential.route.js | 3 +- .../context_menu_button.partial.svg | 2 +- awx/ui/client/src/network-ui/models.js | 3 +- .../network-details/details.controller.js | 6 +- .../network-details/details.partial.html | 12 +-- .../client/src/network-ui/network-nav/main.js | 4 +- .../network-nav/network.nav.block.less | 4 +- .../network-nav/network.nav.controller.js | 24 ++++- .../network-nav/network.nav.strings.js | 19 ---- .../network-nav/network.nav.view.html | 14 +-- .../client/src/network-ui/network.ui.app.js | 4 +- .../src/network-ui/network.ui.controller.js | 10 +- .../src/network-ui/network.ui.strings.js | 56 ++++++++++++ .../add-notifications-action.partial.html | 4 +- .../linkout/organizations-linkout.route.js | 2 +- .../src/partials/survey-maker-modal.html | 6 +- awx/ui/client/src/scheduler/main.js | 4 +- .../client/src/scheduler/scheduler.strings.js | 61 +++++++++++++ .../src/scheduler/schedulerAdd.controller.js | 8 +- .../src/scheduler/schedulerEdit.controller.js | 8 +- .../src/scheduler/schedulerForm.partial.html | 91 ++++++++++--------- .../shared/lookup/lookup-modal.directive.js | 6 +- .../shared/lookup/lookup-modal.partial.html | 6 +- .../smart-status/smart-status.controller.js | 6 +- .../job-template-add.controller.js | 9 +- .../shared/question-definition.form.js | 2 +- .../survey-maker/surveys/init.factory.js | 29 +++--- .../workflow-chart.directive.js | 12 +-- .../workflow-maker.controller.js | 24 ++--- .../workflow-maker.partial.html | 48 +++++----- .../workflow-results/standard-out.block.less | 3 +- .../workflow-results.controller.js | 10 +- .../workflow-results.partial.html | 4 +- 46 files changed, 393 insertions(+), 214 deletions(-) delete mode 100644 awx/ui/client/src/network-ui/network-nav/network.nav.strings.js create mode 100644 awx/ui/client/src/network-ui/network.ui.strings.js create mode 100644 awx/ui/client/src/scheduler/scheduler.strings.js diff --git a/awx/api/serializers.py b/awx/api/serializers.py index b59d182496..6490180632 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -299,10 +299,11 @@ class BaseSerializer(serializers.ModelSerializer): 'system_job': _('Management Job'), 'workflow_job': _('Workflow Job'), 'workflow_job_template': _('Workflow Template'), + 'job_template': _('Job Template') } choices = [] 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)) return choices diff --git a/awx/ui/client/features/output/host-event/host-event-modal.partial.html b/awx/ui/client/features/output/host-event/host-event-modal.partial.html index 47676df842..3dcc12eb6e 100644 --- a/awx/ui/client/features/output/host-event/host-event-modal.partial.html +++ b/awx/ui/client/features/output/host-event/host-event-modal.partial.html @@ -16,23 +16,23 @@
- CREATED + {{strings.get('host_event_modal.CREATED')}} {{(event.created | longDate) || "No result found"}}
- ID + {{strings.get('host_event_modal.ID')}} {{event.id || "No result found"}}
- PLAY + {{strings.get('host_event_modal.PLAY')}} {{event.play || "No result found"}}
- TASK + {{strings.get('host_event_modal.TASK')}} {{event.task || "No result found"}}
- MODULE + {{strings.get('host_event_modal.MODULE')}} {{module_name}}
@@ -48,12 +48,12 @@ @@ -64,7 +64,7 @@
- +
diff --git a/awx/ui/client/features/output/host-event/host-event.controller.js b/awx/ui/client/features/output/host-event/host-event.controller.js index 280bf51818..9f199fcd34 100644 --- a/awx/ui/client/features/output/host-event/host-event.controller.js +++ b/awx/ui/client/features/output/host-event/host-event.controller.js @@ -2,14 +2,15 @@ function HostEventsController ( $scope, $state, HostEventService, - hostEvent + hostEvent, + OutputStrings ) { $scope.processEventStatus = HostEventService.processEventStatus; $scope.processResults = processResults; $scope.isActiveState = isActiveState; $scope.getActiveHostIndex = getActiveHostIndex; $scope.closeHostEvent = closeHostEvent; - + $scope.strings = OutputStrings; function init () { hostEvent.event_name = hostEvent.event; $scope.event = _.cloneDeep(hostEvent); @@ -165,6 +166,7 @@ HostEventsController.$inject = [ '$state', 'HostEventService', 'hostEvent', + 'OutputStrings' ]; module.exports = HostEventsController; diff --git a/awx/ui/client/features/output/output.strings.js b/awx/ui/client/features/output/output.strings.js index a3fb2458e3..ec22a76d7c 100644 --- a/awx/ui/client/features/output/output.strings.js +++ b/awx/ui/client/features/output/output.strings.js @@ -87,11 +87,25 @@ function OutputStrings (BaseString) { ns.stats = { ELAPSED: t.s('Elapsed'), + PLAYS: t.s('Plays'), + TASKS: t.s('Tasks'), + HOSTS: t.s('Hosts') }; ns.stdout = { 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']; diff --git a/awx/ui/client/features/output/stats.partial.html b/awx/ui/client/features/output/stats.partial.html index 151ae1d23b..c43992eed8 100644 --- a/awx/ui/client/features/output/stats.partial.html +++ b/awx/ui/client/features/output/stats.partial.html @@ -8,7 +8,7 @@ ... {{ vm.tasks }} - hosts + {{:: vm.strings.get('stats.HOSTS')}} ... {{ vm.hosts }} diff --git a/awx/ui/client/features/templates/templates.strings.js b/awx/ui/client/features/templates/templates.strings.js index a0fef3aaff..946fe71fcf 100644 --- a/awx/ui/client/features/templates/templates.strings.js +++ b/awx/ui/client/features/templates/templates.strings.js @@ -23,6 +23,7 @@ function TemplatesStrings (BaseString) { ns.prompt = { INVENTORY: t.s('Inventory'), CREDENTIAL: t.s('Credential'), + PROMPT: t.s('PROMPT'), OTHER_PROMPTS: t.s('Other Prompts'), SURVEY: t.s('Survey'), 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.'), 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']; diff --git a/awx/ui/client/lib/components/components.strings.js b/awx/ui/client/lib/components/components.strings.js index a56ea9854d..00102becff 100644 --- a/awx/ui/client/lib/components/components.strings.js +++ b/awx/ui/client/lib/components/components.strings.js @@ -68,7 +68,7 @@ function ComponentsStrings (BaseString) { DASHBOARD: t.s('Dashboard'), JOBS: t.s('Jobs'), SCHEDULES: t.s('Schedules'), - PORTAL_MODE: t.s('Portal Mode'), + MY_VIEW: t.s('My View'), PROJECTS: t.s('Projects'), CREDENTIALS: t.s('Credentials'), CREDENTIAL_TYPES: t.s('Credential Types'), diff --git a/awx/ui/client/lib/components/layout/layout.partial.html b/awx/ui/client/lib/components/layout/layout.partial.html index df8c5d5843..bf4b78097c 100644 --- a/awx/ui/client/lib/components/layout/layout.partial.html +++ b/awx/ui/client/lib/components/layout/layout.partial.html @@ -42,7 +42,7 @@ - +
diff --git a/awx/ui/client/lib/services/base-string.service.js b/awx/ui/client/lib/services/base-string.service.js index 9ecf87b69b..2362339192 100644 --- a/awx/ui/client/lib/services/base-string.service.js +++ b/awx/ui/client/lib/services/base-string.service.js @@ -71,6 +71,7 @@ function BaseStringService (namespace) { this.DELETE = t.s('DELETE'); this.COPY = t.s('COPY'); this.YES = t.s('YES'); + this.CLOSE = t.s('CLOSE'); this.deleteResource = { HEADER: t.s('Delete'), diff --git a/awx/ui/client/src/credential-types/add/add.controller.js b/awx/ui/client/src/credential-types/add/add.controller.js index 1e01e16736..2d44414962 100644 --- a/awx/ui/client/src/credential-types/add/add.controller.js +++ b/awx/ui/client/src/credential-types/add/add.controller.js @@ -6,10 +6,10 @@ export default ['Rest', 'Wait', 'CredentialTypesForm', 'ProcessErrors', 'GetBasePath', - 'GenerateForm', '$scope', '$state', 'Alert', 'GetChoices', 'ParseTypeChange', 'ToJSON', 'CreateSelect2', + 'GenerateForm', '$scope', '$state', 'Alert', 'GetChoices', 'ParseTypeChange', 'ToJSON', 'CreateSelect2', 'i18n', function(Rest, Wait, CredentialTypesForm, ProcessErrors, GetBasePath, - GenerateForm, $scope, $state, Alert, GetChoices, ParseTypeChange, ToJSON, CreateSelect2 + GenerateForm, $scope, $state, Alert, GetChoices, ParseTypeChange, ToJSON, CreateSelect2, i18n ) { var form = CredentialTypesForm, 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_help_text = `

Getting Started with Credential Types`; + const docs_help_text = `

${i18n._('Getting Started with Credential Types')}`; 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."); diff --git a/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.directive.js b/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.directive.js index e14bc18ab0..07d95ab21d 100644 --- a/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.directive.js +++ b/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.directive.js @@ -3,7 +3,8 @@ export default [ '$filter', 'templateUrl', '$location', - function JobsList($filter, templateUrl, $location) { + 'i18n', + function JobsList($filter, templateUrl, $location, i18n) { return { restrict: 'E', link: link, @@ -29,7 +30,7 @@ export default // detailsUrl, status, name, time scope.jobs = _.map(list, function(job){ - let detailsUrl; + let detailsUrl, tooltip; if (job.type === 'workflow_job') { detailsUrl = `/#/workflows/${job.id}`; @@ -37,12 +38,20 @@ export default 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 { detailsUrl, status: job.status, name: job.name, id: job.id, - time: $filter('longDate')(job.finished) + time: $filter('longDate')(job.finished), + tooltip: tooltip }; }); } diff --git a/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.partial.html b/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.partial.html index b2fe78689f..790600c33a 100644 --- a/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.partial.html +++ b/awx/ui/client/src/home/dashboard/lists/jobs/jobs-list.partial.html @@ -16,10 +16,10 @@ - + - + diff --git a/awx/ui/client/src/instance-groups/instance-groups.strings.js b/awx/ui/client/src/instance-groups/instance-groups.strings.js index 6e4cb2c66d..aff0edfd95 100644 --- a/awx/ui/client/src/instance-groups/instance-groups.strings.js +++ b/awx/ui/client/src/instance-groups/instance-groups.strings.js @@ -34,7 +34,8 @@ function InstanceGroupsStrings (BaseString) { ns.capacityBar = { 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 = { @@ -43,7 +44,8 @@ function InstanceGroupsStrings (BaseString) { }; ns.jobs = { - PANEL_TITLE: t.s('Jobs') + PANEL_TITLE: t.s('Jobs'), + RUNNING_JOBS: t.s('Running Jobs') }; ns.error = { diff --git a/awx/ui/client/src/inventories-hosts/inventories/adhoc/adhoc-credential.route.js b/awx/ui/client/src/inventories-hosts/inventories/adhoc/adhoc-credential.route.js index 82f3321652..c62ba4d547 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/adhoc/adhoc-credential.route.js +++ b/awx/ui/client/src/inventories-hosts/inventories/adhoc/adhoc-credential.route.js @@ -31,9 +31,8 @@ export default { } }, resolve: { - ListDefinition: ['CredentialList', 'i18n', function(CredentialList, i18n) { + ListDefinition: ['CredentialList', function(CredentialList) { let list = _.cloneDeep(CredentialList); - list.lookupConfirmText = i18n._('SELECT'); return list; }], Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath', diff --git a/awx/ui/client/src/network-ui/context_menu_button.partial.svg b/awx/ui/client/src/network-ui/context_menu_button.partial.svg index 2c619cfb4d..22425b7f9f 100644 --- a/awx/ui/client/src/network-ui/context_menu_button.partial.svg +++ b/awx/ui/client/src/network-ui/context_menu_button.partial.svg @@ -11,7 +11,7 @@ dy=".3em" text-anchor="left">{{contextMenuButton.name}} -${$scope.strings.get('details.HOST_POPOVER')}

myserver.domain.com
127.0.0.1
10.1.0.140:25
server.example.com:25
`; $scope.formSave = function(){ var host = { diff --git a/awx/ui/client/src/network-ui/network-details/details.partial.html b/awx/ui/client/src/network-ui/network-details/details.partial.html index f7771e8916..acb5df2894 100644 --- a/awx/ui/client/src/network-ui/network-details/details.partial.html +++ b/awx/ui/client/src/network-ui/network-details/details.partial.html @@ -11,9 +11,9 @@
- + {{strings.get('details.HOST_NAME')}}
@@ -22,8 +22,8 @@
-
diff --git a/awx/ui/client/src/network-ui/network-nav/main.js b/awx/ui/client/src/network-ui/network-nav/main.js index 666130a0af..facbb7cd7d 100644 --- a/awx/ui/client/src/network-ui/network-nav/main.js +++ b/awx/ui/client/src/network-ui/network-nav/main.js @@ -1,5 +1,4 @@ import NetworkingController from './network.nav.controller'; -import NetworkingStrings from './network.nav.strings'; const MODULE_NAME = 'at.features.networking'; @@ -45,12 +44,11 @@ function NetworkingRun ($stateExtender, strings) { NetworkingRun.$inject = [ '$stateExtender', - 'NetworkingStrings' + 'awxNetStrings' ]; angular .module(MODULE_NAME, []) - .service('NetworkingStrings', NetworkingStrings) .run(NetworkingRun); export default MODULE_NAME; diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.block.less b/awx/ui/client/src/network-ui/network-nav/network.nav.block.less index c7d283bedd..7bfbd778a7 100644 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.block.less +++ b/awx/ui/client/src/network-ui/network-nav/network.nav.block.less @@ -164,6 +164,7 @@ font-weight: bold; display: flex; align-items: center; + text-transform: uppercase; } .Networking-keyContainer{ @@ -205,7 +206,8 @@ .Networking-keySymbolLabel{ font-size: 12px; padding-left: 15px; - color: @default-stdout-txt + color: @default-stdout-txt; + text-transform: uppercase; } .Networking-toolboxPanelToolbarIcon--selected{ diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js b/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js index bdba11d147..1e0f9573c4 100644 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js +++ b/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js @@ -33,26 +33,42 @@ function NetworkingController (models, $state, $scope, strings) { $scope.$on('awxNet-instatiateSelect', (e, devices) => { for(var i = 0; i < devices.length; 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({ value: device.id, text: device.name, label: device.name, id: device.id, - type: device.type + type: device.type, + group_type: grouping }); } $("#networking-search").select2({ width:'400px', containerCssClass: 'Form-dropDown', - placeholder: 'SEARCH', + placeholder: strings.get('search.SEARCH'), dropdownParent: $('.Networking-toolbar'), }); + $("#networking-actionsDropdown").select2({ width:'400px', containerCssClass: 'Form-dropDown', minimumResultsForSearch: -1, - placeholder: 'ACTIONS', + placeholder: strings.get('actions.ACTIONS'), dropdownParent: $('.Networking-toolbar'), }); }); @@ -118,7 +134,7 @@ NetworkingController.$inject = [ 'resolvedModels', '$state', '$scope', - 'NetworkingStrings', + 'awxNetStrings', 'CreateSelect2' ]; diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.strings.js b/awx/ui/client/src/network-ui/network-nav/network.nav.strings.js deleted file mode 100644 index 4aa4efca5e..0000000000 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.strings.js +++ /dev/null @@ -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; diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html index 2de980e748..4efd698a90 100644 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html +++ b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html @@ -16,8 +16,8 @@
@@ -33,26 +33,26 @@
- KEY + {{ vm.strings.get('key.KEY') }}
d
-
DEBUG MODE
+
{{ vm.strings.get('key.DEBUG_MODE') }}
i
-
HIDE INTERFACES
+
{{ vm.strings.get('key.HIDE_INTERFACES') }}
0
-
RESET ZOOM
+
{{ vm.strings.get('key.RESET_ZOOM') }}
diff --git a/awx/ui/client/src/network-ui/network.ui.app.js b/awx/ui/client/src/network-ui/network.ui.app.js index 7fb414950d..3da725f7ff 100644 --- a/awx/ui/client/src/network-ui/network.ui.app.js +++ b/awx/ui/client/src/network-ui/network.ui.app.js @@ -3,6 +3,7 @@ import atFeaturesNetworking from './network-nav/main'; import networkDetailsDirective from './network-details/main'; import networkZoomWidget from './zoom-widget/main'; +import awxNetStrings from './network.ui.strings'; //console.log = function () { }; var NetworkUIController = require('./network.ui.controller.js'); @@ -40,4 +41,5 @@ export default .directive('awxNetQuadrants', quadrants.quadrants) .directive('awxNetInventoryToolbox', inventoryToolbox.inventoryToolbox) .directive('awxNetTestResults', test_results.test_results) - .directive('awxNetworkUi', awxNetworkUI.awxNetworkUI); + .directive('awxNetworkUi', awxNetworkUI.awxNetworkUI) + .service('awxNetStrings', awxNetStrings); diff --git a/awx/ui/client/src/network-ui/network.ui.controller.js b/awx/ui/client/src/network-ui/network.ui.controller.js index c7e066553f..a207471da6 100644 --- a/awx/ui/client/src/network-ui/network.ui.controller.js +++ b/awx/ui/client/src/network-ui/network.ui.controller.js @@ -28,7 +28,8 @@ var NetworkUIController = function($scope, $log, ProcessErrors, ConfigService, - rbacUiControlService) { + rbacUiControlService, + awxNetStrings) { window.scope = $scope; @@ -153,6 +154,7 @@ var NetworkUIController = function($scope, to_x: 0, to_y: 0}; $scope.canEdit = $scope.$parent.$resolve.resolvedModels.canEdit; + $scope.strings = awxNetStrings; $scope.send_trace_message = function (message) { if (!$scope.recording) { return; @@ -265,7 +267,7 @@ var NetworkUIController = function($scope, }; //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) { $scope.for_each_page('/api/v2/inventories/' + $scope.inventory_id + '/hosts/', function(all_results) { @@ -920,8 +922,8 @@ var NetworkUIController = function($scope, const contextMenuButtonHeight = 26; let contextMenuHeight = 64; $scope.context_menu_buttons = [ - new models.ContextMenuButton("Details", 236, 231, 160, contextMenuButtonHeight, $scope.onDetailsContextButton, $scope), - new models.ContextMenuButton("Remove", 256, 231, 160, contextMenuButtonHeight, $scope.onDeleteContextMenu, $scope) + new models.ContextMenuButton($scope.strings.get('context_menu.DETAILS'), 236, 231, 160, contextMenuButtonHeight, $scope.onDetailsContextButton, $scope, 'details'), + new models.ContextMenuButton($scope.strings.get('context_menu.REMOVE'), 256, 231, 160, contextMenuButtonHeight, $scope.onDeleteContextMenu, $scope, 'remove') ]; if(!$scope.canEdit){ $scope.context_menu_buttons.pop(); diff --git a/awx/ui/client/src/network-ui/network.ui.strings.js b/awx/ui/client/src/network-ui/network.ui.strings.js new file mode 100644 index 0000000000..4b93ea90a6 --- /dev/null +++ b/awx/ui/client/src/network-ui/network.ui.strings.js @@ -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; diff --git a/awx/ui/client/src/notifications/notification-templates-list/add-notifications-action.partial.html b/awx/ui/client/src/notifications/notification-templates-list/add-notifications-action.partial.html index af71530737..e6c2484fe1 100644 --- a/awx/ui/client/src/notifications/notification-templates-list/add-notifications-action.partial.html +++ b/awx/ui/client/src/notifications/notification-templates-list/add-notifications-action.partial.html @@ -1,4 +1,4 @@
-
GO TO NOTIFICATIONS TO
-
ADD A NEW TEMPLATE
+
GO TO NOTIFICATIONS TO
+
ADD A NEW TEMPLATE
diff --git a/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js b/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js index f605f6c08e..b0161b2a89 100644 --- a/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js +++ b/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js @@ -108,7 +108,7 @@ let lists = [{ delete list.fieldActions.delete; list.listTitle = N_('Teams') + ` | {{ name }}`; list.basePath = `${GetBasePath('organizations')}${$stateParams.organization_id}/teams`; - list.emptyListText = "This list is populated by teams added from the Teams section"; + list.emptyListText = `${N_('This list is populated by teams added from the')} ${N_('Teams')} ${N_('section')}`; return list; }], OrgTeamsDataset: ['OrgTeamList', 'QuerySet', '$stateParams', 'GetBasePath', diff --git a/awx/ui/client/src/partials/survey-maker-modal.html b/awx/ui/client/src/partials/survey-maker-modal.html index b6acbe2ab3..476af0bc30 100644 --- a/awx/ui/client/src/partials/survey-maker-modal.html +++ b/awx/ui/client/src/partials/survey-maker-modal.html @@ -57,17 +57,17 @@ {{question.question_description}}
- +  
- -
diff --git a/awx/ui/client/src/scheduler/main.js b/awx/ui/client/src/scheduler/main.js index 038053e83a..80592b2e59 100644 --- a/awx/ui/client/src/scheduler/main.js +++ b/awx/ui/client/src/scheduler/main.js @@ -14,6 +14,7 @@ import SchedulePost from './factories/schedule-post.factory'; import ToggleSchedule from './factories/toggle-schedule.factory'; import SchedulesList from './schedules.list'; import ScheduledJobsList from './scheduled-jobs.list'; +import SchedulerStrings from './scheduler.strings'; export default angular.module('scheduler', []) @@ -26,4 +27,5 @@ export default .factory('ToggleSchedule', ToggleSchedule) .factory('SchedulesList', SchedulesList) .factory('ScheduledJobsList', ScheduledJobsList) - .directive('schedulerDatePicker', schedulerDatePicker); + .directive('schedulerDatePicker', schedulerDatePicker) + .service('SchedulerStrings', SchedulerStrings); diff --git a/awx/ui/client/src/scheduler/scheduler.strings.js b/awx/ui/client/src/scheduler/scheduler.strings.js new file mode 100644 index 0000000000..4d4173e5a3 --- /dev/null +++ b/awx/ui/client/src/scheduler/scheduler.strings.js @@ -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; diff --git a/awx/ui/client/src/scheduler/schedulerAdd.controller.js b/awx/ui/client/src/scheduler/schedulerAdd.controller.js index c5e04c5035..e3fdda845f 100644 --- a/awx/ui/client/src/scheduler/schedulerAdd.controller.js +++ b/awx/ui/client/src/scheduler/schedulerAdd.controller.js @@ -8,12 +8,12 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait', '$scope', '$rootScope', 'CreateSelect2', 'ParseTypeChange', 'GetBasePath', 'Rest', 'ParentObject', 'JobTemplateModel', '$q', 'Empty', 'SchedulePost', 'ProcessErrors', 'SchedulerInit', '$location', 'PromptService', 'RRuleToAPI', 'moment', - 'WorkflowJobTemplateModel', 'TemplatesStrings', 'rbacUiControlService', 'Alert', 'i18n', + 'WorkflowJobTemplateModel', 'SchedulerStrings', 'rbacUiControlService', 'Alert', function($filter, $state, $stateParams, $http, Wait, $scope, $rootScope, CreateSelect2, ParseTypeChange, GetBasePath, Rest, ParentObject, JobTemplate, $q, Empty, SchedulePost, ProcessErrors, SchedulerInit, $location, PromptService, RRuleToAPI, moment, - WorkflowJobTemplate, TemplatesStrings, rbacUiControlService, Alert, i18n + WorkflowJobTemplate, SchedulerStrings, rbacUiControlService, Alert ) { var base = $scope.base || $location.path().replace(/^\//, '').split('/')[0], @@ -46,7 +46,7 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait', }; $scope.preventCredsWithPasswords = true; - $scope.strings = TemplatesStrings; + $scope.strings = SchedulerStrings; /* * 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.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 }); } diff --git a/awx/ui/client/src/scheduler/schedulerEdit.controller.js b/awx/ui/client/src/scheduler/schedulerEdit.controller.js index 6d63b04361..4aa3044adf 100644 --- a/awx/ui/client/src/scheduler/schedulerEdit.controller.js +++ b/awx/ui/client/src/scheduler/schedulerEdit.controller.js @@ -1,11 +1,11 @@ export default ['$filter', '$state', '$stateParams', 'Wait', '$scope', 'moment', '$rootScope', '$http', 'CreateSelect2', 'ParseTypeChange', 'ParentObject', 'ProcessErrors', 'Rest', '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, $rootScope, $http, CreateSelect2, ParseTypeChange, ParentObject, ProcessErrors, Rest, GetBasePath, SchedulerInit, SchedulePost, JobTemplate, $q, Empty, PromptService, RRuleToAPI, - WorkflowJobTemplate, TemplatesStrings, scheduleResolve, timezonesResolve, Alert, i18n + WorkflowJobTemplate, SchedulerStrings, scheduleResolve, timezonesResolve, Alert ) { let schedule, scheduler, scheduleCredentials = []; @@ -21,7 +21,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment, $scope.hideForm = true; $scope.parseType = 'yaml'; - $scope.strings = TemplatesStrings; + $scope.strings = SchedulerStrings; /* * 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.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; } diff --git a/awx/ui/client/src/scheduler/schedulerForm.partial.html b/awx/ui/client/src/scheduler/schedulerForm.partial.html index 6b89b335df..3627fe5d5e 100644 --- a/awx/ui/client/src/scheduler/schedulerForm.partial.html +++ b/awx/ui/client/src/scheduler/schedulerForm.partial.html @@ -1,7 +1,7 @@
-
{{ schedulerName || "ADD SCHEDULE"}}
-
{{ schedulerName || "EDIT SCHEDULE"}}
+
{{ schedulerName || strings.get('state.CREATE_SCHEDULE') }}
+
{{ schedulerName || strings.get('state.EDIT_SCHEDULE') }}
- on the + {{ strings.get('form.ON_THE') }}
- on + {{ strings.get('form.ON') }}
- The day must be between 1 and 31. + {{ strings.get('form.MONTH_DAY_ERROR_MESSAGE') }}
- on the + {{ strings.get('form.ON_THE') }}
@@ -376,7 +376,7 @@ RepeatFrequencyOptions-weekButton" data-value="SU" ng-click="$parent.setWeekday($event,'su')"> - Sun + {{ strings.get('form.SUN') }}
- Please select one or more days. + {{ strings.get('form.WEEK_DAY_ERROR_MESSAGE') }}
- Please provide a value between 1 and 999. + {{ strings.get('form.REPEAT_FREQUENCY_ERROR_MESSAGE') }}
- Please provide a valid date. + {{ strings.get('form.PROVIDE_VALID_DATE') }}
- The time must be in HH24:MM:SS format. + {{ strings.get('form.START_TIME_ERROR_MESSAGE') }}
@@ -574,13 +574,13 @@ SchedulerFormDetail-container--error" ng-show="(preview_list.isEmpty && scheduler_form.$dirty) || (!schedulerIsValid && scheduler_form.$dirty)">

- The scheduler options are invalid, incomplete, or a date is in the past. + {{ strings.get('form.SCHEDULER_OPTIONS_ARE_INVALID') }}

{{ rrule_nlp_description }} @@ -588,17 +588,17 @@