Merge branch 'develop' of github.com:Budibase/budibase into side-panel
This commit is contained in:
commit
c01b9af1f0
|
@ -60,8 +60,6 @@ spec:
|
|||
secretKeyRef:
|
||||
name: {{ template "budibase.fullname" . }}
|
||||
key: jwtSecret
|
||||
- name: LOG_LEVEL
|
||||
value: {{ .Values.services.apps.logLevel | default "info" | quote }}
|
||||
{{ if .Values.services.objectStore.region }}
|
||||
- name: AWS_REGION
|
||||
value: {{ .Values.services.objectStore.region }}
|
||||
|
|
|
@ -124,12 +124,21 @@ http {
|
|||
}
|
||||
|
||||
location /api/backups/ {
|
||||
# calls to export apps are limited
|
||||
limit_req zone=ratelimit burst=20 nodelay;
|
||||
|
||||
# 1800s timeout for app export requests
|
||||
proxy_read_timeout 1800s;
|
||||
proxy_connect_timeout 1800s;
|
||||
proxy_send_timeout 1800s;
|
||||
proxy_pass http://app-service;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_pass http://$apps:4002;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
|
|
|
@ -43,6 +43,24 @@ server {
|
|||
rewrite ^/worker/(.*)$ /$1 break;
|
||||
}
|
||||
|
||||
location /api/backups/ {
|
||||
# calls to export apps are limited
|
||||
limit_req zone=ratelimit burst=20 nodelay;
|
||||
|
||||
# 1800s timeout for app export requests
|
||||
proxy_read_timeout 1800s;
|
||||
proxy_connect_timeout 1800s;
|
||||
proxy_send_timeout 1800s;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_pass http://127.0.0.1:4001;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
# calls to the API are rate limited with bursting
|
||||
limit_req zone=ratelimit burst=20 nodelay;
|
||||
|
|
|
@ -27,12 +27,14 @@ if [[ "${TARGETBUILD}" = "aas" ]]; then
|
|||
else
|
||||
DATA_DIR=${DATA_DIR:-/data}
|
||||
fi
|
||||
|
||||
mkdir -p ${DATA_DIR}
|
||||
# Mount NFS or GCP Filestore if env vars exist for it
|
||||
if [[ -z ${FILESHARE_IP} && -z ${FILESHARE_NAME} ]]; then
|
||||
if [[ ! -z ${FILESHARE_IP} && ! -z ${FILESHARE_NAME} ]]; then
|
||||
echo "Mounting NFS share"
|
||||
apt update && apt install -y nfs-common nfs-kernel-server
|
||||
echo "Mount file share ${FILESHARE_IP}:/${FILESHARE_NAME} to ${DATA_DIR}"
|
||||
mount -o nolock ${FILESHARE_IP}:/${FILESHARE_NAME} ${DATA_DIR}
|
||||
echo "Mounting completed."
|
||||
echo "Mounting result: $?"
|
||||
fi
|
||||
|
||||
if [ -f "${DATA_DIR}/.env" ]; then
|
||||
|
@ -74,9 +76,9 @@ mkdir -p ${DATA_DIR}/couch/{dbs,views}
|
|||
mkdir -p ${DATA_DIR}/minio
|
||||
mkdir -p ${DATA_DIR}/search
|
||||
chown -R couchdb:couchdb ${DATA_DIR}/couch
|
||||
redis-server --requirepass $REDIS_PASSWORD &
|
||||
/opt/clouseau/bin/clouseau &
|
||||
/minio/minio server ${DATA_DIR}/minio &
|
||||
redis-server --requirepass $REDIS_PASSWORD > /dev/stdout 2>&1 &
|
||||
/opt/clouseau/bin/clouseau > /dev/stdout 2>&1 &
|
||||
/minio/minio server ${DATA_DIR}/minio > /dev/stdout 2>&1 &
|
||||
/docker-entrypoint.sh /opt/couchdb/bin/couchdb &
|
||||
/etc/init.d/nginx restart
|
||||
if [[ ! -z "${CUSTOM_DOMAIN}" ]]; then
|
||||
|
@ -85,16 +87,18 @@ if [[ ! -z "${CUSTOM_DOMAIN}" ]]; then
|
|||
chmod +x /etc/cron.d/certificate-renew
|
||||
# Request the certbot certificate
|
||||
/app/letsencrypt/certificate-request.sh ${CUSTOM_DOMAIN}
|
||||
/etc/init.d/nginx restart
|
||||
fi
|
||||
|
||||
/etc/init.d/nginx restart
|
||||
pushd app
|
||||
pm2 start --name app "yarn run:docker"
|
||||
pm2 start -l /dev/stdout --name app "yarn run:docker"
|
||||
popd
|
||||
pushd worker
|
||||
pm2 start --name worker "yarn run:docker"
|
||||
pm2 start -l /dev/stdout --name worker "yarn run:docker"
|
||||
popd
|
||||
sleep 10
|
||||
echo "curl to couchdb endpoints"
|
||||
curl -X PUT ${COUCH_DB_URL}/_users
|
||||
curl -X PUT ${COUCH_DB_URL}/_replicator
|
||||
echo "end of runner.sh, sleeping ..."
|
||||
sleep infinity
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/backend-core",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase backend core libraries used in server and worker",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
|
@ -20,7 +20,7 @@
|
|||
"test:watch": "jest --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/types": "2.1.22-alpha.8",
|
||||
"@budibase/types": "2.1.32-alpha.3",
|
||||
"@shopify/jest-koa-mocks": "5.0.1",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
"aws-sdk": "2.1030.0",
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
exports.UserStatus = {
|
||||
ACTIVE: "active",
|
||||
INACTIVE: "inactive",
|
||||
}
|
||||
|
||||
exports.Cookie = {
|
||||
CurrentApp: "budibase:currentapp",
|
||||
Auth: "budibase:auth",
|
||||
Init: "budibase:init",
|
||||
ACCOUNT_RETURN_URL: "budibase:account:returnurl",
|
||||
DatasourceAuth: "budibase:datasourceauth",
|
||||
OIDC_CONFIG: "budibase:oidc:config",
|
||||
}
|
||||
|
||||
exports.Header = {
|
||||
API_KEY: "x-budibase-api-key",
|
||||
LICENSE_KEY: "x-budibase-license-key",
|
||||
API_VER: "x-budibase-api-version",
|
||||
APP_ID: "x-budibase-app-id",
|
||||
TYPE: "x-budibase-type",
|
||||
PREVIEW_ROLE: "x-budibase-role",
|
||||
TENANT_ID: "x-budibase-tenant-id",
|
||||
TOKEN: "x-budibase-token",
|
||||
CSRF_TOKEN: "x-csrf-token",
|
||||
}
|
||||
|
||||
exports.GlobalRoles = {
|
||||
OWNER: "owner",
|
||||
ADMIN: "admin",
|
||||
BUILDER: "builder",
|
||||
WORKSPACE_MANAGER: "workspace_manager",
|
||||
}
|
||||
|
||||
exports.Config = {
|
||||
SETTINGS: "settings",
|
||||
ACCOUNT: "account",
|
||||
SMTP: "smtp",
|
||||
GOOGLE: "google",
|
||||
OIDC: "oidc",
|
||||
OIDC_LOGOS: "logos_oidc",
|
||||
}
|
||||
|
||||
exports.MAX_VALID_DATE = new Date(2147483647000)
|
||||
exports.DEFAULT_TENANT_ID = "default"
|
|
@ -92,3 +92,4 @@ export const StaticDatabases = {
|
|||
export const APP_PREFIX = DocumentType.APP + SEPARATOR
|
||||
export const APP_DEV = DocumentType.APP_DEV + SEPARATOR
|
||||
export const APP_DEV_PREFIX = APP_DEV
|
||||
export const BUDIBASE_DATASOURCE_TYPE = "budibase"
|
||||
|
|
|
@ -6,10 +6,15 @@ import {
|
|||
DatabaseOpts,
|
||||
DatabaseQueryOpts,
|
||||
DatabasePutOpts,
|
||||
DatabaseCreateIndexOpts,
|
||||
DatabaseDeleteIndexOpts,
|
||||
Document,
|
||||
isDocument,
|
||||
} from "@budibase/types"
|
||||
import { getCouchInfo } from "./connections"
|
||||
import { directCouchCall } from "./utils"
|
||||
import { getPouchDB } from "./pouchDB"
|
||||
import { WriteStream, ReadStream } from "fs"
|
||||
|
||||
export class DatabaseImpl implements Database {
|
||||
public readonly name: string
|
||||
|
@ -77,12 +82,23 @@ export class DatabaseImpl implements Database {
|
|||
return this.updateOutput(() => db.get(id))
|
||||
}
|
||||
|
||||
async remove(id?: string, rev?: string) {
|
||||
async remove(idOrDoc: string | Document, rev?: string) {
|
||||
const db = await this.checkSetup()
|
||||
if (!id || !rev) {
|
||||
let _id: string
|
||||
let _rev: string
|
||||
|
||||
if (isDocument(idOrDoc)) {
|
||||
_id = idOrDoc._id!
|
||||
_rev = idOrDoc._rev!
|
||||
} else {
|
||||
_id = idOrDoc
|
||||
_rev = rev!
|
||||
}
|
||||
|
||||
if (!_id || !_rev) {
|
||||
throw new Error("Unable to remove doc without a valid _id and _rev.")
|
||||
}
|
||||
return this.updateOutput(() => db.destroy(id, rev))
|
||||
return this.updateOutput(() => db.destroy(_id, _rev))
|
||||
}
|
||||
|
||||
async put(document: AnyDocument, opts?: DatabasePutOpts) {
|
||||
|
@ -146,34 +162,32 @@ export class DatabaseImpl implements Database {
|
|||
return this.updateOutput(() => db.compact())
|
||||
}
|
||||
|
||||
private doWithPouchDB(func: string) {
|
||||
const dbName = this.name
|
||||
return async (args: any[]) => {
|
||||
const pouch = getPouchDB(dbName)
|
||||
// @ts-ignore
|
||||
return pouch[func](...args)
|
||||
}
|
||||
}
|
||||
|
||||
// All below functions are in-frequently called, just utilise PouchDB
|
||||
// for them as it implements them better than we can
|
||||
async dump(...args: any[]) {
|
||||
return this.doWithPouchDB("dump")(args)
|
||||
async dump(stream: WriteStream, opts?: { filter?: any }) {
|
||||
const pouch = getPouchDB(this.name)
|
||||
// @ts-ignore
|
||||
return pouch.dump(stream, opts)
|
||||
}
|
||||
|
||||
async load(...args: any[]) {
|
||||
return this.doWithPouchDB("load")(args)
|
||||
async load(stream: ReadStream) {
|
||||
const pouch = getPouchDB(this.name)
|
||||
// @ts-ignore
|
||||
return pouch.load(stream)
|
||||
}
|
||||
|
||||
async createIndex(...args: any[]) {
|
||||
return this.doWithPouchDB("createIndex")(args)
|
||||
async createIndex(opts: DatabaseCreateIndexOpts) {
|
||||
const pouch = getPouchDB(this.name)
|
||||
return pouch.createIndex(opts)
|
||||
}
|
||||
|
||||
async deleteIndex(...args: any[]) {
|
||||
return this.doWithPouchDB("createIndex")(args)
|
||||
async deleteIndex(opts: DatabaseDeleteIndexOpts) {
|
||||
const pouch = getPouchDB(this.name)
|
||||
return pouch.deleteIndex(opts)
|
||||
}
|
||||
|
||||
async getIndexes(...args: any[]) {
|
||||
return this.doWithPouchDB("createIndex")(args)
|
||||
async getIndexes() {
|
||||
const pouch = getPouchDB(this.name)
|
||||
return pouch.getIndexes()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,9 @@ export const queryView = async <T>(
|
|||
return docs.length <= 1 ? (docs[0] as T) : (docs as T[])
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err != null && err.name === "not_found") {
|
||||
const pouchNotFound = err && err.name === "not_found"
|
||||
const couchNotFound = err && err.status === 404
|
||||
if (pouchNotFound || couchNotFound) {
|
||||
await removeDeprecated(db, viewName)
|
||||
await createFunc()
|
||||
return queryView(viewName, params, db, createFunc, opts)
|
||||
|
|
|
@ -1,12 +1,34 @@
|
|||
import { AppBackup, AppBackupRestoreEvent, Event } from "@budibase/types"
|
||||
import {
|
||||
AppBackup,
|
||||
AppBackupRestoreEvent,
|
||||
AppBackupTriggeredEvent,
|
||||
AppBackupTrigger,
|
||||
AppBackupType,
|
||||
Event,
|
||||
} from "@budibase/types"
|
||||
import { publishEvent } from "../events"
|
||||
|
||||
export async function appBackupRestored(backup: AppBackup) {
|
||||
const properties: AppBackupRestoreEvent = {
|
||||
appId: backup.appId,
|
||||
backupName: backup.name!,
|
||||
restoreId: backup._id!,
|
||||
backupCreatedAt: backup.timestamp,
|
||||
}
|
||||
|
||||
await publishEvent(Event.APP_BACKUP_RESTORED, properties)
|
||||
}
|
||||
|
||||
export async function appBackupTriggered(
|
||||
appId: string,
|
||||
backupId: string,
|
||||
type: AppBackupType,
|
||||
trigger: AppBackupTrigger
|
||||
) {
|
||||
const properties: AppBackupTriggeredEvent = {
|
||||
appId: appId,
|
||||
backupId,
|
||||
type,
|
||||
trigger,
|
||||
}
|
||||
await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ function validateDatasource(schema) {
|
|||
const queryValidator = joi
|
||||
.object({
|
||||
type: joi.string().allow(...Object.values(QueryType)),
|
||||
readable: joi.boolean(),
|
||||
fields: joi.object().pattern(joi.string(), fieldValidator),
|
||||
})
|
||||
.required()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/bbui",
|
||||
"description": "A UI solution used in the different Budibase projects.",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"module": "dist/bbui.es.js",
|
||||
|
@ -38,7 +38,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@spectrum-css/actionbutton": "^1.0.1",
|
||||
"@spectrum-css/actiongroup": "^1.0.1",
|
||||
"@spectrum-css/avatar": "^3.0.2",
|
||||
|
@ -85,5 +85,8 @@
|
|||
"svelte-flatpickr": "^3.2.3",
|
||||
"svelte-portal": "^1.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"loader-utils": "1.4.1"
|
||||
},
|
||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -71,10 +71,10 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.1.22-alpha.8",
|
||||
"@budibase/client": "2.1.22-alpha.8",
|
||||
"@budibase/frontend-core": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/bbui": "2.1.32-alpha.3",
|
||||
"@budibase/client": "2.1.32-alpha.3",
|
||||
"@budibase/frontend-core": "2.1.32-alpha.3",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@sentry/browser": "5.19.1",
|
||||
"@spectrum-css/page": "^3.0.1",
|
||||
"@spectrum-css/vars": "^3.0.1",
|
||||
|
|
|
@ -304,6 +304,8 @@
|
|||
const newError = {}
|
||||
if (!external && fieldInfo.name?.startsWith("_")) {
|
||||
newError.name = `Column name cannot start with an underscore.`
|
||||
} else if (fieldInfo.name && !fieldInfo.name.match(/^[_a-zA-Z0-9\s]*$/g)) {
|
||||
newError.name = `Illegal character; must be alpha-numeric.`
|
||||
} else if (PROHIBITED_COLUMN_NAMES.some(name => fieldInfo.name === name)) {
|
||||
newError.name = `${PROHIBITED_COLUMN_NAMES.join(
|
||||
", "
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
}
|
||||
|
||||
function fieldOptions(field) {
|
||||
return schema[field]?.type === "options"
|
||||
return schema[field]?.type === "options" || schema[field]?.type === "array"
|
||||
? schema[field]?.constraints.inclusion
|
||||
: [true, false]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { onMount } from "svelte"
|
||||
import { get } from "svelte/store"
|
||||
import { goto, params } from "@roxi/routify"
|
||||
import { BUDIBASE_INTERNAL_DB } from "constants"
|
||||
import { BUDIBASE_INTERNAL_DB_ID } from "constants/backend"
|
||||
import { database, datasources, queries, tables, views } from "stores/backend"
|
||||
import EditDatasourcePopover from "./popovers/EditDatasourcePopover.svelte"
|
||||
import EditQueryPopover from "./popovers/EditQueryPopover.svelte"
|
||||
|
@ -129,7 +129,7 @@
|
|||
size="18"
|
||||
/>
|
||||
</div>
|
||||
{#if datasource._id !== BUDIBASE_INTERNAL_DB}
|
||||
{#if datasource._id !== BUDIBASE_INTERNAL_DB_ID}
|
||||
<EditDatasourcePopover {datasource} />
|
||||
{/if}
|
||||
</NavItem>
|
||||
|
|
|
@ -10,10 +10,23 @@
|
|||
Divider,
|
||||
Layout,
|
||||
} from "@budibase/bbui"
|
||||
import { datasources } from "stores/backend"
|
||||
import TableDataImport from "../TableDataImport.svelte"
|
||||
import {
|
||||
BUDIBASE_INTERNAL_DB_ID,
|
||||
BUDIBASE_DATASOURCE_TYPE,
|
||||
} from "constants/backend"
|
||||
import { buildAutoColumn, getAutoColumnInformation } from "builderStore/utils"
|
||||
|
||||
$: tableNames = $tables.list.map(table => table.name)
|
||||
$: selectedSource = $datasources.list.find(
|
||||
source => source._id === $datasources.selected
|
||||
)
|
||||
|
||||
$: isSelectedInternal = selectedSource?.type === BUDIBASE_DATASOURCE_TYPE
|
||||
$: targetDatasourceId = isSelectedInternal
|
||||
? selectedSource._id
|
||||
: BUDIBASE_INTERNAL_DB_ID
|
||||
|
||||
export let name
|
||||
let dataImport
|
||||
|
@ -45,7 +58,7 @@
|
|||
schema: addAutoColumns(name, dataImport.schema || {}),
|
||||
dataImport,
|
||||
type: "internal",
|
||||
sourceId: "bb_internal",
|
||||
sourceId: targetDatasourceId,
|
||||
}
|
||||
|
||||
// Only set primary display if defined
|
||||
|
|
|
@ -19,6 +19,7 @@ import FormFieldSelect from "./controls/FormFieldSelect.svelte"
|
|||
import ValidationEditor from "./controls/ValidationEditor/ValidationEditor.svelte"
|
||||
import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCombobox.svelte"
|
||||
import ColumnEditor from "./controls/ColumnEditor/ColumnEditor.svelte"
|
||||
import BasicColumnEditor from "./controls/ColumnEditor/BasicColumnEditor.svelte"
|
||||
import BarButtonList from "./controls/BarButtonList.svelte"
|
||||
|
||||
const componentMap = {
|
||||
|
@ -43,6 +44,7 @@ const componentMap = {
|
|||
filter: FilterEditor,
|
||||
url: URLSelect,
|
||||
columns: ColumnEditor,
|
||||
"columns/basic": BasicColumnEditor,
|
||||
"field/sortable": SortableFieldSelect,
|
||||
"field/string": FormFieldSelect,
|
||||
"field/number": FormFieldSelect,
|
||||
|
|
|
@ -23,14 +23,18 @@
|
|||
export let bindings = []
|
||||
export let nested
|
||||
|
||||
$: showAvailableActions = !actions?.length
|
||||
|
||||
let actionQuery
|
||||
$: parsedQuery =
|
||||
typeof actionQuery === "string" ? actionQuery.toLowerCase().trim() : ""
|
||||
|
||||
let selectedAction = actions?.length ? actions[0] : null
|
||||
|
||||
$: {
|
||||
// Ensure parameters object is never null
|
||||
if (selectedAction && !selectedAction.parameters) {
|
||||
selectedAction.parameters = {}
|
||||
}
|
||||
}
|
||||
$: parsedQuery =
|
||||
typeof actionQuery === "string" ? actionQuery.toLowerCase().trim() : ""
|
||||
$: showAvailableActions = !actions?.length
|
||||
$: mappedActionTypes = actionTypes.reduce((acc, action) => {
|
||||
let parsedName = action.name.toLowerCase().trim()
|
||||
if (parsedQuery.length && parsedName.indexOf(parsedQuery) < 0) {
|
||||
|
@ -40,7 +44,6 @@
|
|||
acc[action.type].push(action)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
// These are ephemeral bindings which only exist while executing actions
|
||||
$: eventContexBindings = getEventContextBindings(
|
||||
$currentAsset,
|
||||
|
@ -50,9 +53,8 @@
|
|||
selectedAction?.id
|
||||
)
|
||||
$: allBindings = eventContexBindings.concat(bindings)
|
||||
|
||||
// Assign a unique ID to each action
|
||||
$: {
|
||||
// Ensure each action has a unique ID
|
||||
if (actions) {
|
||||
actions.forEach(action => {
|
||||
if (!action.id) {
|
||||
|
@ -61,13 +63,11 @@
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
$: selectedActionComponent =
|
||||
selectedAction &&
|
||||
actionTypes.find(t => t.name === selectedAction[EVENT_TYPE_KEY])?.component
|
||||
|
||||
// Select the first action if we delete an action
|
||||
$: {
|
||||
// Select the first action if we delete an action
|
||||
if (selectedAction && !actions?.includes(selectedAction)) {
|
||||
selectedAction = actions?.[0]
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<script>
|
||||
import { Label, Body } from "@budibase/bbui"
|
||||
import { Label } from "@budibase/bbui"
|
||||
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
|
||||
|
||||
export let parameters
|
||||
export let bindings = []
|
||||
</script>
|
||||
|
||||
<Body size="S">Navigate To screen, or leave blank.</Body>
|
||||
<br />
|
||||
<div class="root">
|
||||
<span>
|
||||
You can optionally navigate to another screen after closing the screen
|
||||
modal.
|
||||
</span>
|
||||
<Label small>Screen</Label>
|
||||
<DrawerBindableInput
|
||||
title="Destination URL"
|
||||
|
@ -20,6 +22,9 @@
|
|||
</div>
|
||||
|
||||
<style>
|
||||
span {
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
.root {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
import { datasources, integrations, queries } from "stores/backend"
|
||||
import BindingBuilder from "components/integration/QueryBindingBuilder.svelte"
|
||||
import IntegrationQueryEditor from "components/integration/index.svelte"
|
||||
import { BUDIBASE_DATASOURCE_ID } from "constants/backend"
|
||||
import {
|
||||
BUDIBASE_INTERNAL_DB_ID,
|
||||
BUDIBASE_DATASOURCE_TYPE,
|
||||
} from "constants/backend"
|
||||
|
||||
export let parameters
|
||||
export let bindings = []
|
||||
|
@ -14,7 +17,8 @@
|
|||
)
|
||||
// Executequery must exclude budibase datasource
|
||||
$: executeQueryDatasources = $datasources.list.filter(
|
||||
x => x._id !== BUDIBASE_DATASOURCE_ID
|
||||
x =>
|
||||
x._id !== BUDIBASE_INTERNAL_DB_ID && x.type !== BUDIBASE_DATASOURCE_TYPE
|
||||
)
|
||||
|
||||
function fetchQueryDefinition(query) {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
import ColumnEditor from "./ColumnEditor.svelte"
|
||||
</script>
|
||||
|
||||
<ColumnEditor
|
||||
{...$$props}
|
||||
on:change
|
||||
allowCellEditing={false}
|
||||
subject="Dynamic Filter"
|
||||
/>
|
|
@ -17,6 +17,7 @@
|
|||
export let columns = []
|
||||
export let options = []
|
||||
export let schema = {}
|
||||
export let allowCellEditing = true
|
||||
|
||||
const flipDurationMs = 150
|
||||
let dragDisabled = true
|
||||
|
@ -123,7 +124,9 @@
|
|||
on:change={e => (column.displayName = e.detail)}
|
||||
/>
|
||||
<Input bind:value={column.displayName} placeholder="Label" />
|
||||
<CellEditor bind:column />
|
||||
{#if allowCellEditing}
|
||||
<CellEditor bind:column />
|
||||
{/if}
|
||||
<Icon
|
||||
name="Close"
|
||||
hoverable
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
export let componentInstance
|
||||
export let value = []
|
||||
export let allowCellEditing = true
|
||||
export let subject = "Table"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
@ -68,10 +70,16 @@
|
|||
</script>
|
||||
|
||||
<ActionButton on:click={open}>Configure columns</ActionButton>
|
||||
<Drawer bind:this={drawer} title="Table Columns">
|
||||
<Drawer bind:this={drawer} title="{subject} Columns">
|
||||
<svelte:fragment slot="description">
|
||||
Configure the columns in your table.
|
||||
Configure the columns in your {subject.toLowerCase()}.
|
||||
</svelte:fragment>
|
||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||
<ColumnDrawer slot="body" bind:columns={boundValue} {options} {schema} />
|
||||
<ColumnDrawer
|
||||
slot="body"
|
||||
bind:columns={boundValue}
|
||||
{options}
|
||||
{schema}
|
||||
{allowCellEditing}
|
||||
/>
|
||||
</Drawer>
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<script>
|
||||
import { writable, get as svelteGet } from "svelte/store"
|
||||
import { notifications, Input, ModalContent, Dropzone } from "@budibase/bbui"
|
||||
import {
|
||||
notifications,
|
||||
Input,
|
||||
ModalContent,
|
||||
Dropzone,
|
||||
Toggle,
|
||||
} from "@budibase/bbui"
|
||||
import { store, automationStore } from "builderStore"
|
||||
import { API } from "api"
|
||||
import { apps, admin, auth } from "stores/portal"
|
||||
|
@ -16,6 +22,7 @@
|
|||
|
||||
let creating = false
|
||||
let defaultAppName
|
||||
let includeSampleDB = true
|
||||
|
||||
const values = writable({ name: "", url: null })
|
||||
const validation = createValidationStore()
|
||||
|
@ -98,6 +105,8 @@
|
|||
data.append("templateName", template.name)
|
||||
data.append("templateKey", template.key)
|
||||
data.append("templateFile", $values.file)
|
||||
} else {
|
||||
data.append("sampleData", includeSampleDB)
|
||||
}
|
||||
|
||||
// Create App
|
||||
|
@ -192,6 +201,15 @@
|
|||
</div>
|
||||
{/if}
|
||||
</span>
|
||||
{#if !template && !template?.fromFile}
|
||||
<span>
|
||||
<Toggle
|
||||
text="Include sample data"
|
||||
bind:value={includeSampleDB}
|
||||
disabled={creating}
|
||||
/>
|
||||
</span>
|
||||
{/if}
|
||||
</ModalContent>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -173,7 +173,8 @@ export const SWITCHABLE_TYPES = [
|
|||
...ALLOWABLE_NUMBER_TYPES,
|
||||
]
|
||||
|
||||
export const BUDIBASE_DATASOURCE_ID = "bb_internal"
|
||||
export const BUDIBASE_INTERNAL_DB_ID = "bb_internal"
|
||||
export const BUDIBASE_DATASOURCE_TYPE = "budibase"
|
||||
|
||||
export const IntegrationTypes = {
|
||||
POSTGRES: "POSTGRES",
|
||||
|
|
|
@ -43,8 +43,6 @@ export const LAYOUT_NAMES = {
|
|||
},
|
||||
}
|
||||
|
||||
export const BUDIBASE_INTERNAL_DB = "bb_internal"
|
||||
|
||||
// one or more word characters and whitespace
|
||||
export const APP_NAME_REGEX = /^[\w\s]+$/
|
||||
// zero or more non-whitespace characters
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import { redirect, params } from "@roxi/routify"
|
||||
import { redirect } from "@roxi/routify"
|
||||
import { Button, Tabs, Tab, Layout } from "@budibase/bbui"
|
||||
import { BUDIBASE_INTERNAL_DB } from "constants"
|
||||
import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte"
|
||||
import CreateDatasourceModal from "components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte"
|
||||
|
||||
|
@ -9,10 +8,6 @@
|
|||
|
||||
let modal
|
||||
|
||||
$: isExternal =
|
||||
$params.selectedDatasource &&
|
||||
$params.selectedDatasource !== BUDIBASE_INTERNAL_DB
|
||||
|
||||
function selectFirstDatasource() {
|
||||
$redirect("./table")
|
||||
}
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
import { Button, Heading, Body, Layout, Modal, Divider } from "@budibase/bbui"
|
||||
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
|
||||
import ICONS from "components/backend/DatasourceNavigator/icons"
|
||||
import { tables } from "stores/backend"
|
||||
import { tables, datasources } from "stores/backend"
|
||||
import { goto } from "@roxi/routify"
|
||||
|
||||
let modal
|
||||
|
||||
$: internalTablesBySourceId = $tables.list.filter(
|
||||
table =>
|
||||
table.type !== "external" && $datasources.selected === table.sourceId
|
||||
)
|
||||
</script>
|
||||
|
||||
<Modal bind:this={modal}>
|
||||
|
@ -27,7 +32,7 @@
|
|||
<Divider />
|
||||
<Heading size="S">Tables</Heading>
|
||||
<div class="table-list">
|
||||
{#each $tables.list.filter(table => table.type !== "external") as table}
|
||||
{#each internalTablesBySourceId as table}
|
||||
<div
|
||||
class="table-list-item"
|
||||
on:click={$goto(`../../table/${table._id}`)}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
import { datasources } from "stores/backend"
|
||||
|
||||
datasources.select("datasource_internal_bb_default")
|
||||
</script>
|
||||
|
||||
<slot />
|
|
@ -0,0 +1,87 @@
|
|||
<script>
|
||||
import { Button, Heading, Body, Layout, Modal, Divider } from "@budibase/bbui"
|
||||
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
|
||||
import ICONS from "components/backend/DatasourceNavigator/icons"
|
||||
import { tables, datasources } from "stores/backend"
|
||||
import { goto } from "@roxi/routify"
|
||||
|
||||
let modal
|
||||
$: internalTablesBySourceId = $tables.list.filter(
|
||||
table =>
|
||||
table.type !== "external" && $datasources.selected === table.sourceId
|
||||
)
|
||||
</script>
|
||||
|
||||
<Modal bind:this={modal}>
|
||||
<CreateTableModal />
|
||||
</Modal>
|
||||
|
||||
<section>
|
||||
<Layout>
|
||||
<Layout gap="XS" noPadding>
|
||||
<header>
|
||||
<svelte:component this={ICONS.BUDIBASE} height="26" width="26" />
|
||||
<Heading size="M">Sample Data</Heading>
|
||||
</header>
|
||||
<Body size="M">A little something to get you up and running!</Body>
|
||||
<Body size="M"
|
||||
>If you have no need for this datasource, feel free to delete it.</Body
|
||||
>
|
||||
</Layout>
|
||||
<Divider />
|
||||
<Heading size="S">Tables</Heading>
|
||||
<div class="table-list">
|
||||
<!-- {JSON.stringify($tables.list.map(source => source.sourceId))} -->
|
||||
{#each internalTablesBySourceId as table}
|
||||
<div
|
||||
class="table-list-item"
|
||||
on:click={$goto(`../../table/${table._id}`)}
|
||||
>
|
||||
<Body size="S">{table.name}</Body>
|
||||
{#if table.primaryDisplay}
|
||||
<Body size="S">Display column: {table.primaryDisplay}</Body>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<Button cta on:click={modal.show}>Create new table</Button>
|
||||
</div>
|
||||
</Layout>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
margin: 0 auto;
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
gap: var(--spacing-l);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
|
||||
.table-list-item {
|
||||
border-radius: var(--border-radius-m);
|
||||
background: var(--background);
|
||||
border: var(--border-dark);
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 0.75fr 20px;
|
||||
align-items: center;
|
||||
padding: var(--spacing-m);
|
||||
gap: var(--layout-xs);
|
||||
transition: 200ms background ease;
|
||||
}
|
||||
|
||||
.table-list-item:hover {
|
||||
background: var(--grey-1);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
let modal
|
||||
$: setupComplete =
|
||||
$datasources.list.find(x => (x._id = "bb_internal"))?.entities.length > 1 ||
|
||||
$datasources.list.length > 1
|
||||
$datasources.list.find(x => (x._id = "bb_internal"))?.entities?.length >
|
||||
1 || $datasources.list.length > 1
|
||||
|
||||
onMount(() => {
|
||||
if (!setupComplete && !$admin.isDev) {
|
||||
|
|
|
@ -155,9 +155,9 @@ export function createAuthStore() {
|
|||
await actions.getSelf()
|
||||
},
|
||||
logout: async () => {
|
||||
setUser(null)
|
||||
setPostLogout()
|
||||
await API.logOut()
|
||||
setPostLogout()
|
||||
setUser(null)
|
||||
await setInitInfo({})
|
||||
},
|
||||
updateSelf: async fields => {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/cli",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||
"main": "src/index.js",
|
||||
"bin": {
|
||||
|
@ -26,9 +26,9 @@
|
|||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/types": "2.1.22-alpha.8",
|
||||
"@budibase/backend-core": "2.1.32-alpha.3",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@budibase/types": "2.1.32-alpha.3",
|
||||
"axios": "0.21.2",
|
||||
"chalk": "4.1.0",
|
||||
"cli-progress": "3.11.2",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"joi": "17.6.0",
|
||||
"lookpath": "1.1.0",
|
||||
"node-fetch": "2",
|
||||
"pkg": "5.7.0",
|
||||
"pkg": "5.8.0",
|
||||
"posthog-node": "1.0.7",
|
||||
"pouchdb": "7.3.0",
|
||||
"pouchdb-replication-stream": "1.2.9",
|
||||
|
|
|
@ -9,11 +9,30 @@
|
|||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/generator@7.18.2":
|
||||
version "7.18.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d"
|
||||
integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.18.2"
|
||||
"@jridgewell/gen-mapping" "^0.3.0"
|
||||
jsesc "^2.5.1"
|
||||
|
||||
"@babel/helper-string-parser@^7.19.4":
|
||||
version "7.19.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
|
||||
integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.18.6":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
|
||||
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.19.1":
|
||||
version "7.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
|
||||
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
|
||||
|
||||
"@babel/highlight@^7.10.4":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
|
||||
|
@ -23,10 +42,10 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@7.17.10":
|
||||
version "7.17.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78"
|
||||
integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==
|
||||
"@babel/parser@7.18.4":
|
||||
version "7.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef"
|
||||
integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==
|
||||
|
||||
"@babel/runtime@^7.15.4":
|
||||
version "7.18.9"
|
||||
|
@ -35,14 +54,23 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/types@7.17.10":
|
||||
version "7.17.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4"
|
||||
integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==
|
||||
"@babel/types@7.18.4":
|
||||
version "7.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354"
|
||||
integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.16.7"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.18.2":
|
||||
version "7.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842"
|
||||
integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.19.4"
|
||||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
|
@ -84,6 +112,38 @@
|
|||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.0":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
|
||||
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
|
||||
dependencies:
|
||||
"@jridgewell/set-array" "^1.0.1"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@jridgewell/resolve-uri@3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
|
||||
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
|
||||
|
||||
"@jridgewell/set-array@^1.0.1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
|
||||
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
|
||||
|
||||
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
|
||||
version "1.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
|
||||
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.9":
|
||||
version "0.3.17"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985"
|
||||
integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==
|
||||
dependencies:
|
||||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
|
@ -701,7 +761,7 @@ deep-extend@^0.6.0, deep-extend@~0.6.0:
|
|||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
deep-is@^0.1.3, deep-is@~0.1.3:
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
@ -833,18 +893,6 @@ escape-string-regexp@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
escodegen@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
|
||||
integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==
|
||||
dependencies:
|
||||
esprima "^4.0.1"
|
||||
estraverse "^5.2.0"
|
||||
esutils "^2.0.2"
|
||||
optionator "^0.8.1"
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-scope@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
|
@ -925,7 +973,7 @@ espree@^7.3.0, espree@^7.3.1:
|
|||
acorn-jsx "^5.3.1"
|
||||
eslint-visitor-keys "^1.3.0"
|
||||
|
||||
esprima@^4.0.0, esprima@^4.0.1:
|
||||
esprima@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
@ -1019,7 +1067,7 @@ fast-json-stable-stringify@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
||||
fast-levenshtein@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
||||
|
@ -1585,6 +1633,11 @@ js-yaml@^3.13.1:
|
|||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
|
||||
|
||||
json-buffer@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
|
||||
|
@ -1723,14 +1776,6 @@ levn@^0.4.1:
|
|||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
levn@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||
integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lie@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
|
||||
|
@ -2009,18 +2054,6 @@ onetime@^5.1.0:
|
|||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
optionator@^0.8.1:
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
||||
integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
|
||||
dependencies:
|
||||
deep-is "~0.1.3"
|
||||
fast-levenshtein "~2.0.6"
|
||||
levn "~0.3.0"
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
word-wrap "~1.2.3"
|
||||
|
||||
optionator@^0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
|
||||
|
@ -2136,10 +2169,10 @@ pinkie@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
|
||||
|
||||
pkg-fetch@3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.4.1.tgz#be68bb9f7fdb0f6ed995abc518ab2e35aa64d2fd"
|
||||
integrity sha512-fS4cdayCa1r4jHkOKGPJKnS9PEs6OWZst+s+m0+CmhmPZObMnxoRnf9T9yUWl+lzM2b5aJF7cnQIySCT7Hq8Dg==
|
||||
pkg-fetch@3.4.2:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.4.2.tgz#6f68ebc54842b73f8c0808959a9df3739dcb28b7"
|
||||
integrity sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==
|
||||
dependencies:
|
||||
chalk "^4.1.2"
|
||||
fs-extra "^9.1.0"
|
||||
|
@ -2150,22 +2183,22 @@ pkg-fetch@3.4.1:
|
|||
tar-fs "^2.1.1"
|
||||
yargs "^16.2.0"
|
||||
|
||||
pkg@5.7.0:
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.7.0.tgz#6422df05e8aa147764be6ef912921d0fa719ea95"
|
||||
integrity sha512-PTiAjNq/CGAtK5qUBR6pjheqnipTFjeecgSgIKEcAOJA4GpmZeOZC8pMOoT0rfes5vHsmcFo7wbSRTAmXQurrg==
|
||||
pkg@5.8.0:
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.8.0.tgz#a77644aeff0b94a1656d7f76558837f7c754a4c0"
|
||||
integrity sha512-8h9PUDYFi+LOMLbIyGRdP21g08mAtHidSpofSrf8LWhxUWGHymaRzcopEGiynB5EhQmZUKM6PQ9kCImV2TpdjQ==
|
||||
dependencies:
|
||||
"@babel/parser" "7.17.10"
|
||||
"@babel/types" "7.17.10"
|
||||
"@babel/generator" "7.18.2"
|
||||
"@babel/parser" "7.18.4"
|
||||
"@babel/types" "7.18.4"
|
||||
chalk "^4.1.2"
|
||||
escodegen "^2.0.0"
|
||||
fs-extra "^9.1.0"
|
||||
globby "^11.1.0"
|
||||
into-stream "^6.0.0"
|
||||
is-core-module "2.9.0"
|
||||
minimist "^1.2.6"
|
||||
multistream "^4.1.0"
|
||||
pkg-fetch "3.4.1"
|
||||
pkg-fetch "3.4.2"
|
||||
prebuild-install "6.1.4"
|
||||
resolve "^1.22.0"
|
||||
stream-meter "^1.0.4"
|
||||
|
@ -2262,11 +2295,6 @@ prelude-ls@^1.2.1:
|
|||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
prelude-ls@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
|
||||
|
||||
prepend-http@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
|
@ -2611,11 +2639,6 @@ sort-keys@^2.0.0:
|
|||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-map@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
spark-md5@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc"
|
||||
|
@ -2907,13 +2930,6 @@ type-check@^0.4.0, type-check@~0.4.0:
|
|||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
type-check@~0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
||||
integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==
|
||||
dependencies:
|
||||
prelude-ls "~1.1.2"
|
||||
|
||||
type-fest@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||
|
@ -3036,7 +3052,7 @@ wide-align@^1.1.0:
|
|||
dependencies:
|
||||
string-width "^1.0.2 || 2 || 3 || 4"
|
||||
|
||||
word-wrap@^1.2.3, word-wrap@~1.2.3:
|
||||
word-wrap@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
"description": "This component contains things within itself",
|
||||
"icon": "Selection",
|
||||
"hasChildren": true,
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 400,
|
||||
"height": 200
|
||||
|
@ -284,7 +283,6 @@
|
|||
"description": "A basic html button that is ready for styling",
|
||||
"icon": "Button",
|
||||
"editable": true,
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 105,
|
||||
"height": 35
|
||||
|
@ -421,7 +419,6 @@
|
|||
"section"
|
||||
],
|
||||
"hasChildren": true,
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 400,
|
||||
"height": 100
|
||||
|
@ -684,7 +681,6 @@
|
|||
"illegalChildren": [
|
||||
"section"
|
||||
],
|
||||
"showSettingsBar": true,
|
||||
"editable": true,
|
||||
"size": {
|
||||
"width": 400,
|
||||
|
@ -810,7 +806,6 @@
|
|||
"illegalChildren": [
|
||||
"section"
|
||||
],
|
||||
"showSettingsBar": true,
|
||||
"editable": true,
|
||||
"size": {
|
||||
"width": 400,
|
||||
|
@ -932,7 +927,6 @@
|
|||
"tag": {
|
||||
"name": "Tag",
|
||||
"icon": "Label",
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 100,
|
||||
"height": 25
|
||||
|
@ -1190,7 +1184,6 @@
|
|||
"name": "Link",
|
||||
"description": "A basic link component for internal and external links",
|
||||
"icon": "Link",
|
||||
"showSettingsBar": true,
|
||||
"editable": true,
|
||||
"size": {
|
||||
"width": 200,
|
||||
|
@ -3912,7 +3905,6 @@
|
|||
"dynamicfilter": {
|
||||
"name": "Dynamic Filter",
|
||||
"icon": "Filter",
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 100,
|
||||
"height": 35
|
||||
|
@ -3925,10 +3917,10 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "multifield",
|
||||
"label": "Allowed filter fields",
|
||||
"type": "columns/basic",
|
||||
"label": "Allowed filter columns",
|
||||
"key": "allowedFields",
|
||||
"placeholder": "All fields"
|
||||
"dependsOn": "dataProvider"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
|
@ -4802,7 +4794,6 @@
|
|||
"section"
|
||||
],
|
||||
"hasChildren": true,
|
||||
"showSettingsBar": true,
|
||||
"size": {
|
||||
"width": 400,
|
||||
"height": 100
|
||||
|
@ -5285,4 +5276,4 @@
|
|||
"suffix": "repeater"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"license": "MPL-2.0",
|
||||
"module": "dist/budibase-client.js",
|
||||
"main": "dist/budibase-client.js",
|
||||
|
@ -19,9 +19,9 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.1.22-alpha.8",
|
||||
"@budibase/frontend-core": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/bbui": "2.1.32-alpha.3",
|
||||
"@budibase/frontend-core": "2.1.32-alpha.3",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@spectrum-css/button": "^3.0.3",
|
||||
"@spectrum-css/card": "^3.0.3",
|
||||
"@spectrum-css/divider": "^1.0.3",
|
||||
|
@ -59,5 +59,8 @@
|
|||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-visualizer": "^5.5.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"loader-utils": "1.4.1"
|
||||
},
|
||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
let structureLookupMap = {}
|
||||
|
||||
const registerBlockComponent = (id, order, parentId, instance) => {
|
||||
// Ensure child array exists
|
||||
// Ensure child map exists
|
||||
if (!structureLookupMap[parentId]) {
|
||||
structureLookupMap[parentId] = {}
|
||||
}
|
||||
|
@ -18,6 +18,14 @@
|
|||
structureLookupMap[parentId][order] = instance
|
||||
}
|
||||
|
||||
const unregisterBlockComponent = (order, parentId) => {
|
||||
// Ensure child map exists
|
||||
if (!structureLookupMap[parentId]) {
|
||||
return
|
||||
}
|
||||
delete structureLookupMap[parentId][order]
|
||||
}
|
||||
|
||||
const eject = () => {
|
||||
// Start the new structure with the root component
|
||||
let definition = structureLookupMap[$component.id][0]
|
||||
|
@ -73,6 +81,7 @@
|
|||
// We register block components with their raw props so that we can eject
|
||||
// blocks later on
|
||||
registerComponent: registerBlockComponent,
|
||||
unregisterComponent: unregisterBlockComponent,
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { getContext, onDestroy } from "svelte"
|
||||
import { generate } from "shortid"
|
||||
import { builderStore } from "../stores/builder.js"
|
||||
import Component from "components/Component.svelte"
|
||||
|
@ -42,6 +42,12 @@
|
|||
block.registerComponent(id, order ?? 0, $component?.id, instance)
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if ($builderStore.inBuilder) {
|
||||
block.unregisterComponent(order ?? 0, $component?.id)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<Component {instance} isBlock>
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import BlockComponent from "../../BlockComponent.svelte"
|
||||
import Block from "../../Block.svelte"
|
||||
import Placeholder from "../Placeholder.svelte"
|
||||
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||
|
||||
export let actionType
|
||||
export let dataSource
|
||||
export let size
|
||||
export let disabled
|
||||
export let fields
|
||||
export let labelPosition
|
||||
export let title
|
||||
export let showSaveButton
|
||||
export let showDeleteButton
|
||||
export let rowId
|
||||
export let actionUrl
|
||||
|
||||
const { fetchDatasourceSchema } = getContext("sdk")
|
||||
const FieldTypeToComponentMap = {
|
||||
string: "stringfield",
|
||||
number: "numberfield",
|
||||
options: "optionsfield",
|
||||
array: "multifieldselect",
|
||||
boolean: "booleanfield",
|
||||
longform: "longformfield",
|
||||
datetime: "datetimefield",
|
||||
attachment: "attachmentfield",
|
||||
link: "relationshipfield",
|
||||
json: "jsonfield",
|
||||
barcodeqr: "codescanner",
|
||||
}
|
||||
|
||||
let schema
|
||||
let formId
|
||||
let providerId
|
||||
let repeaterId
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: onSave = [
|
||||
{
|
||||
"##eventHandlerType": "Save Row",
|
||||
parameters: {
|
||||
providerId: formId,
|
||||
tableId: dataSource?.tableId,
|
||||
},
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Screen Modal",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Side Panel",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Navigate To",
|
||||
parameters: {
|
||||
url: actionUrl,
|
||||
},
|
||||
},
|
||||
]
|
||||
$: onDelete = [
|
||||
{
|
||||
"##eventHandlerType": "Delete Row",
|
||||
parameters: {
|
||||
confirm: true,
|
||||
tableId: dataSource?.tableId,
|
||||
rowId: `{{ ${safe(repeaterId)}.${safe("_id")} }}`,
|
||||
revId: `{{ ${safe(repeaterId)}.${safe("_rev")} }}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Screen Modal",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Side Panel",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Navigate To",
|
||||
parameters: {
|
||||
url: actionUrl,
|
||||
},
|
||||
},
|
||||
]
|
||||
$: filter = [
|
||||
{
|
||||
field: "_id",
|
||||
operator: "equal",
|
||||
type: "string",
|
||||
value: !rowId ? `{{ ${safe("url")}.${safe("id")} }}` : rowId,
|
||||
valueType: "Binding",
|
||||
},
|
||||
]
|
||||
|
||||
$: dataProvider = `{{ literal ${safe(providerId)} }}`
|
||||
$: renderDeleteButton = showDeleteButton && actionType === "Update"
|
||||
$: renderSaveButton = showSaveButton && actionType !== "View"
|
||||
$: renderButtons = renderDeleteButton || renderSaveButton
|
||||
$: renderHeader = renderButtons || title
|
||||
|
||||
const fetchSchema = async () => {
|
||||
schema = (await fetchDatasourceSchema(dataSource)) || {}
|
||||
}
|
||||
|
||||
const getComponentForField = field => {
|
||||
if (!field || !schema?.[field]) {
|
||||
return null
|
||||
}
|
||||
const type = schema[field].type
|
||||
return FieldTypeToComponentMap[type]
|
||||
}
|
||||
</script>
|
||||
|
||||
<Block>
|
||||
{#if fields?.length}
|
||||
<BlockComponent
|
||||
type="dataprovider"
|
||||
context="provider"
|
||||
bind:id={providerId}
|
||||
props={{
|
||||
dataSource,
|
||||
filter,
|
||||
limit: 1,
|
||||
paginate: false,
|
||||
}}
|
||||
>
|
||||
<BlockComponent
|
||||
type="repeater"
|
||||
context="repeater"
|
||||
bind:id={repeaterId}
|
||||
props={{
|
||||
dataProvider,
|
||||
noRowsMessage: "We couldn't find a row to display",
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
}}
|
||||
>
|
||||
<BlockComponent
|
||||
type="form"
|
||||
props={{
|
||||
actionType: actionType === "Create" ? "Create" : "Update",
|
||||
dataSource,
|
||||
size,
|
||||
disabled: disabled || actionType === "View",
|
||||
}}
|
||||
styles={{
|
||||
normal: {
|
||||
width: "600px",
|
||||
},
|
||||
}}
|
||||
context="form"
|
||||
bind:id={formId}
|
||||
>
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "column",
|
||||
hAlign: "stretch",
|
||||
vAlign: "top",
|
||||
gap: "M",
|
||||
}}
|
||||
>
|
||||
{#if renderHeader}
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "center",
|
||||
gap: "M",
|
||||
wrap: true,
|
||||
}}
|
||||
order={0}
|
||||
>
|
||||
<BlockComponent
|
||||
type="heading"
|
||||
props={{ text: title || "" }}
|
||||
order={0}
|
||||
/>
|
||||
{#if renderButtons}
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "center",
|
||||
gap: "M",
|
||||
wrap: true,
|
||||
}}
|
||||
order={1}
|
||||
>
|
||||
{#if renderDeleteButton}
|
||||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Delete",
|
||||
onClick: onDelete,
|
||||
quiet: true,
|
||||
type: "secondary",
|
||||
}}
|
||||
order={0}
|
||||
/>
|
||||
{/if}
|
||||
{#if renderSaveButton}
|
||||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Save",
|
||||
onClick: onSave,
|
||||
type: "cta",
|
||||
}}
|
||||
order={1}
|
||||
/>
|
||||
{/if}
|
||||
</BlockComponent>
|
||||
{/if}
|
||||
</BlockComponent>
|
||||
{/if}
|
||||
<BlockComponent
|
||||
type="fieldgroup"
|
||||
props={{ labelPosition }}
|
||||
order={1}
|
||||
>
|
||||
{#each fields as field, idx}
|
||||
{#if getComponentForField(field)}
|
||||
<BlockComponent
|
||||
type={getComponentForField(field)}
|
||||
props={{
|
||||
field,
|
||||
label: field,
|
||||
placeholder: field,
|
||||
disabled,
|
||||
}}
|
||||
order={idx}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
{:else}
|
||||
<Placeholder
|
||||
text="Choose your table and add some fields to your form to get started"
|
||||
/>
|
||||
{/if}
|
||||
</Block>
|
|
@ -0,0 +1,101 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import BlockComponent from "components/BlockComponent.svelte"
|
||||
import Block from "components/Block.svelte"
|
||||
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||
import InnerFormBlock from "./InnerFormBlock.svelte"
|
||||
|
||||
export let actionType
|
||||
export let dataSource
|
||||
export let size
|
||||
export let disabled
|
||||
export let fields
|
||||
export let labelPosition
|
||||
export let title
|
||||
export let showSaveButton
|
||||
export let showDeleteButton
|
||||
export let rowId
|
||||
export let actionUrl
|
||||
|
||||
const { fetchDatasourceSchema } = getContext("sdk")
|
||||
|
||||
let schema
|
||||
let providerId
|
||||
let repeaterId
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: dataProvider = `{{ literal ${safe(providerId)} }}`
|
||||
$: filter = [
|
||||
{
|
||||
field: "_id",
|
||||
operator: "equal",
|
||||
type: "string",
|
||||
value: !rowId ? `{{ ${safe("url")}.${safe("id")} }}` : rowId,
|
||||
valueType: "Binding",
|
||||
},
|
||||
]
|
||||
// We could simply spread $$props into the inner form and append our
|
||||
// additions, but that would create svelte warnings about unused props and
|
||||
// make maintenance in future more confusing as we typically always have a
|
||||
// proper mapping of schema settings to component exports, without having to
|
||||
// search multiple files
|
||||
$: innerProps = {
|
||||
dataSource,
|
||||
actionUrl,
|
||||
actionType,
|
||||
size,
|
||||
disabled,
|
||||
fields,
|
||||
labelPosition,
|
||||
title,
|
||||
showSaveButton,
|
||||
showDeleteButton,
|
||||
schema,
|
||||
repeaterId,
|
||||
}
|
||||
|
||||
const fetchSchema = async () => {
|
||||
schema = (await fetchDatasourceSchema(dataSource)) || {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Block>
|
||||
{#if actionType === "Create"}
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "column",
|
||||
hAlign: "left",
|
||||
vAlign: "stretch",
|
||||
}}
|
||||
>
|
||||
<InnerFormBlock {...innerProps} />
|
||||
</BlockComponent>
|
||||
{:else}
|
||||
<BlockComponent
|
||||
type="dataprovider"
|
||||
context="provider"
|
||||
bind:id={providerId}
|
||||
props={{
|
||||
dataSource,
|
||||
filter,
|
||||
limit: 1,
|
||||
paginate: false,
|
||||
}}
|
||||
>
|
||||
<BlockComponent
|
||||
type="repeater"
|
||||
context="repeater"
|
||||
bind:id={repeaterId}
|
||||
props={{
|
||||
dataProvider,
|
||||
noRowsMessage: "We couldn't find a row to display",
|
||||
direction: "column",
|
||||
hAlign: "center",
|
||||
}}
|
||||
>
|
||||
<InnerFormBlock {...innerProps} />
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
{/if}
|
||||
</Block>
|
|
@ -0,0 +1,200 @@
|
|||
<script>
|
||||
import BlockComponent from "components/BlockComponent.svelte"
|
||||
import Placeholder from "components/app/Placeholder.svelte"
|
||||
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||
|
||||
export let dataSource
|
||||
export let actionUrl
|
||||
export let actionType
|
||||
export let size
|
||||
export let disabled
|
||||
export let fields
|
||||
export let labelPosition
|
||||
export let title
|
||||
export let showSaveButton
|
||||
export let showDeleteButton
|
||||
export let schema
|
||||
export let repeaterId
|
||||
|
||||
const FieldTypeToComponentMap = {
|
||||
string: "stringfield",
|
||||
number: "numberfield",
|
||||
options: "optionsfield",
|
||||
array: "multifieldselect",
|
||||
boolean: "booleanfield",
|
||||
longform: "longformfield",
|
||||
datetime: "datetimefield",
|
||||
attachment: "attachmentfield",
|
||||
link: "relationshipfield",
|
||||
json: "jsonfield",
|
||||
barcodeqr: "codescanner",
|
||||
}
|
||||
|
||||
let formId
|
||||
|
||||
$: onSave = [
|
||||
{
|
||||
"##eventHandlerType": "Save Row",
|
||||
parameters: {
|
||||
providerId: formId,
|
||||
tableId: dataSource?.tableId,
|
||||
},
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Screen Modal",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Side Panel",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Navigate To",
|
||||
parameters: {
|
||||
url: actionUrl,
|
||||
},
|
||||
},
|
||||
]
|
||||
$: onDelete = [
|
||||
{
|
||||
"##eventHandlerType": "Delete Row",
|
||||
parameters: {
|
||||
confirm: true,
|
||||
tableId: dataSource?.tableId,
|
||||
rowId: `{{ ${safe(repeaterId)}.${safe("_id")} }}`,
|
||||
revId: `{{ ${safe(repeaterId)}.${safe("_rev")} }}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Screen Modal",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Close Side Panel",
|
||||
},
|
||||
{
|
||||
"##eventHandlerType": "Navigate To",
|
||||
parameters: {
|
||||
url: actionUrl,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
$: renderDeleteButton = showDeleteButton && actionType === "Update"
|
||||
$: renderSaveButton = showSaveButton && actionType !== "View"
|
||||
$: renderButtons = renderDeleteButton || renderSaveButton
|
||||
$: renderHeader = renderButtons || title
|
||||
|
||||
const getComponentForField = field => {
|
||||
if (!field || !schema?.[field]) {
|
||||
return null
|
||||
}
|
||||
const type = schema[field].type
|
||||
return FieldTypeToComponentMap[type]
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if fields?.length}
|
||||
<BlockComponent
|
||||
type="form"
|
||||
props={{
|
||||
actionType: actionType === "Create" ? "Create" : "Update",
|
||||
dataSource,
|
||||
size,
|
||||
disabled: disabled || actionType === "View",
|
||||
}}
|
||||
styles={{
|
||||
normal: {
|
||||
width: "600px",
|
||||
"margin-left": "auto",
|
||||
"margin-right": "auto",
|
||||
},
|
||||
}}
|
||||
context="form"
|
||||
bind:id={formId}
|
||||
>
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "column",
|
||||
hAlign: "stretch",
|
||||
vAlign: "top",
|
||||
gap: "M",
|
||||
}}
|
||||
>
|
||||
{#if renderHeader}
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "center",
|
||||
gap: "M",
|
||||
wrap: true,
|
||||
}}
|
||||
order={0}
|
||||
>
|
||||
<BlockComponent
|
||||
type="heading"
|
||||
props={{ text: title || "" }}
|
||||
order={0}
|
||||
/>
|
||||
{#if renderButtons}
|
||||
<BlockComponent
|
||||
type="container"
|
||||
props={{
|
||||
direction: "row",
|
||||
hAlign: "stretch",
|
||||
vAlign: "center",
|
||||
gap: "M",
|
||||
wrap: true,
|
||||
}}
|
||||
order={1}
|
||||
>
|
||||
{#if renderDeleteButton}
|
||||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Delete",
|
||||
onClick: onDelete,
|
||||
quiet: true,
|
||||
type: "secondary",
|
||||
}}
|
||||
order={0}
|
||||
/>
|
||||
{/if}
|
||||
{#if renderSaveButton}
|
||||
<BlockComponent
|
||||
type="button"
|
||||
props={{
|
||||
text: "Save",
|
||||
onClick: onSave,
|
||||
type: "cta",
|
||||
}}
|
||||
order={1}
|
||||
/>
|
||||
{/if}
|
||||
</BlockComponent>
|
||||
{/if}
|
||||
</BlockComponent>
|
||||
{/if}
|
||||
<BlockComponent type="fieldgroup" props={{ labelPosition }} order={1}>
|
||||
{#each fields as field, idx}
|
||||
{#if getComponentForField(field)}
|
||||
<BlockComponent
|
||||
type={getComponentForField(field)}
|
||||
props={{
|
||||
field,
|
||||
label: field,
|
||||
placeholder: field,
|
||||
disabled,
|
||||
}}
|
||||
order={idx}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
</BlockComponent>
|
||||
{:else}
|
||||
<Placeholder
|
||||
text="Choose your table and add some fields to your form to get started"
|
||||
/>
|
||||
{/if}
|
|
@ -1,6 +1,6 @@
|
|||
export { default as tableblock } from "./TableBlock.svelte"
|
||||
export { default as cardsblock } from "./CardsBlock.svelte"
|
||||
export { default as repeaterblock } from "./RepeaterBlock.svelte"
|
||||
export { default as formblock } from "./FormBlock.svelte"
|
||||
export { default as formblock } from "./form/FormBlock.svelte"
|
||||
export { default as chartblock } from "./ChartBlock.svelte"
|
||||
export { default as rowexplorer } from "./RowExplorer.svelte"
|
||||
|
|
|
@ -61,7 +61,10 @@
|
|||
clonedSchema = schema
|
||||
} else {
|
||||
allowedFields?.forEach(field => {
|
||||
if (schema[field]) {
|
||||
if (schema[field.name]) {
|
||||
clonedSchema[field.name] = schema[field.name]
|
||||
clonedSchema[field.name].displayName = field.displayName
|
||||
} else if (schema[field]) {
|
||||
clonedSchema[field] = schema[field]
|
||||
}
|
||||
})
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
!BannedTypes.includes(field.type) ||
|
||||
(field.type === "formula" && field.formulaType === "static")
|
||||
)
|
||||
.map(field => field.name)
|
||||
.map(field => ({
|
||||
label: field.displayName || field.name,
|
||||
value: field.name,
|
||||
}))
|
||||
|
||||
const addFilter = () => {
|
||||
filters = [
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
export let label
|
||||
export let placeholder
|
||||
export let disabled = false
|
||||
export let enableTime = false
|
||||
export let enableTime = true
|
||||
export let timeOnly = false
|
||||
export let time24hr = false
|
||||
export let ignoreTimezones = false
|
||||
|
|
|
@ -16,13 +16,16 @@
|
|||
let measured = false
|
||||
|
||||
$: definition = $componentStore.selectedComponentDefinition
|
||||
$: showBar = definition?.showSettingsBar && !$dndIsDragging
|
||||
$: showBar =
|
||||
definition?.showSettingsBar !== false && !$dndIsDragging && definition
|
||||
$: {
|
||||
if (!showBar) {
|
||||
measured = false
|
||||
}
|
||||
}
|
||||
$: settings = getBarSettings(definition)
|
||||
$: isScreen =
|
||||
$builderStore.selectedComponentId === $builderStore.screen?.props?._id
|
||||
|
||||
const getBarSettings = definition => {
|
||||
let allSettings = []
|
||||
|
@ -152,26 +155,30 @@
|
|||
{:else if setting.type === "color"}
|
||||
<SettingsColorPicker prop={setting.key} />
|
||||
{/if}
|
||||
{#if setting.barSeparator !== false}
|
||||
{#if setting.barSeparator !== false && (settings.length != idx + 1 || !isScreen)}
|
||||
<div class="divider" />
|
||||
{/if}
|
||||
{/each}
|
||||
<SettingsButton
|
||||
icon="Duplicate"
|
||||
on:click={() => {
|
||||
builderStore.actions.duplicateComponent(
|
||||
$builderStore.selectedComponentId
|
||||
)
|
||||
}}
|
||||
title="Duplicate component"
|
||||
/>
|
||||
<SettingsButton
|
||||
icon="Delete"
|
||||
on:click={() => {
|
||||
builderStore.actions.deleteComponent($builderStore.selectedComponentId)
|
||||
}}
|
||||
title="Delete component"
|
||||
/>
|
||||
{#if !isScreen}
|
||||
<SettingsButton
|
||||
icon="Duplicate"
|
||||
on:click={() => {
|
||||
builderStore.actions.duplicateComponent(
|
||||
$builderStore.selectedComponentId
|
||||
)
|
||||
}}
|
||||
title="Duplicate component"
|
||||
/>
|
||||
<SettingsButton
|
||||
icon="Delete"
|
||||
on:click={() => {
|
||||
builderStore.actions.deleteComponent(
|
||||
$builderStore.selectedComponentId
|
||||
)
|
||||
}}
|
||||
title="Delete component"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "@budibase/frontend-core",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase frontend core libraries used in builder and client",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.1.22-alpha.8",
|
||||
"@budibase/bbui": "2.1.32-alpha.3",
|
||||
"lodash": "^4.17.21",
|
||||
"svelte": "^3.46.2"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/sdk",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase Public API SDK",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/server",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase Web Server",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -43,11 +43,11 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@apidevtools/swagger-parser": "10.0.3",
|
||||
"@budibase/backend-core": "2.1.22-alpha.8",
|
||||
"@budibase/client": "2.1.22-alpha.8",
|
||||
"@budibase/pro": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/types": "2.1.22-alpha.8",
|
||||
"@budibase/backend-core": "2.1.32-alpha.3",
|
||||
"@budibase/client": "2.1.32-alpha.3",
|
||||
"@budibase/pro": "2.1.32-alpha.3",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@budibase/types": "2.1.32-alpha.3",
|
||||
"@bull-board/api": "3.7.0",
|
||||
"@bull-board/koa": "3.9.4",
|
||||
"@elastic/elasticsearch": "7.10.0",
|
||||
|
|
|
@ -25,8 +25,14 @@ import {
|
|||
migrations,
|
||||
} from "@budibase/backend-core"
|
||||
import { USERS_TABLE_SCHEMA } from "../../constants"
|
||||
import { buildDefaultDocs } from "../../db/defaultData/datasource_bb_default"
|
||||
|
||||
import { removeAppFromUserRoles } from "../../utilities/workerRequests"
|
||||
import { clientLibraryPath, stringToReadStream } from "../../utilities"
|
||||
import {
|
||||
clientLibraryPath,
|
||||
stringToReadStream,
|
||||
isQsTrue,
|
||||
} from "../../utilities"
|
||||
import { getLocksById } from "../../utilities/redis"
|
||||
import {
|
||||
updateClientLibrary,
|
||||
|
@ -117,7 +123,7 @@ const checkAppName = (
|
|||
}
|
||||
}
|
||||
|
||||
async function createInstance(template: any) {
|
||||
async function createInstance(template: any, includeSampleData: boolean) {
|
||||
const tenantId = tenancy.isMultiTenant() ? tenancy.getTenantId() : null
|
||||
const baseAppId = generateAppID(tenantId)
|
||||
const appId = generateDevAppID(baseAppId)
|
||||
|
@ -149,11 +155,23 @@ async function createInstance(template: any) {
|
|||
} else {
|
||||
// create the users table
|
||||
await db.put(USERS_TABLE_SCHEMA)
|
||||
|
||||
if (includeSampleData) {
|
||||
// create ootb stock db
|
||||
await addDefaultTables(db)
|
||||
}
|
||||
}
|
||||
|
||||
return { _id: appId }
|
||||
}
|
||||
|
||||
const addDefaultTables = async (db: any) => {
|
||||
const defaultDbDocs = buildDefaultDocs()
|
||||
|
||||
// add in the default db data docs - tables, datasource, rows and links
|
||||
await db.bulkDocs([...defaultDbDocs])
|
||||
}
|
||||
|
||||
export const fetch = async (ctx: any) => {
|
||||
const dev = ctx.query && ctx.query.status === AppStatus.DEV
|
||||
const all = ctx.query && ctx.query.status === AppStatus.ALL
|
||||
|
@ -234,7 +252,8 @@ const performAppCreate = async (ctx: any) => {
|
|||
if (ctx.request.files && ctx.request.files.templateFile) {
|
||||
instanceConfig.file = ctx.request.files.templateFile
|
||||
}
|
||||
const instance = await createInstance(instanceConfig)
|
||||
const includeSampleData = isQsTrue(ctx.request.body.sampleData)
|
||||
const instance = await createInstance(instanceConfig, includeSampleData)
|
||||
const appId = instance._id
|
||||
const db = context.getAppDB()
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@ const {
|
|||
BudibaseInternalDB,
|
||||
getTableParams,
|
||||
} = require("../../db/utils")
|
||||
const { destroy: tableDestroy } = require("./table/internal")
|
||||
const { BuildSchemaErrors, InvalidColumns } = require("../../constants")
|
||||
const { getIntegration } = require("../../integrations")
|
||||
const { getDatasourceAndQuery } = require("./row/utils")
|
||||
const { invalidateDynamicVariables } = require("../../threads/utils")
|
||||
const { getAppDB } = require("@budibase/backend-core/context")
|
||||
const { events } = require("@budibase/backend-core")
|
||||
const { db: dbCore } = require("@budibase/backend-core")
|
||||
|
||||
exports.fetch = async function (ctx) {
|
||||
// Get internal tables
|
||||
|
@ -21,11 +23,16 @@ exports.fetch = async function (ctx) {
|
|||
include_docs: true,
|
||||
})
|
||||
)
|
||||
const internal = internalTables.rows.map(row => row.doc)
|
||||
|
||||
const internal = internalTables.rows.reduce((acc, row) => {
|
||||
const sourceId = row.doc.sourceId || "bb_internal"
|
||||
acc[sourceId] = acc[sourceId] || []
|
||||
acc[sourceId].push(row.doc)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const bbInternalDb = {
|
||||
...BudibaseInternalDB,
|
||||
entities: internal,
|
||||
}
|
||||
|
||||
// Get external datasources
|
||||
|
@ -37,11 +44,17 @@ exports.fetch = async function (ctx) {
|
|||
)
|
||||
).rows.map(row => row.doc)
|
||||
|
||||
for (let datasource of datasources) {
|
||||
const allDatasources = [bbInternalDb, ...datasources]
|
||||
|
||||
for (let datasource of allDatasources) {
|
||||
if (datasource.config && datasource.config.auth) {
|
||||
// strip secrets from response so they don't show in the network request
|
||||
delete datasource.config.auth
|
||||
}
|
||||
|
||||
if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {
|
||||
datasource.entities = internal[datasource._id]
|
||||
}
|
||||
}
|
||||
|
||||
ctx.body = [bbInternalDb, ...datasources]
|
||||
|
@ -196,20 +209,53 @@ exports.save = async function (ctx) {
|
|||
ctx.body = response
|
||||
}
|
||||
|
||||
const destroyInternalTablesBySourceId = async datasourceId => {
|
||||
const db = getAppDB()
|
||||
|
||||
// Get all internal tables
|
||||
const internalTables = await db.allDocs(
|
||||
getTableParams(null, {
|
||||
include_docs: true,
|
||||
})
|
||||
)
|
||||
|
||||
// Filter by datasource and return the docs.
|
||||
const datasourceTableDocs = internalTables.rows.reduce((acc, table) => {
|
||||
if (table.doc.sourceId == datasourceId) {
|
||||
acc.push(table.doc)
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
// Destroy the tables.
|
||||
for (const table of datasourceTableDocs) {
|
||||
await tableDestroy({
|
||||
params: {
|
||||
tableId: table._id,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.destroy = async function (ctx) {
|
||||
const db = getAppDB()
|
||||
const datasourceId = ctx.params.datasourceId
|
||||
|
||||
const datasource = await db.get(datasourceId)
|
||||
// Delete all queries for the datasource
|
||||
const queries = await db.allDocs(getQueryParams(datasourceId, null))
|
||||
await db.bulkDocs(
|
||||
queries.rows.map(row => ({
|
||||
_id: row.id,
|
||||
_rev: row.value.rev,
|
||||
_deleted: true,
|
||||
}))
|
||||
)
|
||||
|
||||
if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {
|
||||
await destroyInternalTablesBySourceId(datasourceId)
|
||||
} else {
|
||||
const queries = await db.allDocs(getQueryParams(datasourceId, null))
|
||||
await db.bulkDocs(
|
||||
queries.rows.map(row => ({
|
||||
_id: row.id,
|
||||
_rev: row.value.rev,
|
||||
_deleted: true,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
// delete the datasource
|
||||
await db.remove(datasourceId, ctx.params.revId)
|
||||
|
|
|
@ -62,6 +62,7 @@ exports.updateRelatedFormula = async (table, enrichedRows) => {
|
|||
})
|
||||
)
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +125,6 @@ exports.finaliseRow = async (
|
|||
dynamic: false,
|
||||
contextRows: enrichedRow,
|
||||
})
|
||||
|
||||
// don't worry about rev, tables handle rev/lastID updates
|
||||
// if another row has been written since processing this will
|
||||
// handle the auto ID clash
|
||||
|
|
|
@ -2,7 +2,7 @@ import { updateLinks, EventType } from "../../../db/linkedRows"
|
|||
import { getRowParams, generateTableID } from "../../../db/utils"
|
||||
import { FieldTypes } from "../../../constants"
|
||||
import { TableSaveFunctions, hasTypeChanged, handleDataImport } from "./utils"
|
||||
const { getAppDB } = require("@budibase/backend-core/context")
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { isTest } from "../../../environment"
|
||||
import {
|
||||
cleanupAttachments,
|
||||
|
@ -35,7 +35,7 @@ function checkAutoColumns(table: Table, oldTable: Table) {
|
|||
}
|
||||
|
||||
export async function save(ctx: any) {
|
||||
const db = getAppDB()
|
||||
const db = context.getAppDB()
|
||||
const { dataImport, ...rest } = ctx.request.body
|
||||
let tableToSave = {
|
||||
type: "table",
|
||||
|
@ -138,19 +138,19 @@ export async function save(ctx: any) {
|
|||
}
|
||||
|
||||
export async function destroy(ctx: any) {
|
||||
const db = getAppDB()
|
||||
const db = context.getAppDB()
|
||||
const tableToDelete = await db.get(ctx.params.tableId)
|
||||
|
||||
// Delete all rows for that table
|
||||
const rows = await db.allDocs(
|
||||
const rowsData = await db.allDocs(
|
||||
getRowParams(ctx.params.tableId, null, {
|
||||
include_docs: true,
|
||||
})
|
||||
)
|
||||
await db.bulkDocs(
|
||||
rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
|
||||
rowsData.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
|
||||
)
|
||||
await quotas.removeRows(rows.rows.length, {
|
||||
await quotas.removeRows(rowsData.rows.length, {
|
||||
tableId: ctx.params.tableId,
|
||||
})
|
||||
|
||||
|
@ -161,7 +161,7 @@ export async function destroy(ctx: any) {
|
|||
})
|
||||
|
||||
// don't remove the table itself until very end
|
||||
await db.remove(tableToDelete)
|
||||
await db.remove(tableToDelete._id, tableToDelete._rev)
|
||||
|
||||
// remove table search index
|
||||
if (!isTest() || env.COUCH_DB_URL) {
|
||||
|
@ -179,7 +179,9 @@ export async function destroy(ctx: any) {
|
|||
oldTable: null,
|
||||
deletion: true,
|
||||
})
|
||||
await cleanupAttachments(tableToDelete, { rows })
|
||||
await cleanupAttachments(tableToDelete, {
|
||||
rows: rowsData.rows.map((row: any) => row.doc),
|
||||
})
|
||||
return tableToDelete
|
||||
}
|
||||
|
||||
|
|
|
@ -95,18 +95,7 @@ export function makeSureTableUpToDate(table: any, tableToSave: any) {
|
|||
return tableToSave
|
||||
}
|
||||
|
||||
export async function handleDataImport(user: any, table: any, dataImport: any) {
|
||||
if (!dataImport || !dataImport.csvString) {
|
||||
return table
|
||||
}
|
||||
|
||||
const db = getAppDB()
|
||||
// Populate the table with rows imported from CSV in a bulk update
|
||||
const data = await transform({
|
||||
...dataImport,
|
||||
existingTable: table,
|
||||
})
|
||||
|
||||
export function importToRows(data: any, table: any, user: any = {}) {
|
||||
let finalData: any = []
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let row = data[i]
|
||||
|
@ -136,6 +125,22 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
|
|||
|
||||
finalData.push(row)
|
||||
}
|
||||
return finalData
|
||||
}
|
||||
|
||||
export async function handleDataImport(user: any, table: any, dataImport: any) {
|
||||
if (!dataImport || !dataImport.csvString) {
|
||||
return table
|
||||
}
|
||||
|
||||
const db = getAppDB()
|
||||
// Populate the table with rows imported from CSV in a bulk update
|
||||
const data = await transform({
|
||||
...dataImport,
|
||||
existingTable: table,
|
||||
})
|
||||
|
||||
let finalData: any = importToRows(data, table, user)
|
||||
|
||||
await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {
|
||||
tableId: table._id,
|
||||
|
|
|
@ -0,0 +1,646 @@
|
|||
const {
|
||||
FieldTypes,
|
||||
AutoFieldSubTypes,
|
||||
RelationshipTypes,
|
||||
} = require("../../constants/index")
|
||||
const { importToRows } = require("../../api/controllers/table/utils")
|
||||
const { cloneDeep } = require("lodash/fp")
|
||||
const LinkDocument = require("../linkedRows/LinkDocument")
|
||||
const { inventoryImport } = require("./inventoryImport")
|
||||
const { employeeImport } = require("./employeeImport")
|
||||
const { jobsImport } = require("./jobsImport")
|
||||
const { expensesImport } = require("./expensesImport")
|
||||
const { db: dbCore } = require("@budibase/backend-core")
|
||||
|
||||
exports.DEFAULT_JOBS_TABLE_ID = "ta_bb_jobs"
|
||||
exports.DEFAULT_INVENTORY_TABLE_ID = "ta_bb_inventory"
|
||||
exports.DEFAULT_EXPENSES_TABLE_ID = "ta_bb_expenses"
|
||||
exports.DEFAULT_EMPLOYEE_TABLE_ID = "ta_bb_employee"
|
||||
exports.DEFAULT_BB_DATASOURCE_ID = "datasource_internal_bb_default"
|
||||
exports.DEFAULT_BB_DATASOURCE = {
|
||||
_id: this.DEFAULT_BB_DATASOURCE_ID,
|
||||
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
||||
name: "Sample Data",
|
||||
source: "BUDIBASE",
|
||||
config: {},
|
||||
}
|
||||
|
||||
const syncLastIds = (table, rowCount) => {
|
||||
Object.keys(table.schema).forEach(key => {
|
||||
const entry = table.schema[key]
|
||||
if (entry.autocolumn && entry.subtype == "autoID") {
|
||||
entry.lastID = rowCount
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const tableImport = (table, data) => {
|
||||
const cloneTable = cloneDeep(table)
|
||||
const rowDocs = importToRows(data, cloneTable)
|
||||
syncLastIds(cloneTable, rowDocs.length)
|
||||
return { rows: rowDocs, table: cloneTable }
|
||||
}
|
||||
|
||||
// AUTO COLUMNS
|
||||
const AUTO_COLUMNS = {
|
||||
"Created At": {
|
||||
name: "Created At",
|
||||
type: FieldTypes.DATETIME,
|
||||
subtype: AutoFieldSubTypes.CREATED_AT,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Updated At": {
|
||||
name: "Updated At",
|
||||
type: FieldTypes.DATETIME,
|
||||
subtype: AutoFieldSubTypes.UPDATED_AT,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
exports.DEFAULT_INVENTORY_TABLE_SCHEMA = {
|
||||
_id: this.DEFAULT_INVENTORY_TABLE_ID,
|
||||
type: "internal",
|
||||
views: {},
|
||||
sourceId: exports.DEFAULT_BB_DATASOURCE_ID,
|
||||
primaryDisplay: "Item Name",
|
||||
name: "Inventory",
|
||||
schema: {
|
||||
"Item ID": {
|
||||
name: "Item ID",
|
||||
type: FieldTypes.NUMBER,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Item Name": {
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {
|
||||
maximum: null,
|
||||
},
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
},
|
||||
name: "Item Name",
|
||||
},
|
||||
"Item Tags": {
|
||||
type: FieldTypes.ARRAY,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
inclusion: ["Electrical", "Material", "Vehicle", "Office", "Tools"],
|
||||
},
|
||||
name: "Item Tags",
|
||||
sortable: false,
|
||||
},
|
||||
Notes: {
|
||||
type: FieldTypes.LONGFORM,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
name: "Notes",
|
||||
useRichText: null,
|
||||
},
|
||||
Status: {
|
||||
type: FieldTypes.ARRAY,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
inclusion: ["Available", "Repair", "Broken"],
|
||||
},
|
||||
name: "Status",
|
||||
sortable: false,
|
||||
},
|
||||
SKU: {
|
||||
type: FieldTypes.BARCODEQR,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
name: "SKU",
|
||||
},
|
||||
"Purchase Date": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Purchase Date",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
"Purchase Price": {
|
||||
type: FieldTypes.NUMBER,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: null,
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
name: "Purchase Price",
|
||||
},
|
||||
...AUTO_COLUMNS,
|
||||
},
|
||||
}
|
||||
|
||||
exports.DEFAULT_EMPLOYEE_TABLE_SCHEMA = {
|
||||
_id: this.DEFAULT_EMPLOYEE_TABLE_ID,
|
||||
type: "internal",
|
||||
views: {},
|
||||
name: "Employees",
|
||||
sourceId: exports.DEFAULT_BB_DATASOURCE_ID,
|
||||
primaryDisplay: "First Name",
|
||||
schema: {
|
||||
"First Name": {
|
||||
name: "First Name",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
"Last Name": {
|
||||
name: "Last Name",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
Email: {
|
||||
name: "Email",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
Address: {
|
||||
name: "Address",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
City: {
|
||||
name: "City",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
Postcode: {
|
||||
name: "Postcode",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
Phone: {
|
||||
name: "Phone",
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
},
|
||||
"EMPLOYEE ID": {
|
||||
name: "EMPLOYEE ID",
|
||||
type: FieldTypes.NUMBER,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Employee Level": {
|
||||
type: FieldTypes.ARRAY,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: false,
|
||||
inclusion: ["Manager", "Junior", "Senior", "Apprentice", "Contractor"],
|
||||
},
|
||||
name: "Employee Level",
|
||||
sortable: false,
|
||||
},
|
||||
"Badge Photo": {
|
||||
type: "attachment",
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: false,
|
||||
},
|
||||
name: "Badge Photo",
|
||||
sortable: false,
|
||||
},
|
||||
Jobs: {
|
||||
type: FieldTypes.LINK,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: false,
|
||||
},
|
||||
fieldName: "Assigned",
|
||||
name: "Jobs",
|
||||
relationshipType: RelationshipTypes.MANY_TO_MANY,
|
||||
tableId: this.DEFAULT_JOBS_TABLE_ID,
|
||||
},
|
||||
"Start Date": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Start Date",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
"End Date": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "End Date",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
...AUTO_COLUMNS,
|
||||
},
|
||||
}
|
||||
|
||||
exports.DEFAULT_JOBS_TABLE_SCHEMA = {
|
||||
_id: this.DEFAULT_JOBS_TABLE_ID,
|
||||
type: "internal",
|
||||
name: "Jobs",
|
||||
sourceId: exports.DEFAULT_BB_DATASOURCE_ID,
|
||||
primaryDisplay: "Job ID",
|
||||
schema: {
|
||||
"Job ID": {
|
||||
name: "Job ID",
|
||||
type: FieldTypes.NUMBER,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Quote Date": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Quote Date",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
"Quote Price": {
|
||||
type: FieldTypes.NUMBER,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
name: "Quote Price",
|
||||
},
|
||||
"Works Start": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Works Start",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
Address: {
|
||||
type: FieldTypes.LONGFORM,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
name: "Address",
|
||||
useRichText: null,
|
||||
},
|
||||
"Customer Name": {
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {
|
||||
maximum: null,
|
||||
},
|
||||
presence: false,
|
||||
},
|
||||
name: "Customer Name",
|
||||
},
|
||||
Notes: {
|
||||
type: FieldTypes.LONGFORM,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
name: "Notes",
|
||||
useRichText: null,
|
||||
},
|
||||
"Customer Phone": {
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {
|
||||
maximum: null,
|
||||
},
|
||||
presence: false,
|
||||
},
|
||||
name: "Customer Phone",
|
||||
},
|
||||
"Customer Email": {
|
||||
type: FieldTypes.STRING,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {
|
||||
maximum: null,
|
||||
},
|
||||
presence: false,
|
||||
},
|
||||
name: "Customer Email",
|
||||
},
|
||||
Assigned: {
|
||||
name: "Assigned",
|
||||
type: FieldTypes.LINK,
|
||||
tableId: this.DEFAULT_EMPLOYEE_TABLE_ID,
|
||||
fieldName: "Jobs",
|
||||
relationshipType: RelationshipTypes.MANY_TO_MANY,
|
||||
// sortable: true,
|
||||
},
|
||||
"Works End": {
|
||||
type: "datetime",
|
||||
constraints: {
|
||||
type: "string",
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Works End",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
"Updated Price": {
|
||||
type: "number",
|
||||
constraints: {
|
||||
type: "number",
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
name: "Updated Price",
|
||||
},
|
||||
...AUTO_COLUMNS,
|
||||
},
|
||||
}
|
||||
|
||||
exports.DEFAULT_EXPENSES_TABLE_SCHEMA = {
|
||||
_id: this.DEFAULT_EXPENSES_TABLE_ID,
|
||||
type: "internal",
|
||||
views: {},
|
||||
name: "Expenses",
|
||||
sourceId: exports.DEFAULT_BB_DATASOURCE_ID,
|
||||
primaryDisplay: "Expense ID",
|
||||
schema: {
|
||||
"Expense ID": {
|
||||
name: "Expense ID",
|
||||
type: FieldTypes.NUMBER,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
icon: "ri-magic-line",
|
||||
autocolumn: true,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: false,
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
"Expense Tags": {
|
||||
type: FieldTypes.ARRAY,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
inclusion: [
|
||||
"Fuel",
|
||||
"Food",
|
||||
"Materials",
|
||||
"Repair",
|
||||
"Equipment",
|
||||
"Fees",
|
||||
"Service",
|
||||
"Office",
|
||||
"Other",
|
||||
],
|
||||
},
|
||||
name: "Expense Tags",
|
||||
sortable: false,
|
||||
},
|
||||
Cost: {
|
||||
type: FieldTypes.NUMBER,
|
||||
constraints: {
|
||||
type: FieldTypes.NUMBER,
|
||||
presence: {
|
||||
allowEmpty: false,
|
||||
},
|
||||
numericality: {
|
||||
greaterThanOrEqualTo: "",
|
||||
lessThanOrEqualTo: "",
|
||||
},
|
||||
},
|
||||
name: "Cost",
|
||||
},
|
||||
Notes: {
|
||||
type: FieldTypes.LONGFORM,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
},
|
||||
name: "Notes",
|
||||
useRichText: null,
|
||||
},
|
||||
"Payment Due": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Payment Due",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
"Date Paid": {
|
||||
type: FieldTypes.DATETIME,
|
||||
constraints: {
|
||||
type: FieldTypes.STRING,
|
||||
length: {},
|
||||
presence: false,
|
||||
datetime: {
|
||||
latest: "",
|
||||
earliest: "",
|
||||
},
|
||||
},
|
||||
name: "Date Paid",
|
||||
ignoreTimezones: true,
|
||||
},
|
||||
Attachment: {
|
||||
type: FieldTypes.ATTACHMENT,
|
||||
constraints: {
|
||||
type: FieldTypes.ARRAY,
|
||||
presence: false,
|
||||
},
|
||||
name: "Attachment",
|
||||
sortable: false,
|
||||
},
|
||||
...AUTO_COLUMNS,
|
||||
},
|
||||
}
|
||||
|
||||
exports.buildDefaultDocs = () => {
|
||||
const inventoryData = tableImport(
|
||||
this.DEFAULT_INVENTORY_TABLE_SCHEMA,
|
||||
inventoryImport
|
||||
)
|
||||
|
||||
const employeeData = tableImport(
|
||||
this.DEFAULT_EMPLOYEE_TABLE_SCHEMA,
|
||||
employeeImport
|
||||
)
|
||||
|
||||
const jobData = tableImport(this.DEFAULT_JOBS_TABLE_SCHEMA, jobsImport)
|
||||
|
||||
const expensesData = tableImport(
|
||||
this.DEFAULT_EXPENSES_TABLE_SCHEMA,
|
||||
expensesImport
|
||||
)
|
||||
|
||||
// Build one link doc for each employee/job
|
||||
const jobEmployeeLinks = employeeData.rows.map((employee, index) => {
|
||||
return new LinkDocument(
|
||||
employeeData.table._id,
|
||||
"Jobs",
|
||||
employeeData.rows[index]._id,
|
||||
jobData.table._id,
|
||||
"Assigned",
|
||||
jobData.rows[index]._id
|
||||
)
|
||||
})
|
||||
|
||||
return [
|
||||
this.DEFAULT_BB_DATASOURCE,
|
||||
inventoryData.table,
|
||||
employeeData.table,
|
||||
jobData.table,
|
||||
expensesData.table,
|
||||
...inventoryData.rows,
|
||||
...employeeData.rows,
|
||||
...jobData.rows,
|
||||
...expensesData.rows,
|
||||
...jobEmployeeLinks,
|
||||
]
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
exports.employeeImport = [
|
||||
{
|
||||
"First Name": "Julie",
|
||||
"Last Name": "Jimenez",
|
||||
Email: "julie.jimenez@example.com",
|
||||
Address: "4250 New Street",
|
||||
City: "Stevenage",
|
||||
Postcode: "EE32 3SE",
|
||||
Phone: "01754 13523",
|
||||
"Created At": "2022-11-10T17:56:18.353Z",
|
||||
"Updated At": "2022-11-10T18:32:15.298Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Senior"],
|
||||
"Start Date": "2015-02-12T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Mandy",
|
||||
"Last Name": "Clark",
|
||||
Email: "mandy.clark@example.com",
|
||||
Address: "8632 North Street",
|
||||
City: "Hereford",
|
||||
Postcode: "GT81 7DG",
|
||||
Phone: "016973 32814",
|
||||
"Created At": "2022-11-10T17:56:18.353Z",
|
||||
"Updated At": "2022-11-10T18:31:44.928Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Senior"],
|
||||
"Start Date": "2017-09-10T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Holly",
|
||||
"Last Name": "Carroll",
|
||||
Email: "holly.carroll@example.com",
|
||||
Address: "5976 Springfield Road",
|
||||
City: "Edinburgh",
|
||||
Postcode: "Y4 2LH",
|
||||
Phone: "016977 73053",
|
||||
"Created At": "2022-11-10T17:56:18.356Z",
|
||||
"Updated At": "2022-11-10T18:31:32.086Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Senior"],
|
||||
"Start Date": "2022-02-12T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Francis",
|
||||
"Last Name": "Castro",
|
||||
Email: "francis.castro@example.com",
|
||||
Address: "3970 High Street",
|
||||
City: "Wells",
|
||||
Postcode: "X12 6QA",
|
||||
Phone: "017684 23551",
|
||||
"Created At": "2022-11-10T17:56:18.357Z",
|
||||
"Updated At": "2022-11-10T18:31:16.976Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Apprentice"],
|
||||
"Start Date": "2021-03-10T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Richard",
|
||||
"Last Name": "Kelley",
|
||||
Email: "richard.kelley@example.com",
|
||||
Address: "2346 York Road",
|
||||
City: "Leicester",
|
||||
Postcode: "H7S 1AH",
|
||||
Phone: "013873 65167",
|
||||
"Created At": "2022-11-10T17:56:18.353Z",
|
||||
"Updated At": "2022-11-10T18:32:23.314Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Apprentice"],
|
||||
"Start Date": "2020-07-09T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Donald",
|
||||
"Last Name": "Lynch",
|
||||
Email: "donald.lynch@example.com",
|
||||
Address: "9642 New Road",
|
||||
City: "St Albans",
|
||||
Postcode: "V9A 1NP",
|
||||
Phone: "015242 46760",
|
||||
"Created At": "2022-11-10T17:56:18.352Z",
|
||||
"Updated At": "2022-11-10T18:30:38.439Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Junior"],
|
||||
"Start Date": "2018-04-13T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Maria",
|
||||
"Last Name": "Torres",
|
||||
Email: "maria.torres@example.com",
|
||||
Address: "9998 New Road",
|
||||
City: "Aberdeen",
|
||||
Postcode: "LP7 8JQ",
|
||||
Phone: "0101 472 3365",
|
||||
"Created At": "2022-11-10T17:56:18.353Z",
|
||||
"Updated At": "2022-11-10T18:31:37.748Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Manager"],
|
||||
"Start Date": "2016-05-22T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Suzy",
|
||||
"Last Name": "Ruiz",
|
||||
Email: "suzy.ruiz@example.com",
|
||||
Address: "4641 Victoria Street",
|
||||
City: "Armagh",
|
||||
Postcode: "MO4X 8BP",
|
||||
Phone: "015242 79977",
|
||||
"Created At": "2022-11-10T17:56:18.354Z",
|
||||
"Updated At": "2022-11-10T18:58:54.632Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Senior", "Manager"],
|
||||
"Start Date": "2019-05-01T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Patrick",
|
||||
"Last Name": "Garcia",
|
||||
Email: "patrick.garcia@example.com",
|
||||
Address: "7818 The Crescent",
|
||||
City: "Bath",
|
||||
Postcode: "OH5 3HE",
|
||||
Phone: "017683 02608",
|
||||
"Created At": "2022-11-10T17:56:18.353Z",
|
||||
"Updated At": "2022-11-10T18:31:06.820Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Apprentice"],
|
||||
"Start Date": "2014-08-30T12:00:00.000",
|
||||
},
|
||||
{
|
||||
"First Name": "Brayden",
|
||||
"Last Name": "Carpenter",
|
||||
Email: "brayden.carpenter@example.com",
|
||||
Address: "8755 The Drive",
|
||||
City: "Bradford",
|
||||
Postcode: "YH5 8RY",
|
||||
Phone: "015395 12426",
|
||||
"Created At": "2022-11-10T17:56:18.354Z",
|
||||
"Updated At": "2022-11-10T20:41:26.977Z",
|
||||
tableId: "ta_bb_employees",
|
||||
type: "row",
|
||||
"Employee Level": ["Contractor"],
|
||||
"Start Date": "2022-11-09T12:00:00.000",
|
||||
},
|
||||
]
|
|
@ -0,0 +1,114 @@
|
|||
exports.expensesImport = [
|
||||
{
|
||||
"Date Paid": "2022-11-12T12:00:00.000",
|
||||
"Payment Due": "2022-11-01T12:00:00.000",
|
||||
Cost: 117.4,
|
||||
Notes: "Two vans needed a top up",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T19:07:14.714Z",
|
||||
"Updated At": "2022-11-10T20:02:14.440Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Fuel", "Equipment"],
|
||||
},
|
||||
{
|
||||
"Date Paid": "2022-11-11T12:00:00.000",
|
||||
Cost: 217,
|
||||
Notes: "3 branded work bags and safety equipment for the new hires",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T19:10:35.459Z",
|
||||
"Updated At": "2022-11-10T19:10:35.459Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Materials"],
|
||||
},
|
||||
{
|
||||
"Date Paid": "2022-11-25T12:00:00.000",
|
||||
Cost: 420.68,
|
||||
Notes: "Monthly games night",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T19:20:08.264Z",
|
||||
"Updated At": "2022-11-10T19:27:14.141Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Food"],
|
||||
},
|
||||
{
|
||||
"Date Paid": "2022-11-24T12:00:00.000",
|
||||
"Payment Due": "2022-11-24T12:00:00.000",
|
||||
Cost: 45,
|
||||
Notes: "Work van",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T18:20:16.709Z",
|
||||
"Updated At": "2022-11-10T20:02:05.293Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Fuel", "Equipment"],
|
||||
},
|
||||
{
|
||||
"Payment Due": "2022-11-25T12:00:00.000",
|
||||
Cost: 200,
|
||||
Notes: "Accountant payroll management",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T19:06:16.014Z",
|
||||
"Updated At": "2022-11-10T19:06:16.014Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Fees", "Service"],
|
||||
},
|
||||
{
|
||||
"Payment Due": "2022-11-26T12:00:00.000",
|
||||
Cost: 28,
|
||||
Notes: "Circular saw needed a new plug",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T20:03:18.051Z",
|
||||
"Updated At": "2022-11-10T20:03:18.051Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Equipment", "Repair"],
|
||||
},
|
||||
{
|
||||
"Payment Due": "2022-11-11T12:00:00.000",
|
||||
Cost: 131.75,
|
||||
Notes: "Solicitor contract reviews for employees",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T18:56:16.111Z",
|
||||
"Updated At": "2022-11-10T19:20:58.681Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Fees", "Service"],
|
||||
},
|
||||
{
|
||||
Cost: 2500,
|
||||
Notes: "New Laptop for the office. ",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T18:04:11.401Z",
|
||||
"Updated At": "2022-11-10T20:08:16.459Z",
|
||||
type: "row",
|
||||
"Date Paid": "2022-11-09T12:00:00.000",
|
||||
"Expense Tags": ["Equipment"],
|
||||
},
|
||||
{
|
||||
"Date Paid": "2022-10-25T12:00:00.000",
|
||||
Cost: 275,
|
||||
Notes: "Accountant payroll. Added new hire",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T20:01:31.783Z",
|
||||
"Updated At": "2022-11-10T20:01:31.783Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Fees", "Service"],
|
||||
},
|
||||
{
|
||||
"Payment Due": "2022-11-19T12:00:00.000",
|
||||
Cost: 250,
|
||||
Notes: "200 new branded pens and 40 beanie hats. ",
|
||||
Attachment: [],
|
||||
tableId: "ta_bb_expenses",
|
||||
"Created At": "2022-11-10T19:09:08.074Z",
|
||||
"Updated At": "2022-11-10T19:09:08.074Z",
|
||||
type: "row",
|
||||
"Expense Tags": ["Service"],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,106 @@
|
|||
exports.inventoryImport = [
|
||||
{
|
||||
Status: ["Available"],
|
||||
"Item Name": "Little Blue Van",
|
||||
SKU: "",
|
||||
Notes: "MAX PAYLOAD 595 kg \nMAX LOAD LENGTH 1620 mm",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T19:11:40.141Z",
|
||||
"Updated At": "2022-11-10T20:05:04.608Z",
|
||||
type: "row",
|
||||
"Purchase Date": "2022-10-10T12:00:00.000",
|
||||
"Purchase Price": 39995,
|
||||
"Item Tags": ["Vehicle"],
|
||||
},
|
||||
{
|
||||
Status: ["Available"],
|
||||
"Item Name": "Masonry Drill",
|
||||
SKU: "ABC-123",
|
||||
Notes: "Making a burning smell",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T18:46:10.820Z",
|
||||
"Updated At": "2022-11-10T20:11:23.766Z",
|
||||
type: "row",
|
||||
"Purchase Date": "1992-11-19T12:00:00.000",
|
||||
"Item Tags": ["Electrical", "Tools"],
|
||||
"Purchase Price": 250,
|
||||
},
|
||||
{
|
||||
Status: ["Repair"],
|
||||
"Item Name": "Circular saw",
|
||||
SKU: "AB2-100",
|
||||
Notes: "",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T19:04:38.805Z",
|
||||
"Updated At": "2022-11-10T20:20:24.000Z",
|
||||
type: "row",
|
||||
"Purchase Date": "2012-11-15T12:00:00.000",
|
||||
"Item Tags": ["Electrical"],
|
||||
"Purchase Price": 300,
|
||||
},
|
||||
{
|
||||
"Item Tags": ["Electrical"],
|
||||
"Purchase Price": 210,
|
||||
"Purchase Date": "2022-10-17T12:00:00.000",
|
||||
Status: ["Available"],
|
||||
"Item Name": "Tablet Device (5g)",
|
||||
SKU: "PH-001",
|
||||
Notes: "Android tablet for use on site",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T20:21:56.332Z",
|
||||
"Updated At": "2022-11-10T20:21:56.332Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Item Tags": ["Tools", "Electrical"],
|
||||
"Purchase Price": 200,
|
||||
"Purchase Date": "2022-10-12T12:00:00.000",
|
||||
Status: ["Available"],
|
||||
"Item Name": "Power Screwdriver",
|
||||
SKU: "TKIT-002-A",
|
||||
Notes: "",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T20:10:51.129Z",
|
||||
"Updated At": "2022-11-10T20:13:37.821Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
Status: ["Available"],
|
||||
"Item Name": "Large Blue Van",
|
||||
SKU: "",
|
||||
Notes: "MAX LOAD LENGTH 4256 mm",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T19:03:41.698Z",
|
||||
"Updated At": "2022-11-10T20:04:57.932Z",
|
||||
type: "row",
|
||||
"Purchase Date": "2022-10-10T12:00:00.000",
|
||||
"Purchase Price": 65995,
|
||||
"Item Tags": ["Vehicle"],
|
||||
},
|
||||
{
|
||||
"Purchase Price": 2500,
|
||||
"Purchase Date": "2022-11-09T12:00:00.000",
|
||||
Status: ["Available"],
|
||||
"Item Name": "Office Laptop",
|
||||
SKU: "PC-123-ABC",
|
||||
Notes: "Office Laptop \n",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T20:06:14.463Z",
|
||||
"Updated At": "2022-11-10T20:07:02.532Z",
|
||||
type: "row",
|
||||
"Item Tags": ["Electrical", "Office"],
|
||||
},
|
||||
{
|
||||
Status: ["Available"],
|
||||
"Item Name": "Little Red Van",
|
||||
SKU: "",
|
||||
Notes: "MAX PAYLOAD 595 kg \nMAX LOAD LENGTH 1620 mm",
|
||||
tableId: "ta_bb_inventory",
|
||||
"Created At": "2022-11-10T19:55:02.367Z",
|
||||
"Updated At": "2022-11-10T20:05:13.504Z",
|
||||
type: "row",
|
||||
"Purchase Date": "2022-07-17T12:00:00.000",
|
||||
"Purchase Price": 39995,
|
||||
"Item Tags": ["Vehicle"],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,158 @@
|
|||
exports.jobsImport = [
|
||||
{
|
||||
"Works End": "2023-01-28T12:00:00.000",
|
||||
"Customer Email": "susie.peterson@example.com",
|
||||
"Customer Phone": "016973 88386",
|
||||
Notes:
|
||||
"Bring the large van as recycling has been requested. \nAlso, they have a large dog.",
|
||||
"Customer Name": "Susie Peterson",
|
||||
Address: "5452 The Crescent\nBrighton and Hove\nAI7G 7BN",
|
||||
"Works Start": "2023-01-26T12:00:00.000",
|
||||
"Quote Price": 4200,
|
||||
"Quote Date": "2022-11-11T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T18:00:29.510Z",
|
||||
"Updated At": "2022-11-10T20:37:45.120Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Updated Price": 307,
|
||||
"Works End": "2022-11-19T12:00:00.000",
|
||||
"Customer Email": "micheal.murphy@example.co",
|
||||
"Customer Phone": "07344 867816",
|
||||
Notes:
|
||||
"Adding new utils and tearing down the dividing walls. Bring large blue van.\n\nThe customer can be difficult. Avoid",
|
||||
"Customer Name": "Micheal Murphy",
|
||||
Address: "5266 York Road\nOxford\nG2 8EP",
|
||||
"Works Start": "2022-11-10T12:00:00.000",
|
||||
"Quote Price": 1231,
|
||||
"Quote Date": "2022-10-04T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T20:53:39.882Z",
|
||||
"Updated At": "2022-11-10T20:59:49.435Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Customer Email": "",
|
||||
"Customer Phone": "07374 594595",
|
||||
Notes:
|
||||
"Removal and recycle requested of all units.\n\nStill awaiting feedback. If this is still around after next wednesday, just delete it.",
|
||||
"Customer Name": "Charlotte Carpenter",
|
||||
Address: "7780 Mill Lane\nGreater Manchester\nDU57 3GA",
|
||||
"Quote Price": 500,
|
||||
"Quote Date": "2022-11-08T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T21:03:11.782Z",
|
||||
"Updated At": "2022-11-10T21:03:11.782Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Updated Price": 2001,
|
||||
"Works End": "2022-11-16T12:00:00.000",
|
||||
"Customer Email": "leah.freeman@example.com",
|
||||
"Customer Phone": "07844 42134",
|
||||
Notes:
|
||||
"Original quote too high. Material costs dropped.\nFull system installation.",
|
||||
"Customer Name": "Leah Freeman",
|
||||
Address: "4252 Fairview Road\nChester\nW62 7JH",
|
||||
"Works Start": "2022-11-09T12:00:00.000",
|
||||
"Quote Price": 3000,
|
||||
"Quote Date": "2022-10-04T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T20:25:44.284Z",
|
||||
"Updated At": "2022-11-10T20:54:21.655Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Works End": "2022-11-13T12:00:00.000",
|
||||
"Customer Email": "scarlett.gibson@example.co",
|
||||
"Customer Phone": "07572 745859",
|
||||
Notes:
|
||||
"This address has a service dog.\n\nQuote didn't account for a sinkhole at the property. Amended",
|
||||
"Customer Name": "Scarlett Gibson",
|
||||
Address: "5624 The Drive\nArmagh\nNU0 5DW",
|
||||
"Works Start": "2022-11-12T12:00:00.000",
|
||||
"Quote Price": 120,
|
||||
"Quote Date": "2022-11-11T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T19:50:55.215Z",
|
||||
"Updated At": "2022-11-10T20:44:12.004Z",
|
||||
type: "row",
|
||||
"Updated Price": 175,
|
||||
},
|
||||
{
|
||||
"Customer Email": "lester.rose@example.com",
|
||||
"Customer Phone": "07103 009138",
|
||||
Notes: "4 Radiators Removed\nMany cats in the house",
|
||||
"Customer Name": "Lester Rose",
|
||||
Address: "8543 Albert Road\nNewport\nLancashire\nUnited Kingdom\nS58 5YW",
|
||||
"Quote Price": 3543,
|
||||
"Quote Date": "2022-11-10T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T18:43:21.110Z",
|
||||
"Updated At": "2022-11-10T20:40:48.241Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Works End": "2022-11-24T12:00:00.000",
|
||||
"Customer Email": "joel.owens@example.com",
|
||||
"Customer Phone": "07216 548317",
|
||||
Notes:
|
||||
"Full retrofit of current installation. Will need big blue van. \n\nThere's a decent coffee place nearby. Ensure you buy enough for everyone.",
|
||||
"Customer Name": "Joel Owens",
|
||||
Address: "5516 Oaks Cross\nNewry\nT6V 9SL",
|
||||
"Works Start": "2022-11-24T12:00:00.000",
|
||||
"Quote Price": 789,
|
||||
"Quote Date": "2022-11-10T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T21:07:28.365Z",
|
||||
"Updated At": "2022-11-10T21:08:18.661Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Customer Email": "freddie.franklin@example.com",
|
||||
"Customer Phone": "016977 48298",
|
||||
Notes:
|
||||
"Equipment updates and some general maintenance.\n\nHouse has 3 walls.",
|
||||
"Customer Name": "Freddie Franklin",
|
||||
Address: "2035 Brick Kiln Road\nCoventry\nTS81 7AW",
|
||||
"Quote Price": 302,
|
||||
"Quote Date": "2022-11-10T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T18:33:57.850Z",
|
||||
"Updated At": "2022-11-10T20:57:54.015Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Works End": "2022-11-12T12:00:00.000",
|
||||
"Customer Email": "diane.henry@example.com",
|
||||
"Customer Phone": "07635 514491",
|
||||
Notes: "Large van required, recycling requested. \nNew customer",
|
||||
"Customer Name": "Diane Henry",
|
||||
Address:
|
||||
"3518 Station Road\nSunderland\nCounty Down\nUnited Kingdom\nXC67 8ES",
|
||||
"Works Start": "2022-11-11T12:00:00.000",
|
||||
"Quote Price": 2039,
|
||||
"Quote Date": "2022-11-10T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T19:23:08.036Z",
|
||||
"Updated At": "2022-11-10T20:45:40.523Z",
|
||||
type: "row",
|
||||
},
|
||||
{
|
||||
"Works End": "2022-09-23T12:00:00.000",
|
||||
"Customer Email": "warren.alvarez@example.com",
|
||||
"Customer Phone": "07768 90794",
|
||||
Notes:
|
||||
"System restoration and upgrades. \nCustomer is a smoker, bring cleaning equipment",
|
||||
"Customer Name": "Warren Alvarez",
|
||||
Address: "867 High Street\nBath\nKF8 6ZS",
|
||||
"Works Start": "2022-09-23T12:00:00.000",
|
||||
"Quote Price": 1412,
|
||||
"Quote Date": "2022-09-20T12:00:00.000",
|
||||
tableId: "ta_bb_jobs",
|
||||
"Created At": "2022-11-10T20:57:00.124Z",
|
||||
"Updated At": "2022-11-10T21:08:00.446Z",
|
||||
type: "row",
|
||||
},
|
||||
]
|
|
@ -1,55 +1,9 @@
|
|||
const { IncludeDocs, getLinkDocuments } = require("./linkUtils")
|
||||
const {
|
||||
generateLinkID,
|
||||
InternalTables,
|
||||
getUserMetadataParams,
|
||||
} = require("../utils")
|
||||
const { InternalTables, getUserMetadataParams } = require("../utils")
|
||||
const Sentry = require("@sentry/node")
|
||||
const { FieldTypes, RelationshipTypes } = require("../../constants")
|
||||
const { getAppDB } = require("@budibase/backend-core/context")
|
||||
|
||||
/**
|
||||
* Creates a new link document structure which can be put to the database. It is important to
|
||||
* note that while this talks about linker/linked the link is bi-directional and for all intent
|
||||
* and purposes it does not matter from which direction the link was initiated.
|
||||
* @param {string} tableId1 The ID of the first table (the linker).
|
||||
* @param {string} tableId2 The ID of the second table (the linked).
|
||||
* @param {string} fieldName1 The name of the field in the linker table.
|
||||
* @param {string} fieldName2 The name of the field in the linked table.
|
||||
* @param {string} rowId1 The ID of the row which is acting as the linker.
|
||||
* @param {string} rowId2 The ID of the row which is acting as the linked.
|
||||
* @constructor
|
||||
*/
|
||||
function LinkDocument(
|
||||
tableId1,
|
||||
fieldName1,
|
||||
rowId1,
|
||||
tableId2,
|
||||
fieldName2,
|
||||
rowId2
|
||||
) {
|
||||
// build the ID out of unique references to this link document
|
||||
this._id = generateLinkID(
|
||||
tableId1,
|
||||
tableId2,
|
||||
rowId1,
|
||||
rowId2,
|
||||
fieldName1,
|
||||
fieldName2
|
||||
)
|
||||
// required for referencing in view
|
||||
this.type = FieldTypes.LINK
|
||||
this.doc1 = {
|
||||
tableId: tableId1,
|
||||
fieldName: fieldName1,
|
||||
rowId: rowId1,
|
||||
}
|
||||
this.doc2 = {
|
||||
tableId: tableId2,
|
||||
fieldName: fieldName2,
|
||||
rowId: rowId2,
|
||||
}
|
||||
}
|
||||
const LinkDocument = require("./LinkDocument")
|
||||
|
||||
class LinkController {
|
||||
constructor({ tableId, row, table, oldTable }) {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
const { generateLinkID } = require("../utils")
|
||||
const { FieldTypes } = require("../../constants")
|
||||
|
||||
/**
|
||||
* Creates a new link document structure which can be put to the database. It is important to
|
||||
* note that while this talks about linker/linked the link is bi-directional and for all intent
|
||||
* and purposes it does not matter from which direction the link was initiated.
|
||||
* @param {string} tableId1 The ID of the first table (the linker).
|
||||
* @param {string} tableId2 The ID of the second table (the linked).
|
||||
* @param {string} fieldName1 The name of the field in the linker table.
|
||||
* @param {string} fieldName2 The name of the field in the linked table.
|
||||
* @param {string} rowId1 The ID of the row which is acting as the linker.
|
||||
* @param {string} rowId2 The ID of the row which is acting as the linked.
|
||||
* @constructor
|
||||
*/
|
||||
function LinkDocument(
|
||||
tableId1,
|
||||
fieldName1,
|
||||
rowId1,
|
||||
tableId2,
|
||||
fieldName2,
|
||||
rowId2
|
||||
) {
|
||||
// build the ID out of unique references to this link document
|
||||
this._id = generateLinkID(
|
||||
tableId1,
|
||||
tableId2,
|
||||
rowId1,
|
||||
rowId2,
|
||||
fieldName1,
|
||||
fieldName2
|
||||
)
|
||||
// required for referencing in view
|
||||
this.type = FieldTypes.LINK
|
||||
this.doc1 = {
|
||||
tableId: tableId1,
|
||||
fieldName: fieldName1,
|
||||
rowId: rowId1,
|
||||
}
|
||||
this.doc2 = {
|
||||
tableId: tableId2,
|
||||
fieldName: fieldName2,
|
||||
rowId: rowId2,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LinkDocument
|
|
@ -15,7 +15,7 @@ export const SearchIndexes = {
|
|||
|
||||
export const BudibaseInternalDB = {
|
||||
_id: "bb_internal",
|
||||
type: "budibase",
|
||||
type: dbCore.BUDIBASE_DATASOURCE_TYPE,
|
||||
name: "Budibase DB",
|
||||
source: "BUDIBASE",
|
||||
config: {},
|
||||
|
|
|
@ -58,6 +58,7 @@ const SCHEMA: Integration = {
|
|||
},
|
||||
aggregate: {
|
||||
type: QueryType.JSON,
|
||||
readable: true,
|
||||
steps: [
|
||||
{
|
||||
key: "$addFields",
|
||||
|
|
|
@ -97,7 +97,7 @@ async function updateAutomations(prodAppId: string, db: Database) {
|
|||
const oldDevAppId = automation.appId,
|
||||
oldProdAppId = dbCore.getProdAppID(automation.appId)
|
||||
if (
|
||||
automation.definition.trigger.stepId === AutomationTriggerStepId.WEBHOOK
|
||||
automation.definition.trigger?.stepId === AutomationTriggerStepId.WEBHOOK
|
||||
) {
|
||||
const old = automation.definition.trigger.inputs
|
||||
automation.definition.trigger.inputs = {
|
||||
|
|
|
@ -19,7 +19,7 @@ async function getAllInternalTables(db?: Database): Promise<Table[]> {
|
|||
return internalTables.rows.map((tableDoc: any) => ({
|
||||
...tableDoc.doc,
|
||||
type: "internal",
|
||||
sourceId: BudibaseInternalDB._id,
|
||||
sourceId: tableDoc.doc.sourceId || BudibaseInternalDB._id,
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -1273,12 +1273,12 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.1.22-alpha.8.tgz#c68dcd104023b1b0c4b981471fb30387dfce01f7"
|
||||
integrity sha512-ZQugFvr7j3wxXxOr7P33IrBKORNurwNO/JW5gtQLTStUKxp2ip7TQ1VyXiwBRDurzPuypEMk01L9gHNeWVEA7Q==
|
||||
"@budibase/backend-core@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.1.32-alpha.3.tgz#d65f97f6c147e75aa83cfb4c22a5b3bd568bf62d"
|
||||
integrity sha512-CSRn29z64bLEW3GLo6cTwpGjvTgIsfDOBwAiStEOlezzMNlDslvcOBCW0pQUo/0rf5C4zsTy4U1oHDElz7JJ2w==
|
||||
dependencies:
|
||||
"@budibase/types" "2.1.22-alpha.8"
|
||||
"@budibase/types" "2.1.32-alpha.3"
|
||||
"@shopify/jest-koa-mocks" "5.0.1"
|
||||
"@techpass/passport-openidconnect" "0.3.2"
|
||||
aws-sdk "2.1030.0"
|
||||
|
@ -1361,13 +1361,13 @@
|
|||
svelte-flatpickr "^3.2.3"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/pro@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.1.22-alpha.8.tgz#28d2d7133ce102950ad2e6f0328d12dd8f7091f8"
|
||||
integrity sha512-qNNfLzNTv4ndZPEUEK4FgwLl+n6KqAisY18hVPj1pURV6zbZXg8vQwQlUNMrzUnvrJsuHAragVjXogmcNyvtVQ==
|
||||
"@budibase/pro@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.1.32-alpha.3.tgz#32d67f5fe3aa6a993022e685f55a298b4fc364b5"
|
||||
integrity sha512-FwaWZLI8NVSH3Y4RcSvD1ySJXa5yWFgfGha5Zz5rvy3Tw3oSr/AfH91VW4ZLyzpuBQrMJHxLtDmaz3Ywd/jSkQ==
|
||||
dependencies:
|
||||
"@budibase/backend-core" "2.1.22-alpha.8"
|
||||
"@budibase/types" "2.1.22-alpha.8"
|
||||
"@budibase/backend-core" "2.1.32-alpha.3"
|
||||
"@budibase/types" "2.1.32-alpha.3"
|
||||
"@koa/router" "8.0.8"
|
||||
bull "4.10.1"
|
||||
joi "17.6.0"
|
||||
|
@ -1391,10 +1391,10 @@
|
|||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
|
||||
"@budibase/types@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.1.22-alpha.8.tgz#81806dc2e217f0e3b215f967b2e13dbe31144c3a"
|
||||
integrity sha512-B/ejxypUMbyHThkFKaqNgZgHL4vIrvOeZiDq5NI0xbfzO3616hFcVKWhoHbehYfMMuSzYOgXwegkC4J7CTlE+Q==
|
||||
"@budibase/types@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.1.32-alpha.3.tgz#87d53d7b5730f0067c1526a62f85afb13db82a51"
|
||||
integrity sha512-4MGPfe63IKJMSS+4HdznyjEnExKGk1rMa2sfVOvRAZWzdVhgo5m0UarwoKf49lDF3NPiqTLdXQnB4p7AmwQbbg==
|
||||
|
||||
"@bull-board/api@3.7.0":
|
||||
version "3.7.0"
|
||||
|
@ -10098,9 +10098,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.3.tgz#d4b15b8504c63d1fc3f2ade52d41bc8459d6ede1"
|
||||
integrity sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/string-templates",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Handlebars wrapper for Budibase templating.",
|
||||
"main": "src/index.cjs",
|
||||
"module": "dist/bundle.mjs",
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const dayjs = require("dayjs")
|
||||
dayjs.extend(require("dayjs/plugin/duration"))
|
||||
dayjs.extend(require("dayjs/plugin/advancedFormat"))
|
||||
dayjs.extend(require("dayjs/plugin/isoWeek"))
|
||||
dayjs.extend(require("dayjs/plugin/weekYear"))
|
||||
dayjs.extend(require("dayjs/plugin/weekOfYear"))
|
||||
dayjs.extend(require("dayjs/plugin/relativeTime"))
|
||||
dayjs.extend(require("dayjs/plugin/utc"))
|
||||
dayjs.extend(require("dayjs/plugin/timezone"))
|
||||
|
|
|
@ -1284,7 +1284,7 @@ component-emitter@^1.2.1:
|
|||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
concat-stream@^1.4.4:
|
||||
version "1.6.2"
|
||||
|
@ -3178,9 +3178,9 @@ minimalistic-crypto-utils@^1.0.1:
|
|||
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/types",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase types",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PouchDB from "pouchdb"
|
||||
import Nano from "nano"
|
||||
import { AllDocsResponse, AnyDocument } from "../"
|
||||
import { AllDocsResponse, AnyDocument, Document } from "../"
|
||||
|
||||
export type PouchOptions = {
|
||||
inMemory?: boolean
|
||||
|
@ -33,6 +33,21 @@ export type DatabasePutOpts = {
|
|||
force?: boolean
|
||||
}
|
||||
|
||||
export type DatabaseCreateIndexOpts = {
|
||||
index: {
|
||||
fields: string[]
|
||||
name?: string | undefined
|
||||
ddoc?: string | undefined
|
||||
type?: string | undefined
|
||||
}
|
||||
}
|
||||
|
||||
export type DatabaseDeleteIndexOpts = {
|
||||
name: string
|
||||
ddoc: string
|
||||
type?: string | undefined
|
||||
}
|
||||
|
||||
export type DatabaseQueryOpts = {
|
||||
include_docs?: boolean
|
||||
startkey?: string
|
||||
|
@ -44,13 +59,20 @@ export type DatabaseQueryOpts = {
|
|||
keys?: string[]
|
||||
}
|
||||
|
||||
export const isDocument = (doc: any): doc is Document => {
|
||||
return typeof doc === "object" && doc._id && doc._rev
|
||||
}
|
||||
|
||||
export interface Database {
|
||||
name: string
|
||||
|
||||
exists(): Promise<boolean>
|
||||
checkSetup(): Promise<Nano.DocumentScope<any>>
|
||||
get<T>(id?: string): Promise<T | any>
|
||||
remove(id?: string, rev?: string): Promise<Nano.DocumentDestroyResponse>
|
||||
remove(
|
||||
id: string | Document,
|
||||
rev?: string
|
||||
): Promise<Nano.DocumentDestroyResponse>
|
||||
put(
|
||||
document: AnyDocument,
|
||||
opts?: DatabasePutOpts
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { BaseEvent } from "./event"
|
||||
import { AppBackupTrigger, AppBackupType } from "../../documents"
|
||||
|
||||
export interface AppBackupRestoreEvent extends BaseEvent {
|
||||
appId: string
|
||||
backupName: string
|
||||
restoreId: string
|
||||
backupCreatedAt: string
|
||||
}
|
||||
|
||||
export interface AppBackupTriggeredEvent extends BaseEvent {
|
||||
backupId: string
|
||||
appId: string
|
||||
trigger: AppBackupTrigger
|
||||
type: AppBackupType
|
||||
}
|
||||
|
|
|
@ -171,6 +171,7 @@ export enum Event {
|
|||
|
||||
// BACKUP
|
||||
APP_BACKUP_RESTORED = "app:backup:restored",
|
||||
APP_BACKUP_TRIGGERED = "app:backup:triggered",
|
||||
}
|
||||
|
||||
// properties added at the final stage of the event pipeline
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/worker",
|
||||
"email": "hi@budibase.com",
|
||||
"version": "2.1.22-alpha.8",
|
||||
"version": "2.1.32-alpha.3",
|
||||
"description": "Budibase background service",
|
||||
"main": "src/index.ts",
|
||||
"repository": {
|
||||
|
@ -36,10 +36,10 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.1.22-alpha.8",
|
||||
"@budibase/pro": "2.1.22-alpha.8",
|
||||
"@budibase/string-templates": "2.1.22-alpha.8",
|
||||
"@budibase/types": "2.1.22-alpha.8",
|
||||
"@budibase/backend-core": "2.1.32-alpha.3",
|
||||
"@budibase/pro": "2.1.32-alpha.3",
|
||||
"@budibase/string-templates": "2.1.32-alpha.3",
|
||||
"@budibase/types": "2.1.32-alpha.3",
|
||||
"@koa/router": "8.0.8",
|
||||
"@sentry/node": "6.17.7",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
|
|
|
@ -3,7 +3,7 @@ const controller = require("../../controllers/global/configs")
|
|||
const { joiValidator } = require("@budibase/backend-core/auth")
|
||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
||||
const Joi = require("joi")
|
||||
const { Config } = require("../../../constants")
|
||||
const { Config } = require("@budibase/backend-core/constants")
|
||||
|
||||
const router = new Router()
|
||||
|
||||
|
|
|
@ -470,12 +470,12 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/backend-core@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.1.22-alpha.8.tgz#c68dcd104023b1b0c4b981471fb30387dfce01f7"
|
||||
integrity sha512-ZQugFvr7j3wxXxOr7P33IrBKORNurwNO/JW5gtQLTStUKxp2ip7TQ1VyXiwBRDurzPuypEMk01L9gHNeWVEA7Q==
|
||||
"@budibase/backend-core@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.1.32-alpha.3.tgz#d65f97f6c147e75aa83cfb4c22a5b3bd568bf62d"
|
||||
integrity sha512-CSRn29z64bLEW3GLo6cTwpGjvTgIsfDOBwAiStEOlezzMNlDslvcOBCW0pQUo/0rf5C4zsTy4U1oHDElz7JJ2w==
|
||||
dependencies:
|
||||
"@budibase/types" "2.1.22-alpha.8"
|
||||
"@budibase/types" "2.1.32-alpha.3"
|
||||
"@shopify/jest-koa-mocks" "5.0.1"
|
||||
"@techpass/passport-openidconnect" "0.3.2"
|
||||
aws-sdk "2.1030.0"
|
||||
|
@ -508,22 +508,22 @@
|
|||
uuid "8.3.2"
|
||||
zlib "1.0.5"
|
||||
|
||||
"@budibase/pro@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.1.22-alpha.8.tgz#28d2d7133ce102950ad2e6f0328d12dd8f7091f8"
|
||||
integrity sha512-qNNfLzNTv4ndZPEUEK4FgwLl+n6KqAisY18hVPj1pURV6zbZXg8vQwQlUNMrzUnvrJsuHAragVjXogmcNyvtVQ==
|
||||
"@budibase/pro@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.1.32-alpha.3.tgz#32d67f5fe3aa6a993022e685f55a298b4fc364b5"
|
||||
integrity sha512-FwaWZLI8NVSH3Y4RcSvD1ySJXa5yWFgfGha5Zz5rvy3Tw3oSr/AfH91VW4ZLyzpuBQrMJHxLtDmaz3Ywd/jSkQ==
|
||||
dependencies:
|
||||
"@budibase/backend-core" "2.1.22-alpha.8"
|
||||
"@budibase/types" "2.1.22-alpha.8"
|
||||
"@budibase/backend-core" "2.1.32-alpha.3"
|
||||
"@budibase/types" "2.1.32-alpha.3"
|
||||
"@koa/router" "8.0.8"
|
||||
bull "4.10.1"
|
||||
joi "17.6.0"
|
||||
node-fetch "^2.6.1"
|
||||
|
||||
"@budibase/types@2.1.22-alpha.8":
|
||||
version "2.1.22-alpha.8"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.1.22-alpha.8.tgz#81806dc2e217f0e3b215f967b2e13dbe31144c3a"
|
||||
integrity sha512-B/ejxypUMbyHThkFKaqNgZgHL4vIrvOeZiDq5NI0xbfzO3616hFcVKWhoHbehYfMMuSzYOgXwegkC4J7CTlE+Q==
|
||||
"@budibase/types@2.1.32-alpha.3":
|
||||
version "2.1.32-alpha.3"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.1.32-alpha.3.tgz#87d53d7b5730f0067c1526a62f85afb13db82a51"
|
||||
integrity sha512-4MGPfe63IKJMSS+4HdznyjEnExKGk1rMa2sfVOvRAZWzdVhgo5m0UarwoKf49lDF3NPiqTLdXQnB4p7AmwQbbg==
|
||||
|
||||
"@cspotcode/source-map-support@^0.8.0":
|
||||
version "0.8.1"
|
||||
|
|
Loading…
Reference in New Issue