Soft paywall snippets

This commit is contained in:
Andrew Kingston 2024-03-14 14:29:13 +00:00
parent 0e94caafcb
commit 049c2b989b
1 changed files with 100 additions and 50 deletions

View File

@ -1,8 +1,19 @@
<script> <script>
import { Input, Layout, Icon, Popover } from "@budibase/bbui" import {
Input,
Layout,
Icon,
Popover,
Tags,
Tag,
Body,
Button,
} from "@budibase/bbui"
import CodeEditor from "components/common/CodeEditor/CodeEditor.svelte" import CodeEditor from "components/common/CodeEditor/CodeEditor.svelte"
import { EditorModes } from "components/common/CodeEditor" import { EditorModes } from "components/common/CodeEditor"
import SnippetDrawer from "./SnippetDrawer.svelte" import SnippetDrawer from "./SnippetDrawer.svelte"
import { licensing } from "stores/portal"
import UpgradeButton from "pages/builder/portal/_components/UpgradeButton.svelte"
export let addSnippet export let addSnippet
export let snippets export let snippets
@ -16,10 +27,11 @@
let snippetDrawer let snippetDrawer
let editableSnippet let editableSnippet
$: filteredSnippets = getFilteredSnippets(snippets, search) $: enableSnippets = !$licensing.isFreePlan
$: filteredSnippets = getFilteredSnippets(enableSnippets, snippets, search)
const getFilteredSnippets = (snippets, search) => { const getFilteredSnippets = (enableSnippets, snippets, search) => {
if (!snippets?.length) { if (!enableSnippets || !snippets?.length) {
return [] return []
} }
if (!search?.length) { if (!search?.length) {
@ -81,58 +93,77 @@
<div class="snippet-side-panel"> <div class="snippet-side-panel">
<Layout noPadding gap="S"> <Layout noPadding gap="S">
<div class="header"> <div class="header">
{#if searching} {#if enableSnippets}
<div class="search-input"> {#if searching}
<Input <div class="search-input">
placeholder="Search for snippets" <Input
autocomplete="off" placeholder="Search for snippets"
bind:value={search} autocomplete="off"
autofocus bind:value={search}
autofocus
/>
</div>
<Icon
size="S"
name="Close"
hoverable
newStyles
on:click={stopSearching}
/> />
</div> {:else}
<Icon <div class="title">Snippets</div>
size="S" <Icon
name="Close" size="S"
hoverable name="Search"
newStyles hoverable
on:click={stopSearching} newStyles
/> on:click={startSearching}
/>
<Icon
size="S"
name="Add"
hoverable
newStyles
on:click={createSnippet}
/>
{/if}
{:else} {:else}
<div class="title">Snippets</div> <div class="title">
<Icon Snippets
size="S" <Tags>
name="Search" <Tag icon="LockClosed">Premium</Tag>
hoverable </Tags>
newStyles </div>
on:click={startSearching}
/>
<Icon
size="S"
name="Add"
hoverable
newStyles
on:click={createSnippet}
/>
{/if} {/if}
</div> </div>
<div class="snippet-list"> <div class="snippet-list">
{#each filteredSnippets as snippet} {#if enableSnippets}
<div {#each filteredSnippets as snippet}
class="snippet" <div
on:mouseenter={e => showSnippet(snippet, e.target)} class="snippet"
on:mouseleave={hidePopover} on:mouseenter={e => showSnippet(snippet, e.target)}
on:click={() => addSnippet(snippet)} on:mouseleave={hidePopover}
> on:click={() => addSnippet(snippet)}
{snippet.name} >
<Icon {snippet.name}
name="Edit" <Icon
hoverable name="Edit"
newStyles hoverable
size="S" newStyles
on:click={e => editSnippet(e, snippet)} size="S"
/> on:click={e => editSnippet(e, snippet)}
/>
</div>
{/each}
{:else}
<div class="upgrade">
<Body size="S">
Create reusable blocks of JS that can be managed and updated all in
one place with Snippets
</Body>
<UpgradeButton />
</div> </div>
{/each} {/if}
</div> </div>
</Layout> </Layout>
</div> </div>
@ -191,6 +222,25 @@
.title { .title {
flex: 1 1 auto; flex: 1 1 auto;
} }
.title {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-m);
}
/* Upgrade */
.upgrade {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-l);
}
.upgrade :global(p) {
text-align: center;
align-self: center;
}
/* List */ /* List */
.snippet-list { .snippet-list {