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

Issue 29 multi yaml add type part1 #125

Merged
merged 6 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 7 additions & 2 deletions webapp/src/RepoGit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { SimpleGitWrapper } from '@/utils/git/SimpleGitWrapper';
import { unflattenObject } from '@/utils/unflattenObject';
import { debug, info, warn } from '@/utils/log';
import { WriteLanguageFileError, WriteLanguageFileErrors } from '@/errors';
import { type TranslationMap } from '@/utils/adapters';
import { getTranslationsIdText } from '@/utils/translationObjectUtil';

export class RepoGit {
private static repositories: {
Expand Down Expand Up @@ -143,7 +145,7 @@ export class RepoGit {
}

private async writeLangFiles(
languages: Record<string, Record<string, string>>,
languages: TranslationMap,
translationsPath: string,
): Promise<string[]> {
const paths: string[] = [];
Expand All @@ -154,7 +156,10 @@ export class RepoGit {
// TODO: what if language file were yaml not yml?
`${lang}.yml`,
);
const yamlOutput = stringify(unflattenObject(languages[lang]), {
// Temp: keep same behaviour just dehydrate object MassageMap
// TODO: save each in different files according to sourceFile
const translationsIdText = getTranslationsIdText(languages[lang]);
const yamlOutput = stringify(unflattenObject(translationsIdText), {
doubleQuotedAsJSON: true,
singleQuote: true,
});
Expand Down
8 changes: 5 additions & 3 deletions webapp/src/app/projects/[projectName]/[languageName]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import MessageList from '@/components/MessageList';
import PullRequestButton from '@/components/PullRequestButton';
import TitleBar from '@/components/TitleBar';
import SidebarContextProvider from '@/components/SidebarContext';
import { getTranslationsIdText } from '@/utils/translationObjectUtil';

const MessagesPage: NextPage<{
params: { languageName: string; messageId?: string; projectName: string };
Expand All @@ -36,6 +37,7 @@ const MessagesPage: NextPage<{
const msgAdapter = MessageAdapterFactory.createAdapter(projectConfig);
const messages = await msgAdapter.getMessages();
const translations = await Cache.getLanguage(projectName, languageName);
const translationsIdText = getTranslationsIdText(translations);

const prefix = messageId ? messageId : '';
const filteredMessages = messages.filter((message) =>
Expand All @@ -47,8 +49,8 @@ const MessagesPage: NextPage<{
}

filteredMessages.sort((m0, m1) => {
const trans0 = translations[m0.id]?.trim() ?? '';
const trans1 = translations[m1.id]?.trim() ?? '';
const trans0 = translations[m0.id]?.text.trim() ?? '';
const trans1 = translations[m1.id]?.text.trim() ?? '';

if (!trans0) {
return -1;
Expand Down Expand Up @@ -83,7 +85,7 @@ const MessagesPage: NextPage<{
languageName={languageName}
messages={filteredMessages}
projectName={projectName}
translations={translations}
translations={translationsIdText}
/>
</Main>
</Box>
Expand Down
28 changes: 21 additions & 7 deletions webapp/src/store/ProjectStore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('ProjectStore', () => {

const actual = await projectStore.getTranslations('de');
expect(actual).toEqual({
'greeting.headline': 'Hallo',
'greeting.headline': { sourceFile: '', text: 'Hallo' },
});
});

Expand Down Expand Up @@ -66,11 +66,16 @@ describe('ProjectStore', () => {
const after = await projectStore.getTranslations('de');

expect(before).toEqual({
'greeting.headline': 'Hallo',
'greeting.headline': {
sourceFile: '',
text: 'Hallo',
},
});

expect(after).toEqual({
'greeting.headline': 'Hallo!',
'greeting.headline': {
sourceFile: '',
text: 'Hallo!',
},
});
});

Expand All @@ -90,7 +95,10 @@ describe('ProjectStore', () => {
const actual = await projectStore.getTranslations('de');

expect(actual).toEqual({
'greeting.headline': 'Hallo!',
'greeting.headline': {
sourceFile: '',
text: 'Hallo!',
},
});
});

Expand Down Expand Up @@ -147,10 +155,16 @@ describe('ProjectStore', () => {
const languages = await projectStore.getLanguageData();
expect(languages).toEqual({
de: {
'greeting.headline': 'Hallo',
'greeting.headline': {
sourceFile: '',
text: 'Hallo',
},
},
sv: {
'greeting.headline': 'Hej',
'greeting.headline': {
sourceFile: '',
text: 'Hej',
},
},
});
});
Expand Down
18 changes: 11 additions & 7 deletions webapp/src/store/ProjectStore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ITranslationAdapter, TranslationMap } from '@/utils/adapters';
import {
ITranslationAdapter,
MessageMap,
TranslationMap,
} from '@/utils/adapters';
import { LanguageNotFound, MessageNotFound } from '@/errors';

type StoreData = {
Expand All @@ -17,28 +21,28 @@ export class ProjectStore {
this.translationAdapter = translationAdapter;
}

async getLanguageData(): Promise<Record<string, Record<string, string>>> {
async getLanguageData(): Promise<TranslationMap> {
await this.initIfNecessary();

const output: Record<string, Record<string, string>> = {};
const output: TranslationMap = {};
for await (const lang of Object.keys(this.data.languages)) {
output[lang] = await this.getTranslations(lang);
}

return output;
}

async getTranslations(lang: string): Promise<Record<string, string>> {
async getTranslations(lang: string): Promise<MessageMap> {
await this.initIfNecessary();

const language = this.data.languages[lang];
if (!language) {
throw new LanguageNotFound(lang);
}

const output: Record<string, string> = {};
Object.entries(language).forEach(([key, value]) => {
output[key] = value.text;
const output: MessageMap = {};
Object.entries(language).forEach(([key, messageTranslation]) => {
output[key] = { ...messageTranslation };
});

return output;
Expand Down
20 changes: 12 additions & 8 deletions webapp/src/utils/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ export type MessageData = {
}[];
};

export type MessageTranslation = {
sourceFile: string;
text: string;
};

export type MessageMap = Record<
string, // msg id
MessageTranslation
>;

export type TranslationMap = Record<
string,
Record<
string,
{
sourceFile: string;
text: string;
}
>
string, // lang code, ex: 'en', 'de'
MessageMap
>;

export interface IMessageAdapter {
Expand Down
35 changes: 35 additions & 0 deletions webapp/src/utils/translationObjectUtil.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, expect, it } from '@jest/globals';

import { getTranslationsIdText } from './translationObjectUtil';

describe('translationObjectUtil', () => {
describe('getTranslationsIdText()', () => {
it('returns empty object for empty obj', () => {
const actual = getTranslationsIdText({});
expect(actual).toEqual({});
});
it('dehydrate obj one property', () => {
const actual = getTranslationsIdText({
a: { sourceFile: '', text: 'A' },
});
expect(actual).toEqual({ a: 'A' });
});
it('unflat simple obj one object property', () => {
const actual = getTranslationsIdText({
'a.b.c': { sourceFile: '', text: 'ABC' },
});
expect(actual).toEqual({ 'a.b.c': 'ABC' });
});
it('unflat two properties obj', () => {
const actual = getTranslationsIdText({
'a.b.c': { sourceFile: '', text: 'ABC' },
'a.b.e': { sourceFile: '', text: 'ABE' },
});
const expected = {
'a.b.c': 'ABC',
'a.b.e': 'ABE',
};
expect(actual).toEqual(expected);
});
});
});
15 changes: 15 additions & 0 deletions webapp/src/utils/translationObjectUtil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MessageMap } from '@/utils/adapters';

/**
* get basic object of message id and text from MessageMap, by remove sourceFile and keep text
* ex: { 'a.b.c': {sourceFile, text} } => { 'a.b.c': 'text' } } }
*/
export function getTranslationsIdText(
messageMap: MessageMap,
): Record<string, string> {
const result: Record<string, string> = {};
Object.entries(messageMap).forEach(([id, mt]) => {
result[id] = mt.text;
});
return result;
}
1 change: 0 additions & 1 deletion webapp/src/utils/types.ts

This file was deleted.

4 changes: 4 additions & 0 deletions webapp/src/utils/unflattenObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ export interface UnflattenObject {
[key: string]: string | UnflattenObject;
}

/**
* Unflatten a flat object with string values.
* ex: { 'a.b.c': 'value' } => { a: { b: { c: 'value' } } }
*/
export function unflattenObject(obj: Record<string, string>): UnflattenObject {
const result: UnflattenObject = {};
for (const key in obj) {
Expand Down