Merge branch 'spectrum-bbui' of github.com:Budibase/budibase into spectrum-bbui-forms

This commit is contained in:
Andrew Kingston 2021-04-20 14:06:33 +01:00
commit 6ac5a999cb
14 changed files with 203 additions and 149 deletions

View File

@ -59,7 +59,9 @@
{/if} {/if}
</button> </button>
<style> <style>
span {
</style> text-transform: capitalize;
}
</style>

View File

@ -0,0 +1,25 @@
<form class="spectrum-Search">
<div class="spectrum-Textfield">
<svg
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon"
focusable="false"
aria-hidden="true">
<use xlink:href="#spectrum-icon-18-Magnify" />
</svg>
<input
type="search"
placeholder="Search"
name="search"
value=""
class="spectrum-Textfield-input spectrum-Search-input"
autocomplete="off" />
</div>
<button type="reset" class="spectrum-ClearButton spectrum-Search-clearButton">
<svg
class="spectrum-Icon spectrum-UIIcon-Cross75"
focusable="false"
aria-hidden="true">
<use xlink:href="#spectrum-css-icon-Cross75" />
</svg>
</button>
</form>

View File

@ -0,0 +1,19 @@
<script context="module">
export const directions = ["n", "ne", "e", "se", "s", "sw", "w", "nw"]
</script>
<script>
export let direction = "n"
export let name = "Add"
export let hidden = false
export let s = false
export let m = false;
export let l = false;
export let xl = false
$: rotation = directions.indexOf(direction) * 45
</script>
<svg on:click class:spectrum-Icon--sizeS={s} class:spectrum-Icon--sizeM={m} class:spectrum-Icon--sizeL={l} class:spectrum-Icon--sizeXL={xl} class="spectrum-Icon" focusable="false" aria-hidden={hidden} aria-label="{name}" style={`transform: rotate(${rotation}deg)`}>
<use xlink:href="#spectrum-icon-18-{name}" />
</svg>

View File

@ -11,7 +11,7 @@ export { default as ActionButton } from "./ActionButton/ActionButton.svelte"
export { default as ActionGroup } from "./ActionGroup/ActionGroup.svelte" export { default as ActionGroup } from "./ActionGroup/ActionGroup.svelte"
export { default as ActionMenu } from "./ActionMenu/ActionMenu.svelte" export { default as ActionMenu } from "./ActionMenu/ActionMenu.svelte"
export { default as Button } from "./Button/Button.svelte" export { default as Button } from "./Button/Button.svelte"
export { default as Icon, iconOptions, directions } from "./Icons/Icon.svelte" export { default as Icon, directions } from "./Icon/Icon.svelte"
export { default as Toggle } from "./Form/Toggle.svelte" export { default as Toggle } from "./Form/Toggle.svelte"
export { default as RadioGroup } from "./Form/RadioGroup.svelte" export { default as RadioGroup } from "./Form/RadioGroup.svelte"
export { default as Checkbox } from "./Form/Checkbox.svelte" export { default as Checkbox } from "./Form/Checkbox.svelte"
@ -40,6 +40,7 @@ export { default as Table } from "./Table/Table.svelte"
export { default as Tabs } from "./Tabs/Tabs.svelte" export { default as Tabs } from "./Tabs/Tabs.svelte"
export { default as Tab } from "./Tabs/Tab.svelte" export { default as Tab } from "./Tabs/Tab.svelte"
export { default as Divider } from "./Divider/Divider.svelte" export { default as Divider } from "./Divider/Divider.svelte"
export { default as Search } from "./Form/Search.svelte"
// Typography // Typography
export { default as Body } from "./Typography/Body.svelte" export { default as Body } from "./Typography/Body.svelte"

View File

