Browse Source

feat: add loop through elements option

Ahmad Kholid 3 years ago
parent
commit
f2421de094

+ 37 - 36
src/background/workflow-engine/blocks-handler/handler-loop-data.js

@@ -1,11 +1,10 @@
 import { getBlockConnection } from '../helper';
 import { parseJSON } from '@/utils/helper';
 
-function loopData(block) {
-  return new Promise((resolve, reject) => {
-    const { data } = block;
-    const nextBlockId = getBlockConnection(block);
+async function loopData({ data, id, outputs }) {
+  const nextBlockId = getBlockConnection({ outputs });
 
+  try {
     if (this.loopList[data.loopId]) {
       const index = this.loopList[data.loopId].index + 1;
 
@@ -24,43 +23,41 @@ function loopData(block) {
         $index: index,
       };
     } else {
-      let currLoopData;
-
-      switch (data.loopThrough) {
-        case 'numbers':
-          currLoopData = data.fromNumber;
-          break;
-        case 'table':
-        case 'data-columns':
-          currLoopData = this.referenceData.table;
-          break;
-        case 'google-sheets':
-          currLoopData = this.referenceData.googleSheets[data.referenceKey];
-          break;
-        case 'custom-data':
-          currLoopData = JSON.parse(data.loopData);
-          break;
-        case 'variable': {
+      const getLoopData = {
+        number: () => data.fromNumber,
+        table: () => this.referenceData.table,
+        'custom-data': () => JSON.parse(data.loopData),
+        'data-columns': () => this.referenceData.table,
+        'google-sheets': () =>
+          this.referenceData.googleSheets[data.referenceKey],
+        variable: () => {
           const variableVal = this.referenceData.variables[data.variableName];
-          currLoopData = parseJSON(variableVal, variableVal);
-          break;
-        }
-        default:
-      }
 
-      if (data.loopThrough !== 'numbers' && !Array.isArray(currLoopData)) {
-        const error = new Error('invalid-loop-data');
-        error.nextBlockId = nextBlockId;
+          return parseJSON(variableVal, variableVal);
+        },
+        elements: async () => {
+          const elements = await this._sendMessageToTab({
+            isBlock: false,
+            max: data.maxLoop,
+            type: 'loop-elements',
+            selector: data.elementSelector,
+          });
+
+          return elements;
+        },
+      };
 
-        reject(error);
-        return;
+      const currLoopData = await getLoopData[data.loopThrough]();
+
+      if (data.loopThrough !== 'numbers' && !Array.isArray(currLoopData)) {
+        throw new Error('invalid-loop-data');
       }
 
       this.loopList[data.loopId] = {
         index: 0,
-        data: currLoopData,
+        blockId: id,
         id: data.loopId,
-        blockId: block.id,
+        data: currLoopData,
         type: data.loopThrough,
         maxLoop:
           data.loopThrough === 'numbers'
@@ -75,11 +72,15 @@ function loopData(block) {
       };
     }
 
-    resolve({
+    return {
       nextBlockId,
       data: this.referenceData.loopData[data.loopId],
-    });
-  });
+    };
+  } catch (error) {
+    error.nextBlockId = nextBlockId;
+
+    throw error;
+  }
 }
 
 export default loopData;

+ 9 - 0
src/components/newtab/workflow/edit/EditLoopData.vue

@@ -44,6 +44,14 @@
       class="w-full mt-2"
       @change="updateData({ variableName: $event })"
     />
+    <ui-input
+      v-else-if="data.loopThrough === 'elements'"
+      :model-value="data.elementSelector"
+      :label="t('workflow.blocks.base.selector')"
+      placeholder=".selector"
+      class="mt-2 w-full"
+      @change="updateData({ elementSelector: $event })"
+    />
     <ui-input
       v-if="data.loopThrough !== 'numbers'"
       :model-value="data.maxLoop"
@@ -161,6 +169,7 @@ const loopTypes = [
   'google-sheets',
   'variable',
   'custom-data',
+  'elements',
 ];
 
 const state = shallowReactive({

+ 15 - 0
src/content/index.js

@@ -1,4 +1,5 @@
 import browser from 'webextension-polyfill';
+import { finder } from '@medv/finder';
 import { toCamelCase } from '@/utils/helper';
 import elementSelector from './element-selector';
 import executedBlock from './executed-block';
@@ -49,6 +50,20 @@ import blocksHandler from './blocks-handler';
           });
           resolve();
           break;
+        case 'loop-elements': {
+          const selectors = [];
+          const elements = document.body.querySelectorAll(data.selector);
+
+          elements.forEach((el) => {
+            if (data.max > 0 && selectors.length - 1 > data.max) return;
+
+            selectors.push(finder(el));
+          });
+          console.log(data, selectors);
+
+          resolve(selectors);
+          break;
+        }
         default:
       }
     });

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

@@ -412,7 +412,8 @@
             "data-columns": "Table",
             "table": "Table",
             "custom-data": "Custom data",
-            "google-sheets": "Google sheets"
+            "google-sheets": "Google sheets",
+            "elements": "Elements"
           }
         }
       },

+ 1 - 0
src/utils/shared.js

@@ -596,6 +596,7 @@ export const tasks = {
       description: '',
       variableName: '',
       referenceKey: '',
+      elementSelector: '',
       specificRowAndCol: false,
       loopThrough: 'data-columns',
     },