Browse Source

feat: improve editor autocomplete

Ahmad Kholid 2 years ago
parent
commit
0dd0d01ab0
2 changed files with 85 additions and 38 deletions
  1. 14 38
      src/newtab/pages/workflows/[id].vue
  2. 71 0
      src/utils/editor/editorAutocomplete.js

+ 14 - 38
src/newtab/pages/workflows/[id].vue

@@ -309,6 +309,7 @@ import dbStorage from '@/db/storage';
 import DroppedNode from '@/utils/editor/DroppedNode';
 import EditorCommands from '@/utils/editor/EditorCommands';
 import convertWorkflowData from '@/utils/convertWorkflowData';
+import extractAutocopmleteData from '@/utils/editor/editorAutocomplete';
 import WorkflowShare from '@/components/newtab/workflow/WorkflowShare.vue';
 import WorkflowEditor from '@/components/newtab/workflow/WorkflowEditor.vue';
 import WorkflowSettings from '@/components/newtab/workflow/WorkflowSettings.vue';
@@ -349,6 +350,11 @@ const teamWorkflowStore = useTeamWorkflowStore();
 const { teamId, id: workflowId } = route.params;
 const isTeamWorkflow = route.name === 'team-workflows';
 const isPackage = route.name === 'packages-details';
+const funcsAutocomplete = Object.keys(functions).reduce((acc, name) => {
+  acc[`$${name}`] = '';
+
+  return acc;
+}, {});
 
 const editor = shallowRef(null);
 const connectedTable = shallowRef(null);
@@ -466,27 +472,23 @@ const workflowModals = {
     },
   },
 };
-const autocompleteKeys = {
-  loopId: 'loopData',
-  refKey: 'googleSheets',
-  variableName: 'variables',
-};
 
 const autocompleteList = computed(() => {
   const autocompleteData = {
     loopData: {},
     googleSheets: {},
     table: {},
-    ...Object.keys(functions),
+    ...funcsAutocomplete,
     globalData: autocompleteState.common.globalData,
     variables: { ...autocompleteState.common.variables },
   };
 
   Object.values(autocompleteState.blocks).forEach((item) => {
-    Object.keys(item).forEach((key) => {
-      const autocompleteKey = autocompleteKeys[key] || [];
-      autocompleteData[autocompleteKey][item[key]] = '';
-    });
+    if (item.loopData) Object.assign(autocompleteData.loopData, item.loopData);
+    if (item.variables)
+      Object.assign(autocompleteData.variables, item.variables);
+    if (item.googleSheets)
+      Object.assign(autocompleteData.googleSheets, item.googleSheets);
   });
 
   return autocompleteData;
@@ -863,33 +865,6 @@ function ungroupBlocks({ nodes }) {
   editor.value.addSelectedNodes(groupBlocksList);
   editor.value.addEdges(edges);
 }
-function extractAutocopmleteData(label, { data, id }) {
-  const autocompleteData = { [id]: {} };
-  const getData = (blockName, blockData) => {
-    const keys = blocks[blockName]?.autocomplete;
-    const dataList = {};
-    if (!keys) return dataList;
-
-    keys.forEach((key) => {
-      const value = blockData[key];
-      if (!value) return;
-
-      dataList[key] = value;
-    });
-
-    return dataList;
-  };
-
-  if (label === 'blocks-group') {
-    data.blocks.forEach((block) => {
-      autocompleteData[block.itemId] = getData(block.id, block.data);
-    });
-  } else {
-    autocompleteData[id] = getData(label, data);
-  }
-
-  return autocompleteData;
-}
 async function initAutocomplete() {
   const autocompleteCache = sessionStorage.getItem(
     `autocomplete:${workflowId}`
@@ -1598,7 +1573,8 @@ onBeforeUnmount(() => {
   const editorContainer = document.querySelector(
     '.vue-flow__viewport.vue-flow__container'
   );
-  editorContainer.removeEventListener('click', onClickEditor);
+  if (editorContainer)
+    editorContainer.removeEventListener('click', onClickEditor);
 
   window.onbeforeunload = null;
   window.removeEventListener('keydown', onKeydown);

+ 71 - 0
src/utils/editor/editorAutocomplete.js

@@ -0,0 +1,71 @@
+import { getBlocks } from '../getSharedData';
+
+const blocks = getBlocks();
+const autocompleteKeys = {
+  loopId: 'loopData',
+  refKey: 'googleSheets',
+  variableName: 'variables',
+};
+
+function getData(blockName, blockData) {
+  const keys = blocks[blockName]?.autocomplete;
+  const dataList = {};
+  if (!keys) return dataList;
+
+  keys.forEach((key) => {
+    const value = blockData[key];
+    if (!value) return;
+
+    const autocompleteKey = autocompleteKeys[key];
+    if (!dataList[autocompleteKey]) dataList[autocompleteKey] = {};
+
+    dataList[autocompleteKey][value] = '';
+  });
+
+  return dataList;
+}
+
+const extractBlocksAutocomplete = {
+  trigger(blockId, data) {
+    if (!this[blockId].variables) this[blockId].variables = {};
+
+    data.parameters?.forEach((param) => {
+      this[blockId].variables[param.name] = '';
+    });
+
+    if (data.type === 'context-menu') {
+      Object.assign(this[blockId].variables, {
+        $ctxElSelector: '',
+        $ctxTextSelection: '',
+        $ctxLink: '',
+        $ctxMediaUrl: '',
+      });
+    }
+  },
+  'blocks-group': function (blockId, data) {
+    data.blocks.forEach((block) => {
+      this[block.itemId] = getData(block.id, block.data);
+    });
+  },
+  'insert-data': function (blockId, data) {
+    if (!this[blockId].variables) this[blockId].variables = {};
+
+    data.dataList.forEach((item) => {
+      if (item.type !== 'variable' || !item.name.trim()) return;
+
+      this[blockId].variables[item.name] = '';
+    });
+  },
+};
+
+export default function (label, { data, id }) {
+  const autocompleteData = { [id]: {} };
+
+  if (extractBlocksAutocomplete[label]) {
+    extractBlocksAutocomplete[label].call(autocompleteData, id, data);
+  } else {
+    autocompleteData[id] = getData(label, data);
+  }
+
+  return autocompleteData;
+}