new backend beginnings

This commit is contained in:
Martin McKeaveney 2020-03-10 13:53:23 +00:00
parent 88f1129688
commit c777e2ff03
14 changed files with 306 additions and 128 deletions

View File

@ -1,5 +1,6 @@
<script> <script>
import BackendNav from "./nav/BackendNav.svelte" import BackendNav from "./nav/BackendNav.svelte"
import SchemaManagementDrawer from "./nav/SchemaManagementDrawer.svelte"
import Database from "./database/DatabaseRoot.svelte" import Database from "./database/DatabaseRoot.svelte"
import UserInterface from "./userInterface/UserInterfaceRoot.svelte" import UserInterface from "./userInterface/UserInterfaceRoot.svelte"
import ActionsAndTriggers from "./actionsAndTriggers/ActionsAndTriggersRoot.svelte" import ActionsAndTriggers from "./actionsAndTriggers/ActionsAndTriggersRoot.svelte"
@ -7,8 +8,11 @@
import ComingSoon from "./common/ComingSoon.svelte" import ComingSoon from "./common/ComingSoon.svelte"
import { store } from "./builderStore" import { store } from "./builderStore"
import { setContext } from 'svelte';
export let navWidth = "50px" let activeNav = "database";
setContext("activeNav", activeNav);
</script> </script>
<div class="root"> <div class="root">
@ -16,29 +20,32 @@
<BackendNav /> <BackendNav />
</div> </div>
<div class="content"> <div class="content">
{#if $store.activeNav === 'database'} {#if activeNav === 'database'}
<Database /> <Database />
{:else if $store.activeNav === 'actions'} {:else if activeNav === 'actions'}
<ActionsAndTriggers /> <ActionsAndTriggers />
{:else if $store.activeNav === 'access levels'} {:else if activeNav === 'access levels'}
<AccessLevels /> <AccessLevels />
{/if} {/if}
</div> </div>
<div class="nav">
<SchemaManagementDrawer />
</div>
</div> </div>
<style> <style>
.root { .root {
height: 100%; height: 100%;
display: flex; display: flex;
background: #fafafa;
} }
.content { .content {
flex: 1 1 auto; flex: 1 1 auto;
height: 100%; margin: 80px 60px;
background-color: var(--white); background: #fff;
margin: 0; border-radius: 5px;
overflow-y: auto; box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
overflow-x: hidden;
} }
.nav { .nav {

View File

@ -90,4 +90,12 @@
.uk-text-right { .uk-text-right {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
}
.preview-pane {
grid-column: 2;
margin: 80px 60px;
background: #fff;
border-radius: 5px;
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
} }

View File

@ -55,7 +55,6 @@ export const getStore = () => {
currentComponentProps: null, currentComponentProps: null,
currentNodeIsNew: false, currentNodeIsNew: false,
errors: [], errors: [],
activeNav: "database",
isBackend: true, isBackend: true,
hasAppPackage: false, hasAppPackage: false,
accessLevels: { version: 0, levels: [] }, accessLevels: { version: 0, levels: [] },
@ -84,7 +83,6 @@ export const getStore = () => {
store.deleteTrigger = deleteTrigger(store) store.deleteTrigger = deleteTrigger(store)
store.saveLevel = saveLevel(store) store.saveLevel = saveLevel(store)
store.deleteLevel = deleteLevel(store) store.deleteLevel = deleteLevel(store)
store.setActiveNav = setActiveNav(store)
store.saveScreen = saveScreen(store) store.saveScreen = saveScreen(store)
store.addComponentLibrary = addComponentLibrary(store) store.addComponentLibrary = addComponentLibrary(store)
store.renameScreen = renameScreen(store) store.renameScreen = renameScreen(store)
@ -237,7 +235,6 @@ const selectExistingNode = store => nodeId => {
s.currentNode = getNode(shadowHierarchy, nodeId) s.currentNode = getNode(shadowHierarchy, nodeId)
s.currentNodeIsNew = false s.currentNodeIsNew = false
s.errors = [] s.errors = []
s.activeNav = "database"
return s return s
}) })
} }
@ -449,13 +446,6 @@ const deleteLevel = store => level => {
}) })
} }
const setActiveNav = store => navName => {
store.update(s => {
s.activeNav = navName
return s
})
}
const createShadowHierarchy = hierarchy => const createShadowHierarchy = hierarchy =>
constructHierarchy(JSON.parse(JSON.stringify(hierarchy))) constructHierarchy(JSON.parse(JSON.stringify(hierarchy)))

View File

@ -7,7 +7,9 @@
import ErrorsBox from "../common/ErrorsBox.svelte" import ErrorsBox from "../common/ErrorsBox.svelte"
export let left export let left
let confirmDelete = false let confirmDelete = false
const openConfirmDelete = () => { const openConfirmDelete = () => {
confirmDelete = true confirmDelete = true
} }
@ -59,11 +61,4 @@
width: 100%; width: 100%;
align-items: right; align-items: right;
} }
.actions-modal-body {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style> </style>

View File

@ -2,6 +2,7 @@
import HierarchyRow from "./HierarchyRow.svelte" import HierarchyRow from "./HierarchyRow.svelte"
import RecordView from "./RecordView.svelte" import RecordView from "./RecordView.svelte"
import IndexView from "./IndexView.svelte" import IndexView from "./IndexView.svelte"
import ModelDataTable from "./ModelDataTable"
import ActionsHeader from "./ActionsHeader.svelte" import ActionsHeader from "./ActionsHeader.svelte"
import { store } from "../builderStore" import { store } from "../builderStore"
import getIcon from "../common/icon" import getIcon from "../common/icon"
@ -59,7 +60,7 @@
</div> </div>
<div class="node-view"> <div class="node-view">
{#if !$store.currentNode} {#if !$store.currentNode}
<h1 style="margin-left: 100px">:)</h1> <ModelDataTable />
{:else if $store.currentNode.type === 'record'} {:else if $store.currentNode.type === 'record'}
<RecordView /> <RecordView />
{:else} {:else}

View File

@ -0,0 +1,63 @@
<script>
let pages = [1, 2, 3]
export let data = []
export let pageSize = 10
</script>
<section>
<table class="uk-table">
<caption>Shoe Database</caption>
<thead>
<tr>
<th>Table Heading</th>
<th>Table Heading</th>
<th>Table Heading</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Table Footer</td>
<td>Table Footer</td>
<td>Table Footer</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>Table Data</td>
<td>Table Data</td>
<td>Table Data</td>
</tr>
<tr>
<td>Table Data</td>
<td>Table Data</td>
<td>Table Data</td>
</tr>
</tbody>
</table>
<div class="pagination">
<button>Previous</button>
<button>Next</button>
{#each data as page}
<button>{page}</button>
{/each}
</div>
</section>
<style>
table {
border: 1px solid #ccc;
}
thead {
background: var(--background-button);
}
thead th {
color: var(--button-text);
text-transform: capitalize;
}
tr {
border-bottom: 1px solid #ccc;
}
</style>

View File

@ -0,0 +1 @@
export { default } from "./ModelDataTable.svelte"

View File

@ -1,4 +1,5 @@
<script> <script>
import { setContext } from "svelte";
import { store } from "../builderStore" import { store } from "../builderStore"
import HierarchyRow from "./HierarchyRow.svelte" import HierarchyRow from "./HierarchyRow.svelte"
import DropdownButton from "../common/DropdownButton.svelte" import DropdownButton from "../common/DropdownButton.svelte"
@ -6,91 +7,101 @@
import NavItem from "./NavItem.svelte" import NavItem from "./NavItem.svelte"
import getIcon from "../common/icon" import getIcon from "../common/icon"
const newRootRecord = () => { // top level store modifiers
store.newRootRecord() const newRootRecord = () => store.newRootRecord();
const newChildIndex = () => store.newChildIndex();
const newRootIndex = () => store.newRootIndex();
const newUser = () => {
store.update(state => {
});
}
const newDatabase = () => {
store.update(state => {
});
} }
const newRootIndex = () => { const userManagementActions = [
store.newRootIndex()
}
const newChildRecord = () => {
store.newChildRecord()
}
const newChildIndex = () => {
store.newChildIndex()
}
const defaultNewChildActions = [
{ {
label: "New Root Record", label: "New User",
onclick: newRootRecord, onclick: newUser
},
{
label: "New Root Index",
onclick: newRootIndex,
},
]
let newChildActions = defaultNewChildActions
const setActiveNav = name => () => {
store.setActiveNav(name)
}
store.subscribe(db => {
if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
newChildActions = defaultNewChildActions
} else {
newChildActions = [
{
label: "New Root Record",
onclick: newRootRecord,
},
{
label: "New Root Index",
onclick: newRootIndex,
},
{
label: `New Child Record of ${db.currentNode.name}`,
onclick: newChildRecord,
},
{
label: `New Index on ${db.currentNode.name}`,
onclick: newChildIndex,
},
]
} }
}) ];
const databaseManagementActions = [
{
label: "New Database",
onclick: newDatabase
}
];
// let newChildActions = defaultNewChildActions
const setActiveNav = name => () => setContext("activeNav", name);
// store.subscribe(db => {
// if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
// newChildActions = defaultNewChildActions
// } else {
// newChildActions = [
// {
// label: "New Root Record",
// onclick: newRootRecord,
// },
// {
// label: "New Root Index",
// onclick: newRootIndex,
// },
// {
// label: `New Child Record of ${db.currentNode.name}`,
// onclick: newChildRecord,
// },
// {
// label: `New Index on ${db.currentNode.name}`,
// onclick: newChildIndex,
// },
// ]
// }
// })
</script> </script>
<div class="items-root"> <div class="items-root">
<div class="hierarchy"> <div class="hierarchy">
<div class="components-list-container"> <div class="components-list-container">
<div class="nav-group-header"> <div class="nav-group-header">
<div> <div class="hierarchy-title">Databases</div>
{@html getIcon('database', '18')} <DropdownButton iconName="plus" actions={databaseManagementActions} />
</div>
<div class="hierarchy-title">Database</div>
<DropdownButton iconName="plus" actions={newChildActions} />
</div> </div>
</div> </div>
<div class="hierarchy-items-container"> <div class="hierarchy-items-container">
{#each $store.hierarchy.children as record} <DatabasesList />
<!-- {#each $store.hierarchy.children as record}
<HierarchyRow node={record} type="record" /> <HierarchyRow node={record} type="record" />
{/each} {/each}
{#each $store.hierarchy.indexes as index} {#each $store.hierarchy.indexes as index}
<HierarchyRow node={index} type="index" /> <HierarchyRow node={index} type="index" />
{/each} {/each} -->
</div> </div>
</div> </div>
<hr />
<div class="hierarchy">
<div class="components-list-container">
<div class="nav-group-header">
<div class="hierarchy-title">Users</div>
<DropdownButton iconName="plus" actions={userManagementActions} />
</div>
</div>
<NavItem name="actions" label="Actions & Triggers" /> <div class="hierarchy-items-container">
<NavItem name="access levels" label="User Levels" /> <!-- {#each $store.hierarchy.children as record}
<HierarchyRow node={record} type="record" />
{/each} -->
</div>
</div>
</div> </div>
<style> <style>
@ -103,40 +114,15 @@
} }
.nav-group-header { .nav-group-header {
display: grid; display: flex;
grid-template-columns: [icon] auto [title] 1fr [button] auto; justify-content: space-between;
align-items: center;
padding: 2rem 1rem 1rem 1rem; padding: 2rem 1rem 1rem 1rem;
font-size: 0.9rem;
}
.nav-group-header > div:nth-child(1) {
padding: 0rem 0.7rem 0rem 0rem;
vertical-align: bottom;
grid-column-start: icon;
margin-right: 5px;
}
.nav-group-header > div:nth-child(2) {
margin-left: 5px;
vertical-align: bottom;
grid-column-start: title;
margin-top: auto;
}
.nav-group-header > div:nth-child(3) {
vertical-align: bottom;
grid-column-start: button;
cursor: pointer;
color: var(--primary75);
}
.nav-group-header > div:nth-child(3):hover {
color: var(--primary75);
} }
.hierarchy-title { .hierarchy-title {
flex: auto 1 1;
text-transform: uppercase; text-transform: uppercase;
font-size: 0.85em;
} }
.hierarchy { .hierarchy {

View File

@ -1,4 +1,5 @@
<script> <script>
import { getContext } from "svelte";
import { store } from "../builderStore" import { store } from "../builderStore"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import getIcon from "../common/icon" import getIcon from "../common/icon"
@ -7,12 +8,16 @@
export let type export let type
let navActive = "" let navActive = ""
$: icon = type === "index" ? "list" : "file"
const ICON_MAP = {
index: "ri-equalizer-line",
record: "ri-list-settings-line"
}
store.subscribe(state => { store.subscribe(state => {
if (state.currentNode) { if (state.currentNode) {
navActive = navActive =
state.activeNav === "database" && node.nodeId === state.currentNode.nodeId getContext("activeNav") === "database" && node.nodeId === state.currentNode.nodeId
} }
}) })
</script> </script>
@ -23,7 +28,7 @@
class="budibase__nav-item" class="budibase__nav-item"
style="padding-left: {20 + level * 20}px" style="padding-left: {20 + level * 20}px"
class:selected={navActive}> class:selected={navActive}>
{@html getIcon(icon, 12)} <i class={ICON_MAP[type]} />
<span style="margin-left: 1rem">{node.name}</span> <span style="margin-left: 1rem">{node.name}</span>
</div> </div>
{#if node.children} {#if node.children}

View File

@ -1,17 +1,17 @@
<script> <script>
import { store } from "../builderStore" import { getContext, setContext } from "svelte";
import getIcon from "../common/icon" import getIcon from "../common/icon"
export let name = "" export let name = ""
export let label = "" export let label = ""
let navActive = "" $: navActive = getContext("activeNav") === name
store.subscribe(db => { // store.subscribe(db => {
navActive = db.activeNav === name // navActive = db.activeNav === name
}) // })
const setActive = () => store.setActiveNav(name) const setActive = () => setContext("activeNav", name);
</script> </script>
<div <div

View File

@ -0,0 +1,119 @@
<script>
import { store } from "../builderStore"
import HierarchyRow from "./HierarchyRow.svelte"
import DropdownButton from "../common/DropdownButton.svelte"
import { hierarchy as hierarchyFunctions } from "../../../core/src"
import NavItem from "./NavItem.svelte"
import getIcon from "../common/icon"
const newRootRecord = () => {
store.newRootRecord()
}
const newRootIndex = () => {
store.newRootIndex()
}
const newChildRecord = () => {
store.newChildRecord()
}
const newChildIndex = () => {
store.newChildIndex()
}
const defaultNewChildActions = [
{
label: "New Root Record",
onclick: newRootRecord,
},
{
label: "New Root Index",
onclick: newRootIndex,
},
]
let newChildActions = defaultNewChildActions
const setActiveNav = name => () => {
store.setActiveNav(name)
}
store.subscribe(db => {
if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
newChildActions = defaultNewChildActions
} else {
newChildActions = [
{
label: "New Root Record",
onclick: newRootRecord,
},
{
label: "New Root Index",
onclick: newRootIndex,
},
{
label: `New Child Record of ${db.currentNode.name}`,
onclick: newChildRecord,
},
{
label: `New Index on ${db.currentNode.name}`,
onclick: newChildIndex,
},
]
}
})
</script>
<div class="items-root">
<div class="hierarchy">
<div class="components-list-container">
<div class="nav-group-header">
<div class="hierarchy-title">Schema</div>
<DropdownButton iconName="plus" actions={newChildActions} />
</div>
</div>
<div class="hierarchy-items-container">
{#each $store.hierarchy.children as record}
<HierarchyRow node={record} type="record" />
{/each}
{#each $store.hierarchy.indexes as index}
<HierarchyRow node={index} type="index" />
{/each}
</div>
</div>
</div>
<style>
.items-root {
display: flex;
flex-direction: column;
max-height: 100%;
height: 100%;
background-color: var(--secondary5);
}
.nav-group-header {
display: flex;
justify-content: space-between;
padding: 2rem 1rem 1rem 1rem;
}
.hierarchy-title {
align-items: center;
text-transform: uppercase;
font-size: 0.85em;
}
.hierarchy {
display: flex;
flex-direction: column;
}
.hierarchy-items-container {
flex: 1 1 auto;
overflow-y: auto;
}
</style>

View File

@ -126,6 +126,7 @@
flex-direction: column; flex-direction: column;
} }
<<<<<<< HEAD
.preview-pane { .preview-pane {
grid-column: 2; grid-column: 2;
margin: 40px; margin: 40px;
@ -134,6 +135,8 @@
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05); box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
} }
=======
>>>>>>> new backend beginnings
.components-pane { .components-pane {
grid-column: 3; grid-column: 3;
background-color: var(--secondary5); background-color: var(--secondary5);