Google Sheet integration fix (#493)

* Google Sheet integration fix

* fix testcase

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala 2024-07-17 17:52:54 +05:30 committed by GitHub
parent 6ec1f4d745
commit a2c1757815
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 90 additions and 45 deletions

View File

@ -12,6 +12,7 @@ use Google\Service\Sheets\BatchUpdateValuesRequest;
use Google\Service\Sheets\Spreadsheet; use Google\Service\Sheets\Spreadsheet;
use Google\Service\Sheets\ValueRange; use Google\Service\Sheets\ValueRange;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class SpreadsheetManager class SpreadsheetManager
{ {
@ -36,13 +37,6 @@ class SpreadsheetManager
); );
} }
protected function convertToArray(mixed $object): array
{
return is_scalar($object) || is_null($object)
? $object
: $this->convertToArray((array) $object);
}
public function get(string $id): Spreadsheet public function get(string $id): Spreadsheet
{ {
$spreadsheet = $this->driver $spreadsheet = $this->driver
@ -73,9 +67,12 @@ class SpreadsheetManager
public function buildColumns(): array public function buildColumns(): array
{ {
$properties = $this->integration->form->properties; collect($this->integration->form->properties)->each(function ($property) {
// Skip custom blocks
if (Str::of($property['type'])->startsWith('nf-')) {
return;
}
foreach ($properties as $property) {
$key = Arr::first( $key = Arr::first(
array_keys($this->data->columns), array_keys($this->data->columns),
fn (int $key) => $this->data->columns[$key]['id'] === $property['id'] fn (int $key) => $this->data->columns[$key]['id'] === $property['id']
@ -88,12 +85,11 @@ class SpreadsheetManager
} else { } else {
$this->data->columns[] = $column; $this->data->columns[] = $column;
} }
} });
$this->integration->update([ $this->integration->update([
'data' => $this->data, 'data' => $this->data,
]); ]);
return $this->data->columns; return $this->data->columns;
} }
@ -184,6 +180,20 @@ class SpreadsheetManager
protected function buildRange(array $values): string protected function buildRange(array $values): string
{ {
return "A1:" . chr(64 + count($values)) . "1"; $columnsCount = count($values);
$endColumn = $this->getColumnLetter($columnsCount);
return "A1:{$endColumn}1";
}
protected function getColumnLetter(int $columnIndex): string
{
$columnLetter = '';
while ($columnIndex > 0) {
$columnIndex--;
$columnLetter = chr(65 + ($columnIndex % 26)) . $columnLetter;
$columnIndex = (int)($columnIndex / 26);
}
return $columnLetter;
} }
} }

View File

@ -1,10 +1,10 @@
<template> <template>
<input-wrapper v-bind="inputWrapperProps"> <InputWrapper v-bind="inputWrapperProps">
<template #label> <template #label>
<slot name="label" /> <slot name="label" />
</template> </template>
<vue-editor <VueEditor
:id="id ? id : name" :id="id ? id : name"
ref="editor" ref="editor"
v-model="compVal" v-model="compVal"
@ -18,6 +18,7 @@
theme.RichTextAreaInput.input, theme.RichTextAreaInput.input,
theme.RichTextAreaInput.borderRadius, theme.RichTextAreaInput.borderRadius,
]" ]"
:editor-options="editorOptions"
:editor-toolbar="editorToolbar" :editor-toolbar="editorToolbar"
class="rich-editor resize-y" class="rich-editor resize-y"
:style="inputStyle" :style="inputStyle"
@ -29,40 +30,58 @@
<template #error> <template #error>
<slot name="error" /> <slot name="error" />
</template> </template>
</input-wrapper> </InputWrapper>
</template> </template>
<script> <script>
import { inputProps, useFormInput } from "./useFormInput.js" import { Quill, VueEditor } from 'vue3-editor'
import InputWrapper from "./components/InputWrapper.vue" import { inputProps, useFormInput } from './useFormInput.js'
import { VueEditor, Quill } from "vue3-editor" import InputWrapper from './components/InputWrapper.vue'
Quill.imports["formats/link"].PROTOCOL_WHITELIST.push("notion") Quill.imports['formats/link'].PROTOCOL_WHITELIST.push('notion')
export default { export default {
name: "RichTextAreaInput", name: 'RichTextAreaInput',
components: { InputWrapper, VueEditor }, components: { InputWrapper, VueEditor },
props: { props: {
...inputProps, ...inputProps,
editorOptions: {
type: Object,
default: () => {
return {
formats: [
'bold',
'color',
'font',
'italic',
'link',
'underline',
'header',
'indent',
'list'
]
}
}
},
editorToolbar: { editorToolbar: {
type: Array, type: Array,
default: () => { default: () => {
return [ return [
[{ header: 1 }, { header: 2 }], [{ header: 1 }, { header: 2 }],
["bold", "italic", "underline", "link"], ['bold', 'italic', 'underline', 'link'],
[{ list: "ordered" }, { list: "bullet" }], [{ list: 'ordered' }, { list: 'bullet' }],
[{ color: [] }], [{ color: [] }]
] ]
}, }
}, }
}, },
setup (props, context) { setup (props, context) {
return { return {
...useFormInput(props, context), ...useFormInput(props, context)
}
} }
},
} }
</script> </script>

