Initial commit

Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: Michael Cartner <32543275+michaelcartner@users.noreply.github.com>
This commit is contained in:
Eric Tuvesson
2023-09-05 12:08:55 +02:00
commit 53f0d6320e
2704 changed files with 76354 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
### Access Control Rules
When creating and updating records you can also specify access control rules. By default all records created can be read and written by everyone, they are completely public. This is convenient in the beginning when you are working on your applications but as you want to make it publicly available you need to think about access control. You do this by adding access control rules when creating or updating records.
<div className="ndl-image-with-background m">
![](/nodes/data/cloud-data/acl-1.png)
</div>
You can have as many rules as you want. Each rule has a **Target** which can be one of **User**, **Everyone** or **Role**:
- **User** implies that this rule will target a specific user, you can either specify the **User Id** (that is the record Id for the user record) for the user or if omitted the current logged in user will be used.
- **Everyone** means, well, this rule applies to everyone. You can use to to create read only objects, that can be publicly read but not written.
- **Role** means that this object can be accessed as you specify by anyone belonging to a certain role. Please look at the access control [guide](/docs/guides/cloud-data/access-control) for more information.
All rules have the inputs **Read** and **Write** when you specify if the users targeted by the role have read / write access.
Each rule can, depending on the selected **Target** type have the following inputs (it's a good idea to change the label of your rule as in the image above to easier find the inputs when connecting):
| Data | Description |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">User Id</span> | The **User Id** of the user that the rule should apply to. If none is provided via a connection the currently logged in user will be used. This input is only available if the **User** target type is selected. |
| <span className="ndl-data">Role</span> | The **Role Name** of the role that the rule should apply to. This input is only available if the **Role** target type is selected. |
| <span className="ndl-data">Write</span> | Set to **true** for this rule to have write access. |
| <span className="ndl-data">Read</span> | Set to **true** for this rule to have read access. |

View File

@@ -0,0 +1,52 @@
---
hide_title: true
hide_table_of_contents: true
title: Add Record Relation
---
<##head##>
# Add Record Relation
This action node is used to create a relation between two records, the owning record and the target record.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/add-record-relation/add-relation.png)
</div>
One record is the owning record (in this case **Group** records that can have a relation to many **Post** records), it should have a **Relation** type property.
You need to provide the <span className="ndl-data">Id</span> of the owning record. You also need to provide the <span className="ndl-data">Id</span> of the record that you want to add a relation to, this is the Target Record Id input.
Finally, send a <span className="ndl-signal">signal</span> to <span className="ndl-signal">Do</span> to perform the action.
<##head##>
## Inputs
| Data | Description |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | The **Class** of the owning record where you want to add the related object to. |
| <span className="ndl-data">Id</span> | <##input:id##>Specify the **Id** of the record that you want to use as the owning record to add a relation to.<##input##> This input is only valid if **Id Source** is set to **Specify explicitly**. |
| <span className="ndl-data">Relation</span> | You need to choose the **Relation** property of the owning class to use when creating the relation. |
| <span className="ndl-data">Target Record Id</span> | <##input:target record id##>This input should be connected to the **Id** of the target record of the new relation.<##input##> |
@include "./id-source.md"
| Signal | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>When a signal is received on this input the relation will be created in the backend.<##input##> |
## Outputs
| Data | Description |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id</span> | <##output:id##>This is the **Id** of the owning record that have / will receive the new relation. It is simply a mirror of the **Id** input.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>The error message in case something went wrong when attempting to add the relation in the backend.<##output##> |
| Signal | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent on this output when the relation has been added successfully in the backend.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if something went wrong when adding the relation in the backend. The error message will be outputed on the **Error** output.<##output##> |

View File

@@ -0,0 +1,39 @@
---
hide_title: true
hide_table_of_contents: true
title: Cloud File
---
<##head##>
# Cloud File
Represents a file that has been uploaded to the Noodl Cloud Services and stored as a file property in a **Record**.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/cloud-file/cloud-file.png)
</div>
**Cloud File** is typically used in combination with the [Open File Picker](/nodes/utilities/open-file-picker) and the [Upload File](/nodes/data/cloud-data/upload-file) to upload a file and store a reference to it in the database. Then **Cloud File** is used to retrieve the reference and get the URL or Name of the file.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/upload-file/upload-file.png)
</div>
<##head##>
## Inputs
| Data | Description |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Cloud File</span> | <##input:cloud file##>A file that has been stored in the Noodl Cloud Services. Often used in combination with a **Record** to retrieve the **Name** and **URL** of a file.<##input##> |
## Outputs
| Data | Description |
| -------------------------------------- | -------------------------------------------------- |
| <span className="ndl-data">URL</span> | <##output:url##>The URL of the file.<##output##> |
| <span className="ndl-data">Name</span> | <##output:name##>The Name of the file.<##output##> |

