Merge branch 'develop' of github.com:Budibase/budibase into feature/json-backend
This commit is contained in:
commit
5e0a6d6c91
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/auth",
|
"name": "@budibase/auth",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Authentication middlewares for budibase builder and apps",
|
"description": "Authentication middlewares for budibase builder and apps",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.190-alpha.8",
|
"@budibase/bbui": "^0.9.190-alpha.12",
|
||||||
"@budibase/client": "^0.9.190-alpha.8",
|
"@budibase/client": "^0.9.190-alpha.12",
|
||||||
"@budibase/colorpicker": "1.1.2",
|
"@budibase/colorpicker": "1.1.2",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.8",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
|
|
|
@ -524,7 +524,7 @@ export const getFrontendStore = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
paste: async (targetComponent, mode) => {
|
paste: async (targetComponent, mode, preserveBindings = false) => {
|
||||||
let promises = []
|
let promises = []
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
// Stop if we have nothing to paste
|
// Stop if we have nothing to paste
|
||||||
|
@ -536,7 +536,7 @@ export const getFrontendStore = () => {
|
||||||
const cut = state.componentToPaste.isCut
|
const cut = state.componentToPaste.isCut
|
||||||
|
|
||||||
// immediately need to remove bindings, currently these aren't valid when pasted
|
// immediately need to remove bindings, currently these aren't valid when pasted
|
||||||
if (!cut) {
|
if (!cut && !preserveBindings) {
|
||||||
state.componentToPaste = removeBindings(state.componentToPaste)
|
state.componentToPaste = removeBindings(state.componentToPaste)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
const duplicateComponent = () => {
|
const duplicateComponent = () => {
|
||||||
storeComponentForCopy(false)
|
storeComponentForCopy(false)
|
||||||
pasteComponent("below")
|
pasteComponent("below", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteComponent = async () => {
|
const deleteComponent = async () => {
|
||||||
|
@ -69,9 +69,9 @@
|
||||||
store.actions.components.copy(component, cut)
|
store.actions.components.copy(component, cut)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pasteComponent = mode => {
|
const pasteComponent = (mode, preserveBindings = false) => {
|
||||||
// lives in store - also used by drag drop
|
// lives in store - also used by drag drop
|
||||||
store.actions.components.paste(component, mode)
|
store.actions.components.paste(component, mode, preserveBindings)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
key: "layout",
|
key: "layout",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
let newLayoutModal
|
||||||
let modal
|
|
||||||
$: selected = tabs.find(t => t.key === $params.assetType)?.title || "Screens"
|
$: selected = tabs.find(t => t.key === $params.assetType)?.title || "Screens"
|
||||||
|
|
||||||
const navigate = ({ detail }) => {
|
const navigate = ({ detail }) => {
|
||||||
|
@ -93,14 +92,18 @@
|
||||||
{#each $store.layouts as layout, idx (layout._id)}
|
{#each $store.layouts as layout, idx (layout._id)}
|
||||||
<Layout {layout} border={idx > 0} />
|
<Layout {layout} border={idx > 0} />
|
||||||
{/each}
|
{/each}
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={newLayoutModal}>
|
||||||
<NewLayoutModal />
|
<NewLayoutModal />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div class="add-button">
|
<div class="add-button">
|
||||||
<Icon hoverable name="AddCircle" on:click={showModal()} />
|
<Icon
|
||||||
|
hoverable
|
||||||
|
name="AddCircle"
|
||||||
|
on:click={selected === "Layouts" ? newLayoutModal.show() : showModal()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,39 @@
|
||||||
ProgressCircle,
|
ProgressCircle,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import getTemplates from "builderStore/store/screenTemplates"
|
import getTemplates from "builderStore/store/screenTemplates"
|
||||||
|
import { onDestroy } from "svelte"
|
||||||
|
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
|
||||||
export let selectedScreens = []
|
|
||||||
export let chooseModal
|
export let chooseModal
|
||||||
export let save
|
export let save
|
||||||
export let showProgressCircle = false
|
export let showProgressCircle = false
|
||||||
|
|
||||||
|
let selectedScreens = []
|
||||||
|
|
||||||
const blankScreen = "createFromScratch"
|
const blankScreen = "createFromScratch"
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
function setScreens() {
|
||||||
|
dispatch("save", {
|
||||||
|
screens: selectedScreens,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
$: blankSelected = selectedScreens?.length === 1
|
$: blankSelected = selectedScreens?.length === 1
|
||||||
$: autoSelected = selectedScreens?.length > 0 && !blankSelected
|
$: autoSelected = selectedScreens?.length > 0 && !blankSelected
|
||||||
|
|
||||||
let templates = getTemplates($store, $tables.list)
|
let templates = getTemplates($store, $tables.list)
|
||||||
|
|
||||||
|
const confirm = async () => {
|
||||||
|
if (autoSelected) {
|
||||||
|
setScreens()
|
||||||
|
await save()
|
||||||
|
} else {
|
||||||
|
setScreens()
|
||||||
|
chooseModal(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
const toggleScreenSelection = table => {
|
const toggleScreenSelection = table => {
|
||||||
if (selectedScreens.find(s => s.table === table.name)) {
|
if (selectedScreens.find(s => s.table === table.name)) {
|
||||||
selectedScreens = selectedScreens.filter(
|
selectedScreens = selectedScreens.filter(
|
||||||
|
@ -32,14 +55,18 @@
|
||||||
selectedScreens = [...partialTemplates, ...selectedScreens]
|
selectedScreens = [...partialTemplates, ...selectedScreens]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
selectedScreens = []
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style="overflow-y: auto; max-height: 1000px">
|
<div>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
title="Add screens"
|
title="Add screens"
|
||||||
confirmText="Add Screens"
|
confirmText="Add Screens"
|
||||||
cancelText="Cancel"
|
cancelText="Cancel"
|
||||||
onConfirm={() => (autoSelected ? save() : chooseModal(1))}
|
onConfirm={() => confirm()}
|
||||||
disabled={!selectedScreens.length}
|
disabled={!selectedScreens.length}
|
||||||
size="L"
|
size="L"
|
||||||
>
|
>
|
||||||
|
@ -70,29 +97,31 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Detail size="S">Autogenerated Screens</Detail>
|
{#if $tables.list.filter(table => table._id !== "ta_users").length > 0}
|
||||||
|
<Detail size="S">Autogenerated Screens</Detail>
|
||||||
|
|
||||||
{#each $tables.list.filter(table => table._id !== "ta_users") as table}
|
{#each $tables.list.filter(table => table._id !== "ta_users") as table}
|
||||||
<div
|
|
||||||
class:disabled={blankSelected}
|
|
||||||
class:selected={selectedScreens.find(x => x.table === table.name)}
|
|
||||||
on:click={() => toggleScreenSelection(table)}
|
|
||||||
class="item"
|
|
||||||
>
|
|
||||||
<div class="content">
|
|
||||||
<div class="text">{table.name}</div>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
style="color: var(--spectrum-global-color-green-600); float: right"
|
class:disabled={blankSelected}
|
||||||
|
class:selected={selectedScreens.find(x => x.table === table.name)}
|
||||||
|
on:click={() => toggleScreenSelection(table)}
|
||||||
|
class="item"
|
||||||
>
|
>
|
||||||
{#if selectedScreens.find(x => x.table === table.name)}
|
<div class="content">
|
||||||
<div class="checkmark-spacing">
|
<div class="text">{table.name}</div>
|
||||||
<Icon size="S" name="CheckmarkCircleOutline" />
|
</div>
|
||||||
</div>
|
<div
|
||||||
{/if}
|
style="color: var(--spectrum-global-color-green-600); float: right"
|
||||||
|
>
|
||||||
|
{#if selectedScreens.find(x => x.table === table.name)}
|
||||||
|
<div class="checkmark-spacing">
|
||||||
|
<Icon size="S" name="CheckmarkCircleOutline" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/each}
|
||||||
{/each}
|
{/if}
|
||||||
</Layout>
|
</Layout>
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
{#if showProgressCircle}
|
{#if showProgressCircle}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { ModalContent, Input, ProgressCircle } from "@budibase/bbui"
|
import { ModalContent, Input, ProgressCircle } from "@budibase/bbui"
|
||||||
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
||||||
import { selectedAccessRole, allScreens } from "builderStore"
|
import { selectedAccessRole, allScreens } from "builderStore"
|
||||||
|
import { onDestroy } from "svelte"
|
||||||
|
|
||||||
export let screenName
|
export let screenName
|
||||||
export let url
|
export let url
|
||||||
|
@ -32,6 +33,11 @@
|
||||||
screen.routing.roleId === roleId
|
screen.routing.roleId === roleId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
screenName = ""
|
||||||
|
url = ""
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
||||||
import { Modal } from "@budibase/bbui"
|
import { Modal } from "@budibase/bbui"
|
||||||
import { store, selectedAccessRole, allScreens } from "builderStore"
|
import { store, selectedAccessRole, allScreens } from "builderStore"
|
||||||
import { onDestroy } from "svelte"
|
|
||||||
import analytics, { Events } from "analytics"
|
import analytics, { Events } from "analytics"
|
||||||
|
|
||||||
let newScreenModal
|
let newScreenModal
|
||||||
|
@ -34,7 +33,6 @@
|
||||||
for (let screen of createdScreens) {
|
for (let screen of createdScreens) {
|
||||||
await saveScreens(screen)
|
await saveScreens(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
await store.actions.routing.fetch()
|
await store.actions.routing.fetch()
|
||||||
selectedScreens = []
|
selectedScreens = []
|
||||||
createdScreens = []
|
createdScreens = []
|
||||||
|
@ -42,6 +40,7 @@
|
||||||
url = ""
|
url = ""
|
||||||
showProgressCircle = false
|
showProgressCircle = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveScreens = async draftScreen => {
|
const saveScreens = async draftScreen => {
|
||||||
let existingScreenCount = $store.screens.filter(
|
let existingScreenCount = $store.screens.filter(
|
||||||
s => s.props._instanceName == draftScreen.props._instanceName
|
s => s.props._instanceName == draftScreen.props._instanceName
|
||||||
|
@ -90,17 +89,14 @@
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
selectedScreens = []
|
|
||||||
screenName = ""
|
|
||||||
url = ""
|
|
||||||
createdScreens = []
|
|
||||||
})
|
|
||||||
|
|
||||||
export const showModal = () => {
|
export const showModal = () => {
|
||||||
newScreenModal.show()
|
newScreenModal.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setScreens = evt => {
|
||||||
|
selectedScreens = evt.detail.screens
|
||||||
|
}
|
||||||
|
|
||||||
const chooseModal = index => {
|
const chooseModal = index => {
|
||||||
/*
|
/*
|
||||||
0 = newScreenModal
|
0 = newScreenModal
|
||||||
|
@ -119,7 +115,7 @@
|
||||||
|
|
||||||
<Modal bind:this={newScreenModal}>
|
<Modal bind:this={newScreenModal}>
|
||||||
<NewScreenModal
|
<NewScreenModal
|
||||||
bind:selectedScreens
|
on:save={setScreens}
|
||||||
{showProgressCircle}
|
{showProgressCircle}
|
||||||
{save}
|
{save}
|
||||||
{chooseModal}
|
{chooseModal}
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
import { Button, ActionButton, Drawer } from "@budibase/bbui"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import NavigationDrawer from "./NavigationDrawer.svelte"
|
import NavigationDrawer from "./NavigationDrawer.svelte"
|
||||||
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
export let value = []
|
export let value = []
|
||||||
let drawer
|
let drawer
|
||||||
|
let links = cloneDeep(value)
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const save = () => {
|
const save = () => {
|
||||||
dispatch("change", value)
|
dispatch("change", links)
|
||||||
drawer.hide()
|
drawer.hide()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -19,5 +21,5 @@
|
||||||
Configure the links in your navigation bar.
|
Configure the links in your navigation bar.
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||||
<NavigationDrawer slot="body" bind:links={value} />
|
<NavigationDrawer slot="body" bind:links />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.190-alpha.8",
|
"@budibase/bbui": "^0.9.190-alpha.12",
|
||||||
"@budibase/standard-components": "^0.9.139",
|
"@budibase/standard-components": "^0.9.139",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.8",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"regexparam": "^1.3.0",
|
"regexparam": "^1.3.0",
|
||||||
"shortid": "^2.2.15",
|
"shortid": "^2.2.15",
|
||||||
"svelte-spa-router": "^3.0.5"
|
"svelte-spa-router": "^3.0.5"
|
||||||
|
|
|
@ -313,6 +313,9 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.desktop.layout--left .links {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.desktop .nav--left {
|
.desktop .nav--left {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
|
@ -379,6 +382,7 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.mobile .link {
|
.mobile .link {
|
||||||
width: calc(100% - 30px);
|
width: calc(100% - 30px);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -69,9 +69,9 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.190-alpha.8",
|
"@budibase/auth": "^0.9.190-alpha.12",
|
||||||
"@budibase/client": "^0.9.190-alpha.8",
|
"@budibase/client": "^0.9.190-alpha.12",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.8",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@bull-board/api": "^3.7.0",
|
"@bull-board/api": "^3.7.0",
|
||||||
"@bull-board/koa": "^3.7.0",
|
"@bull-board/koa": "^3.7.0",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
version: "3.8"
|
version: "3.8"
|
||||||
services:
|
services:
|
||||||
db:
|
db:
|
||||||
container_name: oracle-xe
|
restart: always
|
||||||
platform: linux/x86_64
|
platform: linux/x86_64
|
||||||
image: container-registry.oracle.com/database/express:18.4.0-xe
|
image: container-registry.oracle.com/database/express:18.4.0-xe
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
FilterTypes,
|
||||||
IncludeRelationships,
|
IncludeRelationships,
|
||||||
Operation,
|
Operation,
|
||||||
PaginationJson,
|
PaginationJson,
|
||||||
|
@ -118,8 +119,13 @@ module External {
|
||||||
}
|
}
|
||||||
// check the row and filters to make sure they aren't a key of some sort
|
// check the row and filters to make sure they aren't a key of some sort
|
||||||
if (config.filters) {
|
if (config.filters) {
|
||||||
for (let filter of Object.values(config.filters)) {
|
for (let [key, filter] of Object.entries(config.filters)) {
|
||||||
if (typeof filter !== "object" || Object.keys(filter).length === 0) {
|
// oneOf is an array, don't iterate it
|
||||||
|
if (
|
||||||
|
typeof filter !== "object" ||
|
||||||
|
Object.keys(filter).length === 0 ||
|
||||||
|
key === FilterTypes.ONE_OF
|
||||||
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
iterateObject(filter)
|
iterateObject(filter)
|
||||||
|
|
|
@ -54,6 +54,17 @@ export enum IncludeRelationships {
|
||||||
EXCLUDE = 0,
|
EXCLUDE = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum FilterTypes {
|
||||||
|
STRING = "string",
|
||||||
|
FUZZY = "fuzzy",
|
||||||
|
RANGE = "range",
|
||||||
|
EQUAL = "equal",
|
||||||
|
NOT_EQUAL = "notEqual",
|
||||||
|
EMPTY = "empty",
|
||||||
|
NOT_EMPTY = "notEmpty",
|
||||||
|
ONE_OF = "oneOf",
|
||||||
|
}
|
||||||
|
|
||||||
export interface QueryDefinition {
|
export interface QueryDefinition {
|
||||||
type: QueryTypes
|
type: QueryTypes
|
||||||
displayName?: string
|
displayName?: string
|
||||||
|
|
|
@ -93,7 +93,7 @@ class InternalBuilder {
|
||||||
if (filters.oneOf) {
|
if (filters.oneOf) {
|
||||||
iterate(filters.oneOf, (key, array) => {
|
iterate(filters.oneOf, (key, array) => {
|
||||||
const fnc = allOr ? "orWhereIn" : "whereIn"
|
const fnc = allOr ? "orWhereIn" : "whereIn"
|
||||||
query = query[fnc](key, array)
|
query = query[fnc](key, Array.isArray(array) ? array : [array])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (filters.string) {
|
if (filters.string) {
|
||||||
|
@ -435,8 +435,6 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
|
||||||
id = results?.[0].id
|
id = results?.[0].id
|
||||||
} else if (sqlClient === SqlClients.MY_SQL) {
|
} else if (sqlClient === SqlClients.MY_SQL) {
|
||||||
id = results?.insertId
|
id = results?.insertId
|
||||||
} else if (sqlClient === SqlClients.ORACLE) {
|
|
||||||
id = response.outBinds[0][0]
|
|
||||||
}
|
}
|
||||||
row = processFn(
|
row = processFn(
|
||||||
await this.getReturningRow(queryFn, this.checkLookupKeys(id, json))
|
await this.getReturningRow(queryFn, this.checkLookupKeys(id, json))
|
||||||
|
|
|
@ -348,27 +348,7 @@ module OracleModule {
|
||||||
this.schemaErrors = final.errors
|
this.schemaErrors = final.errors
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private async internalQuery<T>(query: SqlQuery): Promise<Result<T>> {
|
||||||
* Knex default returning behaviour does not work with oracle
|
|
||||||
* Manually add the behaviour for the return column
|
|
||||||
*/
|
|
||||||
private addReturning(
|
|
||||||
query: SqlQuery,
|
|
||||||
bindings: BindParameters,
|
|
||||||
returnColumn: string
|
|
||||||
) {
|
|
||||||
if (bindings instanceof Array) {
|
|
||||||
bindings.push({ dir: oracledb.BIND_OUT })
|
|
||||||
query.sql =
|
|
||||||
query.sql + ` returning \"${returnColumn}\" into :${bindings.length}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async internalQuery<T>(
|
|
||||||
query: SqlQuery,
|
|
||||||
returnColum?: string,
|
|
||||||
operation?: string
|
|
||||||
): Promise<Result<T>> {
|
|
||||||
let connection
|
let connection
|
||||||
try {
|
try {
|
||||||
connection = await this.getConnection()
|
connection = await this.getConnection()
|
||||||
|
@ -376,13 +356,6 @@ module OracleModule {
|
||||||
const options: ExecuteOptions = { autoCommit: true }
|
const options: ExecuteOptions = { autoCommit: true }
|
||||||
const bindings: BindParameters = query.bindings || []
|
const bindings: BindParameters = query.bindings || []
|
||||||
|
|
||||||
if (
|
|
||||||
returnColum &&
|
|
||||||
(operation === Operation.CREATE || operation === Operation.UPDATE)
|
|
||||||
) {
|
|
||||||
this.addReturning(query, bindings, returnColum)
|
|
||||||
}
|
|
||||||
|
|
||||||
const result: Result<T> = await connection.execute<T>(
|
const result: Result<T> = await connection.execute<T>(
|
||||||
query.sql,
|
query.sql,
|
||||||
bindings,
|
bindings,
|
||||||
|
@ -441,13 +414,46 @@ module OracleModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(json: QueryJson) {
|
async query(json: QueryJson) {
|
||||||
const primaryKeys = json.meta!.table!.primary
|
const operation = this._operation(json)
|
||||||
const primaryKey = primaryKeys ? primaryKeys[0] : undefined
|
const input = this._query(json, { disableReturning: true })
|
||||||
const queryFn = (query: any, operation: string) =>
|
if (Array.isArray(input)) {
|
||||||
this.internalQuery(query, primaryKey, operation)
|
const responses = []
|
||||||
const processFn = (response: any) => (response.rows ? response.rows : [])
|
for (let query of input) {
|
||||||
const output = await this.queryWithReturning(json, queryFn, processFn)
|
responses.push(await this.internalQuery(query))
|
||||||
return output
|
}
|
||||||
|
return responses
|
||||||
|
} else {
|
||||||
|
// read the row to be deleted up front for the return
|
||||||
|
let deletedRows
|
||||||
|
if (operation === Operation.DELETE) {
|
||||||
|
const queryFn = (query: any) => this.internalQuery(query)
|
||||||
|
deletedRows = await this.getReturningRow(queryFn, json)
|
||||||
|
}
|
||||||
|
|
||||||
|
// run the query
|
||||||
|
const response = await this.internalQuery(input)
|
||||||
|
|
||||||
|
// get the results or return the created / updated / deleted row
|
||||||
|
if (deletedRows?.rows?.length) {
|
||||||
|
return deletedRows.rows
|
||||||
|
} else if (response.rows?.length) {
|
||||||
|
return response.rows
|
||||||
|
} else {
|
||||||
|
// get the last row that was updated
|
||||||
|
if (
|
||||||
|
response.lastRowid &&
|
||||||
|
json.endpoint?.entityId &&
|
||||||
|
operation !== Operation.DELETE
|
||||||
|
) {
|
||||||
|
const lastRow = await this.internalQuery({
|
||||||
|
sql: `SELECT * FROM \"${json.endpoint.entityId}\" WHERE ROWID = '${response.lastRowid}'`,
|
||||||
|
})
|
||||||
|
return lastRow.rows
|
||||||
|
} else {
|
||||||
|
return [{ [ operation.toLowerCase() ]: true }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.190-alpha.8",
|
"version": "0.9.190-alpha.12",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -29,8 +29,8 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.190-alpha.8",
|
"@budibase/auth": "^0.9.190-alpha.12",
|
||||||
"@budibase/string-templates": "^0.9.190-alpha.8",
|
"@budibase/string-templates": "^0.9.190-alpha.12",
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"@sentry/node": "^6.0.0",
|
"@sentry/node": "^6.0.0",
|
||||||
"@techpass/passport-openidconnect": "^0.3.0",
|
"@techpass/passport-openidconnect": "^0.3.0",
|
||||||
|
|
Loading…
Reference in New Issue