Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLM-8914 Cart Translations Issue #220

Open
wants to merge 57 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3511d42
chore: use sourceDefaultNamespace for translation mapping
AlexONeillTI Jul 19, 2023
4b220d7
chore: update parseFuncFromString arguments to catch all translations
AlexONeillTI Jul 20, 2023
72fda09
chore: throw error if translations don't exist
AlexONeillTI Jul 24, 2023
6b2400c
fix: use t(translation-key) directly
AlexONeillTI Jul 24, 2023
736e9ff
chore: remove unused contants file
AlexONeillTI Jul 24, 2023
c9bb713
chore: include .mjs files
AlexONeillTI Jul 25, 2023
8e45b8e
chore: abstract functions for use in testing
AlexONeillTI Aug 15, 2023
28be445
fix: Merge branch 'staging' of https://github.com/thoughtindustries/h…
AlexONeillTI Aug 15, 2023
0413d45
chore: adding test cases for parse-translations
AlexONeillTI Aug 16, 2023
3027ae2
chore: remove await from function with .then()
AlexONeillTI Aug 16, 2023
0a27f08
chore: change to deploy script to refactor IIFE in parse-translations…
AlexONeillTI Aug 17, 2023
b2f5e4d
fix: empty translations file before writing
AlexONeillTI Aug 17, 2023
e559bd7
test: GITHUB_WORKSPACE instead of process.cwd
AlexONeillTI Aug 17, 2023
86e7a7f
test: correct path
AlexONeillTI Aug 17, 2023
20b6317
test: access promise
AlexONeillTI Aug 17, 2023
435f6bb
test: test
AlexONeillTI Aug 17, 2023
e17ee92
chore: refactor
AlexONeillTI Aug 17, 2023
b452f73
test: add logging
AlexONeillTI Aug 17, 2023
161f884
chore: check if translations exist in github
AlexONeillTI Aug 17, 2023
f0e9a0d
test: isolate reading test
AlexONeillTI Aug 18, 2023
8c4d509
chore: update processedTranslations
AlexONeillTI Aug 18, 2023
1441330
test: test
AlexONeillTI Aug 18, 2023
781b1c9
test: change scope of function
AlexONeillTI Aug 18, 2023
19df644
chore: adding more logs to debug
AlexONeillTI Aug 18, 2023
cad1f4d
test: hardcode compiledPaths
AlexONeillTI Aug 18, 2023
9c68443
test: test
AlexONeillTI Aug 18, 2023
29e0d7d
chore: hardcode compiledProjectPath
AlexONeillTI Aug 18, 2023
c007ce3
feat: add error handling to getFilePaths
AlexONeillTI Aug 18, 2023
8f339dc
chore: check if file exists for path.join(OP_DIR, 'dist');
AlexONeillTI Aug 18, 2023
123745b
chore: remove dist from .gitignore
AlexONeillTI Aug 18, 2023
c9dc1a6
chore: add writeTranslations tests back
AlexONeillTI Aug 18, 2023
2c94bda
chore: expand test coverage
AlexONeillTI Aug 18, 2023
e3ec81b
chore: remove dist directory
AlexONeillTI Aug 29, 2023
089fb73
chore: remove parse-translations from cli
AlexONeillTI Aug 29, 2023
55d0a1e
chore: update-translations jest test complete
AlexONeillTI Oct 4, 2023
56eb2ec
chore: instance-translation file and new commands
AlexONeillTI Oct 4, 2023
d367874
chore: add jest to lock file
AlexONeillTI Oct 4, 2023
1effcc9
chore: move fetchTranslations to global scope to remove github action…
AlexONeillTI Oct 4, 2023
28c600e
chore: updte fetchTranslations
AlexONeillTI Oct 4, 2023
a90721f
test: update import order
AlexONeillTI Oct 4, 2023
bd30b83
test: test
AlexONeillTI Oct 4, 2023
2097c60
chore: push test ti-config.json
AlexONeillTI Oct 4, 2023
93545ce
test: test
AlexONeillTI Oct 4, 2023
7aeaadf
test: change path.join to path.resolve
AlexONeillTI Oct 10, 2023
dfc8b63
test: process.cwd instead of __dirname
AlexONeillTI Oct 10, 2023
67aff2f
test: test
AlexONeillTI Oct 10, 2023
3036c1f
test: resolve path update
AlexONeillTI Oct 10, 2023
5aaae0a
chore: improve naming
AlexONeillTI Oct 10, 2023
3f16d91
chore: Update deploy.js script
AlexONeillTI Oct 10, 2023
7c1255d
chore: process-translations tests
AlexONeillTI Oct 11, 2023
1287825
chore: Merge branch 'CLM-8914-cart-translation-issues' of https://git…
AlexONeillTI Oct 11, 2023
4569669
Merge branch 'staging' into CLM-8914-cart-translation-issues
AlexONeillTI Nov 17, 2023
f365df4
fix: formatting in package.json
AlexONeillTI Nov 17, 2023
24b0a5e
Merge branch 'staging' into CLM-8914-cart-translation-issues
chrisvariety Jun 14, 2024
bc4e04e
chore: update helium update-translations command
AlexONeillTI Aug 21, 2024
45aae0c
chore: update deploy and translations scripts
AlexONeillTI Aug 22, 2024
6c5d1f5
chore: change parserScript callin deploy script
AlexONeillTI Sep 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],

// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
moduleNameMapper: {
'sortobject(.*)': '<rootDir>/node_modules/sortobject/edition-es2019/index.js'
},

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
modulePathIgnorePatterns: [
Expand Down
2,320 changes: 2,021 additions & 299 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 0 additions & 11 deletions packages/catalog/src/variants/filter-selector/constants.ts

This file was deleted.

16 changes: 13 additions & 3 deletions packages/catalog/src/variants/filter-selector/sort-selector.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { GlobalTypes } from '@thoughtindustries/content';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { CatalogParams, useCatalog } from '../../core';
import { localizedSortMapping } from './constants';
import { CatalogParams, SortField, useCatalog } from '../../core';
import DropdownMenu from './dropdown-menu';

const SortSelector = ({
enabledSorts,
sort
}: Pick<CatalogParams, 'enabledSorts' | 'sort'>): JSX.Element => {
const { t } = useTranslation();

const localizedSortMapping: { [key in SortField]: string } = {
[GlobalTypes.SortColumn.UpdatedAt]: t('catalog.sort-updated'),
[GlobalTypes.SortColumn.CreatedAt]: t('catalog.sort-created'),
[GlobalTypes.SortColumn.Title]: t('catalog.sort-title'),
[GlobalTypes.SortColumn.PublishDate]: t('catalog.sort-publish-date'),
[GlobalTypes.SortColumn.CourseStartDate]: t('catalog.sort-course-start-date'),
[GlobalTypes.SortColumn.Relevance]: t('catalog.sort-relevance')
};

const { urlManager } = useCatalog();
const { field: selectedField, direction: selectedDirection } = sort || {};
const label = t('catalog.sort-by');
const filters = enabledSorts.map(item => ({
isSelected: selectedField === item.field && selectedDirection === item.direction,
name: t(localizedSortMapping[item.field]),
name: localizedSortMapping[item.field],
link: urlManager.composeURLForSetSort(item)
}));

Expand Down
4 changes: 3 additions & 1 deletion tooling/cli/lib/command-modules/update-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ exports.handler = argv => {
};

const updateScriptPath = path.resolve(__dirname, './../update-translations.js');
const updateProcess = exec(`node ${updateScriptPath}`, { env });
const updateProcess = exec(`node -e "require('${updateScriptPath}').updateTranslations()"`, {
env
});

updateProcess.stdout.pipe(process.stdout);
updateProcess.stderr.pipe(process.stderr);
Expand Down
2 changes: 1 addition & 1 deletion tooling/cli/lib/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ async function gatherUsedTranslations() {
const parserScript = path.join(__dirname, 'parse-translations.js');
const exec = childProcess.exec;

const parseProcess = exec(`node ${parserScript}`);
const parseProcess = exec(`node -e "require('${parserScript}').mainFunction()"`);

parseProcess.stdout.pipe(process.stdout);
parseProcess.stderr.pipe(process.stderr);
Expand Down
7 changes: 5 additions & 2 deletions tooling/cli/lib/helpers/filepaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const getFilePaths = async (dir, filePaths = [], skipNodeModules = true) => {
await getFilePaths(filePath, newFilePaths);
}
}
} catch {}
} catch (error) {
console.log(error);
}
return newFilePaths;
};

