Skip to content

Commit

Permalink
Fixes #17263 - move jed (i18n) to webpack
Browse files Browse the repository at this point in the history
  • Loading branch information
amirfefer authored and ohadlevy committed Oct 8, 2018
1 parent e7c1caa commit 60e4da4
Show file tree
Hide file tree
Showing 60 changed files with 177 additions and 59 deletions.
1 change: 0 additions & 1 deletion app/assets/javascripts/application.js
@@ -1,6 +1,5 @@
//= require jquery.turbolinks
//= require turbolinks
//= require i18n
//= require jquery.ui.autocomplete
//= require jquery.ui.spinner
//= require scoped_search
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/charts.js
Expand Up @@ -313,7 +313,7 @@ function get_pie_chart(div, url) {
hostsCount += this.data;
});
expanded_pie(target, data.values);
$('.modal-title').empty().append( __('Fact distribution chart') + ' - <b>' + _.escape(data.name) + ' </b><small> ('+ Jed.sprintf(n__("%s host", "%s hosts", hostsCount), hostsCount) +')</small>');
$('.modal-title').empty().append( __('Fact distribution chart') + ' - <b>' + _.escape(data.name) + ' </b><small> ('+ tfm.i18n.sprintf(n__("%s host", "%s hosts", hostsCount), hostsCount) +')</small>');
target.attr('data-url', foreman_url("/hosts?search=facts." + data.name + "~~VAL1~"));
});
});
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/class_edit.js
Expand Up @@ -20,7 +20,7 @@ function add_puppet_class(item){
var links = content.find('a');

links.attr('onclick', 'remove_puppet_class(this)');
links.attr('data-original-title', Jed.sprintf(__('Click to remove %s'), link.data("class-name")));
links.attr('data-original-title', tfm.i18n.sprintf(__('Click to remove %s'), link.data("class-name")));
links.tooltip();
link.removeClass('glyphicon-plus-sign').addClass('glyphicon-minus-sign');

Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/compute_resources/libvirt/nic_info.js
@@ -1,7 +1,7 @@
providerSpecificNICInfo = function(form) {
if (form.find('select.libvirt_network').val() == 'network') {
return Jed.sprintf(__('physical @ NAT %s'), form.find('select.libvirt_nat').val());
return tfm.i18n.sprintf(__('physical @ NAT %s'), form.find('select.libvirt_nat').val());
} else {
return Jed.sprintf(__('physical @ bridge %s'), form.find('select.libvirt_bridge').val());
return tfm.i18n.sprintf(__('physical @ bridge %s'), form.find('select.libvirt_bridge').val());
}
}
6 changes: 3 additions & 3 deletions app/assets/javascripts/host_checkbox.js
Expand Up @@ -97,7 +97,7 @@ function cleanHostsSelection() {

function multiple_selection() {
var total = $("#pagination").data("count");
var alert_text = Jed.sprintf(n__("Single host is selected in total",
var alert_text = tfm.i18n.sprintf(n__("Single host is selected in total",
"All <b> %d </b> hosts are selected.", total), total);
var undo_text = __("Undo selection");
var multiple_alert = $("#multiple-alert");
Expand All @@ -108,9 +108,9 @@ function multiple_selection() {

function undo_multiple_selection() {
var pagination = pagination_metadata();
var alert_text = Jed.sprintf(n__("Single host on this page is selected.",
var alert_text = tfm.i18n.sprintf(n__("Single host on this page is selected.",
"All %s hosts on this page are selected.", pagination.per_page), pagination.per_page);
var select_text = Jed.sprintf(n__("Select this host",
var select_text = tfm.i18n.sprintf(n__("Select this host",
"Select all<b> %s </b> hosts", pagination.total), pagination.total);
var multiple_alert = $("#multiple-alert");
multiple_alert.find(".text").html( alert_text + ' <a href="#" onclick="multiple_selection();">' + select_text + '</a>');
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/host_edit.js
Expand Up @@ -15,7 +15,7 @@ function update_nics(success_callback) {
data: data,
complete: function(){},
error: function(jqXHR, status, error){
$('#network').html(Jed.sprintf(__("Error loading interfaces information: %s"), error));
$('#network').html(tfm.i18n.sprintf(__("Error loading interfaces information: %s"), error));
$('#network_tab a').addClass('tab-error');
},
success: function(result){
Expand Down Expand Up @@ -740,7 +740,7 @@ function interface_subnet_selected(element, ip_field, skip_mac) {
}
},
error: function(request, status, error) {
setError(interface_ip, Jed.sprintf(__("Error generating IP: %s"), error));
setError(interface_ip, tfm.i18n.sprintf(__("Error generating IP: %s"), error));
},
complete: function () {
tfm.tools.hideSpinner();
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/host_edit_interfaces.js
Expand Up @@ -286,7 +286,7 @@ function nic_info(form) {
// common virtual
var attached = form.find('.attached').val();
if (attached != "")
info = Jed.sprintf(__("virtual attached to %s"), attached);
info = tfm.i18n.sprintf(__("virtual attached to %s"), attached);
else
info = __("virtual");

Expand Down
10 changes: 0 additions & 10 deletions app/assets/javascripts/i18n.js

This file was deleted.

2 changes: 1 addition & 1 deletion app/assets/javascripts/spice.js
Expand Up @@ -30,7 +30,7 @@ function spice_error(e) {
}

function spice_success(m) {
$('#spice-status').text(Jed.sprintf(__('Connected (unencrypted) to: %s'), $('#spice-status').attr('data-host')))
$('#spice-status').text(tfm.i18n.sprintf(__('Connected (unencrypted) to: %s'), $('#spice-status').attr('data-host')))
$('#spice-status').addClass('label-success');
}

Expand Down
14 changes: 8 additions & 6 deletions app/views/layouts/base.html.erb
Expand Up @@ -15,12 +15,6 @@
<%= yield(:stylesheets) %>
<%= csrf_meta_tags %>
<%= javascript_include_tag *webpack_asset_paths('vendor', :extension => 'js'), "data-turbolinks-track" => true %>
<%= javascript_include_tag *webpack_asset_paths('bundle', :extension => 'js'), "data-turbolinks-track" => true %>
<%= javascript_include_tag "locale/#{FastGettext.locale}/app", "data-turbolinks-track" => true %>
<%= javascript_include_tag 'application', "data-turbolinks-track" => true %>
<%= webpack_dev_server %>
<%= yield(:javascripts) %>

<script type="text/javascript">
var URL_PREFIX = '<%= request.script_name %>';
Expand All @@ -34,7 +28,15 @@
<% if SETTINGS[:mark_translated] && !Rails.env.test? %>
var I18N_MARK = true;
<% end %>
</script>
<%= javascript_include_tag "locale/#{FastGettext.locale}/app", "data-turbolinks-track" => true %>
<%= javascript_include_tag *webpack_asset_paths('vendor', :extension => 'js'), "data-turbolinks-track" => true %>
<%= javascript_include_tag *webpack_asset_paths('bundle', :extension => 'js'), "data-turbolinks-track" => true %>
<%= javascript_include_tag 'application', "data-turbolinks-track" => true %>
<%= webpack_dev_server %>
<%= yield(:javascripts) %>

<script type="text/javascript">
<%= yield(:inline_javascripts) %>
</script>

Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -73,6 +73,7 @@
"diff": "~3.0.0",
"ipaddr.js": "~1.2.0",
"isomorphic-fetch": "^2.2.1",
"jed": "^1.1.1",
"jquery": "~2.2.4",
"jquery-flot": "~0.8.3",
"jquery-ujs": "~1.2.0",
Expand Down
2 changes: 2 additions & 0 deletions webpack/assets/javascripts/bundle.js
Expand Up @@ -20,6 +20,7 @@ require('./bundle_lodash');
require('./bundle_novnc');

import compute from './foreman_compute_resource';
import i18n from './react_app/common/I18n';

window.tfm = Object.assign(window.tfm || {}, {
authSource: require('./foreman_auth_source'),
Expand All @@ -39,4 +40,5 @@ window.tfm = Object.assign(window.tfm || {}, {
medium: require('./foreman_medium'),
templateInputs: require('./foreman_template_inputs'),
advancedFields: require('./foreman_advanced_fields'),
i18n,
});
3 changes: 2 additions & 1 deletion webpack/assets/javascripts/compute_resource/openstack.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
import { showSpinner, hideSpinner } from '../foreman_tools';
import { sprintf, translate as __ } from '../react_app/common/I18n';

export function schedulerHintFilterSelected(item) {
const filter = $(item).val();
Expand All @@ -23,7 +24,7 @@ export function schedulerHintFilterSelected(item) {
// eslint-disable-next-line function-paren-newline
$('#scheduler_hint_wrapper').html(
// eslint-disable-next-line no-undef
Jed.sprintf(__('Error loading scheduler hint filters information: %s'), error));
sprintf(__('Error loading scheduler hint filters information: %s'), error));
$('#compute_resource_tab a').addClass('tab-error');
},
success(result) {
Expand Down
3 changes: 2 additions & 1 deletion webpack/assets/javascripts/foreman_compute_resource.js
Expand Up @@ -2,6 +2,7 @@
import $ from 'jquery';
import { activateDatatables } from './foreman_tools';
import { notify } from './foreman_toast_notifications';
import { sprintf, translate as __ } from './react_app/common/I18n';

export default {
ec2: require('./compute_resource/ec2'),
Expand Down Expand Up @@ -30,7 +31,7 @@ $(document).on('ContentLoad', () => {
// eslint-disable-next-line function-paren-newline
tab.html(
// eslint-disable-next-line no-undef
Jed.sprintf(__('There was an error listing VMs: %(status)s %(statusText)s'), {
sprintf(__('There was an error listing VMs: %(status)s %(statusText)s'), {
status: xhr.status,
statusText: xhr.statusText,
}));
Expand Down
3 changes: 2 additions & 1 deletion webpack/assets/javascripts/foreman_editor.js
Expand Up @@ -16,6 +16,7 @@ import 'brace/theme/clouds';
import 'brace/keybinding/vim';
import 'brace/keybinding/emacs';
import 'brace/ext/searchbox';
import { sprintf, translate as __ } from './react_app/common/I18n';

import { initTypeAheadSelect } from './foreman_tools';

Expand Down Expand Up @@ -311,7 +312,7 @@ export function revertTemplate(item) {
.find('h6 span')
.attr('data-original-title');

$('#provisioning_template_audit_comment').text(Jed.sprintf(__('Revert to revision from: %s'), time));
$('#provisioning_template_audit_comment').text(sprintf(__('Revert to revision from: %s'), time));
},
});
}
Expand Down
1 change: 1 addition & 0 deletions webpack/assets/javascripts/foreman_hostgroups.js
@@ -1,4 +1,5 @@
import $ from 'jquery';
import { translate as __ } from './react_app/common/I18n';

export function checkForUnavailablePuppetclasses() {
const unavailableClasses = $('#puppet_klasses #selected_classes .unavailable');
Expand Down
7 changes: 0 additions & 7 deletions webpack/assets/javascripts/foreman_hostgroups.test.js
Expand Up @@ -6,13 +6,6 @@ jest.unmock('./foreman_hostgroups');

describe('checkForUnavailablePuppetclasses', () => {
beforeEach(() => {
window.Jed = {
sprintf(input) {
return input;
},
};
window.__ = input => input;

document.body.innerHTML = `<div>
<ul class="nav-tabs">
<li><a href="#puppet_klasses" data-toggle="tab">Puppet Classes</a></li>
Expand Down
12 changes: 12 additions & 0 deletions webpack/assets/javascripts/foreman_tools.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
import URI from 'urijs';
import { translate as __ } from './react_app/common/I18n';

import { showLoading, hideLoading } from './foreman_navigation';

Expand Down Expand Up @@ -125,3 +126,14 @@ export function updateTable(element) {
Turbolinks.visit(uri.toString());
return false;
}

export function deprecateObjectProperty(obj, oldProp, newProp, version = '1.20') {
const oldPropPointer = obj[oldProp];

Object.defineProperty(obj, oldProp, {
get: () => {
deprecate(oldProp, newProp, version);
return oldPropPointer;
},
});
}
9 changes: 9 additions & 0 deletions webpack/assets/javascripts/foreman_tools.test.js
Expand Up @@ -181,4 +181,13 @@ describe('updateTableTest', () => {
return expect(global.Turbolinks.visit).toHaveBeenLastCalledWith(`http://localhost/?page=1&search=&per_page=${PerPage}`);
});
});

it('deprecateObjectProperty should depracte an object property', () => {
const obj = { deprecated: jest.fn() };
console.warn = jest.fn();

tools.deprecateObjectProperty(obj, 'deprecated', 'tfm.obj', '1.42');
obj.deprecated();
expect(console.warn).toHaveBeenCalledWith('DEPRECATION WARNING: you are using deprecated deprecated, it will be removed in Foreman 1.42. Use tfm.obj instead.');
});
});
32 changes: 32 additions & 0 deletions webpack/assets/javascripts/react_app/common/I18n.js
@@ -0,0 +1,32 @@
import Jed from 'jed';
import { deprecateObjectProperty } from '../../foreman_tools';

const cheveronPrefix = () => (window.I18N_MARK ? '\u00BB' : '');
const cheveronSuffix = () => (window.I18N_MARK ? '\u00AB' : '');

const emptyLocales = {
en: { domain: 'app', locale_data: { app: { '': {} } } },
};

const locales = window.locales || emptyLocales;
let locale = document.getElementsByTagName('html')[0].lang;

locale = locale.length === 0 ? 'en' : locale.replace(/-/g, '_');
export const jed = new Jed(locales[locale]);

export const translate = (...args) => `${cheveronPrefix()}${jed.gettext(...args)}${cheveronSuffix()}`;
export const ngettext = (...args) => `${cheveronPrefix()}${jed.ngettext(...args)}${cheveronSuffix()}`;

export const { sprintf } = jed;

const i18n = {
translate, ngettext, jed, sprintf,
};
export default i18n;
window.__ = translate;
window.n__ = ngettext;
window.Jed = jed;
window.i18n = jed;

deprecateObjectProperty(window, 'i18n', 'tfm.i18n');
deprecateObjectProperty(window, 'Jed', 'tfm.i18n.jed');
27 changes: 27 additions & 0 deletions webpack/assets/javascripts/react_app/common/I18n.test.js
@@ -0,0 +1,27 @@
import Jed from 'jed';
import { translate, ngettext } from './I18n';

jest.unmock('./I18n');
jest.unmock('jed');

describe('gettext', () => {
Jed.gettext = jest.fn(s => s);
it('chevrons should not be presented', () => {
expect(translate('should not be with chevrons')).toMatchSnapshot();
});
it('chevrons should be presented', () => {
global.I18N_MARK = true;
expect(translate('should be with chevrons')).toMatchSnapshot();
});
});

describe('ngettext', () => {
Jed.ngettext = jest.fn(s => s);
it('chevrons should not be presented', () => {
expect(ngettext('should not be with chevrons')).toMatchSnapshot();
});
it('chevrons should be presented', () => {
global.I18N_MARK = true;
expect(ngettext('should be with chevrons')).toMatchSnapshot();
});
});
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`gettext chevrons should be presented 1`] = `"»should be with chevrons«"`;

exports[`gettext chevrons should not be presented 1`] = `"should not be with chevrons"`;

exports[`ngettext chevrons should be presented 1`] = `"»should be with chevrons«"`;

exports[`ngettext chevrons should not be presented 1`] = `"»should not be with chevrons«"`;
3 changes: 2 additions & 1 deletion webpack/assets/javascripts/react_app/common/reduxFormI18n.js
@@ -1,4 +1,5 @@
import Validators from 'redux-form-validators';
import { sprintf, translate as __ } from '../../react_app/common/I18n';

Validators.formatMessage = (props) => {
// reusing existing form strings.
Expand All @@ -9,7 +10,7 @@ Validators.formatMessage = (props) => {
const msg = validations[props.id.replace('form.errors.', '')] || props.defaultMessage;
if (props.values) {
// eslint-disable-next-line no-undef
return Jed.sprintf(__(msg), props.values.count);
return sprintf(msg, props.values.count);
}
return __(msg);
};
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { renderTemplatesDiff } from '../../../foreman_editor';
import { translate as __ } from '../../common/I18n';

const renderListItems = items =>
items &&
Expand Down
@@ -1,6 +1,7 @@
import React from 'react';
import { Col } from 'patternfly-react';
import ShowTaxonomyInline from './ShowTaxonomyInline';
import { translate as __ } from '../../common/I18n';

const ShowOrgsLocs = ({
isOrgEnabled = false,
Expand Down
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import EllipsisWithTooltip from 'react-ellipsis-with-tooltip';
import { translate as __ } from '../../common/I18n';

const UserDetails = ({ isAuditLogin, userInfo, remoteAddress }) => {
const {
Expand Down
@@ -1,3 +1,5 @@
import { translate as __ } from '../../../common/I18n';

export const searchLinkProp = {
textValue: 'testUser',
url: '/audits?search=type+%3D+user+and+auditable_id+%3D+1',
Expand Down
Expand Up @@ -2,6 +2,7 @@ import toJson from 'enzyme-to-json';
import { shallowRenderComponentWithFixtures } from '../../../common/testHelpers';
import ShowTaxonomyInline from '../ShowTaxonomyInline';
import { TaxonomyProps } from './AuditsList.fixtures';
import { translate as __ } from '../../../common/I18n';

const OrgsFixtures = {
'render organizations': {
Expand Down
Expand Up @@ -6,6 +6,7 @@ import ShowOrgsLocs from './ShowOrgsLocs';
import ActionLinks from './ActionLinks';
import ExpansiveView from './ExpansiveView';
import UserDetails from './UserDetails';
import { translate as __ } from '../../common/I18n';
import './audit.scss';

const isAuditLogin = (auditedChanges) => {
Expand Down
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import UUID from 'uuid/v1';
import { Icon, OverlayTrigger, Tooltip } from 'patternfly-react';
import { noop } from '../../../common/helpers';
import { translate as __ } from '../../../common/I18n';

const AutoCompleteClearButton = ({ onClear, tooltipID }) => {
const tooltip = <Tooltip id={tooltipID}>{__('Clear')}</Tooltip>;
Expand Down

0 comments on commit 60e4da4

Please sign in to comment.