diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index 165ed37fb..0551997b7 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -31,11 +31,11 @@ export const getBindableProperties = (asset, componentId) => { const deviceBindings = getDeviceBindings() const stateBindings = getStateBindings() return [ - ...stateBindings, - ...deviceBindings, - ...urlBindings, ...contextBindings, + ...urlBindings, + ...stateBindings, ...userBindings, + ...deviceBindings, ] } diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json index 9a87bb576..c4fd33b08 100644 --- a/packages/builder/src/components/design/AppPreview/componentStructure.json +++ b/packages/builder/src/components/design/AppPreview/componentStructure.json @@ -3,8 +3,8 @@ "name": "Blocks", "icon": "Article", "children": [ - "tablewithsearch", - "cardlistwithsearch" + "tableblock", + "cardsblock" ] }, "section", diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte index a6086bbbc..72b54f3b9 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/PropertyControl.svelte @@ -27,7 +27,7 @@ if (!nested) { return bindings } - return [...(bindings || []), ...(componentBindings || [])] + return [...(componentBindings || []), ...(bindings || [])] } // Handle a value change of any type diff --git a/packages/client/manifest.json b/packages/client/manifest.json index e75150ca4..4a50a11fc 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -2595,6 +2595,11 @@ "key": "linkURL", "label": "Link URL" }, + { + "type": "boolean", + "key": "linkPeek", + "label": "Open link in modal" + }, { "type": "boolean", "key": "horizontal", @@ -2617,9 +2622,9 @@ } ] }, - "tablewithsearch": { + "tableblock": { "block": true, - "name": "Table with search", + "name": "Table block", "icon": "Table", "styles": ["size"], "info": "Only the first 3 search columns will be used.", @@ -2730,18 +2735,23 @@ { "type": "boolean", "key": "showTitleButton", - "label": "Show button", + "label": "Show link button", "defaultValue": false }, + { + "type": "boolean", + "label": "Open link in modal", + "key": "titleButtonPeek" + }, { "type": "text", "key": "titleButtonText", "label": "Button text" }, { - "type": "event", - "label": "Button action", - "key": "titleButtonOnClick" + "type": "url", + "label": "Button link", + "key": "titleButtonURL" } ] }, @@ -2759,9 +2769,9 @@ } ] }, - "cardlistwithsearch": { + "cardsblock": { "block": true, - "name": "Card list with search", + "name": "Cards block", "icon": "Table", "styles": ["size"], "info": "Only the first 3 search columns will be used.", @@ -2838,7 +2848,22 @@ "key": "cardImageURL", "label": "Image URL", "nested": true - + }, + { + "type": "boolean", + "key": "linkCardTitle", + "label": "Link card title" + }, + { + "type": "boolean", + "key": "cardPeek", + "label": "Open link in modal" + }, + { + "type": "url", + "label": "Link screen", + "key": "cardURL", + "nested": true }, { "type": "boolean", @@ -2855,7 +2880,6 @@ "key": "cardButtonText", "label": "Button text", "nested": true - }, { "type": "event", @@ -2872,7 +2896,12 @@ { "type": "boolean", "key": "showTitleButton", - "label": "Show button" + "label": "Show link button" + }, + { + "type": "boolean", + "label": "Open link in modal", + "key": "titleButtonPeek" }, { "type": "text", @@ -2880,9 +2909,21 @@ "label": "Button text" }, { - "type": "event", - "label": "Button action", - "key": "titleButtonOnClick" + "type": "url", + "label": "Button link", + "key": "titleButtonURL" + } + ] + }, + { + "section": true, + "name": "Advanced", + "settings": [ + { + "type": "field", + "label": "ID column for linking (appended to URL)", + "key": "linkColumn", + "placeholder": "Default" } ] } diff --git a/packages/client/src/components/app/SpectrumCard.svelte b/packages/client/src/components/app/SpectrumCard.svelte index d8353eea7..7aa2990ae 100644 --- a/packages/client/src/components/app/SpectrumCard.svelte +++ b/packages/client/src/components/app/SpectrumCard.svelte @@ -8,15 +8,22 @@ export let description export let imageURL export let linkURL + export let linkPeek export let horizontal export let showButton export let buttonText export let buttonOnClick - const { styleable, linkable } = getContext("sdk") + const { styleable, routeStore } = getContext("sdk") const component = getContext("component") - $: external = linkURL && !linkURL.startsWith("/") + const handleLink = e => { + if (!linkURL) { + return + } + e.preventDefault() + routeStore.actions.navigate(linkURL, linkPeek) + }
- {#if linkURL} - {#if external} - {title || "Card Title"} - {:else} - {title || "Card Title"} - {/if} - {:else} - {title || "Card Title"} - {/if} + {title || "Card Title"}
{#if subtitle} @@ -88,11 +89,12 @@ .spectrum-Card-container { padding: var(--spectrum-global-dimension-size-50) 0; } - .spectrum-Card-title :global(a) { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - width: 100%; + .spectrum-Card-title.link { + transition: color 130ms ease-in-out; + } + .spectrum-Card-title.link:hover { + cursor: pointer; + color: var(--spectrum-link-primary-m-text-color-hover); } .spectrum-Card-subtitle { text-overflow: ellipsis; @@ -103,14 +105,6 @@ word-wrap: anywhere; white-space: pre-wrap; } - a { - transition: color 130ms ease-in-out; - color: var(--spectrum-alias-text-color); - } - a:hover { - color: var(--spectrum-link-primary-m-text-color-hover); - } - .horizontal .spectrum-Card-coverPhoto { flex: 0 0 160px; height: auto; diff --git a/packages/client/src/components/app/blocks/CardListWithSearch.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte similarity index 87% rename from packages/client/src/components/app/blocks/CardListWithSearch.svelte rename to packages/client/src/components/app/blocks/CardsBlock.svelte index 7c9a067bd..9eccb2b2d 100644 --- a/packages/client/src/components/app/blocks/CardListWithSearch.svelte +++ b/packages/client/src/components/app/blocks/CardsBlock.svelte @@ -14,15 +14,20 @@ export let limit export let showTitleButton export let titleButtonText - export let titleButtonOnClick + export let titleButtonURL + export let titleButtonPeek export let cardTitle export let cardSubtitle export let cardDescription export let cardImageURL + export let linkCardTitle + export let cardURL + export let cardPeek export let cardHorizontal export let showCardButton export let cardButtonText export let cardButtonOnClick + export let linkColumn const { API, styleable } = getContext("sdk") const context = getContext("context") @@ -37,11 +42,27 @@ let formId let dataProviderId + let repeaterId let schema $: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema) $: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId) $: cardWidth = cardHorizontal ? 420 : 300 + $: fullCardURL = buildFullCardUrl( + linkCardTitle, + cardURL, + repeaterId, + linkColumn + ) + $: titleButtonAction = [ + { + "##eventHandlerType": "Navigate To", + parameters: { + peek: titleButtonPeek, + url: titleButtonURL, + }, + }, + ] // Enrich the default filter with the specified search fields const enrichFilter = (filter, columns, formId) => { @@ -75,6 +96,16 @@ return enrichedColumns.slice(0, 3) } + // Builds a full details page URL for the card title + const buildFullCardUrl = (link, url, repeaterId, linkColumn) => { + if (!link || !url || !repeaterId) { + return null + } + const col = linkColumn || "_id" + const split = url.split("/:") + return `${split[0]}/{{ [${repeaterId}].[${col}] }}` + } + // Load the datasource schema on mount so we can determine column types onMount(async () => { if (dataSource) { @@ -114,7 +145,7 @@ { @@ -113,7 +123,7 @@