mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-23 14:39:32 +08:00
Merge pull request #439 from lowdefy/docs-concepts
fix(docs): Add concepts pages for lists, secrets and deployment.
This commit is contained in:
commit
3cb539b34a
80
packages/docs/concepts/deployment.yaml
Normal file
80
packages/docs/concepts/deployment.yaml
Normal file
@ -0,0 +1,80 @@
|
||||
# Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
_ref:
|
||||
path: templates/general.yaml.njk
|
||||
vars:
|
||||
pageId: deployment
|
||||
pageTitle: Deployment
|
||||
section: Concepts
|
||||
filePath: concepts/deployment.yaml
|
||||
content:
|
||||
- id: md1
|
||||
type: MarkdownWithCode
|
||||
properties:
|
||||
content: |
|
||||
Lowdefy apps can be deployed to the following hosting platforms:
|
||||
|
||||
- Netlify
|
||||
|
||||
## Deploy to Netlify
|
||||
|
||||
#### Step 1
|
||||
|
||||
Your project will need to be hosted as a Github repository.
|
||||
|
||||
#### Step 2
|
||||
|
||||
Link your Github project to Netlify.
|
||||
|
||||
- Once logged in to Netlify, click the "New site from git" button.
|
||||
- Choose Github, and authorise Netlify to access your repositories.
|
||||
- Select your repository.
|
||||
|
||||
> If your repository isn't found, click "Configure Netlify on Github", and give Netlify access to your repository.
|
||||
|
||||
#### Step 3
|
||||
|
||||
Configure your Netlify deployment.
|
||||
|
||||
- Set your build command to `npx @lowdefy/cli build-netlify`.
|
||||
- Set your publish directory to `.lowdefy/publish`.
|
||||
- Review the other settings, and deploy your site.
|
||||
|
||||
> Your site won't work yet. You first need to configure the Lowdefy backend server in the next step.
|
||||
|
||||
#### Step 4
|
||||
|
||||
Configure the Lowdefy backend server.
|
||||
|
||||
- Click the "Site settings" button.
|
||||
- Choose the "Functions" section in the left menu.
|
||||
- Edit the settings and set your functions directory to `.lowdefy/functions`.
|
||||
|
||||
#### Step 5
|
||||
|
||||
Redeploy your site.
|
||||
|
||||
- Go to the "Deploys" tab.
|
||||
- Click the "Trigger deploy" button and deploy your site.
|
||||
- Wait for you site to finish deploying.
|
||||
|
||||
On the "Site overview" tab you will find your site url.
|
||||
- _ref:
|
||||
path: templates/navigation_buttons.yaml
|
||||
vars:
|
||||
previous_page_title: Secrets
|
||||
previous_page_id: secrets
|
||||
next_page_title: Lists
|
||||
next_page_id: lists
|
154
packages/docs/concepts/lists.yaml
Normal file
154
packages/docs/concepts/lists.yaml
Normal file
@ -0,0 +1,154 @@
|
||||
_ref:
|
||||
path: templates/general.yaml.njk
|
||||
vars:
|
||||
pageId: lists
|
||||
pageTitle: Lists
|
||||
section: Concepts
|
||||
filePath: concepts/lists.yaml
|
||||
content:
|
||||
- id: md1
|
||||
type: MarkdownWithCode
|
||||
properties:
|
||||
content: |
|
||||
List category blocks render multiple [`content areas`](/layout), based on data in the [`state`](/context-and-state) object.
|
||||
|
||||
Since the content area might contain input blocks, the block has an array value in state, with it's `block id` as key. For each item in the array, an content area (or set of content areas is rendered). Multiple list blocks can be nested.
|
||||
|
||||
### List indices and block ids
|
||||
|
||||
If a block is to be rendered in an list's content area, the block id should contain a list index placeholder (specified with the `$` symbol) for each list it is a part of. These placeholders will be populated with the blocks `list indices`. The `list indices` are a array of integers, indicating at which position in the list the block is, for each level of list blocks (zero indexed). The block id should be in valid dot-notation once the placeholders have been substituted.
|
||||
|
||||
This can be made more clear with a example. Suppose we have a list block with id `contacts`. Inside this list we have a text input block for the contact name. We would like our state to look like:
|
||||
```yaml
|
||||
contacts:
|
||||
- name: Name 1
|
||||
- name: Name 2
|
||||
```
|
||||
|
||||
The id for the text input block should be `contacts.$.name`. Each text input block will be given an indexed id based on it's position in the contacts list (`contacts.0.name`, `contacts.1.name`, etc.).
|
||||
|
||||
Suppose we also want to add a emails array for each contact. To do this, we can add another list block in the `contacts` array, and add a text input inside the emails array. If we want the emails to be a array of strings, i.e. our `state` should look like:
|
||||
|
||||
```yaml
|
||||
contacts:
|
||||
- name: Name 1
|
||||
emails:
|
||||
- email1@example.com
|
||||
- email2@example.com
|
||||
- name: Name 2
|
||||
emails: []
|
||||
```
|
||||
|
||||
our config should look like:
|
||||
```yaml
|
||||
id: contacts
|
||||
type: ControlledList
|
||||
properties:
|
||||
# ...
|
||||
blocks:
|
||||
- id: contacts.$.name
|
||||
type: TextInput
|
||||
properties:
|
||||
# ...
|
||||
- id: contacts.$.emails
|
||||
type: ControlledList
|
||||
properties:
|
||||
# ...
|
||||
blocks:
|
||||
- id: contacts.$.emails.$
|
||||
type: TextInput
|
||||
properties:
|
||||
# ...
|
||||
```
|
||||
|
||||
Note that the id of the emails list block is `contacts.$.emails` and that it has one `$` placeholder since it is inside the `contacts` list, and the id of the email text input is `contacts.$.emails.$`, which has two `$` placeholders since it is in both the `contacts` and `contacts.$.emails` lists.
|
||||
|
||||
The ids of the `contacts.$.emails.$` text input blocks will look like `contacts.0.emails.3` or `contacts.2.emails.1`, and this will result in the `state` where the emails on a contact are an array of strings.
|
||||
|
||||
### List indices in operators
|
||||
|
||||
List indices are also supported in "getter" operators like `_state`. If the operator is given a key that contains `$` placeholders, and the operator is called from a block with list indices, the placeholders will be populated with the blocks list indices. These indices are populated on `actions` called by the block, and are even populated in `connections` and `requests` if the block that triggered the `Request` action has list indices. This can be used to get values from the `state` array the block is a part of, or even values from another array at the same index.
|
||||
|
||||
### List block methods
|
||||
|
||||
List blocks can provide methods to change their values. These are
|
||||
|
||||
#### `pushItem`
|
||||
Add an item at the end of the list.
|
||||
|
||||
#### `unshiftItem`
|
||||
Add an item at the start of the list.
|
||||
|
||||
#### `removeItem`
|
||||
Remove an item at the specified index.
|
||||
|
||||
#### `moveItemDown`
|
||||
Move the item at the specified index one position to the start of the list. If the item is at the start if the list, the item remains at position `0`.
|
||||
|
||||
#### `moveItemUp`
|
||||
Move the item at the specified index one position to the end of the list. If the item is at the end if the list, the item remains at it's position.
|
||||
|
||||
#### Example
|
||||
```yaml
|
||||
id: page
|
||||
type: PageHeaderMenu
|
||||
blocks:
|
||||
- id: add_item_at_start
|
||||
type: Button
|
||||
events:
|
||||
onClick:
|
||||
- id: add_item_at_start
|
||||
type: CallMethod
|
||||
params:
|
||||
blockId: list
|
||||
method: unshiftItem
|
||||
- id: add_item_at_end
|
||||
type: Button
|
||||
events:
|
||||
onClick:
|
||||
- id: add_item_at_end
|
||||
type: CallMethod
|
||||
params:
|
||||
blockId: list
|
||||
method: pushItem
|
||||
- id: list
|
||||
type: List
|
||||
blocks:
|
||||
- id: list.$.move_item_down
|
||||
type: Button
|
||||
events:
|
||||
onClick:
|
||||
- id: move_item_down
|
||||
type: CallMethod
|
||||
params:
|
||||
blockId: list
|
||||
method: moveItemDown
|
||||
args:
|
||||
- _index: 0 # Get the first index in the indices array
|
||||
- id: list.$.move_item_up
|
||||
type: Button
|
||||
events:
|
||||
onClick:
|
||||
- id: move_item_up
|
||||
type: CallMethod
|
||||
params:
|
||||
blockId: list
|
||||
method: moveItemUp
|
||||
args:
|
||||
- _index: 0
|
||||
- id: list.$.remove_item
|
||||
type: Button
|
||||
events:
|
||||
onClick:
|
||||
- id: remove_item
|
||||
type: CallMethod
|
||||
params:
|
||||
blockId: list
|
||||
method: removeItem
|
||||
args:
|
||||
- _index: 0
|
||||
```
|
||||
|
||||
### Lists and state
|
||||
|
||||
List blocks create a content area for each item in `state`. If `state` is updated, the list block will also update, creating or destroying content areas as necessary. Thus list blocks can also be manipulated by setting `state` directly using the [`SetState`](/SetState) operator.
|
@ -33,3 +33,10 @@ _ref:
|
||||
# Build time operators
|
||||
|
||||
The `_ref` and `_var` operators do not work like other operators. They are evaluated while an app is being built, and can thus be used anywhere in the app configuration. They are used to split a app into multiple files, and to reuse configuration. See [`_ref`](/_ref) for more details.
|
||||
- _ref:
|
||||
path: templates/navigation_buttons.yaml
|
||||
vars:
|
||||
previous_page_title: Events and Actions
|
||||
previous_page_id: events-and-actions
|
||||
next_page_title: Secrets
|
||||
next_page_id: secrets
|
||||
|
56
packages/docs/concepts/secrets.yaml
Normal file
56
packages/docs/concepts/secrets.yaml
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
_ref:
|
||||
path: templates/general.yaml.njk
|
||||
vars:
|
||||
pageId: secrets
|
||||
pageTitle: Secrets
|
||||
section: Concepts
|
||||
filePath: concepts/secrets.yaml
|
||||
content:
|
||||
- id: md1
|
||||
type: Markdown
|
||||
properties:
|
||||
content: |
|
||||
The `secrets` object is a object that can be used to securely store sensitive information like passwords and API keys. Secrets can be accessed using the [`_secret`](/_secret) operator.
|
||||
|
||||
The secrets object only exists on the backend server, and therefore the `_secret` operator can only be used in `connections` and `requests`.
|
||||
|
||||
We intend to support multiple secrets strategies in the future (for example AWS Secrets Manager or Docker secrets). Current secrets can only be set with environment variables.
|
||||
|
||||
## Environment variables strategy
|
||||
|
||||
Secrets can be set by creating an environment variable prefixed with `LOWDEFY_SECRET_`. The secret will then be available in the secrets object with the remaining part ot the name as key.
|
||||
|
||||
For example, if the environment variable `LOWDEFY_SECRET_MY_SECRET` is set to `supersecret`, then `_secret: MY_SECRET` will return `supersecret`.
|
||||
|
||||
Only strings can be set as environment variables. To store a object as a secret, the object can be JSON stringified, and parsed using the `_json.parse` operator.
|
||||
|
||||
To store secrets that contain newline characters, the secret can be base64 encoded, and decoded using the `_base64.decode` operator.
|
||||
|
||||
To use secrets in the local development environment, environment variables can be set using a `.env` file. Create a file called `.env` at the root of the project directory. Then set environment variables as:
|
||||
|
||||
```
|
||||
# .env
|
||||
LOWDEFY_SECRET_MY_SECRET=supersecret
|
||||
```
|
||||
|
||||
- _ref:
|
||||
path: templates/navigation_buttons.yaml
|
||||
vars:
|
||||
previous_page_title: Operators
|
||||
previous_page_id: operators
|
||||
next_page_title: Deployment
|
||||
next_page_id: deployment
|
@ -130,6 +130,22 @@ menus:
|
||||
pageId: operators
|
||||
properties:
|
||||
title: Operators
|
||||
- id: secrets
|
||||
type: MenuLink
|
||||
pageId: secrets
|
||||
properties:
|
||||
title: Secrets
|
||||
- id: deployment
|
||||
type: MenuLink
|
||||
pageId: deployment
|
||||
properties:
|
||||
title: Deployment
|
||||
- id: lists
|
||||
type: MenuLink
|
||||
pageId: lists
|
||||
properties:
|
||||
title: Lists
|
||||
|
||||
- id: blocks_input
|
||||
type: MenuGroup
|
||||
properties:
|
||||
@ -628,6 +644,10 @@ pages:
|
||||
- _ref: concepts/connections-and-requests.yaml
|
||||
- _ref: concepts/events-and-actions.yaml
|
||||
- _ref: concepts/operators.yaml
|
||||
- _ref: concepts/deployment.yaml
|
||||
- _ref: concepts/secrets.yaml
|
||||
- _ref: concepts/deployment.yaml
|
||||
- _ref: concepts/lists.yaml
|
||||
|
||||
- _ref: blocks/input/AutoComplete.yaml
|
||||
- _ref: blocks/input/ButtonSelector.yaml
|
||||
|
Loading…
Reference in New Issue
Block a user