diff --git a/ui/packages/consul-ui/app/instance-initializers/debug.js b/ui/packages/consul-ui/app/instance-initializers/debug.js index 7274f626d..a3f429aa2 100644 --- a/ui/packages/consul-ui/app/instance-initializers/debug.js +++ b/ui/packages/consul-ui/app/instance-initializers/debug.js @@ -1,4 +1,9 @@ import ApplicationRoute from '../routes/application'; +import { I18nService, formatOptionsSymbol } from './i18n'; +import ucfirst from 'consul-ui/utils/ucfirst'; + +import faker from 'faker'; + let isDebugRoute = false; const routeChange = function(transition) { isDebugRoute = transition.to.name.startsWith('docs'); @@ -23,9 +28,65 @@ const DebugRoute = class extends ApplicationRoute { super.willDestroy(...arguments); } }; + +// we currently use HTML in translations, so anything 'word-like' with these +// chars won't get translated +const translator = cb => item => (!['<', '>', '='].includes(item) ? cb(item) : item); + +class DebugI18nService extends I18nService { + formatMessage(value, formatOptions) { + const text = super.formatMessage(...arguments); + let locale = this.env.var('CONSUL_INTL_LOCALE'); + if (locale) { + switch (this.env.var('CONSUL_INTL_LOCALE')) { + case '-': + return text + .split(' ') + .map( + translator(item => + item + .split('') + .map(item => '-') + .join('') + ) + ) + .join(' '); + case 'la-fk': + locale = 'en'; + // fallsthrough + default: + faker.locale = locale; + return text + .split(' ') + .map( + translator(item => { + const word = faker.lorem.word(); + return item.charAt(0) === item.charAt(0).toUpperCase() ? ucfirst(word) : word; + }) + ) + .join(' '); + } + } + return text; + } + [formatOptionsSymbol]() { + const formatOptions = super[formatOptionsSymbol](...arguments); + if (this.env.var('CONSUL_INTL_DEBUG')) { + return Object.fromEntries( + // skip ember-intl special props like htmlSafe and default + Object.entries(formatOptions).map(([key, value]) => + !['htmlSafe', 'default'].includes(key) ? [key, `{${key}}`] : [key, value] + ) + ); + } + return formatOptions; + } +} export default { name: 'debug', + after: 'i18n', initialize(application) { application.register('route:application', DebugRoute); + application.register('service:intl', DebugI18nService); }, }; diff --git a/ui/packages/consul-ui/app/instance-initializers/i18n.js b/ui/packages/consul-ui/app/instance-initializers/i18n.js index 1019a39a2..601fc32d2 100644 --- a/ui/packages/consul-ui/app/instance-initializers/i18n.js +++ b/ui/packages/consul-ui/app/instance-initializers/i18n.js @@ -1,13 +1,18 @@ import IntlService from 'ember-intl/services/intl'; import { inject as service } from '@ember/service'; -class I18nService extends IntlService { +export const formatOptionsSymbol = Symbol(); +export class I18nService extends IntlService { @service('env') env; /** * Additionally injects selected project level environment variables into the * message formatting context for usage within translated texts */ formatMessage(value, formatOptions) { + formatOptions = this[formatOptionsSymbol](formatOptions); + return super.formatMessage(value, formatOptions); + } + [formatOptionsSymbol](options) { const env = [ 'CONSUL_HOME_URL', 'CONSUL_REPO_ISSUES_URL', @@ -19,12 +24,10 @@ class I18nService extends IntlService { prev[key] = this.env.var(key); return prev; }, {}); - - formatOptions = { - ...formatOptions, + return { + ...options, ...env, }; - return super.formatMessage(value, formatOptions); } } export default { diff --git a/ui/packages/consul-ui/app/utils/get-environment.js b/ui/packages/consul-ui/app/utils/get-environment.js index e7c23fd1a..e21a5cfb9 100644 --- a/ui/packages/consul-ui/app/utils/get-environment.js +++ b/ui/packages/consul-ui/app/utils/get-environment.js @@ -159,6 +159,12 @@ export default function(config = {}, win = window, doc = document) { case 'test': $ = dev().reduce(function(prev, [key, value]) { switch (key) { + case 'CONSUL_INTL_LOCALE': + prev['CONSUL_INTL_LOCALE'] = String(value).toLowerCase(); + break; + case 'CONSUL_INTL_DEBUG': + prev['CONSUL_INTL_DEBUG'] = !!JSON.parse(String(value).toLowerCase()); + break; case 'CONSUL_ACLS_ENABLE': prev['CONSUL_ACLS_ENABLED'] = !!JSON.parse(String(value).toLowerCase()); break; diff --git a/ui/packages/consul-ui/docs/bookmarklets.mdx b/ui/packages/consul-ui/docs/bookmarklets.mdx index e566295db..080e24b74 100644 --- a/ui/packages/consul-ui/docs/bookmarklets.mdx +++ b/ui/packages/consul-ui/docs/bookmarklets.mdx @@ -11,8 +11,11 @@ Below is a list of the most commonly used functions as bookmarklets followed by | [Enable ACLs](javascript:Scenario('CONSUL_ACLS_ENABLE=1')) | Enable ACLs | | [Enable Nspaces](javascript:Scenario('CONSUL_NSPACES_ENABLE=1')) | Enable Namespace Support | | [Enable Partitions](javascript:Scenario('CONSUL_PARTITIONS_ENABLE=1')) | Enable Admin Partition Support | -| [Enable SSO ](javascript:Scenario('CONSUL_SSO_ENABLE=1')) | Enable SSO Support | +| [Enable SSO](javascript:Scenario('CONSUL_SSO_ENABLE=1')) | Enable SSO Support | | [Enable Metrics](javascript:Scenario('CONSUL_METRICS_PROXY_ENABLE=1;CONSUL_METRICS_PROVIDER=prometheus')) | Enable all configuration required for viewing the full Metrics Visualization | +| [Enable Intl Debug](javascript:Scenario('CONSUL_INTL_DEBUG=1')) | Render intl interpolation variable names instead of interpolating them | +| [Intl Lorem Ipsum](javascript:Scenario('CONSUL_INTL_LOCALE=la-fk')) | Render all intl copy as lorem ipsum | +| [Intl Dashes](javascript:Scenario('CONSUL_INTL_LOCALE=-')) | Render all intl copy as `-` | | [Toggle QUnit Display](javascript:(function()%7B(function()%7Bconst%20s%20%3D%20document.getElementById(%22ember-testing-container%22).style%3Bs.display%20%3D%20s.display%20%3D%3D%3D%20%22none%22%20%3F%20%22block%22%20%3A%20%22none%22%3B%7D)()%3B%7D)()%3B) | Toggle the QUnit display on or off during browser testing | | Function | Arguments | Description | diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json index 76f15b70f..35c17e2f9 100644 --- a/ui/packages/consul-ui/package.json +++ b/ui/packages/consul-ui/package.json @@ -141,6 +141,7 @@ "eslint": "^7.12.1", "eslint-plugin-ember": "^7.7.2", "eslint-plugin-node": "^11.0.0", + "faker": "^5.5.3", "flat": "^5.0.0", "husky": "^4.2.5", "ivy-codemirror": "^2.1.0", diff --git a/ui/yarn.lock b/ui/yarn.lock index dfb89ec86..7b5c435a6 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1218,45 +1218,6 @@ walk-sync "^1.1.3" wrap-legacy-hbs-plugin-if-needed "^1.0.1" -"@embroider/core@0.36.0": - version "0.36.0" - resolved "https://registry.yarnpkg.com/@embroider/core/-/core-0.36.0.tgz#fbbd60d29c3fcbe02b4e3e63e6043a43de2b9ce3" - integrity sha512-J6esENP+aNt+/r070cF1RCJyCi/Rn1I6uFp37vxyLWwvGDuT0E7wGcaPU29VBkBFqxi4Z1n4F796BaGHv+kX6w== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.12.3" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-runtime" "^7.12.1" - "@babel/runtime" "^7.12.5" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - "@embroider/macros" "0.36.0" - assert-never "^1.1.0" - babel-plugin-syntax-dynamic-import "^6.18.0" - broccoli-node-api "^1.7.0" - broccoli-persistent-filter "^3.1.2" - broccoli-plugin "^4.0.1" - broccoli-source "^3.0.0" - debug "^3.1.0" - escape-string-regexp "^4.0.0" - fast-sourcemap-concat "^1.4.0" - filesize "^4.1.2" - fs-extra "^7.0.1" - fs-tree-diff "^2.0.0" - handlebars "^4.4.2" - js-string-escape "^1.0.1" - jsdom "^16.4.0" - json-stable-stringify "^1.0.1" - lodash "^4.17.10" - pkg-up "^3.1.0" - resolve "^1.8.1" - resolve-package-path "^1.2.2" - semver "^7.3.2" - strip-bom "^3.0.0" - typescript-memoize "^1.0.0-alpha.3" - walk-sync "^1.1.3" - wrap-legacy-hbs-plugin-if-needed "^1.0.1" - "@embroider/macros@0.33.0": version "0.33.0" resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.33.0.tgz#d5826ea7565bb69b57ba81ed528315fe77acbf9d" @@ -1272,28 +1233,39 @@ resolve "^1.8.1" semver "^7.3.2" -"@embroider/macros@0.36.0", "@embroider/macros@^0.36.0": - version "0.36.0" - resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.36.0.tgz#5330f1e6f12112f0f68e34b3e4855dc7dd3c69a5" - integrity sha512-w37G4uXG+Wi3K3EHSFBSr/n6kGFXYG8nzZ9ptzDOC7LP3Oh5/MskBnVZW3+JkHXUPEqKsDGlxPxCVpPl1kQyjQ== +"@embroider/macros@0.41.0", "@embroider/macros@^0.39.0 || ^0.40.0 || ^0.41.0": + version "0.41.0" + resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.41.0.tgz#3e78b6f388d7229906abf4c75edfff8bb0208aca" + integrity sha512-QISzwEEfLsskZeL0jyZDs1RoQSotwBWj+4upTogNHuxQP5j/9H3IMG/3QB1gh8GEpbudATb/cS4NDYK3UBxufw== dependencies: - "@babel/core" "^7.12.3" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - "@embroider/core" "0.36.0" + "@embroider/shared-internals" "0.41.0" assert-never "^1.1.0" ember-cli-babel "^7.23.0" lodash "^4.17.10" resolve "^1.8.1" semver "^7.3.2" -"@embroider/util@^0.36.0": - version "0.36.0" - resolved "https://registry.yarnpkg.com/@embroider/util/-/util-0.36.0.tgz#b2ffb2b06ac491f157a771392191ce91ef2216a6" - integrity sha512-gMIGL9UQ6Pl5WvpcIqIiE+QkK5GW49VLp+IEl+v4w9ZBkH7Z9boiwWariW4y/FtNU1iU8ELFbol1+IJ8I8VN4Q== +"@embroider/shared-internals@0.41.0": + version "0.41.0" + resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-0.41.0.tgz#2553f026d4f48ea1fd11235501feb63bf49fa306" + integrity sha512-fiqUVB6cfh2UBEFE4yhT5EzagkZ1Q26+OhBV0nJszFEJZx4DqVIb3pxSSZ8P+HhpxuJsQ2XpMA/j02ZPFZfbdQ== dependencies: - "@embroider/macros" "0.36.0" - ember-cli-babel "^7.22.1" + ember-rfc176-data "^0.3.17" + fs-extra "^7.0.1" + lodash "^4.17.10" + pkg-up "^3.1.0" + resolve-package-path "^1.2.2" + semver "^7.3.2" + typescript-memoize "^1.0.0-alpha.3" + +"@embroider/util@^0.39.0 || ^0.40.0 || ^0.41.0", "@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0": + version "0.41.0" + resolved "https://registry.yarnpkg.com/@embroider/util/-/util-0.41.0.tgz#5324cb4742aa4ed8d613c4f88a466f73e4e6acc1" + integrity sha512-ytA3J/YfQh7FEUEBwz3ezTqQNm/S5et5rZw3INBIy4Ak4x0NXV/VXLjyL8mv3txL8fGknZTBdXEhDsHUKIq8SQ== + dependencies: + "@embroider/macros" "0.41.0" + broccoli-funnel "^3.0.5" + ember-cli-babel "^7.23.1" "@eslint/eslintrc@^0.4.0": version "0.4.0" @@ -3593,6 +3565,19 @@ broccoli-funnel@^3.0.1, broccoli-funnel@^3.0.2, broccoli-funnel@^3.0.3: path-posix "^1.0.0" walk-sync "^2.0.2" +broccoli-funnel@^3.0.5: + version "3.0.8" + resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-3.0.8.tgz#f5b62e2763c3918026a15a3c833edc889971279b" + integrity sha512-ng4eIhPYiXqMw6SyGoxPHR3YAwEd2lr9FgBI1CyTbspl4txZovOsmzFkMkGAlu88xyvYXJqHiM2crfLa65T1BQ== + dependencies: + array-equal "^1.0.0" + broccoli-plugin "^4.0.7" + debug "^4.1.1" + fs-tree-diff "^2.0.1" + heimdalljs "^0.2.0" + minimatch "^3.0.0" + walk-sync "^2.0.2" + broccoli-kitchen-sink-helpers@^0.2.5: version "0.2.9" resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc" @@ -3810,6 +3795,19 @@ broccoli-plugin@^4.0.0, broccoli-plugin@^4.0.1, broccoli-plugin@^4.0.2, broccoli rimraf "^3.0.2" symlink-or-copy "^1.3.1" +broccoli-plugin@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz#dd176a85efe915ed557d913744b181abe05047db" + integrity sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg== + dependencies: + broccoli-node-api "^1.7.0" + broccoli-output-wrapper "^3.2.5" + fs-merger "^3.2.1" + promise-map-series "^0.3.0" + quick-temp "^0.1.8" + rimraf "^3.0.2" + symlink-or-copy "^1.3.1" + broccoli-rollup@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/broccoli-rollup/-/broccoli-rollup-4.1.1.tgz#7531a24d88ddab9f1bace1c6ee6e6ca74a38d36f" @@ -5434,20 +5432,20 @@ ember-auto-import@^1.5.2, ember-auto-import@^1.5.3, ember-auto-import@^1.6.0: webpack "^4.43.0" ember-basic-dropdown@^3.0.16: - version "3.0.16" - resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-3.0.16.tgz#287fcde57b5a37405d89cc65e0a4ad9a2e8e1b0b" - integrity sha512-ctVQL63nWoZ6+Lvb6aCo70SUA8ieMz5fQa0BuQKeV2LQx8njXDiZZ96gaK0PBn60glNghbIr1ZKU+wmnIT++5w== + version "3.0.19" + resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-3.0.19.tgz#e15e71097cbcbc585e85c2c5cf677a6434edb1d5" + integrity sha512-5mZ4hbfGLd+TrFAp0JsfcpIb10zqF60SorKc1Bsm29kJF2wy8p0JUXMb21VVF7+phkrRFYbcXy5enFc8qdm4xw== dependencies: "@ember/render-modifiers" "^1.0.2" - "@embroider/macros" "^0.36.0" - "@embroider/util" "^0.36.0" + "@embroider/macros" "^0.39.0 || ^0.40.0 || ^0.41.0" + "@embroider/util" "^0.39.0 || ^0.40.0 || ^0.41.0" "@glimmer/component" "^1.0.4" "@glimmer/tracking" "^1.0.4" ember-cli-babel "^7.23.1" - ember-cli-htmlbars "^5.3.2" + ember-cli-htmlbars "^5.7.0" ember-cli-typescript "^4.1.0" - ember-element-helper "^0.3.2" - ember-maybe-in-element "^2.0.1" + ember-element-helper "^0.5.2" + ember-maybe-in-element "^2.0.2" ember-style-modifier "^0.6.0" ember-truth-helpers "^2.1.0 || ^3.0.0" @@ -5634,7 +5632,7 @@ ember-cli-htmlbars@^4.0.5, ember-cli-htmlbars@^4.2.1, ember-cli-htmlbars@^4.2.3, strip-bom "^4.0.0" walk-sync "^2.0.2" -ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2, ember-cli-htmlbars@^5.2.0, ember-cli-htmlbars@^5.3.1, ember-cli-htmlbars@^5.3.2, ember-cli-htmlbars@^5.6.3: +ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2, ember-cli-htmlbars@^5.2.0, ember-cli-htmlbars@^5.3.1, ember-cli-htmlbars@^5.6.3, ember-cli-htmlbars@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-5.7.1.tgz#eb5b88c7d9083bc27665fb5447a9b7503b32ce4f" integrity sha512-9laCgL4tSy48orNoQgQKEHp93MaqAs9ZOl7or5q+8iyGGJHW6sVXIYrVv5/5O9HfV6Ts8/pW1rSoaeKyLUE+oA== @@ -6111,14 +6109,14 @@ ember-destroyable-polyfill@^2.0.2: ember-cli-version-checker "^5.1.1" ember-compatibility-helpers "^1.2.1" -ember-element-helper@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.3.2.tgz#a0e384c266c6fb0e39803708d6f5e83ce6dba659" - integrity sha512-t4lrekoRb/jVQeg/N1V0kzehV6cw0YAH1hG1H2+Ykl35YxpYdX7/8hKtaGzVPxceemUVFO7fUorEQ6Y//wpWdA== +ember-element-helper@^0.5.2: + version "0.5.5" + resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.5.5.tgz#4a9ecb4dce57ee7f5ceb868a53c7b498c729f056" + integrity sha512-Tu3hsI+/mjHBUvw62Qi+YDZtKkn59V66CjwbgfNTZZ7aHf4gFm1ow4zJ4WLnpnie8p9FvOmIUxwl5HvgPJIcFA== dependencies: + "@embroider/util" "^0.39.1 || ^0.40.0 || ^0.41.0" ember-cli-babel "^7.17.2" ember-cli-htmlbars "^5.1.0" - ember-compatibility-helpers "^1.2.1" ember-exam@^4.0.0: version "4.0.9" @@ -6173,7 +6171,7 @@ ember-getowner-polyfill@^2.0.0: ember-cli-version-checker "^2.1.0" ember-factory-for-polyfill "^1.3.1" -ember-in-element-polyfill@^1.0.0: +ember-in-element-polyfill@^1.0.0, ember-in-element-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz#143504445bb4301656a2eaad42644d684f5164dd" integrity sha512-eHs+7D7PuQr8a1DPqsJTsEyo3FZ1XuH6WEZaEBPDa9s0xLlwByCNKl8hi1EbXOgvgEZNHHi9Rh0vjxyfakrlgg== @@ -6266,15 +6264,15 @@ ember-maybe-import-regenerator@^0.1.6: ember-cli-babel "^6.0.0-beta.4" regenerator-runtime "^0.9.5" -ember-maybe-in-element@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ember-maybe-in-element/-/ember-maybe-in-element-2.0.1.tgz#fa3a26cc2c522a27129d6528b400b9c820943be6" - integrity sha512-Mp/HTVOGu9H7kWoq5xncVLEvPFgRuHdsqWyZ1v/gBA8Y3d2q2LdrmDK9Zg59i+cCs4oa9LrMeFyKMAbBS3vyDw== +ember-maybe-in-element@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/ember-maybe-in-element/-/ember-maybe-in-element-2.0.3.tgz#640ea56b492bdacd1c41c128c2163d933c18c3ec" + integrity sha512-XKuBYPYELwsEmDnJXI7aNSZtt/SKGgRZNMFhASODLz7j0OHSNrcJtjo5Wam/alxIjUIYVjEnMnOzqBLMfJnQkQ== dependencies: ember-cli-babel "^7.21.0" ember-cli-htmlbars "^5.2.0" ember-cli-version-checker "^5.1.1" - ember-in-element-polyfill "^1.0.0" + ember-in-element-polyfill "^1.0.1" ember-modifier-manager-polyfill@^1.1.0, ember-modifier-manager-polyfill@^1.2.0: version "1.2.0" @@ -7215,6 +7213,11 @@ faker@^4.1.0: resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= +faker@^5.5.3: + version "5.5.3" + resolved "https://registry.yarnpkg.com/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e" + integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g== + fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -7709,6 +7712,17 @@ fs-merger@^3.0.1, fs-merger@^3.1.0: rimraf "^2.6.3" walk-sync "^2.0.2" +fs-merger@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/fs-merger/-/fs-merger-3.2.1.tgz#a225b11ae530426138294b8fbb19e82e3d4e0b3b" + integrity sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug== + dependencies: + broccoli-node-api "^1.7.0" + broccoli-node-info "^2.1.0" + fs-extra "^8.0.1" + fs-tree-diff "^2.0.1" + walk-sync "^2.2.0" + fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6: version "0.5.9" resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz#a4ec6182c2f5bd80b9b83c8e23e4522e6f5fd946"