merge master
This commit is contained in:
commit
f8f15b7b4b
|
@ -34,3 +34,14 @@ jobs:
|
||||||
CI: true
|
CI: true
|
||||||
name: Budibase CI
|
name: Budibase CI
|
||||||
- run: yarn test:e2e:ci
|
- run: yarn test:e2e:ci
|
||||||
|
|
||||||
|
- name: Build and Push Staging Docker Image
|
||||||
|
# Only run on push
|
||||||
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||||
|
run: |
|
||||||
|
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
|
||||||
|
yarn build:docker:staging
|
||||||
|
env:
|
||||||
|
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
tag=$1
|
||||||
|
tag=${tag:-latest}
|
||||||
|
|
||||||
pushd ../../build
|
pushd ../../build
|
||||||
docker-compose build --force app-service
|
docker-compose build --force app-service
|
||||||
docker-compose build --force worker-service
|
docker-compose build --force worker-service
|
||||||
docker tag build_app-service budibase/budibase-apps:latest
|
|
||||||
|
docker tag build_app-service budibase/budibase-apps:$tag
|
||||||
|
docker tag build_worker-service budibase/budibase-worker:$tag
|
||||||
|
|
||||||
docker push budibase/budibase-apps
|
docker push budibase/budibase-apps
|
||||||
docker tag build_worker-service budibase/budibase-worker:latest
|
|
||||||
docker push budibase/budibase-worker
|
docker push budibase/budibase-worker
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
"format": "prettier --write \"{,!(node_modules)/**/}*.{js,jsx,svelte}\"",
|
"format": "prettier --write \"{,!(node_modules)/**/}*.{js,jsx,svelte}\"",
|
||||||
"test:e2e": "lerna run cy:test",
|
"test:e2e": "lerna run cy:test",
|
||||||
"test:e2e:ci": "lerna run cy:ci",
|
"test:e2e:ci": "lerna run cy:ci",
|
||||||
"build:docker": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -"
|
"build:docker": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -",
|
||||||
|
"build:docker:staging": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh staging && cd -"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -63,10 +63,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.55.1",
|
"@budibase/bbui": "^1.55.2",
|
||||||
"@budibase/client": "^0.5.3",
|
"@budibase/client": "^0.6.2",
|
||||||
"@budibase/colorpicker": "^1.0.1",
|
"@budibase/colorpicker": "^1.0.1",
|
||||||
"@budibase/string-templates": "^0.5.3",
|
"@budibase/string-templates": "^0.6.2",
|
||||||
"@budibase/svelte-ag-grid": "^0.0.16",
|
"@budibase/svelte-ag-grid": "^0.0.16",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@svelteschool/svelte-forms": "^0.7.0",
|
"@svelteschool/svelte-forms": "^0.7.0",
|
||||||
|
|
|
@ -106,6 +106,16 @@ function highlightFeedbackIcon() {
|
||||||
return isFeedbackTimeElapsed(firstRunStr)
|
return isFeedbackTimeElapsed(firstRunStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Opt In/Out
|
||||||
|
const ifAnalyticsEnabled = func => () => {
|
||||||
|
if (analyticsEnabled && process.env.POSTHOG_TOKEN) {
|
||||||
|
return func()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const disabled = () => posthog.has_opted_out_capturing()
|
||||||
|
const optIn = () => posthog.opt_in_capturing()
|
||||||
|
const optOut = () => posthog.opt_out_capturing()
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
activate,
|
activate,
|
||||||
identify,
|
identify,
|
||||||
|
@ -115,4 +125,7 @@ export default {
|
||||||
requestFeedbackOnDeploy,
|
requestFeedbackOnDeploy,
|
||||||
submitFeedback,
|
submitFeedback,
|
||||||
highlightFeedbackIcon,
|
highlightFeedbackIcon,
|
||||||
|
disabled: ifAnalyticsEnabled(disabled),
|
||||||
|
optIn: ifAnalyticsEnabled(optIn),
|
||||||
|
optOut: ifAnalyticsEnabled(optOut),
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<Input
|
<Input
|
||||||
value={field.name}
|
value={field.name}
|
||||||
secondary
|
secondary
|
||||||
|
placeholder="Enter field name"
|
||||||
on:change={fieldNameChanged(field.name)} />
|
on:change={fieldNameChanged(field.name)} />
|
||||||
<Select
|
<Select
|
||||||
secondary
|
secondary
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script>
|
||||||
|
export let width = "100"
|
||||||
|
export let height = "100"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
{width}
|
||||||
|
{height}
|
||||||
|
viewBox="0 0 2900 2000">
|
||||||
|
<g id="layer101">
|
||||||
|
<path
|
||||||
|
fill="#5b350f"
|
||||||
|
d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z" />
|
||||||
|
</g>
|
||||||
|
<g id="layer102">
|
||||||
|
<path
|
||||||
|
fill="#406f23"
|
||||||
|
d="M735 1983 c-137 -19 -322 -95 -431 -175 -138 -103 -250 -315 -284 -542 -24 -161 22 -298 129 -382 123 -97 318 -180 577 -243 l130 -32 29 -67 c41 -94 135 -231 199 -289 292 -267 732 -319 1094 -128 148 79 224 151 418 400 137 176 173 242 228 414 41 130 70 301 70 416 0 236 -146 421 -382 484 -206 56 -392 19 -733 -144 -96 -47 -181 -85 -189 -85 -7 0 -61 46 -119 103 -163 159 -283 231 -433 261 -71 15 -229 19 -303 9z m460 -643 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -51 -100 -126 -173 -238 -230 l-89 -45 -131 0 c-151 0 -222 18 -323 84 -138 89 -243 264 -243 406 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z" />
|
||||||
|
</g>
|
||||||
|
<g id="layer103">
|
||||||
|
<path
|
||||||
|
fill="#c6d821"
|
||||||
|
d="M2215 1789 c-27 -4 -68 -15 -90 -23 -42 -15 -264 -116 -397 -180 l-77 -38 78 -102 c102 -134 144 -208 175 -305 37 -116 49 -200 44 -309 -7 -157 -46 -218 -175 -278 -94 -44 -178 -56 -313 -43 -108 10 -401 53 -479 70 -24 5 -45 8 -47 6 -2 -2 20 -44 49 -92 67 -115 176 -225 281 -284 87 -49 235 -103 335 -121 91 -16 253 -14 346 5 175 37 269 95 419 264 307 347 422 563 457 859 18 148 9 247 -29 325 -88 179 -340 286 -577 246z" />
|
||||||
|
<path
|
||||||
|
fill="#c6d821"
|
||||||
|
d="M549 1680 c-272 -34 -426 -142 -495 -346 -22 -68 -26 -91 -22 -164 6 -115 32 -173 112 -248 70 -65 236 -153 370 -196 241 -79 722 -172 985 -192 180 -14 343 55 404 170 34 64 30 168 -11 271 -88 223 -245 373 -568 542 -222 116 -379 161 -584 168 -69 2 -155 0 -191 -5z m646 -340 c163 -51 296 -150 329 -246 23 -69 20 -93 -20 -174 -50 -100 -126 -173 -235 -229 -84 -42 -90 -44 -200 -48 -190 -8 -312 37 -434 161 -98 99 -155 221 -155 331 0 62 12 76 120 134 160 85 229 102 405 96 87 -2 139 -9 190 -25z" />
|
||||||
|
</g>
|
||||||
|
<g id="layer104">
|
||||||
|
<path
|
||||||
|
fill="#f6f654"
|
||||||
|
d="M2190 1721 c-57 -19 -469 -184 -494 -198 -12 -7 -5 -21 34 -72 28 -35 71 -96 97 -137 l46 -74 69 0 c38 0 83 -6 102 -14 52 -22 105 -75 139 -140 28 -55 32 -70 32 -147 0 -84 -2 -90 -48 -183 -96 -187 -234 -296 -376 -296 -44 0 -80 7 -110 20 -28 13 -65 20 -105 20 -72 0 -264 22 -426 49 -63 10 -117 17 -118 15 -10 -8 59 -113 110 -169 106 -115 238 -183 448 -231 155 -35 313 -29 447 17 78 27 210 117 279 191 82 89 277 353 336 456 92 159 137 344 125 513 -9 117 -37 189 -101 258 -109 116 -332 172 -486 122z" />
|
||||||
|
<path
|
||||||
|
fill="#f6f654"
|
||||||
|
d="M490 1624 c-153 -33 -275 -125 -339 -257 -54 -109 -59 -201 -17 -301 32 -76 164 -189 288 -245 51 -23 260 -91 281 -91 3 0 -21 25 -54 56 -94 91 -150 193 -170 313 -14 90 1 111 123 172 161 81 195 91 343 96 111 5 143 2 215 -16 221 -55 380 -192 380 -327 0 -52 -46 -143 -106 -212 -75 -85 -233 -170 -323 -173 -25 -1 -25 -1 4 -10 140 -43 411 -62 527 -38 142 30 238 125 238 234 0 88 -58 230 -139 337 -105 139 -431 343 -676 423 -161 52 -429 71 -575 39z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<script>
|
||||||
|
export let width = "100"
|
||||||
|
export let height = "100"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
{width}
|
||||||
|
{height}
|
||||||
|
viewBox="0 0 147 147"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M128.244 27.5625H83.3444L74.1569
|
||||||
|
45.9375H22.9688V124.031H137.812V27.5625H128.244ZM128.625
|
||||||
|
45.9375H92.7478L97.5621 36.75H128.625V45.9375Z"
|
||||||
|
fill="#2A4B59" />
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M73.5827 67.597C72.6671 67.5874 71.7543 67.6986 70.8678
|
||||||
|
67.9278V68.061H70.9964C71.6302 69.0199 72.3383 69.9277 73.1141
|
||||||
|
70.7759C73.647 71.837 74.111 72.889 74.6393 73.9502L74.7679 73.8169C75.2581
|
||||||
|
73.4258 75.6415 72.917 75.8825 72.3379C76.1234 71.7589 76.2141 71.1283
|
||||||
|
76.146 70.5048C75.8564 70.0602 75.5911 69.6001 75.3513 69.1267C74.9562
|
||||||
|
68.4652 74.0926 68.1345 73.5597 67.6062"
|
||||||
|
fill="white" />
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M139.319 125.345C134.95 125.032 130.564 125.658 126.457 127.183C125.464
|
||||||
|
127.578 123.875 127.578 123.742 128.836C124.275 129.365 124.339 130.214
|
||||||
|
124.808 130.959C125.714 132.492 126.878 133.858 128.248 134.997C129.626
|
||||||
|
136.058 131.028 137.11 132.488 138.038C135.07 139.632 138.001 140.555
|
||||||
|
140.495 142.144C141.956 143.063 143.408 144.262 144.873 145.259C145.599
|
||||||
|
145.787 146.058 146.637 146.986 146.977V146.775C146.712 146.039 146.374
|
||||||
|
145.329 145.976 144.653C145.314 143.996 144.653 143.394 143.986
|
||||||
|
142.737C142.043 140.171 139.72 137.917 137.096 136.053C134.974 134.592
|
||||||
|
130.338 132.608 129.479 130.164L129.346 130.031C130.906 129.811 132.443
|
||||||
|
129.454 133.94 128.965C136.186 128.372 138.24 128.506 140.56 127.913C141.621
|
||||||
|
127.647 143.541 126.994 143.541 126.994V125.961C142.356 124.785 141.51
|
||||||
|
123.204 140.266 122.097C136.876 119.139 133.264 116.447 129.461
|
||||||
|
114.045C127.426 112.735 124.808 111.885 122.649 110.769C121.868 110.374
|
||||||
|
120.558 110.181 120.099 109.524C119.022 107.943 118.121 106.248 117.412
|
||||||
|
104.471C115.475 100.744 113.684 96.944 112.042 93.0786C111.076 90.527
|
||||||
|
109.961 88.0344 108.702 85.6138C102.629 75.3049 93.8692 66.8402 83.3582
|
||||||
|
61.1245C80.7056 59.8389 77.8847 58.9342 74.9792 58.4372C73.3392 58.3683
|
||||||
|
71.7038 58.2396 70.0685 58.1753C69.0107 57.4823 68.0036 56.7147 67.055
|
||||||
|
55.8784C63.3202 53.5218 53.7009 48.4136 50.9493 55.1572C49.1807 59.4156
|
||||||
|
53.5677 63.6051 55.0836 65.7688C56.3514 67.2941 57.4683 68.9387 58.4187
|
||||||
|
70.6795C58.8781 71.7912 59.0067 72.9764 59.4707 74.1524C60.4281 77.1443
|
||||||
|
61.5648 80.0758 62.8746 82.931C63.5769 84.3429 64.3863 85.699 65.2956
|
||||||
|
86.9873C65.8238 87.7131 66.738 88.0347 66.9355 89.2199C66.2106 90.78 65.7036
|
||||||
|
92.4324 65.4288 94.1306C64.2846 97.7426 63.8637 101.545 64.19 105.32C64.5163
|
||||||
|
109.094 65.5835 112.768 67.3306 116.13C68.378 117.765 70.8678 121.372
|
||||||
|
74.2212 119.993C77.1658 118.817 76.5181 115.083 77.3633 111.812C77.5609
|
||||||
|
111.022 77.4276 110.503 77.8227 109.974V110.618C77.8227 110.618 79.4948
|
||||||
|
114.293 80.3217 116.171C82.5698 119.591 85.3631 122.618 88.5905
|
||||||
|
125.134C89.8767 126.245 90.9145 127.614 91.6361
|
||||||
|
129.153V130.339H93.1153C93.0837 129.805 92.9362 129.285 92.6832
|
||||||
|
128.815C92.4301 128.344 92.0775 127.935 91.6499 127.614C90.4391 126.367
|
||||||
|
89.33 125.024 88.3332 123.6C85.6231 119.742 83.234 115.669 81.1899
|
||||||
|
111.421C80.1655 109.34 79.2743 107.071 78.4337 104.99C78.0524 104.191
|
||||||
|
78.0524 102.983 77.4139 102.583C76.2312 103.981 75.2053 105.505 74.3544
|
||||||
|
107.126C73.3203 110.403 72.7195 113.8 72.5675 117.233C72.3148 117.301
|
||||||
|
72.4388 117.233 72.3148 117.366C70.2752 116.833 69.5586 114.61 68.8052
|
||||||
|
112.772C66.8219 107.009 66.6218 100.781 68.231 94.9023C68.6903 93.5242
|
||||||
|
70.5967 89.0821 69.825 87.7453C69.4391 86.4682 68.1666 85.7378 67.4638
|
||||||
|
84.7318C66.5711 83.3765 65.8024 81.9436 65.1669 80.4504C63.6372 76.7065
|
||||||
|
62.8701 72.5538 61.2117 68.8098C60.2956 67.0053 59.2292 65.2811 58.0236
|
||||||
|
63.6557C56.6915 62.031 55.5163 60.2837 54.514 58.4372C54.2707 58.0251
|
||||||
|
54.1215 57.5643 54.077 57.0878C54.0326 56.6113 54.0939 56.1309 54.2568
|
||||||
|
55.6809C54.2928 55.4547 54.4023 55.2467 54.5684 55.0889C54.7344 54.9312
|
||||||
|
54.9478 54.8325 55.1755 54.8081C56.0024 54.0731 58.3636 55.0056 59.1905
|
||||||
|
55.4099C61.4133 56.2841 63.5306 57.4059 65.5023 58.7541C66.421 59.4248
|
||||||
|
68.4974 61.1245 68.4974 61.1245H69.1176C71.2353 61.5839 73.624 61.2531
|
||||||
|
75.6085 61.8503C78.9646 62.967 82.1671 64.5011 85.1406 66.4165C93.9149
|
||||||
|
72.002 101.049 79.8174 105.812 89.0637C106.607 90.5842 106.942 91.9761
|
||||||
|
107.65 93.561C109.028 96.8133 110.764 100.125 112.152 103.3C113.372 106.43
|
||||||
|
114.951 109.408 116.856 112.175C117.848 113.553 121.822 114.293 123.609
|
||||||
|
115.023C125.17 115.557 126.703 116.17 128.202 116.86C130.453 118.239 132.7
|
||||||
|
119.842 134.822 121.367C135.879 122.162 139.191 123.815 139.388 125.143"
|
||||||
|
fill="#F3FDFF" />
|
||||||
|
</svg>
|
|
@ -6,6 +6,8 @@ import CouchDB from "./CouchDB.svelte"
|
||||||
import S3 from "./S3.svelte"
|
import S3 from "./S3.svelte"
|
||||||
import Airtable from "./Airtable.svelte"
|
import Airtable from "./Airtable.svelte"
|
||||||
import SqlServer from "./SQLServer.svelte"
|
import SqlServer from "./SQLServer.svelte"
|
||||||
|
import MySQL from "./MySQL.svelte"
|
||||||
|
import ArangoDB from "./ArangoDB.svelte"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
POSTGRES: Postgres,
|
POSTGRES: Postgres,
|
||||||
|
@ -16,4 +18,6 @@ export default {
|
||||||
SQL_SERVER: SqlServer,
|
SQL_SERVER: SqlServer,
|
||||||
S3: S3,
|
S3: S3,
|
||||||
AIRTABLE: Airtable,
|
AIRTABLE: Airtable,
|
||||||
|
MYSQL: MySQL,
|
||||||
|
ARANGODB: ArangoDB,
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,9 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click|stopPropagation bind:this={anchor}>
|
<div on:click|stopPropagation bind:this={anchor}>
|
||||||
<TextButton
|
<TextButton text on:click={dropdown.show} active={false}>
|
||||||
text
|
<Icon name="add" />
|
||||||
on:click={dropdown.show}
|
Add Parameters
|
||||||
active={false}>
|
|
||||||
<Icon name="add" />
|
|
||||||
Add Parameters
|
|
||||||
</TextButton>
|
</TextButton>
|
||||||
<DropdownMenu align="right" {anchor} bind:this={dropdown}>
|
<DropdownMenu align="right" {anchor} bind:this={dropdown}>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
@ -39,4 +36,4 @@
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
min-width: 600px;
|
min-width: 600px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { notificationStore } from "builderStore/store/notifications"
|
import { notificationStore } from "builderStore/store/notifications"
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from "svelte/animate"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
|
|
||||||
export let themes = {
|
export let themes = {
|
||||||
|
|
|
@ -26,10 +26,9 @@
|
||||||
<div class="drawer-contents">
|
<div class="drawer-contents">
|
||||||
<div class="container" data-cy="binding-dropdown-modal">
|
<div class="container" data-cy="binding-dropdown-modal">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<Heading extraSmall>Objects</Heading>
|
|
||||||
<Spacer medium />
|
|
||||||
{#if context}
|
{#if context}
|
||||||
<Heading extraSmall>Tables</Heading>
|
<Heading extraSmall>Columns</Heading>
|
||||||
|
<Spacer small />
|
||||||
<ul>
|
<ul>
|
||||||
{#each context as { readableBinding }}
|
{#each context as { readableBinding }}
|
||||||
<li on:click={() => addToText(readableBinding)}>
|
<li on:click={() => addToText(readableBinding)}>
|
||||||
|
@ -53,8 +52,8 @@
|
||||||
<TextArea
|
<TextArea
|
||||||
thin
|
thin
|
||||||
bind:value
|
bind:value
|
||||||
placeholder="Add text, or click the objects on the left to add them to the
|
placeholder="Add text, or click the objects on the left to add them to
|
||||||
textbox." />
|
the textbox." />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,15 +62,20 @@
|
||||||
.container {
|
.container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: 260px 1fr;
|
||||||
}
|
}
|
||||||
.list {
|
.list {
|
||||||
width: 150px;
|
border-right: var(--border-light);
|
||||||
border-right: 1.5px solid var(--grey-4);
|
padding: var(--spacing-l);
|
||||||
padding: var(--spacing-s);
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-xl);
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
}
|
}
|
||||||
.text :global(p) {
|
.text :global(p) {
|
||||||
|
@ -89,10 +93,12 @@
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
font-size: var(--font-size-xs);
|
font-size: var(--font-size-xs);
|
||||||
color: var(--grey-7);
|
color: var(--grey-7);
|
||||||
padding: var(--spacing-s) 0;
|
padding: var(--spacing-m) 0;
|
||||||
margin: auto 0px;
|
margin: auto 0px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
border: var(--border-light);
|
||||||
|
border-width: 1px 0 1px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
li:hover {
|
li:hover {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
TextButton,
|
|
||||||
Body,
|
Body,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
|
Spacer,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { AddIcon, ArrowDownIcon } from "components/common/Icons/"
|
import { AddIcon, ArrowDownIcon } from "components/common/Icons/"
|
||||||
import actionTypes from "./actions"
|
import actionTypes from "./actions"
|
||||||
|
@ -33,6 +33,9 @@
|
||||||
parameters: {},
|
parameters: {},
|
||||||
[EVENT_TYPE_KEY]: actionType.name,
|
[EVENT_TYPE_KEY]: actionType.name,
|
||||||
}
|
}
|
||||||
|
if (!actions) {
|
||||||
|
actions = []
|
||||||
|
}
|
||||||
actions.push(newAction)
|
actions.push(newAction)
|
||||||
selectedAction = newAction
|
selectedAction = newAction
|
||||||
actions = actions
|
actions = actions
|
||||||
|
@ -48,12 +51,11 @@
|
||||||
<div class="actions-list">
|
<div class="actions-list">
|
||||||
<div>
|
<div>
|
||||||
<div bind:this={addActionButton}>
|
<div bind:this={addActionButton}>
|
||||||
<TextButton text small blue on:click={addActionDropdown.show}>
|
<Spacer small />
|
||||||
<div style="height: 20px; width: 20px;">
|
<Button wide secondary on:click={addActionDropdown.show}>
|
||||||
<AddIcon />
|
|
||||||
</div>
|
|
||||||
Add Action
|
Add Action
|
||||||
</TextButton>
|
</Button>
|
||||||
|
<Spacer medium />
|
||||||
</div>
|
</div>
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
bind:this={addActionDropdown}
|
bind:this={addActionDropdown}
|
||||||
|
@ -80,7 +82,7 @@
|
||||||
</div>
|
</div>
|
||||||
<i
|
<i
|
||||||
class="ri-close-fill"
|
class="ri-close-fill"
|
||||||
style="margin-left: var(--spacing-m);"
|
style="margin-left: auto;"
|
||||||
on:click={() => deleteAction(index)} />
|
on:click={() => deleteAction(index)} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -107,7 +109,7 @@
|
||||||
|
|
||||||
.action-header > span {
|
.action-header > span {
|
||||||
margin-bottom: var(--spacing-m);
|
margin-bottom: var(--spacing-m);
|
||||||
font-size: var(--font-size-s);
|
font-size: var(--font-size-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-header > span:hover,
|
.action-header > span:hover,
|
||||||
|
@ -117,13 +119,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-list {
|
.actions-list {
|
||||||
border: var(--border-light);
|
border-right: var(--border-light);
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.available-action {
|
.available-action {
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-s);
|
||||||
font-size: var(--font-size-m);
|
font-size: var(--font-size-xs);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +137,7 @@
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: var(--spacing-m);
|
grid-gap: var(--spacing-m);
|
||||||
grid-template-columns: 15% 1fr;
|
grid-template-columns: 260px 1fr;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
@ -143,15 +145,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-container {
|
.action-container {
|
||||||
border: var(--border-light);
|
border-top: var(--border-light);
|
||||||
border-width: 1px 0 0 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected-action-container {
|
.selected-action-container {
|
||||||
padding-bottom: var(--spacing-s);
|
padding: var(--spacing-xl);
|
||||||
padding-top: var(--spacing-s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -164,4 +164,9 @@
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--blue);
|
color: var(--blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i:hover {
|
||||||
|
color: var(--red);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -156,7 +156,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.available-action {
|
.available-action {
|
||||||
padding: var(--spacing-s);
|
padding: var(--spacing-m);
|
||||||
font-size: var(--font-size-m);
|
font-size: var(--font-size-m);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,15 +34,17 @@
|
||||||
}))
|
}))
|
||||||
return [...acc, ...viewsArr]
|
return [...acc, ...viewsArr]
|
||||||
}, [])
|
}, [])
|
||||||
$: queries = $backendUiStore.queries.map(query => ({
|
$: queries = $backendUiStore.queries
|
||||||
label: query.name,
|
.filter(query => query.queryVerb === "read")
|
||||||
name: query.name,
|
.map(query => ({
|
||||||
tableId: query._id,
|
label: query.name,
|
||||||
...query,
|
name: query.name,
|
||||||
schema: query.schema,
|
tableId: query._id,
|
||||||
parameters: query.parameters,
|
...query,
|
||||||
type: "query",
|
schema: query.schema,
|
||||||
}))
|
parameters: query.parameters,
|
||||||
|
type: "query",
|
||||||
|
}))
|
||||||
$: bindableProperties = getBindableProperties(
|
$: bindableProperties = getBindableProperties(
|
||||||
$currentAsset.props,
|
$currentAsset.props,
|
||||||
$store.selectedComponentId
|
$store.selectedComponentId
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form on:submit|preventDefault>
|
<form on:submit|preventDefault>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
{#each schemaKeys as field}
|
{#each schemaKeys as field}
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter {field} name"
|
placeholder="Enter {field} name"
|
||||||
outline
|
outline
|
||||||
|
@ -33,8 +33,8 @@
|
||||||
type={schema.fields[field]?.type}
|
type={schema.fields[field]?.type}
|
||||||
required={schema.fields[field]?.required}
|
required={schema.fields[field]?.required}
|
||||||
bind:value={fields[field]} />
|
bind:value={fields[field]} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{#if schema.customisable}
|
{#if schema.customisable}
|
||||||
<Editor
|
<Editor
|
||||||
|
|
|
@ -135,17 +135,22 @@
|
||||||
<Input placeholder="✎ Edit Query Name" bind:value={query.name} />
|
<Input placeholder="✎ Edit Query Name" bind:value={query.name} />
|
||||||
</div>
|
</div>
|
||||||
{#if config}
|
{#if config}
|
||||||
<div class="props">
|
<div class="props">
|
||||||
<div class="query-type">Query type: <span class="query-type-span">{config[query.queryVerb].type}</span></div>
|
<div class="query-type">
|
||||||
<div class="select">
|
Query type:
|
||||||
<Select primary thin bind:value={query.queryVerb}>
|
<span class="query-type-span">{config[query.queryVerb].type}</span>
|
||||||
{#each Object.keys(config) as queryVerb}
|
</div>
|
||||||
<option value={queryVerb}>{queryVerb}</option>
|
<div class="select">
|
||||||
{/each}
|
<Select primary thin bind:value={query.queryVerb}>
|
||||||
</Select>
|
{#each Object.keys(config) as queryVerb}
|
||||||
</div>
|
<option value={queryVerb}>{queryVerb}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<EditQueryParamsPopover bind:parameters={query.parameters} bindable={false} />
|
<EditQueryParamsPopover
|
||||||
|
bind:parameters={query.parameters}
|
||||||
|
bindable={false} />
|
||||||
{/if}
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
<Spacer extraLarge />
|
<Spacer extraLarge />
|
||||||
|
@ -164,7 +169,7 @@
|
||||||
<div class="viewer-controls">
|
<div class="viewer-controls">
|
||||||
<Button
|
<Button
|
||||||
blue
|
blue
|
||||||
disabled={data.length === 0}
|
disabled={data.length === 0 || !query.name}
|
||||||
on:click={saveQuery}>
|
on:click={saveQuery}>
|
||||||
Save Query
|
Save Query
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -182,7 +187,11 @@
|
||||||
{#each fields as field, idx}
|
{#each fields as field, idx}
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<Input outline placeholder="Field Name" type={'text'} bind:value={field.name} />
|
<Input
|
||||||
|
outline
|
||||||
|
placeholder="Field Name"
|
||||||
|
type={'text'}
|
||||||
|
bind:value={field.name} />
|
||||||
<Select thin border bind:value={field.type}>
|
<Select thin border bind:value={field.type}>
|
||||||
<option value={''}>Select a field type</option>
|
<option value={''}>Select a field type</option>
|
||||||
<option value={'STRING'}>Text</option>
|
<option value={'STRING'}>Text</option>
|
||||||
|
@ -195,8 +204,8 @@
|
||||||
on:click={() => deleteField(idx)} />
|
on:click={() => deleteField(idx)} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
<Spacer small />
|
<Spacer small />
|
||||||
<Button thin secondary on:click={newField}>Add Field</Button>
|
<Button thin secondary on:click={newField}>Add Field</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</Switcher>
|
</Switcher>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -206,7 +215,6 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
{#if schema}
|
{#if schema}
|
||||||
{#key query._id}
|
{#key query._id}
|
||||||
{#if schema.type === QueryTypes.SQL}
|
{#if schema.type === QueryTypes.SQL}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { Input, Label } from "@budibase/bbui"
|
import { Input, Label, TextButton } from "@budibase/bbui"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
import { notifier } from "builderStore/store/notifications"
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@
|
||||||
if (key === "budibase") {
|
if (key === "budibase") {
|
||||||
const isValid = await analytics.identifyByApiKey(value)
|
const isValid = await analytics.identifyByApiKey(value)
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
// TODO: add validation message
|
notifier.danger("Your API Key is invalid.")
|
||||||
keys = { ...keys }
|
keys = { ...keys }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,10 @@
|
||||||
thin
|
thin
|
||||||
edit
|
edit
|
||||||
value={keys.budibase}
|
value={keys.budibase}
|
||||||
label="Budibase API Key" />
|
label="Budibase Cloud API Key" />
|
||||||
|
<TextButton text medium blue href="https://portal.budi.live">
|
||||||
|
Log in to the Budibase Hosting Portal to get your API Key. →
|
||||||
|
</TextButton>
|
||||||
<div>
|
<div>
|
||||||
<Label extraSmall grey>Instance ID (Webhooks)</Label>
|
<Label extraSmall grey>Instance ID (Webhooks)</Label>
|
||||||
<span>{$backendUiStore.selectedDatabase._id}</span>
|
<span>{$backendUiStore.selectedDatabase._id}</span>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { notifier } from "builderStore/store/notifications"
|
import { notifier } from "builderStore/store/notifications"
|
||||||
import { hostingStore } from "builderStore"
|
import { hostingStore } from "builderStore"
|
||||||
|
import { HostingTypes } from "constants/backend"
|
||||||
import { Input, ModalContent, Toggle } from "@budibase/bbui"
|
import { Input, ModalContent, Toggle } from "@budibase/bbui"
|
||||||
import ThemeEditor from "components/settings/ThemeEditor.svelte"
|
import ThemeEditor from "components/settings/ThemeEditor.svelte"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
@ -9,8 +10,10 @@
|
||||||
let hostingInfo
|
let hostingInfo
|
||||||
let selfhosted = false
|
let selfhosted = false
|
||||||
|
|
||||||
|
$: analyticsDisabled = analytics.disabled()
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
hostingInfo.type = selfhosted ? "self" : "cloud"
|
hostingInfo.type = selfhosted ? HostingTypes.SELF : HostingTypes.CLOUD
|
||||||
if (!selfhosted && hostingInfo._rev) {
|
if (!selfhosted && hostingInfo._rev) {
|
||||||
hostingInfo = {
|
hostingInfo = {
|
||||||
type: hostingInfo.type,
|
type: hostingInfo.type,
|
||||||
|
@ -27,13 +30,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelfHosting(event) {
|
function updateSelfHosting(event) {
|
||||||
if (hostingInfo.type === "cloud" && event.target.checked) {
|
if (hostingInfo.type === HostingTypes.CLOUD && event.target.checked) {
|
||||||
hostingInfo.hostingUrl = "localhost:10000"
|
hostingInfo.hostingUrl = "localhost:10000"
|
||||||
hostingInfo.useHttps = false
|
hostingInfo.useHttps = false
|
||||||
hostingInfo.selfHostKey = "budibase"
|
hostingInfo.selfHostKey = "budibase"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleAnalytics() {
|
||||||
|
if (analyticsDisabled) {
|
||||||
|
analytics.optIn()
|
||||||
|
} else {
|
||||||
|
analytics.optOut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
hostingInfo = await hostingStore.actions.fetch()
|
hostingInfo = await hostingStore.actions.fetch()
|
||||||
selfhosted = hostingInfo.type === "self"
|
selfhosted = hostingInfo.type === "self"
|
||||||
|
@ -58,6 +69,16 @@
|
||||||
<Input bind:value={hostingInfo.selfHostKey} label="Hosting Key" />
|
<Input bind:value={hostingInfo.selfHostKey} label="Hosting Key" />
|
||||||
<Toggle thin text="HTTPS" bind:checked={hostingInfo.useHttps} />
|
<Toggle thin text="HTTPS" bind:checked={hostingInfo.useHttps} />
|
||||||
{/if}
|
{/if}
|
||||||
|
<h5>Analytics</h5>
|
||||||
|
<p>
|
||||||
|
If you would like to send analytics that help us make budibase better,
|
||||||
|
please let us know below.
|
||||||
|
</p>
|
||||||
|
<Toggle
|
||||||
|
thin
|
||||||
|
text="Send Analytics To Budibase"
|
||||||
|
checked={!analyticsDisabled}
|
||||||
|
on:change={toggleAnalytics} />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -22,36 +22,11 @@
|
||||||
//Move this to context="module" once svelte-forms is updated so that it can bind to stores correctly
|
//Move this to context="module" once svelte-forms is updated so that it can bind to stores correctly
|
||||||
const createAppStore = writable({ currentStep: 0, values: {} })
|
const createAppStore = writable({ currentStep: 0, values: {} })
|
||||||
|
|
||||||
export let hasKey
|
|
||||||
export let template
|
export let template
|
||||||
|
|
||||||
let isApiKeyValid
|
|
||||||
let lastApiKey
|
let lastApiKey
|
||||||
let fetchApiKeyPromise
|
let fetchApiKeyPromise
|
||||||
|
|
||||||
const validateApiKey = async apiKey => {
|
|
||||||
if (isApiKeyValid) return true
|
|
||||||
if (!apiKey) return false
|
|
||||||
|
|
||||||
// make sure we only fetch once, unless API Key is changed
|
|
||||||
if (isApiKeyValid === undefined || apiKey !== lastApiKey) {
|
|
||||||
lastApiKey = apiKey
|
|
||||||
// svelte reactivity was causing a requst to get fired mutiple times
|
|
||||||
// so, we make everything await the same promise, if one exists
|
|
||||||
if (!fetchApiKeyPromise) {
|
|
||||||
fetchApiKeyPromise = analytics.identifyByApiKey(apiKey)
|
|
||||||
}
|
|
||||||
isApiKeyValid = await fetchApiKeyPromise
|
|
||||||
fetchApiKeyPromise = undefined
|
|
||||||
}
|
|
||||||
return isApiKeyValid
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiValidation = {
|
|
||||||
apiKey: string()
|
|
||||||
.required("Please enter your API key.")
|
|
||||||
.test("valid-apikey", "This API key is invalid", validateApiKey),
|
|
||||||
}
|
|
||||||
const infoValidation = {
|
const infoValidation = {
|
||||||
applicationName: string().required("Your application must have a name."),
|
applicationName: string().required("Your application must have a name."),
|
||||||
}
|
}
|
||||||
|
@ -66,7 +41,7 @@
|
||||||
let submitting = false
|
let submitting = false
|
||||||
let errors = {}
|
let errors = {}
|
||||||
let validationErrors = {}
|
let validationErrors = {}
|
||||||
let validationSchemas = [apiValidation, infoValidation, userValidation]
|
let validationSchemas = [infoValidation, userValidation]
|
||||||
|
|
||||||
function buildStep(component) {
|
function buildStep(component) {
|
||||||
return {
|
return {
|
||||||
|
@ -76,7 +51,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// steps need to be initialized for cypress from the get go
|
// steps need to be initialized for cypress from the get go
|
||||||
let steps = [buildStep(API), buildStep(Info), buildStep(User)]
|
let steps = [buildStep(Info), buildStep(User)]
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
let hostingInfo = await hostingStore.actions.fetch()
|
let hostingInfo = await hostingStore.actions.fetch()
|
||||||
|
@ -87,17 +62,11 @@
|
||||||
infoValidation.applicationName = string()
|
infoValidation.applicationName = string()
|
||||||
.required("Your application must have a name.")
|
.required("Your application must have a name.")
|
||||||
.notOneOf(existingAppNames)
|
.notOneOf(existingAppNames)
|
||||||
isApiKeyValid = true
|
|
||||||
steps = [buildStep(Info), buildStep(User)]
|
steps = [buildStep(Info), buildStep(User)]
|
||||||
validationSchemas = [infoValidation, userValidation]
|
validationSchemas = [infoValidation, userValidation]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (hasKey) {
|
|
||||||
validationSchemas.shift()
|
|
||||||
steps.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles form navigation
|
// Handles form navigation
|
||||||
const back = () => {
|
const back = () => {
|
||||||
if ($createAppStore.currentStep > 0) {
|
if ($createAppStore.currentStep > 0) {
|
||||||
|
@ -145,11 +114,6 @@
|
||||||
async function createNewApp() {
|
async function createNewApp() {
|
||||||
submitting = true
|
submitting = true
|
||||||
try {
|
try {
|
||||||
// Add API key if there is none.
|
|
||||||
if (!hasKey) {
|
|
||||||
await updateKey(["budibase", $createAppStore.values.apiKey])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create App
|
// Create App
|
||||||
const appResp = await post("/api/applications", {
|
const appResp = await post("/api/applications", {
|
||||||
name: $createAppStore.values.applicationName,
|
name: $createAppStore.values.applicationName,
|
||||||
|
|
|
@ -87,3 +87,8 @@ export const FILE_TYPES = {
|
||||||
CODE: ["js", "rs", "py", "java", "rb", "hs", "yml"],
|
CODE: ["js", "rs", "py", "java", "rb", "hs", "yml"],
|
||||||
DOCUMENT: ["odf", "docx", "doc", "pdf", "csv"],
|
DOCUMENT: ["odf", "docx", "doc", "pdf", "csv"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const HostingTypes = {
|
||||||
|
CLOUD: "cloud",
|
||||||
|
SELF: "self",
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
<div class="query-list-item" on:click={() => onClickQuery(query)}>
|
<div class="query-list-item" on:click={() => onClickQuery(query)}>
|
||||||
<p class="query-name">{query.name}</p>
|
<p class="query-name">{query.name}</p>
|
||||||
<p>{query.queryVerb}</p>
|
<p>{query.queryVerb}</p>
|
||||||
<p>4000 records</p>
|
|
||||||
<p>→</p>
|
<p>→</p>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -59,7 +58,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -115,7 +113,7 @@
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
border: var(--border-grey);
|
border: var(--border-grey);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 2fr 0.75fr 0.75fr 1fr 20px;
|
grid-template-columns: 2fr 0.75fr 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: var(--spacing-m) var(--layout-xs);
|
padding: var(--spacing-m) var(--layout-xs);
|
||||||
gap: var(--layout-xs);
|
gap: var(--layout-xs);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { Button, Spacer, Modal } from "@budibase/bbui"
|
import { Button, Spacer, Modal } from "@budibase/bbui"
|
||||||
import { store } from "builderStore"
|
import { store, hostingStore } from "builderStore"
|
||||||
import { notifier } from "builderStore/store/notifications"
|
import { notifier } from "builderStore/store/notifications"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
import Spinner from "components/common/Spinner.svelte"
|
import Spinner from "components/common/Spinner.svelte"
|
||||||
|
@ -17,6 +17,18 @@
|
||||||
$: appId = $store.appId
|
$: appId = $store.appId
|
||||||
|
|
||||||
async function deployApp() {
|
async function deployApp() {
|
||||||
|
// Must have cloud or self host API key to deploy
|
||||||
|
if (!$hostingStore.hostingInfo?.selfHostKey) {
|
||||||
|
const response = await api.get(`/api/keys/`)
|
||||||
|
const userKeys = await response.json()
|
||||||
|
if (!userKeys.budibase) {
|
||||||
|
notifier.danger(
|
||||||
|
"No budibase API Keys configured. You must set either a self hosted or cloud API key to deploy your budibase app."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const DEPLOY_URL = `/api/deploy`
|
const DEPLOY_URL = `/api/deploy`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -29,6 +41,7 @@
|
||||||
|
|
||||||
analytics.captureEvent("Deployed App", {
|
analytics.captureEvent("Deployed App", {
|
||||||
appId,
|
appId,
|
||||||
|
hostingType: $hostingStore.hostingInfo?.type,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (analytics.requestFeedbackOnDeploy()) {
|
if (analytics.requestFeedbackOnDeploy()) {
|
||||||
|
@ -37,6 +50,7 @@
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
analytics.captureEvent("Deploy App Failed", {
|
analytics.captureEvent("Deploy App Failed", {
|
||||||
appId,
|
appId,
|
||||||
|
hostingType: $hostingStore.hostingInfo?.type,
|
||||||
})
|
})
|
||||||
analytics.captureException(err)
|
analytics.captureException(err)
|
||||||
notifier.danger("Deployment unsuccessful. Please try again later.")
|
notifier.danger("Deployment unsuccessful. Please try again later.")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { store } from "builderStore"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
import AppList from "components/start/AppList.svelte"
|
import AppList from "components/start/AppList.svelte"
|
||||||
import { get } from "builderStore/api"
|
import { get } from "builderStore/api"
|
||||||
|
@ -35,10 +36,6 @@
|
||||||
hasKey = true
|
hasKey = true
|
||||||
analytics.identify(keys.userId)
|
analytics.identify(keys.userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keys.budibase) {
|
|
||||||
modal.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectTemplate(newTemplate) {
|
function selectTemplate(newTemplate) {
|
||||||
|
|
|
@ -842,10 +842,10 @@
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@budibase/bbui@^1.55.1":
|
"@budibase/bbui@^1.55.2":
|
||||||
version "1.55.1"
|
version "1.55.2"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.55.1.tgz#291fb6fa10479b49f078d3a911ad0ed42c2e6b12"
|
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.55.2.tgz#be636e8b86b7e516a08eb626bb50c4b1f9774bf8"
|
||||||
integrity sha512-bxsHBwkOqCtuFz89e0hAXwvwycfS4xPPrEge5PxK1Lh3uqetO4bXoIxYaIDjfi2Ku7CYIzEmOwSloNaQWeTF4g==
|
integrity sha512-CevH/olxDFIko9uwYUpUTevPmpShrLwJSR7+wn/JetZERwhTwbLhOXzpsyXaK226qQ8vWhm0U31HRSKI1HwDDg==
|
||||||
dependencies:
|
dependencies:
|
||||||
markdown-it "^12.0.2"
|
markdown-it "^12.0.2"
|
||||||
quill "^1.3.7"
|
quill "^1.3.7"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
|
@ -9,14 +9,14 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/string-templates": "^0.5.3",
|
"@budibase/string-templates": "^0.6.2",
|
||||||
"deep-equal": "^2.0.1",
|
"deep-equal": "^2.0.1",
|
||||||
"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"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@budibase/standard-components": "^0.5.3",
|
"@budibase/standard-components": "^0.6.2",
|
||||||
"@rollup/plugin-commonjs": "^16.0.0",
|
"@rollup/plugin-commonjs": "^16.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^10.0.0",
|
"@rollup/plugin-node-resolve": "^10.0.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
|
|
|
@ -2,9 +2,14 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { setContext, onMount } from "svelte"
|
import { setContext, onMount } from "svelte"
|
||||||
import Component from "./Component.svelte"
|
import Component from "./Component.svelte"
|
||||||
import NotificationDisplay from './NotificationDisplay.svelte'
|
import NotificationDisplay from "./NotificationDisplay.svelte"
|
||||||
import SDK from "../sdk"
|
import SDK from "../sdk"
|
||||||
import { createDataStore, initialise, screenStore, notificationStore } from "../store"
|
import {
|
||||||
|
createDataStore,
|
||||||
|
initialise,
|
||||||
|
screenStore,
|
||||||
|
notificationStore,
|
||||||
|
} from "../store"
|
||||||
|
|
||||||
// Provide contexts
|
// Provide contexts
|
||||||
setContext("sdk", SDK)
|
setContext("sdk", SDK)
|
||||||
|
@ -24,4 +29,4 @@
|
||||||
{#if loaded && $screenStore.activeLayout}
|
{#if loaded && $screenStore.activeLayout}
|
||||||
<Component definition={$screenStore.activeLayout.props} />
|
<Component definition={$screenStore.activeLayout.props} />
|
||||||
{/if}
|
{/if}
|
||||||
<NotificationDisplay />
|
<NotificationDisplay />
|
||||||
|
|
|
@ -1,60 +1,59 @@
|
||||||
<script>
|
<script>
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from "svelte/animate"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
const { notifications } = getContext("sdk")
|
const { notifications } = getContext("sdk")
|
||||||
|
|
||||||
export let themes = {
|
export let themes = {
|
||||||
danger: "#E26D69",
|
danger: "#E26D69",
|
||||||
success: "#84C991",
|
success: "#84C991",
|
||||||
warning: "#f0ad4e",
|
warning: "#f0ad4e",
|
||||||
info: "#5bc0de",
|
info: "#5bc0de",
|
||||||
default: "#aaaaaa",
|
default: "#aaaaaa",
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="notifications">
|
<div class="notifications">
|
||||||
{#each $notifications as notification (notification.id)}
|
{#each $notifications as notification (notification.id)}
|
||||||
<div
|
<div
|
||||||
animate:flip
|
animate:flip
|
||||||
class="toast"
|
class="toast"
|
||||||
style="background: {themes[notification.type]};"
|
style="background: {themes[notification.type]};"
|
||||||
transition:fly={{ y: -30 }}>
|
transition:fly={{ y: -30 }}>
|
||||||
<div class="content">{notification.message}</div>
|
<div class="content">{notification.message}</div>
|
||||||
{#if notification.icon}<i class={notification.icon} />{/if}
|
{#if notification.icon}<i class={notification.icon} />{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.notifications {
|
.notifications {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
border-radius: var(--border-radius-s);
|
border-radius: var(--border-radius-s);
|
||||||
/* The toasts now support being auto sized, so this static width could be removed */
|
/* The toasts now support being auto sized, so this static width could be removed */
|
||||||
width: 40vw;
|
width: 40vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: block;
|
display: block;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/electron.js",
|
"main": "src/electron.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -49,13 +49,14 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@budibase/client": "^0.6.2",
|
||||||
|
"@budibase/string-templates": "^0.6.2",
|
||||||
"@elastic/elasticsearch": "^7.10.0",
|
"@elastic/elasticsearch": "^7.10.0",
|
||||||
"@budibase/client": "^0.5.3",
|
|
||||||
"@budibase/string-templates": "^0.5.3",
|
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"@sendgrid/mail": "^7.1.1",
|
"@sendgrid/mail": "^7.1.1",
|
||||||
"@sentry/node": "^5.19.2",
|
"@sentry/node": "^5.19.2",
|
||||||
"airtable": "^0.10.1",
|
"airtable": "^0.10.1",
|
||||||
|
"arangojs": "^7.2.0",
|
||||||
"aws-sdk": "^2.767.0",
|
"aws-sdk": "^2.767.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"chmodr": "^1.2.0",
|
"chmodr": "^1.2.0",
|
||||||
|
@ -82,6 +83,7 @@
|
||||||
"lodash": "^4.17.13",
|
"lodash": "^4.17.13",
|
||||||
"mongodb": "^3.6.3",
|
"mongodb": "^3.6.3",
|
||||||
"mssql": "^6.2.3",
|
"mssql": "^6.2.3",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
"open": "^7.3.0",
|
"open": "^7.3.0",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
|
|
|
@ -77,11 +77,21 @@ exports.getLinkDocuments = async function({
|
||||||
}
|
}
|
||||||
params.include_docs = !!includeDocs
|
params.include_docs = !!includeDocs
|
||||||
try {
|
try {
|
||||||
const response = await db.query(getQueryIndex(ViewNames.LINK), params)
|
let linkRows = (await db.query(getQueryIndex(ViewNames.LINK), params)).rows
|
||||||
|
// filter to get unique entries
|
||||||
|
const foundIds = []
|
||||||
|
linkRows = linkRows.filter(link => {
|
||||||
|
const unique = foundIds.indexOf(link.id) === -1
|
||||||
|
if (unique) {
|
||||||
|
foundIds.push(link.id)
|
||||||
|
}
|
||||||
|
return unique
|
||||||
|
})
|
||||||
|
|
||||||
if (includeDocs) {
|
if (includeDocs) {
|
||||||
return response.rows.map(row => row.doc)
|
return linkRows.map(row => row.doc)
|
||||||
} else {
|
} else {
|
||||||
return response.rows.map(row => row.value)
|
return linkRows.map(row => row.value)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// check if the view doesn't exist, it should for all new instances
|
// check if the view doesn't exist, it should for all new instances
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
const { Database, aql } = require("arangojs")
|
||||||
|
const { FIELD_TYPES, QUERY_TYPES } = require("./Integration")
|
||||||
|
|
||||||
|
const SCHEMA = {
|
||||||
|
docs: "https://github.com/arangodb/arangojs",
|
||||||
|
datasource: {
|
||||||
|
url: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
default: "http://localhost:8529",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
default: "root",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: FIELD_TYPES.PASSWORD,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
databaseName: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
default: "_system",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
collection: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
read: {
|
||||||
|
type: QUERY_TYPES.SQL,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
type: QUERY_TYPES.JSON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArangoDBIntegration {
|
||||||
|
constructor(config) {
|
||||||
|
config.auth = {
|
||||||
|
username: config.username,
|
||||||
|
password: config.password,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config = config
|
||||||
|
this.client = new Database(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
async read(query) {
|
||||||
|
try {
|
||||||
|
const result = await this.client.query(query.sql)
|
||||||
|
return result.all()
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying arangodb", err.message)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(query) {
|
||||||
|
const clc = this.client.collection(this.config.collection)
|
||||||
|
try {
|
||||||
|
const result = await this.client.query(
|
||||||
|
aql`INSERT ${query.json} INTO ${clc} RETURN NEW`
|
||||||
|
)
|
||||||
|
return result.all()
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying arangodb", err.message)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
schema: SCHEMA,
|
||||||
|
integration: ArangoDBIntegration,
|
||||||
|
}
|
|
@ -3,10 +3,11 @@ const dynamodb = require("./dynamodb")
|
||||||
const mongodb = require("./mongodb")
|
const mongodb = require("./mongodb")
|
||||||
const elasticsearch = require("./elasticsearch")
|
const elasticsearch = require("./elasticsearch")
|
||||||
const couchdb = require("./couchdb")
|
const couchdb = require("./couchdb")
|
||||||
// const redis = require("./redis")
|
|
||||||
const sqlServer = require("./microsoftSqlServer")
|
const sqlServer = require("./microsoftSqlServer")
|
||||||
const s3 = require("./s3")
|
const s3 = require("./s3")
|
||||||
const airtable = require("./airtable")
|
const airtable = require("./airtable")
|
||||||
|
const mysql = require("./mysql")
|
||||||
|
const arangodb = require("./arangodb")
|
||||||
|
|
||||||
const DEFINITIONS = {
|
const DEFINITIONS = {
|
||||||
POSTGRES: postgres.schema,
|
POSTGRES: postgres.schema,
|
||||||
|
@ -17,6 +18,8 @@ const DEFINITIONS = {
|
||||||
SQL_SERVER: sqlServer.schema,
|
SQL_SERVER: sqlServer.schema,
|
||||||
S3: s3.schema,
|
S3: s3.schema,
|
||||||
AIRTABLE: airtable.schema,
|
AIRTABLE: airtable.schema,
|
||||||
|
MYSQL: mysql.schema,
|
||||||
|
ARANGODB: arangodb.schema,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INTEGRATIONS = {
|
const INTEGRATIONS = {
|
||||||
|
@ -28,6 +31,8 @@ const INTEGRATIONS = {
|
||||||
S3: s3.integration,
|
S3: s3.integration,
|
||||||
SQL_SERVER: sqlServer.integration,
|
SQL_SERVER: sqlServer.integration,
|
||||||
AIRTABLE: airtable.integration,
|
AIRTABLE: airtable.integration,
|
||||||
|
MYSQL: mysql.integration,
|
||||||
|
ARANGODB: arangodb.integration,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
const mysql = require("mysql")
|
||||||
|
|
||||||
|
const SCHEMA = {
|
||||||
|
docs: "https://github.com/mysqljs/mysql",
|
||||||
|
datasource: {
|
||||||
|
host: {
|
||||||
|
type: "string",
|
||||||
|
default: "localhost",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
type: "string",
|
||||||
|
default: "root",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: "password",
|
||||||
|
default: "root",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
database: {
|
||||||
|
type: "string",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
create: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
class MySQLIntegration {
|
||||||
|
constructor(config) {
|
||||||
|
this.config = config
|
||||||
|
this.client = mysql.createConnection(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
query(query) {
|
||||||
|
// Node MySQL is callback based, so we must wrap our call in a promise
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.client.connect()
|
||||||
|
return this.client.query(query.sql, (error, results) => {
|
||||||
|
if (error) return reject(error)
|
||||||
|
resolve(results)
|
||||||
|
this.client.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
create(query) {
|
||||||
|
return this.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
read(query) {
|
||||||
|
return this.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
update(query) {
|
||||||
|
return this.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(query) {
|
||||||
|
return this.query(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
schema: SCHEMA,
|
||||||
|
integration: MySQLIntegration,
|
||||||
|
}
|
|
@ -58,7 +58,7 @@ class PostgresIntegration {
|
||||||
|
|
||||||
async create({ sql }) {
|
async create({ sql }) {
|
||||||
const response = await this.client.query(sql)
|
const response = await this.client.query(sql)
|
||||||
return response.rows
|
return response.rows.length ? response.rows : [{ created: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async read({ sql }) {
|
async read({ sql }) {
|
||||||
|
@ -68,12 +68,12 @@ class PostgresIntegration {
|
||||||
|
|
||||||
async update({ sql }) {
|
async update({ sql }) {
|
||||||
const response = await this.client.query(sql)
|
const response = await this.client.query(sql)
|
||||||
return response.rows
|
return response.rows.length ? response.rows : [{ updated: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete({ sql }) {
|
async delete({ sql }) {
|
||||||
const response = await this.client.query(sql)
|
const response = await this.client.query(sql)
|
||||||
return response.rows
|
return response.rows.length ? response.rows : [{ deleted: true }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +0,0 @@
|
||||||
*
|
|
||||||
!dist/*
|
|
||||||
!components.json
|
|
|
@ -10,6 +10,11 @@
|
||||||
"start:dev": "sirv public --single --dev",
|
"start:dev": "sirv public --single --dev",
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
|
"files": [
|
||||||
|
"manifest.json",
|
||||||
|
"package.json",
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-alias": "^3.1.1",
|
"@rollup/plugin-alias": "^3.1.1",
|
||||||
"@rollup/plugin-commonjs": "^16.0.0",
|
"@rollup/plugin-commonjs": "^16.0.0",
|
||||||
|
@ -29,7 +34,7 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"svelte"
|
"svelte"
|
||||||
],
|
],
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"gitHead": "62ebf3cedcd7e9b2494b4f8cbcfb90927609b491",
|
"gitHead": "62ebf3cedcd7e9b2494b4f8cbcfb90927609b491",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"module": "dist/bundle.js",
|
"module": "dist/bundle.js",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/deployment",
|
"name": "@budibase/deployment",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.5.3",
|
"version": "0.6.2",
|
||||||
"description": "Budibase Deployment Server",
|
"description": "Budibase Deployment Server",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
Loading…
Reference in New Issue