Add Row Explorer Block (#8454)

* Add Row Explorer Block and Row Details Component

* PR Feedback

* adding showSaveButton prop to formblock in row explorer

* PR Feedback

* PR Feedback

* Change row explorer name in manifest

Co-authored-by: Martin McKeaveney <martinmckeaveney@gmail.com>
This commit is contained in:
Gerard Burns 2022-11-14 11:54:44 +00:00 committed by GitHub
parent 2332bedb13
commit e70710f7b9
4 changed files with 340 additions and 3 deletions

View File

@ -7,7 +7,8 @@
"cardsblock",
"repeaterblock",
"formblock",
"chartblock"
"chartblock",
"rowexplorer"
]
},
{

View File

@ -5186,5 +5186,88 @@
"suffix": "repeater"
}
]
},
"rowexplorer": {
"block": true,
"name": "Row Explorer Block",
"icon": "PersonalizationField",
"size": {
"width": 600,
"height": 400
},
"settings": [
{
"type": "table",
"label": "Table",
"key": "dataSource",
"required": true
},
{
"type": "text",
"label": "Height",
"key": "height",
"defaultValue": "426px"
},
{
"section": true,
"name": "Cards",
"settings": [
{
"type": "field",
"label": "Search Field",
"key": "cardSearchField",
"nested": true
},
{
"type": "text",
"key": "cardTitle",
"label": "Title",
"nested": true,
"defaultValue": "Title"
},
{
"type": "text",
"key": "cardSubtitle",
"label": "Subtitle",
"nested": true,
"defaultValue": "Subtitle"
},
{
"type": "text",
"key": "cardDescription",
"label": "Description",
"nested": true,
"defaultValue": "Description"
},
{
"type": "text",
"key": "cardImageURL",
"label": "Image URL",
"nested": true
}
]
},
{
"section": true,
"name": "Details",
"settings": [
{
"type": "text",
"key": "detailTitle",
"label": "Title"
},
{
"type": "multifield",
"label": "Fields",
"key": "detailFields",
"nested": true
}
]
}
],
"context": {
"type": "schema",
"suffix": "repeater"
}
}
}

View File

@ -0,0 +1,252 @@
<script>
import Block from "components/Block.svelte"
import BlockComponent from "components/BlockComponent.svelte"
import { makePropSafe as safe } from "@budibase/string-templates"
import { generate } from "shortid"
export let dataSource
export let height
export let cardTitle
export let cardSubtitle
export let cardDescription
export let cardImageURL
export let cardSearchField
export let detailFields
export let detailTitle
const stateKey = generate()
let listDataProviderId
let listRepeaterId
</script>
<Block>
<BlockComponent
type="container"
props={{
direction: "row",
gap: "M",
}}
styles={{
custom: `
height: ${height} !important;
`,
}}
>
<BlockComponent
type="dataprovider"
order={0}
bind:id={listDataProviderId}
props={{
dataSource,
paginate: true,
limit: 10,
filter: [
{
id: 0,
field: cardSearchField,
operator: "fuzzy",
type: "string",
value: `{{ ${safe("state")}.${safe(stateKey + "-search")} }}`,
valueType: "Binding",
noValue: false,
},
],
}}
styles={{
custom: `
flex: 3;
overflow: scroll;
{{#if (and ${safe("state")}.${safe(stateKey)} ${safe(
"device"
)}.${safe("mobile")}) }}
display: none;
{{/if}}
`,
}}
>
<BlockComponent
type="form"
order={0}
styles={{
normal: {
"margin-bottom": "12px",
},
}}
>
<BlockComponent
type="stringfield"
props={{
placeholder: "Search...",
field: `${stateKey}-search`,
onChange: [
{
parameters: {
key: `${stateKey}-search`,
type: "set",
persist: null,
value: `{{ ${safe("eventContext")}.${safe("value")} }}`,
},
"##eventHandlerType": "Update State",
id: 0,
},
],
}}
/>
</BlockComponent>
<BlockComponent
type="repeater"
order={1}
bind:id={listRepeaterId}
context="repeater"
props={{
dataProvider: `{{ literal ${safe(listDataProviderId)} }}`,
direction: "column",
gap: "S",
noRowsMessage: "No data",
}}
>
<BlockComponent
type="spectrumcard"
props={{
title: cardTitle,
subtitle: cardSubtitle,
description: cardDescription,
imageURL: cardImageURL,
horizontal: true,
buttonOnClick: [
{
parameters: {
key: stateKey,
type: "set",
persist: null,
value: `{{ ${safe(listRepeaterId)}.${safe("_id")} }}`,
},
"##eventHandlerType": "Update State",
id: 0,
},
],
}}
styles={{
normal: {
width: "auto",
},
}}
/>
</BlockComponent>
</BlockComponent>
<BlockComponent
type="container"
order={1}
props={{
hAlign: "center",
vAlign: "middle",
size: "grow",
direction: "column",
}}
styles={{
custom: `
padding: 20px;
background-color: var(--spectrum-global-color-gray-50));
border: 1px solid var(--spectrum-global-color-gray-300);
border-radius: 4px;
flex: 4;
{{#if (or ${safe("state")}.${safe(stateKey)} ${safe("device")}.${safe(
"mobile"
)}) }}
display: none;
{{/if}}
`,
}}
>
<BlockComponent
type="icon"
order={0}
props={{
icon: "ri-list-check-2",
size: "ri-2x",
color: "var(--spectrum-global-color-gray-700)",
}}
styles={{
normal: {
"margin-bottom": "12px",
},
}}
/>
<BlockComponent
type="text"
order={1}
props={{
text: "Select a row to view its fields",
color: "var(--spectrum-global-color-gray-700)",
}}
/>
</BlockComponent>
<BlockComponent
type="container"
order={2}
props={{
hAlign: "center",
vAlign: "top",
size: "grow",
direction: "column",
}}
styles={{
custom: `
background-color: var(--spectrum-global-color-gray-50));
border: 1px solid var(--spectrum-global-color-gray-300);
border-radius: 4px;
padding: 20px;
overflow-y: scroll;
flex: 4;
{{#if (isFalsey ${safe("state")}.${safe(stateKey)}) }}
display: none;
{{/if}}
`,
}}
>
<BlockComponent
type="button"
order={0}
props={{
text: "← Back",
onClick: [
{
parameters: {
key: stateKey,
type: "set",
persist: null,
value: "",
},
"##eventHandlerType": "Update State",
id: 0,
},
],
}}
styles={{
custom: `
align-self: flex-end;
margin-bottom: 16px;
{{#if (not ${safe("device")}.${safe("mobile")}) }}
display: none;
{{/if}}
`,
}}
/>
<BlockComponent
type="formblock"
order={1}
props={{
showSaveButton: true,
dataSource,
actionType: "Update",
rowId: `{{ ${safe("state")}.${safe(stateKey)} }}`,
fields: detailFields,
title: detailTitle,
}}
/>
</BlockComponent>
</BlockComponent>
</Block>

View File

@ -3,3 +3,4 @@ export { default as cardsblock } from "./CardsBlock.svelte"
export { default as repeaterblock } from "./RepeaterBlock.svelte"
export { default as formblock } from "./FormBlock.svelte"
export { default as chartblock } from "./ChartBlock.svelte"
export { default as rowexplorer } from "./RowExplorer.svelte"