Skip to content

Commit

Permalink
Merge pull request #351 from kendraio/develop
Browse files Browse the repository at this point in the history
Production release with comparison block and service worker flag
  • Loading branch information
the-greenman committed Jan 16, 2023
2 parents c7976b0 + 4150db5 commit 81fef53
Show file tree
Hide file tree
Showing 19 changed files with 1,117 additions and 291 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ Adding a "Block" (i.e. Task for the Flow editor)

Use the Angular CLI to scaffold a new block: `npx ng g c blocks/my-block`
Edit the generated my-block.component.ts to make it a sub-class of BaseBlock.


Start by setting up your initial imports.

```javascript
import { BaseBlockComponent } from '../base-block/base-block.component';
import {get} from 'lodash-es';
```

Take a look at one of the more recent blocks as an example, eg the AudioPlayer:

```javascript
Expand Down Expand Up @@ -124,3 +133,13 @@ To make the block show up in the App:
This is needed for the flow to show up in rendered workflows.
- Add a definition, and default configuration, for the block to the block types so it can appear in the "Add Task" dialog:
[src/app/dialogs/add-block-dialog/block-types.ts](src/app/dialogs/add-block-dialog/block-types.ts)
Adding a custom block editor interface
--------------------------------------
The block editor is implemented using the blocks-editor component.
In order to create a custom editor, you will need to create a new component,
and call it via [blocks-editor.component.html](/src/app/components/blocks-editor/blocks-editor.component.html)
6 changes: 3 additions & 3 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
{
"type": "initial",
"maximumWarning": "25mb",
"maximumError": "25mb"
"maximumError": "30mb"
},
{
"type": "anyComponentStyle",
Expand Down Expand Up @@ -116,8 +116,8 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "10mb",
"maximumError": "25mb"
"maximumWarning": "20mb",
"maximumError": "30mb"
},
{
"type": "anyComponentStyle",
Expand Down
205 changes: 205 additions & 0 deletions cypress/e2e/comparison.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import { loadFlowCode } from '../support/helper';
// tslint:disable: quotemark
/// <reference types="Cypress" />

describe('Comparison Block Capabilities', () => {

// Working default
it('has a default result', () => {
loadFlowCode([
{
"type": "mapping",
"mapping": "{source:`one`, one:`one`, two:`two` }"
},
{
"type":"comparison",
"valueGetter":'data.source',
"default":'default'
},
{
"type":'debug'
}
]);
cy.contains('default');

});

// basic matching

it('returns a value for a matching comparison', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`one`, one:`one`, two:`two` }"
},
{
"type":"comparison",
"valueGetter":'data.source',
"default":'default',
"comparisons": [
{
operator:'==',
target:'one',
output:'one'
}
]
},
{
"type":'debug'
}
]);
cy.contains('one');
});




// value and jmespath targets

it('returns a jmespath value for a matching comparison', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`one`, one:`one`, two:`two`, path:`one` }"
},
{
"type":"comparison",
"valueGetter":'data.source',
"default":'default',
"comparisons": [
{
operator:'==',
target:'data.path',
targetType:'jmespath',
output:'path'
}
]
},
{
"type":'debug'
}
]);
cy.contains('path');
});


// multiple comparisons

it('keeps processing comparisons until it finds a matching comparison', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`two`, one:`one`, two:`two` }"
},
{
"type":"comparison",
"valueGetter":'data.source',
"default":'default',
"comparisons": [
{
operator:'==',
target:'one',
output:'first'
},
{
operator:'==',
target:'two',
output:'second'
}
]
},
{
"type":'debug'
}
]);
cy.contains('second');
});


// invalid comparison definitions

it('ignores badly formed comparisons', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`two`, one:`one`, two:`two` }"
},
{
"type":"comparison",
"valueGetter":'data.source',
"default":'default',
"comparisons": [
{
operator:'==',
target:'',
output:'first'
},
{
operator:'==',
target:'two',
output:'second'
}
]
},
{
"type":'debug'
}
]);
cy.contains('second');
});

// nothing there

it('can cope with a non-existent source value', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`two`, one:`one`, two:`two` }"
},
{
"type":"comparison",
"valueGetter":'data.null',
"default":'default',
"comparisons": [
{
operator:'null',
output:'null'
}
]
},
{
"type":'debug'
}
]);
cy.contains('null');
});

it('allows jmespath default values', () =>{
loadFlowCode([
{
"type": "mapping",
"mapping": "{ source:`two`, one:`first`, two:`second` }"
},
{
"type": "comparison",
"valueGetter": "data.source",
"default": "data.two",
"defaultType": "jmespath",
"comparisons": [
{
"operator": "typeof",
"target": "array",
"targetType": "value",
"output": "one",
"outputType": "value"
}
]
},
{
"type":'debug'
}
]);
cy.contains('second');
});

});
79 changes: 79 additions & 0 deletions docs/workflow/blocks/comparison.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
Comparison
==========

Perform a simple operation, comparing a source value with a set of target values.

The comparison block works through each of a set of operations, and when
it finds a successful match, returns the specified output.

Once a match is found, processing stops. If no match is found, a default is returned.

The output of the block will replace "data".

Configuration
-------------

The comparison block is configured by a custom form.

(General) Value Types
++++++++++++++++++++++

The comparison block assumes that target, output and default values are strings by default.
However, it is possible to specify that these are JMESPath values, which means that
they will be passed through the mapper to retrieve data, or perform additional operations.

Block Setup
+++++++++++

Source
^^^^^^

The source that we will be comparing against. This is a JMESpath expression.

Default
^^^^^^^

If no match is set, the default is returned.


Comparison definitions
++++++++++++++++++++++

Operator
^^^^^^^^

What operation should be performed. '==', '>','<' etc.
Some operators require a target, to be compared with, others simply work on the source.

Target
^^^^^^
If the operator requires a second value to compare with, a target needs to be specified.


Output
^^^^^^
On a successful match, the output for the comparison is returned.



Default config
--------------
Under the hood, this is the default block config JSON.

.. code-block:: json
{
type: 'comparison',
valueGetter: 'data',
default: 'NO',
defaultType: 'value',
comparisons: [
{
operator: '==',
target:'OK',
targetType:'value',
output:'YES',
outputType:'value'
}
]
}
10 changes: 8 additions & 2 deletions docs/workflow/blocks/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ HTTP Request

Get, put or post data to an external HTTP endpoint.


Default config
--------------

Expand All @@ -19,15 +20,19 @@ Default config
"userId": 1
}
}
"useProxy": false
}
Supported properties
--------------------

- **method** - REQUIRED - allowed values are get, put, post, and delete.
- **notify** (boolean) (default = true): Show a notification message if the request is successful. This message is not
- **useProxy** (boolean) (default = false) - Set to true to use a proxy. Useful for CORS. Proxy setting are set at https://app.kendra.io/core/settings
- **notify** (boolean) (default = true) - Show a notification message if the request is successful. This message is not
sent when the HTTP method is GET, but can be turned on and off for POST, PUT, and DELETE requests by using this
property.
- **headers** - A set of headers with header name as object key. Values are processed by JMESpath
- **endpoint** - The request endpoint. Can take multiple forms. See below.


Examples
Expand All @@ -40,7 +45,8 @@ For simple requests, the ``endpoint`` can just be a simple string:
{
"type": "http",
"method": "get",
"endpoint": "https://covid19.mathdro.id/api"
"endpoint": "https://covid19.mathdro.id/api",
"useProxy" : true
}
Expand Down

0 comments on commit 81fef53

Please sign in to comment.