View File

@@ -0,0 +1,68 @@
---
hide_title: true
hide_table_of_contents: true
title: Cloud Function
---
<##head##>
# Cloud Function
Cloud functions are logic components that run in the cloud and not on the client like other logic components. The **Cloud Function** node is how you initiate a call to a cloud function component. Learn more about how to use cloud functions in this [guide](/docs/guides/cloud-logic/introduction).
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/cloud-function/cloud-function-1.png)
</div>
You will first need to pick the cloud function that you want to call with this node.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/cloud-function/cloud-function-2.png)
</div>
After you have picked the cloud function, the **Cloud Function** node will receive the input parameters and output result parameters defined in the cloud function so you can hook them up to the logic of your application.
A cloud function can either return a **Success** or **Failure** response, this will result in the corresponding output signal on the **Cloud Function** node. You can use this to trigger different flows in your logic.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/cloud-function/cloud-function-3.png)
</div>
If a **Failure** signal is emitted you can also use the **Error** output that will contain the error message sent from the cloud function.
If a **Success** signal is sent the result parameters will be available as outputs on the **Cloud Function** node.
<##head##>
## Inputs
| Data | Description |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Function</span> | <##input:functionName##>The cloud function component that this node will call.<##input##> |
### Parameters
The **Cloud Function** node will receive all parameters specified in the [Request](/nodes/cloud-functions/request) node in the cloud function component as inputs. When the <span className="ndl-signal">Call</span> signal is received the values on the inputs will be sent to the cloud funciton.
| Signal | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Call</span> | <##input:call##>Send a signal on this input to issue the request to the cloud function.<##input##> |
## Outputs
| Data | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Error</span> | <##output:error##>If the cloud function results in an error status, this output will contain the error message. <##output##> |
### Result
The **Cloud Function** node will receive all result parameters specified in any [Response](/nodes/cloud-functions/response) node in the cloud function component that is called. When the cloud function completes and retuns a **Sucess** status, any result parameters sent back will be available on these outputs.
| Signal | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>This is sent if the cloud function returns a **Success** status.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>This is sent if the cloud function returns a **Failure** status.<##output##> |

View File

@@ -0,0 +1,77 @@
---
hide_title: true
hide_table_of_contents: true
title: Config
---
<##head##>
# Config
This node is used to fetch a configuration parameter from the cloud services. Can be used to store any sort of parameters like API Keys, email templates etc. The node works much like the [Variable](/nodes/data/variable/variable-node) node.
<div className="ndl-image-with-background xl">
![](/nodes/data/cloud-data/config/config-node.png)
</div>
You pick a **Parameter** in the properties of the node. First you must specify the **Parameter** in the **Config** section of the cloud services dashboard. Check out [this guide](/docs/guides/cloud-data/creating-a-backend) for more details on the dashboard.
<div className="ndl-image-with-background xl">
![](/nodes/data/cloud-data/config/config-dashboard.png)
</div>
<##head##>
When creating a parameter you can specify if it requires the **Master Key** or not. Requiring the master key means that you can only access these parameters in cloud functions, which is important for config parameters that needs to be kept secure.
Once you have create your parameters in the cloud services dashboard you can pick which parameter this node should read with the drop down.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/config/config-props.png)
</div>
## Local Override
Config parameters are especially useful when you need to have values that vary depending if you are working in your **testing** or **production** environment (which cloud service you are currently using). You can also specify a local override for a config parameter so that **this particular node** will return that value when your are working locally with the project. That is, when the working in the editor or when viewing the project in an external browser using the ```localhost``` domain.
<div className="ndl-image-with-background xl">
![](/nodes/data/cloud-data/config/config-local.png)
</div>
For the node above we want a special config parameter for when running locally so we can test without having to deploy every time, so we add a **Local Override** in the parameters of the config node.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/config/config-local-props.png)
</div>
## Inputs
| Data | Description |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Parameter</span> | <##input:configKey##>The config parameter to use for this node.<##input##> |
## Local Override
| Data | Description |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Enable</span> | <##input:useDevValue##>Checking this will provide a special value for this node when running in the editor or from ```localhost```<##input##> |
| <span className="ndl-data">Value</span> | <##input:devValue##>The value to return from this node when running in the editor or on ```localhost```<##input##> |
## Outputs
| Data | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Value</span> | <##output:value##>The value for this config parameter for the current active cloud service, or the local override. <##output##> |

