Update new view popover to allow for creating calculation views

This commit is contained in:
Andrew Kingston 2024-09-27 10:39:50 +01:00
parent 3b934a3f2d
commit 60c55b06ed
No known key found for this signature in database
4 changed files with 99 additions and 14 deletions

View File

@ -8,17 +8,22 @@
export let url = null export let url = null
export let hoverable = false export let hoverable = false
export let showArrow = false export let showArrow = false
export let selected = false
</script> </script>
<a <a
href={url} href={url}
class="list-item" class="list-item"
class:hoverable={hoverable || url != null} class:hoverable={hoverable || url != null}
class:selected
class:large={!!subtitle}
on:click on:click
> >
<div class="left"> <div class="list-item__left">
{#if icon} {#if icon}
<Icon name={icon} color={iconColor} /> <div class="list-item__icon">
<Icon name={icon} color={iconColor} size={subtitle ? "XL" : "M"} />
</div>
{/if} {/if}
<div class="list-item__text"> <div class="list-item__text">
{#if title} {#if title}
@ -33,7 +38,7 @@
{/if} {/if}
</div> </div>
</div> </div>
<div class="right"> <div class="list-item__right">
<slot name="right" /> <slot name="right" />
{#if showArrow} {#if showArrow}
<Icon name="ChevronRight" /> <Icon name="ChevronRight" />
@ -49,9 +54,12 @@
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
border: 1px solid var(--spectrum-global-color-gray-300); border: 1px solid var(--spectrum-global-color-gray-300);
transition: background 130ms ease-out; transition: background 130ms ease-out, border-color 130ms ease-out;
gap: var(--spacing-m); gap: var(--spacing-m);
color: var(--spectrum-global-color-gray-800); color: var(--spectrum-global-color-gray-800);
cursor: pointer;
position: relative;
box-sizing: border-box;
} }
.list-item:not(:first-child) { .list-item:not(:first-child) {
border-top: none; border-top: none;
@ -64,27 +72,71 @@
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
} }
.hoverable:hover { .list-item.hoverable:not(.selected):hover {
cursor: pointer;
background: var(--spectrum-global-color-gray-200); background: var(--spectrum-global-color-gray-200);
border-color: var(--spectrum-global-color-gray-400);
} }
.left, /* Selection is only meant for standalone list items (non stacked) so we just set a fixed border radius */
.right { .list-item.selected {
background-color: var(--spectrum-global-color-blue-100);
border-color: var(--spectrum-global-color-blue-100);
}
.list-item.selected:after {
content: "";
position: absolute;
height: 100%;
width: 100%;
border: 1px solid var(--spectrum-global-color-blue-400);
pointer-events: none;
top: 0;
left: 0;
border-radius: 4px;
box-sizing: border-box;
z-index: 1;
opacity: 0.5;
}
/* Large icons */
.list-item.large .list-item__icon {
background-color: var(--spectrum-global-color-gray-200);
padding: 4px;
border-radius: 4px;
border: 1px solid var(--spectrum-global-color-gray-300);
transition: background-color 130ms ease-out, border-color 130ms ease-out,
color 130ms ease-out;
}
.list-item.large.hoverable:not(.selected):hover .list-item__icon {
background-color: var(--spectrum-global-color-gray-300);
}
.list-item.large.selected .list-item__icon {
background-color: var(--spectrum-global-color-blue-400);
color: white;
border-color: var(--spectrum-global-color-blue-100);
}
/* Internal layout */
.list-item__left,
.list-item__right {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
gap: var(--spacing-s); gap: var(--spacing-s);
} }
.left { .list-item.large .list-item__left,
.list-item.large .list-item__right {
gap: var(--spacing-m);
}
.list-item__left {
width: 0; width: 0;
flex: 1 1 auto; flex: 1 1 auto;
} }
.right { .list-item__right {
flex: 0 0 auto; flex: 0 0 auto;
color: var(--spectrum-global-color-gray-600); color: var(--spectrum-global-color-gray-600);
} }
/* Text */
.list-item__text { .list-item__text {
flex: 1 1 auto; flex: 1 1 auto;
width: 0; width: 0;
@ -96,6 +148,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.list-item__subtitle { .list-item__subtitle {
color: var(--spectrum-global-color-gray-600); color: var(--spectrum-global-color-gray-700);
font-size: 12px;
} }
</style> </style>

View File

@ -4,6 +4,7 @@
export let title export let title
export let align = "left" export let align = "left"
export let showPopover export let showPopover
export let width
let popover let popover
let anchor let anchor
@ -22,8 +23,8 @@
<Popover <Popover
bind:this={popover} bind:this={popover}
bind:open bind:open
minWidth={400} minWidth={width || 400}
maxWidth={400} maxWidth={width || 400}
{anchor} {anchor}
{align} {align}
{showPopover} {showPopover}

View File

@ -1,12 +1,13 @@
<script> <script>
import DetailPopover from "components/common/DetailPopover.svelte" import DetailPopover from "components/common/DetailPopover.svelte"
import { Input, notifications, Button, Icon } from "@budibase/bbui" import { Input, notifications, Button, Icon, ListItem } from "@budibase/bbui"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { viewsV2 } from "stores/builder" import { viewsV2 } from "stores/builder"
export let table export let table
export let firstView = false export let firstView = false
let calculation = false
let name let name
let popover let popover
@ -39,6 +40,7 @@
tableId: table._id, tableId: table._id,
schema: enrichSchema(table.schema), schema: enrichSchema(table.schema),
primaryDisplay: table.primaryDisplay, primaryDisplay: table.primaryDisplay,
calculation,
}) })
notifications.success(`View ${name} created`) notifications.success(`View ${name} created`)
$goto(`./${newView.id}`) $goto(`./${newView.id}`)
@ -52,6 +54,7 @@
title="Create view" title="Create view"
bind:this={popover} bind:this={popover}
on:open={() => (name = null)} on:open={() => (name = null)}
width={540}
> >
<svelte:fragment slot="anchor" let:open> <svelte:fragment slot="anchor" let:open>
{#if firstView} {#if firstView}
@ -66,6 +69,28 @@
</div> </div>
{/if} {/if}
</svelte:fragment> </svelte:fragment>
<div class="options">
<div>
<ListItem
title="Table"
subtitle="Create a subset of your data"
hoverable
on:click={() => (calculation = false)}
selected={!calculation}
icon="Rail"
/>
</div>
<div>
<ListItem
title="Calculation"
subtitle="Calculate groups of rows"
hoverable
on:click={() => (calculation = true)}
selected={calculation}
icon="123"
/>
</div>
</div>
<Input <Input
label="Name" label="Name"
thin thin
@ -81,6 +106,11 @@
</DetailPopover> </DetailPopover>
<style> <style>
.options {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-m);
}
.icon { .icon {
height: 32px; height: 32px;
padding: 0 8px; padding: 0 8px;

View File

@ -72,6 +72,7 @@ export interface ViewV2 {
type?: SortType type?: SortType
} }
schema?: Record<string, ViewFieldMetadata> schema?: Record<string, ViewFieldMetadata>
calculation?: boolean
} }
export type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema export type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema