Update create view button to be a popover instead of modal

This commit is contained in:
Andrew Kingston 2024-08-23 14:10:23 +01:00
parent 8d87395a98
commit 57da6d8cac
No known key found for this signature in database
10 changed files with 117 additions and 114 deletions

View File

@ -38,7 +38,7 @@
}
</script>
<DetailPopover title="Automations" minWidth={400} bind:this={popover}>
<DetailPopover title="Automations" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="JourneyVoyager"

View File

@ -1,29 +0,0 @@
<script>
import { getContext } from "svelte"
import { Modal, ActionButton, TooltipType, TempTooltip } from "@budibase/bbui"
import GridCreateViewModal from "../../modals/grid/GridCreateViewModal.svelte"
const { filter } = getContext("grid")
let modal
let firstFilterUsage = false
$: {
if ($filter?.length && !firstFilterUsage) {
firstFilterUsage = true
}
}
</script>
<TempTooltip
text="Create a view to save your filters"
type={TooltipType.Info}
condition={firstFilterUsage}
>
<ActionButton icon="CollectionAdd" quiet on:click={modal.show}>
Create view
</ActionButton>
</TempTooltip>
<Modal bind:this={modal}>
<GridCreateViewModal />
</Modal>

View File

@ -89,7 +89,7 @@
}
</script>
<DetailPopover title="Generate" bind:this={popover} minWidth={400}>
<DetailPopover title="Generate" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton selected={open}>
<div class="center">

View File

@ -60,7 +60,7 @@
}
</script>
<DetailPopover title="Row actions" minWidth={400} maxWidth={400}>
<DetailPopover title="Row actions">
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="Engagement"

View File

@ -26,7 +26,7 @@
}
</script>
<DetailPopover title="Screens" minWidth={400} bind:this={popover}>
<DetailPopover title="Screens" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton
icon="WebPage"

View File

@ -3,8 +3,6 @@
export let title
export let align = "left"
export let minWidth
export let maxWidth
export let showPopover
let popover
@ -24,11 +22,13 @@
<Popover
bind:this={popover}
bind:open
minWidth={minWidth || 300}
minWidth={400}
maxWidth={400}
{anchor}
{align}
{maxWidth}
{showPopover}
on:open
on:close
>
<div class="detail-popover">
<div class="detail-popover__header">

View File

