Skip to content

Commit

Permalink
0.12.0. (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
b4rtaz authored May 24, 2024
1 parent 833d439 commit 44dc0f9
Show file tree
Hide file tree
Showing 54 changed files with 677 additions and 116 deletions.
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

0 comments on commit 44dc0f9

Please sign in to comment.