Skip to content

0.3.1. #7

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 12, 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.3.1

Added new value model: boolean (`booleanValueModel({ ... })`).

## 0.3.0

* Added new value model: nullable any variable (`nullableAnyVariableValueModel({ ... })`). This value model allows you to select any variable. Additionally, you can specify a variable type that can be selected by a user.
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 @@ -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.0",
"sequential-workflow-editor": "^0.3.0"
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-editor": "^0.3.1"
},
"devDependencies": {
"ts-loader": "^9.4.2",
Expand All @@ -33,4 +33,4 @@
"@typescript-eslint/parser": "^5.47.0",
"eslint": "^8.30.0"
}
}
}
4 changes: 2 additions & 2 deletions demos/webpack-app/src/playground/default-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ const definition: MyDefinition = {
type: 'if',
componentType: 'switch',
properties: {
a: { modelId: 'nullableVariable', value: { name: 'remainder' } },
operator: '=',
a: { modelId: 'nullableAnyVariable', value: { name: 'remainder', type: 'number' } },
operator: '==',
b: { modelId: 'number', value: 0 }
},
branches: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { branchName, createForkActivity } from 'sequential-workflow-machine';
import { IfStep } from '../../model/if-step-model';
import { GlobalState } from '../global-state';
Expand All @@ -6,19 +7,23 @@ export const ifActivity = createForkActivity<IfStep, GlobalState>({
stepType: 'if',
init: () => ({}),
handler: async (step: IfStep, { $dynamics }: GlobalState) => {
const a = $dynamics.readNumber(step.properties.a);
const b = $dynamics.readNumber(step.properties.b);
const a = $dynamics.readAny<any>(step.properties.a);
const b = $dynamics.readAny<any>(step.properties.b);

const result = compare(a, b, step.properties.operator);
return branchName(result ? 'true' : 'false');
}
});

function compare(a: number, b: number, operator: string): boolean {
function compare(a: any, b: any, operator: string): boolean {
switch (operator) {
case '=':
case '==':
return a == b;
case '===':
return a === b;
case '!=':
return a != b;
case '!==':
return a !== b;
case '>':
return a > b;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const logActivity = createAtomActivity<LogStep, GlobalState>({
init: () => ({}),
stepType: 'log',
handler: async (step: LogStep, { $variables, $dynamics, $logger }: GlobalState) => {
let message = $dynamics.readAny(step.properties.message);
let message = $dynamics.readString(step.properties.message);

for (const variable of step.properties.variables.variables) {
const value = $variables.isSet(variable.name) ? $variables.read(variable.name) || '<empty>' : '<not set>';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {
Dynamic,
NullableAnyVariable,
NullableVariable,
booleanValueModelId,
nullableAnyVariableValueModelId,
nullableVariableValueModelId,
numberValueModelId,
stringValueModelId
Expand All @@ -10,20 +13,22 @@ import { VariablesService } from './variables-service';
export class DynamicsService {
public constructor(private readonly $variables: VariablesService) {}

public readAny<TValue>(dynamic: Dynamic<TValue | NullableVariable>): TValue {
public readAny<TValue>(dynamic: Dynamic<unknown>): TValue {
switch (dynamic.modelId) {
case stringValueModelId:
case numberValueModelId:
case booleanValueModelId:
return dynamic.value as TValue;
case nullableVariableValueModelId: {
const variable = dynamic.value as NullableVariable;
case nullableVariableValueModelId:
case nullableAnyVariableValueModelId: {
const variable = dynamic.value as NullableVariable | NullableAnyVariable;
if (!variable || !variable.name) {
throw new Error('Variable is not set');
}
return this.$variables.read<TValue>(variable.name);
}
}
throw new Error(`Model is not supported: ${dynamic.modelId}`);
throw new Error(`Dynamic model is not supported: ${dynamic.modelId}`);
}

public readString(dynamic: Dynamic<string | NullableVariable>): string {
Expand Down
26 changes: 14 additions & 12 deletions demos/webpack-app/src/playground/model/if-step-model.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
import {
Dynamic,
NullableVariable,
ValueKnownType,
booleanValueModel,
branchesValueModel,
choiceValueModel,
createBranchedStepModel,
dynamicValueModel,
nullableVariableValueModel,
numberValueModel
nullableAnyVariableValueModel,
numberValueModel,
stringValueModel
} from 'sequential-workflow-editor-model';
import { BranchedStep } from 'sequential-workflow-model';

export interface IfStep extends BranchedStep {
type: 'if';
componentType: 'switch';
properties: {
a: Dynamic<number | NullableVariable>;
a: Dynamic<number | string | boolean | NullableVariable>;
operator: string;
b: Dynamic<number | NullableVariable>;
b: Dynamic<number | string | boolean | NullableVariable>;
};
}

export const ifStepModel = createBranchedStepModel<IfStep>('if', 'switch', step => {
const val = dynamicValueModel({
const ab = dynamicValueModel({
models: [
numberValueModel({}),
nullableVariableValueModel({
isRequired: true,
valueType: ValueKnownType.number
stringValueModel({}),
booleanValueModel({}),
nullableAnyVariableValueModel({
isRequired: true
})
]
});

step.property('a').value(val).label('A');
step.property('a').value(ab).label('A');

step.property('operator')
.label('Operator')
.value(
choiceValueModel({
choices: ['=', '!=', '>', '>=', '<', '<=']
choices: ['==', '===', '!=', '!==', '>', '>=', '<', '<=']
})
);

step.property('b').value(val).label('B');
step.property('b').value(ab).label('B');

step.branches().value(
branchesValueModel({
Expand Down
2 changes: 1 addition & 1 deletion demos/webpack-app/src/playground/storage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MyDefinition } from './model/definition-model';
import { RawInputData } from './playground';

const version = 1;
const version = 2;
const definitionKey = `definition_${version}`;
const inputDataKey = `inputData_${version}`;

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.0",
"version": "0.3.1",
"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.0",
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-model": "^0.1.3"
},
"peerDependencies": {
"sequential-workflow-editor-model": "^0.3.0",
"sequential-workflow-editor-model": "^0.3.1",
"sequential-workflow-model": "^0.1.3"
},
"devDependencies": {
Expand Down
38 changes: 38 additions & 0 deletions editor/src/value-editors/boolean/boolean-value-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { BooleanValueModel, ValueModelContext } from 'sequential-workflow-editor-model';
import { ValueEditor } from '../value-editor';
import { validationErrorComponent } from '../../components/validation-error-component';
import { valueEditorContainerComponent } from '../../components/value-editor-container-component';
import { rowComponent } from '../../components/row-component';
import { selectComponent } from '../../components/select-component';

export const booleanValueEditorId = 'boolean';

export function booleanValueEditor(context: ValueModelContext<BooleanValueModel>): ValueEditor<BooleanValueModel> {
function validate() {
validation.setDefaultError(context.validate());
}

function onSelected(index: number) {
context.setValue(index === 1);
validate();
}

const select = selectComponent({
stretched: true
});
select.setValues(['False', 'True']);
select.selectIndex(context.getValue() ? 1 : 0);
select.onSelected.subscribe(onSelected);

const row = rowComponent([select.view]);

const validation = validationErrorComponent();
const container = valueEditorContainerComponent([row.view, validation.view]);

validate();

return {
view: container.view,
validate
};
}
2 changes: 2 additions & 0 deletions editor/src/value-editors/value-editor-factory-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { dynamicValueEditor, dynamicValueEditorId } from './dynamic/dynamic-valu
import { choiceValueEditor, choiceValueEditorId } from './choice/choice-value-editor';
import { branchesValueModelId, sequenceValueModelId } from 'sequential-workflow-editor-model';
import { nullableAnyVariableValueEditor, nullableAnyVariableValueEditorId } from './nullable-any-variable/nullable-any-variable-editor';
import { booleanValueEditor, booleanValueEditorId } from './boolean/boolean-value-editor';

const editors: { id: string; factory: ValueEditorFactory | null }[] = [
{ id: anyVariablesValueEditorId, factory: anyVariablesValueEditor as ValueEditorFactory },
{ id: booleanValueEditorId, factory: booleanValueEditor as ValueEditorFactory },
{ id: choiceValueEditorId, factory: choiceValueEditor as ValueEditorFactory },
{ id: nullableAnyVariableValueEditorId, factory: nullableAnyVariableValueEditor as ValueEditorFactory },
{ id: dynamicValueEditorId, factory: dynamicValueEditor as ValueEditorFactory },
Expand Down
2 changes: 1 addition & 1 deletion model/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sequential-workflow-editor-model",
"version": "0.3.0",
"version": "0.3.1",
"homepage": "https://nocode-js.com/",
"author": {
"name": "NoCode JS",
Expand Down
26 changes: 26 additions & 0 deletions model/src/test-tools/definition-model-stub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Path } from '../core';
import { DefinitionModel } from '../model';

export function createDefinitionModelStub(): DefinitionModel {
return {
root: {
properties: [],
sequence: {
dependencies: [],
name: 'stub',
label: 'Stub sequence',
value: {
id: 'stub',
label: 'Stub',
path: Path.create(['sequence']),
configuration: {},
getDefaultValue: () => [],
getVariableDefinitions: () => null,
validate: () => null
}
}
},
steps: {},
valueTypes: []
};
}
7 changes: 7 additions & 0 deletions model/src/test-tools/model-activator-stub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ModelActivator } from '../activator';
import { createDefinitionModelStub } from './definition-model-stub';

export function createModelActivatorStub(): ModelActivator {
let index = 0;
return ModelActivator.create(createDefinitionModelStub(), () => `0x${index++}`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface BooleanValueModelConfiguration {
defaultValue?: boolean;
}
28 changes: 28 additions & 0 deletions model/src/value-models/boolean/boolean-value-model.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Path } from '../../core';
import { createModelActivatorStub } from '../../test-tools/model-activator-stub';
import { booleanValueModel } from './boolean-value-model';
import { BooleanValueModelConfiguration } from './boolean-value-model-configuration';

describe('booleanValueModel', () => {
const modelActivator = createModelActivatorStub();

function getModel(configuration: BooleanValueModelConfiguration) {
return booleanValueModel(configuration)(Path.create('test'));
}

describe('getDefaultValue()', () => {
it('returns false as default', () => {
const value = getModel({}).getDefaultValue(modelActivator);

expect(value).toBe(false);
});

it('returns the configured default value', () => {
const valueTrue = getModel({ defaultValue: true }).getDefaultValue(modelActivator);
expect(valueTrue).toBe(true);

const valueFalse = getModel({ defaultValue: false }).getDefaultValue(modelActivator);
expect(valueFalse).toBe(false);
});
});
});
24 changes: 24 additions & 0 deletions model/src/value-models/boolean/boolean-value-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ValueModel, ValueModelFactory } from '../../model';
import { Path } from '../../core/path';
import { BooleanValueModelConfiguration } from './boolean-value-model-configuration';

export type BooleanValueModel = ValueModel<boolean, BooleanValueModelConfiguration>;

export const booleanValueModelId = 'boolean';

export function booleanValueModel(configuration: BooleanValueModelConfiguration): ValueModelFactory<BooleanValueModel> {
return (path: Path) => ({
id: booleanValueModelId,
label: 'Boolean',
path,
configuration,
getDefaultValue() {
if (configuration.defaultValue !== undefined) {
return configuration.defaultValue;
}
return false;
},
getVariableDefinitions: () => null,
validate: () => null
});
}
2 changes: 2 additions & 0 deletions model/src/value-models/boolean/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './boolean-value-model-configuration';
export * from './boolean-value-model';
3 changes: 2 additions & 1 deletion model/src/value-models/dynamic/dynamic-value-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export function dynamicValueModel<TValueModelFactory extends ValueModelFactory[]
const value = context.getValue();
const model = subModels.find(m => m.id === value.modelId);
if (!model) {
throw new Error(`Cannot find model id: ${value.modelId}`);
const availableModels = subModels.map(m => m.id).join(', ');
throw new Error(`Cannot find sub model id: ${value.modelId} (available: ${availableModels})`);
}
const childContext = context.createChildContext(model);
return model.validate(childContext);
Expand Down
1 change: 1 addition & 0 deletions model/src/value-models/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './any-variables';
export * from './boolean';
export * from './branches';
export * from './choice';
export * from './dynamic';
Expand Down