View File

@@ -0,0 +1,47 @@
---
hide_title: true
hide_table_of_contents: true
title: Create New Record
---
<##head##>
# Create New Record
This node is used to create a new record of a given class. You specify the class of record to be created in the Property Panel. Sending a <span className="ndl-signal">signal</span> to <span className="ndl-signal">Do</span> will perform the action.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/create-new-record/create-new-record.png)
</div>
You can also provide values for the properties of the record either via connections or by typing the values in the property panel.
<##head##>
## Inputs
| Data | Description |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | Choose a class for the record that you want to create. |
| <span className="ndl-data">Source Object Id</span> | <##input:source object id##>This input can be used to provide an object whose properties will be used as the initial values of the newly created record. <##input##> |
| <span className="ndl-data">Property Inputs</span> | When the class of the record to be created is choosen, all properties of that class will be available as inputs. When the **Do** signal is received a new record will be created with the values of the properties either specified in the property panel or via connections. <##input:prop-\*##>The value of these inputs will become the properties of the newly created record.<##input##> |
| Signal | Description |
| -------------------------------------- | ---------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>Send a signal on this input to create a new record.<##input##> |
@include "./_acl.md"
## Outputs
| Data | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id</span> | <##output:id##>The **Id** of the new record that was created if the action was successful.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>The specific error message in case something went wrong when creating the record.<##output##> |
| Signal | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent here when the new record have been created successfully.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if something went wrong when creating the record.<##output##> You can find the specific error in the **Error** output. |

View File

@@ -0,0 +1,48 @@
---
hide_title: true
hide_table_of_contents: true
title: Delete Record
---
<##head##>
# Delete Record
This node will delete a **Record** of a given **Class** from the Noodl Cloud Services backend.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/delete-record/delete-record-node.png)
</div>
You will need to provide the **Id** of the record to be deleted, there are multiple ways to do this, see the **Id Source** property for details.
Then send a signal on the **Do** input to perform the action.
<##head##>
## Inputs
| Data | Description |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | You need to select the **Class** of records that this node will act on. |
| <span className="ndl-data">Id</span> | <##input:id##>Specify the **Id** of the record that you want to delete.<##input##> This input is only valid if **Id Source** is set to **Specify explicitly**. |
@include "./id-source.md"
| Signal | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>When a signal is received on this input the record will be deleted on the backend.<##input##> |
## Outputs
| Data | Description |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Id</span> | <##output:id##>The **Id** of the record that will be / was deleted by this node. Simply reflecting the **Id** input.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>If something went wrong when deleting the record in the backend, this output will contain the error message.<##output##> |
| Signal | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent on this output when the record have been successfully deleted in the backend.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if something went wrong when attempting to delete the record in the backend.<##output##> |

View File