Expand All @@ -33,7 +35,8 @@ const filePathIsValid = filePath => {
filePath.endsWith('.js') ||
filePath.endsWith('.jsx') ||
filePath.endsWith('.ts') ||
filePath.endsWith('.tsx')
filePath.endsWith('.tsx') ||
filePath.endsWith('.mjs')
);
};

Expand Down
3 changes: 2 additions & 1 deletion tooling/cli/lib/helpers/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ const writeTranslationFile = async (dir, translations, generateBackup = false) =
}

const devFileName = path.join(dirPath, 'translations.json');
return writeFile(devFileName, stringifiedTranslations);

await writeFile(devFileName, stringifiedTranslations);
};

// react-i18next handles pluralizations differently than the
Expand Down
106 changes: 63 additions & 43 deletions tooling/cli/lib/parse-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ const path = require('path');
const { readFile, writeFile } = require('fs/promises');
const Parser = require('i18next-scanner').Parser;
const { getFilePaths, filePathIsValid } = require('./helpers/filepaths');
const fsPromises = require('fs/promises');

const OP_DIR = process.cwd();
const TI_TRANSLATIONS_PATH = path.join(OP_DIR, 'locales/translations.json');
const TI_TRANSLATIONS = require(TI_TRANSLATIONS_PATH);
const FINAL_TRANSLATIONS = {};
const KEYS_WITH_PLURALS = [];

(async function () {
async function processTranslations(TI_TRANSLATIONS, OP_DIR) {
const FINAL_TRANSLATIONS = {};
const KEYS_WITH_PLURALS = [];
const compiledProjectPath = path.join(OP_DIR, 'dist');

const compiledProjectFiles = await getFilePaths(compiledProjectPath);

// i18next-scanner's pluralization uses the `_plural` suffix,
Expand All @@ -22,6 +20,38 @@ const KEYS_WITH_PLURALS = [];
interpolation: { prefix: '%{', suffix: '}' }
});

function addToTranslations(key) {
const translatedLanguages = Object.keys(TI_TRANSLATIONS);
for (const lang of translatedLanguages) {
if (!FINAL_TRANSLATIONS[lang]) {
FINAL_TRANSLATIONS[lang] = { lms: {} };
}

if (translationExists(lang, key)) {
const sourceTranslation = TI_TRANSLATIONS[lang].lms[key];
FINAL_TRANSLATIONS[lang].lms[key] = sourceTranslation;

if (KEYS_WITH_PLURALS.includes(key)) {
const pluralizedKey = `${key}_other`;
if (translationExists(lang, pluralizedKey)) {
FINAL_TRANSLATIONS[lang].lms[pluralizedKey] = TI_TRANSLATIONS[lang].lms[pluralizedKey];
}
}
}
}
}
function gatherPluralizedKeys() {
const pluralizedKeys = Object.keys(TI_TRANSLATIONS.en.lms).filter(key =>
key.includes('_other')
);
for (const pluralKey of pluralizedKeys) {
KEYS_WITH_PLURALS.push(pluralKey.replace('_other', ''));
}
}
function translationExists(lang, key) {
return TI_TRANSLATIONS[lang] && TI_TRANSLATIONS[lang].lms[key];
}

for (const filePath of compiledProjectFiles) {
if (filePathIsValid(filePath)) {
const fileContents = await readFile(filePath, 'utf8');
Expand All @@ -35,8 +65,10 @@ const KEYS_WITH_PLURALS = [];
gatherPluralizedKeys();

const i18nStore = parser.get();

// en is default lang and lms is default namespace, so all keys used should be in that object
const i18nNSObject = i18nStore.en && i18nStore.en.lms ? i18nStore.en.lms : {};

const usedTranslationKeys = Object.keys(i18nNSObject);

for (const key of usedTranslationKeys) {
Expand All @@ -58,49 +90,37 @@ const KEYS_WITH_PLURALS = [];
}
}
}
return FINAL_TRANSLATIONS;
}

async function readTranslations(OP_DIR) {
const TI_TRANSLATIONS_PATH = path.join(OP_DIR, 'locales/translations.json');
const fileContent = await fsPromises.readFile(TI_TRANSLATIONS_PATH, 'utf8');
const TI_TRANSLATIONS = JSON.parse(fileContent);
return TI_TRANSLATIONS;
}

