@lowdefy/docs 3.23.2 → 4.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/operators/client/filter_default_value.js +55 -0
- package/{public/modules/connectDocsearch.js → dist/operatorsClient.js} +2 -20
- package/{templates/blocks/schemaTransformer.js → dist/types.js} +6 -11
- package/package.json +23 -8
- package/404.yaml +0 -26
- package/CHANGELOG.md +0 -659
- package/actions/CallMethod.yaml +0 -57
- package/actions/JsAction.yaml +0 -281
- package/actions/Link.yaml +0 -120
- package/actions/Login.yaml +0 -123
- package/actions/Logout.yaml +0 -44
- package/actions/Message.yaml +0 -68
- package/actions/Notification.yaml +0 -84
- package/actions/Request.yaml +0 -70
- package/actions/Reset.yaml +0 -42
- package/actions/ResetValidation.yaml +0 -102
- package/actions/ScrollTo.yaml +0 -100
- package/actions/SetGlobal.yaml +0 -78
- package/actions/SetState.yaml +0 -85
- package/actions/Throw.yaml +0 -89
- package/actions/Validate.yaml +0 -104
- package/actions/Wait.yaml +0 -40
- package/blocks/all_icons.yaml +0 -802
- package/blocks/container/Affix.yaml +0 -26
- package/blocks/container/Badge.yaml +0 -27
- package/blocks/container/Box.yaml +0 -27
- package/blocks/container/Card.yaml +0 -29
- package/blocks/container/Collapse.yaml +0 -38
- package/blocks/container/Comment.yaml +0 -43
- package/blocks/container/ConfirmModal.yaml +0 -36
- package/blocks/container/Drawer.yaml +0 -45
- package/blocks/container/Label.yaml +0 -29
- package/blocks/container/Modal.yaml +0 -46
- package/blocks/container/Result.yaml +0 -34
- package/blocks/container/Span.yaml +0 -27
- package/blocks/container/Spin.yaml +0 -27
- package/blocks/container/Tabs.yaml +0 -41
- package/blocks/container/Tooltip.yaml +0 -38
- package/blocks/context/Context.yaml +0 -27
- package/blocks/context/PageHCF.yaml +0 -28
- package/blocks/context/PageHCSF.yaml +0 -29
- package/blocks/context/PageHSCF.yaml +0 -29
- package/blocks/context/PageHeaderMenu.yaml +0 -52
- package/blocks/context/PageSHCF.yaml +0 -29
- package/blocks/context/PageSiderMenu.yaml +0 -53
- package/blocks/display/Alert.yaml +0 -26
- package/blocks/display/Anchor.yaml +0 -26
- package/blocks/display/Avatar.yaml +0 -24
- package/blocks/display/Breadcrumb.yaml +0 -29
- package/blocks/display/Button.yaml +0 -43
- package/blocks/display/DangerousHtml.yaml +0 -62
- package/blocks/display/DangerousMarkdown.yaml +0 -46
- package/blocks/display/Descriptions.yaml +0 -49
- package/blocks/display/Divider.yaml +0 -25
- package/blocks/display/EChart.yaml +0 -53
- package/blocks/display/Html.yaml +0 -50
- package/blocks/display/Icon.yaml +0 -25
- package/blocks/display/Img.yaml +0 -40
- package/blocks/display/Markdown.yaml +0 -32
- package/blocks/display/MarkdownWithCode.yaml +0 -48
- package/blocks/display/Menu.yaml +0 -48
- package/blocks/display/Message.yaml +0 -34
- package/blocks/display/MobileMenu.yaml +0 -48
- package/blocks/display/Notification.yaml +0 -34
- package/blocks/display/Paragraph.yaml +0 -32
- package/blocks/display/Progress.yaml +0 -53
- package/blocks/display/Skeleton.yaml +0 -28
- package/blocks/display/Statistic.yaml +0 -37
- package/blocks/display/Title.yaml +0 -32
- package/blocks/input/AutoComplete.yaml +0 -31
- package/blocks/input/ButtonSelector.yaml +0 -37
- package/blocks/input/CheckboxSelector.yaml +0 -37
- package/blocks/input/CheckboxSwitch.yaml +0 -56
- package/blocks/input/ChromeColorSelector.yaml +0 -25
- package/blocks/input/CircleColorSelector.yaml +0 -25
- package/blocks/input/ColorSelector.yaml +0 -25
- package/blocks/input/CompactColorSelector.yaml +0 -25
- package/blocks/input/DateRangeSelector.yaml +0 -27
- package/blocks/input/DateSelector.yaml +0 -27
- package/blocks/input/DateTimeSelector.yaml +0 -29
- package/blocks/input/GithubColorSelector.yaml +0 -25
- package/blocks/input/MonthSelector.yaml +0 -27
- package/blocks/input/MultipleSelector.yaml +0 -117
- package/blocks/input/NumberInput.yaml +0 -24
- package/blocks/input/Pagination.yaml +0 -33
- package/blocks/input/ParagraphInput.yaml +0 -32
- package/blocks/input/PasswordInput.yaml +0 -48
- package/blocks/input/RadioSelector.yaml +0 -36
- package/blocks/input/RatingSlider.yaml +0 -24
- package/blocks/input/S3UploadButton.yaml +0 -28
- package/blocks/input/Selector.yaml +0 -98
- package/blocks/input/SliderColorSelector.yaml +0 -24
- package/blocks/input/SwatchesColorSelector.yaml +0 -24
- package/blocks/input/Switch.yaml +0 -24
- package/blocks/input/TextArea.yaml +0 -28
- package/blocks/input/TextInput.yaml +0 -59
- package/blocks/input/TitleInput.yaml +0 -32
- package/blocks/input/TwitterColorSelector.yaml +0 -24
- package/blocks/input/WeekSelector.yaml +0 -26
- package/blocks/list/ControlledList.yaml +0 -191
- package/blocks/list/List.yaml +0 -158
- package/blocks/list/TimelineList.yaml +0 -135
- package/body.html +0 -1
- package/concepts/blocks.yaml +0 -249
- package/concepts/cli.yaml +0 -173
- package/concepts/connections-and-requests.yaml +0 -114
- package/concepts/context-and-state.yaml +0 -82
- package/concepts/custom-blocks.yaml +0 -176
- package/concepts/custom-code.yaml +0 -196
- package/concepts/events-and-actions.yaml +0 -224
- package/concepts/hosting-files.yaml +0 -50
- package/concepts/layout.yaml +0 -1464
- package/concepts/lists.yaml +0 -162
- package/concepts/lowdefy-schema.yaml +0 -244
- package/concepts/operators.yaml +0 -66
- package/concepts/overview.yaml +0 -48
- package/concepts/secrets.yaml +0 -56
- package/connections/AWSS3.yaml +0 -228
- package/connections/AmazonRedshift.yaml +0 -75
- package/connections/AxiosHttp.yaml +0 -194
- package/connections/Elasticsearch.yaml +0 -378
- package/connections/GoogleSheet.yaml +0 -332
- package/connections/Knex.yaml +0 -181
- package/connections/KnexRequests.md +0 -121
- package/connections/MSSQL.yaml +0 -90
- package/connections/MariaDB.yaml +0 -77
- package/connections/MongoDB.yaml +0 -452
- package/connections/MySQL.yaml +0 -92
- package/connections/OracleDB.yaml +0 -73
- package/connections/PostgreSQL.yaml +0 -99
- package/connections/SQLite.yaml +0 -94
- package/connections/SendGridMail.yaml +0 -113
- package/connections/Stripe.yaml +0 -139
- package/deployment/aws-lambda.yaml +0 -128
- package/deployment/docker.yaml +0 -118
- package/deployment/netlify.yaml +0 -69
- package/deployment/node-server.yaml +0 -111
- package/head.html +0 -7
- package/howto/generate-csv.yaml.njk +0 -251
- package/howto/generate-pdf.yaml.njk +0 -651
- package/howto/generateCsv/lowdefy.yaml +0 -63
- package/howto/generateCsv/public/csvMake.js +0 -27
- package/howto/generatePdf/inv_template.yaml +0 -200
- package/howto/generatePdf/lowdefy.yaml +0 -116
- package/howto/generatePdf/my_header.html +0 -1
- package/howto/generatePdf/public/logo_example.png +0 -0
- package/howto/generatePdf/public/modules/importUmd.js +0 -7
- package/howto/generatePdf/public/modules/pdfMake.js +0 -7
- package/howto/generatePdf/public/modules/vfs_fonts.js +0 -12
- package/introduction.yaml +0 -100
- package/lowdefy.yaml +0 -66
- package/menus.yaml +0 -841
- package/operators/_actions.yaml +0 -123
- package/operators/_and.yaml +0 -90
- package/operators/_args.yaml +0 -79
- package/operators/_array.yaml +0 -326
- package/operators/_base64.yaml +0 -56
- package/operators/_change_case.yaml +0 -347
- package/operators/_date.yaml +0 -71
- package/operators/_diff.yaml +0 -76
- package/operators/_divide.yaml +0 -46
- package/operators/_eq.yaml +0 -67
- package/operators/_event.yaml +0 -102
- package/operators/_format.yaml +0 -209
- package/operators/_function.yaml +0 -66
- package/operators/_get.yaml +0 -108
- package/operators/_global.yaml +0 -106
- package/operators/_gt.yaml +0 -65
- package/operators/_gte.yaml +0 -65
- package/operators/_hash.yaml +0 -109
- package/operators/_if.yaml +0 -44
- package/operators/_if_none.yaml +0 -61
- package/operators/_index.yaml +0 -64
- package/operators/_input.yaml +0 -113
- package/operators/_js.yaml +0 -189
- package/operators/_json.yaml +0 -128
- package/operators/_list_contexts.yaml +0 -37
- package/operators/_location.yaml +0 -59
- package/operators/_log.yaml +0 -36
- package/operators/_lt.yaml +0 -65
- package/operators/_lte.yaml +0 -65
- package/operators/_math.yaml +0 -374
- package/operators/_media.yaml +0 -86
- package/operators/_menu.yaml +0 -81
- package/operators/_mql.yaml +0 -101
- package/operators/_ne.yaml +0 -77
- package/operators/_not.yaml +0 -47
- package/operators/_number.yaml +0 -157
- package/operators/_nunjucks.yaml +0 -73
- package/operators/_object.yaml +0 -193
- package/operators/_operator.yaml +0 -47
- package/operators/_or.yaml +0 -81
- package/operators/_product.yaml +0 -59
- package/operators/_random.yaml +0 -104
- package/operators/_ref.yaml +0 -232
- package/operators/_regex.yaml +0 -83
- package/operators/_request.yaml +0 -50
- package/operators/_secret.yaml +0 -74
- package/operators/_state.yaml +0 -113
- package/operators/_string.yaml +0 -283
- package/operators/_subtract.yaml +0 -38
- package/operators/_sum.yaml +0 -59
- package/operators/_switch.yaml +0 -51
- package/operators/_type.yaml +0 -92
- package/operators/_uri.yaml +0 -56
- package/operators/_url_query.yaml +0 -119
- package/operators/_user.yaml +0 -107
- package/operators/_uuid.yaml +0 -114
- package/operators/_var.yaml +0 -105
- package/operators/_yaml.yaml +0 -83
- package/pages.yaml +0 -228
- package/public/images/authors/gervwyk.jpeg +0 -0
- package/public/images/authors/sandile.jpeg +0 -0
- package/public/images/howto/header_generate_csv.jpg +0 -0
- package/public/images/howto/header_generate_pdf.jpg +0 -0
- package/public/logo_example.png +0 -0
- package/public/lowdefy_app_schema.png +0 -0
- package/public/modules/csvMake.js +0 -27
- package/public/modules/filterDefaultValue.js +0 -48
- package/public/modules/importUmd.js +0 -7
- package/public/modules/index.js +0 -5
- package/public/modules/pdfMake.js +0 -7
- package/public/modules/test/filterDefaultValue.test.js +0 -91
- package/public/modules/vfs_fonts.js +0 -12
- package/public/sitemap.xml +0 -1024
- package/templates/actions.yaml.njk +0 -68
- package/templates/blocks/defaultValueTransformer.js +0 -51
- package/templates/blocks/exampleTransformer.js +0 -81
- package/templates/blocks/layout.yaml +0 -114
- package/templates/blocks/propertiesFormTransformer.js +0 -419
- package/templates/blocks/propertiesGetterTransformer.js +0 -132
- package/templates/blocks/schema.yaml.njk +0 -42
- package/templates/blocks/style.yaml +0 -26
- package/templates/blocks/template.yaml.njk +0 -496
- package/templates/blog.yaml.njk +0 -221
- package/templates/cli_command.yaml.njk +0 -37
- package/templates/footer.yaml.njk +0 -604
- package/templates/general.yaml.njk +0 -124
- package/templates/generateSitemap.js +0 -42
- package/templates/header.yaml +0 -138
- package/templates/navigation_buttons.yaml +0 -68
- package/templates/operators.yaml.njk +0 -82
- package/templates/operatorsMethodTransformer.js +0 -119
- package/templates/test/array.test.js +0 -1355
- package/templates/test/boolean.test.js +0 -102
- package/templates/test/button.test.js +0 -170
- package/templates/test/color.test.js +0 -128
- package/templates/test/enum.test.js +0 -109
- package/templates/test/icon.test.js +0 -113
- package/templates/test/integer.test.js +0 -103
- package/templates/test/manual.test.js +0 -246
- package/templates/test/number.test.js +0 -103
- package/templates/test/object.test.js +0 -442
- package/templates/test/oneOf.test.js +0 -806
- package/templates/test/string.test.js +0 -102
- package/templates/test/yaml.test.js +0 -621
- package/tutorial/next-steps.yaml +0 -83
- package/tutorial/tutorial-actions-operators-config.yaml +0 -142
- package/tutorial/tutorial-actions-operators.yaml +0 -436
- package/tutorial/tutorial-add-blocks-config.yaml +0 -109
- package/tutorial/tutorial-add-blocks.yaml +0 -195
- package/tutorial/tutorial-create-page-config.yaml +0 -77
- package/tutorial/tutorial-create-page.yaml +0 -196
- package/tutorial/tutorial-deploy.yaml +0 -146
- package/tutorial/tutorial-requests-config.yaml +0 -186
- package/tutorial/tutorial-requests.yaml +0 -338
- package/tutorial/tutorial-start.yaml +0 -282
- package/users/login-and-logout.yaml +0 -164
- package/users/openid-connect.yaml +0 -84
- package/users/protected-pages.yaml +0 -67
- package/users/roles.yaml +0 -70
- package/users/user-object.yaml +0 -73
- package/users/users-introduction.yaml +0 -80
- package/version.yaml +0 -1
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Copyright 2020-2021 Lowdefy, Inc
|
|
2
|
-
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
_ref:
|
|
16
|
-
path: templates/general.yaml.njk
|
|
17
|
-
vars:
|
|
18
|
-
pageId: connections-and-requests
|
|
19
|
-
pageTitle: Connections and Requests
|
|
20
|
-
section: Concepts
|
|
21
|
-
filePath: concepts/connections-and-requests.yaml
|
|
22
|
-
content:
|
|
23
|
-
- id: md1
|
|
24
|
-
type: Markdown
|
|
25
|
-
properties:
|
|
26
|
-
content: |
|
|
27
|
-
### TLDR
|
|
28
|
-
- `connections` define links to other services, like connecting to a database. They are defined at the root of the lowdefy configuration.
|
|
29
|
-
- `requests` use connections to make a call to the connected external services.
|
|
30
|
-
- Use the [`_secret`](/_secret) operator to reference API keys or other secrets as required - do not code secrets into your config or commit secrets to your config source control.
|
|
31
|
-
|
|
32
|
-
-----------
|
|
33
|
-
In a Lowdefy app you can integrate with other services like API's or databases using `connections` and `requests`. Connections configure the connection settings to the service, and often contain parameters like connection strings, urls and secrets like passwords or API keys. Requests are used to interact with the connection, like inserting a data record, executing a query or calling a API end-point.
|
|
34
|
-
|
|
35
|
-
- id: alert2
|
|
36
|
-
type: Alert
|
|
37
|
-
properties:
|
|
38
|
-
type: warning
|
|
39
|
-
showIcon: false
|
|
40
|
-
message: Sensitive information like passwords or API keys are often required to use external services. The _secret operator should be used to reference these secrets, they should never be coded directly in your app, or committed to source control.
|
|
41
|
-
|
|
42
|
-
- id: md2
|
|
43
|
-
type: Markdown
|
|
44
|
-
properties:
|
|
45
|
-
content: |
|
|
46
|
-
# Connections
|
|
47
|
-
|
|
48
|
-
Connections are defined at the root of your Lowdefy configuration, in the `connections` array. Each connection must have an `id`, a `type`, and `properties` defining the connection. Operators in connection properties are evaluated every time a request is called.
|
|
49
|
-
|
|
50
|
-
# Connection Schema
|
|
51
|
-
|
|
52
|
-
The schema for a Lowdefy connection is:
|
|
53
|
-
|
|
54
|
-
- `id: string`: __Required__ - A unique identifier for the connection. This is used by requests to specify which connection to use.
|
|
55
|
-
- `type: string`: __Required__ - The connection type to be used.
|
|
56
|
-
- `properties: object`: The settings passed to the connection. __Operators are evaluated__.
|
|
57
|
-
|
|
58
|
-
###### Connections definition example:
|
|
59
|
-
```yaml
|
|
60
|
-
lowdefy: LOWDEFY_VERSION
|
|
61
|
-
connections:
|
|
62
|
-
- id: connection1
|
|
63
|
-
type: ConnectionType1
|
|
64
|
-
properties:
|
|
65
|
-
# ...
|
|
66
|
-
- id: connection2
|
|
67
|
-
type: ConnectionType2
|
|
68
|
-
properties:
|
|
69
|
-
# ...
|
|
70
|
-
pages:
|
|
71
|
-
# ...
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Our goal is to make connections for everything. As the Lowdefy community grows, we will continue to develop the most requested connections. If the connection you require is not supported yet, please head over to our [new connections voting board](https://github.com/lowdefy/lowdefy/discussions/309) to request and vote for new connections.
|
|
75
|
-
|
|
76
|
-
# Requests
|
|
77
|
-
|
|
78
|
-
Requests can be defined on any block, and the results of the request are available to any block in the same context. Requests must have an `id`, `type`, `connectionId` field specifying the connection to use, and `properties` defining the request settings. Requests can be called using the [`Request`](/Request) action. Operators in request properties are evaluated every time a request is called.
|
|
79
|
-
|
|
80
|
-
# Request Schema
|
|
81
|
-
|
|
82
|
-
The schema for a Lowdefy request is:
|
|
83
|
-
|
|
84
|
-
- `id: string`: __Required__ - A identifier for the request. It must be unique within the context the request is defined in.
|
|
85
|
-
- `type: string`: __Required__ - The request type to be used. It must be a type supported by the connection type.
|
|
86
|
-
- `connectionId: string`: __Required__ - The `id` of the connection that should be used.
|
|
87
|
-
- `properties: object`: The settings passed to the request. __Operators are evaluated__.
|
|
88
|
-
|
|
89
|
-
###### Requests definition example:
|
|
90
|
-
```yaml
|
|
91
|
-
id: block_with_requests
|
|
92
|
-
type: BlockType
|
|
93
|
-
requests:
|
|
94
|
-
- id: request1
|
|
95
|
-
type: RequestType1
|
|
96
|
-
connectionId: connectionId1
|
|
97
|
-
properties:
|
|
98
|
-
# ...
|
|
99
|
-
- id: request2
|
|
100
|
-
type: RequestType2
|
|
101
|
-
connectionId: connectionId2
|
|
102
|
-
properties:
|
|
103
|
-
# ...
|
|
104
|
-
properties:
|
|
105
|
-
# ...
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
- _ref:
|
|
109
|
-
path: templates/navigation_buttons.yaml
|
|
110
|
-
vars:
|
|
111
|
-
previous_page_title: Layout
|
|
112
|
-
previous_page_id: layout
|
|
113
|
-
next_page_title: Events and Actions
|
|
114
|
-
next_page_id: events-and-actions
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Copyright 2020-2021 Lowdefy, Inc
|
|
2
|
-
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
_ref:
|
|
16
|
-
path: templates/general.yaml.njk
|
|
17
|
-
vars:
|
|
18
|
-
pageId: context-and-state
|
|
19
|
-
pageTitle: Context and State
|
|
20
|
-
section: Concepts
|
|
21
|
-
filePath: concepts/context-and-state.yaml
|
|
22
|
-
content:
|
|
23
|
-
- id: md1
|
|
24
|
-
type: Markdown
|
|
25
|
-
properties:
|
|
26
|
-
content: |
|
|
27
|
-
#### TLDR
|
|
28
|
-
- The first block on a page must be a `context` category block.
|
|
29
|
-
- A page can have multiple `context` blocks.
|
|
30
|
-
- Every `context` has a single `state` object.
|
|
31
|
-
- All input blocks write their value to `state`, with the their `id` as the key in the `state` object.
|
|
32
|
-
- Input blocks which are not visible are removed from `state`.
|
|
33
|
-
- The `SetState` action can also modify the `state` object.
|
|
34
|
-
|
|
35
|
-
-------
|
|
36
|
-
|
|
37
|
-
A Lowdefy block with category `context` provides the environment for a part of a Lowdefy app to run in. More than one context can be placed on a page, but generally only one is needed. The first block on a page must be a `context` category block.
|
|
38
|
-
|
|
39
|
-
The standard page blocks like [`PageHeaderMenu`](/PageHeaderMenu) or [`PageSiderMenu`](/PageSiderMenu) are all `context` category blocks, and the [`Context`](/Context) block is a simple container that also provides a context.
|
|
40
|
-
|
|
41
|
-
Each context provides encapsulation to the blocks inside it. It has it's own `state` object as well as requests.
|
|
42
|
-
|
|
43
|
-
Every `input` category block inside the context will have a value in the `state` object, with the their `id` as the key in the `state` object, unless the block is not visible, in which case the input value is removed the state object.
|
|
44
|
-
|
|
45
|
-
The only other way to modify the `state` object is to use a `SetState` action. See [`SetState`](/SetState) and [`events-and-actions`](/events-and-actions) for more details.
|
|
46
|
-
|
|
47
|
-
Contexts remain even as users navigate to new pages, so if a user returns to a page, the state as they left it will remain.
|
|
48
|
-
|
|
49
|
-
# Url queries
|
|
50
|
-
|
|
51
|
-
A new context is created for each distinct URL query parameters seen by the app. This means that if a page is open with two different URL queries, two different contexts, with separate `state` objects will be created.
|
|
52
|
-
|
|
53
|
-
# Context IDs
|
|
54
|
-
|
|
55
|
-
Each context created has a identifier with the following structure:
|
|
56
|
-
```
|
|
57
|
-
{pageId}:{blockId}:{JSON stringified urlQuery object}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
# Context data objects
|
|
61
|
-
|
|
62
|
-
A Lowdefy `context` makes some additional data object accessible via operators. These include:
|
|
63
|
-
|
|
64
|
-
- [`_global`](/_global): The `global` object is a single app level data object defined in the Lowdefy [config root](/lowdefy-schema). This object is the same for every `context`, it is also passed between the client and server. If the [`SetGlobal`](/SetGlobal) action is called, it is not consistent between clients, like different users, or a single user with multiple tabs open.
|
|
65
|
-
|
|
66
|
-
- [`_state`](/_state): A `state` object is unique to a `context` and every [`input` block](/blocks) maintains a value in it's parent `state` object. This `state` object is passed to the server when requests are called. The [`SetState`](/SetState) action can be used to modify the value of a `state` object in the same `context` from which `SetState` is called.
|
|
67
|
-
|
|
68
|
-
- [`_url_query`](/_url_query): The `urlQuery` object is used to access variables set in the url. Url query parameters can be set using the `urlQuery` field in the [`Link`](/Link) action. It can be useful to create sharable links containing some additional information other than the page route. For example setting a document id in the url so that the document can be retrieved when the link is opened during the page [`onEnter`](/events-and-actions) event. __Note that any variables set to `urlQuery` will be publicly visible__.
|
|
69
|
-
|
|
70
|
-
- [`_input`](/_input): The `input` object is unique to a page, and works similar to the `urlQuery` object. The `input` object is used to pass information between page transitions. This variable set to the `input` object are not written to the url, so they are not visible publicly but also cannot be used to share the data in a link since a `input` object is only consistent between one `context` and the next to which it links. A `input` object is set to the `input` field of the [`Link`](/Link) action when linking from one page `context` to the next.
|
|
71
|
-
|
|
72
|
-
- [`_media`](/_media): The `media` object contains some information about the client screen size etc. This is useful in order to add additional responsive logic to a page.
|
|
73
|
-
|
|
74
|
-
- [`_user`](/user-object): The `user` object contains the data in the user idToken if OpenID Connect authentication is configured and a user is logged in.
|
|
75
|
-
|
|
76
|
-
- _ref:
|
|
77
|
-
path: templates/navigation_buttons.yaml
|
|
78
|
-
vars:
|
|
79
|
-
previous_page_title: Lowdefy Schema
|
|
80
|
-
previous_page_id: lowdefy-schema
|
|
81
|
-
next_page_title: Blocks
|
|
82
|
-
next_page_id: blocks
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# Copyright 2020-2021 Lowdefy, Inc
|
|
2
|
-
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
_ref:
|
|
16
|
-
path: templates/general.yaml.njk
|
|
17
|
-
vars:
|
|
18
|
-
pageId: custom-blocks
|
|
19
|
-
pageTitle: Custom Blocks
|
|
20
|
-
section: Concepts
|
|
21
|
-
filePath: concepts/custom-blocks.yaml
|
|
22
|
-
content:
|
|
23
|
-
- id: warning
|
|
24
|
-
type: Alert
|
|
25
|
-
properties:
|
|
26
|
-
message: |
|
|
27
|
-
SECURITY WARNING: Blocks execute JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Make sure that you only load blocks from a trusted source.
|
|
28
|
-
type: warning
|
|
29
|
-
- id: md1
|
|
30
|
-
type: MarkdownWithCode
|
|
31
|
-
properties:
|
|
32
|
-
content: |
|
|
33
|
-
Blocks in Lowdefy are simple, most often state-less, [React components](https://reactjs.org/docs/components-and-props.html). Lowdefy uses [webpack module federation](https://webpack.js.org/concepts/module-federation/) to implement a micro front-end strategy. This means blocks are imported at load time, and not part of the Lowdefy app build.
|
|
34
|
-
|
|
35
|
-
The decoupling of blocks provides the considerable advantages:
|
|
36
|
-
- Block developers can extend the UI capabilities of Lowdefy by building blocks for the community to utilize.
|
|
37
|
-
- Lowdefy app developers can use community blocks to experiment and extend their apps.
|
|
38
|
-
- Lowdefy blocks are simple, most often stateless React components, thus blocks can be developed quickly and can be used inside Lowdefy apps with ease.
|
|
39
|
-
- The build process is simple and fast since you only build the code for your block, and not the entire application.
|
|
40
|
-
- The Lowdefy engine takes care off the application state, the the block only has to concern itself with a easy application interface.
|
|
41
|
-
|
|
42
|
-
## Using Custom Blocks
|
|
43
|
-
|
|
44
|
-
To use a custom block type inside a Lowdefy app, configure the `types` object in the root of the Lowdefy config. For example to use a AmCharts block we can add a `AmChartsXY` type to the `types`.
|
|
45
|
-
|
|
46
|
-
```yaml
|
|
47
|
-
name: dashboard-app
|
|
48
|
-
lowdefy: 3.23.2
|
|
49
|
-
types:
|
|
50
|
-
AmChartsXY:
|
|
51
|
-
url: https://blocks-cdn.lowdefy.com/v3.10.1/blocks-amcharts/meta/AmChartsXY.json
|
|
52
|
-
# ...
|
|
53
|
-
pages:
|
|
54
|
-
- id: dashboard
|
|
55
|
-
type: PageHeaderMenu
|
|
56
|
-
blocks:
|
|
57
|
-
- id: my_chart
|
|
58
|
-
type: AmChartsXY
|
|
59
|
-
properties:
|
|
60
|
-
#...
|
|
61
|
-
#...
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
By default Lowdefy build apps with a set of pre-configured, default block types to make it easier to build apps, for example using [`Button`](/Button), [`TextInput`](/TextInput), [`Box`](/Box), etc. All the blocks documented in the Lowdefy docs are default types. We will continue to build out this list of default blocks to make it as easy as possible to build excellent feature rich apps.
|
|
65
|
-
|
|
66
|
-
It is possible to overwrite the default a block type by simply defining a url for the default type in the `types` object. This is especially useful when you need to use a older version of a block, or would like to do something unique.
|
|
67
|
-
|
|
68
|
-
#### Examples of Custom Blocks
|
|
69
|
-
|
|
70
|
-
##### AmCharts:
|
|
71
|
-
|
|
72
|
-
[AmCharts](https://www.amcharts.com/) enables you to render powerful javascript charts. We have created the [AmCharts Lowdefy blocks](https://github.com/lowdefy/blocks-amcharts) making it easy to use highly customizable charts in your apps.
|
|
73
|
-
|
|
74
|
-
##### Ag-Grid:
|
|
75
|
-
|
|
76
|
-
[Ag-Grid](https://www.ag-grid.com/) enables you to render feature rich tables. We have created the [AgGrid Lowdefy blocks](https://github.com/lowdefy/blocks-aggrid) making it easy to use advanced tables in your apps.
|
|
77
|
-
|
|
78
|
-
## Steps to develop a custom block
|
|
79
|
-
|
|
80
|
-
#### 1. Clone the blocks template repository
|
|
81
|
-
|
|
82
|
-
To develop a custom block, first clone the [Lowdefy blocks template repository](https://github.com/lowdefy/blocks-template). This template provides a project structure for building a custom block. This structure can be modified to your preferences with the following exceptions:
|
|
83
|
-
- Keep the webpack configuration to ensure your custom block works with Lowdefy block module federation.
|
|
84
|
-
- Blocks need meta data in the block schema format which Lowdefy uses to interpret how to render your block.
|
|
85
|
-
|
|
86
|
-
#### 2. Start your local block server
|
|
87
|
-
|
|
88
|
-
Once the repository is cloned, `yarn install` the block dependencies. Then start the local block server by running `yarn start`. The default is to start you block server on `http://localhost:3002`. Open `http://localhost:3002/meta/DisplayBlock.json` in your browser and confirm the the block meta data is served.
|
|
89
|
-
|
|
90
|
-
You can create multiple blocks in the same repository, or run multiple block servers from different block repositories. Use `yarn start --port {{ port_number }}` when you need to run multiple block servers.
|
|
91
|
-
|
|
92
|
-
#### 3. Configure your block types
|
|
93
|
-
|
|
94
|
-
In your `lowdefy.yaml` file, add your custom block type to the `types` object with the local path.
|
|
95
|
-
|
|
96
|
-
```yaml
|
|
97
|
-
name: dashboard-app
|
|
98
|
-
lowdefy: 3.23.2
|
|
99
|
-
types:
|
|
100
|
-
MyCustomBlock:
|
|
101
|
-
url: http://localhost:3002/meta/MyCustomBlock.json
|
|
102
|
-
# ...
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
You can then test your block locally by running `npx lowdefy@latest dev` to develop your Lowdefy app together with your custom block.
|
|
106
|
-
|
|
107
|
-
#### 4. Code your Lowdefy block
|
|
108
|
-
|
|
109
|
-
A Lowdefy block consist of two files, your schema file and your React component. With Lowdefy we try to keep blocks stateless and let the Lowdefy engine mange application state.
|
|
110
|
-
|
|
111
|
-
For most applications this is fine and it simplifies the block logic, the result is "smaller" blocks and more flexibility to the Lowdefy app builder. It is up to the block developer to decide how to balance the trade off between configurability and complexity of the block. For example, it might be better for a UI elements like a Calender to be state-full and packaged as one piece, rather than to break the Calender up into various smaller blocks, that Lowdefy app developers need to piece together. With that said, it is worth mentioning that every time the block properties changes, Lowdefy will rerender the entire block, this can have a performance impact when blocks become large and complex.
|
|
112
|
-
|
|
113
|
-
### Block schema definition
|
|
114
|
-
|
|
115
|
-
- `category: enum`: How this block should be rendered in the Lowdefy app. Can be either `display`, `input`, `container`, `context` or `list`.
|
|
116
|
-
- `valueType: enum`: For blocks of the `input` block category, Lowdefy enforces a value type in `state`. This can be either a `boolean`, `number`, `string`, `object` or `array`. Lowdefy provides a default value for the block. This is usually `null`, but is `false` for boolean blocks, and the empty array, `[]`, for array blocks.
|
|
117
|
-
- `loading: boolean | object`: Settings for the default loading skeleton to render while the block is in a loading status. `false` will render an empty div element while `true` will render the default block skeleton based on the block category. Else an `object` can be provided for more refined settings, see the [loading placeholder types](/blocks) for more details A Lowdefy app developer can over write these defaults by defining the `loading` settings when configuring a block.
|
|
118
|
-
- `schema: object`: Provide a valid [JSON-Schema](https://json-schema.org/) definition for the block `properties` and `events`.
|
|
119
|
-
|
|
120
|
-
### Block React Component Props
|
|
121
|
-
|
|
122
|
-
The React component will receive the following props:
|
|
123
|
-
|
|
124
|
-
- `basePath: string`: The base path setting for the application. This variable is used to prefix route paths for example `${basePath}/public/logo-square-light-theme.png`. The default base path is ''.
|
|
125
|
-
- `blockId: string`: The block's id within the Lowdefy app, this is useful for setting a unique `id` on DOM elements.
|
|
126
|
-
- `content: object`: Passed to `container` and `context` block categories. The `content` object with methods to render sub blocks into content areas. The method name is the same as the area key, for example, 'content.content()` renders a blocks default `content` area.
|
|
127
|
-
- `events: object`: All events defined on the block in the Lowdefy app config.
|
|
128
|
-
- `[event_key]: object`: Event keys gives a handle name to the event details.
|
|
129
|
-
- `loading: boolean`: True while the list of actions are being executed.
|
|
130
|
-
- `actions: actionObjects[]`: The list of [Lowdefy action objects](https://docs.lowdefy.com/events-and-actions) which will be evaluated by the Lowdefy engine.
|
|
131
|
-
- `history: object[]`: A list of objects logging the event calls and responses.
|
|
132
|
-
- `blockId: string`: The block id from which the event was called.
|
|
133
|
-
- `endTimestamp: datetime`: Timestamp for when the event was completed.
|
|
134
|
-
- `event: object`: The event object passed to the event.
|
|
135
|
-
- `eventName: string`: The event name which which triggerEvent was called.
|
|
136
|
-
- `success: boolean`: True if all actions for the event executed without throwing any errors.
|
|
137
|
-
- `startTimestamp: datetime`: Timestamp for when the event was started.
|
|
138
|
-
- `responses: object`: The list of action responses, where the object key is equal to the action id.
|
|
139
|
-
- `{{ key }}: string`:
|
|
140
|
-
- `type: string`: The type of action called.
|
|
141
|
-
- `error: Error`: If the action throw an error.
|
|
142
|
-
- `index: number`: Index of the action in the event array.
|
|
143
|
-
- `response: any`: The returned result of the action.
|
|
144
|
-
- `skipped: boolean`: True if the action was skipped.
|
|
145
|
-
- `methods: object`: All application methods built into Lowdefy, available for the block.
|
|
146
|
-
- `makeCssClass(cssObject | cssObject[]): string`: This methods creates a css class for the block to apply to DOM elements. Css classes are created using [Emotion](https://emotion.sh/docs/introduction). If a list of cssObject are given the cssObjects are shallow merged with the preceding objects properties being overwritten by the latter. Any valid css style object can be passed, including media queries. Default media queries are built in:
|
|
147
|
-
- `xs?: object`: Css object applied for screen media with max width of 576px.
|
|
148
|
-
- `sm?: object`: Css object applied for screen media with min width of 576px.
|
|
149
|
-
- `md?: object`: Css object applied for screen media with min width of 768px.
|
|
150
|
-
- `lg?: object`: Css object applied for screen media with min width of 992px.
|
|
151
|
-
- `xl?: object`: Css object applied for screen media with min width of 1200px.
|
|
152
|
-
- `xxl?: object`: Css object applied for screen media with min width of 1600px.
|
|
153
|
-
- `registerEvent(event: { name: string, actions: actionObjects[] })`: This method can be used to register internal actions for the block to trigger, and overwrites the user config if user defined actions are provided for the same event name.
|
|
154
|
-
- `registerMethod(methodName: string, fn(any))`: This method allows the block developed to expose a method to the Lowdefy app developer via the [`CallMethod`](https://docs.lowdefy.com/CallMethod) action. When the method name for the block id is triggered via a `CallMethod` action, `fn` is evaluated.
|
|
155
|
-
- `triggerEvent({name: string, event?: any })`: This methods triggers a event when called, like `onClick` for when a button is clicked. Optionally, event data can be passed which will be available inside the event actions through the [`_event`](https://docs.lowdefy.com/_event) operator.
|
|
156
|
-
- `properties: object`: The properties object provides all the block settings defined in the Lowdefy config, operators can be used when defining block properties and evaluated operators are passed to the block. When the evaluated result of these properties change, the block rerenders to display the updated block.
|
|
157
|
-
- `required: boolean`: For blocks of the `input` category, whether or not a input value is required. Required can be defined by operators and the evaluated result is passed to the block. The [`Validate`](https://docs.lowdefy.com/Validate) action will check if the required values are present else raise `validation` errors and suspend further block actions in the event queue.
|
|
158
|
-
- `validation: object`: For blocks of the `input` category, the validation property provides result of `Validate` relevant relevant to the specific block. See [block validation](/blocks) for more details.
|
|
159
|
-
- `status: enum`: The validation status result. Can be `error`, `success` or `warning`. Only validation which results in an `error` status will suspend further block actions in the event queue.
|
|
160
|
-
- `errors: string[]`: The list of error messaged raised whiled block validation was evaluated, for this block.
|
|
161
|
-
- `warnings: string[]`: The list of warnings messaged raised whiled block validation was evaluated, for this block.
|
|
162
|
-
|
|
163
|
-
## Deploying Custom Blocks
|
|
164
|
-
|
|
165
|
-
Both the block metadata and block React component need to be built by webpack and hosted on a publicly accessible static file server. Any Lowdefy app can then load and use the block. You also need to set the `remoteEntryUrl` in `webpack.prod.js` in order to build the correct block meta data, make sure the URL is pointing to where your block is hosted.
|
|
166
|
-
|
|
167
|
-
The easiest way to host your custom block is the deploy the custom block to [npm](https://www.npmjs.com/) and [Unpkg](https://unpkg.com/) will automatically host your block for you on their CDN. Although this option is easy, the cache settings for Unpkg can result in longer load times in some cases which can result in a unreliable user experience. It is thus best to deploy you blocks to your own static file servers.
|
|
168
|
-
|
|
169
|
-
We are working on a Lowdefy blocks CDN to improve this developer experience in the future.
|
|
170
|
-
- _ref:
|
|
171
|
-
path: templates/navigation_buttons.yaml
|
|
172
|
-
vars:
|
|
173
|
-
previous_page_title: Custom Code
|
|
174
|
-
previous_page_id: custom-code
|
|
175
|
-
next_page_title: User authentication
|
|
176
|
-
next_page_id: users-introduction
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# Copyright 2020-2021 Lowdefy, Inc
|
|
2
|
-
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
_ref:
|
|
16
|
-
path: templates/general.yaml.njk
|
|
17
|
-
vars:
|
|
18
|
-
pageId: custom-code
|
|
19
|
-
pageTitle: Custom Code
|
|
20
|
-
section: Concepts
|
|
21
|
-
filePath: concepts/custom-code.yaml
|
|
22
|
-
content:
|
|
23
|
-
- id: warning
|
|
24
|
-
type: Alert
|
|
25
|
-
properties:
|
|
26
|
-
message: |
|
|
27
|
-
SECURITY WARNING: Custom code executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your custom code, make sure that you only load trusted code.
|
|
28
|
-
type: warning
|
|
29
|
-
- id: md1
|
|
30
|
-
type: MarkdownWithCode
|
|
31
|
-
properties:
|
|
32
|
-
content: |
|
|
33
|
-
Lowdefy runs as a single page web app (SPA). It is possible to extend the functionality of a Lowdefy app by loading custom code (HTML, CSS and JavaScript) into the HTML `head` and `body` to of the default `index.html` page.
|
|
34
|
-
|
|
35
|
-
The content loaded into the `head` and `body` tag can be any valid HTML, most often `script` tags are loaded to register a new [`JsAction`](/JsAction) or [`_js`](/_js) operator. However, third party code can also be imported, for example Google Analytics, Intercom, etc. Be sure to only load trusted code into your app, as this code will be able to execute JavaScript on all pages of your Lowdefy app, which could expose you app or data to security vulnerabilities. Your own code can easily be hosted from the [Lowdefy public folder](/hosting-files).
|
|
36
|
-
|
|
37
|
-
> __Warning__: Lowdefy implements the [Ant design](https://ant.design/) UI component framework for app layout and most blocks, thus the default Ant Design CSS is loaded for all Lowdefy apps. Take caution not to unintentionally overwrite existing style settings and classes which can result in a degraded user experience.
|
|
38
|
-
|
|
39
|
-
## Schema to load custom code
|
|
40
|
-
|
|
41
|
-
- `app.html.appendHead: string`: Any valid HTML content can be loaded just before the `</head>` tag of the Lowdefy app `index.html` file.
|
|
42
|
-
- `app.html.appendBody: string`: Any valid HTML content can be loaded just before the `</body>` tag of the Lowdefy app `index.html` file.
|
|
43
|
-
|
|
44
|
-
Most often it is convenient to abstract this HTML out to a separate file using the [`_ref`](/_ref) operator.
|
|
45
|
-
|
|
46
|
-
> __Warning__: Code imported using `appendHead` or `appendBody` will be loaded, and can execute JavaScript on every page of your Lowdefy app.
|
|
47
|
-
|
|
48
|
-
#### Examples
|
|
49
|
-
|
|
50
|
-
###### Loading third party code snippet like Google Analytics:
|
|
51
|
-
|
|
52
|
-
To add [Google Analytics](/https://developers.google.com/analytics/devguides/collection/analyticsjs) to a Lowdefy app, the `lowdefy.yaml` can be setup with:
|
|
53
|
-
|
|
54
|
-
```yaml
|
|
55
|
-
name: google-analytics-example
|
|
56
|
-
lowdefy: 3.23.2
|
|
57
|
-
# ...
|
|
58
|
-
app:
|
|
59
|
-
html:
|
|
60
|
-
appendHead: |
|
|
61
|
-
<!-- Google Analytics -->
|
|
62
|
-
<script>
|
|
63
|
-
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
64
|
-
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
65
|
-
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
66
|
-
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
67
|
-
|
|
68
|
-
ga('create', 'UA-XXXXX-Y', 'auto');
|
|
69
|
-
ga('send', 'pageview');
|
|
70
|
-
</script>
|
|
71
|
-
<!-- End Google Analytics -->
|
|
72
|
-
# ...
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
###### Load, register and trigger a custom `JsAction` from code in the app `public` folder:
|
|
76
|
-
|
|
77
|
-
This example fetches a list of Todos from [{JSON}placeholder](https://jsonplaceholder.typicode.com/), and updates [state](/context-and-state).
|
|
78
|
-
|
|
79
|
-
1) First, add the JavaScript code to the `public` folder and resister the `JsAction`:
|
|
80
|
-
```js
|
|
81
|
-
// /public/fetchTodos.js
|
|
82
|
-
function async fetchTodos(context, numItems, skip) {
|
|
83
|
-
const data = await fetch('https://jsonplaceholder.typicode.com/todos');
|
|
84
|
-
const todos = await data.json();
|
|
85
|
-
return todos.slice(skip, skip + numItems);
|
|
86
|
-
}
|
|
87
|
-
// Register the JsAction for the Lowdefy app to use.
|
|
88
|
-
window.lowdefy.registerJsAction('fetchTodos', fetchTodos);
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
2) Import the JavaScript as a module into the page:
|
|
92
|
-
```html
|
|
93
|
-
<!-- /header_modules.html -->
|
|
94
|
-
<script type="module" src="/public/fetchTodos.js"></script>
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
3) Set load the custom code into the app header and trigger the action on page load:
|
|
98
|
-
```yaml
|
|
99
|
-
# /lowdefy.yaml
|
|
100
|
-
name: json-todos
|
|
101
|
-
lowdefy: 3.23.2
|
|
102
|
-
app:
|
|
103
|
-
html:
|
|
104
|
-
appendHead:
|
|
105
|
-
_ref: header_modules.html # Load the custom HTML into the header.
|
|
106
|
-
pages:
|
|
107
|
-
- id: todos
|
|
108
|
-
type: PageHeaderMenu
|
|
109
|
-
events:
|
|
110
|
-
onEnter:
|
|
111
|
-
- id: get_todos
|
|
112
|
-
type: JsAction
|
|
113
|
-
params:
|
|
114
|
-
name: fetchTodos # Trigger the custom JavaScript action.
|
|
115
|
-
args:
|
|
116
|
-
- 10 # numItems
|
|
117
|
-
- 0 # skip
|
|
118
|
-
- id: set_todos
|
|
119
|
-
type: SetState
|
|
120
|
-
params:
|
|
121
|
-
todos:
|
|
122
|
-
# Set the response of the get_todos action to state.
|
|
123
|
-
_actions: get_todos.response
|
|
124
|
-
# ...
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Loading and registering a [`_js`](/_js) operator
|
|
128
|
-
|
|
129
|
-
Similar to the loading custom JavaScript actions, custom JavaScript operators can also be loaded. In order for the Lowdefy app engine to execute a custom JavaScript [operator](/operators), the JavaScript code for the operator must be loaded onto the page and registered using the `registerJsOperator` method available on the browser [`window`](https://developer.mozilla.org/en-US/docs/Web/API/window) object by calling `window.lowdefy.registerJsOperator(name: string, action: function)`.
|
|
130
|
-
|
|
131
|
-
All `_js` functions must be synchronous.
|
|
132
|
-
|
|
133
|
-
#### Examples
|
|
134
|
-
|
|
135
|
-
###### Load, register and use a custom `_js` operator from code in the app `public` folder:
|
|
136
|
-
|
|
137
|
-
This example uses a `_js` operator to remove all duplicates from a list of names.
|
|
138
|
-
|
|
139
|
-
1) First, add the JavaScript code to the `public` folder and resister the `_js` operator:
|
|
140
|
-
```js
|
|
141
|
-
// /public/foo_operators.js
|
|
142
|
-
function removeDuplicates(items) {
|
|
143
|
-
return [ ...new Set(items) ];
|
|
144
|
-
}
|
|
145
|
-
// Register the removeDuplicates function as a _js.deduplicate operator.
|
|
146
|
-
window.lowdefy.registerJsOperator('deduplicate', removeDuplicates);
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
2) Import the JavaScript as a module into the page:
|
|
150
|
-
```html
|
|
151
|
-
<!-- /header.html -->
|
|
152
|
-
<script type="module" src="/public/foo_operators.js"></script>
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
3) Set load the custom code into the app header and use the new operator on the page:
|
|
156
|
-
```yaml
|
|
157
|
-
# /lowdefy.yaml
|
|
158
|
-
name: operator-example
|
|
159
|
-
lowdefy: 3.23.2
|
|
160
|
-
app:
|
|
161
|
-
html:
|
|
162
|
-
appendHead:
|
|
163
|
-
_ref: header.html # Load the custom HTML into the header.
|
|
164
|
-
pages:
|
|
165
|
-
- id: some_names
|
|
166
|
-
type: PageHeaderMenu
|
|
167
|
-
blocks:
|
|
168
|
-
- id: names
|
|
169
|
-
type: ButtonSelector
|
|
170
|
-
properties:
|
|
171
|
-
title: Select your new friend
|
|
172
|
-
options:
|
|
173
|
-
# use the removeDuplicates function and pass a list of names as a function argument
|
|
174
|
-
_js.deduplicate:
|
|
175
|
-
- - Anne
|
|
176
|
-
- Sam
|
|
177
|
-
- Joe
|
|
178
|
-
- Micheal
|
|
179
|
-
- Sam
|
|
180
|
-
- Steven
|
|
181
|
-
- Anne
|
|
182
|
-
- Pepper
|
|
183
|
-
# ...
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
------
|
|
187
|
-
|
|
188
|
-
Custom code provides an easy way to extent the logic functionality of Lowdefy apps. However, to extend the UI capabilities beyond the existing features provided by the default Lowdefy blocks, custom blocks can be loaded onto apps.
|
|
189
|
-
|
|
190
|
-
- _ref:
|
|
191
|
-
path: templates/navigation_buttons.yaml
|
|
192
|
-
vars:
|
|
193
|
-
previous_page_title: Lists
|
|
194
|
-
previous_page_id: lists
|
|
195
|
-
next_page_title: Custom Blocks
|
|
196
|
-
next_page_id: custom-blocks
|