View File

@ -74,7 +74,7 @@
theme.SelectInput.fontSize, theme.SelectInput.fontSize,
]" ]"
> >
{{ option.name }} {{ getOptionName(option) }}
</p> </p>
<span <span
v-if="selected" v-if="selected"
@ -157,7 +157,8 @@ export default {
methods: { methods: {
getOptionName(val) { getOptionName(val) {
const option = this.finalOptions.find((optionCandidate) => { const option = this.finalOptions.find((optionCandidate) => {
return optionCandidate[this.optionKey] === val return optionCandidate[this.optionKey] === val ||
(typeof val === 'object' && optionCandidate[this.optionKey] === val[this.optionKey])
}) })
if (option) return option[this.displayKey] if (option) return option[this.displayKey]
return null return null

View File

@ -91,6 +91,7 @@
:alt="field.name" :alt="field.name"
:src="field.image_block" :src="field.image_block"
class="max-w-full" class="max-w-full"
:class="theme.default.borderRadius"
> >
</div> </div>
</template> </template>

View File

@ -517,6 +517,17 @@
:form="field" :form="field"
:editor-toolbar="editorToolbarCustom" :editor-toolbar="editorToolbarCustom"
label="Field Help" label="Field Help"
:editor-options="{
formats: [
'bold',
'color',
'font',
'italic',
'link',
'underline',
'list'
]
}"
help="Your field help will be shown below/above the field, just like this text." help="Your field help will be shown below/above the field, just like this text."
:help-position="field.help_position" :help-position="field.help_position"
/> />

View File

@ -10,6 +10,7 @@
v-model="integrationData.oauth_id" v-model="integrationData.oauth_id"
name="provider" name="provider"
:options="providers" :options="providers"
display-key="email"
option-key="id" option-key="id"
emit-key="id" emit-key="id"
:required="true" :required="true"
@ -43,13 +44,13 @@
</template> </template>
<script setup> <script setup>
import IntegrationWrapper from "./components/IntegrationWrapper.vue" import IntegrationWrapper from './components/IntegrationWrapper.vue'
const props = defineProps({ const props = defineProps({
integration: { type: Object, required: true }, integration: { type: Object, required: true },
form: { type: Object, required: true }, form: { type: Object, required: true },
integrationData: { type: Object, required: true }, integrationData: { type: Object, required: true },
formIntegrationId: { type: Number, required: false, default: null }, formIntegrationId: { type: Number, required: false, default: null }
}) })
const providersStore = useOAuthProvidersStore() const providersStore = useOAuthProvidersStore()

View File

@ -49,6 +49,7 @@
"section_name": "Databases", "section_name": "Databases",
"file_name": "GoogleSheetsIntegration", "file_name": "GoogleSheetsIntegration",
"actions_file_name": "GoogleSheetsIntegrationActions", "actions_file_name": "GoogleSheetsIntegrationActions",
"is_pro": false "is_pro": false,
"crisp_help_page_slug": "how-do-i-integrate-google-sheets-for-my-database-goefny"
} }
} }

View File

@ -49,6 +49,7 @@
"section_name": "Databases", "section_name": "Databases",
"file_name": "GoogleSheetsIntegration", "file_name": "GoogleSheetsIntegration",
"actions_file_name": "GoogleSheetsIntegrationActions", "actions_file_name": "GoogleSheetsIntegrationActions",
"is_pro": false "is_pro": false,
"crisp_help_page_slug": "how-do-i-integrate-google-sheets-for-my-database-goefny"
} }
} }

View File

@ -63,8 +63,8 @@ test('update columns', function () {
$form->update([ $form->update([
'properties' => [ 'properties' => [
['id' => '000', 'name' => 'First'], ['id' => '000', 'name' => 'First', 'type' => 'text'],
['id' => '001', 'name' => 'Second'], ['id' => '001', 'name' => 'Second', 'type' => 'text'],
] ]
]); ]);
@ -82,8 +82,8 @@ test('update columns', function () {
url: 'https://google.com', url: 'https://google.com',
spreadsheet_id: 'sp_test', spreadsheet_id: 'sp_test',
columns: [ columns: [
['id' => '000', 'name' => 'First'], ['id' => '000', 'name' => 'First', 'type' => 'text'],
['id' => '001', 'name' => 'Second'], ['id' => '001', 'name' => 'Second', 'type' => 'text'],
] ]
) )
]); ]);
@ -96,8 +96,8 @@ test('update columns', function () {
$form->update([ $form->update([
'properties' => [ 'properties' => [
['id' => '000', 'name' => 'First name'], ['id' => '000', 'name' => 'First name', 'type' => 'text'],
['id' => '002', 'name' => 'Email'], ['id' => '002', 'name' => 'Email', 'type' => 'text'],
] ]
]); ]);