Skip to content

Commit

Permalink
improved demo.
Browse files Browse the repository at this point in the history
  • Loading branch information
b4rtaz committed May 24, 2024
1 parent 14a92fd commit 28ab411
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 80 deletions.
42 changes: 40 additions & 2 deletions demos/webpack-app/public/assets/i18n.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
html,
body,
#designer {
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
body {
display: flex;
flex-direction: column;
}
body,
input,
h1,
textarea {
font: 14px/1.3em Arial, Verdana, sans-serif;
}
.header {
width: 100%;
display: flex;
align-items: center;
background: #203fd2;
color: #fff;
}
.header h1 {
margin: 0;
padding: 0;
}
.header a {
color: #fff;
}
.header .column {
padding: 10px;
}
.header .column.flex-1 {
flex: 1;
}
.header .text-center {
text-align: center;
}
.header .column.text-end {
text-align: right;
}
@media only screen and (max-width: 700px) {
.header .column.hidden-mobile {
display: none;
}
}
a {
color: #000;
text-decoration: underline;
}
a:hover {
text-decoration: none;
}
#designer {
flex: 1;
}
15 changes: 15 additions & 0 deletions demos/webpack-app/public/i18n.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
<link rel="stylesheet" href="./assets/i18n.css" />
</head>
<body>
<header class="header">
<div class="column flex-1 hidden-mobile">
<h1>🚩 I18n Example</h1>
</div>
<div class="column">
Language:
<select id="lang">
<option value="pl">🇵🇱 Polish</option>
<option value="en">🇬🇧 English</option>
</select>
</div>
<div class="column flex-1 text-end">
<a href="https://github.com/nocode-js/sequential-workflow-editor" target="_blank">GitHub</a>
</div>
</header>
<div id="designer"></div>
</body>
</html>
191 changes: 113 additions & 78 deletions demos/webpack-app/src/i18n/app.ts
Original file line number Diff line number Diff line change
@@ -1,102 +1,136 @@
import { EditorProvider } from 'sequential-workflow-editor';
import { ChownStep, definitionModel } from './definition-model';
import { ChownStep, I18nDefinition, definitionModel } from './definition-model';
import { Designer, Uid } from 'sequential-workflow-designer';
import { defaultI18n } from 'sequential-workflow-editor-model';

import 'sequential-workflow-designer/css/designer.css';
import 'sequential-workflow-designer/css/designer-light.css';
import 'sequential-workflow-editor/css/editor.css';

