You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: workspaces/building-a-workspace/README.md
+170-53
Original file line number
Diff line number
Diff line change
@@ -26,69 +26,103 @@ Deleting a component may impact other components. If this is the case, you'll be
26
26
27
27
## Understanding how components work
28
28
29
-
### The Text Component
29
+
### Layout & Guidance components
30
30
31
-
Write anything you wish to display, then customize how it's displayed using the style options.
31
+
Components to design your workspace in an intuitive way.
32
32
33
-
###The Action Component
33
+
#### Section component
34
34
35
-
The **Action** component can be used to trigger `global,``single`, and `bulk` Smart Actions as well as CRUD operations. 
35
+
The section component lets you regroup multiple components into a single area.
36
36
37
-
<figure><imgsrc="../../.gitbook/assets/Screenshot 2022-10-05 at 16.56.40.png"alt=""><figcaption></figcaption></figure>
37
+
It enables you to configure the [visibility](./#managing-visibility-of-your-components) for all the components inside only through the Section component.
38
38
39
-
If you've selected an action that requires selected record(s) to apply to, then you'll need to specify a source component:
39
+
It also enable youto drag the components inside altogether.
40
40
41
-
Here we have linked the `action2` component so that when you select a record from the`collection1` component, you'll be able to trigger the _Edit a company_ action in 1 click. 
41
+
#### Tabs Component
42
42
43
-
### The Field Component
43
+
Like the [section component](./#section-component), the tabs components lets you regroup multiple components into a single area, only the active tab components are displayed.
44
44
45
-
The **Field** component lets you read data of a record that you selected in a "source" component. 
45
+
The tabs component can hold between 1 and 10 tabs.
46
+
47
+
#### Text Component
48
+
49
+
Write anything you wish to display, then customize how it's displayed using the style options.
46
50
47
51
{% hint style="info" %}
48
-
**Source** components are components that let you select a record: Collection, Search, Dropdown components can be source components.
52
+
You can add [custom style](./#styling-your-components) on this component.
49
53
{% endhint %}
50
54
51
-
If you have a Collection component in your workspace, make sure its "On row click" option is set to "Select a record": this will allow you to select a record in your table, which in turn feeds the **Field** component. 
55
+
#### Link Component
52
56
53
-
.png>)
57
+
The link component lets you create a link on the workspace. There are 2 modes:
54
58
55
-
In the Field component, select `collection1` as the source and choose which field value you wish to display: here we chose `name`.
59
+
-**Custom**: you can set the url you want, and in this url you can use the value of another component selected record. e.g.: `https://mydomain/posts/{{collection1.selectedRecord.id}}`
60
+
-**Redirect to record**: clicking the link will redirect you on the record's detail page.
56
61
57
-
.png>)
62
+
{% hint style="info" %}
63
+
You can add [custom style](./#styling-your-components) on this component.
64
+
{% endhint %}
58
65
59
-
You may have a more complex use case, where you'd want to display a property further away. To achieve this, you'll have to click the _Toggle to input code_ button:
You can use the horizontal and vertical dividers to create a visual separation between components.
62
69
63
-
For instance, if your collection is `Company` and it is linked to a `Country` collection, you may want to display `{{country.name}}` or even `{{country.headquarter.address}}`.
70
+
{% hint style="info" %}
71
+
You can add [custom style](./#styling-your-components) on this component.
72
+
{% endhint %}
64
73
65
-
#### Widgets & labels
74
+
###Source components
66
75
67
-
Note that you may also choose which [widget](../../collections/customize-your-fields/#list-of-display-widgets) to use to display your field.
76
+
Components to set the context of your workspace.
77
+
78
+
#### Search Component
79
+
80
+
Use the Search component to quickly select a record within a given Collection.
81
+
82
+
You can customize the field used to display the search results.
68
83
69
84
{% hint style="info" %}
70
-
The **(Inherited)** widget will use the same widget used in your Collection settings for this field.
85
+
You can use this component as a source for other components ([Field](./#field-component), [Link](./#link-component), [Text](./#text-component)) or use it in filters.
71
86
{% endhint %}
72
87
73
-
Lastly you may also choose whether to display the label and customize it.
88
+
#### Collection Component
74
89
75
-
### The Search component 
90
+
The collection component lets you visualize your data and select records in a workspace.
91
+
There are 2 types for the collection component, _Collection_ and _Relationship_.
76
92
77
-
Use the Search component to quickly select a record within a given Collection:
93
+
The _Collection_ type behaves as a regular collection in Forest Admin. You can select records, trigger actions, filter and so on.
78
94
79
-
.png>)
95
+
The _Relationship_ type lets you visualize your has-many relationships. To make it work, you need to use another workspace component as the source.
96
+
Let's say you have a user collection, and one user can have multiple documents.
97
+
You can use a search component to search for a user, and use the _Collection Relationship_ component to list all the documents of a selected user.
80
98
81
-
With the above settings, you'll be searching within **all fields** of your `Company` records and displaying the [reference field](../../collections/manage-your-collection-settings.md#general-tab).
99
+
For the 2 types of collection components, you can do the following (independently from the regular collectionsettings):
82
100
83
-
The Search component can then be used in other components like Field ("on record from"), Text, (templating), Collection (templating in filter), Chart (templating in filter), etc.
101
+
- Add a custom filter on the collection
102
+
- Add a custom sorting field and sorting order
103
+
- Customize the displayed columns
104
+
- Reorder the displayed columns
105
+
- Disable the search, or the actions for this component
84
106
85
-
### The Dropdown component 
107
+
{% hint style="info" %}
108
+
You can use this component as a source for other components ([Field](./#field-component), [Link](./#link-component), [Text](./#text-component)) or use it in filters.
109
+
{% endhint %}
110
+
111
+
#### Inbox Component
112
+
113
+
The inbox component lets your operator treat their [inbox](../../other-tabs/collaboration/distribute-tasks-with-inboxes.md) tasks directly from a workspace.
114
+
115
+
{% hint style="info" %}
116
+
You can use this component as a source for other components ([Field](./#field-component), [Link](./#link-component), [Text](./#text-component)) or use it in filters.
117
+
{% endhint %}
118
+
119
+
#### Dropdown Component
86
120
87
121
The Dropdown is a great UI classic. Here's how you can set it up:
88
122
89
123
Choose a mode between "Static", "Dynamic > Simple" and "Dynamic > Smart"
90
124
91
-
#### Static
125
+
#####Static
92
126
93
127
In _Static_ mode, you hard-code values. You may re-order them using the handles.
94
128
@@ -98,13 +132,13 @@ In _Static_ mode, you hard-code values. You may re-order them using the handles.
98
132
_Enable search_ adds a search to your dropdown, making is easier to find values when there are many.
99
133
{% endhint %}
100
134
101
-
#### Dynamic > Simple
135
+
#####Dynamic > Simple
102
136
103
137
In _Simple_ mode, you choose a collection, a field and optionally a filter: this defines the values that will appear in the dropdown.
104
138
105
139
.png>)
106
140
107
-
#### Dynamic > Smart
141
+
#####Dynamic > Smart
108
142
109
143
_Smart_ mode lets you fetch values from an external endpoint.
110
144
@@ -121,40 +155,129 @@ As explained in the tooltip, the expected response format is:
121
155
}
122
156
```
123
157
124
-
### The Metabase component
158
+
#### Date Picker Component
159
+
160
+
The date picker component lets your operator choose a date.
161
+
You can set maximum and / or minimum dates that are enabled.
162
+
163
+
Minimum and maximum dates can be hardcoded or use [templating](./#making-your-components-interact) to get a date from a selected record.
164
+
165
+
You can use the `{{currentDate}}` templating to ensure the selected date is in a good range, for example:
166
+
167
+
- Minimum date: `{{currentDate.subtract.days.1}}`
168
+
- Maximum date: `{{currentDate.add.days.1}}`
169
+
170
+
#### Toggle Component
171
+
172
+
The toggle component can be used as an input, to dynamically filter another source component.
173
+
174
+
You have to pick a value type (String, Number, Boolean, etc..), then set the value the component will have when it has the `toggled on` state. The value of the toggle component is used only when toggled on.
175
+
176
+
Example:
177
+
178
+
Let's say you have a collection component using your **Users** collection. You can add many toggle components to enable quick filtering with combined filters on your collection component.
179
+
180
+
- You can have a _String_ toggle with value "onboarding" to filter the user status.
181
+
- You can have a _Boolean_ toggle with value true to filter on the user `isEmailVerified` field.
182
+
183
+
Or
184
+
185
+
- You can create multiple _Date_ toggle and use the templating for the value, like:
186
+
-`{{currentDate.startOf.months}}`
187
+
-`{{currentDate.subtract.days.15}}`
188
+
-`{{currentDate.startOf.days}}`
189
+
- And use these toggles in a `OR` filter on the collection component
190
+
191
+
#### Input Component
192
+
193
+
The input component is an input.
194
+
195
+
You should use it when you want to dynamically filter a collection or a search component using a text or a number.
196
+
197
+
### Data & Actions
198
+
199
+
Components to interact with your data.
200
+
201
+
#### Action Component
202
+
203
+
The Action component can be used to trigger `global`, `single`, and `bulk` Smart Actions as well as CRUD operations.
204
+
205
+
<figure><imgsrc="../../.gitbook/assets/Screenshot 2022-10-05 at 16.56.40.png"alt=""><figcaption></figcaption></figure>
206
+
207
+
If you've selected an action that requires selected record(s) to apply to, then you'll need to specify a source component:
208
+
209
+
Here we have linked the `action2` component so that when you select a record from the`collection1` component, you'll be able to trigger the _Edit a company_ action in 1 click.
210
+
211
+
#### Field Component
212
+
213
+
The Field component lets you read data of a record that you selected in a [source](./#source-components) component.
214
+
215
+
If you have a Collection component in your workspace, make sure its "On row click" option is set to "Select a record": this will allow you to select a record in your table, which in turn feeds the Field component.
216
+
217
+
.png>)
218
+
219
+
In the Field component, select `collection1` as the source and choose which field value you wish to display: here we chose `name`.
220
+
221
+
.png>)
222
+
223
+
You may have a more complex use case, where you'd want to display a property further away. To achieve this, you'll have to click the _Toggle to input code_ button:
For instance, if your collection is `Company` and it is linked to a `Country` collection, you may want to display `{{country.name}}` or even `{{country.headquarter.address}}`.
228
+
229
+
##### Widgets & labels
230
+
231
+
Note that you may also choose which [widget](../../collections/customize-your-fields/#list-of-display-widgets) to use to display your field.
232
+
233
+
{% hint style="info" %}
234
+
The **(Inherited)** widget will use the same widget used in your Collection settings for this field.
235
+
{% endhint %}
236
+
237
+
Lastly you may also choose whether to display the label and customize it.
238
+
239
+
### Analytics
240
+
241
+
Components to visualize your data.
242
+
243
+
#### Metabase component
125
244
126
245
All you have to do to embed your Metabase dashboard into Forest Admin workspace is to create a new Metabase component and fill in all necesary informations.
This corresponds to the url of your Metabase instance. For example, if your Metabase instance is accessible through https://myanalytics.mycompany.com, then you must set it to the url option.
133
252
134
-
#### Token
253
+
#####Token
135
254
136
255
The token is a JWT token and ensures valid authentication when retrieving the Metabase dashboard. The simplest way to do this is to generate it online using https://token.dev. To sign it, you need to use the METABASE_SECRET_KEY provided by Metabase.
137
256
138
257
You must replace METABASE_DASHBOARD_ID by the correct dashboard ID provided by Metabase.
Here are the parameters that the dashboard can take into account.
151
271
This is a basic query string based input that can interact with workspace context.
152
272
153
273
For example if your dashboard take `projectId` as parameters, you can put the following as option input.
274
+
154
275
```
155
276
projectId=1
156
277
```
278
+
157
279
or
280
+
158
281
```
159
282
projectId={{searchComponent.selectedRecord.id}}
160
283
```
@@ -172,20 +295,12 @@ This opens an autocomplete dropdown which helps you use the correct syntax.
172
295
173
296
Here are some examples:
174
297
175
-
<table><thead><tr><thwidth="340.66545807311365">Templating syntaxe</th><th>Result</th></tr></thead><tbody><tr><td><code>{{collection1.selectedRecord.email}}</code></td><td>Displays the column "email" of the select row of collection1</td></tr><tr><td><code>{{currentUser.fullName}}</code></td><td>Displays the current user's fullname</td></tr><tr><td><code>{{currentUser.email}}</code></td><td>Displays the current user's email</td></tr><tr><td><code>{{currentUser.team}}</code></td><td>Displays the current user's team</td></tr><tr><td><code>{{currentUser.tags.some-tag}}</code></td><td>Displays the current user's value of the tag "some-tag"</td></tr></tbody></table>
298
+
<table><thead><tr><thwidth="340.66545807311365">Templating syntaxe</th><th>Result</th></tr></thead><tbody><tr><td><code>{{collection1.selectedRecord.email}}</code></td><td>Displays the column "email" of the select row of collection1</td></tr><tr><td><code>{{currentUser.fullName}}</code></td><td>Displays the current user's fullname</td></tr><tr><td><code>{{currentUser.email}}</code></td><td>Displays the current user's email</td></tr><tr><td><code>{{currentUser.team}}</code></td><td>Displays the current user's team</td></tr><tr><td><code>{{currentUser.tags.some-tag}}</code></td><td>Displays the current user's value of the tag "some-tag"</td></tr><tr><td><code>{{currentDate.option}}</code></td><td>Displays a date manipulated from the current date</td></tr></tbody></table>
176
299
177
300
{% hint style="success" %}
178
301
If you rename your components, the syntax adjusts automatically in all components using templating.
179
302
{% endhint %}
180
303
181
-
#### Adding related data
182
-
183
-
Templating may also be used **in filters** of the Collection component. In practice, this allows you to recreate a related data collection.
184
-
185
-
.png>)
186
-
187
-
In the example above, we've set up collection1 (`Customer`) and collection2 (`Order`) so that when you click on a **Customer**, it shows **their Orders only** in collection2.
188
-
189
304
#### Filtering charts
190
305
191
306
Templating is also useful within the **Chart** component: you may use other components' data to filter on your chart(s).
@@ -205,14 +320,12 @@ Templating also works within **Query** mode, i.e within your SQL queries, like s
205
320
206
321
.png>)
207
322
208
-
**Bonus**: it's also possible to use templating in the Timeframe property of Time-based charts. This means that you could for instance create a **Dropdown** component with values _Day_, _Week_, _Month_ and _Year_ and using that dropdown would automatically refresh the chart based on the selected timeframe! 
323
+
**Bonus**: it's also possible to use templating in the Timeframe property of Time-based charts. This means that you could for instance create a **Dropdown** component with values _Day_, _Week_, _Month_ and _Year_ and using that dropdown would automatically refresh the chart based on the selected timeframe!
209
324
210
325
This is how you would set it up:
211
326
212
327
.png>)
213
328
214
-
215
-
216
329
## Managing visibility of your components
217
330
218
331
Every component has a `Visible` option - at the bottom of its settings panel - which allows you to control when it is displayed:
@@ -221,29 +334,33 @@ Every component has a `Visible` option - at the bottom of its settings panel - w
221
334
222
335
The default choice is **Always**, but there are 2 other options that we'll explain shortly:
223
336
224
-
* Only when a component is visible
225
-
* Only when dynamic variables are defined / Only when source record is selected
337
+
- Only when a component is visible
338
+
- Only when dynamic variables are defined / Only when source record is selected
226
339
227
340
### Only when a component is visible
228
341
229
-
This lets you basically select another component and make your component visible when that other component is. 
342
+
This lets you basically select another component and make your component visible when that other component is.
230
343
231
344
A pretty basic example of this is if you want to show dividers only if the component they are splitting the view for is visible.
232
345
233
346
Similarly, you can make a Section component hidden unless a component inside of it is displayed.
234
347
235
348
### Only when dynamic variables are defined / Only when source record is selected
236
349
237
-
As covered in the [Making your components interact](./#making-your-components-interact) section above, components can be set up to depend on information from another component, using **templating**. This visibility option makes it so that the component is visible only if information from the other component it depends on is available. 
350
+
As covered in the [Making your components interact](./#making-your-components-interact) section above, components can be set up to depend on information from another component, using **templating**. This visibility option makes it so that the component is visible only if information from the other component it depends on is available.
238
351
239
352
Here's an example:
240
353
241
354
.png>)
242
355
243
-
:point\_up: This is a Collection component (`collection2`) that is filtered on another Collection component (`collection1`). See how the filter contains _dynamic variables_ (a.k.a templating)? Well, choosing the "Only when dynamic variables are defined" option means `collection2` will appear only if a record of `collection1` is selected.
356
+
:point*up: This is a Collection component (`collection2`) that is filtered on another Collection component (`collection1`). See how the filter contains \_dynamic variables* (a.k.a templating)? Well, choosing the "Only when dynamic variables are defined" option means `collection2` will appear only if a record of `collection1` is selected.
244
357
245
358
{% hint style="info" %}
246
359
With the **Always** option, filters containing templating are ignored if undefined.\
247
360
\
248
361
In practice, this means that in the above screenshot, if Visible was set on Always, `collection2` would ignore its filters unless a record from `collection1` is selected.
249
362
{% endhint %}
363
+
364
+
## Styling your components
365
+
366
+
For components with style options, you can change the color, the font, the alignment and the formatting of the displayed text.
0 commit comments