Browse Source

feat: add insert data block

Ahmad Kholid 3 years ago
parent
commit
430c43fd96

+ 24 - 0
src/background/workflow-engine/blocks-handler/handler-insert-data.js

@@ -0,0 +1,24 @@
+import { getBlockConnection } from '../helper';
+import { parseJSON } from '@/utils/helper';
+import mustacheReplacer from '@/utils/reference-data/mustache-replacer';
+
+function delay({ outputs, data }, { refData }) {
+  return new Promise((resolve) => {
+    data.dataList.forEach(({ name, value, type }) => {
+      const replacedValue = mustacheReplacer(value, refData);
+      const realValue = parseJSON(replacedValue, replacedValue);
+
+      if (type === 'table') {
+        this.addDataToColumn(name, realValue);
+      } else {
+        this.referenceData.variables[name] = realValue;
+      }
+    });
+
+    resolve({
+      nextBlockId: getBlockConnection({ outputs }),
+    });
+  });
+}
+
+export default delay;

+ 1 - 1
src/components/newtab/logs/LogsDataViewer.vue

@@ -31,7 +31,7 @@
       {{ t('workflow.table.title') }}
     </ui-tab>
     <ui-tab value="variables">
-      {{ t('workflow.variables.title') }}
+      {{ t('workflow.variables.title', 2) }}
     </ui-tab>
   </ui-tabs>
   <shared-codemirror

+ 116 - 0
src/components/newtab/workflow/edit/EditInsertData.vue

@@ -0,0 +1,116 @@
+<template>
+  <div>
+    <ui-textarea
+      :model-value="data.description"
+      :placeholder="t('common.description')"
+      class="w-full"
+      @change="updateData({ description: $event })"
+    />
+    <ul v-show="dataList.length > 0" class="mt-4 data-list">
+      <li
+        v-for="(item, index) in dataList"
+        :key="index"
+        class="mb-4 pb-4 border-b"
+      >
+        <div class="flex mb-2">
+          <ui-select
+            :model-value="item.type"
+            class="mr-2 flex-shrink-0"
+            @change="changeItemType(index, $event)"
+          >
+            <option value="table">
+              {{ t('workflow.table.title') }}
+            </option>
+            <option value="variable">
+              {{ t('workflow.variables.title') }}
+            </option>
+          </ui-select>
+          <ui-input
+            v-if="item.type === 'variable'"
+            v-model="item.name"
+            :placeholder="t('workflow.variables.name')"
+            :title="t('workflow.variables.name')"
+            class="flex-1"
+          />
+          <ui-select
+            v-else
+            v-model="item.name"
+            :placeholder="t('workflow.table.select')"
+          >
+            <option
+              v-for="column in workflow.data.value.table"
+              :key="column.name"
+              :value="column.name"
+            >
+              {{ column.name }}
+            </option>
+          </ui-select>
+        </div>
+        <div class="flex items-center">
+          <ui-input
+            v-model="item.value"
+            placeholder="value"
+            title="value"
+            class="flex-1 mr-2"
+          />
+          <ui-button icon @click="dataList.splice(index, 1)">
+            <v-remixicon name="riDeleteBin7Line" />
+          </ui-button>
+        </div>
+      </li>
+    </ul>
+    <ui-button class="mt-4" variant="accent" @click="addItem">
+      {{ t('common.add') }}
+    </ui-button>
+  </div>
+</template>
+<script setup>
+import { ref, watch, inject } from 'vue';
+import { useI18n } from 'vue-i18n';
+
+const props = defineProps({
+  data: {
+    type: Object,
+    default: () => ({}),
+  },
+});
+const emit = defineEmits(['update:data']);
+
+const { t } = useI18n();
+
+const workflow = inject('workflow');
+const dataList = ref(JSON.parse(JSON.stringify(props.data.dataList)));
+
+function updateData(value) {
+  emit('update:data', { ...props.data, ...value });
+}
+function addItem() {
+  dataList.value.push({
+    type: 'table',
+    name: '',
+    value: '',
+  });
+}
+function changeItemType(index, type) {
+  dataList.value[index] = {
+    ...dataList.value[index],
+    type,
+    name: '',
+  };
+}
+
+watch(
+  dataList,
+  (value) => {
+    updateData({ dataList: value });
+  },
+  { deep: true }
+);
+</script>
+<style scoped>
+.data-list li:last-child {
+  padding-bottom: 0;
+  margin-bottom: 0;
+  border-bottom: 0;
+}
+</style>

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

@@ -32,6 +32,10 @@
           "timeout": "Selector timeout (ms)"
         }
       },
+      "insert-data": {
+        "name": "Insert data",
+        "description": "Insert data into table or variable"
+      },
       "clipboard": {
         "name": "Clipboard",
         "description": "Get the copied text from the clipboard",
@@ -42,7 +46,7 @@
       "upload-file": {
         "name": "Upload file",
         "description": "Upload file into <input type=\"file\"> element",
-        "filePath": "File path",
+        "filePath": "URL or File path",
         "addFile": "Add file",
         "requirement": "See the requirement before using this block",
         "noFileAccess": "Automa doesn't have file access"

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

@@ -113,7 +113,7 @@
       "unpublish": "Unpublish"
     },
     "variables": {
-      "title": "Variables",
+      "title": "Variable | Variables",
       "name": "Variable name",
       "assign": "Assign to variable"
     },
@@ -137,6 +137,7 @@
     "table": {
       "title": "Table",
       "placeholder": "Search or add column",
+      "select": "Select column",
       "column": {
         "name": "Column name",
         "type": "Data type"

+ 1 - 1
src/utils/reference-data/mustache-replacer.js

@@ -118,7 +118,7 @@ export default function (str, refData) {
   if (!str || typeof str !== 'string') return '';
 
   const data = { ...refData, functions };
-  const replacedStr = replacer(str, {
+  const replacedStr = replacer(`${str}`, {
     data,
     tagLen: 2,
     regex: /\{\{(.*?)\}\}/g,

+ 16 - 0
src/utils/shared.js

@@ -666,6 +666,22 @@ export const tasks = {
       dataColumn: '',
     },
   },
+  'insert-data': {
+    name: 'Insert data',
+    description: 'Insert data into table or variable',
+    icon: 'riDatabase2Line',
+    component: 'BlockBasic',
+    category: 'general',
+    editComponent: 'EditInsertData',
+    inputs: 1,
+    outputs: 1,
+    allowedInputs: true,
+    maxConnection: 1,
+    data: {
+      description: '',
+      dataList: [],
+    },
+  },
   'switch-to': {
     name: 'Switch frame',
     description: 'Switch between main window and iframe',