1
0
Fork 0
mirror of synced 2024-10-03 19:43:32 +13:00

Merge pull request #10172 from Budibase/fix/budi-6797

Googlesheets onboarding - fix in cloud, disable self host
This commit is contained in:
Michael Drury 2023-03-31 13:19:29 +01:00 committed by GitHub
commit 1c6465edcb
9 changed files with 97 additions and 22 deletions

View file

@ -32,8 +32,7 @@ export async function getConfig<T extends Config>(
const db = context.getGlobalDB()
try {
// await to catch error
const config = (await db.get(generateConfigID(type))) as T
return config
return (await db.get(generateConfigID(type))) as T
} catch (e: any) {
if (e.status === 404) {
return

View file

@ -78,17 +78,23 @@ export async function postAuth(
),
{ successRedirect: "/", failureRedirect: "/error" },
async (err: any, tokens: string[]) => {
const baseUrl = `/builder/app/${authStateCookie.appId}/data`
// update the DB for the datasource with all the user info
await doWithDB(authStateCookie.appId, async (db: Database) => {
const datasource = await db.get(authStateCookie.datasourceId)
let datasource
try {
datasource = await db.get(authStateCookie.datasourceId)
} catch (err: any) {
if (err.status === 404) {
ctx.redirect(baseUrl)
}
}
if (!datasource.config) {
datasource.config = {}
}
datasource.config.auth = { type: "google", ...tokens }
await db.put(datasource)
ctx.redirect(
`/builder/app/${authStateCookie.appId}/data/datasource/${authStateCookie.datasourceId}`
)
ctx.redirect(`${baseUrl}/datasource/${authStateCookie.datasourceId}`)
})
}
)(ctx, next)

View file

@ -5,18 +5,28 @@
export let preAuthStep
export let datasource
export let disabled
$: tenantId = $auth.tenantId
</script>
<button
class:disabled
{disabled}
on:click={async () => {
let ds = datasource
let appId = $store.appId
if (!ds) {
ds = await preAuthStep()
const resp = await preAuthStep()
if (resp.datasource && resp.appId) {
ds = resp.datasource
appId = resp.appId
} else {
ds = resp
}
}
window.open(
`/api/global/auth/${tenantId}/datasource/google?datasourceId=${ds._id}&appId=${$store.appId}`,
`/api/global/auth/${tenantId}/datasource/google?datasourceId=${ds._id}&appId=${appId}`,
"_blank"
)
}}
@ -26,6 +36,10 @@
</button>
<style>
.disabled {
opacity: 0.5;
}
button {
width: 195px;
height: 40px;

View file

@ -1,12 +1,15 @@
<script>
import { Button, FancyForm, FancyInput, FancyCheckbox } from "@budibase/bbui"
import GoogleButton from "components/backend/DatasourceNavigator/_components/GoogleButton.svelte"
import { capitalise } from "helpers/helpers"
import PanelHeader from "./PanelHeader.svelte"
import { helpers } from "@budibase/shared-core"
export let title = ""
export let onBack = null
export let onNext = () => {}
export let fields = {}
export let type = ""
let errors = {}
@ -57,8 +60,9 @@
}
$: isValid = getIsValid(fields, errors, values)
$: isGoogle = helpers.isGoogleSheets(type)
const handleNext = () => {
const handleNext = async () => {
const parsedValues = {}
Object.entries(values).forEach(([name, value]) => {
@ -69,7 +73,10 @@
}
})
return onNext(parsedValues)
if (isGoogle) {
parsedValues.isGoogle = isGoogle
}
return await onNext(parsedValues)
}
</script>
@ -99,7 +106,11 @@
{/each}
</FancyForm>
</div>
<Button cta disabled={!isValid} on:click={handleNext}>Connect</Button>
{#if isGoogle}
<GoogleButton disabled={!isValid} preAuthStep={handleNext} />
{:else}
<Button cta disabled={!isValid} on:click={handleNext}>Connect</Button>
{/if}
</div>
<style>

View file

@ -4,19 +4,20 @@
import DataPanel from "./_components/DataPanel.svelte"
import DatasourceConfigPanel from "./_components/DatasourceConfigPanel.svelte"
import ExampleApp from "./_components/ExampleApp.svelte"
import { FancyButton, notifications, Modal } from "@budibase/bbui"
import { FancyButton, notifications, Modal, Body } from "@budibase/bbui"
import IntegrationIcon from "components/backend/DatasourceNavigator/IntegrationIcon.svelte"
import { SplitPage } from "@budibase/frontend-core"
import { API } from "api"
import { store, automationStore } from "builderStore"
import { saveDatasource } from "builderStore/datasource"
import { integrations } from "stores/backend"
import { auth, admin } from "stores/portal"
import { auth, admin, organisation } from "stores/portal"
import FontAwesomeIcon from "components/common/FontAwesomeIcon.svelte"
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
import createFromScratchScreen from "builderStore/store/screenTemplates/createFromScratchScreen"
import { Roles } from "constants/backend"
import Spinner from "components/common/Spinner.svelte"
import { helpers } from "@budibase/shared-core"
let name = "My first app"
let url = "my-first-app"
@ -25,10 +26,11 @@
let plusIntegrations = {}
let integrationsLoading = true
$: getIntegrations()
let creationLoading = false
let uploadModal
let googleComplete = false
$: getIntegrations()
const createApp = async useSampleData => {
creationLoading = true
@ -62,6 +64,7 @@
await store.actions.screens.save(defaultScreenTemplate)
appId = createdApp.instance._id
return createdApp
} catch (e) {
creationLoading = false
throw e
@ -74,6 +77,13 @@
const newPlusIntegrations = {}
Object.entries($integrations).forEach(([integrationType, schema]) => {
// google sheets not available in self-host
if (
helpers.isGoogleSheets(integrationType) &&
!$organisation.googleDatasourceConfigured
) {
return
}
if (schema?.plus) {
newPlusIntegrations[integrationType] = schema
}
@ -92,12 +102,17 @@
notifications.success(`App created successfully`)
}
const handleCreateApp = async ({ datasourceConfig, useSampleData }) => {
const handleCreateApp = async ({
datasourceConfig,
useSampleData,
isGoogle,
}) => {
try {
await createApp(useSampleData)
const app = await createApp(useSampleData)
let datasource
if (datasourceConfig) {
await saveDatasource({
datasource = await saveDatasource({
plus: true,
auth: undefined,
name: plusIntegrations[stage].friendlyName,
@ -107,7 +122,14 @@
})
}
goToApp()
store.set()
if (isGoogle) {
googleComplete = true
return { datasource, appId: app.appId }
} else {
goToApp()
}
} catch (e) {
console.log(e)
creationLoading = false
@ -127,8 +149,15 @@
<SplitPage>
{#if stage === "name"}
<NamePanel bind:name bind:url onNext={() => (stage = "data")} />
{:else if googleComplete}
<div class="centered">
<Body
>Please login to your Google account in the new tab which as opened to
continue.</Body
>
</div>
{:else if integrationsLoading || creationLoading}
<div class="spinner">
<div class="centered">
<Spinner />
</div>
{:else if stage === "data"}
@ -174,8 +203,13 @@
<DatasourceConfigPanel
title={plusIntegrations[stage].friendlyName}
fields={plusIntegrations[stage].datasource}
type={stage}
onBack={() => (stage = "data")}
onNext={data => handleCreateApp({ datasourceConfig: data })}
onNext={data => {
const isGoogle = data.isGoogle
delete data.isGoogle
return handleCreateApp({ datasourceConfig: data, isGoogle })
}}
/>
{:else}
<p>There was an problem. Please refresh the page and try again.</p>
@ -186,7 +220,7 @@
</SplitPage>
<style>
.spinner {
.centered {
display: flex;
justify-content: center;
align-items: center;

View file

@ -245,6 +245,10 @@ class GoogleSheetsIntegration implements DatasourcePlus {
}
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
// not fully configured yet
if (!this.config.auth) {
return
}
await this.connect()
const sheets = this.client.sheetsByIndex
const tables: Record<string, Table> = {}

View file

@ -0,0 +1,2 @@
export * from "./helpers"
export * from "./integrations"

View file

@ -0,0 +1,5 @@
import { SourceName } from "@budibase/types"
export function isGoogleSheets(type: SourceName) {
return type === SourceName.GOOGLE_SHEETS
}