Merge pull request #126 from shogunpurple/backend-design
Backend design
This commit is contained in:
commit
e88d3e821a
|
@ -5,6 +5,7 @@
|
||||||
import { store, initialise } from "./builderStore"
|
import { store, initialise } from "./builderStore"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import IconButton from "./common/IconButton.svelte"
|
import IconButton from "./common/IconButton.svelte"
|
||||||
|
import Spinner from "./common/Spinner.svelte"
|
||||||
|
|
||||||
let init = initialise()
|
let init = initialise()
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,9 +13,9 @@
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
{#await init}
|
{#await init}
|
||||||
|
<div class="spinner-container">
|
||||||
<h1>loading</h1>
|
<Spinner />
|
||||||
|
</div>
|
||||||
{:then result}
|
{:then result}
|
||||||
|
|
||||||
{#if $store.hasAppPackage}
|
{#if $store.hasAppPackage}
|
||||||
|
@ -52,4 +53,13 @@
|
||||||
bottom: 25px;
|
bottom: 25px;
|
||||||
right: 25px;
|
right: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spinner-container {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import Checkbox from "../common/Checkbox.svelte"
|
import Checkbox from "../common/Checkbox.svelte"
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import { validateAccessLevels } from "../common/core"
|
import { validateAccessLevels } from "../common/core"
|
||||||
import ErrorsBox from "../common/ErrorsBox.svelte"
|
import ErrorsBox from "../common/ErrorsBox.svelte"
|
||||||
|
|
||||||
|
@ -64,10 +65,11 @@
|
||||||
|
|
||||||
<form class="uk-form-horizontal">
|
<form class="uk-form-horizontal">
|
||||||
|
|
||||||
<Textbox label="Name" bind:text={clonedLevel.name} />
|
<Textbox label="Access Level Name" bind:text={clonedLevel.name} />
|
||||||
|
|
||||||
|
<h4 class="budibase__title--4">Permissions</h4>
|
||||||
{#each permissionMatrix as permission}
|
{#each permissionMatrix as permission}
|
||||||
<div>
|
<div class="permission-container">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={getPermissionName(permission.permission)}
|
label={getPermissionName(permission.permission)}
|
||||||
checked={permission.hasPermission}
|
checked={permission.hasPermission}
|
||||||
|
@ -77,15 +79,19 @@
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ButtonGroup style="margin-top: 10px">
|
<div class="uk-modal-footer uk-text-right">
|
||||||
<Button color="primary" grouped on:click={save}>Save</Button>
|
<ButtonGroup>
|
||||||
<Button color="secondary" grouped on:click={() => onFinished()}>
|
<ActionButton primary grouped on:click={save}>Save</ActionButton>
|
||||||
|
<ActionButton alert grouped on:click={() => onFinished()}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.permission-container {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import { store } from "../builderStore"
|
import { store } from "../builderStore"
|
||||||
import { generateFullPermissions, getNewAccessLevel } from "../common/core"
|
import { generateFullPermissions, getNewAccessLevel } from "../common/core"
|
||||||
import getIcon from "../common/icon"
|
import getIcon from "../common/icon"
|
||||||
|
@ -47,11 +48,10 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button grouped color="secondary" on:click={createNewLevel}>
|
<ActionButton primary on:click={createNewLevel}>
|
||||||
Create New Access Level
|
Create New Access Level
|
||||||
</Button>
|
</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|
||||||
{#if $store.accessLevels}
|
{#if $store.accessLevels}
|
||||||
|
@ -82,7 +82,11 @@
|
||||||
</table>
|
</table>
|
||||||
{:else}(no actions added){/if}
|
{:else}(no actions added){/if}
|
||||||
|
|
||||||
<Modal bind:isOpen={isEditing}>
|
<Modal
|
||||||
|
onClosed={() => isEditing = false}
|
||||||
|
bind:isOpen={isEditing}
|
||||||
|
title={isEditing ? "Edit Access Level" : "Create Access Level"}
|
||||||
|
>
|
||||||
{#if isEditing}
|
{#if isEditing}
|
||||||
<AccessLevelView
|
<AccessLevelView
|
||||||
level={editingLevel}
|
level={editingLevel}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Textbox from "../common/Textbox.svelte"
|
import Textbox from "../common/Textbox.svelte"
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import { cloneDeep, filter, keys, map, isUndefined } from "lodash/fp"
|
import { cloneDeep, filter, keys, map, isUndefined } from "lodash/fp"
|
||||||
import ErrorsBox from "../common/ErrorsBox.svelte"
|
import ErrorsBox from "../common/ErrorsBox.svelte"
|
||||||
|
@ -10,16 +11,15 @@
|
||||||
export let action
|
export let action
|
||||||
export let onFinished = action => {}
|
export let onFinished = action => {}
|
||||||
export let allActions
|
export let allActions
|
||||||
export let isNew = true
|
|
||||||
|
|
||||||
let optKey = ""
|
let optKey = ""
|
||||||
let optValue = ""
|
let optValue = ""
|
||||||
|
|
||||||
let clonedAction = cloneDeep(action)
|
let clonedAction = cloneDeep(action)
|
||||||
let initialOptions = pipe(action.initialOptions, [
|
let initialOptions = pipe(
|
||||||
keys,
|
action.initialOptions,
|
||||||
map(k => ({ key: k, value: action.initialOptions[k] })),
|
[keys, map(k => ({ key: k, value: action.initialOptions[k] }))]
|
||||||
])
|
)
|
||||||
let errors = []
|
let errors = []
|
||||||
|
|
||||||
const addNewOption = () => {
|
const addNewOption = () => {
|
||||||
|
@ -44,17 +44,26 @@
|
||||||
const removeOption = opt => {
|
const removeOption = opt => {
|
||||||
if (opt) {
|
if (opt) {
|
||||||
delete clonedAction.initialOptions[opt.key]
|
delete clonedAction.initialOptions[opt.key]
|
||||||
initialOptions = pipe(initialOptions, [filter(o => o.key !== opt.key)])
|
initialOptions = pipe(
|
||||||
|
initialOptions,
|
||||||
|
[filter(o => o.key !== opt.key)]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const save = () => {
|
const save = () => {
|
||||||
const newActionsList = [
|
const newActionsList = [
|
||||||
...pipe(allActions, [filter(a => a !== action)]),
|
...pipe(
|
||||||
|
allActions,
|
||||||
|
[filter(a => a !== action)]
|
||||||
|
),
|
||||||
clonedAction,
|
clonedAction,
|
||||||
]
|
]
|
||||||
|
|
||||||
errors = pipe(newActionsList, [validateActions, map(e => e.error)])
|
errors = pipe(
|
||||||
|
newActionsList,
|
||||||
|
[validateActions, map(e => e.error)]
|
||||||
|
)
|
||||||
|
|
||||||
if (errors.length === 0) onFinished(clonedAction)
|
if (errors.length === 0) onFinished(clonedAction)
|
||||||
}
|
}
|
||||||
|
@ -89,9 +98,7 @@
|
||||||
class="uk-input uk-width-1-4 uk-margin-right"
|
class="uk-input uk-width-1-4 uk-margin-right"
|
||||||
placeholder="value"
|
placeholder="value"
|
||||||
bind:value={optValue} />
|
bind:value={optValue} />
|
||||||
<Button color="primary-outline uk-width-1-4" on:click={addNewOption}>
|
<ActionButton primary on:click={addNewOption}>Add</ActionButton>
|
||||||
Add
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 10px">
|
||||||
{#each initialOptions as option}
|
{#each initialOptions as option}
|
||||||
|
@ -107,11 +114,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="uk-modal-footer uk-text-right">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button color="secondary" grouped on:click={save}>Save</Button>
|
<ActionButton primary grouped on:click={save}>Save</ActionButton>
|
||||||
<Button color="tertiary" grouped on:click={cancel}>Cancel</Button>
|
<ActionButton alert grouped on:click={cancel}>Cancel</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -19,11 +19,16 @@
|
||||||
|
|
||||||
let actionsArray = []
|
let actionsArray = []
|
||||||
store.subscribe(s => {
|
store.subscribe(s => {
|
||||||
actionsArray = pipe(s.actions, [keys, map(k => s.actions[k])])
|
actionsArray = pipe(
|
||||||
|
s.actions,
|
||||||
|
[keys, map(k => s.actions[k])]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
let getDefaultOptionsHtml = defaultOptions =>
|
let getDefaultOptionsHtml = defaultOptions =>
|
||||||
pipe(defaultOptions, [
|
pipe(
|
||||||
|
defaultOptions,
|
||||||
|
[
|
||||||
keys,
|
keys,
|
||||||
map(
|
map(
|
||||||
k =>
|
k =>
|
||||||
|
@ -32,7 +37,8 @@
|
||||||
)}`
|
)}`
|
||||||
),
|
),
|
||||||
join("<br>"),
|
join("<br>"),
|
||||||
])
|
]
|
||||||
|
)
|
||||||
|
|
||||||
let actionEditingFinished = action => {
|
let actionEditingFinished = action => {
|
||||||
if (action) {
|
if (action) {
|
||||||
|
@ -43,7 +49,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h3 class="title">Actions</h3>
|
<h3 class="budibase__title--3">Actions</h3>
|
||||||
|
|
||||||
{#if actionsArray}
|
{#if actionsArray}
|
||||||
<table class="fields-table uk-table uk-table-small uk-table-striped">
|
<table class="fields-table uk-table uk-table-small uk-table-striped">
|
||||||
|
@ -79,7 +85,9 @@
|
||||||
</table>
|
</table>
|
||||||
{:else}(no actions added){/if}
|
{:else}(no actions added){/if}
|
||||||
|
|
||||||
<Modal bind:isOpen={isEditing}>
|
<Modal
|
||||||
|
title={editingActionIsNew ? 'Create Action' : 'Edit Action'}
|
||||||
|
bind:isOpen={isEditing}>
|
||||||
{#if isEditing}
|
{#if isEditing}
|
||||||
<ActionView
|
<ActionView
|
||||||
action={editingAction}
|
action={editingAction}
|
||||||
|
@ -99,11 +107,6 @@
|
||||||
color: var(--secondary75);
|
color: var(--secondary75);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 3rem 0rem 0rem 0rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-content {
|
.table-content {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import getIcon from "../common/icon"
|
import getIcon from "../common/icon"
|
||||||
import { store } from "../builderStore"
|
import { store } from "../builderStore"
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import Actions from "./Actions.svelte"
|
import Actions from "./Actions.svelte"
|
||||||
import Triggers from "./Triggers.svelte"
|
import Triggers from "./Triggers.svelte"
|
||||||
|
@ -83,12 +84,12 @@
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<div class="actions-header">
|
<div class="actions-header">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button color="secondary" grouped on:click={newAction}>
|
<ActionButton color="secondary" grouped on:click={newAction}>
|
||||||
Create New Action
|
Create New Action
|
||||||
</Button>
|
</ActionButton>
|
||||||
<Button color="tertiary" grouped on:click={newTrigger}>
|
<ActionButton color="tertiary" grouped on:click={newTrigger}>
|
||||||
Create New Trigger
|
Create New Trigger
|
||||||
</Button>
|
</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -121,6 +122,7 @@
|
||||||
|
|
||||||
.actions-header {
|
.actions-header {
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-view {
|
.node-view {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Textbox from "../common/Textbox.svelte"
|
import Textbox from "../common/Textbox.svelte"
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import Dropdown from "../common/Dropdown.svelte"
|
import Dropdown from "../common/Dropdown.svelte"
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import CodeArea from "../common/CodeArea.svelte"
|
import CodeArea from "../common/CodeArea.svelte"
|
||||||
|
@ -13,7 +14,6 @@
|
||||||
export let onFinished = action => {}
|
export let onFinished = action => {}
|
||||||
export let allTriggers
|
export let allTriggers
|
||||||
export let allActions
|
export let allActions
|
||||||
export let isNew = true
|
|
||||||
|
|
||||||
let clonedTrigger = cloneDeep(trigger)
|
let clonedTrigger = cloneDeep(trigger)
|
||||||
let errors = []
|
let errors = []
|
||||||
|
@ -22,7 +22,10 @@
|
||||||
let cancel = () => onFinished()
|
let cancel = () => onFinished()
|
||||||
let save = () => {
|
let save = () => {
|
||||||
const newTriggersList = [
|
const newTriggersList = [
|
||||||
...pipe(allTriggers, [filter(t => t !== trigger)]),
|
...pipe(
|
||||||
|
allTriggers,
|
||||||
|
[filter(t => t !== trigger)]
|
||||||
|
),
|
||||||
clonedTrigger,
|
clonedTrigger,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -51,19 +54,22 @@
|
||||||
options={['', ...actionNames]}
|
options={['', ...actionNames]}
|
||||||
bind:selected={clonedTrigger.actionName} />
|
bind:selected={clonedTrigger.actionName} />
|
||||||
<CodeArea
|
<CodeArea
|
||||||
label="Condition (javascript)"
|
label="Condition"
|
||||||
|
javascript
|
||||||
bind:text={clonedTrigger.condition} />
|
bind:text={clonedTrigger.condition} />
|
||||||
<CodeArea
|
<CodeArea
|
||||||
label="Action Options Creator (javascript)"
|
label="Action Options Creator"
|
||||||
|
javascript
|
||||||
bind:text={clonedTrigger.optionsCreator} />
|
bind:text={clonedTrigger.optionsCreator} />
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div class="uk-modal-footer uk-text-right">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button color="primary" grouped on:click={save}>Save</Button>
|
<ActionButton primary on:click={save}>Save</ActionButton>
|
||||||
<Button color="tertiary" grouped on:click={cancel}>Cancel</Button>
|
<ActionButton alert on:click={cancel}>Cancel</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h3 class="title">Triggers</h3>
|
<h3 class="budibase__title--3">Triggers</h3>
|
||||||
|
|
||||||
{#if $store.triggers}
|
{#if $store.triggers}
|
||||||
<table class="fields-table uk-table uk-table-small uk-table-striped">
|
<table class="fields-table uk-table uk-table-small uk-table-striped">
|
||||||
|
@ -57,7 +57,10 @@
|
||||||
</table>
|
</table>
|
||||||
{:else}(no triggers added){/if}
|
{:else}(no triggers added){/if}
|
||||||
|
|
||||||
<Modal bind:isOpen={isEditing}>
|
<Modal
|
||||||
|
title={editingTriggerIsNew ? 'Create Trigger' : 'Edit Trigger'}
|
||||||
|
onClosed={() => (isEditing = false)}
|
||||||
|
bind:isOpen={isEditing}>
|
||||||
{#if isEditing}
|
{#if isEditing}
|
||||||
<TriggerView
|
<TriggerView
|
||||||
trigger={editingTrigger}
|
trigger={editingTrigger}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* Budibase Component Styles */
|
||||||
|
.header {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #999;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__title {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__title--2 {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__title--3 {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__title--4 {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__label--big {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.6;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__label--medium {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.6;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__label--small {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 10px;
|
||||||
|
opacity: 0.6;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__sub-heading {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__nav-item {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 7px 0 3px;
|
||||||
|
height: 35px;
|
||||||
|
margin: 5px 0;
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__nav-item.selected {
|
||||||
|
color: var(--button-text);
|
||||||
|
background: var(--background-button) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__nav-item:hover {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__input {
|
||||||
|
width: 250px;
|
||||||
|
height: 35px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid #DBDBDB;
|
||||||
|
text-align: left;
|
||||||
|
letter-spacing: 0.7px;
|
||||||
|
color: #163057;
|
||||||
|
font-size: 16px;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uk-text-right {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
|
@ -29,12 +29,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: none;
|
border: none;
|
||||||
width: 167px;
|
min-width: 120px;
|
||||||
height: 64px;
|
height: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover {
|
||||||
|
|
|
@ -8,18 +8,9 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
.root {
|
||||||
display: flex;
|
display: grid;
|
||||||
}
|
grid-auto-flow: column;
|
||||||
|
grid-gap: 5px;
|
||||||
.root:last-child {
|
width: 50%;
|
||||||
border-radius: 0 var(--borderradius) var(--borderradius) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.root:first-child {
|
|
||||||
border-radius: var(--borderradius) 0 0 var(--borderradius);
|
|
||||||
}
|
|
||||||
|
|
||||||
.root:not(:first-child):not(:last-child) {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
<script>
|
<script>
|
||||||
|
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 label = ""
|
||||||
|
export let javascript = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>{label}</div>
|
<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>
|
||||||
|
@ -13,10 +20,18 @@
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background: var(--lightslate);
|
background: var(--lightslate);
|
||||||
color: var(--white);
|
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import Button from "./Button.svelte"
|
import Button from "./Button.svelte"
|
||||||
|
import ActionButton from "./ActionButton.svelte"
|
||||||
import ButtonGroup from "./ButtonGroup.svelte"
|
import ButtonGroup from "./ButtonGroup.svelte"
|
||||||
import UIkit from "uikit"
|
import UIkit from "uikit"
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ export const hide = () => {
|
||||||
UIkit.modal(theModal).hide()
|
UIkit.modal(theModal).hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
let theModal;
|
let theModal
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
hide()
|
hide()
|
||||||
|
@ -29,29 +30,22 @@ const ok = () => {
|
||||||
hide()
|
hide()
|
||||||
onOk()
|
onOk()
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<div id="my-id" uk-modal bind:this={theModal}>
|
<div id="my-id" uk-modal bind:this={theModal}>
|
||||||
<div class="uk-modal-dialog">
|
<div class="uk-modal-dialog">
|
||||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
<button class="uk-modal-close-default" type="button" uk-close />
|
||||||
<div class="uk-modal-header">
|
<div class="uk-modal-header">
|
||||||
<h2 class="uk-modal-title">{title}</h2>
|
<h4 class="budibase__title--4">{title}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="uk-modal-body">
|
<div class="uk-modal-body">
|
||||||
<slot>{body}</slot>
|
<slot>{body}</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="uk-modal-footer">
|
<div class="uk-modal-footer">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button grouped color="primary" on:click={ok}>
|
<ActionButton alert on:click={ok}>{okText}</ActionButton>
|
||||||
{okText}
|
<ActionButton primary on:click={cancel}>{cancelText}</ActionButton>
|
||||||
</Button>
|
|
||||||
<Button grouped color="secondary" on:click={cancel}>
|
|
||||||
{cancelText}
|
|
||||||
</Button>
|
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
|
import Select from "../common/Select.svelte";
|
||||||
|
|
||||||
export let selected
|
export let selected
|
||||||
export let label
|
export let label
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
<label class="uk-form-label">{label}</label>
|
<label class="uk-form-label">{label}</label>
|
||||||
<div class="uk-form-controls">
|
<div class="uk-form-controls">
|
||||||
{#if multiple}
|
{#if multiple}
|
||||||
<select
|
<Select
|
||||||
class="uk-select uk-form-width-{width} uk-form-{size}"
|
class="uk-select uk-form-width-{width} uk-form-{size}"
|
||||||
multiple
|
multiple
|
||||||
bind:value={selected}
|
bind:value={selected}
|
||||||
|
@ -27,9 +28,9 @@
|
||||||
{!textMember ? option : textMember(option)}
|
{!textMember ? option : textMember(option)}
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</Select>
|
||||||
{:else}
|
{:else}
|
||||||
<select
|
<Select
|
||||||
class="uk-select uk-form-width-{width} uk-form-{size}"
|
class="uk-select uk-form-width-{width} uk-form-{size}"
|
||||||
bind:value={selected}
|
bind:value={selected}
|
||||||
on:change>
|
on:change>
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
{!textMember ? option : textMember(option)}
|
{!textMember ? option : textMember(option)}
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</Select>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
class="dropdown-content"
|
class="dropdown-content"
|
||||||
style="display: {isDroppedDown ? 'inline-block' : 'none'}">
|
style="display: {isDroppedDown ? 'inline-block' : 'none'}">
|
||||||
{#each actions as action}
|
{#each actions as action}
|
||||||
<div class="action-row" on:click={action.onclick}>{action.label}</div>
|
<div class="budibase__nav-item" on:click={action.onclick}>{action.label}</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M0.220001 0.220001H19.78V19.7802H0.220001V0.220001Z"
|
||||||
|
fill="#F0DB4F" />
|
||||||
|
<path
|
||||||
|
d="M18.1792 15.115C18.0359 14.2227 17.4541 13.4731 15.7305 12.7742C15.1317
|
||||||
|
12.4991 14.4642 12.302 14.2653 11.8483C14.1947 11.5842 14.1853 11.4355 14.23
|
||||||
|
11.2756C14.3583 10.7569 14.9775 10.5952 15.4683 10.7439C15.7844 10.8499
|
||||||
|
16.0836 11.0934 16.2641 11.482C17.1081 10.9355 17.1064 10.9391 17.6958
|
||||||
|
10.5634C17.48 10.2289 17.3648 10.0745 17.2236 9.93142C16.7159 9.36439
|
||||||
|
16.0242 9.07235 14.918 9.0947L14.3417 9.16923C13.7895 9.30876 13.2633 9.5986
|
||||||
|
12.9547 9.9872C12.0287 11.0378 12.2928 12.8766 13.4195 13.6333C14.5295
|
||||||
|
14.4664 16.1601 14.6559 16.3684 15.435C16.5711 16.3888 15.6675 16.6975
|
||||||
|
14.7694 16.5878C14.1075 16.4502 13.7394 16.1138 13.3414 15.502C12.6089
|
||||||
|
15.926 12.6089 15.926 11.8558 16.3591C12.0344 16.7495 12.222 16.9263 12.5214
|
||||||
|
17.2645C13.9383 18.7017 17.4839 18.6311 18.1198 16.4558C18.1456 16.3811
|
||||||
|
18.3169 15.883 18.1792 15.115V15.115ZM10.8534 9.20985H9.0239L9.0164
|
||||||
|
13.9399C9.0164 14.9458 9.06843 15.868 8.90484 16.1506C8.63718 16.7066
|
||||||
|
7.94359 16.6377 7.62749 16.5299C7.30578 16.3717 7.14218 16.1469 6.95265
|
||||||
|
15.8291C6.90062 15.7378 6.86156 15.6672 6.84843 15.6617L5.36093
|
||||||
|
16.5727C5.60828 17.0803 5.97265 17.521 6.43937 17.8072C7.13656 18.2256
|
||||||
|
8.07359 18.3539 9.05359 18.1289C9.6914 17.9431 10.2417 17.5583 10.5298
|
||||||
|
16.9725C10.9464 16.2045 10.857 15.275 10.8533 14.2469C10.8626 12.5695
|
||||||
|
10.8534 10.8925 10.8534 9.20985Z"
|
||||||
|
fill="#323330" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -15,3 +15,4 @@ export { default as CheckIcon } from "./Check.svelte"
|
||||||
export { default as GridIcon } from "./Grid.svelte"
|
export { default as GridIcon } from "./Grid.svelte"
|
||||||
export { default as ShapeIcon } from "./Shape.svelte"
|
export { default as ShapeIcon } from "./Shape.svelte"
|
||||||
export { default as AddIcon } from "./Add.svelte"
|
export { default as AddIcon } from "./Add.svelte"
|
||||||
|
export { default as JavaScriptIcon } from "./JavaScript.svelte"
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import UIkit from "uikit"
|
import UIkit from "uikit"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
|
|
||||||
export let isOpen = false
|
export let isOpen = false
|
||||||
export let onClosed = () => {}
|
export let onClosed = () => {}
|
||||||
export let id = ""
|
export let id = ""
|
||||||
|
export let title
|
||||||
|
|
||||||
let ukModal
|
let ukModal
|
||||||
let listenerAdded = false
|
let listenerAdded = false
|
||||||
|
@ -25,13 +27,20 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={ukModal} uk-modal {id}>
|
<div bind:this={ukModal} uk-modal {id}>
|
||||||
<div class="uk-modal-dialog uk-modal-body" uk-overflow-auto>
|
<div class="uk-modal-dialog" uk-overflow-auto>
|
||||||
|
{#if title}
|
||||||
|
<div class="uk-modal-header">
|
||||||
|
<h4 class="budibase__title--4">{title}</h4>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div class="uk-modal-body">
|
||||||
{#if onClosed}
|
{#if onClosed}
|
||||||
<button class="uk-modal-close-default" type="button" uk-close />
|
<button class="uk-modal-close-default" type="button" uk-close />
|
||||||
{/if}
|
{/if}
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.uk-modal-dialog {
|
.uk-modal-dialog {
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
<div class="uk-margin">
|
<div class="uk-margin">
|
||||||
<label class="uk-form-label">{label}</label>
|
<label class="uk-form-label">{label}</label>
|
||||||
<div class="uk-form-controls">
|
<div class="uk-form-controls">
|
||||||
<input class="uk-input" {value} on:change={inputChanged} />
|
<input class="budibase__input" {value} on:change={inputChanged} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
color: var(--secondary50);
|
color: var(--secondary50);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<script>
|
||||||
|
export let ratio = "4.5"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span uk-spinner={`ratio: ${ratio}`} />
|
|
@ -13,7 +13,7 @@
|
||||||
<label class="uk-form-label">{label}</label>
|
<label class="uk-form-label">{label}</label>
|
||||||
<div class="uk-form-controls">
|
<div class="uk-form-controls">
|
||||||
<input
|
<input
|
||||||
class="uk-input uk-form-width-{width} uk-form-{size}"
|
class="budibase__input"
|
||||||
class:uk-form-danger={hasError}
|
class:uk-form-danger={hasError}
|
||||||
on:change
|
on:change
|
||||||
bind:value={text}
|
bind:value={text}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import Button from "../common/Button.svelte"
|
import Button from "../common/Button.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import ButtonGroup from "../common/ButtonGroup.svelte"
|
import ButtonGroup from "../common/ButtonGroup.svelte"
|
||||||
import { store } from "../builderStore"
|
import { store } from "../builderStore"
|
||||||
import Modal from "../common/Modal.svelte"
|
import Modal from "../common/Modal.svelte"
|
||||||
|
@ -20,14 +21,14 @@
|
||||||
<div class="root" style="left: {left}">
|
<div class="root" style="left: {left}">
|
||||||
|
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button color="secondary" grouped on:click={store.saveCurrentNode}>
|
<ActionButton color="secondary" grouped on:click={store.saveCurrentNode}>
|
||||||
{#if $store.currentNodeIsNew}Create{:else}Update{/if}
|
{#if $store.currentNodeIsNew}Create{:else}Update{/if}
|
||||||
</Button>
|
</ActionButton>
|
||||||
|
|
||||||
{#if !$store.currentNodeIsNew}
|
{#if !$store.currentNodeIsNew}
|
||||||
<Button color="tertiary" grouped on:click={openConfirmDelete}>
|
<ActionButton alert grouped on:click={openConfirmDelete}>
|
||||||
Delete
|
Delete
|
||||||
</Button>
|
</ActionButton>
|
||||||
{/if}
|
{/if}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|
||||||
|
@ -37,15 +38,17 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Modal bind:isOpen={confirmDelete}>
|
<Modal onClosed={() => (confirmDelete = false)} bind:isOpen={confirmDelete}>
|
||||||
<div style="margin: 10px 0px 20px 0px">
|
<span>
|
||||||
Are you sure you want to delete {$store.currentNode.name}?
|
Are you sure you want to delete {$store.currentNode.name}?
|
||||||
</div>
|
</span>
|
||||||
<div style="float:right">
|
<div class="uk-modal-footer uk-text-right">
|
||||||
<Button color="primary" on:click={deleteCurrentNode}>Yes</Button>
|
<ButtonGroup>
|
||||||
<Button color="secondary" on:click={() => (confirmDelete = false)}>
|
<ActionButton alert on:click={deleteCurrentNode}>Yes</ActionButton>
|
||||||
|
<ActionButton primary on:click={() => (confirmDelete = false)}>
|
||||||
No
|
No
|
||||||
</Button>
|
</ActionButton>
|
||||||
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,4 +59,11 @@
|
||||||
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>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import ValuesList from "../common/ValuesList.svelte"
|
import ValuesList from "../common/ValuesList.svelte"
|
||||||
import ErrorsBox from "../common/ErrorsBox.svelte"
|
import ErrorsBox from "../common/ErrorsBox.svelte"
|
||||||
import Checkbox from "../common/Checkbox.svelte"
|
import Checkbox from "../common/Checkbox.svelte"
|
||||||
|
import ActionButton from "../common/ActionButton.svelte"
|
||||||
import DatePicker from "../common/DatePicker.svelte"
|
import DatePicker from "../common/DatePicker.svelte"
|
||||||
import {
|
import {
|
||||||
cloneDeep,
|
cloneDeep,
|
||||||
|
@ -141,18 +142,14 @@
|
||||||
label="Max Length"
|
label="Max Length"
|
||||||
bind:value={clonedField.typeOptions.maxLength} />
|
bind:value={clonedField.typeOptions.maxLength} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ButtonGroup style="float: right;">
|
<div class="uk-modal-footer uk-text-right">
|
||||||
<Button color="primary" grouped on:click={save}>Save</Button>
|
<ButtonGroup>
|
||||||
<Button color="tertiary" grouped on:click={() => onFinished(false)}>
|
<ActionButton primary on:click={save}>Save</ActionButton>
|
||||||
|
<ActionButton alert on:click={() => onFinished(false)}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</ActionButton>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -14,7 +14,9 @@
|
||||||
|
|
||||||
store.subscribe($store => {
|
store.subscribe($store => {
|
||||||
index = $store.currentNode
|
index = $store.currentNode
|
||||||
indexableRecords = pipe($store.hierarchy, [
|
indexableRecords = pipe(
|
||||||
|
$store.hierarchy,
|
||||||
|
[
|
||||||
hierarchyFunctions.getFlattenedHierarchy,
|
hierarchyFunctions.getFlattenedHierarchy,
|
||||||
filter(hierarchyFunctions.isDecendant(index.parent())),
|
filter(hierarchyFunctions.isDecendant(index.parent())),
|
||||||
filter(hierarchyFunctions.isRecord),
|
filter(hierarchyFunctions.isRecord),
|
||||||
|
@ -22,7 +24,8 @@
|
||||||
node: n,
|
node: n,
|
||||||
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
|
isallowed: some(id => n.nodeId === id)(index.allowedRecordNodeIds),
|
||||||
})),
|
})),
|
||||||
])
|
]
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleAllowedRecord = record => {
|
const toggleAllowedRecord = record => {
|
||||||
|
@ -40,7 +43,7 @@
|
||||||
<Textbox bind:text={index.name} label="Name" />
|
<Textbox bind:text={index.name} label="Name" />
|
||||||
|
|
||||||
<div class="allowed-records">
|
<div class="allowed-records">
|
||||||
<div>Records to Index</div>
|
<div class="index-label">Records to Index</div>
|
||||||
{#each indexableRecords as rec}
|
{#each indexableRecords as rec}
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -55,11 +58,9 @@
|
||||||
bind:selected={index.indexType}
|
bind:selected={index.indexType}
|
||||||
options={['ancestor', 'reference']} />
|
options={['ancestor', 'reference']} />
|
||||||
|
|
||||||
<CodeArea bind:text={index.map} label="Map (javascript)" />
|
<CodeArea bind:text={index.map} javascript label="Map" />
|
||||||
<CodeArea bind:text={index.filter} label="Filter (javascript expression)" />
|
<CodeArea bind:text={index.filter} javascript label="Filter" />
|
||||||
<CodeArea
|
<CodeArea javascript bind:text={index.getShardName} label="Shard Name" />
|
||||||
bind:text={index.getShardName}
|
|
||||||
label="Shard Name (javascript expression)" />
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -76,4 +77,9 @@
|
||||||
.allowed-records > span {
|
.allowed-records > span {
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.index-label {
|
||||||
|
color: #333;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
<div class="root">
|
<div class="root">
|
||||||
|
|
||||||
<form class="uk-form-horizontal">
|
<form class="uk-form-horizontal">
|
||||||
<h3 class="settings-title">Settings</h3>
|
<h3 class="budibase__title--3">Settings</h3>
|
||||||
|
|
||||||
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
|
<Textbox label="Name:" bind:text={record.name} on:change={nameChanged} />
|
||||||
{#if !record.isSingle}
|
{#if !record.isSingle}
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
<div class="recordkey">{record.nodeKey()}</div>
|
<div class="recordkey">{record.nodeKey()}</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
<h3 class="title">
|
<h3 class="budibase__title--3">
|
||||||
Fields
|
Fields
|
||||||
<span class="add-field-button" on:click={newField}>
|
<span class="add-field-button" on:click={newField}>
|
||||||
{@html getIcon('plus')}
|
{@html getIcon('plus')}
|
||||||
|
@ -150,6 +150,7 @@
|
||||||
|
|
||||||
{#if editingField}
|
{#if editingField}
|
||||||
<Modal
|
<Modal
|
||||||
|
title="Manage Index Fields"
|
||||||
bind:isOpen={editingField}
|
bind:isOpen={editingField}
|
||||||
onClosed={() => onFinishedFieldEdit(false)}>
|
onClosed={() => onFinishedFieldEdit(false)}>
|
||||||
<FieldView
|
<FieldView
|
||||||
|
@ -160,7 +161,7 @@
|
||||||
</Modal>
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h3 class="title">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">
|
||||||
|
@ -199,15 +200,6 @@
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-title {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 3rem 0rem 0rem 0rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recordkey {
|
.recordkey {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "./budibase.css";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--primary100: #173157FF;
|
--primary100: #173157FF;
|
||||||
--primary75: #454CA0BF;
|
--primary75: #454CA0BF;
|
||||||
|
|
|
@ -105,9 +105,8 @@
|
||||||
.nav-group-header {
|
.nav-group-header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: [icon] auto [title] 1fr [button] auto;
|
grid-template-columns: [icon] auto [title] 1fr [button] auto;
|
||||||
padding: 2rem 1rem 0rem 1rem;
|
padding: 2rem 1rem 1rem 1rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-group-header > div:nth-child(1) {
|
.nav-group-header > div:nth-child(1) {
|
||||||
|
@ -137,13 +136,12 @@
|
||||||
|
|
||||||
.hierarchy-title {
|
.hierarchy-title {
|
||||||
flex: auto 1 1;
|
flex: auto 1 1;
|
||||||
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hierarchy {
|
.hierarchy {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1 0 auto;
|
|
||||||
height: 100px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hierarchy-items-container {
|
.hierarchy-items-container {
|
||||||
|
|
|
@ -13,16 +13,14 @@
|
||||||
if (s.currentNode)
|
if (s.currentNode)
|
||||||
navActive =
|
navActive =
|
||||||
s.activeNav === "database" && node.nodeId === s.currentNode.nodeId
|
s.activeNav === "database" && node.nodeId === s.currentNode.nodeId
|
||||||
? "active"
|
|
||||||
: ""
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
|
||||||
<div
|
<div
|
||||||
class="title {navActive}"
|
class="budibase__nav-item"
|
||||||
on:click={() => store.selectExistingNode(node.nodeId)}
|
on:click={() => store.selectExistingNode(node.nodeId)}
|
||||||
style="padding-left: {20 + level * 20}px">
|
class:selected={navActive}>
|
||||||
|
<div style="padding-left: {20 + level * 20}px">
|
||||||
{@html getIcon(icon, 12)}
|
{@html getIcon(icon, 12)}
|
||||||
<span style="margin-left: 1rem">{node.name}</span>
|
<span style="margin-left: 1rem">{node.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,27 +35,3 @@
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
.root {
|
|
||||||
display: block;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--secondary50);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title:hover {
|
|
||||||
background-color: var(--secondary10);
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background-color: var(--primary10);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -8,28 +8,16 @@
|
||||||
let navActive = ""
|
let navActive = ""
|
||||||
|
|
||||||
store.subscribe(db => {
|
store.subscribe(db => {
|
||||||
navActive = db.activeNav === name ? "active" : ""
|
navActive = db.activeNav === name
|
||||||
})
|
})
|
||||||
|
|
||||||
const setActive = () => store.setActiveNav(name)
|
const setActive = () => store.setActiveNav(name)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="nav-item {navActive}" on:click={setActive}>{label}</div>
|
<div class="budibase__nav-item backend-nav-item" class:selected={navActive} on:click={setActive}>{label}</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.nav-item {
|
.backend-nav-item {
|
||||||
padding: 1.5rem 1rem 0rem 1rem;
|
padding-left: 25px;
|
||||||
font-size: 0.9rem;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item:hover {
|
|
||||||
background-color: var(--primary10);
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background-color: var(--primary10);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
{#each _screens as screen}
|
{#each _screens as screen}
|
||||||
<div
|
<div
|
||||||
class="hierarchy-item component"
|
class="budibase__nav-item component"
|
||||||
class:selected={$store.currentComponentInfo._id === screen.component.props._id}
|
class:selected={$store.currentComponentInfo._id === screen.component.props._id}
|
||||||
on:click|stopPropagation={() => store.setCurrentScreen(screen.title)}>
|
on:click|stopPropagation={() => store.setCurrentScreen(screen.title)}>
|
||||||
|
|
||||||
|
@ -92,37 +92,16 @@
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:this={confirmDeleteDialog}
|
bind:this={confirmDeleteDialog}
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component`}
|
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component?`}
|
||||||
okText="Delete Component"
|
okText="Delete Component"
|
||||||
onOk={() => store.deleteComponent(componentToDelete)} />
|
onOk={() => store.deleteComponent(componentToDelete)} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
.root {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 0.8rem;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hierarchy-item {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0 7px 0 3px;
|
|
||||||
height: 35px;
|
|
||||||
margin: 5px 0;
|
|
||||||
border-radius: 0 5px 5px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hierarchy-item:hover {
|
|
||||||
background: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
color: var(--button-text);
|
|
||||||
background: var(--background-button) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
{#each components as component, index (component._id)}
|
{#each components as component, index (component._id)}
|
||||||
<li on:click|stopPropagation={() => onSelect(component)}>
|
<li on:click|stopPropagation={() => onSelect(component)}>
|
||||||
<div
|
<div
|
||||||
class="item"
|
class="budibase__nav-item item"
|
||||||
class:selected={currentComponent === component}
|
class:selected={currentComponent === component}
|
||||||
style="padding-left: {level * 20 + 53}px">
|
style="padding-left: {level * 20 + 53}px">
|
||||||
<div>{get_capitalised_name(component._component)}</div>
|
<div>{get_capitalised_name(component._component)}</div>
|
||||||
|
@ -98,7 +98,6 @@
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 0.8rem;
|
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,12 +128,6 @@
|
||||||
color: var(--button-text);
|
color: var(--button-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected {
|
|
||||||
color: var(--button-text);
|
|
||||||
background: var(--background-button) !important;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reorder-buttons {
|
.reorder-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -34,10 +34,17 @@
|
||||||
let selectedEvent = null
|
let selectedEvent = null
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
const componentDefinition = components.find(c => c.name === component._component)
|
const componentDefinition = components.find(
|
||||||
|
c => c.name === component._component
|
||||||
|
)
|
||||||
events = Object.keys(componentDefinition.props)
|
events = Object.keys(componentDefinition.props)
|
||||||
.filter(propName => componentDefinition.props[propName].type === EVENT_TYPE)
|
.filter(
|
||||||
.map(propName => ({ name: propName, handlers: (component[propName] || []) }))
|
propName => componentDefinition.props[propName].type === EVENT_TYPE
|
||||||
|
)
|
||||||
|
.map(propName => ({
|
||||||
|
name: propName,
|
||||||
|
handlers: component[propName] || [],
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const openModal = event => {
|
const openModal = event => {
|
||||||
|
@ -61,7 +68,8 @@
|
||||||
{#each events as event, index}
|
{#each events as event, index}
|
||||||
{#if event.handlers.length > 0}
|
{#if event.handlers.length > 0}
|
||||||
<div
|
<div
|
||||||
class="handler-container hierarchy-item {selectedEvent && selectedEvent.index === index ? 'selected' : ''}"
|
class:selected={selectedEvent && selectedEvent.index === index}
|
||||||
|
class="handler-container budibase__nav-item"
|
||||||
on:click={() => openModal({ ...event, index })}>
|
on:click={() => openModal({ ...event, index })}>
|
||||||
<span class="event-name">{event.name}</span>
|
<span class="event-name">{event.name}</span>
|
||||||
<span class="edit-text">EDIT</span>
|
<span class="edit-text">EDIT</span>
|
||||||
|
@ -107,21 +115,9 @@
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
border: 2px solid #f9f9f9;
|
border: 2px solid #f9f9f9;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
}
|
|
||||||
|
|
||||||
.hierarchy-item {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 11px 7px;
|
|
||||||
margin: 5px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 1.5em;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hierarchy-item:hover {
|
|
||||||
background: #f9f9f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.event-name {
|
.event-name {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -51,12 +51,12 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="root">
|
|
||||||
<div
|
<div
|
||||||
class="hierarchy-item component"
|
class="budibase__nav-item"
|
||||||
class:selected={$store.currentComponentInfo._id === _layout.component.props._id}
|
class:selected={$store.currentComponentInfo._id === _layout.component.props._id}
|
||||||
on:click|stopPropagation={() => store.setScreenType('page')}>
|
on:click|stopPropagation={() => store.setScreenType('page')}>
|
||||||
|
|
||||||
|
<div class="component">
|
||||||
<span
|
<span
|
||||||
class="icon"
|
class="icon"
|
||||||
class:rotate={$store.currentPreviewItem.name !== _layout.title}>
|
class:rotate={$store.currentPreviewItem.name !== _layout.title}>
|
||||||
|
@ -87,37 +87,11 @@
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bind:this={confirmDeleteDialog}
|
bind:this={confirmDeleteDialog}
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component`}
|
body={`Are you sure you wish to delete this '${lastPartOfName(componentToDelete)}' component?`}
|
||||||
okText="Delete Component"
|
okText="Delete Component"
|
||||||
onOk={() => store.deleteComponent(componentToDelete)} />
|
onOk={() => store.deleteComponent(componentToDelete)} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.root {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hierarchy-item {
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0 7px 0 3px;
|
|
||||||
height: 35px;
|
|
||||||
margin: 5px 0;
|
|
||||||
border-radius: 0 5px 5px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hierarchy-item:hover {
|
|
||||||
background: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
color: var(--button-text);
|
|
||||||
background: var(--background-button) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185h-125.184z"/><path fill="#323330" d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zm-46.885-37.793h-11.709l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue