Merge pull request #213 from Budibase/simplified-component-panel-generic-tabs
makes the Component panel tabs more generic
This commit is contained in:
commit
f86b1beb5c
|
@ -20,7 +20,7 @@
|
||||||
pipe,
|
pipe,
|
||||||
} from "components/common/core"
|
} from "components/common/core"
|
||||||
|
|
||||||
import Tab from "./ComponentTab/Tab.svelte"
|
import Tab from "./ItemTab/Tab.svelte"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
|
|
||||||
export let toggleTab
|
export let toggleTab
|
||||||
|
@ -51,6 +51,15 @@
|
||||||
selectTemplateDialog.show()
|
selectTemplateDialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onComponentChosen = component => {
|
||||||
|
if (component.template) {
|
||||||
|
onTemplateChosen(component.template)
|
||||||
|
} else {
|
||||||
|
store.addChildComponent(component._component)
|
||||||
|
toggleTab()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onTemplateInstanceChosen = () => {
|
const onTemplateInstanceChosen = () => {
|
||||||
selectedComponent = null
|
selectedComponent = null
|
||||||
const instance = templateInstances.find(
|
const instance = templateInstances.find(
|
||||||
|
@ -63,16 +72,13 @@
|
||||||
$: templatesByComponent = groupBy(t => t.component)($store.templates)
|
$: templatesByComponent = groupBy(t => t.component)($store.templates)
|
||||||
$: hierarchy = $store.hierarchy
|
$: hierarchy = $store.hierarchy
|
||||||
$: libraryModules = $store.libraries
|
$: libraryModules = $store.libraries
|
||||||
$: standaloneTemplates = pipe(
|
$: standaloneTemplates = pipe(templatesByComponent, [
|
||||||
templatesByComponent,
|
|
||||||
[
|
|
||||||
values,
|
values,
|
||||||
flatten,
|
flatten,
|
||||||
filter(t => !$store.components.some(c => c.name === t.component)),
|
filter(t => !$store.components.some(c => c.name === t.component)),
|
||||||
map(t => ({ name: splitName(t.component).componentName, template: t })),
|
map(t => ({ name: splitName(t.component).componentName, template: t })),
|
||||||
uniqBy(t => t.name),
|
uniqBy(t => t.name),
|
||||||
]
|
])
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
@ -86,7 +92,9 @@
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<Tab list={selectedCategory} {onTemplateChosen} />
|
<Tab
|
||||||
|
list={selectedCategory}
|
||||||
|
on:selectItem={e => onComponentChosen(e.detail)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<script>
|
<script>
|
||||||
export let component
|
export let item
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="component-item" on:click>
|
<div class="item-item" on:click>
|
||||||
<div class="component-icon">
|
<div class="item-icon">
|
||||||
<i class={component.icon} />
|
<i class={item.icon} />
|
||||||
</div>
|
</div>
|
||||||
<div class="component-text">
|
<div class="item-text">
|
||||||
<div class="component-name">{component.name}</div>
|
<div class="item-name">{item.name}</div>
|
||||||
<div class="component-description">
|
<div class="item-description">
|
||||||
<p>{component.description}</p>
|
<p>{item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.component-item {
|
.item-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 10px 0px 8px 10px;
|
padding: 10px 0px 8px 10px;
|
||||||
|
@ -23,13 +23,13 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-item:hover {
|
.item-item:hover {
|
||||||
/* background: #f5f5f5; */
|
/* background: #f5f5f5; */
|
||||||
background: #fbfbfb;
|
background: #fbfbfb;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-icon {
|
.item-icon {
|
||||||
flex: 0 0 40px;
|
flex: 0 0 40px;
|
||||||
/* background: #efe9e9; */
|
/* background: #efe9e9; */
|
||||||
background: #f1f4fc;
|
background: #f1f4fc;
|
||||||
|
@ -40,19 +40,19 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-text {
|
.item-text {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-name {
|
.item-name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-description {
|
.item-description {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #808192;
|
color: #808192;
|
||||||
}
|
}
|
|
@ -1,24 +1,17 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
import Item from "./Item.svelte"
|
import Item from "./Item.svelte"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
export let list
|
export let list
|
||||||
export let onTemplateChosen
|
|
||||||
let category = list
|
let category = list
|
||||||
|
|
||||||
const onComponentChosen = component => {
|
const handleClick = item => {
|
||||||
if (component.template) {
|
if (item.children && item.children.length > 0) {
|
||||||
onTemplateChosen(component.template)
|
list = item
|
||||||
} else {
|
} else {
|
||||||
store.addChildComponent(component._component)
|
dispatch("selectItem", item)
|
||||||
toggleTab()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleClick = component => {
|
|
||||||
if (component.type && component.type.length > 0) {
|
|
||||||
list = component
|
|
||||||
} else {
|
|
||||||
onComponentChosen(component)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +24,8 @@
|
||||||
<button class="back-button" on:click={() => (list = category)}>Back</button>
|
<button class="back-button" on:click={() => (list = category)}>Back</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#each list.type as component}
|
{#each list.children as item}
|
||||||
<Item {component} on:click={() => handleClick(component)} />
|
<Item {item} on:click={() => handleClick(item)} />
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<style>
|
<style>
|
|
@ -3,20 +3,20 @@ export default {
|
||||||
{
|
{
|
||||||
name: 'Basic',
|
name: 'Basic',
|
||||||
isCategory: true,
|
isCategory: true,
|
||||||
type: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'Container',
|
name: 'Container',
|
||||||
description: 'This component contains things within itself',
|
description: 'This component contains things within itself',
|
||||||
icon: 'ri-layout-row-fill',
|
icon: 'ri-layout-row-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Text',
|
name: 'Text',
|
||||||
description: 'This is a simple text component',
|
description: 'This is a simple text component',
|
||||||
icon: 'ri-t-box-fill',
|
icon: 'ri-t-box-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: [
|
children: [
|
||||||
{
|
{
|
||||||
_component: '@budibase/standard-components/heading',
|
_component: '@budibase/standard-components/heading',
|
||||||
name: 'Headline',
|
name: 'Headline',
|
||||||
|
@ -45,102 +45,102 @@ export default {
|
||||||
description: 'A basic html button that is ready for styling',
|
description: 'A basic html button that is ready for styling',
|
||||||
icon: 'ri-radio-button-fill',
|
icon: 'ri-radio-button-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Icon',
|
name: 'Icon',
|
||||||
description: 'A basic component for displaying icons',
|
description: 'A basic component for displaying icons',
|
||||||
icon: 'ri-sun-fill',
|
icon: 'ri-sun-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Avatar',
|
name: 'Avatar',
|
||||||
description: 'A basic component for rendering an avatar',
|
description: 'A basic component for rendering an avatar',
|
||||||
icon: 'ri-user-smile-fill',
|
icon: 'ri-user-smile-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Link',
|
name: 'Link',
|
||||||
description: 'A basic link component for internal and external links',
|
description: 'A basic link component for internal and external links',
|
||||||
icon: 'ri-link',
|
icon: 'ri-link',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Form',
|
name: 'Form',
|
||||||
isCategory: true,
|
isCategory: true,
|
||||||
type: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'Button',
|
name: 'Button',
|
||||||
description: 'A basic html button that is ready for styling',
|
description: 'A basic html button that is ready for styling',
|
||||||
icon: 'ri-radio-button-fill',
|
icon: 'ri-radio-button-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Icon',
|
name: 'Icon',
|
||||||
description: 'A basic component for displaying icons',
|
description: 'A basic component for displaying icons',
|
||||||
icon: 'ri-sun-fill',
|
icon: 'ri-sun-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Avatar',
|
name: 'Avatar',
|
||||||
description: 'A basic component for rendering an avatar',
|
description: 'A basic component for rendering an avatar',
|
||||||
icon: 'ri-user-smile-fill',
|
icon: 'ri-user-smile-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Link',
|
name: 'Link',
|
||||||
description: 'A basic link component for internal and external links',
|
description: 'A basic link component for internal and external links',
|
||||||
icon: 'ri-link',
|
icon: 'ri-link',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Blocks',
|
name: 'Blocks',
|
||||||
isCategory: true,
|
isCategory: true,
|
||||||
type: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'Card',
|
name: 'Card',
|
||||||
description: 'A basic card component that can contain content and actions.',
|
description: 'A basic card component that can contain content and actions.',
|
||||||
icon: 'ri-layout-bottom-line',
|
icon: 'ri-layout-bottom-line',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
description: 'A component that automatically generates a login screen for your app.',
|
description: 'A component that automatically generates a login screen for your app.',
|
||||||
icon: 'ri-login-box-fill',
|
icon: 'ri-login-box-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Navbar',
|
name: 'Navbar',
|
||||||
description: 'A component for handling the navigation within your app.',
|
description: 'A component for handling the navigation within your app.',
|
||||||
icon: 'ri-navigation-fill',
|
icon: 'ri-navigation-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Data',
|
name: 'Data',
|
||||||
isCategory: true,
|
isCategory: true,
|
||||||
type: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'Table',
|
name: 'Table',
|
||||||
description: 'A component that generates a table from your data.',
|
description: 'A component that generates a table from your data.',
|
||||||
icon: 'ri-archive-drawer-fill',
|
icon: 'ri-archive-drawer-fill',
|
||||||
commonProps: {},
|
commonProps: {},
|
||||||
type: []
|
children: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Form',
|
name: 'Form',
|
||||||
|
@ -153,7 +153,7 @@ export default {
|
||||||
description: "Form for saving a record",
|
description: "Form for saving a record",
|
||||||
name: "@budibase/materialdesign-components/recordForm",
|
name: "@budibase/materialdesign-components/recordForm",
|
||||||
},
|
},
|
||||||
type: []
|
children: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue