Merge branch 'spectrum-bbui' of github.com:Budibase/budibase into spectrum-bbui-forms
This commit is contained in:
commit
b823f2bed1
|
@ -51,9 +51,13 @@
|
||||||
"@spectrum-css/modal": "^3.0.1",
|
"@spectrum-css/modal": "^3.0.1",
|
||||||
"@spectrum-css/picker": "^1.0.1",
|
"@spectrum-css/picker": "^1.0.1",
|
||||||
"@spectrum-css/popover": "^3.0.1",
|
"@spectrum-css/popover": "^3.0.1",
|
||||||
|
"@spectrum-css/progressbar": "^1.0.2",
|
||||||
|
"@spectrum-css/progresscircle": "^1.0.2",
|
||||||
"@spectrum-css/table": "^3.0.1",
|
"@spectrum-css/table": "^3.0.1",
|
||||||
"@spectrum-css/textfield": "^3.0.1",
|
"@spectrum-css/textfield": "^3.0.1",
|
||||||
|
"@spectrum-css/tabs": "^3.0.1",
|
||||||
"@spectrum-css/toast": "^3.0.1",
|
"@spectrum-css/toast": "^3.0.1",
|
||||||
|
"@spectrum-css/typography": "^3.0.1",
|
||||||
"@spectrum-css/underlay": "^2.0.9",
|
"@spectrum-css/underlay": "^2.0.9",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
"dayjs": "^1.10.4",
|
"dayjs": "^1.10.4",
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/divider/dist/index-vars.css"
|
||||||
|
export let l = false
|
||||||
|
export let m = false
|
||||||
|
export let s = false
|
||||||
|
|
||||||
|
export let vertical = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<hr
|
||||||
|
class:spectrum-Divider--sizeL={l}
|
||||||
|
class:spectrum-Divider--sizeM={m}
|
||||||
|
class:spectrum-Divider--sizeS={s}
|
||||||
|
class="spectrum-Divider spectrum-Divider--{vertical ? 'vertical' : 'horizontal'} spectrum-Dialog-divider">
|
|
@ -1,8 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/dialog/dist/index-vars.css"
|
|
||||||
import "@spectrum-css/modal/dist/index-vars.css"
|
import "@spectrum-css/modal/dist/index-vars.css"
|
||||||
import "@spectrum-css/underlay/dist/index-vars.css"
|
import "@spectrum-css/underlay/dist/index-vars.css"
|
||||||
import { createEventDispatcher, setContext } from "svelte"
|
import { createEventDispatcher, setContext, tick } from "svelte"
|
||||||
import { fade, fly } from "svelte/transition"
|
import { fade, fly } from "svelte/transition"
|
||||||
import Portal from "svelte-portal"
|
import Portal from "svelte-portal"
|
||||||
import Context from "../context"
|
import Context from "../context"
|
||||||
|
@ -31,6 +30,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function focusFirstInput(node) {
|
||||||
|
const inputs = node.querySelectorAll("input")
|
||||||
|
if (inputs) {
|
||||||
|
await tick()
|
||||||
|
inputs[0].focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setContext(Context.Modal, { show, hide })
|
setContext(Context.Modal, { show, hide })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -45,6 +52,7 @@
|
||||||
<div class="modal-wrapper" on:click|self={hide}>
|
<div class="modal-wrapper" on:click|self={hide}>
|
||||||
<div class="modal-inner-wrapper" on:click|self={hide}>
|
<div class="modal-inner-wrapper" on:click|self={hide}>
|
||||||
<div
|
<div
|
||||||
|
use:focusFirstInput
|
||||||
class="spectrum-Modal is-open"
|
class="spectrum-Modal is-open"
|
||||||
transition:fly={{ y: 30, duration: 200 }}>
|
transition:fly={{ y: 30, duration: 200 }}>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/divider/dist/index-vars.css"
|
|
||||||
|
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import Button from "../Button/Button.svelte"
|
import Button from "../Button/Button.svelte"
|
||||||
|
import Heading from "../Typography/Heading.svelte"
|
||||||
|
import Divider from "../Divider/Divider.svelte"
|
||||||
import Icon from "../Icons/Icon.svelte"
|
import Icon from "../Icons/Icon.svelte"
|
||||||
import Context from "../context"
|
import Context from "../context"
|
||||||
|
|
||||||
|
@ -35,10 +35,8 @@
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-modal="true">
|
aria-modal="true">
|
||||||
<div class="spectrum-Dialog-grid">
|
<div class="spectrum-Dialog-grid">
|
||||||
<h1 class="spectrum-Dialog-heading">{title}</h1>
|
<Heading m h2>{title}</Heading>
|
||||||
<hr
|
<Divider m />
|
||||||
class="spectrum-Divider spectrum-Divider--sizeS spectrum-Divider--horizontal spectrum-Dialog-divider" />
|
|
||||||
|
|
||||||
<!-- TODO: Remove content-grid class once Layout components are in bbui -->
|
<!-- TODO: Remove content-grid class once Layout components are in bbui -->
|
||||||
<section class="spectrum-Dialog-content content-grid">
|
<section class="spectrum-Dialog-content content-grid">
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/progressbar/dist/index-vars.css"
|
||||||
|
import { tweened } from 'svelte/motion';
|
||||||
|
import { cubicOut } from 'svelte/easing';
|
||||||
|
|
||||||
|
export let value = false
|
||||||
|
export let easing = cubicOut
|
||||||
|
export let duration = 1000;
|
||||||
|
export let width = false;
|
||||||
|
export let sideLabel = false
|
||||||
|
export let overBackground = false
|
||||||
|
|
||||||
|
export let s = false;
|
||||||
|
export let m = false;
|
||||||
|
export let l = false;
|
||||||
|
export let xl = false;
|
||||||
|
|
||||||
|
const progress = tweened(0, {
|
||||||
|
duration: duration,
|
||||||
|
easing: easing
|
||||||
|
});
|
||||||
|
|
||||||
|
$: if (value) $progress = value
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<div class:spectrum-ProgressBar--indeterminate={!value} class:spectrum-ProgressBar--sideLabel={sideLabel} class:spectrum-ProgressBar--sizeS={s} class:spectrum-ProgressBar--sizeM={m} class:spectrum-ProgressBar--sizeL={l} class:spectrum-ProgressBar--sizeXL={xl} class="spectrum-ProgressBar" value={$progress} role="progressbar" aria-valuenow={$progress} aria-valuemin="0" aria-valuemax="100" style={width ? `width: ${width}px;` : ''}>
|
||||||
|
{#if $$slots}
|
||||||
|
<div class:spectrum-FieldLabel--sizeS={s} class:spectrum-FieldLabel--sizeM={m} class:spectrum-FieldLabel--sizeL={l} class:spectrum-FieldLabel--sizeXL={xl} class="spectrum-FieldLabel spectrum-ProgressBar-label"><slot /></div>
|
||||||
|
{/if}
|
||||||
|
{#if value}
|
||||||
|
<div class:spectrum-FieldLabel--sizeS={s} class:spectrum-FieldLabel--sizeM={m} class:spectrum-FieldLabel--sizeL={l} class:spectrum-FieldLabel--sizeXL={xl} class="spectrum-FieldLabel spectrum-ProgressBar-percentage">{Math.round($progress)}%</div>
|
||||||
|
{/if}
|
||||||
|
<div class="spectrum-ProgressBar-track">
|
||||||
|
<div class="spectrum-ProgressBar-fill" style={value ? `width: ${$progress}%` : ''}></div>
|
||||||
|
</div>
|
||||||
|
<div class="spectrum-ProgressBar-label" hidden=""></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script>
|
||||||
|
// WIP! Does not yet work.
|
||||||
|
import "@spectrum-css/progresscircle/dist/index-vars.css"
|
||||||
|
import { tweened } from 'svelte/motion';
|
||||||
|
import { cubicOut } from 'svelte/easing';
|
||||||
|
|
||||||
|
export let value = false
|
||||||
|
export let small;
|
||||||
|
export let large;
|
||||||
|
|
||||||
|
export let overBackground;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class:spectrum-ProgressBar--indeterminate={!value} class:spectrum-ProgressCircle--small={small} class:spectrum-ProgressCircle--large={large} class="spectrum-ProgressCircle">
|
||||||
|
<div class="spectrum-ProgressCircle-track"></div>
|
||||||
|
<div class="spectrum-ProgressCircle-fills">
|
||||||
|
<div class="spectrum-ProgressCircle-fillMask1">
|
||||||
|
<div class="spectrum-ProgressCircle-fillSubMask1">
|
||||||
|
<div class="spectrum-ProgressCircle-fill"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="spectrum-ProgressCircle-fillMask2">
|
||||||
|
<div class="spectrum-ProgressCircle-fillSubMask2">
|
||||||
|
<div class="spectrum-ProgressCircle-fill"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
import { getContext, onMount } from 'svelte'
|
||||||
|
import Portal from "svelte-portal"
|
||||||
|
export let title
|
||||||
|
export let icon = '';
|
||||||
|
|
||||||
|
const selected = getContext('tab')
|
||||||
|
let tab;
|
||||||
|
let tabInfo
|
||||||
|
const setTabInfo = () => {
|
||||||
|
tabInfo = tab.getBoundingClientRect()
|
||||||
|
if ($selected.title === title) {
|
||||||
|
$selected.info = tabInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
setTabInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={tab} on:click={() => $selected = {...$selected, title, info: tab.getBoundingClientRect()} } class:is-selected={$selected.title === title} class="spectrum-Tabs-item" tabindex="0">
|
||||||
|
{#if icon}
|
||||||
|
<svg class="spectrum-Icon spectrum-Icon--sizeM" focusable="false" aria-hidden="true" aria-label="Folder">
|
||||||
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
<span class="spectrum-Tabs-itemLabel">{title}</span>
|
||||||
|
</div>
|
||||||
|
{#if $selected.title === title}
|
||||||
|
<Portal target=".spectrum-Tabs-content-{$selected.id}">
|
||||||
|
<slot />
|
||||||
|
</Portal>
|
||||||
|
{/if}
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/tabs/dist/index-vars.css"
|
||||||
|
import { writable } from 'svelte/store'
|
||||||
|
import { onMount, setContext, createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
|
export let selected;
|
||||||
|
export let vertical = false
|
||||||
|
let _id = id()
|
||||||
|
const tab = writable({title: selected, id: _id})
|
||||||
|
setContext('tab', tab)
|
||||||
|
|
||||||
|
let container;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
$: selected = $tab.title
|
||||||
|
$: selected = dispatch('select', selected)
|
||||||
|
|
||||||
|
let top, left, width, height;
|
||||||
|
$: calculateIndicatorLength($tab)
|
||||||
|
$: calculateIndicatorOffset($tab)
|
||||||
|
|
||||||
|
function calculateIndicatorLength() {
|
||||||
|
if (!vertical) {
|
||||||
|
width = $tab.info?.width + 24 + 'px'
|
||||||
|
height = $tab.info?.height
|
||||||
|
} else {
|
||||||
|
height = $tab.info?.height + 4 + 'px'
|
||||||
|
width = $tab.info?.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateIndicatorOffset() {
|
||||||
|
if (!vertical) {
|
||||||
|
left = $tab.info?.left - container?.getBoundingClientRect().left - 12 + 'px'
|
||||||
|
top = $tab.info?.top
|
||||||
|
} else {
|
||||||
|
top = $tab.info?.top - container?.getBoundingClientRect().top + 'px'
|
||||||
|
left = $tab.info?.left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
calculateIndicatorLength()
|
||||||
|
calculateIndicatorOffset()
|
||||||
|
})
|
||||||
|
|
||||||
|
function id() {
|
||||||
|
return (
|
||||||
|
"_" +
|
||||||
|
Math.random()
|
||||||
|
.toString(36)
|
||||||
|
.substr(2, 9)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<div bind:this={container} class="selected-border spectrum-Tabs spectrum-Tabs--{vertical ? 'vertical' : 'horizontal'}">
|
||||||
|
<slot />
|
||||||
|
<div class="spectrum-Tabs-selectionIndicator indicator-transition" style="width: {width}; height: {height}; left: {left}; top: {top};"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spectrum-Tabs-content spectrum-Tabs-content-{_id}" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.spectrum-Tabs-content {
|
||||||
|
margin-top: var(--spectrum-global-dimension-static-size-150);
|
||||||
|
}
|
||||||
|
.indicator-transition {
|
||||||
|
transition: all 200ms
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
export let xxxl = false;
|
||||||
|
export let xxl = false;
|
||||||
|
export let xl = false;
|
||||||
|
export let l = false;
|
||||||
|
export let m = false;
|
||||||
|
export let s = false;
|
||||||
|
export let xs = false;
|
||||||
|
export let xxs = false;
|
||||||
|
|
||||||
|
export let serif = false;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p class="spectrum-Body"
|
||||||
|
class:spectrum-Body--serif={serif}
|
||||||
|
class:spectrum-Body--sizeXXXL={xxxl}
|
||||||
|
class:spectrum-Body--sizeXXL={xxl}
|
||||||
|
class:spectrum-Body--sizeXL={xl}
|
||||||
|
class:spectrum-Body--sizeL={l}
|
||||||
|
class:spectrum-Body--sizeM={m}
|
||||||
|
class:spectrum-Body--sizeS={s}
|
||||||
|
class:spectrum-Body--sizeXS={xs}
|
||||||
|
class:spectrum-Body--sizeXXS={xxs}>
|
||||||
|
<slot />
|
||||||
|
</p>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
export let xl = false;
|
||||||
|
export let l = false;
|
||||||
|
export let m = false;
|
||||||
|
export let s = false;
|
||||||
|
export let xs = false;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<code class="spectrum-Code"
|
||||||
|
class:spectrum-Code--sizeXL={xl}
|
||||||
|
class:spectrum-Code--sizeL={l}
|
||||||
|
class:spectrum-Code--sizeM={m}
|
||||||
|
class:spectrum-Code--sizeS={s}
|
||||||
|
class:spectrum-Code--sizeXS={xs}>
|
||||||
|
<slot />
|
||||||
|
</code>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
export let xl = false;
|
||||||
|
export let l = false;
|
||||||
|
export let m = false;
|
||||||
|
export let s = false;
|
||||||
|
|
||||||
|
export let serif = false;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p class="spectrum-Detail"
|
||||||
|
class:spectrum-Detail--serif={serif}
|
||||||
|
class:spectrum-Detail--sizeXL={xl}
|
||||||
|
class:spectrum-Detail--sizeL={l}
|
||||||
|
class:spectrum-Detail--sizeM={m}
|
||||||
|
class:spectrum-Detail--sizeS={s}>
|
||||||
|
<slot />
|
||||||
|
</p>
|
|
@ -0,0 +1,78 @@
|
||||||
|
<script>
|
||||||
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
|
// Level
|
||||||
|
export let h1 = false;
|
||||||
|
export let h2 = false;
|
||||||
|
export let h3 = false;
|
||||||
|
export let h4 = false;
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
export let xxxl = false;
|
||||||
|
export let xxl = false;
|
||||||
|
export let xl = false;
|
||||||
|
export let l = false;
|
||||||
|
export let m = false;
|
||||||
|
export let s = false;
|
||||||
|
export let xs = false;
|
||||||
|
export let xxs = false;
|
||||||
|
|
||||||
|
export let serif = false;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if h1}
|
||||||
|
<h1 class="spectrum-Heading"
|
||||||
|
class:spectrum-Heading--serif={serif}
|
||||||
|
class:spectrum-Heading--sizeXXXL={xxxl}
|
||||||
|
class:spectrum-Heading--sizeXXL={xxl}
|
||||||
|
class:spectrum-Heading--sizeXL={xl}
|
||||||
|
class:spectrum-Heading--sizeL={l}
|
||||||
|
class:spectrum-Heading--sizeM={m}
|
||||||
|
class:spectrum-Heading--sizeS={s}
|
||||||
|
class:spectrum-Heading--sizeXS={xs}
|
||||||
|
class:spectrum-Heading--sizeXXS={xxs}>
|
||||||
|
<slot />
|
||||||
|
</h1>
|
||||||
|
{:else if h2}
|
||||||
|
<h2 class="spectrum-Heading"
|
||||||
|
class:spectrum-Heading--serif={serif}
|
||||||
|
class:spectrum-Heading--sizeXXXL={xxxl}
|
||||||
|
class:spectrum-Heading--sizeXXL={xxl}
|
||||||
|
class:spectrum-Heading--sizeXL={xl}
|
||||||
|
class:spectrum-Heading--sizeL={l}
|
||||||
|
class:spectrum-Heading--sizeM={m}
|
||||||
|
class:spectrum-Heading--sizeS={s}
|
||||||
|
class:spectrum-Heading--sizeXS={xs}
|
||||||
|
class:spectrum-Heading--sizeXXS={xxs}>
|
||||||
|
<slot />
|
||||||
|
</h2>
|
||||||
|
{:else if h3}
|
||||||
|
<h3 class="spectrum-Heading"
|
||||||
|
class:spectrum-Heading--serif={serif}
|
||||||
|
class:spectrum-Heading--sizeXXXL={xxxl}
|
||||||
|
class:spectrum-Heading--sizeXXL={xxl}
|
||||||
|
class:spectrum-Heading--sizeXL={xl}
|
||||||
|
class:spectrum-Heading--sizeL={l}
|
||||||
|
class:spectrum-Heading--sizeM={m}
|
||||||
|
class:spectrum-Heading--sizeS={s}
|
||||||
|
class:spectrum-Heading--sizeXS={xs}
|
||||||
|
class:spectrum-Heading--sizeXXS={xxs}>
|
||||||
|
<slot />
|
||||||
|
</h3>
|
||||||
|
{:else if h4}
|
||||||
|
<h4 class="spectrum-Heading"
|
||||||
|
class:spectrum-Heading--serif={serif}
|
||||||
|
class:spectrum-Heading--sizeXXXL={xxxl}
|
||||||
|
class:spectrum-Heading--sizeXXL={xxl}
|
||||||
|
class:spectrum-Heading--sizeXL={xl}
|
||||||
|
class:spectrum-Heading--sizeL={l}
|
||||||
|
class:spectrum-Heading--sizeM={m}
|
||||||
|
class:spectrum-Heading--sizeS={s}
|
||||||
|
class:spectrum-Heading--sizeXS={xs}
|
||||||
|
class:spectrum-Heading--sizeXXS={xxs}>
|
||||||
|
<slot />
|
||||||
|
</h4>
|
||||||
|
{:else}
|
||||||
|
SPECIFY HEADING SIZE!
|
||||||
|
{/if}
|
|
@ -21,8 +21,8 @@ export { default as DetailSummary } from "./List/Items/DetailSummary.svelte"
|
||||||
export { default as Switcher } from "./Switcher/Switcher.svelte"
|
export { default as Switcher } from "./Switcher/Switcher.svelte"
|
||||||
export { default as DropdownMenu } from "./DropdownMenu/DropdownMenu.svelte"
|
export { default as DropdownMenu } from "./DropdownMenu/DropdownMenu.svelte"
|
||||||
export { default as Popover } from "./Popover/Popover.svelte"
|
export { default as Popover } from "./Popover/Popover.svelte"
|
||||||
export { default as Body } from "./Styleguide/Body.svelte"
|
export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte"
|
||||||
export { default as Heading } from "./Styleguide/Heading.svelte"
|
export { default as ProgressCircle } from "./ProgressCircle/ProgressCircle.svelte"
|
||||||
export { default as Label } from "./Styleguide/Label.svelte"
|
export { default as Label } from "./Styleguide/Label.svelte"
|
||||||
export { default as Link } from "./Link/Link.svelte"
|
export { default as Link } from "./Link/Link.svelte"
|
||||||
export { default as Close } from "./Button/Close.svelte"
|
export { default as Close } from "./Button/Close.svelte"
|
||||||
|
@ -39,6 +39,16 @@ export { default as Multiselect } from "./Form/Multiselect.svelte"
|
||||||
export { default as Slider } from "./Form/Slider.svelte"
|
export { default as Slider } from "./Form/Slider.svelte"
|
||||||
export { default as Context } from "./context"
|
export { default as Context } from "./context"
|
||||||
export { default as Table } from "./Table/Table.svelte"
|
export { default as Table } from "./Table/Table.svelte"
|
||||||
|
export { default as Tabs } from "./Tabs/Tabs.svelte"
|
||||||
|
export { default as Tab } from "./Tabs/Tab.svelte"
|
||||||
|
export { default as Divider } from "./Divider/Divider.svelte"
|
||||||
|
|
||||||
|
// Typography
|
||||||
|
export { default as Body } from "./Typography/Body.svelte"
|
||||||
|
export { default as Heading } from "./Typography/Heading.svelte"
|
||||||
|
export { default as Detail } from "./Typography/Detail.svelte"
|
||||||
|
export { default as Code } from "./Typography/Code.svelte"
|
||||||
|
|
||||||
|
|
||||||
// Core form components to be used elsewhere (standard components)
|
// Core form components to be used elsewhere (standard components)
|
||||||
export * from "./Form/Core"
|
export * from "./Form/Core"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,12 +46,12 @@
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<Heading small>Available bindings</Heading>
|
<Heading s h3>Available bindings</Heading>
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
<Input extraThin placeholder="Search" bind:value={search} />
|
<Input extraThin placeholder="Search" bind:value={search} />
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
{#each categories as [categoryName, bindings]}
|
{#each categories as [categoryName, bindings]}
|
||||||
<Heading extraSmall>{categoryName}</Heading>
|
<Heading xs h4>{categoryName}</Heading>
|
||||||
<Spacer extraSmall />
|
<Spacer extraSmall />
|
||||||
{#each bindableProperties.filter(binding =>
|
{#each bindableProperties.filter(binding =>
|
||||||
binding.label.match(searchRgx)
|
binding.label.match(searchRgx)
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{/each}
|
{/each}
|
||||||
<Heading extraSmall>Helpers</Heading>
|
<Heading xs h3>Helpers</Heading>
|
||||||
<Spacer extraSmall />
|
<Spacer extraSmall />
|
||||||
{#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
|
{#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
|
||||||
<div class="binding" on:click={() => addToText(helper)}>
|
<div class="binding" on:click={() => addToText(helper)}>
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<Input extraThin placeholder="Search" bind:value={search} />
|
<Input extraThin placeholder="Search" bind:value={search} />
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
{#if context}
|
{#if context}
|
||||||
<Heading extraSmall>Columns</Heading>
|
<Heading xs h3>Columns</Heading>
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<ul>
|
<ul>
|
||||||
{#each context.filter(context =>
|
{#each context.filter(context =>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
{#if instance}
|
{#if instance}
|
||||||
<Heading extraSmall>Components</Heading>
|
<Heading xs h3>Components</Heading>
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<ul>
|
<ul>
|
||||||
{#each instance.filter(instance =>
|
{#each instance.filter(instance =>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
{/if}
|
{/if}
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<Heading extraSmall>Helpers</Heading>
|
<Heading xs h3>Helpers</Heading>
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<ul>
|
<ul>
|
||||||
{#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
|
{#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
|
||||||
|
|
|
@ -137,7 +137,7 @@
|
||||||
<DropdownMenu bind:this={dropdownRight} anchor={anchorRight}>
|
<DropdownMenu bind:this={dropdownRight} anchor={anchorRight}>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<Heading extraSmall>Tables</Heading>
|
<Heading xs h3>Tables</Heading>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
{#each tables as table}
|
{#each tables as table}
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<Heading extraSmall>Views</Heading>
|
<Heading xs h3>Views</Heading>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
{#each views as view}
|
{#each views as view}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="apps-card">
|
<div class="apps-card">
|
||||||
<Heading small black>{name}</Heading>
|
<Heading s h3>{name}</Heading>
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
<div class="card-footer" data-cy={`app-${name}`}>
|
<div class="card-footer" data-cy={`app-${name}`}>
|
||||||
<ActionButton text medium blue on:click={() => $goto(`/builder/${_id}`)}>
|
<ActionButton text medium blue on:click={() => $goto(`/builder/${_id}`)}>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import AppCard from "./AppCard.svelte"
|
import AppCard from "./AppCard.svelte"
|
||||||
import { Heading } from "@budibase/bbui"
|
import { Heading, Divider } from "@budibase/bbui"
|
||||||
import Spinner from "components/common/Spinner.svelte"
|
import Spinner from "components/common/Spinner.svelte"
|
||||||
import { get } from "builderStore/api"
|
import { get } from "builderStore/api"
|
||||||
|
|
||||||
|
@ -19,23 +19,18 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<Heading lh medium black>Your Apps</Heading>
|
<Heading m h2>Your Apps</Heading>
|
||||||
|
<Divider s />
|
||||||
{#await promise}
|
{#await promise}
|
||||||
<div class="spinner-container">
|
<div class="spinner-container">
|
||||||
<Spinner size="30" />
|
<Spinner size="30" />
|
||||||
</div>
|
</div>
|
||||||
{:then apps}
|
{:then apps}
|
||||||
<div class="inner">
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<div class="apps">
|
<div class="apps">
|
||||||
{#each apps as app}
|
{#each apps as app}
|
||||||
<AppCard {...app} />
|
<AppCard {...app} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:catch err}
|
{:catch err}
|
||||||
<h1 style="color:red">{err}</h1>
|
<h1 style="color:red">{err}</h1>
|
||||||
{/await}
|
{/await}
|
||||||
|
@ -43,6 +38,7 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.apps {
|
.apps {
|
||||||
|
margin-top: var(--spectrum-global-dimension-static-size-150);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||||
grid-gap: var(--layout-m);
|
grid-gap: var(--layout-m);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import AppList from "components/start/AppList.svelte"
|
import AppList from "components/start/AppList.svelte"
|
||||||
import { get } from "builderStore/api"
|
import { get } from "builderStore/api"
|
||||||
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
||||||
import { Button, Heading, Modal, Spacer, Menu, MenuSection, MenuItem } from "@budibase/bbui"
|
import { Button, Heading, Modal, Spacer, Divider } from "@budibase/bbui"
|
||||||
import TemplateList from "components/start/TemplateList.svelte"
|
import TemplateList from "components/start/TemplateList.svelte"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
import Banner from "/assets/orange-landscape.png"
|
import Banner from "/assets/orange-landscape.png"
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<Heading medium black>Welcome to the Budibase Beta</Heading>
|
<Heading m h1>Welcome to the Budibase Beta</Heading>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<Button secondary on:click={initiateAppImport}>Import Web App</Button>
|
<Button secondary on:click={initiateAppImport}>Import Web App</Button>
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
|
|
|
@ -18,58 +18,5 @@ function hasResource(ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
module.exports = (permType, permLevel = null) => async (ctx, next) => {
|
||||||
if (env.isProd() && ctx.headers["x-api-key"] && ctx.headers["x-instanceid"]) {
|
|
||||||
// api key header passed by external webhook
|
|
||||||
if (await isAPIKeyValid(ctx.headers["x-api-key"])) {
|
|
||||||
ctx.auth = {
|
|
||||||
authenticated: AuthTypes.EXTERNAL,
|
|
||||||
apiKey: ctx.headers["x-api-key"],
|
|
||||||
}
|
|
||||||
ctx.user = {
|
|
||||||
appId: ctx.headers["x-instanceid"],
|
|
||||||
}
|
|
||||||
return next()
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx.throw(403, "API key invalid")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctx.user) {
|
|
||||||
return ctx.throw(403, "No user info found")
|
|
||||||
}
|
|
||||||
|
|
||||||
const role = ctx.user.role
|
|
||||||
const isAdmin = ADMIN_ROLES.includes(role._id)
|
|
||||||
const isAuthed = ctx.auth.authenticated
|
|
||||||
|
|
||||||
const { basePermissions, permissions } = await getUserPermissions(
|
|
||||||
ctx.appId,
|
|
||||||
role._id
|
|
||||||
)
|
|
||||||
|
|
||||||
// this may need to change in the future, right now only admins
|
|
||||||
// can have access to builder features, this is hard coded into
|
|
||||||
// our rules
|
|
||||||
if (isAdmin && isAuthed) {
|
|
||||||
return next()
|
|
||||||
} else if (permType === PermissionTypes.BUILDER) {
|
|
||||||
return ctx.throw(403, "Not Authorized")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
hasResource(ctx) &&
|
|
||||||
doesHaveResourcePermission(permissions, permLevel, ctx)
|
|
||||||
) {
|
|
||||||
return next()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAuthed) {
|
|
||||||
ctx.throw(403, "Session not authenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
|
|
||||||
ctx.throw(403, "User does not have permission")
|
|
||||||
}
|
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue