Skip to content

0.3.2. #8

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

Merged
merged 1 commit into from
Jun 14, 2023
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.2

* The `StepModel` interface has two new properties: `category` and `description`. The category is used to group steps in the toolbox. The description is used to display an additional information about a step in the editor.
* The `PropertyModel` interface has one new property: `hint`. The hint is used to display an additional information about a property in the editor.

## 0.3.1

Added new value model: boolean (`booleanValueModel({ ... })`).
Expand Down
4 changes: 2 additions & 2 deletions demos/webpack-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"sequential-workflow-model": "^0.1.3",
"sequential-workflow-designer": "^0.13.2",
"sequential-workflow-machine": "^0.2.0",
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-editor": "^0.3.1"
"sequential-workflow-editor-model": "^0.3.2",
"sequential-workflow-editor": "^0.3.2"
},
"devDependencies": {
"ts-loader": "^9.4.2",
Expand Down
9 changes: 2 additions & 7 deletions demos/webpack-app/src/playground/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { editorProvider } from './editor-provider';
import { AppState, AppStorage } from './storage';
import { Playground } from './playground';
import { executeMachine } from './machine/machine-executor';
import { MyDefinition, definitionModel } from './model/definition-model';
import { MyDefinition } from './model/definition-model';
import { defaultAppState } from './default-state';

import 'sequential-workflow-designer/css/designer.css';
Expand Down Expand Up @@ -33,12 +33,7 @@ export class App {
}
},
toolbox: {
groups: [
{
name: 'Steps',
steps: Object.keys(definitionModel.steps).map(stepType => editorProvider.activateStep(stepType))
}
]
groups: editorProvider.getToolboxGroups()
},
undoStackSize: 10,
definitionWalker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export interface CalculateStep extends Step {
}