@ -1,33 +1,45 @@
<script> <script>
import AutomationList from "./AutomationList.svelte" import AutomationList from "./AutomationList.svelte"
import CreateAutomationModal from "./CreateAutomationModal.svelte" import CreateAutomationModal from "./CreateAutomationModal.svelte"
import { Modal } from "@budibase/bbui" import { Modal, Tabs, Tab } from "@budibase/bbui"
let modal let modal
</script> </script>
<div class="title"> <div class="title">
<h1>Automations</h1> <Tabs selected="Automations">
<Tab title="Automations">
<div class="tab-content-padding">
<AutomationList />
<Modal bind:this={modal}>
<CreateAutomationModal />
</Modal>
</div>
</Tab>
</Tabs>
<i <i
on:click={modal.show} on:click={modal.show}
data-cy="new-automation" data-cy="new-automation"
class="ri-add-circle-fill" /> class="ri-add-circle-fill" />
</div> </div>
<AutomationList />
<Modal bind:this={modal}>
<CreateAutomationModal />
</Modal>
<style> <style>
.tab-content-padding {
padding: 0 var(--spacing-s);
}
i {
font-size: 20px;
position: absolute;
top: var(--spacing-l);
right: var(--spacing-l);
}
.title { .title {
display: flex; display: flex;
flex-direction: row; flex-direction: column;
justify-content: space-between; justify-content: flex-start;
align-items: center; align-items: stretch;
} position: relative;
.title h1 {
font-size: var(--font-size-m);
font-weight: 500;
margin: 0;
} }
.title i { .title i {
font-size: 20px; font-size: 20px;

View File

@ -8,12 +8,11 @@
screenSearchString, screenSearchString,
} from "builderStore" } from "builderStore"
import { roles } from "stores/backend" import { roles } from "stores/backend"
import { FrontendTypes } from "constants"
import ComponentNavigationTree from "components/design/NavigationPanel/ComponentNavigationTree/index.svelte" import ComponentNavigationTree from "components/design/NavigationPanel/ComponentNavigationTree/index.svelte"
import Layout from "components/design/NavigationPanel/Layout.svelte" import Layout from "components/design/NavigationPanel/Layout.svelte"
import NewScreenModal from "components/design/NavigationPanel/NewScreenModal.svelte" import NewScreenModal from "components/design/NavigationPanel/NewScreenModal.svelte"
import NewLayoutModal from "components/design/NavigationPanel/NewLayoutModal.svelte" import NewLayoutModal from "components/design/NavigationPanel/NewLayoutModal.svelte"
import { Modal, Switcher, Select, Input } from "@budibase/bbui" import { Modal, Select, Input, Tabs, Tab } from "@budibase/bbui"
const tabs = [ const tabs = [
{ {
@ -27,14 +26,11 @@
] ]
let modal let modal
let routes = {} $: selected = tabs.find(t => t.key === $params.assetType).title
$: tab = $params.assetType
const navigate = ({ detail }) => { const navigate = ({ detail }) => {
if (!detail) { const { key } = tabs.find(t => t.title === detail)
return $goto(`../${key}`)
}
$goto(`../${detail.heading.key}`)
} }
const updateAccessRole = event => { const updateAccessRole = event => {
@ -68,52 +64,51 @@
</script> </script>
<div class="title"> <div class="title">
<Switcher headings={tabs} bind:value={tab} on:change={navigate}> <Tabs {selected} on:select={navigate}>
{#if tab === FrontendTypes.SCREEN} <Tab title="Screens">
<i <div class="tab-content-padding">
on:click={modal.show} <div class="role-select">
data-cy="new-screen" <Select
class="ri-add-circle-fill" /> on:change={updateAccessRole}
<div class="role-select"> value={$selectedAccessRole}
<Select label="Filter by Access"
extraThin getOptionLabel={role => role.name}
secondary getOptionValue={role => role._id}
on:change={updateAccessRole} options={$roles} />
value={$selectedAccessRole} <div class="search-screens">
label="Filter by Access" <Input
getOptionLabel={role => role.name} placeholder="Enter a route to search"
getOptionValue={role => role._id} label="Search Screens"
options={$roles} /> bind:value={$screenSearchString} />
<div class="search-screens"> <i
<Input class="ri-close-line"
extraThin on:click={() => ($screenSearchString = null)} />
placeholder="Enter a route to search" </div>
label="Search Screens"
bind:value={$screenSearchString} />
<i
class="ri-close-line"
on:click={() => ($screenSearchString = null)} />
</div> </div>
<div class="nav-items-container">
<ComponentNavigationTree />
</div>
<Modal bind:this={modal}>
<NewScreenModal />
</Modal>
</div> </div>
<div class="nav-items-container"> </Tab>
<ComponentNavigationTree /> <Tab title="Layouts">
<div class="tab-content-padding">
<i
on:click={modal.show}
data-cy="new-layout"
class="ri-add-circle-fill" />
{#each $store.layouts as layout, idx (layout._id)}
<Layout {layout} border={idx > 0} />
{/each}
<Modal bind:this={modal}>
<NewLayoutModal />
</Modal>
</div> </div>
<Modal bind:this={modal}> </Tab>
<NewScreenModal /> </Tabs>
</Modal> <i on:click={modal.show} data-cy="new-screen" class="ri-add-circle-fill" />
{:else if tab === FrontendTypes.LAYOUT}
<i
on:click={modal.show}
data-cy="new-layout"
class="ri-add-circle-fill" />
{#each $store.layouts as layout, idx (layout._id)}
<Layout {layout} border={idx > 0} />
{/each}
<Modal bind:this={modal}>
<NewLayoutModal />
</Modal>
{/if}
</Switcher>
</div> </div>
<style> <style>
@ -127,8 +122,8 @@
.title i { .title i {
font-size: 20px; font-size: 20px;
position: absolute; position: absolute;
top: 0; top: var(--spacing-l);
right: 0; right: var(--spacing-l);
} }
.title i:hover { .title i:hover {
cursor: pointer; cursor: pointer;
@ -144,6 +139,10 @@
gap: var(--spacing-m); gap: var(--spacing-m);
} }
.tab-content-padding {
padding: 0 var(--spacing-s);
}
.search-screens { .search-screens {
position: relative; position: relative;
} }

View File

@ -1,6 +1,7 @@
<script> <script>
import { get } from "svelte/store" import { get } from "svelte/store"
import { store, selectedComponent, currentAsset } from "builderStore" import { store, selectedComponent, currentAsset } from "builderStore"
import { Tabs, Tab } from '@budibase/bbui'
import { FrontendTypes } from "constants" import { FrontendTypes } from "constants"
import CategoryTab from "./CategoryTab.svelte" import CategoryTab from "./CategoryTab.svelte"
import DesignView from "./DesignView.svelte" import DesignView from "./DesignView.svelte"
@ -44,47 +45,46 @@
} }
</script> </script>
<CategoryTab <Tabs selected="Settings">
onClick={category => (selectedCategory = category)} <Tab title="Settings">
{categories} <div class="tab-content-padding">
{selectedCategory} /> {#if definition && definition.name}
<div class="instance-name">{definition.name}</div>
{#if definition && definition.name} {/if}
<div class="instance-name">{definition.name}</div> <SettingsView
{/if}
<div class="component-props-container">
{#if selectedCategory.value === 'design'}
<DesignView
componentInstance={$selectedComponent}
componentDefinition={definition}
{onStyleChanged}
{onCustomStyleChanged}
{onUpdateTransition}
{onResetStyles} />
{:else if selectedCategory.value === 'settings'}
<SettingsView
componentInstance={$selectedComponent} componentInstance={$selectedComponent}
componentDefinition={definition} componentDefinition={definition}
{showDisplayName} {showDisplayName}
onChange={store.actions.components.updateProp} onChange={store.actions.components.updateProp}
onScreenPropChange={setAssetProps} onScreenPropChange={setAssetProps}
assetInstance={$store.currentView !== 'component' && $currentAsset} /> assetInstance={$store.currentView !== 'component' && $currentAsset} />
{/if} </div>
</div> </Tab>
<Tab title="Design">
<div class="tab-content-padding">
{#if definition && definition.name}
<div class="instance-name">{definition.name}</div>
{/if}
<DesignView
componentInstance={$selectedComponent}
componentDefinition={definition}
{onStyleChanged}
{onCustomStyleChanged}
{onUpdateTransition}
{onResetStyles} />
</div>
</Tab>
</Tabs>
<style> <style>
.component-props-container {
flex: 1 1 auto; .tab-content-padding {
min-height: 0; padding: 0 var(--spacing-s);
overflow-y: auto;
margin-left: -20px;
margin-right: -20px;
padding: 0 20px;
} }
.instance-name { .instance-name {
font-size: var(--font-size-xs); font-size: var(--font-size-xs);
margin-bottom: var(--spacing-l);
font-weight: 500; font-weight: 500;
color: var(--grey-7); color: var(--grey-7);
} }

View File

@ -1,6 +1,6 @@
<script> <script>
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { ActionButton, Heading, Spacer } from "@budibase/bbui" import { ActionButton, Heading, Spacer, Icon } from "@budibase/bbui"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
import Spinner from "components/common/Spinner.svelte" import Spinner from "components/common/Spinner.svelte"
import download from "downloadjs" import download from "downloadjs"
@ -36,7 +36,7 @@
</ActionButton> </ActionButton>
{#if appExportLoading} {#if appExportLoading}
<Spinner size="10" /> <Spinner size="10" />
{:else}<i class="ri-folder-download-line" on:click={exportApp} />{/if} {:else}<ActionButton icon="Download" quiet />{/if}
</div> </div>
</div> </div>

View File

@ -6,7 +6,7 @@
</script> </script>
<div> <div>
<Button overBackground quiet icon="Settings" text on:click={modal.show}> <Button primary quiet icon="Settings" text on:click={modal.show}>
Settings Settings
</Button> </Button>
</div> </div>

View File

@ -1,7 +1,7 @@
<script> <script>
import { store, automationStore } from "builderStore" import { store, automationStore } from "builderStore"
import { roles } from "stores/backend" import { roles } from "stores/backend"
import { Button } from "@budibase/bbui" import { Button, ActionGroup, ActionButton, Icon } from "@budibase/bbui"
import SettingsLink from "components/settings/Link.svelte" import SettingsLink from "components/settings/Link.svelte"
import ThemeEditorDropdown from "components/settings/ThemeEditorDropdown.svelte" import ThemeEditorDropdown from "components/settings/ThemeEditorDropdown.svelte"
import FeedbackNavLink from "components/feedback/FeedbackNavLink.svelte" import FeedbackNavLink from "components/feedback/FeedbackNavLink.svelte"
@ -60,14 +60,11 @@
</button> </button>
<!-- This gets all indexable subroutes and sticks them in the top nav. --> <!-- This gets all indexable subroutes and sticks them in the top nav. -->
{#each $layout.children as { path, title }} <ActionGroup>
<span {#each $layout.children as { path, title }}
class:active={$isActive(path)} <ActionButton quiet selected={$isActive(path)} on:click={topItemNavigate(path)}>{title}</ActionButton>
class="topnavitem" {/each}
on:click={topItemNavigate(path)}> </ActionGroup>
{title}
</span>
{/each}
</div> </div>
<div class="toprightnav"> <div class="toprightnav">
<ThemeEditorDropdown /> <ThemeEditorDropdown />
@ -76,6 +73,7 @@
<a <a
target="_blank" target="_blank"
href="https://github.com/Budibase/budibase/discussions"> href="https://github.com/Budibase/budibase/discussions">
<Icon />
<i class="ri-github-fill" /> <i class="ri-github-fill" />
</a> </a>
</div> </div>
@ -144,7 +142,7 @@
.topleftnav { .topleftnav {
display: flex; display: flex;
align-items: center; place-items: center;
} }
.topnavitem { .topnavitem {

View File

@ -28,13 +28,10 @@
.nav { .nav {
overflow-y: auto; overflow-y: auto;
background: var(--background);
padding: var(--spacing-l) var(--spacing-xl);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: var(--spacing-l);
border-right: var(--border-light); border-right: var(--border-light);
} }

View File

@ -1,6 +1,6 @@
<script> <script>
import { isActive, goto } from "@roxi/routify" import { isActive, goto } from "@roxi/routify"
import { Switcher, Modal } from "@budibase/bbui" import { Switcher, Modal, Tabs, Tab } from "@budibase/bbui"
import TableNavigator from "components/backend/TableNavigator/TableNavigator.svelte" import TableNavigator from "components/backend/TableNavigator/TableNavigator.svelte"
import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte" import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte"
import CreateDatasourceModal from "components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte" import CreateDatasourceModal from "components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte"
@ -17,11 +17,11 @@
}, },
] ]
let tab = $isActive("./datasource") ? "datasource" : "table" let selected = $isActive("./datasource") ? "External" : "Internal"
function selectFirstTableOrSource({ detail }) { function selectFirstTableOrSource({ detail }) {
const type = detail.heading.key const { key } = tabs.find(t => t.title === detail)
if (type === "datasource") { if (key === "datasource") {
$goto("./datasource") $goto("./datasource")
} else { } else {
$goto("./table") $goto("./table")
@ -34,28 +34,30 @@
<!-- routify:options index=0 --> <!-- routify:options index=0 -->
<div class="root"> <div class="root">
<div class="nav"> <div class="nav">
<Switcher <Tabs {selected} on:select={selectFirstTableOrSource}>
headings={tabs} <Tab title="Internal">
bind:value={tab} <div class="tab-content-padding">
on:change={selectFirstTableOrSource}> <TableNavigator />
<div class="title"> <Modal bind:this={modal}>
<i <CreateTableModal />
data-cy={`new-${tab}`} </Modal>
class="ri-add-circle-fill" </div>
on:click={modal.show} /> </Tab>
</div> <Tab title="External">
{#if tab === 'table'} <div class="tab-content-padding">
<TableNavigator /> <DatasourceNavigator />
<Modal bind:this={modal}> <Modal bind:this={modal}>
<CreateTableModal /> <CreateDatasourceModal />
</Modal> </Modal>
{:else if tab === 'datasource'} </div>
<DatasourceNavigator /> </Tab>
<Modal bind:this={modal}> </Tabs>
<CreateDatasourceModal /> <div class="title">
</Modal> <i
{/if} data-cy={`new-${selected === 'External' ? 'datasource' : 'tabel'}`}
</Switcher> class="ri-add-circle-fill"
on:click={modal.show} />
</div>
</div> </div>
<div class="content"> <div class="content">
<slot /> <slot />
@ -84,16 +86,17 @@
.content :global(> span) { .content :global(> span) {
display: contents; display: contents;
} }
.tab-content-padding {
padding: 0 var(--spacing-s);
}
.nav { .nav {
overflow-y: auto; overflow-y: auto;
background: var(--background); background: var(--background);
padding: var(--spacing-l) var(--spacing-xl);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: var(--spacing-l);
position: relative; position: relative;
border-right: var(--border-light); border-right: var(--border-light);
} }
@ -102,7 +105,7 @@
font-size: 20px; font-size: 20px;
position: absolute; position: absolute;
top: var(--spacing-l); top: var(--spacing-l);
right: var(--spacing-xl); right: var(--spacing-l);
} }
i:hover { i:hover {

View File

@ -5,7 +5,7 @@
onMount(async () => { onMount(async () => {
// navigate to first table in list, if not already selected // navigate to first table in list, if not already selected
$datasources.list.length > 0 && $goto(`../${$datasources.list[0]._id}`) $datasources.list.length > 0 && $goto(`./${$datasources.list[0]._id}`)
}) })
</script> </script>

View File

@ -177,7 +177,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--spacing-l); gap: var(--spacing-l);
padding: var(--spacing-l) var(--spacing-xl) 60px var(--spacing-xl); padding: 0 0 60px 0;
overflow-y: auto; overflow-y: auto;
border-right: var(--border-light); border-right: var(--border-light);
} }
@ -206,8 +206,6 @@
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: var(--spacing-l);
padding: var(--spacing-l) var(--spacing-xl);
border-left: var(--border-light); border-left: var(--border-light);
overflow-x: hidden; overflow-x: hidden;
} }