@@ -0,0 +1,54 @@
---
hide_title: true
hide_table_of_contents: true
title: Filter Record
---
<##head##>
# Filter Record
This node is used to filter an <span className="ndl-data">array</span> that is assumed to contain Records of a given class based on custom filter conditions.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/filter-records/filter-records-node.png)
</div>
You can specify both filter and sorting visually.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/filter-records/filter-records-visual.png)
</div>
<##head##>
## Inputs
| Data | Description |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Enabled</span> | <##input:enabled##>If disabled the node will simply pass the input array through without change, if enabled the input array will be filtered and sorted.<##input##> |
| <span className="ndl-data">Class</span> | The **Class** of records that the input array is assumed to contain. |
| <span className="ndl-data">Use Limit</span> | <##input:use limit##>Enabled or disable limiting of the input array to a specific number of maximum records.<##input##> |
| <span className="ndl-data">Limit</span> | <##input:limit##>The number of maximum records to limit the output filtered array to contain.<##input##> |
| <span className="ndl-data">Skip</span> | <##input:skip##>The number of records in the beginning of the output filtered array to skip.<##input##> |
| <span className="ndl-data">Items</span> | <##input:items##>The input array of records that should be filtered by this node.<##input##> |
| <span className="ndl-data">Filter Parameter Inputs</span> | <##input:fp-\*##>Each filter parameter get an input where a connection can be made to provide the value for the paramter.<##input##> |
| Signal | Description |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Filter</span> | <##input:filter##>Send a signal on this input to perform the filtering, this will produce a new filtered array on the **Items** output. If this input does not have a connection, the input array will be filtered every time it is updated.<##input##> |
## Outputs
| Data | Description |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Items</span> | <##output:items##>This output will contain the filtered array of records.<##output##> |
| <span className="ndl-data">Count</span> | <##output:count##>The number of records in the filtered output array.<##output##> |
| <span className="ndl-data">First Record Id</span> | <##output:first record id##>The **Id** of the first record in the filtered output array.<##output##> |
| Signal | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Filtered</span> | <##output:filtered##>A signal will be sent on this output when the input array have been successfully filtered.<##output##> |

View File

@@ -0,0 +1,5 @@
An Id of a record is needed to perform the action of this node:
| Data | Description |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id Source</span> | The **Id Soure** property specifies how this Id is retrieved, the options are:<br/><br/>`Specify explicitly`: This means you need to specify the Id of the record explicitly through e.g. a connection to the **Id** input.<br/>`From repeater`: This means that the Id for the record will be derived from a repeater. This option is only valid if the component this node is placed in is created by a repeater. Then this node will act on the repeater object that this component was created for. |

View File

@@ -0,0 +1,346 @@
---
hide_title: true
hide_table_of_contents: true
title: Query Records
---
<##head##>
# Query Records
This node is used to fetch a selection of records from the Noodl Cloud Services backend. You can provide a query to define the selection of records you want to retrieve.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/query-records/query-records-node.png)
</div>
You can specify the query using filter, sorting and limit in the Property Panel.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/query-records/query-records-filter-1.png)
</div>
<##head##>
## Filters
By default the **Query Records** will fetch all **Records**, you can however add a filter. You can choose from a simple filter where you can filter on one or more **Record** properties, or a more advanced JSON based filter syntax, that also can include Javascript logic.
### Simple Filters
The **Simple** filters are created through a UI where you select properties and how to filter them in the filter panel.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/query-records/query-records-filter-2.png)
</div>
Note that you can select if you want the filter to use a static value or a value that comes from an input.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/query-records/query-records-filter-3.png)
</div>
### Sorting with Simple Filters
By default the **Query Records** does not return the result of a fetch sorted. You can specify sorting. Like filters you add which properties you want to sort on.
For each property you can choose the sorting order.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/query-records/query-records-sorting-1.png)
</div>
## Limit
Be default up to a 1000 records are returned. But you can specify a **Limit**, the number of records to return, and **Skip**, at what index to start returning records. This is very useful for pagination when listing records.
<div className="ndl-image-with-background m">
![](/nodes/data/cloud-data/query-records/query-records-limit.png)
</div>
## Total Count
If you choose to limit the returned records or if you have more than the maximum allowed return records you can request the total count to be returned with your query.
<div className="ndl-image-with-background m">
![](/nodes/data/cloud-data/query-records/query-records-total-count.png)
</div>
By enabling this you will provide the total count on the <span class="ndl-data">Total Count</span> output.
## Advanced filters
If you choose _Advanced_ as filter type you will get the option to specify a filter script. This is regular javascript code but you need to end the script by calling the _where_ function with the filter definition provided. This is done using the following syntax:
```javascript
where({
Completed: { equalTo: true },
});
```
The above filter will return all **Records** in the collection that has the _Completed_ property _true_. You can select from a number of operators:
- **lessThan** Less Than
- **lessThanOrEqualTo** Less Than Or Equal To
- **greaterThan** Greater Than
- **greaterThanOrEqualTo** Greater Than Or Equal To
- **equalTo** Not Equal To
- **notEqualTo** Not Equal To
- **containedIn** Contained In
- **notContainedIn** Not Contained in
- **exists** A value is set for the key
- **matchesRegex** Check if a value matches a regex pattern
- **text** Text search in one or several columns using a text index
- **idEqualTo** Match the id of the item to a specific id
- **idContainedIn** Check if the id of the item matches an id in an array of ids
- **pointsTo** Check if the id of the item matches an id in an array of ids
- **relatedTo** Checks if the item is related to another item, through a _relation_
For instance, to filter on if a certain property (in this example Letter) is one of many possible values:
```javascript
where({
Letter: { containedIn: ["A", "B", "C"] },
});
```
Or to filter all **Records** that have a value set for a specific property:
```javascript
where({
Letter: { exists: true },
});
```
You can also combine these filters into expressions using **and** and **or**, for instance:
```javascript
where({
and: [{ ZipCode: { exists: true } }, { Score: { greaterThan: 10 } }],
});
```
You can also use the **matchesRegex** operator to filter by regular expression, this is generally slow and not recommended for large sets. Learn more [here](https://docs.mongodb.com/manual/reference/operator/query/regex/)
```javascript
where({
SomeString: { matchesRegex: "pattern", options: "i" },
});
```
As mentioned above the filter script is a javascript function so you can provide javascript code if you like:
```javascript
where({
SomeDate: { equalTo: new Date() },
});
```
You can also specify variables instead of explicitly specifying the filter values, this will create an input port on the _Query Collection_ node that can then be connected to. You specify variables simply by using the **Inputs** object. The filter below will create an input called MyStringInput.
```javascript
where({
SomeString: { equalTo: Inputs.MyStringInput },
});
```
You can also do text search in strings. This will create an index in the database and text search only works on one property so you have to choose wisely. Also text search matches whole words and must be the first filter in an _and_ or _or_ sequence.
```javascript
where({
SomeString: { text: { search: Inputs.MyStringInput } },
});
```
You can also toggle case sensitivity for text searches.
```javascript
where({
SomeString: {
text: {
search: {
term: Inputs.MyStringInput,
caseSensitive: true,
},
},
},
});
```
If you need to match the _Id_ of **Records** in the collection you need to use the special operation:
```javascript
where({
idEqualTo: Inputs.TheRecordId,
});
```
In the above filter you can connect a _Record Id_ output to the _TheRecordId_ parameter to fetch just one specific object. You can also request a set of object based on their Id.
```javascript
where({
idContainedIn: [Inputs.FirstObjectId, Inputs.SecondObjectId],
});
```
Some properties in your _Records_ can be of _Pointer_ type, that means that they reference another **Records** with a specific _Id_. If you want to filter out **Records** that point to a specific **Records**, use this syntax. Let's say you have a collection of _Post_ **Records**, each have a set of _Comment_ **Records** where each _Comment_ points back to it's owning _Post_ via the _Owner_ property. The filter below will find all _Comments_ for a _Post_ given that you provide the post id.
```javascript
where({
Owner: { pointsTo: Inputs.MyPostId },
});
```
You can also provide an array if you want to find _Comments_ that are related to a set of _Post_ **Records**.
```javascript
where({
Owner: { pointsTo: [Inputs.MyFirstPostId, Inputs.MySecondPost] },
});
```
Don't forget that you need to send a signal to _Fetch_ to perform a new fetch with a new filter if any of the filter inputs have changed.
**Records** also support many-to-many relationships via _Relations_. <!-- , check out the guide [here](/guides/relations) for more information. --> You can filter our all **Records** in the collection you are querying that are related to a specific **Record** via a _Relation_ with a given key using:
```javascript
where({
relatedTo: { id: Inputs.MyRecordWithARelation, key: "the-relation-key" },
});
```
### Geo queries
Noodl allows you to associate real-world latitude and longitude coordinates with an object. Using a **GeoPoint** property type in a class allows queries to take into account the proximity of an object to a reference point. This allows you to easily do things like find out what user is closest to another user or which places are closest to a user.
If you have a **Record** with a **GeoPoint** type property called **Location** you can use these queries, first `nearSphere`, it will return results ordered by the distance from the specified `latitude` and `longitude` point.
```javascript
where({
Location: {
nearSphere: {
latitude: 48.0,
longitude: -110.1,
},
},
});
```
You can also specify a maximum distance from the center point by using either `maxDistanceInMiles` or `maxDistanceInKilometers`, e.g.
```javascript
where({
Location: {
nearSphere: {
latitude: 48.0,
longitude: -110.1,
maxDistanceInKilometers: 100,
},
},
});
```
Another option is to query only records with **Location** that are within a certain rectangular bounding box. This makes it possible to query for the set of records that are contained within a particular area. It's done using the `withinBox` query.
```javascript
where({
Location: {
withinBox: [
{
latitude: 37.71,
longitude: -122.53,
},
{
latitude: 30.82,
longitude: -122.37,
},
],
},
});
```
Its also possible to query for the set of records that are contained within or on the bounds of a polygon. Opened or closed paths are allowed, minimum of 3 points. It's done using the `withinPolygon` query.
```javascript
where({
Location: {
withinPolygon: [
{
latitude: 25.774,
longitude: -80.19,
},
{
latitude: 18.466,
longitude: -66.118,
},
{
latitude: 32.321,
longitude: -64.757,
},
],
},
});
```
### Sorting in advanced filters
To specify the sort order when using advanced filter you run a function called _sort_ in the filter script.
```javascript
where({
// You where filter here
});
sort(["createdAt"]);
```
The sort function takes an array with strings specifying the names of the properties you want to sort by. You can prefix the property name with "-" to specify that you want to sort in descending order instead of the default ascending order.
```javascript
sort(["-Age", "createdAt"]);
```
## Inputs
| Data | Description |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | Select the **Class** for the types of records this node should query. When the **Class** is selected you can create filters and sorting based on the properties of the **Class**. |
| <span className="ndl-data">Filter</span> | This specifies the type of filter, you can choose from:<br/><br/>`Visual`: Specify your filter using the visual filter editor.<br/>`JavaScript`: Specify your filter using JavaScript (this is more flexible and you can create more dynamic queyries but it's also more complex) |
| <span className="ndl-data">Use Limit</span> | <##input:use limit##>Enable or disable the use of limit, i.e. that you can specify how many records are returned as a maximum and if a number of record should be skipped.<##input##> |
| <span className="ndl-data">Limit</span> | <##input:limit##>The maximum number of records to be returned by the backend.<##input##> |
| <span className="ndl-data">Skip</span> | <##input:skip##>This property allows you to skip a number of records from being returned by the backend. Using **Skip** and **Limit** allows you to do paging, e.g. return records from 10-20.<##input##> |
| <span className="ndl-data">Fetch Total Count</span> | <##input:storageEnableCount##>Enable this to also query for the total count of records matching the filters. Even if you limit the returned result. <##input##> |
| <span className="ndl-data">Query Parameters</span> | <##input:qp-\*##>The input for specifying the value of a query parameter.<##input##> Each paramteter used in your query will get an input where you can provide a value through a connection.<##input##> |
| Signal | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>Send a signal here to perform the query and fetch matching records from the backend.<##input##> |
## Outputs
| Data | Description |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Items</span> | <##output:items##>The result of the query as an array of **Records**.<##output##> |
| <span className="ndl-data">Count</span> | <##output:count##>The number of records in the result.<##output##> |
| <span className="ndl-data">First Record Id</span> | <##output:first record id##>The Id of the first Record in the result array.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>This output contains the error message incase something when wrong when executing the query.<##output##> |
| <span className="ndl-data">Total Count</span> | <##output:storageTotalCount##>If **Fetch Total Count** is enabled then this output will contain the total number of records that match the query. Even if you limit the returned result.<##output##> |
| Signal | Description |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent here if the query was successful and the result is ready.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent here if something went wrong with the query. You can find the error message via the **Error** output.<##output##> |

View File

@@ -0,0 +1,50 @@
---
hide_title: true
hide_table_of_contents: true
title: Record
---
<##head##>
# Record
This node is used to read data from a **Record**. A **Record** is an **Object** with a **Class**, with predefined properties of specific types and that can be stored in the Noodl backend.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/record/record-node.png)
</div>
You have to choose the class for the **Record** node in the property panel and you must make sure that the node has the Id of the record it should access (there are multiple ways to do this, see full docs for details).
Then you can access the properties of the specific **Record** through the property outputs.
<##head##>
## Inputs
| Data | Description |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | Select the **Class** for this Records that this node will get data from. Choosing the **Class** will make the node get all properties of the class as outputs. |
| <span className="ndl-data">Id</span> | <##input:id##>The Id of the **Record** that this node should read data from.<##input##> |
@include "./id-source.md"
| Signal | Description |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Fetch</span> | <##input:fetch##>Send a signal on this input to fetch the data for this **Record** from the backend. All **Record** nodes that share the **Id** with this node (i.e. are reading data from the same record) will be updated.<##input##> |
## Outputs
| Data | Description |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id</span> | <##output:id##>The Id of the **Record** this node is accessing the properties for.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>This will contain the error message if a fetch action failed and the **Failure** signal was emitted.<##output##> |
| <span className="ndl-data">Class Properties</span> | <##output:prop-\*##>The value of this property in the record that the node reads from.<##output##> This node will have an output for each property in the **Class** that have been selected on the node. |
| Signal | Description |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Fetched</span> | <##output:fetched##>A signal is sent on this output when a **Fetch** has been completed successfully. This is as a result of triggering a fetch by sending a signal to the **Fetch** input.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if a fetch action has failed. This is a potential result of triggering a fetch by sending a signal to the **Fetch** input.<##output##> |
| <span className="ndl-signal">Changed</span> | <##output:changed##>A signal is sent on this output if the record that this node is reading data from has changed locally.<##output##> |
| <span className="ndl-signal">Property Changed Signal</span> | <##output:changed-\*##>A signal is sent here if the value of the property on the record this node is reading data from has changed locally.<##output##> |

View File

@@ -0,0 +1,52 @@
---
hide_title: true
hide_table_of_contents: true
title: Remove Record Relation
---
<##head##>
# Remove Record Relation
This node is used to remove a relation between two records, the owning record and the target record.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/remove-record-relation/remove-relation.png)
</div>
One record is the owning record (in this case **Group** records that can have a relation to many **Post** records), it should have a **Relation** type property.
You need to provide the <span className="ndl-data">Id</span> of the owning record. You also need to provide the <span className="ndl-data">Id</span> of the record that you want to add a relation to, this is the <span className="ndl-data">Target Record Id</span> input.
Finally, send a <span className="ndl-signal">signal</span> to <span className="ndl-signal">Do</span> to perform the action.
<##head##>
## Inputs
| Data | Description |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | The **Class** of the owning record where you want to remove the relation from. |
| <span className="ndl-data">Id</span> | <##input:id##>Specify the **Id** of the record that you want to use as the owning record to remove an existing relation from.<##input##> This input is only valid if **Id Source** is set to **Specify explicitly**. |
| <span className="ndl-data">Relation</span> | You need to choose the **Relation** property of the owning class to use when removing the relation. |
| <span className="ndl-data">Target Record Id</span> | <##input:target record id##>This input should be connected to the **Id** of the target record that have an existing relation to the owning record via the **Relation** property that should be removed.<##input##> |
@include "./id-source.md"
| Signal | Description |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>When a signal is received on this input the relation will be removed in the backend, if it exists.<##input##> |
## Outputs
| Data | Description |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id</span> | <##output:id##>This is the **Id** of the owning record. It is simply a mirror of the **Id** input.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>The error message in case something went wrong when attempting to remove the relation in the backend.<##output##> |
| Signal | Description |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent on this output when the relation has been removed successfully in the backend.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if something went wrong when removing the relation in the backend. The error message will be outputed on the **Error** output.<##output##> |

View File

@@ -0,0 +1,52 @@
---
hide_title: true
hide_table_of_contents: true
title: Set Record Properties
---
<##head##>
# Set Record Properties
This action node will set property values of a record.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/set-record-properties/set-record-properties-node.png)
</div>
You need specify the class of the record in the property panel. Then you can either specify the values of the properties to set in the property panel or by providing them as an input connection.
Send a <span className="ndl-signal">signal</span> to <span className="ndl-signal">Do</span> to perform the action.
<##head##>
## Inputs
| Data | Description |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Class</span> | The class of record for this node. Choosing the class will determine which property inputs that become available on the node. |
| <span className="ndl-data">Store to</span> | <##input:store to##>Specifies if this node should store both to the cloud and locally, or only locally.<##input##> |
| <span className="ndl-data">Properties to store</span> | <##input:properties to store##>Specifies if only the explicitly specified properties should be save, **only specified**, this means that only the properties that have a value either in the property panel or via an input connection will be written to the cloud record. If **All** is selected that means that all properties will always be written, if there is no explicit value provided on this node the value of the object with the corresponding **Id** will be used.<##input##> |
| <span className="ndl-data">Id</span> | <##input:id##>Specify the **Id** of the record that you want to set the properties on.<##input##> This input is only valid if **Id Source** is set to **Specify explicitly**. |
| <span className="ndl-data">Property Inputs</span> | <##input:prop-\*##>The value to set this property to when the action is triggered.<##input##> For each property in the specified class there will be an input of the correct type. You can provide the values for the inputs either through connections or by specifying them in the property panel. |
@include "./id-source.md"
| Signal | Description |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | <##input:do##>When a signal is received on this input the properties will be set on the record.<##input##> |
@include "./_acl.md"
## Outputs
| Data | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Id</span> | <##output:id##>The **Id** of the record where the properties will be updated by this node.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>The specific error message in case something went wrong when updating the record.<##output##> |
| Signal | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | <##output:success##>A signal is sent here when the record have been updated successfully.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>A signal is sent on this output if something went wrong when updating the record.<##output##> You can find the specific error in the **Error** output. |

