Skip to content

Layout Components

Buttons

Customizing the default Buttons

There are some default buttons present in every system. These Buttons handle basic functions like saving a resource, redirecting to /create and more. You can modify the behaviour of these buttons for each module by defining custom options in the bakery plan module definition.

Code example:

{
"bakery_resource_module": "module_identifier",
"bakery_resource": {
"buttons": {
"button_key": {
"<option>": "<argument>"
}
}
}
}

The keys are:

  • save for default ‘save’ button in create view
  • update for default ‘save’ button in update/edit view
  • continue for default ‘save and continue’ button in update/edit view
  • delete for default ‘delete’ button in show view
  • edit for default ‘edit’ button in show view
  • create for default ‘create’ button in index view
  • excelfor default ‘excel’ button in index view

All buttons can take the following options:

  • display: Boolean (whether to display the button at all. Default: true)
  • title: String (a custom title for the button. will be prefixed with buttons. for translations)
  • trigger: event_identifier (The event identifier to trigger when the button is clicked. this will change the functionality of the button and not trigger the default actions)
  • style: primary|dashed|danger|link|-

All of these options can be used individually or combined.

A note to trigger: if the button_key is save, update or contiune (the buttons in /edit and /create) the current value of any fields will be sent to the prototype output of the event element.

Adding Custom Buttons

You can add custom buttons to the Buttonbar that can trigger any webhook. These Buttons will be shown before other webhook buttons that where auto added by workflow elements using show_in_button_bar: true.

These Buttons are defined the same way and in the same place as customising the default buttons, and they support (mostly) the same options.

There are a few quirks to look out for though:

  • Custom Buttons have to use an identifier that is not one of the keys for default buttons defined above!
  • The display option is ignored and does nothing when defined on custom buttons. Set ‘show_in’ to an empty array if you want to hide a button!
  • If the trigger option is not set, the identifier of the button will be used and treated as a webhook identifier
  • If the title option is not set, the identifier of the button will be used as the translation suffix
  • Ifshow_in is not set, the button will show in every view. If it is set, it will respect the common module modes (e.b. “module.show”)
  • Using the icon option with a valid antd icon identifier changes the icon

Adding Buttons in Lists

You can define buttons in lists that will trigger webhooks with the current entity and field / row information of the clicked button. This enables you to get the specific tuple from the list that’s in the row where the corresponding button was pressed.

These Buttons will only show up in module.show.

The Webhook will receive the field & row information in the selector output. It is an object with two keys.

  • fieldIdentifier <String>: Is the identifier of the list from where the button was triggered.
  • rowIndex <String>: Is the index of the row from where the button was triggered.

Code example for a list field:

{
"identifier": "list_field",
"type": "list",
"options": {
"buttons": [
{
"title": "custom_button",
"trigger": "webhook_identifier",
"icon": "api",
"position": 0
}
],
"fields": [
{
...
}
]
}
}

This Code example will create buttons in the first col of the list that will trigger the webhook webhook_identifier. The translation key of the th element will be buttons.custom_button. The button will show the api icon in the list.

Only the trigger key is required. All other keys are optional.

  • if no title is set, the title will be buttons.webhook_identifier.
  • if no icon is set, a default icon will be used. Only valid antd icon identifiers are supported.
  • if no position is set, the button col will be appended as the last col in the list.

Headline

  • options.identifier: string
  • options.size: small|-
  • options.align: center|-

Text

  • options.identifier: string uses translation key module.texts.identifier
  • options.text: string fallback if no identifier is set (be aware that this can not be translated)
  • options.has_border: boolean whether the text component itself should have an extra border. Useful when using in combination with show_in and in a col with options.borderless: true

Calendar

Option nameTypeDefaultDescription
available_viewsarray<ViewType>['year', 'month', 'week', 'day','list']View types (like “month”, “day”, etc.) that the user can choose from
custom_viewsarray<ViewTypeDef>[]Definitions for custom views
default_viewViewTypemonthDetermines the view that is opened when opening the layout
eventsarray<EventDef>[]The “event types” that this calendar will display
editablebooleantrueDetermines if the events can be edited within the calendar by dragging and resizing
heightstring/int80vhThe height of the calendar
week_numbersbooleanfalseWhether to show week numbers in day grid views (e.g. “month”)
nav_buttonsbooleantrueWhether to show the navigation buttons
filter_sidebarbooleantrueWhether to show the filter sidebar

Events

Option nameTypeDefaultDescription
identifierstringIdentifier of this event type. Used as a translation key.
modulemodule_identifierThe module containing the field defined in the field attribute
fieldfield_identifierThe field identifier of the field that contains the date of an event. This field needs to be of the types date,datetime or dateRange
color#hex#1890ffThe event background color
iconIconAn icon that will be displayed within the event element
quick_createbooleanIf quick creation in calendar view is possible for the event
pre_filtersarray<PreFilter>Filters out entities before displaying
recurrencestring objectDetermines a pattern by which this event will reoccur within the calendar (e.g. monthly). Reference.
text_color#hex#ffffffThe event text color
titlestringThe event title
recipesRecipesRecipes for all event attributes
[
{
"type": "calendar",
"options": {
"availableViews": [
"list7days"
],
"custom_views": {
"list7days": {
"type": "list",
"duration": {
"days": 7
}
}
},
"default_view": "list7days",
"editable": false,
"events": [
{
"identifier": "employeeHoliday",
"module": "holidays",
"field": "dateRange",
"color": "#7db5ff",
"pre_filters": [
{
"column": "employee.id",
"operator": "=",
"recipe": "user().id"
}
],
"recipes": {
"title": "'Birthday: ' + this.employee.name"
}
},
{
"identifier": "employeeBirthdays",
"module": "employees",
"field": "birthdate",
"color": "#4adeff",
"text_color": "rgba(0, 0, 0, 0.85)",
"pre_filters": [
{
"column": "id",
"operator": "=",
"recipe": "user().id"
}
],
"recurrence": "yearly",
"recipes": {
"title": "'Birthday: ' + this.first_name + ' ' + this.family_name"
}
}
],
"height": "50vh",
"navButtons": false,
"filterSidebar": false,
"weekNumbers": true
}
}
]

Fields

See Layout -> Fields


