UI structure
This commit is contained in:
parent
8c983192e6
commit
4678f2c168
|
@ -47,6 +47,7 @@
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"shortid": "^2.2.8",
|
"shortid": "^2.2.8",
|
||||||
"string_decoder": "^1.2.0",
|
"string_decoder": "^1.2.0",
|
||||||
|
"svelte-routing": "^1.4.2",
|
||||||
"uikit": "^3.1.7"
|
"uikit": "^3.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -165,7 +165,7 @@ export default {
|
||||||
svelte({
|
svelte({
|
||||||
// enable run-time checks when not in production
|
// enable run-time checks when not in production
|
||||||
dev: !production,
|
dev: !production,
|
||||||
include: "src/**/*.svelte",
|
include: ["src/**/*.svelte", "node_modules/**/*.svelte"],
|
||||||
// we'll extract any component CSS out into
|
// we'll extract any component CSS out into
|
||||||
// a separate file — better for performance
|
// a separate file — better for performance
|
||||||
css: css => {
|
css: css => {
|
||||||
|
|
|
@ -29,16 +29,16 @@
|
||||||
{/await}
|
{/await}
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<IconButton icon="settings"
|
<IconButton icon="settings"
|
||||||
on:click={store.showSettings}/>
|
on:click={store.showSettings}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{#if $store.useAnalytics}
|
{#if $store.useAnalytics}
|
||||||
<iframe src="https://marblekirby.github.io/bb-analytics.html" width="0" height="0" style="visibility:hidden;display:none"/>
|
<iframe src="https://marblekirby.github.io/bb-analytics.html" width="0" height="0" style="visibility:hidden;display:none"/>
|
||||||
{/if}
|
{/if}
|
||||||
-->
|
-->
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -8,11 +8,9 @@
|
||||||
import ComingSoon from "./common/ComingSoon.svelte"
|
import ComingSoon from "./common/ComingSoon.svelte"
|
||||||
|
|
||||||
import { store } from "./builderStore"
|
import { store } from "./builderStore"
|
||||||
import { setContext } from 'svelte';
|
import { setContext } from "svelte"
|
||||||
|
|
||||||
let activeNav = "database";
|
let activeNav = "database"
|
||||||
|
|
||||||
setContext("activeNav", activeNav);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
@ -20,14 +18,13 @@
|
||||||
<BackendNav />
|
<BackendNav />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- {#if activeNav === 'database'} -->
|
<Database />
|
||||||
<Database />
|
</div>
|
||||||
<!-- {:else if activeNav === 'actions'}
|
<!-- {:else if activeNav === 'actions'}
|
||||||
<ActionsAndTriggers />
|
<ActionsAndTriggers />
|
||||||
{:else if activeNav === 'access levels'}
|
{:else if activeNav === 'access levels'}
|
||||||
<AccessLevels />
|
<AccessLevels />
|
||||||
{/if} -->
|
{/if} -->
|
||||||
</div>
|
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<SchemaManagementDrawer />
|
<SchemaManagementDrawer />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -98,4 +98,24 @@
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__table {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__table thead {
|
||||||
|
background: var(--background-button);
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__table th {
|
||||||
|
color: var(--button-text);
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__table tr {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
}
|
}
|
|
@ -148,8 +148,6 @@ export const getStore = () => {
|
||||||
store.addStylesheet = addStylesheet(store)
|
store.addStylesheet = addStylesheet(store)
|
||||||
store.removeStylesheet = removeStylesheet(store)
|
store.removeStylesheet = removeStylesheet(store)
|
||||||
store.savePage = savePage(store)
|
store.savePage = savePage(store)
|
||||||
// store.showFrontend = showFrontend(store)
|
|
||||||
// store.showBackend = showBackend(store)
|
|
||||||
store.showSettings = showSettings(store)
|
store.showSettings = showSettings(store)
|
||||||
store.useAnalytics = useAnalytics(store)
|
store.useAnalytics = useAnalytics(store)
|
||||||
store.createGeneratedComponents = createGeneratedComponents(store)
|
store.createGeneratedComponents = createGeneratedComponents(store)
|
||||||
|
|
|
@ -2,24 +2,17 @@
|
||||||
import { JavaScriptIcon } from "../common/Icons"
|
import { JavaScriptIcon } from "../common/Icons"
|
||||||
// todo: use https://ace.c9.io
|
// todo: use https://ace.c9.io
|
||||||
export let text = ""
|
export let text = ""
|
||||||
export let label = ""
|
|
||||||
export let javascript = false
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="header">
|
|
||||||
{#if javascript}
|
|
||||||
<JavaScriptIcon />
|
|
||||||
{/if}
|
|
||||||
<span>{label}</span>
|
|
||||||
</div>
|
|
||||||
<textarea class="uk-textarea" bind:value={text} />
|
<textarea class="uk-textarea" bind:value={text} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
textarea {
|
textarea {
|
||||||
padding: 3px;
|
padding: 10px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background: var(--lightslate);
|
background: var(--primary100);
|
||||||
|
color: var(--white);
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<script>
|
<script>
|
||||||
import getIcon from "./icon"
|
import getIcon from "./icon"
|
||||||
|
|
||||||
|
export let icon
|
||||||
export let value
|
export let value
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="select-container">
|
<div class="select-container">
|
||||||
<select on:change bind:value>
|
{#if icon}
|
||||||
|
<i class={icon} />
|
||||||
|
{/if}
|
||||||
|
<select
|
||||||
|
class:adjusted={icon}
|
||||||
|
on:change bind:value
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</select>
|
</select>
|
||||||
<span class="arrow">
|
<span class="arrow">
|
||||||
|
@ -22,6 +30,16 @@
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.adjusted {
|
||||||
|
padding-left: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
position: absolute;
|
||||||
|
left: 8px;
|
||||||
|
top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<script>
|
||||||
|
export let data = []
|
||||||
|
export let headers = []
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<table class="uk-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Edit</th>
|
||||||
|
{#each headers as header}
|
||||||
|
<th>{header}</th>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each data as row}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="uk-inline">
|
||||||
|
<i class="ri-more-line" />
|
||||||
|
<div uk-dropdown="mode: click">
|
||||||
|
<ul class="uk-nav uk-dropdown-nav">
|
||||||
|
<li>
|
||||||
|
<div>View</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>Edit</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div on:click={() => (deleteRecordModal = true)}>Delete</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>Duplicate</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{#each headers as header}
|
||||||
|
<td>{row[header]}</td>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -1,12 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import HierarchyRow from "./HierarchyRow.svelte"
|
import HierarchyRow from "./HierarchyRow.svelte"
|
||||||
import RecordView from "./RecordView.svelte"
|
import ModelView from "./ModelView.svelte"
|
||||||
import IndexView from "./IndexView.svelte"
|
import IndexView from "./IndexView.svelte"
|
||||||
import ModelDataTable from "./ModelDataTable"
|
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"
|
||||||
import DropdownButton from "../common/DropdownButton.svelte"
|
import DropdownButton from "../common/DropdownButton.svelte"
|
||||||
|
import Modal from "../common/Modal.svelte"
|
||||||
import { hierarchy as hierarchyFunctions } from "../../../core/src"
|
import { hierarchy as hierarchyFunctions } from "../../../core/src"
|
||||||
|
|
||||||
const hierarchyWidth = "200px"
|
const hierarchyWidth = "200px"
|
||||||
|
@ -53,18 +54,24 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="actions-header">
|
<!-- <div class="actions-header">
|
||||||
{#if $store.currentNode}
|
{#if $store.currentNode}
|
||||||
<ActionsHeader left={hierarchyWidth} />
|
<ActionsHeader />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div> -->
|
||||||
<div class="node-view">
|
<div class="node-view">
|
||||||
{#if !$store.currentNode}
|
<div class="breadcrumbs">{$store.currentlySelectedDatabase}</div>
|
||||||
<ModelDataTable />
|
<ModelDataTable />
|
||||||
{:else if $store.currentNode.type === 'record'}
|
{#if $store.currentNode}
|
||||||
<RecordView />
|
<Modal isOpen={$store.currentNode}>
|
||||||
{:else}
|
{#if $store.currentNode.type === 'record'}
|
||||||
<IndexView />
|
<ModelView />
|
||||||
|
<ActionsHeader />
|
||||||
|
{:else}
|
||||||
|
<IndexView />
|
||||||
|
<ActionsHeader />
|
||||||
|
{/if}
|
||||||
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -68,20 +68,14 @@
|
||||||
|
|
||||||
<ErrorsBox {errors} />
|
<ErrorsBox {errors} />
|
||||||
|
|
||||||
<form class="uk-form-horizontal">
|
<form class="uk-form-stacked">
|
||||||
|
<Textbox label="Name" bind:text={clonedField.name} />
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label="Type"
|
label="Type"
|
||||||
bind:selected={clonedField.type}
|
bind:selected={clonedField.type}
|
||||||
options={keys(allTypes)}
|
options={keys(allTypes)}
|
||||||
on:change={typeChanged} />
|
on:change={typeChanged} />
|
||||||
|
|
||||||
{#if isNew}
|
|
||||||
<Textbox label="Field Name" bind:text={clonedField.name} />
|
|
||||||
{:else}
|
|
||||||
<div style="font-weight: bold">{clonedField.name}</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<Textbox label="Label" bind:text={clonedField.label} />
|
<Textbox label="Label" bind:text={clonedField.label} />
|
||||||
|
|
||||||
{#if clonedField.type === 'string'}
|
{#if clonedField.type === 'string'}
|
||||||
|
@ -89,7 +83,7 @@
|
||||||
label="Max Length"
|
label="Max Length"
|
||||||
bind:value={clonedField.typeOptions.maxLength} />
|
bind:value={clonedField.typeOptions.maxLength} />
|
||||||
<ValuesList
|
<ValuesList
|
||||||
label="Values (options)"
|
label="Categories"
|
||||||
bind:values={clonedField.typeOptions.values} />
|
bind:values={clonedField.typeOptions.values} />
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label="Declared Values Only"
|
label="Declared Values Only"
|
||||||
|
|
|
@ -9,20 +9,30 @@
|
||||||
|
|
||||||
const pipe = common.$
|
const pipe = common.$
|
||||||
|
|
||||||
|
const SNIPPET_EDITORS = {
|
||||||
|
MAP: "Map",
|
||||||
|
FILTER: "Filter",
|
||||||
|
SHARD: "Shard Name",
|
||||||
|
}
|
||||||
|
|
||||||
let index
|
let index
|
||||||
let indexableRecords = []
|
let indexableRecords = []
|
||||||
|
let currentSnippetEditor = SNIPPET_EDITORS.MAP
|
||||||
|
|
||||||
store.subscribe($store => {
|
store.subscribe($store => {
|
||||||
index = $store.currentNode
|
index = $store.currentNode
|
||||||
indexableRecords = pipe($store.hierarchy, [
|
indexableRecords = pipe(
|
||||||
hierarchyFunctions.getFlattenedHierarchy,
|
$store.hierarchy,
|
||||||
filter(hierarchyFunctions.isDecendant(index.parent())),
|
[
|
||||||
filter(hierarchyFunctions.isRecord),
|
hierarchyFunctions.getFlattenedHierarchy,
|
||||||
map(n => ({
|
filter(hierarchyFunctions.isDecendant(index.parent())),
|
||||||
node: n,
|
filter(hierarchyFunctions.isRecord),
|
||||||
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
|
map(n => ({
|
||||||
})),
|
node: n,
|
||||||
])
|
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
|
||||||
|
})),
|
||||||
|
]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleAllowedRecord = record => {
|
const toggleAllowedRecord = record => {
|
||||||
|
@ -36,11 +46,28 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="uk-form-horizontal root">
|
<h3 class="budibase__title--3">
|
||||||
<Textbox bind:text={index.name} label="Name" />
|
<i class="ri-eye-line" />
|
||||||
|
Create / Edit View
|
||||||
|
</h3>
|
||||||
|
<form class="uk-form-stacked root">
|
||||||
|
<h4 class="budibase__label--big">Settings</h4>
|
||||||
|
<div class="uk-grid-small" uk-grid>
|
||||||
|
<div class="uk-width-1-2@s">
|
||||||
|
<Textbox bind:text={index.name} label="Name" />
|
||||||
|
</div>
|
||||||
|
<div class="uk-width-1-2@s">
|
||||||
|
<Dropdown
|
||||||
|
label="View Type"
|
||||||
|
bind:selected={index.indexType}
|
||||||
|
options={['ancestor', 'reference']} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="allowed-records">
|
<div class="allowed-records">
|
||||||
<div class="index-label">Records to Index</div>
|
<div class="budibase__label--big">
|
||||||
|
Which models would you like to add to this view?
|
||||||
|
</div>
|
||||||
{#each indexableRecords as rec}
|
{#each indexableRecords as rec}
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -50,14 +77,22 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Dropdown
|
<h4 class="budibase__label--big">Snippets</h4>
|
||||||
label="Index Type"
|
{#each Object.values(SNIPPET_EDITORS) as snippetType}
|
||||||
bind:selected={index.indexType}
|
<span
|
||||||
options={['ancestor', 'reference']} />
|
class="snippet-selector__heading hoverable"
|
||||||
|
class:highlighted={currentSnippetEditor === snippetType}
|
||||||
<CodeArea bind:text={index.map} javascript label="Map" />
|
on:click={() => (currentSnippetEditor = snippetType)}>
|
||||||
<CodeArea bind:text={index.filter} javascript label="Filter" />
|
{snippetType}
|
||||||
<CodeArea javascript bind:text={index.getShardName} label="Shard Name" />
|
</span>
|
||||||
|
{/each}
|
||||||
|
{#if currentSnippetEditor === SNIPPET_EDITORS.MAP}
|
||||||
|
<CodeArea bind:text={index.map} label="Map" />
|
||||||
|
{:else if currentSnippetEditor === SNIPPET_EDITORS.FILTER}
|
||||||
|
<CodeArea bind:text={index.filter} label="Filter" />
|
||||||
|
{:else if currentSnippetEditor === SNIPPET_EDITORS.SHARD}
|
||||||
|
<CodeArea bind:text={index.getShardName} label="Shard Name" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -79,4 +114,13 @@
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.snippet-selector__heading {
|
||||||
|
margin-right: 20px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlighted {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { store } from "../../builderStore"
|
||||||
import Select from "../../common/Select.svelte"
|
import Select from "../../common/Select.svelte"
|
||||||
|
import { CreateEditRecordModal, DeleteRecordModal } from "./modals"
|
||||||
import ActionButton from "../../common/ActionButton.svelte"
|
import ActionButton from "../../common/ActionButton.svelte"
|
||||||
|
import TablePagination from "./TablePagination.svelte"
|
||||||
|
import * as api from "./api"
|
||||||
|
import { getIndexSchema } from "../../common/core"
|
||||||
|
|
||||||
let pages = [1, 2, 3]
|
let pages = [1, 2, 3]
|
||||||
|
|
||||||
|
@ -10,14 +15,31 @@
|
||||||
{ name: "Martin", inStock: true },
|
{ name: "Martin", inStock: true },
|
||||||
]
|
]
|
||||||
export let headers = ["name", "inStock"]
|
export let headers = ["name", "inStock"]
|
||||||
export let pageSize = 10
|
// export let pageSize = 10
|
||||||
|
|
||||||
|
let selectedView = ""
|
||||||
|
let modalOpen = false
|
||||||
|
let deleteRecordModal = false
|
||||||
|
|
||||||
|
$: indexes = $store.hierarchy.indexes
|
||||||
|
|
||||||
|
const getSchema = getIndexSchema($store.hierarchy)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<CreateEditRecordModal bind:modalOpen />
|
||||||
|
<DeleteRecordModal modalOpen={deleteRecordModal} />
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h4 class="budibase__title--3">Shoe database</h4>
|
|
||||||
<div class="table-controls">
|
<div class="table-controls">
|
||||||
<Select />
|
<h4 class="budibase__title--3">Shoe database</h4>
|
||||||
<ActionButton primary>Create new record</ActionButton>
|
<Select
|
||||||
|
icon="ri-eye-line"
|
||||||
|
on:change={e => api.fetchDataForView(e.target.value)}>
|
||||||
|
{#each indexes as index}
|
||||||
|
({console.log(getSchema(index))})
|
||||||
|
<option value={index.name}>{index.name}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<table class="uk-table">
|
<table class="uk-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -32,7 +54,25 @@
|
||||||
{#each data as row}
|
{#each data as row}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<i class="ri-more-line" />
|
<div class="uk-inline">
|
||||||
|
<i class="ri-more-line" />
|
||||||
|
<div uk-dropdown="mode: click">
|
||||||
|
<ul class="uk-nav uk-dropdown-nav">
|
||||||
|
<li>
|
||||||
|
<div>View</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div on:click={() => (modalOpen = true)}>Edit</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div on:click={() => (deleteRecordModal = true)}>Delete</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div>Duplicate</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{#each headers as header}
|
{#each headers as header}
|
||||||
<td>{row[header]}</td>
|
<td>{row[header]}</td>
|
||||||
|
@ -41,13 +81,7 @@
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="pagination">
|
<TablePagination {data} />
|
||||||
<button>Previous</button>
|
|
||||||
<button>Next</button>
|
|
||||||
<!-- {#each data as page}
|
|
||||||
<button>{page}</button>
|
|
||||||
{/each} -->
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -76,4 +110,8 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ri-more-line:hover, .uk-dropdown-nav li:hover{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<script>
|
||||||
|
export let data = []
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<div class="pagination__buttons">
|
||||||
|
<button>Previous</button>
|
||||||
|
<button>Next</button>
|
||||||
|
{#each data as page, idx}
|
||||||
|
<button>{idx + 1}</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<p>Showing 10 (hardcoded, update this) of {data.length} entries</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.pagination {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination__buttons button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
text-transform: capitalize;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: Roboto;
|
||||||
|
min-width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination__buttons button:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ri-more-line:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,24 @@
|
||||||
|
import api from "../../builderStore/api";
|
||||||
|
|
||||||
|
export async function deleteRecord(appName, appInstanceId, record) {
|
||||||
|
const DELETE_RECORDS_URL = `/_builder/instance/${appName}/${appInstanceId}/api/record/${record.name}/${record.id}`
|
||||||
|
const response = await api.delete({
|
||||||
|
url: DELETE_RECORDS_URL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createNewRecord(record) {
|
||||||
|
console.log(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchDataForView(viewName) {
|
||||||
|
console.log(viewName);
|
||||||
|
// const FETCH_RECORDS_URL = `/_builder/instance/${}/${}/api/listRecords/`
|
||||||
|
|
||||||
|
// const response = await api.get({ url: FETCH_RECORDS_URL });
|
||||||
|
|
||||||
|
// console.log(response);
|
||||||
|
|
||||||
|
// GET /_builder/instance/:appname/:instanceid/api/listRecords/contacts/abcd1234/all_deals
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../common/Modal.svelte"
|
||||||
|
import ActionButton from "../../common/ActionButton.svelte"
|
||||||
|
import * as api from "./api"
|
||||||
|
|
||||||
|
export let modalOpen = false
|
||||||
|
|
||||||
|
let recordInfo = {}
|
||||||
|
|
||||||
|
const onClosed = () => (modalOpen = false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {onClosed} bind:isOpen={modalOpen} title={"Create / Edit Field"}>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<ActionButton alert on:click={onClosed}>Cancel</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
disabled={false}
|
||||||
|
on:click={() => api.createNewRecord(recordInfo)}>
|
||||||
|
Save
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../common/Modal.svelte"
|
||||||
|
import ActionButton from "../../common/ActionButton.svelte"
|
||||||
|
import * as api from "./api"
|
||||||
|
|
||||||
|
export let modalOpen = false
|
||||||
|
|
||||||
|
let recordInfo = {}
|
||||||
|
|
||||||
|
const onClosed = () => (modalOpen = false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {onClosed} bind:isOpen={modalOpen} title={'Record'}>
|
||||||
|
<h4 class="budibase__title--4">Create / Edit Record</h4>
|
||||||
|
<div class="actions">
|
||||||
|
<ActionButton alert on:click={onClosed}>Cancel</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
disabled={false}
|
||||||
|
on:click={() => api.createNewRecord(recordInfo)}>
|
||||||
|
Save
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -0,0 +1,60 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../../common/Modal.svelte"
|
||||||
|
import ActionButton from "../../../common/ActionButton.svelte"
|
||||||
|
import * as api from "../api"
|
||||||
|
|
||||||
|
export let modalOpen = false
|
||||||
|
export let model = {}
|
||||||
|
|
||||||
|
const onClosed = () => (modalOpen = false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {onClosed} bind:isOpen={modalOpen} title={'Record'}>
|
||||||
|
<h4 class="budibase__title--4">Create / Edit Record</h4>
|
||||||
|
<div class="actions">
|
||||||
|
<form>
|
||||||
|
<div class="uk-margin">
|
||||||
|
<label class="uk-form-label" for="form-stacked-text">Text</label>
|
||||||
|
<div class="uk-form-controls">
|
||||||
|
<input
|
||||||
|
class="uk-input"
|
||||||
|
id="form-stacked-text"
|
||||||
|
type="text"
|
||||||
|
placeholder="Some text..." />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="uk-margin">
|
||||||
|
<label class="uk-form-label" for="form-stacked-select">Select</label>
|
||||||
|
<div class="uk-form-controls">
|
||||||
|
<select class="uk-select" id="form-stacked-select">
|
||||||
|
<option>Option 01</option>
|
||||||
|
<option>Option 02</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="uk-margin">
|
||||||
|
<div class="uk-form-label">Radio</div>
|
||||||
|
<div class="uk-form-controls">
|
||||||
|
<label>
|
||||||
|
<input class="uk-radio" type="radio" name="radio1" />
|
||||||
|
Option 01
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
<input class="uk-radio" type="radio" name="radio1" />
|
||||||
|
Option 02
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<ActionButton alert on:click={onClosed}>Cancel</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
disabled={false}
|
||||||
|
on:click={() => api.createNewRecord(recordInfo)}>
|
||||||
|
Save
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../common/Modal.svelte"
|
||||||
|
import ActionButton from "../../common/ActionButton.svelte"
|
||||||
|
import * as api from "./api"
|
||||||
|
|
||||||
|
export let modalOpen = false
|
||||||
|
|
||||||
|
let recordInfo = {}
|
||||||
|
|
||||||
|
const onClosed = () => (modalOpen = false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {onClosed} bind:isOpen={modalOpen} title={'Record'}>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<ActionButton alert on:click={onClosed}>Cancel</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
disabled={false}
|
||||||
|
on:click={() => api.createNewRecord(recordInfo)}>
|
||||||
|
Save
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script>
|
||||||
|
import Modal from "../../../common/Modal.svelte"
|
||||||
|
import ActionButton from "../../../common/ActionButton.svelte"
|
||||||
|
import * as api from "../api"
|
||||||
|
|
||||||
|
export let modalOpen = false
|
||||||
|
|
||||||
|
let recordInfo = {}
|
||||||
|
|
||||||
|
const onClosed = () => (modalOpen = false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal {onClosed} bind:isOpen={modalOpen} title={"Delete Record?"}>
|
||||||
|
<h4 class="budibase__title--4">Delete Record</h4>
|
||||||
|
Are you sure you want to delete this record? All of your data will be permanently removed. This action cannot be undone.
|
||||||
|
<div class="modal-actions">
|
||||||
|
<ActionButton on:click={onClosed}>Cancel</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
alert
|
||||||
|
on:click={() => api.deleteRecord(recordInfo)}>
|
||||||
|
Delete
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -0,0 +1,2 @@
|
||||||
|
export { default as DeleteRecordModal } from "./DeleteRecord.svelte";
|
||||||
|
export { default as CreateEditRecordModal } from "./CreateEditRecord.svelte";
|
|
@ -24,11 +24,14 @@
|
||||||
record = $store.currentNode
|
record = $store.currentNode
|
||||||
const flattened = h.getFlattenedHierarchy($store.hierarchy)
|
const flattened = h.getFlattenedHierarchy($store.hierarchy)
|
||||||
getIndexAllowedRecords = index =>
|
getIndexAllowedRecords = index =>
|
||||||
pipe(index.allowedRecordNodeIds, [
|
pipe(
|
||||||
filter(id => some(n => n.nodeId === id)(flattened)),
|
index.allowedRecordNodeIds,
|
||||||
map(id => find(n => n.nodeId === id)(flattened).name),
|
[
|
||||||
join(", "),
|
filter(id => some(n => n.nodeId === id)(flattened)),
|
||||||
])
|
map(id => find(n => n.nodeId === id)(flattened).name),
|
||||||
|
join(", "),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
newField = () => {
|
newField = () => {
|
||||||
isNewField = true
|
isNewField = true
|
||||||
|
@ -72,16 +75,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let getTypeOptions = typeOptions =>
|
let getTypeOptions = typeOptions =>
|
||||||
pipe(typeOptions, [
|
pipe(
|
||||||
keys,
|
typeOptions,
|
||||||
map(
|
[
|
||||||
k =>
|
keys,
|
||||||
`<span style="color:var(--slate)">${k}: </span>${getTypeOptionsValueText(
|
map(
|
||||||
typeOptions[k]
|
k =>
|
||||||
)}`
|
`<span style="color:var(--slate)">${k}: </span>${getTypeOptionsValueText(
|
||||||
),
|
typeOptions[k]
|
||||||
join("<br>"),
|
)}`
|
||||||
])
|
),
|
||||||
|
join("<br>"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
const nameChanged = ev => {
|
const nameChanged = ev => {
|
||||||
const pluralName = n => `${n}s`
|
const pluralName = n => `${n}s`
|
||||||
|
@ -93,68 +99,78 @@
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
|
||||||
<form class="uk-form-horizontal">
|
<form class="uk-form-stacked">
|
||||||
<h3 class="budibase__title--3">Settings</h3>
|
<h3 class="budibase__title--3">
|
||||||
|
<i class="ri-list-settings-line" />
|
||||||
|
Create / Edit Model
|
||||||
|
</h3>
|
||||||
|
|
||||||
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
|
<h3 class="budibase__label--big">Settings</h3>
|
||||||
|
|
||||||
|
<Textbox label="Name" bind:text={record.name} on:change={nameChanged} />
|
||||||
{#if !record.isSingle}
|
{#if !record.isSingle}
|
||||||
<Textbox label="Collection Name:" bind:text={record.collectionName} />
|
<Textbox label="Collection Name" bind:text={record.collectionName} />
|
||||||
<Textbox
|
<Textbox
|
||||||
label="Estimated Record Count:"
|
label="Estimated Record Count"
|
||||||
bind:text={record.estimatedRecordCount} />
|
bind:text={record.estimatedRecordCount} />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="recordkey">{record.nodeKey()}</div>
|
<div class="recordkey">{record.nodeKey()}</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
<h3 class="budibase__title--3">
|
<div class="table-controls">
|
||||||
|
<span class="budibase__label--big">Fields</span>
|
||||||
|
<h4 class="hoverable" on:click={newField}>Add new field</h4>
|
||||||
|
</div>
|
||||||
|
<!-- <h3 class="budibase__label--big">
|
||||||
Fields
|
Fields
|
||||||
<span class="add-field-button" on:click={newField}>
|
<span class="add-field-button" on:click={newField}>
|
||||||
{@html getIcon('plus')}
|
{@html getIcon('plus')}
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3> -->
|
||||||
|
|
||||||
{#if record.fields.length > 0}
|
<table class="fields-table uk-table budibase__table">
|
||||||
<table class="fields-table uk-table">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
|
<th>Edit</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Values</th>
|
||||||
|
<th />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each record.fields as field}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<td>
|
||||||
<th>Type</th>
|
<i class="ri-more-line" on:click={() => editField(field)} />
|
||||||
<th>Options</th>
|
</td>
|
||||||
<th />
|
<td>
|
||||||
|
<div>{field.name}</div>
|
||||||
|
</td>
|
||||||
|
<td>{field.type}</td>
|
||||||
|
<td>({console.log(field.typeOptions)}) {field.typeOptions.values}</td>
|
||||||
|
<td>
|
||||||
|
<!-- <span class="edit-button" on:click={() => editField(field)}>
|
||||||
|
{@html getIcon('edit')}
|
||||||
|
</span> -->
|
||||||
|
<span class="edit-button" on:click={() => deleteField(field)}>
|
||||||
|
{@html getIcon('trash')}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{/each}
|
||||||
<tbody>
|
</tbody>
|
||||||
{#each record.fields as field}
|
</table>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="field-label">{field.label}</div>
|
|
||||||
<div style="font-size: 0.8em; color: var(--slate)">
|
|
||||||
{field.name}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>{field.type}</td>
|
|
||||||
<td>
|
|
||||||
{@html getTypeOptions(field.typeOptions)}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="edit-button" on:click={() => editField(field)}>
|
|
||||||
{@html getIcon('edit')}
|
|
||||||
</span>
|
|
||||||
<span class="edit-button" on:click={() => deleteField(field)}>
|
|
||||||
{@html getIcon('trash')}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{:else}(no fields added){/if}
|
|
||||||
|
|
||||||
{#if editingField}
|
{#if editingField}
|
||||||
<Modal
|
<Modal
|
||||||
title="Manage Index Fields"
|
|
||||||
bind:isOpen={editingField}
|
bind:isOpen={editingField}
|
||||||
onClosed={() => onFinishedFieldEdit(false)}>
|
onClosed={() => onFinishedFieldEdit(false)}>
|
||||||
|
|
||||||
|
<h3 class="budibase__title--3">
|
||||||
|
<i class="ri-file-list-line" />
|
||||||
|
Create / Edit Field
|
||||||
|
</h3>
|
||||||
<FieldView
|
<FieldView
|
||||||
field={fieldToEdit}
|
field={fieldToEdit}
|
||||||
onFinished={onFinishedFieldEdit}
|
onFinished={onFinishedFieldEdit}
|
||||||
|
@ -163,9 +179,9 @@
|
||||||
</Modal>
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h3 class="budibase__title--3">Indexes</h3>
|
<!-- <h3 class="budibase__title--3">Indexes</h3> -->
|
||||||
|
|
||||||
{#each record.indexes as index}
|
<!-- {#each record.indexes as index}
|
||||||
<div class="index-container">
|
<div class="index-container">
|
||||||
<div class="index-name">
|
<div class="index-name">
|
||||||
{index.name}
|
{index.name}
|
||||||
|
@ -192,7 +208,7 @@
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="no-indexes">No indexes added.</div>
|
<div class="no-indexes">No indexes added.</div>
|
||||||
{/each}
|
{/each} -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -213,10 +229,6 @@
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-field-button {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-button {
|
.edit-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--secondary25);
|
color: var(--secondary25);
|
||||||
|
@ -227,35 +239,6 @@
|
||||||
color: var(--secondary75);
|
color: var(--secondary75);
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
padding: 1rem 5rem 1rem 0rem;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-label {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead > tr {
|
|
||||||
border-width: 0px 0px 1px 0px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: var(--secondary75);
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody > tr {
|
|
||||||
border-width: 0px 0px 1px 0px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: var(--primary10);
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody > tr:hover {
|
tbody > tr:hover {
|
||||||
background-color: var(--primary10);
|
background-color: var(--primary10);
|
||||||
}
|
}
|
||||||
|
@ -264,38 +247,17 @@
|
||||||
color: var(--secondary75);
|
color: var(--secondary75);
|
||||||
}
|
}
|
||||||
|
|
||||||
.index-container {
|
.table-controls {
|
||||||
border-style: solid;
|
display: flex;
|
||||||
border-width: 0 0 1px 0;
|
justify-content: space-between;
|
||||||
border-color: var(--secondary25);
|
align-items: center;
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.index-label {
|
.ri-more-line:hover {
|
||||||
color: var(--slate);
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.index-name {
|
h4 {
|
||||||
font-weight: bold;
|
|
||||||
color: var(--primary100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.index-container code {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: inline;
|
|
||||||
background-color: var(--primary10);
|
|
||||||
color: var(--secondary100);
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.index-field-row {
|
|
||||||
margin: 1rem 0rem 0rem 0rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-indexes {
|
|
||||||
margin: 1rem 0rem 0rem 0rem;
|
|
||||||
font-family: var(--fontnormal);
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -102,4 +102,8 @@ h5 {
|
||||||
font-family: var(--fontblack);
|
font-family: var(--fontblack);
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
color: var(--darkslate);
|
color: var(--darkslate);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hoverable:hover {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
|
@ -15,5 +15,5 @@ import "codemirror/theme/monokai.css"
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
const app = new App({
|
const app = new App({
|
||||||
target: document.getElementById("app"),
|
target: document.getElementById("app")
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { setContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { store } from "../builderStore"
|
import { store } from "../builderStore"
|
||||||
import HierarchyRow from "./HierarchyRow.svelte"
|
import HierarchyRow from "./HierarchyRow.svelte"
|
||||||
import DatabasesList from "./DatabasesList.svelte"
|
import DatabasesList from "./DatabasesList.svelte"
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
// let newChildActions = defaultNewChildActions
|
// let newChildActions = defaultNewChildActions
|
||||||
|
|
||||||
const setActiveNav = name => () => setContext("activeNav", name)
|
const setActiveNav = name => () => getContext("navigation").setActiveNav(name);
|
||||||
|
|
||||||
// store.subscribe(db => {
|
// store.subscribe(db => {
|
||||||
// if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
|
// if (!db.currentNode || hierarchyFunctions.isIndex(db.currentNode)) {
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { navigate } from "svelte-routing"
|
||||||
import { store } from "../builderStore"
|
import { store } from "../builderStore"
|
||||||
import getIcon from "../common/icon"
|
import getIcon from "../common/icon"
|
||||||
import { CheckIcon } from "../common/Icons"
|
import { CheckIcon } from "../common/Icons"
|
||||||
|
|
||||||
$: instances = $store.appInstances
|
$: instances = $store.appInstances
|
||||||
|
|
||||||
|
function selectDatabase(databaseId) {
|
||||||
|
store.update(state => {
|
||||||
|
state.currentlySelectedDatabase = databaseId
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
navigate("/database", { replace: true })
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
@ -11,14 +20,14 @@
|
||||||
{#each $store.appInstances as { id, name }}
|
{#each $store.appInstances as { id, name }}
|
||||||
<li>
|
<li>
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
{#if id === $store.currentPageName}
|
{#if id === $store.currentlySelectedDatabase}
|
||||||
<CheckIcon />
|
<CheckIcon />
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class:active={id === $store.currentPageName}
|
class:active={id === $store.currentlySelectedDatabase}
|
||||||
on:click={() => store.setCurrentPage(id)}>
|
on:click={() => selectDatabase(id)}>
|
||||||
{name}
|
{name}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
|
|
||||||
store.subscribe(state => {
|
store.subscribe(state => {
|
||||||
if (state.currentNode) {
|
if (state.currentNode) {
|
||||||
navActive =
|
navActive = node.nodeId === state.currentNode.nodeId
|
||||||
getContext("activeNav") === "database" && node.nodeId === state.currentNode.nodeId
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -70,7 +70,19 @@
|
||||||
<div class="components-list-container">
|
<div class="components-list-container">
|
||||||
<div class="nav-group-header">
|
<div class="nav-group-header">
|
||||||
<div class="hierarchy-title">Schema</div>
|
<div class="hierarchy-title">Schema</div>
|
||||||
<DropdownButton iconName="plus" actions={newChildActions} />
|
<div class="uk-inline">
|
||||||
|
<i class="ri-add-line" />
|
||||||
|
<div uk-dropdown="mode: click">
|
||||||
|
<ul class="uk-nav uk-dropdown-nav">
|
||||||
|
<li>
|
||||||
|
Model
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
View
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ export const generateSchema = (hierarchy, indexNode) => {
|
||||||
keys,
|
keys,
|
||||||
map(k => ({ name: k, type: schema[k].name })),
|
map(k => ({ name: k, type: schema[k].name })),
|
||||||
filter(s => s.name !== "sortKey"),
|
filter(s => s.name !== "sortKey"),
|
||||||
orderBy("name", ["desc"]), // reverse aplha
|
orderBy("name", ["desc"]), // reverse alpha
|
||||||
concat([{ name: "sortKey", type: all.string.name }]), // sortKey on end
|
concat([{ name: "sortKey", type: all.string.name }]), // sortKey on end
|
||||||
reverse, // sortKey first, then rest are alphabetical
|
reverse, // sortKey first, then rest are alphabetical
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in New Issue