@ -0,0 +1,103 @@
<script>
import DetailPopover from "components/common/DetailPopover.svelte"
import { Input, notifications, Button, Icon } from "@budibase/bbui"
import { goto } from "@roxi/routify"
import { viewsV2 } from "stores/builder"
export let table
export let firstView = false
let name
let popover
$: views = Object.keys(table?.views || {}).map(x => x.toLowerCase())
$: trimmedName = name?.trim()
$: nameExists = views.includes(trimmedName?.toLowerCase())
$: nameValid = trimmedName?.length && !nameExists
export const show = () => {
popover?.show()
}
const enrichSchema = schema => {
// We need to sure that "visible" is set to true for any fields which have
// not yet been saved with grid metadata attached
const cloned = { ...schema }
Object.entries(cloned).forEach(([field, fieldSchema]) => {
if (fieldSchema.visible == null) {
cloned[field] = { ...cloned[field], visible: true }
}
})
return cloned
}
const saveView = async () => {
popover.hide()
try {
const newView = await viewsV2.create({
name: trimmedName,
tableId: table._id,
schema: enrichSchema(table.schema),
primaryDisplay: table.primaryDisplay,
})
notifications.success(`View ${name} created`)
$goto(`./${newView.id}`)
} catch (error) {
notifications.error("Error creating view")
}
}
</script>
<DetailPopover
title="Create view"
bind:this={popover}
on:open={() => (name = null)}
>
<svelte:fragment slot="anchor" let:open>
{#if firstView}
<Button cta>Create a view</Button>
{:else}
<div class="icon" class:open>
<Icon
name="Add"
size="L"
color="var(--spectrum-global-color-gray-600)"
/>
</div>
{/if}
</svelte:fragment>
<Input
label="Name"
thin
bind:value={name}
error={nameExists ? "A view already exists with that name" : null}
autofocus
/>
<div>
<Button cta on:click={saveView} disabled={nameExists || !nameValid}>
Create view
</Button>
</div>
</DetailPopover>
<style>
.icon {
height: 32px;
padding: 0 8px;
border-radius: 4px;
display: grid;
place-items: center;
transition: background 130ms ease-out;
}
.icon:hover,
.icon:active,
.icon.open {
background: var(--spectrum-global-color-gray-300);
cursor: pointer;
}
.icon:hover :global(.spectrum-Icon),
.icon:active :global(.spectrum-Icon),
.icon.open :global(.spectrum-Icon) {
color: var(--spectrum-global-color-gray-900) !important;
}
</style>

View File

@ -1,64 +1,2 @@
<script>
import { Modal, Input, notifications, ModalContent } from "@budibase/bbui"
import { goto } from "@roxi/routify"
import { viewsV2 } from "stores/builder"
export let table
let name
let modal
$: views = Object.keys(table?.views || {}).map(x => x.toLowerCase())
$: trimmedName = name?.trim()
$: nameExists = views.includes(trimmedName?.toLowerCase())
$: nameValid = trimmedName?.length && !nameExists
export const show = () => {
name = null
modal?.show()
}
const enrichSchema = schema => {
// We need to sure that "visible" is set to true for any fields which have
// not yet been saved with grid metadata attached
const cloned = { ...schema }
Object.entries(cloned).forEach(([field, fieldSchema]) => {
if (fieldSchema.visible == null) {
cloned[field] = { ...cloned[field], visible: true }
}
})
return cloned
}
const saveView = async () => {
try {
const newView = await viewsV2.create({
name: trimmedName,
tableId: table._id,
schema: enrichSchema(table.schema),
primaryDisplay: table.primaryDisplay,
})
notifications.success(`View ${name} created`)
name = null
$goto(`./${newView.id}`)
} catch (error) {
notifications.error("Error creating view")
}
}
</script>
<Modal bind:this={modal}>
<ModalContent
title="Create view"
confirmText="Create view"
onConfirm={saveView}
disabled={!nameValid}
>
<Input
label="View name"
thin
bind:value={name}
error={nameExists ? "A view already exists with that name" : null}
/>
</ModalContent>
</Modal>

View File

@ -39,7 +39,7 @@
</script>
<Modal bind:this={editorModal} on:show={initForm}>
<ModalContent title="Edit View" onConfirm={save} confirmText="Save">
<Input label="View Name" thin bind:value={updatedName} />
<ModalContent title="Edit view" onConfirm={save} confirmText="Save">
<Input label="Name" thin bind:value={updatedName} />
</ModalContent>
</Modal>

View File

@ -26,6 +26,7 @@
import CreateViewModal from "./CreateViewModal.svelte"
import { onDestroy } from "svelte"
import { derived } from "svelte/store"
import CreateViewButton from "./CreateViewButton.svelte"
// View overflow
let observer
@ -34,7 +35,6 @@
let overflowMenu
// Editing table
let createViewModal
let editTableModal
let deleteTableModal
@ -268,7 +268,7 @@
</div>
{/if}
{#if !hasViews && tableEditable}
<Button cta on:click={createViewModal?.show}>Create a view</Button>
<CreateViewButton firstView {table} />
<span>
To create subsets of data, control access and more, create a view.
</span>
@ -311,19 +311,11 @@
</ActionMenu>
{/if}
{#if hasViews}
<Icon
name="Add"
size="L"
hoverable
color="var(--spectrum-global-color-gray-600)"
hoverColor="var(--spectrum-global-color-gray-900)"
on:click={createViewModal?.show}
/>
<CreateViewButton firstView={false} {table} />
{/if}
</div>
{#if table && tableEditable}
<CreateViewModal {table} bind:this={createViewModal} />
<EditTableModal {table} bind:this={editTableModal} />
<DeleteTableModal {table} bind:this={deleteTableModal} />
{/if}
@ -343,7 +335,7 @@
justify-content: flex-start;
align-items: center;
padding: 0 var(--spacing-xl);
gap: 12px;
gap: 8px;
}
.nav__views {
flex: 0 1 auto;
@ -353,7 +345,6 @@
align-items: center;
overflow: hidden;
gap: 8px;
margin-left: -4px;
}
/* Table and view items */