export const calculateStepModel = createStepModel<CalculateStep>('calculate', 'task', step => {
step.category('Values');
step.description('Calculate value from two numbers. Result is stored in variable.');

const val = dynamicValueModel({
models: [
numberValueModel({}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export interface ConvertValueStep extends Step {
}

export const convertValueStepModel = createStepModel<ConvertValueStep>('convertValue', 'task', step => {
step.category('Values');
step.description('Convert value from one variable to another.');

step.property('source')
.value(
nullableAnyVariableValueModel({
Expand Down
10 changes: 7 additions & 3 deletions demos/webpack-app/src/playground/model/if-step-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export interface IfStep extends BranchedStep {
}

export const ifStepModel = createBranchedStepModel<IfStep>('if', 'switch', step => {
step.category('Logic');
step.description('Check condition and execute different branches.');

const ab = dynamicValueModel({
models: [
numberValueModel({}),
Expand All @@ -34,17 +37,18 @@ export const ifStepModel = createBranchedStepModel<IfStep>('if', 'switch', step
]
});

step.property('a').value(ab).label('A');
step.property('a').value(ab).label('A').hint('Left side of comparison.');

step.property('operator')
.label('Operator')
.value(
choiceValueModel({
choices: ['==', '===', '!=', '!==', '>', '>=', '<', '<=']
})
);
)
.hint('Comparison operator.\nStep supports strict and non-strict operators.');

step.property('b').value(ab).label('B');
step.property('b').value(ab).label('B').hint('Right side of comparison.');

step.branches().value(
branchesValueModel({
Expand Down
3 changes: 3 additions & 0 deletions demos/webpack-app/src/playground/model/loop-step-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export interface LoopStep extends SequentialStep {
}

export const loopStepModel = createSequentialStepModel('loop', 'container', step => {
step.category('Logic');
step.description('Loop over a range of numbers.');

step.property('from')
.label('From')
.value(
Expand Down
5 changes: 4 additions & 1 deletion demos/webpack-app/src/playground/model/root-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MyDefinition } from './definition-model';

export const rootModel = createRootModel<MyDefinition>(root => {
root.property('inputs')
.hint('Variables passed to the workflow from the outside.')
.value(variableDefinitionsValueModel({}))
.dependentProperty('outputs')
.customValidator({
Expand All @@ -11,7 +12,9 @@ export const rootModel = createRootModel<MyDefinition>(root => {
return inputs.variables.length > 0 ? null : 'At least one input is required';
}
});
root.property('outputs').value(variableDefinitionsValueModel({})).label('Outputs');

root.property('outputs').hint('Variables returned from the workflow.').value(variableDefinitionsValueModel({})).label('Outputs');

root.sequence().value(
sequenceValueModel({
sequence: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface SetStringValueStep extends Step {
}

export const setStringValueStepModel = createStepModel<SetStringValueStep>('setStringValue', 'task', step => {
step.category('Values');

step.property('variable')
.value(
nullableVariableValueModel({
Expand Down
50 changes: 48 additions & 2 deletions editor/css/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,23 @@
.swe-editor {
margin: 10px 0 0;
font-size: 13px;
line-height: 1.3em;
line-height: 1.3rem;
}
.swe-editor-header {
padding: 0 10px 5px;
}
.swe-editor-header-title {
margin: 0;
padding: 5px 0 10px;
font-size: 1.4rem;
line-height: 1.3rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.swe-editor-header-description {
margin: 0 0 10px;
color: #666;
}

/* properties */
Expand All @@ -24,14 +40,44 @@
}
.swe-property-header-label {
display: block;
flex: 1;
padding: 0;
margin: 0;
font-size: 1.05rem;
line-height: 1.3rem;
}
.swe-property-header-hint-toggle {
display: block;
width: 18px;
height: 18px;
margin: 0 8px;
background: #ddd;
border-radius: 50% 50%;
text-align: center;
font-size: 11px;
cursor: pointer;
}
.swe-property-header-hint-toggle:hover {
background: #eee;
}
.swe-property-header-hint-toggle-icon {
width: 70%;
height: 70%;
margin: 15%;
}
.swe-property-header-hint-toggle-icon path {
fill: #777;
}
.swe-property-header-control {
flex: 1;
text-align: right;
}
.swe-property-hint-text {
margin: 0 0 10px;
padding: 6px 10px;
border-radius: 5px;
background: #eee;
border: 1px solid #ddd;
}
.swe-validation-error-text {
margin: 0 0 10px;
padding: 6px 10px;
Expand Down
6 changes: 3 additions & 3 deletions editor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sequential-workflow-editor",
"version": "0.3.1",
"version": "0.3.2",
"type": "module",
"main": "./lib/esm/index.js",
"types": "./lib/index.d.ts",
Expand Down Expand Up @@ -46,11 +46,11 @@
"prettier:fix": "prettier --write ./src ./css"
},
"dependencies": {
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-editor-model": "^0.3.2",
"sequential-workflow-model": "^0.1.3"
},
"peerDependencies": {
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-editor-model": "^0.3.2",
"sequential-workflow-model": "^0.1.3"
},
"devDependencies": {
Expand Down
28 changes: 28 additions & 0 deletions editor/src/components/input-component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { inputComponent } from './input-component';

describe('InputComponent', () => {
it('triggers onChanged event when new character is added to field', () => {
let count = 0;

const input = inputComponent('Foo');
input.onChanged.subscribe(value => {
expect(value).toBe('FooB');
count++;
});

(input.view as HTMLInputElement).value = 'FooB';
input.view.dispatchEvent(new Event('input'));

expect(count).toBe(1);
});

it('renders input[type=text] by default', () => {
const input = inputComponent('x');
expect(input.view.getAttribute('type')).toBe('text');
});

it('renders input[type=number] when configuration is set', () => {
const input = inputComponent('x', { type: 'number' });
expect(input.view.getAttribute('type')).toBe('number');
});
});
33 changes: 33 additions & 0 deletions editor/src/components/input-component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { SimpleEvent } from 'sequential-workflow-editor-model';
import { Component } from './component';
import { Html } from '../core';

export interface InputComponent extends Component {
onChanged: SimpleEvent<string>;
}

export interface InputConfiguration {
type?: 'text' | 'number';
placeholder?: string;
}

export function inputComponent(value: string, configuration?: InputConfiguration): InputComponent {
const onChanged = new SimpleEvent<string>();

const view = Html.element('input', {
class: 'swe-input swe-stretched',
type: configuration?.type ?? 'text'
});
if (configuration?.placeholder) {
view.setAttribute('placeholder', configuration.placeholder);
}
view.value = value;
view.addEventListener('input', () => {
onChanged.forward(view.value);
});

return {
view,
onChanged
};
}
21 changes: 21 additions & 0 deletions editor/src/core/append-multiline-text.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { appendMultilineText } from './append-multiline-text';

describe('appendMultilineText()', () => {
let parent: HTMLElement;

beforeEach(() => {
parent = document.createElement('div');
});

it('appends correctly if passed text with \\n', () => {
appendMultilineText(parent, 'Hello\nWorld\nNow');

expect(parent.innerHTML).toBe('Hello<br>World<br>Now');
});

it('appends correctly if passed text with \\r\\n', () => {
appendMultilineText(parent, 'Hello\r\nWorld\r\nToday');

expect(parent.innerHTML).toBe('Hello<br>World<br>Today');
});
});
10 changes: 10 additions & 0 deletions editor/src/core/append-multiline-text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function appendMultilineText(target: HTMLElement, text: string) {
const lines = text.split(/\r?\n/g);
for (let i = 0; i < lines.length; i++) {
if (i > 0) {
target.appendChild(document.createElement('br'));
}
const line = document.createTextNode(lines[i]);
target.appendChild(line);
}
}
16 changes: 16 additions & 0 deletions editor/src/core/icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const ns = 'http://www.w3.org/2000/svg';

export class Icons {
public static help =
'M431-330q1-72 16.5-105t58.5-72q42-38 64.5-70.5T593-647q0-45-30-75t-84-30q-52 0-80 29.5T358-661l-84-37q22-59 74.5-100.5T479-840q100 0 154 55.5T687-651q0 48-20.5 87T601-482q-49 47-59 72t-11 80H431Zm48 250q-29 0-49.5-20.5T409-150q0-29 20.5-49.5T479-220q29 0 49.5 20.5T549-150q0 29-20.5 49.5T479-80Z';

public static createSvg(icon: string, cls: string): SVGElement {
const svg = document.createElementNS(ns, 'svg');
svg.setAttribute('viewBox', '0 -960 960 960');
svg.classList.add(cls);
const path = document.createElementNS(ns, 'path');
path.setAttribute('d', icon);
svg.appendChild(path);
return svg;
}
}
27 changes: 27 additions & 0 deletions editor/src/editor-header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Component } from './components/component';
import { Html } from './core';
import { appendMultilineText } from './core/append-multiline-text';

export interface EditorHeaderData {
title: string;
description?: string;
}

export class EditorHeader implements Component {
public static create(data: EditorHeaderData): EditorHeader {
const view = Html.element('div', { class: 'swe-editor-header' });

const title = Html.element('h3', { class: 'swe-editor-header-title' });
title.textContent = data.title;
view.appendChild(title);

if (data.description) {
const description = Html.element('p', { class: 'swe-editor-header-description' });
appendMultilineText(description, data.description);
view.appendChild(description);
}
return new EditorHeader(view);
}

private constructor(public readonly view: HTMLElement) {}
}
1 change: 1 addition & 0 deletions editor/src/editor-provider-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import { DefinitionWalker } from 'sequential-workflow-model';
export interface EditorProviderConfiguration {
uidGenerator: UidGenerator;
definitionWalker?: DefinitionWalker;
isHeaderHidden?: boolean;
}
Loading