async function writeTranslations(FINAL_TRANSLATIONS, OP_DIR) {
await writeFile(
path.join(OP_DIR, 'locales/translations.json'),
JSON.stringify(FINAL_TRANSLATIONS, null, 2)
);
})()
.then(() => {
console.log('>>> Translations parsed');
process.exit(0);
})
.catch(err => {
console.error('>>> Error parsing translations', err.message);
process.exit(1);
});
}

function addToTranslations(key) {
const translatedLanguages = Object.keys(TI_TRANSLATIONS);
for (const lang of translatedLanguages) {
if (!FINAL_TRANSLATIONS[lang]) {
FINAL_TRANSLATIONS[lang] = { lms: {} };
}

if (translationExists(lang, key)) {
const sourceTranslation = TI_TRANSLATIONS[lang].lms[key];
FINAL_TRANSLATIONS[lang].lms[key] = sourceTranslation;

if (KEYS_WITH_PLURALS.includes(key)) {
const pluralizedKey = `${key}_other`;
if (translationExists(lang, pluralizedKey)) {
FINAL_TRANSLATIONS[lang].lms[pluralizedKey] = TI_TRANSLATIONS[lang].lms[pluralizedKey];
}
}
async function mainFunction() {
try {
const OP_DIR = process.cwd();
const TI_TRANSLATIONS = await readTranslations(OP_DIR);
const translation_to_write = await processTranslations(TI_TRANSLATIONS, OP_DIR);
if (Object.keys(translation_to_write).length !== 0) {
await writeTranslations(translation_to_write, OP_DIR);
console.log('>>> Translations parsed');
process.exit(0);
}
} catch (err) {
console.log('>>> Error parsing translations:', err.message);
process.exit(1);
}
}

function translationExists(lang, key) {
return TI_TRANSLATIONS[lang] && TI_TRANSLATIONS[lang].lms[key];
}

function gatherPluralizedKeys() {
const pluralizedKeys = Object.keys(TI_TRANSLATIONS.en.lms).filter(key => key.includes('_other'));
for (const pluralKey of pluralizedKeys) {
KEYS_WITH_PLURALS.push(pluralKey.replace('_other', ''));
}
}
module.exports = { processTranslations, readTranslations, writeTranslations, mainFunction };
48 changes: 25 additions & 23 deletions tooling/cli/lib/update-translations.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,7 @@
const { fetchTranslations, writeTranslationFile } = require('./helpers/translations');
const path = require('path');

const OP_DIR = process.cwd();
const configPath = path.join(OP_DIR, '/ti-config');
const config = require(configPath);
const INSTANCE_NAME = process.env.INSTANCE_NAME;

(async function () {
const instance = findTIInstance();
const instanceTranslations = await fetchTranslations(instance);

if (instanceTranslations && instanceTranslations.length) {
await writeTranslationFile(OP_DIR, instanceTranslations);
}
})()
.then(() => {
console.log('>>> Translations updated successfully');
process.exit(0);
})
.catch(err => {
console.error('>>> Error updating translations: ', err);
process.exit(1);
});

function findTIInstance() {
function findTIInstance(config, INSTANCE_NAME) {
const { instances = [] } = config;
let instance;

Expand All @@ -40,3 +18,27 @@ function findTIInstance() {

return instance;
}

async function updateTranslations(pathToWrite) {
if (pathToWrite === undefined) {
pathToWrite = process.cwd();
}
const configPath = path.resolve(pathToWrite, 'ti-config.json');
const config = require(configPath);
const INSTANCE_NAME = process.env.INSTANCE_NAME;
try {
const instance = findTIInstance(config, INSTANCE_NAME);
const instanceTranslations = await fetchTranslations(instance);

if (instanceTranslations && instanceTranslations.length) {
await writeTranslationFile(pathToWrite, instanceTranslations);
console.log('>>> Translations updated successfully');
process.exit(0);
}
} catch (err) {
console.error('>>> Error updating translations: ', err);
process.exit(1);
}
}

module.exports = { updateTranslations, findTIInstance };
3 changes: 2 additions & 1 deletion tooling/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "The Helium CLI",
"main": "lib/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"jest": "jest"
},
"bin": {
"helium": "lib/index.js"
Expand Down
Loading
Loading