Merge branch 'spectrum-bbui' into spectrum/kevs-bits-and-bobs-the-sequel
This commit is contained in:
commit
0a036e5f20
|
@ -23,15 +23,13 @@
|
||||||
class:active
|
class:active
|
||||||
class="spectrum-Button spectrum-Button--size{size.toUpperCase()}"
|
class="spectrum-Button spectrum-Button--size{size.toUpperCase()}"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click|preventDefault
|
on:click|preventDefault>
|
||||||
>
|
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
|
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label={icon}
|
aria-label={icon}>
|
||||||
>
|
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -46,4 +44,7 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
.active {
|
||||||
|
color: var(--spectrum-global-color-blue-600) !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel`}>
|
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeL spectrum-Form-itemLabel`}>
|
||||||
<slot />
|
<slot />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
<script>
|
<script>
|
||||||
import { Popover, Button } from "@budibase/bbui"
|
import { Modal, Button } from "@budibase/bbui"
|
||||||
import CalculatePopover from "../popovers/CalculatePopover.svelte"
|
import CalculateModal from "../modals/CalculateModal.svelte"
|
||||||
|
|
||||||
export let view = {}
|
export let view = {}
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<Button
|
||||||
<Button icon="Calculator" primary size="S" quiet
|
icon="Calculator"
|
||||||
on:click={dropdown.show}
|
primary
|
||||||
|
size="S"
|
||||||
|
quiet
|
||||||
|
on:click={modal.show}
|
||||||
active={view.field && view.calculation}>
|
active={view.field && view.calculation}>
|
||||||
Calculate
|
Calculate
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<CalculateModal {view} />
|
||||||
<CalculatePopover {view} onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { Popover, Button } from "@budibase/bbui"
|
import { Modal, Button } from "@budibase/bbui"
|
||||||
import CreateViewPopover from "../popovers/CreateViewPopover.svelte"
|
import CreateViewModal from "../modals/CreateViewModal.svelte"
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<Button icon="CollectionAdd" primary size="S" quiet on:click={modal.show}>
|
||||||
<Button icon="CollectionAdd" primary size="S" quiet on:click={dropdown.show}>
|
|
||||||
Create New View
|
Create New View
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<CreateViewModal />
|
||||||
<CreateViewPopover onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { Button, Icon, Popover } from "@budibase/bbui"
|
import { Button, Modal } from "@budibase/bbui"
|
||||||
import ExportPopover from "../popovers/ExportPopover.svelte"
|
import ExportModal from "../modals/ExportModal.svelte"
|
||||||
|
|
||||||
export let view
|
export let view
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<Button icon="Download" primary size="S" quiet on:click={modal.show}>
|
||||||
<Button icon="Download" primary size="S" quiet on:click={dropdown.show}>
|
|
||||||
Export
|
Export
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<ExportModal {view} />
|
||||||
<ExportPopover {view} onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
<script>
|
<script>
|
||||||
import { Popover, Button, Icon } from "@budibase/bbui"
|
import { Button, Modal } from "@budibase/bbui"
|
||||||
import FilterPopover from "../popovers/FilterPopover.svelte"
|
import FilterModal from "../modals/FilterModal.svelte"
|
||||||
|
|
||||||
export let view = {}
|
export let view = {}
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<Button
|
||||||
<Button icon="Filter" primary size="S" quiet
|
icon="Filter"
|
||||||
on:click={dropdown.show}
|
primary
|
||||||
active={view.filters && view.filters.length}>
|
size="S"
|
||||||
|
quiet
|
||||||
|
on:click={modal.show}
|
||||||
|
active={view.filters?.length}>
|
||||||
Filter
|
Filter
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<FilterModal {view} />
|
||||||
<FilterPopover {view} onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
<script>
|
<script>
|
||||||
import { Popover, Button } from "@budibase/bbui"
|
import { Modal, Button } from "@budibase/bbui"
|
||||||
import GroupByPopover from "../popovers/GroupByPopover.svelte"
|
import GroupByModal from "../modals/GroupByModal.svelte"
|
||||||
|
|
||||||
export let view = {}
|
export let view = {}
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<Button
|
||||||
<Button icon="Group" primary size="S" quiet active={!!view.groupBy} on:click={dropdown.show}>
|
icon="Group"
|
||||||
|
primary
|
||||||
|
size="S"
|
||||||
|
quiet
|
||||||
|
active={!!view.groupBy}
|
||||||
|
on:click={modal.show}>
|
||||||
Group By
|
Group By
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<GroupByModal {view} />
|
||||||
<GroupByPopover {view} onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,29 +1,25 @@
|
||||||
<script>
|
<script>
|
||||||
import { Button, Popover } from "@budibase/bbui"
|
import { Button, Modal } from "@budibase/bbui"
|
||||||
import { permissions } from "stores/backend"
|
import { permissions } from "stores/backend"
|
||||||
import ManageAccessPopover from "../popovers/ManageAccessPopover.svelte"
|
import ManageAccessModal from "../modals/ManageAccessModal.svelte"
|
||||||
|
|
||||||
export let resourceId
|
export let resourceId
|
||||||
|
|
||||||
let anchor
|
let modal
|
||||||
let dropdown
|
|
||||||
let resourcePermissions
|
let resourcePermissions
|
||||||
|
|
||||||
async function openDropdown() {
|
async function openDropdown() {
|
||||||
resourcePermissions = await permissions.forResource(resourceId)
|
resourcePermissions = await permissions.forResource(resourceId)
|
||||||
dropdown.show()
|
modal.show()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
|
||||||
<Button icon="LockClosed" primary size="S" quiet on:click={openDropdown}>
|
<Button icon="LockClosed" primary size="S" quiet on:click={openDropdown}>
|
||||||
Manage Access
|
Manage Access
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Modal bind:this={modal}>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<ManageAccessModal
|
||||||
<ManageAccessPopover
|
|
||||||
{resourceId}
|
{resourceId}
|
||||||
levels={$permissions}
|
levels={$permissions}
|
||||||
permissions={resourcePermissions}
|
permissions={resourcePermissions} />
|
||||||
onClosed={dropdown.hide} />
|
</Modal>
|
||||||
</Popover>
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { Button, Select, Label, notifications } from "@budibase/bbui"
|
import { Select, Label, notifications, ModalContent } from "@budibase/bbui"
|
||||||
import { tables, views } from "stores/backend"
|
import { tables, views } from "stores/backend"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
|
||||||
|
@ -35,13 +35,15 @@
|
||||||
function saveView() {
|
function saveView() {
|
||||||
views.save(view)
|
views.save(view)
|
||||||
notifications.success(`View ${view.name} saved.`)
|
notifications.success(`View ${view.name} saved.`)
|
||||||
onClosed()
|
|
||||||
analytics.captureEvent("Added View Calculate", { field: view.field })
|
analytics.captureEvent("Added View Calculate", { field: view.field })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="actions">
|
<ModalContent
|
||||||
<h5>Calculate</h5>
|
title="Calculate"
|
||||||
|
confirmText="Save"
|
||||||
|
onConfirm={saveView}
|
||||||
|
disabled={!view.field}>
|
||||||
<div class="input-group-row">
|
<div class="input-group-row">
|
||||||
<Label>The</Label>
|
<Label>The</Label>
|
||||||
<Select
|
<Select
|
||||||
|
@ -54,31 +56,9 @@
|
||||||
<Select bind:value={view.field} options={fields} />
|
<Select bind:value={view.field} options={fields} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
</ModalContent>
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
<Button cta on:click={saveView} disabled={!view.field}>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.actions {
|
|
||||||
width: 200px;
|
|
||||||
display: grid;
|
|
||||||
grid-gap: var(--spacing-xl);
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-row {
|
.input-group-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { Button, Input, notifications, Heading } from "@budibase/bbui"
|
import { Input, notifications, ModalContent } from "@budibase/bbui"
|
||||||
import { goto } from "@roxi/routify"
|
import { goto } from "@roxi/routify"
|
||||||
import { views as viewsStore } from "stores/backend"
|
import { views as viewsStore } from "stores/backend"
|
||||||
import { tables } from "stores/backend"
|
import { tables } from "stores/backend"
|
||||||
|
@ -23,37 +23,14 @@
|
||||||
field,
|
field,
|
||||||
})
|
})
|
||||||
notifications.success(`View ${name} created`)
|
notifications.success(`View ${name} created`)
|
||||||
onClosed()
|
|
||||||
analytics.captureEvent("View Created", { name })
|
analytics.captureEvent("View Created", { name })
|
||||||
$goto(`../../view/${name}`)
|
$goto(`../../view/${name}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="actions">
|
<ModalContent
|
||||||
<Heading s>Create View</Heading>
|
title="Create View"
|
||||||
|
confirmText="Create View"
|
||||||
|
onConfirm={saveView}>
|
||||||
<Input label="View Name" thin bind:value={name} />
|
<Input label="View Name" thin bind:value={name} />
|
||||||
<div class="footer">
|
</ModalContent>
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
<Button cta on:click={saveView}>Save View</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: grid;
|
|
||||||
grid-gap: var(--spacing-xl);
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
// Changes the selected role
|
// Changes the selected role
|
||||||
const changeRole = event => {
|
const changeRole = event => {
|
||||||
const id = event?.target?.value
|
const id = event?.detail
|
||||||
const role = $roles.find(role => role._id === id)
|
const role = $roles.find(role => role._id === id)
|
||||||
if (role) {
|
if (role) {
|
||||||
selectedRole = {
|
selectedRole = {
|
||||||
|
@ -94,42 +94,34 @@
|
||||||
secondary
|
secondary
|
||||||
label="Role"
|
label="Role"
|
||||||
value={selectedRoleId}
|
value={selectedRoleId}
|
||||||
on:change={changeRole}>
|
on:change={changeRole}
|
||||||
<option value="">Create new role</option>
|
options={$roles}
|
||||||
{#each $roles as role}
|
placeholder="Create new role"
|
||||||
<option value={role._id}>{role.name}</option>
|
getOptionValue={role => role._id}
|
||||||
{/each}
|
getOptionLabel={role => role.name} />
|
||||||
</Select>
|
|
||||||
{#if selectedRole}
|
{#if selectedRole}
|
||||||
<Input
|
<Input
|
||||||
label="Name"
|
label="Name"
|
||||||
bind:value={selectedRole.name}
|
bind:value={selectedRole.name}
|
||||||
thin
|
|
||||||
disabled={builtInRoles.includes(selectedRole.name)} />
|
disabled={builtInRoles.includes(selectedRole.name)} />
|
||||||
<Select
|
<Select
|
||||||
thin
|
|
||||||
secondary
|
|
||||||
label="Inherits Role"
|
label="Inherits Role"
|
||||||
bind:value={selectedRole.inherits}>
|
bind:value={selectedRole.inherits}
|
||||||
<option value="">None</option>
|
options={otherRoles}
|
||||||
{#each otherRoles as role}
|
getOptionValue={role => role._id}
|
||||||
<option value={role._id}>{role.name}</option>
|
getOptionLabel={role => role.name}
|
||||||
{/each}
|
placeholder="None" />
|
||||||
</Select>
|
|
||||||
<Select
|
<Select
|
||||||
thin
|
|
||||||
secondary
|
|
||||||
label="Base Permissions"
|
label="Base Permissions"
|
||||||
bind:value={selectedRole.permissionId}>
|
bind:value={selectedRole.permissionId}
|
||||||
<option value="">Choose permissions</option>
|
options={basePermissions}
|
||||||
{#each basePermissions as basePerm}
|
getOptionValue={x => x._id}
|
||||||
<option value={basePerm._id}>{basePerm.name}</option>
|
getOptionLabel={x => x.name}
|
||||||
{/each}
|
placeholder="Choose permissions" />
|
||||||
</Select>
|
|
||||||
{/if}
|
{/if}
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
{#if !isCreating}
|
{#if !isCreating}
|
||||||
<Button red on:click={deleteRole}>Delete</Button>
|
<Button warning on:click={deleteRole}>Delete</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<script>
|
||||||
|
import { Select, ModalContent } from "@budibase/bbui"
|
||||||
|
import download from "downloadjs"
|
||||||
|
|
||||||
|
const FORMATS = [
|
||||||
|
{
|
||||||
|
name: "CSV",
|
||||||
|
key: "csv",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "JSON",
|
||||||
|
key: "json",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export let view
|
||||||
|
|
||||||
|
let exportFormat = FORMATS[0].key
|
||||||
|
|
||||||
|
async function exportView() {
|
||||||
|
download(
|
||||||
|
`/api/views/export?view=${encodeURIComponent(
|
||||||
|
view.name
|
||||||
|
)}&format=${exportFormat}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ModalContent title="Export Data" confirmText="Export" onConfirm={exportView}>
|
||||||
|
<Select
|
||||||
|
label="Format"
|
||||||
|
bind:value={exportFormat}
|
||||||
|
options={FORMATS}
|
||||||
|
placeholder={null}
|
||||||
|
getOptionLabel={x => x.name}
|
||||||
|
getOptionValue={x => x.key} />
|
||||||
|
</ModalContent>
|
|
@ -1,7 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import { Button, Input, Select, DatePicker } from "@budibase/bbui"
|
import {
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
Body,
|
||||||
|
Select,
|
||||||
|
DatePicker,
|
||||||
|
ModalContent,
|
||||||
|
Label,
|
||||||
|
notifications,
|
||||||
|
Icon,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import { tables, views } from "stores/backend"
|
import { tables, views } from "stores/backend"
|
||||||
import { notifications } from "@budibase/bbui"
|
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
|
||||||
const CONDITIONS = [
|
const CONDITIONS = [
|
||||||
|
@ -55,7 +64,6 @@
|
||||||
function saveView() {
|
function saveView() {
|
||||||
views.save(view)
|
views.save(view)
|
||||||
notifications.success(`View ${view.name} saved.`)
|
notifications.success(`View ${view.name} saved.`)
|
||||||
onClosed()
|
|
||||||
analytics.captureEvent("Added View Filter", {
|
analytics.captureEvent("Added View Filter", {
|
||||||
filters: JSON.stringify(view.filters),
|
filters: JSON.stringify(view.filters),
|
||||||
})
|
})
|
||||||
|
@ -67,7 +75,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFilter() {
|
function addFilter() {
|
||||||
view.filters.push({})
|
view.filters.push({ conjunction: "AND" })
|
||||||
view.filters = view.filters
|
view.filters = view.filters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,9 +106,8 @@
|
||||||
// reset if type changed
|
// reset if type changed
|
||||||
if (
|
if (
|
||||||
filter.key &&
|
filter.key &&
|
||||||
ev.target.value &&
|
ev.detail &&
|
||||||
viewTable.schema[filter.key].type !==
|
viewTable.schema[filter.key].type !== viewTable.schema[ev.detail].type
|
||||||
viewTable.schema[ev.target.value].type
|
|
||||||
) {
|
) {
|
||||||
filter.value = ""
|
filter.value = ""
|
||||||
}
|
}
|
||||||
|
@ -110,17 +117,21 @@
|
||||||
const getOptionValue = x => x.key
|
const getOptionValue = x => x.key
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="actions">
|
<ModalContent
|
||||||
<h5>Filter</h5>
|
title="Filter"
|
||||||
|
confirmText="Save"
|
||||||
|
onConfirm={saveView}
|
||||||
|
size="large">
|
||||||
{#if view.filters.length}
|
{#if view.filters.length}
|
||||||
<div class="input-group-row">
|
<div class="input-group-row">
|
||||||
{#each view.filters as filter, idx}
|
{#each view.filters as filter, idx}
|
||||||
{#if idx === 0}
|
{#if idx === 0}
|
||||||
<p>Where</p>
|
<Label>Where</Label>
|
||||||
{:else}
|
{:else}
|
||||||
<Select
|
<Select
|
||||||
bind:value={filter.conjunction}
|
bind:value={filter.conjunction}
|
||||||
options={CONJUNCTIONS}
|
options={CONJUNCTIONS}
|
||||||
|
placeholder={null}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue} />
|
{getOptionValue} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -152,61 +163,22 @@
|
||||||
placeholder={filter.key || fields[0]}
|
placeholder={filter.key || fields[0]}
|
||||||
bind:value={filter.value} />
|
bind:value={filter.value} />
|
||||||
{/if}
|
{/if}
|
||||||
<i class="ri-close-circle-fill" on:click={() => removeFilter(idx)} />
|
<Icon hoverable name="Close" on:click={() => removeFilter(idx)} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Body s>Add a filter to get started.</Body>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="footer">
|
<div slot="footer">
|
||||||
<div class="add-filter">
|
<Button secondary on:click={addFilter}>Add Filter</Button>
|
||||||
<Button text on:click={addFilter}>Add Filter</Button>
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
<Button cta on:click={saveView}>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</ModalContent>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.actions {
|
|
||||||
display: grid;
|
|
||||||
grid-gap: var(--spacing-xl);
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ri-close-circle-fill {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-row {
|
.input-group-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(50px, auto) 1fr 1fr 1fr 15px;
|
grid-template-columns: minmax(70px, auto) 1fr 1fr 1fr 15px;
|
||||||
gap: var(--spacing-s);
|
gap: var(--spacing-s);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-filter {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script>
|
||||||
|
import { Button, Select, ModalContent, notifications } from "@budibase/bbui"
|
||||||
|
import { tables, views } from "stores/backend"
|
||||||
|
import { FIELDS } from "constants/backend"
|
||||||
|
|
||||||
|
export let view = {}
|
||||||
|
export let onClosed
|
||||||
|
|
||||||
|
$: viewTable = $tables.list.find(({ _id }) => _id === $views.selected.tableId)
|
||||||
|
$: fields =
|
||||||
|
viewTable &&
|
||||||
|
Object.entries(viewTable.schema)
|
||||||
|
.filter(entry => entry[1].type !== FIELDS.LINK.type)
|
||||||
|
.map(([key]) => key)
|
||||||
|
|
||||||
|
function saveView() {
|
||||||
|
views.save(view)
|
||||||
|
notifications.success(`View ${view.name} saved.`)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ModalContent title="Group By" confirmText="Save" onConfirm={saveView}>
|
||||||
|
<Select bind:value={view.groupBy} options={fields} />
|
||||||
|
</ModalContent>
|
|
@ -1,14 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { roles, permissions as permissionsStore } from "stores/backend"
|
import { roles, permissions as permissionsStore } from "stores/backend"
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
Label,
|
Label,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
Spacer,
|
Spacer,
|
||||||
notifications,
|
notifications,
|
||||||
Heading,
|
|
||||||
Body,
|
Body,
|
||||||
|
ModalContent,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { capitalise } from "../../../../helpers"
|
import { capitalise } from "../../../../helpers"
|
||||||
|
|
||||||
|
@ -31,12 +30,8 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="popover">
|
<ModalContent title="Manage Access" showCancelButton={false} confirmText="Done">
|
||||||
<Heading s>Who Can Access This Data?</Heading>
|
|
||||||
<div class="note">
|
|
||||||
<Body s>Specify the minimum access level role for this data.</Body>
|
<Body s>Specify the minimum access level role for this data.</Body>
|
||||||
</div>
|
|
||||||
<Spacer large />
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<Label extraSmall grey>Level</Label>
|
<Label extraSmall grey>Level</Label>
|
||||||
<Label extraSmall grey>Role</Label>
|
<Label extraSmall grey>Role</Label>
|
||||||
|
@ -50,41 +45,12 @@
|
||||||
getOptionValue={x => x._id} />
|
getOptionValue={x => x._id} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
</ModalContent>
|
||||||
<Spacer large />
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.popover {
|
|
||||||
display: grid;
|
|
||||||
width: 400px;
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
margin-top: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
grid-gap: var(--spacing-s);
|
grid-gap: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.note {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -1,63 +0,0 @@
|
||||||
<script>
|
|
||||||
import { Button, Select, Heading } from "@budibase/bbui"
|
|
||||||
import download from "downloadjs"
|
|
||||||
|
|
||||||
const FORMATS = [
|
|
||||||
{
|
|
||||||
name: "CSV",
|
|
||||||
key: "csv",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "JSON",
|
|
||||||
key: "json",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export let view
|
|
||||||
export let onClosed
|
|
||||||
|
|
||||||
let exportFormat = FORMATS[0].key
|
|
||||||
|
|
||||||
async function exportView() {
|
|
||||||
download(
|
|
||||||
`/api/views/export?view=${encodeURIComponent(
|
|
||||||
view.name
|
|
||||||
)}&format=${exportFormat}`
|
|
||||||
)
|
|
||||||
onClosed()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="popover">
|
|
||||||
<Heading s>Export Data</Heading>
|
|
||||||
<Select
|
|
||||||
label="Format"
|
|
||||||
bind:value={exportFormat}
|
|
||||||
options={FORMATS}
|
|
||||||
getOptionLabel={x => x.name}
|
|
||||||
getOptionValue={x => x.key} />
|
|
||||||
<div class="footer">
|
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
<Button cta on:click={exportView}>Export</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.popover {
|
|
||||||
display: grid;
|
|
||||||
grid-gap: var(--spacing-xl);
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,63 +0,0 @@
|
||||||
<script>
|
|
||||||
import { Button, Select } from "@budibase/bbui"
|
|
||||||
import { tables, views } from "stores/backend"
|
|
||||||
import { notifications } from "@budibase/bbui"
|
|
||||||
import { FIELDS } from "constants/backend"
|
|
||||||
|
|
||||||
export let view = {}
|
|
||||||
export let onClosed
|
|
||||||
|
|
||||||
$: viewTable = $tables.list.find(({ _id }) => _id === $views.selected.tableId)
|
|
||||||
$: fields =
|
|
||||||
viewTable &&
|
|
||||||
Object.entries(viewTable.schema)
|
|
||||||
.filter(entry => entry[1].type !== FIELDS.LINK.type)
|
|
||||||
.map(([key]) => key)
|
|
||||||
|
|
||||||
function saveView() {
|
|
||||||
views.save(view)
|
|
||||||
notifications.success(`View ${view.name} saved.`)
|
|
||||||
onClosed()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<h5>Group By</h5>
|
|
||||||
<Select bind:value={view.groupBy} options={fields} />
|
|
||||||
<div class="footer">
|
|
||||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
||||||
<Button cta on:click={saveView}>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.actions {
|
|
||||||
display: grid;
|
|
||||||
width: 200px;
|
|
||||||
grid-gap: var(--spacing-xl);
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 20px 1fr;
|
|
||||||
gap: var(--spacing-s);
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
}
|
|
||||||
</style>
|
|
Loading…
Reference in New Issue