Browse Source

feat: support 'workflow' keyword when referencing data

Ahmad Kholid 3 years ago
parent
commit
d13fb0dfbd

+ 32 - 4
src/background/workflow-engine/blocks-handler/handler-execute-workflow.js

@@ -1,13 +1,26 @@
 import browser from 'webextension-polyfill';
 import WorkflowEngine from '../engine';
 import { getBlockConnection } from '../helper';
-import { isWhitespace } from '@/utils/helper';
+import { isWhitespace, parseJSON } from '@/utils/helper';
+import decryptFlow, { getWorkflowPass } from '@/utils/decrypt-flow';
 
 function workflowListener(workflow, options) {
   return new Promise((resolve, reject) => {
+    if (workflow.isProtected) {
+      const flow = parseJSON(workflow.drawflow, null);
+
+      if (!flow) {
+        const pass = getWorkflowPass(workflow.pass);
+
+        workflow.drawflow = decryptFlow(workflow, pass);
+      }
+    }
+
     const engine = new WorkflowEngine(workflow, options);
     engine.init();
     engine.on('destroyed', ({ id, status, message }) => {
+      options.events.onDestroyed(engine);
+
       if (status === 'error') {
         const error = new Error(message);
         error.data = { logId: id };
@@ -23,9 +36,8 @@ function workflowListener(workflow, options) {
   });
 }
 
-async function executeWorkflow(block) {
-  const nextBlockId = getBlockConnection(block);
-  const { data } = block;
+async function executeWorkflow({ outputs, data }) {
+  const nextBlockId = getBlockConnection({ outputs });
 
   try {
     if (data.workflowId === '') throw new Error('empty-workflow');
@@ -48,6 +60,22 @@ async function executeWorkflow(block) {
         onInit: (engine) => {
           this.childWorkflowId = engine.id;
         },
+        onDestroyed: (engine) => {
+          if (data.executeId) {
+            const { dataColumns, globalData, googleSheets } =
+              engine.referenceData;
+
+            this.referenceData.workflow[data.executeId] = {
+              dataColumns,
+              globalData,
+              googleSheets,
+            };
+          }
+          console.log(
+            'destroyed: ',
+            this.referenceData.workflow[data.executeId]
+          );
+        },
       },
       states: this.states,
       logger: this.logger,

+ 1 - 0
src/background/workflow-engine/engine.js

@@ -45,6 +45,7 @@ class WorkflowEngine {
     };
     this.referenceData = {
       loopData: {},
+      workflow: {},
       dataColumns: [],
       googleSheets: {},
       globalData: parseJSON(globalDataValue, globalDataValue),

+ 8 - 5
src/components/newtab/workflow/WorkflowBuilder.vue

@@ -83,7 +83,7 @@ export default {
       default: '',
     },
   },
-  emits: ['load', 'deleteBlock', 'update'],
+  emits: ['load', 'deleteBlock', 'update', 'save'],
   setup(props, { emit }) {
     useGroupTooltip();
     const { t } = useI18n();
@@ -351,13 +351,16 @@ export default {
             drawflow: { Home: { data: newDrawflowData } },
           };
 
-          emit('update', {
-            version: currentExtVersion,
-            drawflow: JSON.stringify(data),
-          });
+          emit('update', { version: currentExtVersion });
         }
 
         editor.value.import(data);
+
+        if (isOldWorkflow) {
+          setTimeout(() => {
+            emit('save');
+          }, 200);
+        }
       } else {
         editor.value.addNode(
           'trigger',

+ 7 - 0
src/components/newtab/workflow/edit/EditExecuteWorkflow.vue

@@ -14,6 +14,13 @@
         {{ workflow.name }}
       </option>
     </ui-select>
+    <ui-input
+      :model-value="data.executeId"
+      :placeholder="t('workflow.blocks.execute-workflow.executeId')"
+      :title="t('workflow.blocks.execute-workflow.executeId')"
+      class="mb-2 w-full"
+      @change="updateData({ executeId: $event })"
+    />
     <p>{{ t('common.globalData') }}</p>
     <pre
       v-if="!state.showGlobalData"

+ 6 - 1
src/components/popup/home/HomeWorkflowCard.vue

@@ -15,7 +15,12 @@
     <button v-else title="Execute" @click="$emit('execute', workflow)">
       <v-remixicon name="riPlayLine" />
     </button>
-    <ui-popover class="h-6">
+    <v-remixicon
+      v-if="workflow.isProtected"
+      name="riShieldKeyholeLine"
+      class="text-green-600"
+    />
+    <ui-popover v-else class="h-6">
       <template #trigger>
         <button>
           <v-remixicon name="riMoreLine" />

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

@@ -95,6 +95,7 @@
         "name": "Execute workflow",
         "overwriteNote": "This will overwrite the global data of the selected workflow",
         "select": "Select workflow",
+        "executeId": "Execute Id",
         "description": ""
       },
       "google-sheets": {

+ 3 - 2
src/newtab/pages/workflows/[id].vue

@@ -99,10 +99,11 @@
       </div>
       <keep-alive>
         <workflow-builder
-          v-if="activeTab === 'editor' && state.drawflow"
+          v-if="activeTab === 'editor' && state.drawflow !== null"
           class="h-full w-full"
           :data="state.drawflow"
           :version="workflow.version"
+          @save="saveWorkflow"
           @update="updateWorkflow"
           @load="editor = $event"
           @deleteBlock="deleteBlock"
@@ -480,7 +481,7 @@ onMounted(() => {
     router.push('/workflows');
     return;
   }
-
+  console.log(workflow.value, state.drawflow);
   if (workflow.value.isProtected) {
     protectionState.needed = true;
   } else {

+ 4 - 0
src/utils/decrypt-flow.js

@@ -2,6 +2,7 @@ import { nanoid } from 'nanoid';
 import hmacSHA256 from 'crypto-js/hmac-sha256';
 import AES from 'crypto-js/aes';
 import encUtf8 from 'crypto-js/enc-utf8';
+import { parseJSON } from './helper';
 import getPassKey from './get-pass-key';
 
 export function getWorkflowPass(pass) {
@@ -21,5 +22,8 @@ export default function ({ pass, drawflow }, password) {
       message: 'incorrect-password',
     };
 
+  const isDecrypted = parseJSON(drawflow, null);
+  if (isDecrypted) return isDecrypted;
+
   return AES.decrypt(drawflow, password).toString(encUtf8);
 }

+ 1 - 0
src/utils/shared.js

@@ -43,6 +43,7 @@ export const tasks = {
     refDataKeys: ['globalData'],
     data: {
       workflowId: '',
+      executeId: '',
       globalData: '',
     },
   },