View File

@@ -0,0 +1,45 @@
---
hide_title: true
hide_table_of_contents: true
title: Upload File
---
<##head##>
# Upload File
This node uploads a file to the Noodl Cloud Services. Can be used in combination with a **Record** to link the file to a property. When retrieving the file reference you can get the **URL** to the file and **Name** of file using a [Cloud File](/nodes/data/cloud-data/cloud-file) node.
<div className="ndl-image-with-background l">
![](/nodes/data/cloud-data/upload-file/upload-file.png)
</div>
<##head##>
## Inputs
| Data | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">File</span> | <##input:file##>An HTML5 [File](https://developer.mozilla.org/en-US/docs/Web/API/File). The [File Picker](/nodes/utilities/open-file-picker) can be used to open a file dialog picker and generate the **File** from a local file. It's also possible to retrieve the File from external sources, or generate it by code. <##input##> |
| Signal | Description |
| ------------------------------------------ | ---------------------------------------------------------- |
| <span className="ndl-signal">Upload</span> | <##input:upload##>Triggers the upload to start.<##input##> |
## Outputs
| Data | Description |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Cloud File</span> | <##output:cloudFile##>A [Cloud File](/nodes/data/cloud-data/cloud-file), which consists of an URL and a file name. Can be connected to a property of a [Record](/nodes/data/cloud-data/record) if the property type is specified as 'File'.<##output##> |
| <span className="ndl-data">Total Bytes</span> | <##output:progressTotalBytes##>The total size of the file in bytes that is being uploaded.<##output##> |
| <span className="ndl-data">Uploaded Bytes</span> | <##output:progressLoadedBytes##>Contains the number of bytes have been uploaded so far. Starts at 0, and moves towards **Total Bytes** after the **Upload** input signal has been triggered. The value is updated each time the **Progress Changed** event is sent.<##output##> |
| <span className="ndl-data">Uploaded Percent</span> | <##output:progressLoadedPercent##>The current percentage of the file that have been uploaded. Starts at 0, and moves towards 100 after the **Upload** input signal has been triggered. The value is updated each time the **Progress Changed** event is sent.<##output##> |
| <span className="ndl-data">Error</span> | <##output:error##>The error message as a string, if the upload fails.<##output##> |
| <span className="ndl-data">Error Status Code</span> | <##output:errorStatus##>An [HTTP error code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status). For example, `413` if the file is too large.<##output##> |
| Signal | Description |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-signal">Progress Changed</span> | <##output:progressChanged##>This event is used to track the upload progress. It is triggered multiple times during an upload when **Uploaded Bytes** and **Uploaded Percent** are updated.<##output##> |
| <span className="ndl-signal">Success</span> | <##output:success##>This event triggers when the file was uploaded successfully.<##output##> |
| <span className="ndl-signal">Failure</span> | <##output:failure##>This event triggers if there was en error uploading the file.<##output##> |