const designerDict: Record<string, string> = {
'controlBar.resetView': 'Resetuj widok',
'controlBar.zoomIn': 'Przybliż',
'controlBar.zoomOut': 'Oddal',
'controlBar.turnOnOffDragAndDrop': 'Włącz/wyłącz przeciąganie i upuszczanie',
'controlBar.deleteSelectedStep': 'Usuń wybrany krok',
'controlBar.undo': 'Cofnij',
'controlBar.redo': 'Dalej',
'smartEditor.toggle': 'Zwiń/rozwiń',
'toolbox.title': 'Przybornik',
'toolbox.search': 'Szukaj',
'contextMenu.select': 'Zaznacz',
'contextMenu.unselect': 'Odznacz',
'contextMenu.delete': 'Usuń',
'contextMenu.resetView': 'Resetuj widok',
'contextMenu.duplicate': 'Duplikuj',

// steps
'step.chown.name': 'Uprawnienia',
'toolbox.item.chown.label': 'Uprawnienia'
const designerDict: Record<string, Record<string, string>> = {
pl: {
'controlBar.resetView': 'Resetuj widok',
'controlBar.zoomIn': 'Przybliż',
'controlBar.zoomOut': 'Oddal',
'controlBar.turnOnOffDragAndDrop': 'Włącz/wyłącz przeciąganie i upuszczanie',
'controlBar.deleteSelectedStep': 'Usuń wybrany krok',
'controlBar.undo': 'Cofnij',
'controlBar.redo': 'Dalej',
'smartEditor.toggle': 'Zwiń/rozwiń',
'toolbox.title': 'Przybornik',
'toolbox.search': 'Szukaj',
'contextMenu.select': 'Zaznacz',
'contextMenu.unselect': 'Odznacz',
'contextMenu.delete': 'Usuń',
'contextMenu.resetView': 'Resetuj widok',
'contextMenu.duplicate': 'Duplikuj',

// steps
'toolbox.item.chown.label': 'Uprawnienia'
}
};

const editorDict: Record<string, string> = {
'toolbox.defaultGroupName': 'Inne',
'stringDictionary.noItems': 'Brak elementów',
'stringDictionary.addItem': 'Dodaj element',
'stringDictionary.key': 'Klucz',
'stringDictionary.value': 'Wartość',
'stringDictionary.delete': 'Usuń',
'stringDictionary.valueTooShort': 'Wartość musi mieć conajmniej :min znaków',
'stringDictionary.duplicatedKey': 'Klucz jest zduplikowany',
'stringDictionary.keyIsRequired': 'Klucz jest wymagany',

'number.valueMustBeNumber': 'Wartość musi być liczbą',
'number.valueTooLow': 'Wartość musi być minimum :min.',
'number.valueTooHigh': 'Wartość musi być maximum :max.',

'boolean.false': 'Fałsz',
'boolean.true': 'Prawda',

'string.valueTooShort': 'Wartość musi mieć minimum :min znaków.',
'string.valueDoesNotMatchPattern': 'Wartość nie pasuje do oczekiwanego wzorca.',

'dynamic.string.label': 'Tekst',
'dynamic.number.label': 'Liczba',

// root
'root.property:properties/timeout': 'Przekroczenie czasu',
'root.property:properties/debug': 'Tryb debug',

// steps
'step.chown.name': 'Uprawnienia',
'step.chown.property:name': 'Nazwa',
'step.chown.property:properties/stringOrNumber': 'Tekst lub liczba',
'step.chown.property:properties/users': 'Użytkownik'
const editorDict: Record<string, Record<string, string>> = {
pl: {
'toolbox.defaultGroupName': 'Inne',
'stringDictionary.noItems': 'Brak elementów',
'stringDictionary.addItem': 'Dodaj element',
'stringDictionary.key': 'Klucz',
'stringDictionary.value': 'Wartość',
'stringDictionary.delete': 'Usuń',
'stringDictionary.valueTooShort': 'Wartość musi mieć conajmniej :min znaków',
'stringDictionary.duplicatedKey': 'Klucz jest zduplikowany',
'stringDictionary.keyIsRequired': 'Klucz jest wymagany',

'number.valueMustBeNumber': 'Wartość musi być liczbą',
'number.valueTooLow': 'Wartość musi być minimum :min.',
'number.valueTooHigh': 'Wartość musi być maximum :max.',

'boolean.false': 'Fałsz',
'boolean.true': 'Prawda',

'string.valueTooShort': 'Wartość musi mieć minimum :min znaków.',
'string.valueDoesNotMatchPattern': 'Wartość nie pasuje do oczekiwanego wzorca.',

'dynamic.string.label': 'Tekst',
'dynamic.number.label': 'Liczba',

// root
'root.property:properties/timeout': 'Przekroczenie czasu',
'root.property:properties/debug': 'Tryb debug',

// steps
'step.chown.name': 'Uprawnienia',
'step.chown.property:name': 'Nazwa',
'step.chown.property:properties/stringOrNumber': 'Tekst lub liczba',
'step.chown.property:properties/users': 'Użytkownik'
}
};

function designerI18n(key: string, defaultValue: string) {
const translation = designerDict[key];
if (translation) {
return translation;
export class App {
public static create() {
const placeholder = document.getElementById('designer') as HTMLElement;
const langInput = document.getElementById('lang') as HTMLInputElement;
const app = new App(placeholder, langInput.value);
app.reload();
langInput.addEventListener('change', () => {
app.setLang(langInput.value);
app.reload();
});
return app;
}
console.log(`<designer>`, key, defaultValue);
return defaultValue;
}

function editorI18n(key: string, defaultValue: string, replacements?: { [key: string]: string }) {
const translation = editorDict[key];
if (translation) {
defaultValue = translation;
} else {
console.log(`<editor>`, key, defaultValue);
private designer: Designer<I18nDefinition> | null = null;
private definition: I18nDefinition | null = null;

public constructor(private readonly placeholder: HTMLElement, private lang: string) {}

private readonly designerI18n = (key: string, defaultValue: string) => {
const dict = designerDict[this.lang];
if (dict) {
const translation = dict[key];
if (translation) {
return translation;
}
}
console.log(`<designer>`, key, defaultValue);
return defaultValue;
};

private readonly editorI18n = (key: string, defaultValue: string, replacements?: { [key: string]: string }) => {
const dict = editorDict[this.lang];
if (dict) {
const translation = dict[key];
if (translation) {
defaultValue = translation;
} else {
console.log(`<editor>`, key, defaultValue);
}
}
return defaultI18n(key, defaultValue, replacements);
};

public setLang(lang: string) {
this.lang = lang;
}
return defaultI18n(key, defaultValue, replacements);
}

export class App {
public static create() {
const placeholder = document.getElementById('designer') as HTMLElement;
public reload() {
if (this.designer) {
this.designer.destroy();
}

const editorProvider = EditorProvider.create(definitionModel, {
uidGenerator: Uid.next,
i18n: editorI18n
i18n: this.editorI18n
});

const definition = editorProvider.activateDefinition();
const step = editorProvider.activateStep('chown') as ChownStep;
definition.sequence.push(step);
if (!this.definition) {
this.definition = editorProvider.activateDefinition();
const step = editorProvider.activateStep('chown') as ChownStep;
this.definition.sequence.push(step);
}

Designer.create(placeholder, definition, {
this.designer = Designer.create(this.placeholder, this.definition, {
controlBar: true,
editors: {
rootEditorProvider: editorProvider.createRootEditorProvider(),
Expand All @@ -113,8 +147,9 @@ export class App {
groups: editorProvider.getToolboxGroups(),
labelProvider: editorProvider.createStepLabelProvider()
},
i18n: designerI18n
i18n: this.designerI18n
});
this.designer.onDefinitionChanged.subscribe(d => (this.definition = d));
}
}

Expand Down
18 changes: 18 additions & 0 deletions model/src/i18n.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defaultI18n } from './i18n';

describe('defaultI18n', () => {
it('returns expected value', () => {
expect(defaultI18n('key', 'test')).toBe('test');
expect(
defaultI18n('key', 'We need :min users', {
min: '10'
})
).toBe('We need 10 users');
expect(
defaultI18n('key', 'Your name :name should have :n characters', {
name: 'Alice',
n: '4'
})
).toBe('Your name Alice should have 4 characters');
});
});

0 comments on commit 28ab411

Please sign in to comment.