Browse Source

feat: add `Get spreadsheet range` option in google sheets block

Ahmad Kholid 3 years ago
parent
commit
f3e860b0f5

+ 24 - 0
src/background/workflowEngine/blocksHandler/handlerGoogleSheets.js

@@ -21,6 +21,21 @@ async function getSpreadsheetValues({ spreadsheetId, range, firstRowAsKey }) {
 
   return sheetsData;
 }
+async function getSpreadsheetRange({ spreadsheetId, range }) {
+  const response = await googleSheets.getRange({ spreadsheetId, range });
+  const result = await response.json();
+
+  if (!response.ok) {
+    throw new Error(result.statusMessage);
+  }
+
+  const data = {
+    tableRange: result.tableRange || null,
+    lastRange: result.updates.updatedRange,
+  };
+
+  return data;
+}
 async function updateSpreadsheetValues(
   {
     spreadsheetId,
@@ -82,6 +97,15 @@ export default async function ({ data, outputs }, { refData }) {
       if (data.refKey && !isWhitespace(data.refKey)) {
         refData.googleSheets[data.refKey] = spreadsheetValues;
       }
+    } else if (data.type === 'getRange') {
+      result = await getSpreadsheetRange(data);
+
+      if (data.assignVariable) {
+        this.setVariable(data.variableName, result);
+      }
+      if (data.saveData) {
+        this.addDataToColumn(data.dataColumn, result);
+      }
     } else if (data.type === 'update') {
       result = await updateSpreadsheetValues(data, refData.table);
     }

+ 4 - 1
src/components/newtab/workflow/WorkflowSettings.vue

@@ -127,7 +127,10 @@
           <ui-switch v-model="settings.insertDefaultColumn" />
         </div>
         <transition-expand>
-          <div v-if="settings.insertDefaultColumn" class="flex pt-4">
+          <div
+            v-if="settings.insertDefaultColumn"
+            class="flex pt-4 items-center"
+          >
             <p class="flex-1">
               {{ t('workflow.settings.defaultColumn.name') }}
             </p>

+ 56 - 22
src/components/newtab/workflow/edit/EditGoogleSheets.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="mb-10">
     <ui-textarea
       :model-value="data.description"
       class="w-full mb-2"
@@ -9,13 +9,10 @@
     <ui-select
       :model-value="data.type"
       class="w-full mb-2"
-      @change="updateData({ type: $event })"
+      @change="onActionChange"
     >
-      <option value="get">
-        {{ t('workflow.blocks.google-sheets.select.get') }}
-      </option>
-      <option value="update">
-        {{ t('workflow.blocks.google-sheets.select.update') }}
+      <option v-for="action in actions" :key="action" :value="action">
+        {{ t(`workflow.blocks.google-sheets.select.${action}`) }}
       </option>
     </ui-select>
     <edit-autocomplete>
@@ -84,13 +81,17 @@
       <p v-if="previewDataState.status === 'error'" class="text-red-500">
         {{ previewDataState.errorMessage }}
       </p>
-      <shared-codemirror
-        v-if="previewDataState.data && previewDataState.status !== 'error'"
-        :model-value="previewDataState.data"
-        :line-numbers="false"
-        readonly
-        class="mt-4 max-h-96 scroll"
-      />
+    </template>
+    <template v-else-if="data.type === 'getRange'">
+      <insert-workflow-data :data="data" variables @update="updateData" />
+      <ui-button
+        :loading="previewDataState.status === 'loading'"
+        variant="accent"
+        class="mt-4"
+        @click="previewData"
+      >
+        {{ t('workflow.blocks.google-sheets.previewData') }}
+      </ui-button>
     </template>
     <template v-else-if="data.type === 'update'">
       <ui-select
@@ -143,6 +144,17 @@
         {{ t('workflow.blocks.google-sheets.insertData') }}
       </ui-button>
     </template>
+    <shared-codemirror
+      v-if="
+        previewDataState.data &&
+        previewDataState.status !== 'error' &&
+        type !== 'update'
+      "
+      :model-value="previewDataState.data"
+      :line-numbers="false"
+      readonly
+      class="mt-4 max-h-96 scroll"
+    />
     <ui-modal
       v-model="customDataState.showModal"
       title="Custom data"
@@ -163,6 +175,7 @@ import { useI18n } from 'vue-i18n';
 import { googleSheets } from '@/utils/api';
 import { convert2DArrayToArrayObj } from '@/utils/helper';
 import EditAutocomplete from './EditAutocomplete.vue';
+import InsertWorkflowData from './InsertWorkflowData.vue';
 
 const SharedCodemirror = defineAsyncComponent(() =>
   import('@/components/newtab/shared/SharedCodemirror.vue')
@@ -178,6 +191,7 @@ const emit = defineEmits(['update:data']);
 
 const { t } = useI18n();
 
+const actions = ['get', 'getRange', 'update'];
 const dataFrom = ['data-columns', 'custom'];
 const valueInputOptions = ['RAW', 'USER_ENTERED'];
 
@@ -197,10 +211,15 @@ function updateData(value) {
 async function previewData() {
   try {
     previewDataState.status = 'loading';
-    const response = await googleSheets.getValues({
-      spreadsheetId: props.data.spreadsheetId,
+
+    const isGetValues = props.data.type === 'get';
+    const params = {
       range: props.data.range,
-    });
+      spreadsheetId: props.data.spreadsheetId,
+    };
+    const response = await (isGetValues
+      ? googleSheets.getValues(params)
+      : googleSheets.getRange(params));
 
     if (!response.ok) {
       const error = await response.json();
@@ -208,18 +227,33 @@ async function previewData() {
       throw new Error(error.statusMessage || response.statusText);
     }
 
-    const { values } = await response.json();
-    const sheetsData = props.data.firstRowAsKey
-      ? convert2DArrayToArrayObj(values)
-      : values;
+    let result = await response.json();
 
-    previewDataState.data = JSON.stringify(sheetsData, null, 2);
+    if (isGetValues) {
+      result = props.data.firstRowAsKey
+        ? convert2DArrayToArrayObj(result.values)
+        : result.values;
+    } else {
+      result = {
+        tableRange: result.tableRange || null,
+        lastRange: result.updates.updatedRange,
+      };
+    }
 
+    previewDataState.data = JSON.stringify(result, null, 2);
     previewDataState.status = 'idle';
   } catch (error) {
+    console.error(error);
     previewDataState.data = '';
     previewDataState.status = 'error';
     previewDataState.errorMessage = error.message;
   }
 }
+function onActionChange(value) {
+  updateData({ type: value });
+
+  previewDataState.data = '';
+  previewDataState.status = '';
+  previewDataState.errorMessage = '';
+}
 </script>

+ 2 - 0
src/locales/en/blocks.json

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

+ 11 - 0
src/utils/api.js

@@ -17,6 +17,17 @@ 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: [],
+      }),
+    });
+  },
   updateValues({ spreadsheetId, range, valueInputOption, options = {} }) {
     const url = `${this.getUrl(spreadsheetId, range)}&valueInputOption=${
       valueInputOption || 'RAW'

+ 4 - 0
src/utils/shared.js

@@ -548,6 +548,10 @@ export const tasks = {
       customData: '',
       description: '',
       spreadsheetId: '',
+      dataColumn: '',
+      saveData: true,
+      assignVariable: false,
+      variableName: '',
       firstRowAsKey: false,
       keysAsFirstRow: true,
       valueInputOption: 'RAW',