Explorar o código

feat: add more option to element-exists block

Ahmad Kholid %!s(int64=3) %!d(string=hai) anos
pai
achega
f788572cb9

+ 49 - 30
src/components/block/BlockElementExists.vue

@@ -1,40 +1,53 @@
 <template>
-  <div :id="componentId" class="p-4 element-exists">
-    <div class="flex items-center mb-2">
-      <div
-        :class="block.category.color"
-        class="inline-block text-sm mr-4 p-2 rounded-lg"
-      >
-        <v-remixicon
-          :path="icons.riFocus3Line"
-          size="20"
-          class="inline-block mr-1"
-        />
-        <span>Element exists</span>
-      </div>
-      <div class="flex-grow"></div>
+  <block-base
+    :id="componentId"
+    class="element-exists"
+    @edit="editBlock"
+    @delete="editor.removeNodeId(`node-${block.id}`)"
+  >
+    <div
+      :class="block.category.color"
+      class="inline-block text-sm mb-2 p-2 rounded-lg"
+    >
       <v-remixicon
-        :path="icons.riDeleteBin7Line"
-        class="cursor-pointer"
-        @click="editor.removeNodeId(`node-${block.id}`)"
+        :path="icons.riFocus3Line"
+        size="20"
+        class="inline-block mr-1"
       />
+      <span>Element exists</span>
     </div>
-    <input
-      :value="block.data.selector"
-      class="px-4 py-2 rounded-lg w-48 mb-2 bg-input"
-      placeholder="Element selector"
-      required
-      @input="handleInput"
-    />
+    <p
+      title="Element selector"
+      class="
+        text-overflow
+        p-2
+        rounded-lg
+        bg-box-transparent
+        text-sm
+        font-mono
+        text-right
+        mb-2
+      "
+      style="max-width: 200px"
+    >
+      {{ block.data.selector || 'Element selector' }}
+    </p>
     <p class="text-right text-gray-600">
       <span title="Execute when element doesn't exists"> &#9432; </span>
       Fallback
     </p>
-  </div>
+    <input
+      type="text"
+      class="hidden trigger"
+      disabled="true"
+      @change="handleDataChanged"
+    />
+  </block-base>
 </template>
 <script setup>
 import { VRemixIcon as VRemixicon } from 'v-remixicon';
 import emitter from 'tiny-emitter/instance';
+import BlockBase from './BlockBase.vue';
 import { icons } from '@/lib/v-remixicon';
 import { useComponentId } from '@/composable/componentId';
 import { useEditorBlock } from '@/composable/editorBlock';
@@ -49,16 +62,22 @@ const props = defineProps({
 const componentId = useComponentId('block-delay');
 const block = useEditorBlock(`#${componentId}`, props.editor);
 
-function handleInput({ target }) {
-  target.reportValidity();
+function editBlock() {
+  emitter.emit('editor:edit-block', {
+    ...block.details,
+    data: block.data,
+    blockId: block.id,
+  });
+}
+function handleDataChanged() {
+  const { data } = props.editor.getNodeFromId(block.id);
 
-  props.editor.updateNodeDataFromId(block.id, { selector: target.value });
-  emitter.emit('editor:data-changed', block.id);
+  block.data = data;
 }
 </script>
 <style>
 .drawflow .element-exists .outputs {
-  top: 74px !important;
+  top: 70px !important;
   transform: none !important;
 }
 .drawflow .element-exists .output {

+ 2 - 0
src/components/newtab/workflow/WorkflowEditBlock.vue

@@ -21,6 +21,7 @@ import EditForms from './edit/EditForms.vue';
 import EditTrigger from './edit/EditTrigger.vue';
 import EditGetText from './edit/EditGetText.vue';
 import EditTriggerEvent from './edit/EditTriggerEvent.vue';
+import EditElementExists from './edit/EditElementExists.vue';
 import EditScrollElement from './edit/EditScrollElement.vue';
 import EditAttributeValue from './edit/EditAttributeValue.vue';
 import EditInteractionBase from './edit/EditInteractionBase.vue';
@@ -31,6 +32,7 @@ export default {
     EditTrigger,
     EditGetText,
     EditTriggerEvent,
+    EditElementExists,
     EditScrollElement,
     EditAttributeValue,
     EditInteractionBase,

+ 41 - 0
src/components/newtab/workflow/edit/EditElementExists.vue

@@ -0,0 +1,41 @@
+<template>
+  <ui-input
+    :model-value="data.selector"
+    label="Element selector"
+    class="mb-1 w-full"
+    @change="updateData({ selector: $event })"
+  />
+  <div class="flex space-x-2">
+    <ui-input
+      :model-value="data.tryCount"
+      class="flex-1"
+      type="number"
+      title="Try check element exists"
+      label="Try for"
+      min="1"
+      @change="updateData({ tryCount: +$event })"
+    />
+    <ui-input
+      :model-value="data.timeout"
+      label="Timeout(ms)"
+      title="Timeout for each try"
+      class="flex-1"
+      type="number"
+      min="200"
+      @change="updateData({ timeout: +$event })"
+    />
+  </div>
+</template>
+<script setup>
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => ({}),
+  },
+});
+const emit = defineEmits(['update:data']);
+
+function updateData(value) {
+  emit('update:data', { ...props.data, ...value });
+}
+</script>

+ 8 - 2
src/components/newtab/workflow/edit/EditInteractionBase.vue

@@ -14,8 +14,10 @@
     class="mb-1 w-full"
     @change="updateData({ selector: $event })"
   />
-  <template v-if="!hideSelector || !data.disableMultiple">
+  <template v-if="!hideSelector">
     <ui-checkbox
+      v-if="!data.disableMultiple && !hideMultiple"
+      class="mr-6"
       :model-value="data.multiple"
       @change="updateData({ multiple: $event })"
     >
@@ -23,7 +25,7 @@
     </ui-checkbox>
     <ui-checkbox
       :model-value="data.markEl"
-      class="ml-6"
+      title="An element will not be selected after marked"
       @change="updateData({ markEl: $event })"
     >
       Mark element
@@ -41,6 +43,10 @@ const props = defineProps({
     type: Boolean,
     default: false,
   },
+  hideMultiple: {
+    type: Boolean,
+    default: false,
+  },
 });
 const emit = defineEmits(['update:data', 'change']);
 

+ 1 - 0
src/components/ui/UiInput.vue

@@ -37,6 +37,7 @@
           @blur="$emit('blur', $event)"
           @input="emitValue"
         />
+        <slot name="append" />
       </div>
     </label>
   </div>

+ 20 - 3
src/content/blocks-handler.js

@@ -159,8 +159,25 @@ export function link(block) {
 
 export function elementExists({ data }) {
   return new Promise((resolve) => {
-    const element = document.querySelector(data.selector);
-    console.log('exists', element);
-    resolve(!!element);
+    let trying = 0;
+
+    function checkElement() {
+      if (trying >= (data.tryCount || 1)) {
+        resolve(false);
+        return;
+      }
+
+      const element = document.querySelector(data.selector);
+      console.log(element, trying);
+      if (element) {
+        resolve(true);
+      } else {
+        trying += 1;
+
+        setTimeout(checkElement, data.timeout || 500);
+      }
+    }
+
+    checkElement();
   });
 }

+ 3 - 0
src/utils/shared.js

@@ -258,6 +258,7 @@ export const tasks = {
     description: 'Check if an element is exists',
     icon: 'riFocus3Line',
     component: 'BlockElementExists',
+    editComponent: 'EditElementExists',
     category: 'conditions',
     inputs: 1,
     outputs: 2,
@@ -265,6 +266,8 @@ export const tasks = {
     maxConnection: 1,
     data: {
       selector: '',
+      tryCount: 1,
+      timeout: 500,
       markEl: false,
     },
   },