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

0.12.0. #33

Merged
merged 5 commits into from
May 24, 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.12.0

This version introduces the localization feature. Now you can localize the editor to any language you want.

## 0.11.3

This version improves the behavior of the `Dynamic` value editor, when the sub editor contains a control visible in the property header.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Powerful workflow editor builder for sequential workflows. Written in TypeScript
* [🛠 Playground](https://nocode-js.github.io/sequential-workflow-editor/webpack-app/public/playground.html)
* [📖 Editors](https://nocode-js.github.io/sequential-workflow-editor/webpack-app/public/editors.html)
* [🎯 Placement Restrictions](https://nocode-js.github.io/sequential-workflow-editor/webpack-app/public/placement-restrictions.html)
* [🚩 Internationalization](https://nocode-js.github.io/sequential-workflow-editor/webpack-app/public/i18n.html)
* [🚢 Vanilla JS](https://nocode-js.github.io/sequential-workflow-editor/vanilla-js-app/vanilla-js.html)

Pro:
Expand Down
6 changes: 3 additions & 3 deletions demos/vanilla-js-app/vanilla-js.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
}
</style>

<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.19.1/css/designer.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.19.1/css/designer-light.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.19.1/dist/index.umd.js"></script>
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.1/css/designer.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.1/css/designer-light.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.1/dist/index.umd.js"></script>

<script src="./assets/lib.js"></script>
<script src="./assets/vanilla-js.js"></script>
Expand Down
6 changes: 3 additions & 3 deletions demos/webpack-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"dependencies": {
"xstate": "^4.38.2",
"sequential-workflow-model": "^0.2.0",
"sequential-workflow-designer": "^0.17.0",
"sequential-workflow-designer": "^0.21.1",
"sequential-workflow-machine": "^0.4.0",
"sequential-workflow-editor-model": "^0.11.3",
"sequential-workflow-editor": "^0.11.3"
"sequential-workflow-editor-model": "^0.12.0",
"sequential-workflow-editor": "^0.12.0"
},
"devDependencies": {
"ts-loader": "^9.4.2",
Expand Down
59 changes: 59 additions & 0 deletions demos/webpack-app/public/assets/i18n.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
html,
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;
}
29 changes: 29 additions & 0 deletions demos/webpack-app/public/i18n.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>🚩 I18n Example - Sequential Workflow Editor</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="icon" href="./assets/favicon.ico" />
<script src="./builds/i18n.js" defer></script>
<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>
156 changes: 156 additions & 0 deletions demos/webpack-app/src/i18n/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { EditorProvider } from 'sequential-workflow-editor';
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, 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, 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'
}
};

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;
}

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;
}

public reload() {
if (this.designer) {
this.designer.destroy();
}

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

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

this.designer = Designer.create(this.placeholder, this.definition, {
controlBar: true,
editors: {
rootEditorProvider: editorProvider.createRootEditorProvider(),
stepEditorProvider: editorProvider.createStepEditorProvider()
},
validator: {
step: editorProvider.createStepValidator(),
root: editorProvider.createRootValidator()
},
steps: {
iconUrlProvider: () => './assets/icon-task.svg'
},
toolbox: {
groups: editorProvider.getToolboxGroups(),
labelProvider: editorProvider.createStepLabelProvider()
},
i18n: this.designerI18n
});
this.designer.onDefinitionChanged.subscribe(d => (this.definition = d));
}
}

document.addEventListener('DOMContentLoaded', App.create, false);
69 changes: 69 additions & 0 deletions demos/webpack-app/src/i18n/definition-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
Dynamic,
StringDictionary,
createBooleanValueModel,
createDefinitionModel,
createDynamicValueModel,
createNumberValueModel,
createStepModel,
createStringDictionaryValueModel,
createStringValueModel
} from 'sequential-workflow-editor-model';
import { Definition, Step } from 'sequential-workflow-model';

export interface I18nDefinition extends Definition {
properties: {
timeout: number;
debug: boolean;
};
}

export interface ChownStep extends Step {
type: 'chown';
componentType: 'task';
properties: {
stringOrNumber: Dynamic<string | number>;
users: StringDictionary;
};
}

export const definitionModel = createDefinitionModel<I18nDefinition>(model => {
model.root(root => {
root.property('timeout').value(
createNumberValueModel({
min: 100,
max: 200,
defaultValue: 150
})
);
root.property('debug').value(
createBooleanValueModel({
defaultValue: false
})
);
});
model.steps([
createStepModel<ChownStep>('chown', 'task', step => {
step.property('stringOrNumber').value(
createDynamicValueModel({
models: [
createStringValueModel({
pattern: /^[a-zA-Z0-9]+$/
}),
createNumberValueModel({
min: 1,
max: 100,
defaultValue: 50
})
]
})
);
step.property('users').value(
createStringDictionaryValueModel({
valueMinLength: 1,
uniqueKeys: true
})
);
})
]);
});
5 changes: 3 additions & 2 deletions demos/webpack-app/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ function bundle(name) {
}

module.exports = [
bundle('playground'),
bundle('editors'),
bundle('placement-restrictions')
bundle('i18n'),
bundle('placement-restrictions'),
bundle('playground'),
];
Loading
Loading