Browse Source

feat: add `append values` option in google sheets block

Ahmad Kholid 3 years ago
parent
commit
d72c453d81

+ 26 - 6
src/background/workflowEngine/blocksHandler/handlerGoogleSheets.js

@@ -38,12 +38,14 @@ async function getSpreadsheetRange({ spreadsheetId, range }) {
 }
 async function updateSpreadsheetValues(
   {
-    spreadsheetId,
     range,
-    valueInputOption,
-    keysAsFirstRow,
+    append,
     dataFrom,
     customData,
+    spreadsheetId,
+    keysAsFirstRow,
+    insertDataOption,
+    valueInputOption,
   },
   columns
 ) {
@@ -63,11 +65,23 @@ async function updateSpreadsheetValues(
     values = parseJSON(customData, customData);
   }
 
+  const queries = {
+    valueInputOption: valueInputOption || 'RAW',
+  };
+
+  if (append) {
+    Object.assign(queries, {
+      includeValuesInResponse: false,
+      insertDataOption: insertDataOption || 'INSERT_ROWS',
+    });
+  }
+
   const response = await googleSheets.updateValues({
     range,
+    append,
     spreadsheetId,
-    valueInputOption,
     options: {
+      queries,
       body: JSON.stringify({ values }),
     },
   });
@@ -106,8 +120,14 @@ export default async function ({ data, outputs }, { refData }) {
       if (data.saveData) {
         this.addDataToColumn(data.dataColumn, result);
       }
-    } else if (data.type === 'update') {
-      result = await updateSpreadsheetValues(data, refData.table);
+    } else if (['update', 'append'].includes(data.type)) {
+      result = await updateSpreadsheetValues(
+        {
+          ...data,
+          append: data.type === 'append',
+        },
+        refData.table
+      );
     }
 
     return {

+ 27 - 3
src/components/newtab/workflow/edit/EditGoogleSheets.vue

@@ -93,7 +93,7 @@
         {{ t('workflow.blocks.google-sheets.previewData') }}
       </ui-button>
     </template>
-    <template v-else-if="data.type === 'update'">
+    <template v-else-if="['update', 'append'].includes(data.type)">
       <ui-select
         :model-value="data.valueInputOption"
         class="w-full mt-2"
@@ -117,6 +117,29 @@
           {{ option }}
         </option>
       </ui-select>
+      <ui-select
+        :model-value="data.insertDataOption || 'INSERT_ROWS'"
+        class="w-full mt-2"
+        @change="updateData({ insertDataOption: $event })"
+      >
+        <template #label>
+          {{ t('workflow.blocks.google-sheets.insertDataOption') }}
+          <a
+            href="https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append#InsertDataOption"
+            target="_blank"
+            rel="noopener"
+          >
+            <v-remixicon name="riInformationLine" size="18" class="inline" />
+          </a>
+        </template>
+        <option
+          v-for="option in insertDataOptions"
+          :key="option"
+          :value="option"
+        >
+          {{ option }}
+        </option>
+      </ui-select>
       <ui-select
         :model-value="data.dataFrom"
         :label="t('workflow.blocks.google-sheets.dataFrom.label')"
@@ -148,7 +171,7 @@
       v-if="
         previewDataState.data &&
         previewDataState.status !== 'error' &&
-        type !== 'update'
+        data.type !== 'update'
       "
       :model-value="previewDataState.data"
       :line-numbers="false"
@@ -191,9 +214,10 @@ const emit = defineEmits(['update:data']);
 
 const { t } = useI18n();
 
-const actions = ['get', 'getRange', 'update'];
+const actions = ['get', 'getRange', 'update', 'append'];
 const dataFrom = ['data-columns', 'custom'];
 const valueInputOptions = ['RAW', 'USER_ENTERED'];
+const insertDataOptions = ['OVERWRITE', 'INSERT_ROWS'];
 
 const previewDataState = shallowReactive({
   data: '',

+ 3 - 1
src/locales/en/blocks.json

@@ -216,6 +216,7 @@
         "keysAsFirstRow": "Use keys as the first row",
         "insertData": "Insert data",
         "valueInputOption": "Value input option",
+        "insertDataOption": "Insert data option",
         "rangeToSearch": "Range to start the search",
         "dataFrom": {
           "label": "Data from",
@@ -239,7 +240,8 @@
         "select": {
           "get": "Get spreadsheet cell values",
           "getRange": "Get spreadsheet range",
-          "update": "Update spreadsheet cell values"
+          "update": "Update spreadsheet cell values",
+          "append": "Append spreadsheet cell values"
         }
       },
       "active-tab": {

+ 29 - 13
src/utils/api.js

@@ -2,6 +2,18 @@ import secrets from 'secrets';
 import browser from 'webextension-polyfill';
 import { parseJSON } from './helper';
 
+function queryBuilder(obj) {
+  let str = '';
+
+  Object.entries(obj).forEach(([key, value], index) => {
+    if (index !== 0) str += `&`;
+
+    str += `${key}=${value}`;
+  });
+
+  return str;
+}
+
 export function fetchApi(path, options) {
   const urlPath = path.startsWith('/') ? path : `/${path}`;
 
@@ -18,24 +30,28 @@ export const googleSheets = {
     return fetchApi(url);
   },
   getRange({ spreadsheetId, range }) {
-    const baseURL = this.getUrl(spreadsheetId, range);
-    const url = `${baseURL}&valueInputOption=RAW&includeValuesInResponse=false&insertDataOption=INSERT_ROWS`;
-
-    return fetchApi(url, {
-      method: 'POST',
-      body: JSON.stringify({
-        values: [],
-      }),
+    return googleSheets.updateValues({
+      range,
+      append: true,
+      spreadsheetId,
+      options: {
+        body: JSON.stringify({ values: [] }),
+        queries: {
+          valueInputOption: 'RAW',
+          includeValuesInResponse: false,
+          insertDataOption: 'INSERT_ROWS',
+        },
+      },
     });
   },
-  updateValues({ spreadsheetId, range, valueInputOption, options = {} }) {
-    const url = `${this.getUrl(spreadsheetId, range)}&valueInputOption=${
-      valueInputOption || 'RAW'
-    }`;
+  updateValues({ spreadsheetId, range, options = {}, append }) {
+    const url = `${this.getUrl(spreadsheetId, range)}&${queryBuilder(
+      options?.queries || {}
+    )}`;
 
     return fetchApi(url, {
       ...options,
-      method: 'PUT',
+      method: append ? 'POST' : 'PUT',
     });
   },
 };

+ 1 - 0
src/utils/shared.js

@@ -555,6 +555,7 @@ export const tasks = {
       firstRowAsKey: false,
       keysAsFirstRow: true,
       valueInputOption: 'RAW',
+      InsertDataOption: 'INSERT_ROWS',
       dataFrom: 'data-columns',
     },
   },