diff --git a/packages/builder/package.json b/packages/builder/package.json
index d308c1e5ec..6d0bb15083 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -79,6 +79,7 @@
"posthog-js": "1.4.5",
"remixicon": "2.5.0",
"shortid": "2.2.15",
+ "svelte-dnd-action": "^0.8.9",
"svelte-loading-spinners": "^0.1.1",
"svelte-portal": "0.1.0",
"uuid": "8.3.1",
diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js
index 429ba1c683..dee0b86fb3 100644
--- a/packages/builder/src/builderStore/dataBinding.js
+++ b/packages/builder/src/builderStore/dataBinding.js
@@ -120,7 +120,7 @@ const getContextBindings = (asset, componentId) => {
tableName = info.table?.name
// Add _id and _rev fields for certain types
- if (datasource.type === "table" || datasource.type === "link") {
+ if (schema && ["table", "link"].includes(datasource.type)) {
schema["_id"] = { type: "string" }
schema["_rev"] = { type: "string" }
}
diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js
index 19987764e5..8877ccef69 100644
--- a/packages/builder/src/builderStore/store/frontend.js
+++ b/packages/builder/src/builderStore/store/frontend.js
@@ -285,6 +285,7 @@ export const getFrontendStore = () => {
_id: uuid(),
_component: definition.component,
_styles: { normal: {}, hover: {}, active: {} },
+ _transition: "",
_instanceName: `New ${definition.name}`,
...cloneDeep(props),
...extras,
@@ -487,6 +488,15 @@ export const getFrontendStore = () => {
selected._styles = { normal: {}, hover: {}, active: {} }
await store.actions.preview.saveSelected()
},
+ updateTransition: async transition => {
+ const selected = get(selectedComponent)
+ if (transition == null || transition === "") {
+ selected._transition = ""
+ } else {
+ selected._transition = transition
+ }
+ await store.actions.preview.saveSelected()
+ },
updateProp: async (name, value) => {
let component = get(selectedComponent)
if (!name || !component) {
diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js
index 182736a1d5..c4085e483c 100644
--- a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js
+++ b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js
@@ -14,6 +14,7 @@ export class Component extends BaseStructure {
active: {},
selected: {},
},
+ _transition: "",
_instanceName: "",
_children: [],
}
@@ -39,6 +40,11 @@ export class Component extends BaseStructure {
return this
}
+ transition(transition) {
+ this._json._transition = transition
+ return this
+ }
+
// Shorthand for custom props "type"
type(type) {
this._json.type = type
diff --git a/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte b/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte
index e09803e130..7d56867d03 100644
--- a/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte
+++ b/packages/builder/src/components/automation/AutomationPanel/AutomationPanel.svelte
@@ -2,10 +2,6 @@
import AutomationList from "./AutomationList.svelte"
import CreateAutomationModal from "./CreateAutomationModal.svelte"
import { Modal } from "@budibase/bbui"
- import { automationStore, backendUiStore } from "builderStore"
- import { notifier } from "builderStore/store/notifications"
-
- let selectedTab = "AUTOMATIONS"
let modal
@@ -40,12 +36,4 @@
cursor: pointer;
color: var(--blue);
}
-
- span:not(.selected) {
- color: var(--grey-5);
- }
-
- span:not(.selected):hover {
- color: var(--ink);
- }
diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
index 5bd535087d..804dceec87 100644
--- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
+++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte
@@ -8,13 +8,6 @@
$: valid = !!name
$: instanceId = $backendUiStore.selectedDatabase._id
- $: appId = $store.appId
-
- function sleep(ms) {
- return new Promise(resolve => {
- setTimeout(resolve, ms)
- })
- }
async function createAutomation() {
await automationStore.actions.create({
diff --git a/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte b/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte
index a3ec5b2ae5..eb983dc948 100644
--- a/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte
+++ b/packages/builder/src/components/automation/AutomationPanel/EditAutomationPopover.svelte
@@ -60,29 +60,4 @@
div.icon i {
font-size: 16px;
}
-
- ul {
- list-style: none;
- margin: 0;
- padding: var(--spacing-s) 0;
- }
-
- li {
- display: flex;
- font-family: var(--font-sans);
- font-size: var(--font-size-xs);
- color: var(--ink);
- padding: var(--spacing-s) var(--spacing-m);
- margin: auto 0;
- align-items: center;
- cursor: pointer;
- }
-
- li:hover {
- background-color: var(--grey-2);
- }
-
- li:active {
- color: var(--blue);
- }
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBindingPanel.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBindingPanel.svelte
new file mode 100644
index 0000000000..a05d5b9996
--- /dev/null
+++ b/packages/builder/src/components/automation/SetupPanel/AutomationBindingPanel.svelte
@@ -0,0 +1,190 @@
+
+
+
+
+
Available bindings
+
+
+
+ {#each categories as [categoryName, bindings]}
+
{categoryName}
+
+ {#each bindableProperties.filter(binding =>
+ binding.label.match(searchRgx)
+ ) as binding}
+
addToText(binding)}>
+
{binding.label}
+
{binding.type}
+
+
+ {binding.description || ''}
+
+
+ {/each}
+ {/each}
+
Helpers
+
+ {#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
+
addToText(helper)}>
+
{helper.label}
+
+
+ {@html helper.description || ''}
+
+
{helper.example || ''}
+
+ {/each}
+
+
+
+ {#if !validity}
+
+ Current Handlebars syntax is invalid, please check the guide
+ here
+ for more details.
+
+ {/if}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
index ed89d4316d..2cd00d9ec0 100644
--- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
+++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte
@@ -5,7 +5,8 @@
import { Button, Input, Select, Label } from "@budibase/bbui"
import { automationStore } from "builderStore"
import WebhookDisplay from "../Shared/WebhookDisplay.svelte"
- import BindableInput from "../../common/BindableInput.svelte"
+ import DrawerBindableInput from "../../common/DrawerBindableInput.svelte"
+ import AutomationBindingPanel from './AutomationBindingPanel.svelte'
export let block
export let webhookModal
@@ -64,10 +65,12 @@
{:else if value.customType === 'password'}
{:else if value.customType === 'email'}
- block.inputs[key] = e.detail}
{bindings} />
{:else if value.customType === 'table'}
@@ -78,10 +81,12 @@
{:else if value.customType === 'triggerSchema'}
{:else if value.type === 'string' || value.type === 'number'}
- block.inputs[key] = e.detail}
{bindings} />
{/if}
@@ -102,11 +107,4 @@
font-size: var(--font-size-xs);
color: var(--grey-7);
}
-
- textarea {
- min-height: 150px;
- font-family: inherit;
- padding: 12px;
- margin-top: 8px;
- }
diff --git a/packages/builder/src/components/automation/SetupPanel/GenericBindingPopover.svelte b/packages/builder/src/components/automation/SetupPanel/GenericBindingPopover.svelte
deleted file mode 100644
index 06013cfea2..0000000000
--- a/packages/builder/src/components/automation/SetupPanel/GenericBindingPopover.svelte
+++ /dev/null
@@ -1,219 +0,0 @@
-
-
-
-
-
-
Available bindings
-
-
-
-
-
- {#each categories as [categoryName, bindings]}
-
{categoryName}
-
- {#each bindings.filter(binding =>
- binding.label.match(searchRgx)
- ) as binding}
-
onClickBinding(binding)}>
-
{binding.label}
-
{binding.type}
-
-
- {binding.description || ''}
-
-
- {/each}
- {/each}
-
Helpers
-
- {#each helpers.filter(helper => helper.label.match(searchRgx) || helper.description.match(searchRgx)) as helper}
-
onClickBinding(helper)}>
-
{helper.label}
-
-
- {@html helper.description || ''}
-
-
{helper.example || ''}
-
- {/each}
-
-
-
-
-
Data binding
-
- Binding connects one piece of data to another and makes it dynamic.
- Click the objects on the left to add them to the textbox.
-
-
- {#if !validity}
-
- Current Handlebars syntax is invalid, please check the guide
- here
- for more details.
-
- {/if}
-
-
-
-
-
-
diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte
index 7b010f2ecb..4244a0bced 100644
--- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte
+++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte
@@ -1,7 +1,8 @@
-
-
-
-
-
diff --git a/packages/builder/src/components/common/DrawerBindableInput.svelte b/packages/builder/src/components/common/DrawerBindableInput.svelte
index b534376a55..647638e8c9 100644
--- a/packages/builder/src/components/common/DrawerBindableInput.svelte
+++ b/packages/builder/src/components/common/DrawerBindableInput.svelte
@@ -8,6 +8,7 @@
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
+ export let panel = BindingPanel
export let value = ""
export let bindings = []
export let thin = true
@@ -49,7 +50,8 @@
Save
-
(tempValue = event.detail)}
diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json
index 87bef3d3a1..16109b5a96 100644
--- a/packages/builder/src/components/design/AppPreview/componentStructure.json
+++ b/packages/builder/src/components/design/AppPreview/componentStructure.json
@@ -12,6 +12,7 @@
"fieldgroup",
"stringfield",
"numberfield",
+ "passwordfield",
"optionsfield",
"booleanfield",
"longformfield",
@@ -49,6 +50,7 @@
"heading",
"text",
"image",
+ "backgroundimage",
"link",
"icon",
"embed"
diff --git a/packages/builder/src/components/design/NavigationPanel/ComponentDropdownMenu.svelte b/packages/builder/src/components/design/NavigationPanel/ComponentDropdownMenu.svelte
index 665f09ad61..23d9d40228 100644
--- a/packages/builder/src/components/design/NavigationPanel/ComponentDropdownMenu.svelte
+++ b/packages/builder/src/components/design/NavigationPanel/ComponentDropdownMenu.svelte
@@ -2,7 +2,6 @@
import { get } from "svelte/store"
import { store, currentAsset } from "builderStore"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
- import { last } from "lodash/fp"
import { findComponentParent } from "builderStore/storeUtils"
import { DropdownMenu } from "@budibase/bbui"
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
@@ -17,16 +16,10 @@
$: noChildrenAllowed = !component || !definition?.hasChildren
$: noPaste = !$store.componentToPaste
- const lastPartOfName = c => (c ? last(c._component.split("/")) : "")
-
const hideDropdown = () => {
dropdown.hide()
}
- const selectComponent = component => {
- store.actions.components.select(component)
- }
-
const moveUpComponent = () => {
const asset = get(currentAsset)
const parent = findComponentParent(asset.props, component._id)
diff --git a/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte b/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte
index c33d12c1a1..b924aa4b32 100644
--- a/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte
+++ b/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte
@@ -1,11 +1,8 @@
-
-
+
+
-
+
{#if groups.length > 0}
{#each groups as groupName}
+ {#if componentDefinition?.transitionable}
+
+ onUpdateTransition(event.target.value)} name="transition" label="Transition" secondary thin>
+ {#each transitions as transition}
+ {capitalize(transition)}
+ {/each}
+
+
+ {/if}
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
index 39eb2752bf..38f6b521fa 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte
@@ -24,29 +24,9 @@
const onStyleChanged = store.actions.components.updateStyle
const onCustomStyleChanged = store.actions.components.updateCustomStyle
+ const onUpdateTransition = store.actions.components.updateTransition
const onResetStyles = store.actions.components.resetStyles
- function walkProps(component, action) {
- action(component)
- if (component.children) {
- for (let child of component.children) {
- walkProps(child, action)
- }
- }
- }
-
- function flattenComponents(props) {
- const components = []
- props.forEach(comp =>
- walkProps(comp, c => {
- if ("_component" in c) {
- components.push(c)
- }
- })
- )
- return components
- }
-
function setAssetProps(name, value) {
const selectedAsset = get(currentAsset)
store.update(state => {
@@ -62,10 +42,6 @@
})
store.actions.preview.saveSelected()
}
-
- function getProps(obj, keys) {
- return keys.map((key, i) => [key, obj[key], obj.props._id + i])
- }
{:else if selectedCategory.value === 'settings'}
+ import {flip} from "svelte/animate";
+ import {dndzone} from "svelte-dnd-action";
import { Button, DropdownMenu, Spacer } from "@budibase/bbui"
import actionTypes from "./actions"
+ const flipDurationMs = 150;
+
const EVENT_TYPE_KEY = "##eventHandlerType"
export let actions
+ // dndzone needs an id on the array items, so this adds some temporary ones.
+ if (actions) {
+ actions = actions.map((action, i) => {
+ return {...action, id: i}
+ })
+ }
+
let addActionButton
let addActionDropdown
let selectedAction = actions?.length ? actions[0] : null
@@ -30,19 +41,26 @@
const newAction = {
parameters: {},
[EVENT_TYPE_KEY]: actionType.name,
+ id: actions ? actions.length + 1 : 0
}
if (!actions) {
actions = []
}
- actions.push(newAction)
+ actions = [...actions, newAction]
selectedAction = newAction
- actions = actions
addActionDropdown.hide()
}
const selectAction = action => () => {
selectedAction = action
}
+
+ function handleDndConsider(e) {
+ actions = e.detail.items;
+ }
+ function handleDndFinalize(e) {
+ actions = e.detail.items;
+ }
@@ -69,21 +87,23 @@
{#if actions && actions.length > 0}
- {#each actions as action, index}
-
-
{/if}
@@ -156,17 +176,6 @@
padding: var(--spacing-l);
}
- a {
- flex: 1;
- color: var(--grey-5);
- font-size: var(--font-size-s);
- text-decoration: none;
- }
-
- a:hover {
- color: var(--blue);
- }
-
i:hover {
color: var(--red);
cursor: pointer;
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogIn.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogIn.svelte
new file mode 100644
index 0000000000..c49369bf29
--- /dev/null
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogIn.svelte
@@ -0,0 +1,36 @@
+
+
+
+ Email
+ (parameters.email = value.detail)}
+ {bindings} />
+ Password
+ (parameters.password = value.detail)}
+ {bindings} />
+
+
+
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte
new file mode 100644
index 0000000000..2b0aad8342
--- /dev/null
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/LogOut.svelte
@@ -0,0 +1,7 @@
+
This action doesn't require any additional settings.
+
+
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js
index e851bdb4be..4700ea5c8f 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/EventsEditor/actions/index.js
@@ -4,6 +4,8 @@ import DeleteRow from "./DeleteRow.svelte"
import ExecuteQuery from "./ExecuteQuery.svelte"
import TriggerAutomation from "./TriggerAutomation.svelte"
import ValidateForm from "./ValidateForm.svelte"
+import LogIn from "./LogIn.svelte"
+import LogOut from "./LogOut.svelte"
// defines what actions are available, when adding a new one
// the component is the setup panel for the action
@@ -35,4 +37,12 @@ export default [
name: "Validate Form",
component: ValidateForm,
},
+ {
+ name: "Log In",
+ component: LogIn,
+ },
+ {
+ name: "Log Out",
+ component: LogOut,
+ },
]
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/IconSelect/IconSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/IconSelect/IconSelect.svelte
index b76a743438..4bf3b80ae2 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/IconSelect/IconSelect.svelte
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/IconSelect/IconSelect.svelte
@@ -1,7 +1,6 @@
diff --git a/packages/builder/src/components/integration/QueryEditor.svelte b/packages/builder/src/components/integration/QueryEditor.svelte
index 42c6d7cef9..c4d42e9812 100644
--- a/packages/builder/src/components/integration/QueryEditor.svelte
+++ b/packages/builder/src/components/integration/QueryEditor.svelte
@@ -3,7 +3,6 @@
import { Label, Spacer } from "@budibase/bbui"
import { onMount, createEventDispatcher } from "svelte"
import { themeStore } from "builderStore"
- import { handlebarsCompletions } from "constants/completions"
const dispatch = createEventDispatcher()
@@ -21,13 +20,6 @@
export let editorHeight = 500
// export let parameters = []
- let completions = handlebarsCompletions()
-
- // $: completions = parameters.map(param => ({
- // text: `{{ ${param.name} }}`,
- // displayText: param.name,
- // }))
-
let width
let height
diff --git a/packages/builder/src/components/integration/QueryFieldsBuilder.svelte b/packages/builder/src/components/integration/QueryFieldsBuilder.svelte
index 48857e5596..31ed818293 100644
--- a/packages/builder/src/components/integration/QueryFieldsBuilder.svelte
+++ b/packages/builder/src/components/integration/QueryFieldsBuilder.svelte
@@ -7,9 +7,6 @@
export let schema
export let editable
- let draftField = {}
-
- $: fieldKeys = Object.keys(fields)
$: schemaKeys = Object.keys(schema.fields)
function updateCustomFields({ detail }) {
diff --git a/packages/builder/src/components/settings/ThemeEditorDropdown.svelte b/packages/builder/src/components/settings/ThemeEditorDropdown.svelte
index c95bf5c045..64a431fc19 100644
--- a/packages/builder/src/components/settings/ThemeEditorDropdown.svelte
+++ b/packages/builder/src/components/settings/ThemeEditorDropdown.svelte
@@ -43,12 +43,7 @@
.topnavitemright:hover i {
color: var(--ink);
}
-
- h5 {
- margin: 0;
- font-weight: 500;
- }
-
+
.content {
padding: var(--spacing-xl);
}
diff --git a/packages/builder/src/components/start/TemplateList.svelte b/packages/builder/src/components/start/TemplateList.svelte
index e4c7ce92d1..19492d2bae 100644
--- a/packages/builder/src/components/start/TemplateList.svelte
+++ b/packages/builder/src/components/start/TemplateList.svelte
@@ -61,11 +61,4 @@
.card-footer {
margin-top: var(--spacing-m);
}
-
- h3 {
- font-size: var(--font-size-l);
- font-weight: 600;
- color: var(--ink);
- text-transform: capitalize;
- }
diff --git a/packages/builder/src/pages/[application]/_reset.svelte b/packages/builder/src/pages/[application]/_reset.svelte
index 71a0e918f2..2411fad0c9 100644
--- a/packages/builder/src/pages/[application]/_reset.svelte
+++ b/packages/builder/src/pages/[application]/_reset.svelte
@@ -130,11 +130,6 @@
border-bottom: 1px solid var(--grey-2);
}
- .content > div {
- height: 100%;
- width: 100%;
- }
-
.toprightnav {
display: flex;
flex-direction: row;
diff --git a/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte b/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte
index 3a51a3a75f..2080480fce 100644
--- a/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte
+++ b/packages/builder/src/pages/[application]/data/datasource/[selectedDatasource]/[query]/index.svelte
@@ -1,11 +1,8 @@
{#if loaded && $screenStore.activeLayout}
-
+
diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte
index 6980313312..84c935026e 100644
--- a/packages/client/src/components/Component.svelte
+++ b/packages/client/src/components/Component.svelte
@@ -34,12 +34,14 @@
$: id = definition._id
$: updateComponentProps(definition, $context)
$: styles = definition._styles
+ $: transition = definition._transition
// Update component context
$: componentStore.set({
id,
children: children.length,
styles: { ...styles, id },
+ transition
})
// Gets the component constructor for the specified component
diff --git a/packages/client/src/components/Screen.svelte b/packages/client/src/components/Screen.svelte
index eaa88ceee2..e0e6cdb62e 100644
--- a/packages/client/src/components/Screen.svelte
+++ b/packages/client/src/components/Screen.svelte
@@ -18,19 +18,6 @@
{#key screenDefinition?._id}
-
-
-
+
{/key}
-
-
diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js
index 1a3a4177a8..7eef69441d 100644
--- a/packages/client/src/sdk.js
+++ b/packages/client/src/sdk.js
@@ -7,6 +7,7 @@ import {
builderStore,
} from "./store"
import { styleable } from "./utils/styleable"
+import transition from "./utils/transition"
import { linkable } from "./utils/linkable"
import Provider from "./components/Provider.svelte"
import { ActionTypes } from "./constants"
@@ -19,6 +20,7 @@ export default {
screenStore,
builderStore,
styleable,
+ transition,
linkable,
Provider,
ActionTypes,
diff --git a/packages/client/src/store/auth.js b/packages/client/src/store/auth.js
index 29ded50ac7..8158e343c4 100644
--- a/packages/client/src/store/auth.js
+++ b/packages/client/src/store/auth.js
@@ -21,7 +21,7 @@ const createAuthStore = () => {
const logIn = async ({ email, password }) => {
const user = await API.logIn({ email, password })
if (!user.error) {
- store.set(user)
+ await fetchUser()
await initialise()
goToDefaultRoute()
}
diff --git a/packages/client/src/store/notification.js b/packages/client/src/store/notification.js
index 64757569ed..d69a39080e 100644
--- a/packages/client/src/store/notification.js
+++ b/packages/client/src/store/notification.js
@@ -1,42 +1,33 @@
-import { writable, derived } from "svelte/store"
-import { generate } from "shortid"
+import { writable } from "svelte/store"
const NOTIFICATION_TIMEOUT = 3000
const createNotificationStore = () => {
- const _notifications = writable([])
- let block = false
-
- const send = (message, type = "default") => {
- if (block) {
- return
- }
- _notifications.update(state => {
- return [...state, { id: generate(), type, message }]
- })
- }
-
- const blockNotifications = (timeout = 1000) => {
- block = true
- setTimeout(() => (block = false), timeout)
- }
-
- const notifications = derived(_notifications, ($_notifications, set) => {
- set($_notifications)
- if ($_notifications.length > 0) {
- const timeout = setTimeout(() => {
- _notifications.update(state => {
- state.shift()
- return state
- })
- set($_notifications)
- }, NOTIFICATION_TIMEOUT)
- return () => {
- clearTimeout(timeout)
- }
+ const timeoutIds = new Set()
+ const _notifications = writable([], () => {
+ return () => {
+ // clear all the timers
+ timeoutIds.forEach(timeoutId => {
+ clearTimeout(timeoutId)
+ })
+ _notifications.set([])
}
})
- const { subscribe } = notifications
+
+ const send = (message, type = "default") => {
+ let _id = id()
+ _notifications.update(state => {
+ return [...state, { id: _id, type, message }]
+ })
+ const timeoutId = setTimeout(() => {
+ _notifications.update(state => {
+ return state.filter(({ id }) => id !== _id)
+ })
+ }, NOTIFICATION_TIMEOUT)
+ timeoutIds.add(timeoutId)
+ }
+
+ const { subscribe } = _notifications
return {
subscribe,
@@ -45,8 +36,16 @@ const createNotificationStore = () => {
warning: msg => send(msg, "warning"),
info: msg => send(msg, "info"),
success: msg => send(msg, "success"),
- blockNotifications,
}
}
+function id() {
+ return (
+ "_" +
+ Math.random()
+ .toString(36)
+ .substr(2, 9)
+ )
+}
+
export const notificationStore = createNotificationStore()
diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js
index cadb046514..4d2865d586 100644
--- a/packages/client/src/utils/buttonActions.js
+++ b/packages/client/src/utils/buttonActions.js
@@ -1,5 +1,5 @@
import { get } from "svelte/store"
-import { routeStore, builderStore } from "../store"
+import { routeStore, builderStore, authStore } from "../store"
import { saveRow, deleteRow, executeQuery, triggerAutomation } from "../api"
import { ActionTypes } from "../constants"
@@ -68,6 +68,15 @@ const refreshDatasourceHandler = async (action, context) => {
)
}
+const loginHandler = async action => {
+ const { email, password } = action.parameters
+ await authStore.actions.logIn({ email, password })
+}
+
+const logoutHandler = async () => {
+ await authStore.actions.logOut()
+}
+
const handlerMap = {
["Save Row"]: saveRowHandler,
["Delete Row"]: deleteRowHandler,
@@ -76,6 +85,8 @@ const handlerMap = {
["Trigger Automation"]: triggerAutomationHandler,
["Validate Form"]: validateFormHandler,
["Refresh Datasource"]: refreshDatasourceHandler,
+ ["Log In"]: loginHandler,
+ ["Log Out"]: logoutHandler,
}
/**
diff --git a/packages/client/src/utils/transition.js b/packages/client/src/utils/transition.js
new file mode 100644
index 0000000000..3814c1fc65
--- /dev/null
+++ b/packages/client/src/utils/transition.js
@@ -0,0 +1,16 @@
+import { fade, blur, scale, fly } from "svelte/transition"
+
+// Default options
+const transitions = new Map([
+ ["fade", { tn: fade, opt: {} }],
+ ["blur", { tn: blur, opt: {} }],
+ // This one seems to not result in any effect
+ // ["slide", { tn: slide, opt: {} }],
+ ["scale", { tn: scale, opt: {} }],
+ ["fly", { tn: fly, opt: { y: 80 } }],
+])
+
+export default function transition(node, { type, options = {} }) {
+ const { tn, opt } = transitions.get(type) || { tn: () => {}, opt: {} }
+ return tn(node, { ...opt, ...options })
+}
diff --git a/packages/server/src/constants/screens.js b/packages/server/src/constants/screens.js
index 54c1271efc..54dcc2551d 100644
--- a/packages/server/src/constants/screens.js
+++ b/packages/server/src/constants/screens.js
@@ -21,6 +21,7 @@ exports.createHomeScreen = () => ({
active: {},
selected: {},
},
+ _transition: "fade",
type: "div",
_children: [
{
@@ -69,6 +70,7 @@ exports.createLoginScreen = app => ({
active: {},
selected: {},
},
+ _transition: "fade",
type: "div",
_children: [
{
diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json
index 6a359026df..5be1665b03 100644
--- a/packages/standard-components/manifest.json
+++ b/packages/standard-components/manifest.json
@@ -5,6 +5,7 @@
"icon": "ri-layout-column-line",
"hasChildren": true,
"styleable": true,
+ "transitionable": true,
"settings": []
},
"datagrid": {
@@ -272,6 +273,63 @@
}
]
},
+ "backgroundimage": {
+ "name": "Background Image",
+ "description": "A background image",
+ "icon": "ri-image-line",
+ "styleable": true,
+ "settings": [
+ {
+ "type": "text",
+ "label": "URL",
+ "key": "url"
+ },
+ {
+ "type": "select",
+ "label": "Position",
+ "key": "position",
+ "defaultValue": "center center",
+ "options": [
+ {
+ "label": "Center Top",
+ "value": "center top"
+ },
+ {
+ "label": "Center",
+ "value": "center center"
+ },
+ {
+ "label": "Center Bottom",
+ "value": "center bottom"
+ },
+ {
+ "label": "Left Top",
+ "value": "left top"
+ },
+ {
+ "label": "Left Center",
+ "value": "left center"
+ },
+ {
+ "label": "Left Bottom",
+ "value": "left bottom"
+ },
+ {
+ "label": "Right Top",
+ "value": "right top"
+ },
+ {
+ "label": "Right Center",
+ "value": "right center"
+ },
+ {
+ "label": "Right Bottom",
+ "value": "right bottom"
+ }
+ ]
+ }
+ ]
+ },
"icon": {
"name": "Icon",
"description": "A basic component for displaying icons",
@@ -372,6 +430,11 @@
"type": "boolean",
"label": "New Tab",
"key": "openInNewTab"
+ },
+ {
+ "type": "boolean",
+ "label": "External",
+ "key": "external"
}
]
},
@@ -1211,6 +1274,34 @@
}
]
},
+ "passwordfield": {
+ "name": "Password Field",
+ "icon": "ri-lock-password-line",
+ "styleable": true,
+ "settings": [
+ {
+ "type": "field/string",
+ "label": "Field",
+ "key": "field"
+ },
+ {
+ "type": "text",
+ "label": "Label",
+ "key": "label"
+ },
+ {
+ "type": "text",
+ "label": "Placeholder",
+ "key": "placeholder"
+ },
+ {
+ "type": "boolean",
+ "label": "Disabled",
+ "key": "disabled",
+ "defaultValue": false
+ }
+ ]
+ },
"optionsfield": {
"name": "Options Picker",
"icon": "ri-file-list-line",
diff --git a/packages/standard-components/src/BackgroundImage.svelte b/packages/standard-components/src/BackgroundImage.svelte
new file mode 100644
index 0000000000..c78cdc87b6
--- /dev/null
+++ b/packages/standard-components/src/BackgroundImage.svelte
@@ -0,0 +1,38 @@
+
+
+
+
+
diff --git a/packages/standard-components/src/Container.svelte b/packages/standard-components/src/Container.svelte
index 22139d7d7e..8f49ba0ca9 100644
--- a/packages/standard-components/src/Container.svelte
+++ b/packages/standard-components/src/Container.svelte
@@ -1,62 +1,62 @@
{#if type === 'div'}
-
+
{:else if type === 'header'}
-
+
{:else if type === 'main'}
-
+
{:else if type === 'footer'}
-
+
{:else if type === 'aside'}
-
+
{:else if type === 'summary'}
-
+
{:else if type === 'details'}
-
+
{:else if type === 'article'}
-
+
{:else if type === 'nav'}
-
+
{:else if type === 'mark'}
-
+
{:else if type === 'figure'}
-
+
{:else if type === 'figcaption'}
-
+
{:else if type === 'paragraph'}
-
+
{/if}
diff --git a/packages/standard-components/src/Link.svelte b/packages/standard-components/src/Link.svelte
index 5ae1ae75c4..0ada211eb7 100644
--- a/packages/standard-components/src/Link.svelte
+++ b/packages/standard-components/src/Link.svelte
@@ -7,11 +7,19 @@
export let url = ""
export let text = ""
export let openInNewTab = false
+ export let external = false
$: target = openInNewTab ? "_blank" : "_self"
-
- {text}
-
-
+{#if external}
+
+ {text}
+
+
+{:else}
+
+ {text}
+
+
+{/if}
diff --git a/packages/standard-components/src/forms/PasswordField.svelte b/packages/standard-components/src/forms/PasswordField.svelte
new file mode 100644
index 0000000000..71edd4f97f
--- /dev/null
+++ b/packages/standard-components/src/forms/PasswordField.svelte
@@ -0,0 +1,5 @@
+
+
+
diff --git a/packages/standard-components/src/forms/index.js b/packages/standard-components/src/forms/index.js
index 3998424db3..fed371278b 100644
--- a/packages/standard-components/src/forms/index.js
+++ b/packages/standard-components/src/forms/index.js
@@ -8,3 +8,4 @@ export { default as longformfield } from "./LongFormField.svelte"
export { default as datetimefield } from "./DateTimeField.svelte"
export { default as attachmentfield } from "./AttachmentField.svelte"
export { default as relationshipfield } from "./RelationshipField.svelte"
+export { default as passwordfield } from "./PasswordField.svelte"
diff --git a/packages/standard-components/src/index.js b/packages/standard-components/src/index.js
index 14886e2a17..a9d8920895 100644
--- a/packages/standard-components/src/index.js
+++ b/packages/standard-components/src/index.js
@@ -31,5 +31,6 @@ export { default as cardhorizontal } from "./CardHorizontal.svelte"
export { default as cardstat } from "./CardStat.svelte"
export { default as icon } from "./Icon.svelte"
export { default as search } from "./Search.svelte"
+export { default as backgroundimage } from "./BackgroundImage.svelte"
export * from "./charts"
export * from "./forms"