Browse Source

feat: add element-exists handler

Ahmad Kholid 3 years ago
parent
commit
1a720a14ef

+ 36 - 10
src/background/blocks-handler.js

@@ -4,11 +4,11 @@ import { objectHasKey } from '@/utils/helper';
 import dataExporter from '@/utils/data-exporter';
 import dataExporter from '@/utils/data-exporter';
 
 
 function getBlockConnection(block, index = 1) {
 function getBlockConnection(block, index = 1) {
-  const blockId = block.outputs[`output_${index}`].connections[0]?.node;
+  const blockId = block.outputs[`output_${index}`]?.connections[0]?.node;
 
 
   return blockId;
   return blockId;
 }
 }
-function converData(data, type) {
+function convertData(data, type) {
   let result = data;
   let result = data;
 
 
   switch (type) {
   switch (type) {
@@ -35,10 +35,7 @@ export function trigger(block) {
 export function openWebsite(block) {
 export function openWebsite(block) {
   return new Promise((resolve, reject) => {
   return new Promise((resolve, reject) => {
     browser.tabs
     browser.tabs
-      .create({
-        active: true,
-        url: block.data.url,
-      })
+      .create(block.data)
       .then((tab) => {
       .then((tab) => {
         this._listener({
         this._listener({
           name: 'tab-updated',
           name: 'tab-updated',
@@ -86,15 +83,22 @@ export function interactionHandler(block) {
       delay: block.name === 'link' ? 5000 : 0,
       delay: block.name === 'link' ? 5000 : 0,
       callback: (data) => {
       callback: (data) => {
         if (objectHasKey(block.data, 'dataColumn')) {
         if (objectHasKey(block.data, 'dataColumn')) {
+          console.log(data);
           const column =
           const column =
             Object.values(this.workflow.dataColumns).find(
             Object.values(this.workflow.dataColumns).find(
               ({ name }) => name === block.data.dataColumn
               ({ name }) => name === block.data.dataColumn
             ) ?? {};
             ) ?? {};
           const name = column.name || 'column';
           const name = column.name || 'column';
-          console.log(column, converData(data, column.type));
-          (this.data[name] = this.data[name] || []).push(
-            converData(data, column.type)
-          );
+
+          if (!objectHasKey(this.data, name)) this.data[name] = [];
+
+          if (Array.isArray(data)) {
+            data.forEach((item) => {
+              this.data[name].push(convertData(item, column.type));
+            });
+          } else {
+            this.data[name].push(convertData(data, column.type));
+          }
         }
         }
 
 
         resolve({
         resolve({
@@ -127,3 +131,25 @@ export function exportData(block) {
     });
     });
   });
   });
 }
 }
+
+export function elementExists(block) {
+  return new Promise((resolve) => {
+    if (!this._connectedTab) return;
+
+    this._connectedTab.postMessage(block);
+    this._listener({
+      name: 'tab-message',
+      id: block.name,
+      once: true,
+      callback: (data) => {
+        console.log(data, 'element-exists');
+        console.log(block.connections, getBlockConnection(block, data ? 1 : 2));
+
+        resolve({
+          data,
+          nextBlockId: getBlockConnection(block, data ? 1 : 2),
+        });
+      },
+    });
+  });
+}

+ 4 - 1
src/components/block/BlockElementExists.vue

@@ -26,7 +26,10 @@
       required
       required
       @input="handleInput"
       @input="handleInput"
     />
     />
-    <p class="text-right text-gray-600">Fallback</p>
+    <p class="text-right text-gray-600">
+      <span title="Execute when element doesn't exists"> &#9432; </span>
+      Fallback
+    </p>
   </div>
   </div>
 </template>
 </template>
 <script setup>
 <script setup>

+ 3 - 1
src/components/block/BlockExportData.vue

@@ -63,7 +63,9 @@ const exportTypes = [
 
 
 watch(
 watch(
   () => block.data,
   () => block.data,
-  debounce((value) => {
+  debounce((value, oldValue) => {
+    if (Object.keys(oldValue).length === 0) return;
+
     props.editor.updateNodeDataFromId(block.id, value);
     props.editor.updateNodeDataFromId(block.id, value);
     emitter.emit('editor:data-changed', block.id);
     emitter.emit('editor:data-changed', block.id);
   }, 250),
   }, 250),

+ 14 - 2
src/components/block/BlockOpenWebsite.vue

@@ -21,17 +21,21 @@
     </div>
     </div>
     <input
     <input
       :value="block.data.url"
       :value="block.data.url"
-      class="px-4 py-2 rounded-lg w-48 bg-input"
+      class="px-4 py-2 mb-1 rounded-lg block w-48 bg-input"
       placeholder="http://example.com"
       placeholder="http://example.com"
       type="url"
       type="url"
       required
       required
       @input="handleInput"
       @input="handleInput"
     />
     />
+    <ui-checkbox :model-value="block.data.active" @change="handleCheckbox">
+      Set as active tab
+    </ui-checkbox>
   </div>
   </div>
 </template>
 </template>
 <script setup>
 <script setup>
 import { VRemixIcon as VRemixicon } from 'v-remixicon';
 import { VRemixIcon as VRemixicon } from 'v-remixicon';
 import emitter from 'tiny-emitter/instance';
 import emitter from 'tiny-emitter/instance';
+import UiCheckbox from '@/components/ui/UiCheckbox.vue';
 import { icons } from '@/lib/v-remixicon';
 import { icons } from '@/lib/v-remixicon';
 import { debounce } from '@/utils/helper';
 import { debounce } from '@/utils/helper';
 import { useComponentId } from '@/composable/componentId';
 import { useComponentId } from '@/composable/componentId';
@@ -57,7 +61,15 @@ const handleInput = debounce(({ target }) => {
 
 
   if (!res) return;
   if (!res) return;
 
 
-  props.editor.updateNodeDataFromId(block.id, { url: res[0] });
+  const [url] = res;
+
+  props.editor.updateNodeDataFromId(block.id, { ...block.data, url });
+  block.data.url = url;
   emitter.emit('editor:data-changed', block.id);
   emitter.emit('editor:data-changed', block.id);
 }, 250);
 }, 250);
+function handleCheckbox(value) {
+  props.editor.updateNodeDataFromId(block.id, { ...block.data, active: value });
+  block.data.active = value;
+  emitter.emit('editor:data-changed', block.id);
+}
 </script>
 </script>

+ 6 - 1
src/components/ui/uiCheckbox.vue

@@ -30,7 +30,7 @@
         "
         "
       >
       >
         <v-remixicon
         <v-remixicon
-          name="riCheckLine"
+          :path="icons.riCheckLine"
           size="20"
           size="20"
           class="text-white"
           class="text-white"
         ></v-remixicon>
         ></v-remixicon>
@@ -42,7 +42,11 @@
   </label>
   </label>
 </template>
 </template>
 <script>
 <script>
+import { VRemixIcon as VRemixicon } from 'v-remixicon';
+import { icons } from '@/lib/v-remixicon';
+
 export default {
 export default {
+  components: { VRemixicon },
   props: {
   props: {
     modelValue: {
     modelValue: {
       type: Boolean,
       type: Boolean,
@@ -57,6 +61,7 @@ export default {
     }
     }
 
 
     return {
     return {
+      icons,
       changeHandler,
       changeHandler,
     };
     };
   },
   },

+ 14 - 6
src/content/blocks-handler.js

@@ -31,7 +31,7 @@ export function eventClick({ data }) {
 export function getText({ data }) {
 export function getText({ data }) {
   return new Promise((resolve) => {
   return new Promise((resolve) => {
     let regex;
     let regex;
-    let textResult = '';
+    const textResult = [];
 
 
     if (data.regex) {
     if (data.regex) {
       regex = new RegExp(data.regex, data.regexExp.join(''));
       regex = new RegExp(data.regex, data.regexExp.join(''));
@@ -42,7 +42,7 @@ export function getText({ data }) {
 
 
       if (regex) text = text.match(regex).join(' ');
       if (regex) text = text.match(regex).join(' ');
 
 
-      textResult += `${text} `;
+      textResult.push(text);
     });
     });
 
 
     resolve(textResult);
     resolve(textResult);
@@ -55,20 +55,20 @@ export function elementScroll({ data }) {
       element.scroll(data.scrollX, data.scrollY);
       element.scroll(data.scrollX, data.scrollY);
     });
     });
 
 
+    window.dispatchEvent(new Event('scroll'));
+
     resolve('');
     resolve('');
   });
   });
 }
 }
 
 
 export function attributeValue({ data }) {
 export function attributeValue({ data }) {
   return new Promise((resolve) => {
   return new Promise((resolve) => {
-    let result = '';
+    const result = [];
 
 
     handleElement(data, (element) => {
     handleElement(data, (element) => {
       const value = element.getAttribute(data.attributeName);
       const value = element.getAttribute(data.attributeName);
 
 
-      window.dispatchEvent(new Event('scroll'));
-
-      result += `${value} `;
+      result.push(value);
     });
     });
 
 
     resolve(result);
     resolve(result);
@@ -124,3 +124,11 @@ export function link({ data }) {
     resolve('');
     resolve('');
   });
   });
 }
 }
+
+export function elementExists({ data }) {
+  return new Promise((resolve) => {
+    const element = document.querySelector(data.selector);
+
+    resolve(!!element);
+  });
+}

+ 1 - 0
src/utils/shared.js

@@ -144,6 +144,7 @@ export const tasks = {
     maxConnection: 1,
     maxConnection: 1,
     data: {
     data: {
       url: '',
       url: '',
+      active: true,
     },
     },
   },
   },
   forms: {
   forms: {