Resource Table

  • module: module_identifier the identifier of the module where resources will be loaded from
  • workflow: webhook_identifier the identifier of the workflow event if you want to use a workflow to fill the resource table
  • pre_filters: array<PreFilterObject> defines prefilters for the table
  • hide_crud_buttons: boolean hides the default ‘read’, ‘edit’, ‘delete’ buttons from the ‘actions’ col
  • buttons: array<Buttons> contains an array with button definitions that will be rendered in the ‘actions’ col
  • selectable: boolean determines if the entries of the table can be selected. Defaults to true.
  • columns: array<string>|ColumnDefarray of columns to be displayed/fetched. By default, all fields (except for list fields) will be shown. Only the visible columns are fetched by default. If needed, the list of fetched columns can be expanded when using aColumnDef` definition.
  • bulk_actions: array<Buttons> array of buttons shown over the resource table that are hidden until an entry is selected.
  • aggregates: array<AggregateDef> defines which aggregates should be loaded to be available in recipes.
  • summary: array<SummaryDef> defines what the “summary”-rows at the bottom of the table should display.
  • options: pageSize : int default number of entities which get shown upon load

An array of IDs of the selected entries, ordered by their position in the table, will be sent to the given webhook event.

Standard actions (currently only deletions) can still be used by using the “action” property.

Options for custom Buttons

  • title: String translation key. will be prefixed with buttons. (title: test) will be passed as buttons.test to the translator.
  • icon: String name of the antd icon type
  • type: primary|secondary|dashed|danger|link antd button type
  • event: String webhook event name that will be triggered on a click. The Event gets the resource the current row represents.
Example of a table with one custom Button and no CRUD Buttons:
{
"type": "resource_table",
"options": {
"module": "module_for_resources",
"hide_crud_buttons": true,
"buttons": [
{
"title": "button_title_translation_key",
"icon": "ant_icon_name",
"type": "ant_button_type",
"event": "webhook_event_name"
}
]
}
}
Example of a table with one custom bulk action and a custom “bulk-delete” button:
{
"type": "resource_table",
"options": {
"module": "<module_for_resources>",
"selectable": true,
"bulk_actions": [
{
"identifier": "<Name of webhook event>",
"icon": "<ant_icon_name>"
},
{
"action": "delete",
"icon": "<ant_icon_name>",
"style": "<ant_button_style>",
"title": "_.bulk_delete"
}
]
}
}

Pre-Filters

schema of a pre-filter Object:

{
"column": "column_name",
"operator": "operator",
"value": "value"
}

Pre-filter Object using current module’s field:

{
"column": "column_name",
"operator": "operator",
"field": "field_identifier"
}

Pre-filter Object using recipe:

{
"column": "column_name",
"operator": "operator",
"recipe": "this.field_identifier + _context.context_field_identifier"
}

full example of a resource table using a ColumnDef object

{
"type": "resource_table",
"options": {
"module": "module_for_resources",
"row_settings": {
"recipes": {
"style": "field_needed_for_recipe ? 'background: green' : ''"
}
},
"columns": {
"display": [
"field_displayed_1",
"field_displayed_2"
],
"fetch": [
"field_displayed_1",
"field_displayed_2",
"field_needed_for_recipe"
]
}
}
}

schema of a computed style:

{
"type": "resource_table",
"options": {
"module": "manufacturers",
"column_settings": {
"status": {
"recipes": {
"style": "(status == 'good') ? 'background-color: green; color: white;' : '' || (status == 'bad') ? 'background-color: red; color: white;' : ''"
}
}
},
"row_settings": {
"recipes": {
"style": "on_hold ? 'background-color: lightgray' : ''"
}
}
}
}

AggregateDef schema

The key within the functions object determines the key the loaded aggregate can later be referenced in recipes by the key $.aggregates.<function_name>. The function can be every aggregate function that MySQL supports (like count, sum, min, max, avg).

Example definition

{
"functions": {
"totalCount": {
"function": "count",
"fields": [
"id"
]
}
}
}

With pre-filters:

{
"pre_filters": [
{
"column": "completed",
"operator": "=",
"value": true
}
],
"functions": {
"completedCount": {
"function": "sum",
"fields": [
"completed"
]
}
}
}

SummaryDef schema

This definition consists of an object, whose keys are a field_identifier that determine under which column the defined data should be displayed. The SummaryDef is defined within an array, every new array element means another summary row will be appended to the table. Use the recipe option to calculate a fitting display of your data. The type allows the following values:

  • text - Displays the data as text. Supports HTML.
  • statistic - Displays the data as an AntDesign “Statistic” component.
  • progress - Displays the data as a progress-bar. Needs to be a value between 0-100.

Example definition

{
"completed": {
"type": "text",
"recipe": "$.aggregates.completedCount"
},
"total_amount": {
"recipe": "sum(this[*].total_amount)"
}
}

Example definition of a progress bar summary field

{
"completed": {
"type": "progress",
"title": "completed",
"recipe": "round(sum(this[*].completed) / len(this[*].completed) * 1000) / 10"
}
}

Workflow resource

You can get data from your workflow and put this to your resourceTable by using an event/webhook and a response/ResourceTable. Your workflow should return data structured like this:

{
"your_key": "data",
"your_key_a": "data_a"
}

with the same keys as your resource_table

"columns": [
{
"identifier": "your_key",
},
{
"identifier": "your_key_a",
},
]

Differences to modules:

  • No persistent data. ( No Edit / Delete or View)
  • No row selection
  • You have to use the input data in workflow to add searching, filtering and sorting functionalities

Example of Workflow Resource Table

{
"type": "resource_table",
"options": {
"workflow": "YourWorkflowsWebhookName",
"columns": [
{
"identifier": "your_key"
},
{
"identifier": "your_key_without_sorter",
"options": {
"no_sorter_in_entity_table": true
}
},
{
"identifier": "your_key_without_search",
"options": {
"no_filter_in_entity_table": true
}
}
]
}
}
What a workflow must consist of:

The event/webhook event which receives the following data:

  • result: Result count
  • page Current page
  • filters : array Searchfilter for columns Example: [column_key] => ( [0] => „searchstring“)
  • sortField : string Column to filter
  • sortOrder : string Sort Order ( Ascend / Descend )
  • seach : string Global search string
  • entity : array Current Resource / Entity

you could get these by adding a variable to output like:

Key | Value data | input:

An elment to get your data Array like source/entities or a just an op/recipe with data

And at least the response/resourceTable Element which needs following data:

  • Resource Data - Array of your Data
  • Current Page - Number of your Current Page (You could use $data.page if you have this set up)
  • Entity per Page - The number of entities per page
  • Total - The total amount of entities (Input will be ignored if you use Auto Pagination)
  • Auto Pagination - If it is set to True, your input array will be divided into the number of entries per page.

workflow-resource-table

Collapsibles

Full example
{
"cols": [
{
"span": 24,
"components": [
{
"type": "collapse",
"options": {
"title": "group",
"accordion": true,
"active_key": "my_key",
"no_padding": true,
"panels": [
{
"title": "my_title",
"key": "my_key",
"components": [
{
"type": "field_group",
"options": {
"fields": []
}
}
]
},
{
"title": "my_title2",
"key": "my_key2",
"components": [
{
"type": "field_group",
"options": {
"fields": []
}
}
]
}
]
}
}
]
}
]
}

collapsible

  • title: String
  • accordion: boolean determine if only one panel should be open at a time
  • active_key: boolean select the open panel when the page is loaded
  • no_padding: boolean
  • panels: array the list of panels identified by their key

Panel

  • title: String
  • key: String used to reference a panel

Affix

A component where its content is “sticky”, meaning that it will be fixed on top of the page when scrolling past it.

  • top: int determines the offset from the top in pixels
  • components: array<Component> layout components placed in the affix bar

Widgets

With the widget component, different charts can be displayed. The current chart options include: Donut, Line, Column and Progress

  • chart: String determines the type of chart. This can be ‘donut’, ‘line’, ‘column’ or ‘progress’

Options for Donut

  • headline : String
  • instances : Array
  • labelsBelow : boolean
  • hideLegend : boolean

The instances array holds objects with the following values:

  • color : Hex
  • label : String
  • trigger: TriggerObject (Optional)
  • value : Int

The TriggerObject holds the following keys, all except type are optional:

  • type: String Required. Values: redirect | webhook
  • target_module: String (module identifier)
  • target_resource: Int (resource id)
  • target_data: Object Will be passed directly into the body of the webhook request
  • target_action: String Module action (e.g. module.create). Used for type redirect, default is module
  • target_anchor: String Anchor tag, will be appended to url with leading # when using type redirect

Donut Example

{
"type": "widget",
"chart": "donut",
"options": {
"headline": "customer_lead",
"instances": [
{
"color": "#00BFFF",
"label": "new_lead",
"value": 30
},
{
"color": "#5F9EA0",
"label": "in_contact_with_customer",
"value": 20
},
{
"color": "#ADD8E6",
"label": "lead_completed",
"value": 20
}
]
}
}
  • headline : String
  • axis : Array This Array stores strings. They are the labels to be displayed on the x-axis. (e.g. year numbers)
  • lines : Array This Array stores objects. One object stores the data for one line.

The lines Array holds objects with the following values:

  • label : String The name of the line
  • color : Hex The color in which the line should be displayed
  • values : Array This Array stores Int values

Line Example

{
"type": "widget",
"chart": "line",
"options": {
"headline": "job_performance",
"axis": [
"2004",
"2005",
"2006",
"2007",
"2008"
],
"lines": [
{
"label": "peter",
"color": "#b80f0f",
"values": [
10,
20,
5,
60,
30
]
}
]
}
}

Options for Column

  • headline : String
  • axis : Array This Array stores strings. They are the labels to be displayed on the x-axis. (e.g. year numbers)
  • columns : Array This Array stores objects. One object stores the data for one column.

The columns Array holds objects with the following values:

  • label : String The name of the column
  • color : Hex The color in which the column should be displayed
  • values : Array This Array stores Int values

Column Example

{
"span": 24,
"components": [
{
"type": "widget",
"chart": "column",
"options": {
"headline": "test_data",
"axis": [
"2004",
"2005",
"2006",
"2007",
"2008"
],
"columns": [
{
"label": "column1",
"color": "#b80f0f",
"values": [
10,
20,
5,
60,
30
]
},
{
"label": "column2",
"color": "#fcf912",
"values": [
20,
8,
15,
50,
80
]
}
]
}
}
]
}

Options for Progressbar

  • headline : String
  • max : Int this defines which value would be 100%
  • current : Int defines the current number of completed steps/products/…
  • color : Hex

ProgressBar Example

{
"type": "widget",
"chart": "progress",
"options": {
"headline": "realized_product",
"current": 600,
"max": 1800,
"color": "#0fb83c"
}
}

The component navigation can calculate a route between two addresses. It has input fields and shows the arrival time. It can display an interactive map of the calculated route.

Options for Navigation

  • map: String set this value to “true” if you want the map to be displayed. Otherwise the component will only show time and distance.

Map

The map component displays a single address with a marker on an interactive map. It has no input fields and shows the map only, the address data has to be set via api.

Options for Map

  • address: String
  • height: String this is css, so values could be 30vh, 300px or something else
  • mode: heatmap; heatmap shows additional heat information via a workflow response (*1)
  • event: Workflowevent you can use workflows to fill address data as its response
{
"type": "map",
"options": {
"recipes": {
"address": "zip"
},
"height": "40vh"
}
}
Too large for expand/collapse
Path is api/database/seeds/3b/workflows/setGeoDataForLeads.workflow.json
Too large for expand/collapse
Path is api/database/seeds/3b/workflows/getGeoDataForLeads.workflow.json