Merge remote-tracking branch 'origin/develop' into fix/logo-urls
This commit is contained in:
commit
42e3ca1872
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.6.19-alpha.49",
|
||||
"version": "2.6.19-alpha.52",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/backend-core",
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
.help {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: var(--spacing-xl);
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,11 @@
|
|||
})
|
||||
|
||||
onDestroy(() => {
|
||||
store.actions.reset()
|
||||
// Run async on a slight delay to let other cleanup logic run without
|
||||
// being confused by the store wiping
|
||||
setTimeout(() => {
|
||||
store.actions.reset()
|
||||
}, 10)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,13 +2,11 @@
|
|||
import { Button } from "@budibase/bbui"
|
||||
</script>
|
||||
|
||||
<div class="beta-background" />
|
||||
<div class="beta">
|
||||
Enjoying the Grid?
|
||||
<Button
|
||||
size="M"
|
||||
cta
|
||||
on:click={() => window.open("https://t.maze.co/156382627", "_blank")}
|
||||
on:click={() => window.open("https://t.maze.co/165900794", "_blank")}
|
||||
>
|
||||
Give Feedback
|
||||
</Button>
|
||||
|
@ -17,30 +15,16 @@
|
|||
<style>
|
||||
.beta {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
right: 32px;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
z-index: 10;
|
||||
}
|
||||
.beta :global(.spectrum-Button) {
|
||||
background: var(--spectrum-global-color-magenta-400);
|
||||
border-color: var(--spectrum-global-color-magenta-400);
|
||||
}
|
||||
.beta-background {
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: -230px;
|
||||
right: -105px;
|
||||
width: 1400px;
|
||||
height: 320px;
|
||||
transform: rotate(-22deg);
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
var(--cell-background) 20%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
</style>
|
|
@ -3,6 +3,7 @@
|
|||
import DatasourceNavigator from "components/backend/DatasourceNavigator/DatasourceNavigator.svelte"
|
||||
import Panel from "components/design/Panel.svelte"
|
||||
import { isActive, goto } from "@roxi/routify"
|
||||
import BetaButton from "./_components/BetaButton.svelte"
|
||||
</script>
|
||||
|
||||
<!-- routify:options index=1 -->
|
||||
|
@ -19,6 +20,7 @@
|
|||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
<BetaButton />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -39,5 +41,6 @@
|
|||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
flex: 1 1 auto;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
import DatasourceConfigModal from "components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte"
|
||||
import GoogleDatasourceConfigModal from "components/backend/DatasourceNavigator/modals/GoogleDatasourceConfigModal.svelte"
|
||||
import { createRestDatasource } from "builderStore/datasource"
|
||||
import DatasourceOption from "./_DatasourceOption.svelte"
|
||||
import DatasourceOption from "./_components/DatasourceOption.svelte"
|
||||
import IntegrationIcon from "components/backend/DatasourceNavigator/IntegrationIcon.svelte"
|
||||
import ICONS from "components/backend/DatasourceNavigator/icons/index.js"
|
||||
import FontAwesomeIcon from "components/common/FontAwesomeIcon.svelte"
|
||||
|
|
|
@ -1,42 +1,9 @@
|
|||
<script>
|
||||
import { Tooltip } from "@budibase/bbui"
|
||||
import { UserAvatar } from "@budibase/frontend-core"
|
||||
|
||||
export let row
|
||||
|
||||
let showTooltip
|
||||
</script>
|
||||
|
||||
{#if row?.user?.email}
|
||||
<div
|
||||
class="container"
|
||||
on:mouseover={() => (showTooltip = true)}
|
||||
on:focus={() => (showTooltip = true)}
|
||||
on:mouseleave={() => (showTooltip = false)}
|
||||
>
|
||||
<UserAvatar user={row.user} />
|
||||
</div>
|
||||
{#if showTooltip}
|
||||
<div class="tooltip">
|
||||
<Tooltip textWrapping text={row.user.email} direction="bottom" />
|
||||
</div>
|
||||
{/if}
|
||||
<UserAvatar user={row.user} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
.tooltip {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 75%;
|
||||
left: 120%;
|
||||
transform: translateX(-100%) translateY(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
width: 130px;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
Breadcrumb,
|
||||
Header,
|
||||
} from "components/portal/page"
|
||||
import { apps, auth, overview } from "stores/portal"
|
||||
import { apps, overview } from "stores/portal"
|
||||
import { AppStatus } from "constants"
|
||||
import analytics, { Events, EventSource } from "analytics"
|
||||
import { store } from "builderStore"
|
||||
|
@ -52,8 +52,6 @@
|
|||
$: appId = $overview.selectedAppId
|
||||
$: initialiseApp(appId)
|
||||
$: isPublished = app?.status === AppStatus.DEPLOYED
|
||||
$: appLocked = !!app?.lockedBy
|
||||
$: lockedByYou = $auth.user.email === app?.lockedBy?.email
|
||||
|
||||
const initialiseApp = async appId => {
|
||||
loaded = false
|
||||
|
@ -139,14 +137,7 @@
|
|||
</Button>
|
||||
</span>
|
||||
<span class="desktop">
|
||||
<Button
|
||||
size="M"
|
||||
cta
|
||||
disabled={appLocked && !lockedByYou}
|
||||
on:click={editApp}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button size="M" cta on:click={editApp}>Edit</Button>
|
||||
</span>
|
||||
<ActionMenu align="right">
|
||||
<span slot="control" class="app-overview-actions-icon">
|
||||
|
@ -158,13 +149,7 @@
|
|||
</MenuItem>
|
||||
</span>
|
||||
<span class="mobile">
|
||||
<MenuItem
|
||||
icon="Edit"
|
||||
disabled={appLocked && !lockedByYou}
|
||||
on:click={editApp}
|
||||
>
|
||||
Edit
|
||||
</MenuItem>
|
||||
<MenuItem icon="Edit" on:click={editApp}>Edit</MenuItem>
|
||||
</span>
|
||||
<MenuItem
|
||||
on:click={() => exportApp({ published: false })}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
}
|
||||
|
||||
onMount(async () => {
|
||||
await Promise.all(fetchConfig(), fetchAPIKey())
|
||||
await Promise.all([fetchConfig(), fetchAPIKey()])
|
||||
})
|
||||
|
||||
const copyToClipboard = async value => {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { createAPIClient } from "../../../api"
|
||||
import { attachStores } from "../stores"
|
||||
import BulkDeleteHandler from "../controls/BulkDeleteHandler.svelte"
|
||||
import BetaButton from "../controls/BetaButton.svelte"
|
||||
import GridBody from "./GridBody.svelte"
|
||||
import ResizeOverlay from "../overlays/ResizeOverlay.svelte"
|
||||
import ReorderOverlay from "../overlays/ReorderOverlay.svelte"
|
||||
|
@ -144,7 +143,6 @@
|
|||
<HeaderRow />
|
||||
<GridBody />
|
||||
</div>
|
||||
<BetaButton />
|
||||
{#if allowAddRows}
|
||||
<NewRow />
|
||||
{/if}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const Padding = 128
|
||||
export const Padding = 256
|
||||
export const MaxCellRenderHeight = 252
|
||||
export const MaxCellRenderWidthOverflow = 200
|
||||
export const ScrollBarSize = 8
|
||||
|
|
|
@ -457,22 +457,41 @@ class GoogleSheetsIntegration implements DatasourcePlus {
|
|||
}) {
|
||||
try {
|
||||
await this.connect()
|
||||
const hasFilters = dataFilters.hasFilters(query.filters)
|
||||
const limit = query.paginate?.limit || 100
|
||||
const page: number =
|
||||
typeof query.paginate?.page === "number"
|
||||
? query.paginate.page
|
||||
: parseInt(query.paginate?.page || "1")
|
||||
const offset = (page - 1) * limit
|
||||
const sheet = this.client.sheetsByTitle[query.sheet]
|
||||
let rows: GoogleSpreadsheetRow[] = []
|
||||
if (query.paginate) {
|
||||
const limit = query.paginate.limit || 100
|
||||
let page: number =
|
||||
typeof query.paginate.page === "number"
|
||||
? query.paginate.page
|
||||
: parseInt(query.paginate.page || "1")
|
||||
if (query.paginate && !hasFilters) {
|
||||
rows = await sheet.getRows({
|
||||
limit,
|
||||
offset: (page - 1) * limit,
|
||||
offset,
|
||||
})
|
||||
} else {
|
||||
rows = await sheet.getRows()
|
||||
}
|
||||
const filtered = dataFilters.runLuceneQuery(rows, query.filters)
|
||||
// this is a special case - need to handle the _id, it doesn't exist
|
||||
// we cannot edit the returned structure from google, it does not have
|
||||
// setter functions and is immutable, easier to update the filters
|
||||
// to look for the _rowNumber property rather than rowNumber
|
||||
if (query.filters?.equal) {
|
||||
const idFilterKeys = Object.keys(query.filters.equal).filter(filter =>
|
||||
filter.includes(GOOGLE_SHEETS_PRIMARY_KEY)
|
||||
)
|
||||
for (let idFilterKey of idFilterKeys) {
|
||||
const id = query.filters.equal[idFilterKey]
|
||||
delete query.filters.equal[idFilterKey]
|
||||
query.filters.equal[`_${GOOGLE_SHEETS_PRIMARY_KEY}`] = id
|
||||
}
|
||||
}
|
||||
let filtered = dataFilters.runLuceneQuery(rows, query.filters)
|
||||
if (hasFilters && query.paginate) {
|
||||
filtered = filtered.slice(offset, offset + limit)
|
||||
}
|
||||
const headerValues = sheet.headerValues
|
||||
let response = []
|
||||
for (let row of filtered) {
|
||||
|
@ -535,7 +554,12 @@ class GoogleSheetsIntegration implements DatasourcePlus {
|
|||
const row = rows[query.rowIndex]
|
||||
if (row) {
|
||||
await row.delete()
|
||||
return [{ deleted: query.rowIndex }]
|
||||
return [
|
||||
{
|
||||
deleted: query.rowIndex,
|
||||
[GOOGLE_SHEETS_PRIMARY_KEY]: query.rowIndex,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
throw new Error("Row does not exist.")
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ export class BaseSocket {
|
|||
this.io.on("connection", async socket => {
|
||||
// Add built in handler for heartbeats
|
||||
socket.on(SocketEvent.Heartbeat, async () => {
|
||||
console.log(socket.data.email, "heartbeat received")
|
||||
await this.extendSessionTTL(socket.data.sessionId)
|
||||
})
|
||||
|
||||
|
|
|
@ -455,3 +455,19 @@ export const luceneLimit = (docs: any[], limit: string) => {
|
|||
}
|
||||
return docs.slice(0, numLimit)
|
||||
}
|
||||
|
||||
export const hasFilters = (query?: Query) => {
|
||||
if (!query) {
|
||||
return false
|
||||
}
|
||||
const skipped = ["allOr"]
|
||||
for (let [key, value] of Object.entries(query)) {
|
||||
if (skipped.includes(key) || typeof value !== "object") {
|
||||
continue
|
||||
}
|
||||
if (Object.keys(value).length !== 0) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue