瀏覽代碼

feat: add 'execute workflows at once' option in collection

Ahmad Kholid 3 年之前
父節點
當前提交
059679f061

+ 22 - 7
src/background/collection-engine/index.js

@@ -3,6 +3,7 @@ import browser from 'webextension-polyfill';
 import { toCamelCase } from '@/utils/helper';
 import { toCamelCase } from '@/utils/helper';
 import * as flowHandler from './flow-handler';
 import * as flowHandler from './flow-handler';
 import workflowState from '../workflow-state';
 import workflowState from '../workflow-state';
+import WorkflowEngine from '../workflow-engine';
 
 
 class CollectionEngine {
 class CollectionEngine {
   constructor(collection) {
   constructor(collection) {
@@ -24,17 +25,31 @@ class CollectionEngine {
     try {
     try {
       if (this.collection.flow.length === 0) return;
       if (this.collection.flow.length === 0) return;
 
 
-      await workflowState.add(this.id, {
-        state: this.state,
-        isCollection: true,
-        collectionId: this.collection.id,
-      });
-
       const { workflows } = await browser.storage.local.get('workflows');
       const { workflows } = await browser.storage.local.get('workflows');
 
 
       this.workflows = workflows;
       this.workflows = workflows;
       this.startedTimestamp = Date.now();
       this.startedTimestamp = Date.now();
-      this._flowHandler(this.collection.flow[0]);
+
+      if (this.collection?.options.atOnce) {
+        this.collection.flow.forEach(({ itemId, type }) => {
+          if (type !== 'workflow') return;
+
+          const currentWorkflow = workflows.find(({ id }) => id === itemId);
+
+          if (currentWorkflow) {
+            const engine = new WorkflowEngine(currentWorkflow, {});
+
+            engine.init();
+          }
+        });
+      } else {
+        await workflowState.add(this.id, {
+          state: this.state,
+          isCollection: true,
+          collectionId: this.collection.id,
+        });
+        this._flowHandler(this.collection.flow[0]);
+      }
     } catch (error) {
     } catch (error) {
       console.error(error);
       console.error(error);
     }
     }

+ 10 - 2
src/background/workflow-engine/blocks-handler.js

@@ -578,13 +578,21 @@ export function repeatTask({ data, id, outputs }) {
 
 
 export function webhook({ data, outputs }) {
 export function webhook({ data, outputs }) {
   return new Promise((resolve, reject) => {
   return new Promise((resolve, reject) => {
+    const nextBlockId = getBlockConnection({ outputs });
+
     if (!data.url) {
     if (!data.url) {
-      reject(new Error('URL is empty'));
+      const error = new Error('URL is empty');
+      error.nextBlockId = nextBlockId;
+
+      reject(error);
       return;
       return;
     }
     }
 
 
     if (!data.url.startsWith('http')) {
     if (!data.url.startsWith('http')) {
-      reject(new Error('URL is not valid'));
+      const error = new Error('URL is not valid');
+      error.nextBlockId = nextBlockId;
+
+      reject(error);
       return;
       return;
     }
     }
 
 

+ 3 - 0
src/models/collection.js

@@ -14,6 +14,9 @@ class Collection extends Model {
       name: this.string(''),
       name: this.string(''),
       flow: this.attr([]),
       flow: this.attr([]),
       createdAt: this.number(),
       createdAt: this.number(),
+      options: this.attr({
+        atOnce: false,
+      }),
     };
     };
   }
   }
 
 

+ 49 - 2
src/newtab/pages/collections/[id].vue

@@ -81,6 +81,7 @@
                 {{ runningCollection.length }}
                 {{ runningCollection.length }}
               </span>
               </span>
             </ui-tab>
             </ui-tab>
+            <ui-tab value="options">Options</ui-tab>
           </ui-tabs>
           </ui-tabs>
         </div>
         </div>
         <ui-tab-panels v-model="state.activeTab">
         <ui-tab-panels v-model="state.activeTab">
@@ -111,7 +112,25 @@
               @update:modelValue="updateCollectionFlow"
               @update:modelValue="updateCollectionFlow"
             >
             >
               <template #item="{ element, index }">
               <template #item="{ element, index }">
-                <ui-card class="group flex cursor-move mb-2 items-center">
+                <ui-card
+                  class="
+                    group
+                    flex
+                    cursor-move
+                    mb-2
+                    items-center
+                    relative
+                    overflow-hidden
+                  "
+                >
+                  <span
+                    :class="[
+                      element.type === 'block'
+                        ? 'bg-yellow-200'
+                        : 'bg-green-200',
+                    ]"
+                    class="absolute w-2 left-0 top-0 h-full"
+                  ></span>
                   <v-remixicon :name="element.icon" class="mr-4" />
                   <v-remixicon :name="element.icon" class="mr-4" />
                   <p class="flex-1 text-overflow">{{ element.name }}</p>
                   <p class="flex-1 text-overflow">{{ element.name }}</p>
                   <router-link
                   <router-link
@@ -167,13 +186,23 @@
               />
               />
             </div>
             </div>
           </ui-tab-panel>
           </ui-tab-panel>
+          <ui-tab-panel value="options">
+            <ui-checkbox v-model="collectionOptions.atOnce">
+              <p class="leading-tight">
+                Execute all workflows in the collection at once
+              </p>
+              <p class="text-sm text-gray-600 leading-tight">
+                Block not gonna executed when using this option
+              </p>
+            </ui-checkbox>
+          </ui-tab-panel>
         </ui-tab-panels>
         </ui-tab-panels>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
 </template>
 </template>
 <script setup>
 <script setup>
-import { computed, shallowReactive, onMounted } from 'vue';
+import { computed, shallowReactive, onMounted, watch } from 'vue';
 import { nanoid } from 'nanoid';
 import { nanoid } from 'nanoid';
 import { useStore } from 'vuex';
 import { useStore } from 'vuex';
 import { useRoute, useRouter } from 'vue-router';
 import { useRoute, useRouter } from 'vue-router';
@@ -213,6 +242,9 @@ const state = shallowReactive({
   activeTab: 'flow',
   activeTab: 'flow',
   sidebarTab: 'workflows',
   sidebarTab: 'workflows',
 });
 });
+const collectionOptions = shallowReactive({
+  atOnce: false,
+});
 
 
 const runningCollection = computed(() =>
 const runningCollection = computed(() =>
   store.state.workflowState.filter(
   store.state.workflowState.filter(
@@ -293,7 +325,22 @@ function deleteCollection() {
   });
   });
 }
 }
 
 
+watch(
+  () => collectionOptions,
+  (value) => {
+    Collection.update({
+      where: route.params.id,
+      data: {
+        options: value,
+      },
+    });
+  },
+  { deep: true }
+);
+
 onMounted(() => {
 onMounted(() => {
+  Object.assign(collectionOptions, collection.value.options);
+
   collectionFlow.value.forEach((item, index) => {
   collectionFlow.value.forEach((item, index) => {
     if (!item.itemId && item.type === 'workflow') {
     if (!item.itemId && item.type === 'workflow') {
       deleteCollectionFlow(index);
       deleteCollectionFlow(index);