Browse Source

feat: use forms in Automa shortcut

Ahmad Kholid 2 years ago
parent
commit
987f116a81

+ 92 - 56
src/content/commandPalette/App.vue

@@ -47,42 +47,37 @@
         </div>
         <template v-else>
           <div v-if="paramsState.active">
-            <div class="p-2 rounded-lg bg-box-transparent">
-              <p class="text-sm text-gray-500">Workflow parameters</p>
-              <div>
-                <span
-                  v-for="(item, index) in paramsState.items"
-                  :key="item.name"
-                  :class="{
-                    'font-semibold': paramsState.activeIndex === index,
-                  }"
+            <ul class="space-y-4 divide-y">
+              <li
+                v-for="(param, paramIdx) in paramsState.items"
+                :key="paramIdx"
+              >
+                <component
+                  :is="paramsList[param.type].valueComp"
+                  v-if="paramsList[param.type]"
+                  v-model="param.value"
+                  :label="param.name"
+                  :param-data="param"
+                  class="w-full"
+                />
+                <ui-input
+                  v-else
+                  v-model="param.value"
+                  :type="param.inputType || param.type"
+                  :label="param.name"
+                  :placeholder="param.placeholder"
+                  class="w-full"
+                  @keyup.enter="runWorkflow(index, workflow)"
+                />
+                <p
+                  v-if="param.description"
+                  title="Description"
+                  class="ml-1 text-sm"
                 >
-                  {{ item.name }};
-                </span>
-              </div>
-            </div>
-            <div class="pl-2 text-gray-500">
-              <p class="mt-2">
-                Example:
-                <span v-for="item in paramsState.items" :key="item.name">
-                  {{ item.placeholder || defaultPlaceholders[item.type] }};
-                </span>
-              </p>
-              <div class="flex items-center mt-4">
-                <p class="flex-1 mr-4">
-                  {{ paramsState.workflow.description }}
-                </p>
-                <p>
-                  Press
-                  <span
-                    class="rounded-md bg-box-transparent p-1 text-gray-600 ml-1 text-xs text-center inline-block border-2 border-gray-300 font-semibold"
-                  >
-                    Escape
-                  </span>
-                  to cancel
+                  {{ param.description }}
                 </p>
-              </div>
-            </div>
+              </li>
+            </ul>
           </div>
           <template v-else>
             <p
@@ -136,8 +131,25 @@
           </template>
         </template>
       </div>
-      <div class="px-4 py-2">
+      <div class="px-4 py-2 flex items-center">
+        <div v-if="paramsState.active" class="pl-2 text-gray-500">
+          <div class="flex items-center">
+            <p class="mr-4">
+              {{ paramsState.workflow.description }}
+            </p>
+            <p>
+              Press
+              <span
+                class="rounded-md bg-box-transparent p-1 text-gray-600 ml-1 text-xs text-center inline-block border-2 border-gray-300 font-semibold"
+              >
+                Escape
+              </span>
+              to cancel
+            </p>
+          </div>
+        </div>
         <p
+          v-else
           class="inline-flex items-center cursor-pointer text-gray-600"
           @click="openDashboard"
         >
@@ -148,6 +160,14 @@
             size="20"
           />
         </p>
+        <div class="flex-grow" />
+        <ui-button
+          v-if="paramsState.active"
+          variant="accent"
+          @click="executeWorkflowWithParams"
+        >
+          Execute
+        </ui-button>
       </div>
     </ui-card>
   </div>
@@ -155,6 +175,7 @@
 <script setup>
 import {
   onMounted,
+  reactive,
   onBeforeUnmount,
   shallowReactive,
   watch,
@@ -163,14 +184,20 @@ import {
   inject,
 } from 'vue';
 import browser from 'webextension-polyfill';
+import workflowParameters from '@business/parameters';
 import { getReadableShortcut } from '@/composable/shortcut';
 import { sendMessage } from '@/utils/message';
 import { debounce } from '@/utils/helper';
-
-const defaultPlaceholders = {
-  string: 'Text',
-  number: '123123',
+import ParameterInputValue from '@/components/newtab/workflow/edit/Parameter/ParameterInputValue.vue';
+
+const paramsList = {
+  string: {
+    id: 'string',
+    name: 'Input (string)',
+    valueComp: ParameterInputValue,
+  },
 };
+
 const logoUrl = browser.runtime.getURL('/icon-128.png');
 
 const inputRef = ref(null);
@@ -181,7 +208,7 @@ const state = shallowReactive({
   shortcutKeys: [],
   selectedIndex: -1,
 });
-const paramsState = shallowReactive({
+const paramsState = reactive({
   items: [],
   workflow: {},
   active: false,
@@ -240,6 +267,7 @@ function executeWorkflow(workflow) {
 
     paramsState.workflow = workflow;
     paramsState.items = triggerData.parameters;
+
     paramsState.active = true;
   } else {
     sendExecuteCommand(workflow);
@@ -249,6 +277,28 @@ function executeWorkflow(workflow) {
   state.query = '';
   paramsState.inputtedVal = '';
 }
+function getParamsValues(params) {
+  const getParamVal = {
+    string: (str) => str,
+    number: (num) => (Number.isNaN(+num) ? 0 : +num),
+    default: (value) => value,
+  };
+
+  return params.reduce((acc, param) => {
+    const valueFunc =
+      getParamVal[param.type] ||
+      paramsList[param.type]?.getValue ||
+      getParamVal.default;
+    const value = valueFunc(param.value || param.defaultValue);
+    acc[param.name] = value;
+
+    return acc;
+  }, {});
+}
+function executeWorkflowWithParams() {
+  const variables = getParamsValues(paramsState.items);
+  sendExecuteCommand(paramsState.workflow, { data: { variables } });
+}
 function onKeydown(event) {
   const { ctrlKey, altKey, metaKey, key, shiftKey } = event;
 
@@ -301,22 +351,7 @@ function onInputKeydown(event) {
   }
 
   if (key === 'Enter') {
-    if (paramsState.active) {
-      const variables = {};
-      const values = paramsState.inputtedVal.split(';');
-
-      paramsState.items.forEach((item, index) => {
-        let value = values[index] ?? '';
-        if (item.type === 'number') value = +value ?? '';
-
-        variables[item.name] = value;
-      });
-
-      sendExecuteCommand(paramsState.workflow, { data: { variables } });
-
-      return;
-    }
-
+    if (paramsState.active) return;
     executeWorkflow(workflows.value[state.selectedIndex]);
   }
 }
@@ -411,6 +446,7 @@ onMounted(() => {
   });
 
   window.addEventListener('keydown', onKeydown);
+  Object.assign(paramsList, workflowParameters());
 });
 onBeforeUnmount(() => {
   window.removeEventListener('keydown', onKeydown);

+ 3 - 1
src/content/commandPalette/compsUi.js

@@ -7,17 +7,19 @@ import UiButton from '@/components/ui/UiButton.vue';
 import UiSelect from '@/components/ui/UiSelect.vue';
 import UiSpinner from '@/components/ui/UiSpinner.vue';
 import UiTextarea from '@/components/ui/UiTextarea.vue';
+import UiPopover from '@/components/ui/UiPopover.vue';
 import TransitionExpand from '@/components/transitions/TransitionExpand.vue';
 
 export default function (app) {
   app.component('UiCard', UiCard);
   app.component('UiList', UiList);
-  app.component('UiListItem', UiListItem);
   app.component('UiInput', UiInput);
   app.component('UiButton', UiButton);
   app.component('UiSelect', UiSelect);
+  app.component('UiPopover', UiPopover);
   app.component('UiSpinner', UiSpinner);
   app.component('UiTextarea', UiTextarea);
+  app.component('UiListItem', UiListItem);
   app.component('TransitionExpand', TransitionExpand);
 
   app.directive('autofocus', VAutofocus);

+ 2 - 0
src/content/commandPalette/icons.js

@@ -13,6 +13,7 @@ import {
   riDownloadLine,
   riCommandLine,
   riExternalLinkLine,
+  riArrowDropDownLine,
 } from 'v-remixicon/icons';
 
 export default {
@@ -30,4 +31,5 @@ export default {
   riDownloadLine,
   riCommandLine,
   riExternalLinkLine,
+  riArrowDropDownLine,
 };