浏览代码

feat: settings in the block menu

Ahmad Kholid 2 年之前
父节点
当前提交
1f7e447fbf

+ 9 - 1
src/components/block/BlockBase.vue

@@ -12,6 +12,14 @@
         >
           <v-remixicon size="20" name="riDeleteBin7Line" />
         </button>
+        <button
+          :title="$t('workflow.blocks.base.settings.title')"
+          @click.stop="
+            $emit('settings', { details: blockData.details, data, blockId })
+          "
+        >
+          <v-remixicon size="20" name="riSettings3Line" />
+        </button>
         <button
           v-if="!excludeGroupBlocks.includes(blockData.details?.id)"
           :title="$t('workflow.blocks.base.moveToGroup')"
@@ -74,7 +82,7 @@ const props = defineProps({
     default: '',
   },
 });
-defineEmits(['delete', 'edit', 'update']);
+defineEmits(['delete', 'edit', 'update', 'settings']);
 
 const workflowUtils = inject('workflow-utils', null);
 

+ 2 - 1
src/components/block/BlockBasic.vue

@@ -9,6 +9,7 @@
     @edit="$emit('edit')"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle
       v-if="label !== 'trigger'"
@@ -108,7 +109,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-defineEmits(['delete', 'edit', 'update']);
+defineEmits(['delete', 'edit', 'update', 'settings']);
 
 const { t, te } = useI18n();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockBasicWithFallback.vue

@@ -8,6 +8,7 @@
     @edit="$emit('edit')"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="flex items-center">
@@ -71,7 +72,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-defineEmits(['delete', 'edit', 'update']);
+defineEmits(['delete', 'edit', 'update', 'settings']);
 
 const { t } = useI18n();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockConditions.vue

@@ -8,6 +8,7 @@
     @edit="$emit('edit')"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="flex items-center">
@@ -98,7 +99,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-defineEmits(['delete', 'edit', 'update']);
+defineEmits(['delete', 'settings', 'edit', 'update']);
 
 const { t } = useI18n();
 const componentId = useComponentId('block-conditions');

+ 2 - 1
src/components/block/BlockDelay.vue

@@ -7,6 +7,7 @@
     class="w-48"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="flex items-center mb-2">
@@ -68,7 +69,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-defineEmits(['update', 'delete']);
+defineEmits(['update', 'delete', 'settings']);
 
 const { t } = useI18n();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockElementExists.vue

@@ -8,6 +8,7 @@
     @edit="$emit('edit')"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div
@@ -65,7 +66,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-defineEmits(['delete', 'edit', 'update']);
+defineEmits(['delete', 'edit', 'update', 'settings']);
 
 const { t } = useI18n();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockGroup.vue

@@ -9,6 +9,7 @@
     @edit="$emit('edit')"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="p-4">
@@ -133,7 +134,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-const emit = defineEmits(['update', 'delete', 'edit']);
+const emit = defineEmits(['update', 'delete', 'edit', 'settings']);
 
 const { t, te } = useI18n();
 const toast = useToast();

+ 2 - 1
src/components/block/BlockLoopBreakpoint.vue

@@ -7,6 +7,7 @@
     class="w-48"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="flex items-center mb-2">
@@ -63,7 +64,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-const emit = defineEmits(['delete', 'update']);
+const emit = defineEmits(['delete', 'update', 'settings']);
 
 const { t } = useI18n();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockPackage.vue

@@ -7,6 +7,7 @@
     class="w-64 block-package"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <div class="flex items-center">
       <img
@@ -119,7 +120,7 @@ const props = defineProps({
     default: null,
   },
 });
-const emit = defineEmits(['update', 'delete']);
+const emit = defineEmits(['update', 'delete', 'settings']);
 
 const packageStore = usePackageStore();
 const block = useEditorBlock(props.label);

+ 2 - 1
src/components/block/BlockRepeatTask.vue

@@ -7,6 +7,7 @@
     class="repeat-task w-64"
     @delete="$emit('delete', id)"
     @update="$emit('update', $event)"
+    @settings="$emit('settings', $event)"
   >
     <Handle :id="`${id}-input-1`" type="target" :position="Position.Left" />
     <div class="flex items-center mb-2">
@@ -65,7 +66,7 @@ const props = defineProps({
     default: () => ({}),
   },
 });
-const emit = defineEmits(['delete', 'update']);
+const emit = defineEmits(['delete', 'update', 'settings']);
 
 const block = useEditorBlock(props.label);
 const componentId = useComponentId('block-delay');

+ 2 - 23
src/components/newtab/workflow/WorkflowEditBlock.vue

@@ -9,6 +9,7 @@
       <p class="font-semibold inline-block capitalize">
         {{ getBlockName() }}
       </p>
+      <div class="flex-grow"></div>
       <a
         :title="t('common.docs')"
         :href="`https://docs.automa.site/blocks/${data.id}.html`"
@@ -16,21 +17,8 @@
         target="_blank"
         class="text-gray-600 dark:text-gray-200"
       >
-        <v-remixicon name="riInformationLine" size="20" />
+        <v-remixicon name="riInformationLine" />
       </a>
-      <div class="flex-grow"></div>
-      <ui-switch
-        v-if="data.id !== 'trigger'"
-        v-tooltip="
-          t(
-            `workflow.blocks.base.toggle.${
-              blockData.disableBlock ? 'enable' : 'disable'
-            }`
-          )
-        "
-        :model-value="!blockData.disableBlock"
-        @change="$emit('update', { ...blockData, disableBlock: !$event })"
-      />
     </div>
     <component
       :is="getEditComponent()"
@@ -44,21 +32,12 @@
         connections: data.id === 'wait-connections' ? data.connections : null,
       }"
     />
-    <edit-block-settings
-      v-if="!excludeOnError.includes(data.id)"
-      :key="data.itemId || data.blockId"
-      :data="data"
-      class="mt-4"
-      @change="$emit('update', { ...blockData, ...$event })"
-    />
   </div>
 </template>
 <script setup>
 import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { excludeOnError } from '@/utils/shared';
 import customEditComponents from '@business/blocks/editComponents';
-import EditBlockSettings from './edit/EditBlockSettings.vue';
 
 const editComponents = require.context(
   './edit',

+ 34 - 2
src/components/newtab/workflow/WorkflowEditor.vue

@@ -56,6 +56,7 @@
           editor: name === 'node-BlockPackage' ? editor : null,
         }"
         @delete="deleteBlock"
+        @settings="initEditBlockSettings"
         @edit="editBlock(nodeProps, $event)"
         @update="updateBlockData(nodeProps.id, $event)"
       />
@@ -63,10 +64,21 @@
     <template #edge-custom="edgeProps">
       <editor-custom-edge v-bind="edgeProps" />
     </template>
+    <ui-modal
+      v-model="blockSettingsState.show"
+      :title="t('workflow.blocks.base.settings.title')"
+      content-class="max-w-xl modal-block-settings"
+      @close="clearBlockSettings"
+    >
+      <edit-block-settings
+        :data="blockSettingsState.data"
+        @change="updateBlockData(blockSettingsState.data.blockId, $event)"
+      />
+    </ui-modal>
   </vue-flow>
 </template>
 <script setup>
-import { onMounted, onBeforeUnmount, watch, computed } from 'vue';
+import { onMounted, onBeforeUnmount, watch, computed, reactive } from 'vue';
 import { useI18n } from 'vue-i18n';
 import {
   VueFlow,
@@ -77,8 +89,9 @@ import {
 import { Background, MiniMap } from '@vue-flow/additional-components';
 import cloneDeep from 'lodash.clonedeep';
 import { useStore } from '@/stores/main';
-import { categories } from '@/utils/shared';
 import { getBlocks } from '@/utils/getSharedData';
+import { categories } from '@/utils/shared';
+import EditBlockSettings from './edit/EditBlockSettings.vue';
 import EditorCustomEdge from './editor/EditorCustomEdge.vue';
 import EditorSearchBlocks from './editor/EditorSearchBlocks.vue';
 
@@ -172,6 +185,25 @@ const blocks = getBlocks();
 const settings = store.settings.editor;
 const isDisabled = computed(() => props.options.disabled ?? props.disabled);
 
+const blockSettingsState = reactive({
+  show: false,
+  data: {},
+});
+
+function initEditBlockSettings({ blockId, details, data }) {
+  blockSettingsState.data = {
+    blockId,
+    id: details.id,
+    data: cloneDeep(data),
+  };
+  blockSettingsState.show = true;
+}
+function clearBlockSettings() {
+  Object.assign(blockSettingsState, {
+    data: null,
+    show: false,
+  });
+}
 function minimapNodeClassName({ label }) {
   const { category } = blocks[label];
   const { color } = categories[category];

+ 38 - 58
src/components/newtab/workflow/edit/EditBlockSettings.vue

@@ -1,60 +1,34 @@
 <template>
-  <div class="block-settings">
-    <slot
-      name="button"
-      :active="state.onError.enable"
-      :show="() => (state.showModal = true)"
-    >
-      <ui-button
-        :class="{ 'text-primary': state.onError.enable }"
-        @click="state.showModal = true"
-      >
-        <v-remixicon name="riShieldLine" class="-ml-1 mr-2" />
-        <span>
-          {{ t('workflow.blocks.base.settings.title') }}
-        </span>
-      </ui-button>
-    </slot>
-    <ui-modal
-      v-model="state.showModal"
-      :title="t('workflow.blocks.base.settings.title')"
-      content-class="max-w-xl modal-block-settings"
-    >
-      <ui-tabs v-model="state.activeTab" class="-mt-2">
-        <ui-tab v-for="tab in tabs" :key="tab.id" :value="tab.id">
-          {{ tab.name }}
-        </ui-tab>
-      </ui-tabs>
-      <ui-tab-panels
-        v-if="state.retrieved"
-        v-model="state.activeTab"
-        class="mt-4"
-      >
-        <ui-tab-panel value="general">
-          <block-setting-general
-            v-model:data="state.settings"
-            @change="onDataChange('settings', $event)"
-          />
-        </ui-tab-panel>
-        <ui-tab-panel value="on-error">
-          <slot name="on-error">
-            <block-setting-on-error
-              :data="state.onError"
-              @change="onDataChange('onError', $event)"
-            />
-          </slot>
-        </ui-tab-panel>
-        <ui-tab-panel value="lines">
-          <block-setting-lines :block-id="data.blockId" />
-        </ui-tab-panel>
-      </ui-tab-panels>
-    </ui-modal>
-  </div>
+  <ui-tabs v-model="state.activeTab" class="-mt-2">
+    <ui-tab v-for="tab in tabs" :key="tab.id" :value="tab.id">
+      {{ tab.name }}
+    </ui-tab>
+  </ui-tabs>
+  <ui-tab-panels v-if="state.retrieved" v-model="state.activeTab" class="mt-4">
+    <ui-tab-panel value="general">
+      <block-setting-general
+        v-model:data="state.settings"
+        @change="onDataChange('settings', $event)"
+      />
+    </ui-tab-panel>
+    <ui-tab-panel value="on-error">
+      <slot name="on-error">
+        <block-setting-on-error
+          :data="state.onError"
+          @change="onDataChange('onError', $event)"
+        />
+      </slot>
+    </ui-tab-panel>
+    <ui-tab-panel value="lines">
+      <block-setting-lines :block-id="data.blockId" />
+    </ui-tab-panel>
+  </ui-tab-panels>
 </template>
 <script setup>
 import { reactive, onMounted } from 'vue';
 import { useI18n } from 'vue-i18n';
 import defu from 'defu';
+import { excludeOnError } from '@/utils/shared';
 import BlockSettingLines from './BlockSetting/BlockSettingLines.vue';
 import BlockSettingOnError from './BlockSetting/BlockSettingOnError.vue';
 import BlockSettingGeneral from './BlockSetting/BlockSettingGeneral.vue';
@@ -68,12 +42,15 @@ const props = defineProps({
     type: String,
     default: '',
   },
+  show: Boolean,
 });
-const emit = defineEmits(['change']);
+const emit = defineEmits(['change', 'close']);
 
 const { t } = useI18n();
 
+let currActiveTab = 'on-error';
 const browserType = BROWSER_TYPE;
+const isOnErrorSupported = !excludeOnError.includes(props.data.id);
 const supportedBlocks = ['forms', 'event-click', 'trigger-event', 'press-key'];
 const tabs = [
   {
@@ -82,11 +59,15 @@ const tabs = [
   },
   { id: 'lines', name: t('workflow.blocks.base.settings.line.title') },
 ];
-const isSupported =
+const isDebugSupported =
   browserType !== 'firefox' && supportedBlocks.includes(props.data.id);
 
-if (isSupported) {
+if (isDebugSupported) {
+  currActiveTab = 'general';
   tabs.unshift({ id: 'general', name: t('settings.menu.general') });
+} else if (!isOnErrorSupported) {
+  currActiveTab = 'lines';
+  tabs.shift();
 }
 
 const defaultSettings = {
@@ -105,15 +86,14 @@ const defaultSettings = {
 };
 
 const state = reactive({
-  showModal: false,
   retrieved: false,
+  activeTab: currActiveTab,
   onError: defaultSettings.onError,
   settings: defaultSettings.general,
-  activeTab: !isSupported ? 'on-error' : 'general',
 });
 
 function onDataChange(key, data) {
-  if (!state.retrieved || !state.showModal) return;
+  if (!state.retrieved) return;
 
   state[key] = data;
   emit('change', { [key]: data });
@@ -134,7 +114,7 @@ onMounted(() => {
 
   setTimeout(() => {
     state.retrieved = true;
-  }, 1000);
+  }, 200);
 });
 </script>
 <style>

+ 40 - 44
src/components/newtab/workflow/edit/EditConditions.vue

@@ -20,52 +20,49 @@
         {{ t('workflow.blocks.conditions.add') }}
       </ui-button>
       <div class="flex-grow"></div>
-      <edit-block-settings
-        :data="{ data, blockId }"
-        on-error-label="Cn conditions not met"
-        @change="updateData($event)"
+      <ui-button
+        v-tooltip:bottom="t('common.settings')"
+        icon
+        @click="state.showSettings = !state.showSettings"
       >
-        <template #button="{ show }">
-          <ui-button v-tooltip:bottom="t('common.settings')" icon @click="show">
-            <v-remixicon
-              :name="state.showSettings ? 'riCloseLine' : 'riSettings3Line'"
-            />
-          </ui-button>
-        </template>
-        <template #on-error>
-          <label class="flex items-center mt-6">
-            <ui-switch
-              :model-value="data.retryConditions"
-              @change="updateData({ retryConditions: $event })"
-            />
-            <span class="ml-2 leading-tight">
-              {{ t('workflow.blocks.conditions.retryConditions') }}
-            </span>
-          </label>
-          <div v-if="data.retryConditions" class="mt-2">
-            <ui-input
-              :model-value="data.retryCount"
-              :title="t('workflow.blocks.element-exists.tryFor.title')"
-              :label="t('workflow.blocks.element-exists.tryFor.label')"
-              class="w-full mb-1"
-              type="number"
-              min="1"
-              @change="updateData({ retryCount: +$event })"
-            />
-            <ui-input
-              :model-value="data.retryTimeout"
-              :label="t('workflow.blocks.element-exists.timeout.label')"
-              :title="t('workflow.blocks.element-exists.timeout.title')"
-              class="w-full"
-              type="number"
-              min="200"
-              @change="updateData({ retryTimeout: +$event })"
-            />
-          </div>
-        </template>
-      </edit-block-settings>
+        <v-remixicon
+          :name="state.showSettings ? 'riCloseLine' : 'riSettings3Line'"
+        />
+      </ui-button>
     </div>
+    <template v-if="state.showSettings">
+      <label class="flex items-center mt-6">
+        <ui-switch
+          :model-value="data.retryConditions"
+          @change="updateData({ retryConditions: $event })"
+        />
+        <span class="ml-2 leading-tight">
+          {{ t('workflow.blocks.conditions.retryConditions') }}
+        </span>
+      </label>
+      <div v-if="data.retryConditions" class="mt-2">
+        <ui-input
+          :model-value="data.retryCount"
+          :title="t('workflow.blocks.element-exists.tryFor.title')"
+          :label="t('workflow.blocks.element-exists.tryFor.label')"
+          class="w-full mb-1"
+          type="number"
+          min="1"
+          @change="updateData({ retryCount: +$event })"
+        />
+        <ui-input
+          :model-value="data.retryTimeout"
+          :label="t('workflow.blocks.element-exists.timeout.label')"
+          :title="t('workflow.blocks.element-exists.timeout.title')"
+          class="w-full"
+          type="number"
+          min="200"
+          @change="updateData({ retryTimeout: +$event })"
+        />
+      </div>
+    </template>
     <draggable
+      v-else
       v-model="conditions"
       item-key="id"
       tag="ui-list"
@@ -129,7 +126,6 @@ import { nanoid } from 'nanoid';
 import Draggable from 'vuedraggable';
 import { sleep } from '@/utils/helper';
 import SharedConditionBuilder from '@/components/newtab/shared/SharedConditionBuilder/index.vue';
-import EditBlockSettings from './EditBlockSettings.vue';
 
 const props = defineProps({
   data: {