Browse Source

feat: add workflow settings

Ahmad Kholid 3 years ago
parent
commit
84bab7fd9c

+ 7 - 2
src/background/blocks-handler.js

@@ -105,7 +105,10 @@ export async function activeTab(block) {
 export function interactionHandler(block) {
   return new Promise((resolve, reject) => {
     if (!this.connectedTab) {
-      reject(new Error("Can't connect to a tab"));
+      const error = new Error("Can't connect to a tab");
+      error.nextBlockId = getBlockConnection(block);
+      reject(error);
+
       return;
     }
 
@@ -170,7 +173,9 @@ export function exportData(block) {
 export function elementExists(block) {
   return new Promise((resolve, reject) => {
     if (!this.connectedTab) {
-      reject(new Error("Can't connect to a tab"));
+      const error = new Error("Can't connect to a tab");
+      error.nextBlockId = getBlockConnection(block);
+      reject(error);
 
       return;
     }

+ 21 - 2
src/background/workflow-engine.js

@@ -133,6 +133,12 @@ class WorkflowEngine {
     workflowState.update(this.tabId, this.state);
   }
 
+  stop() {
+    /* to-do add stop log */
+    console.log('stoppp');
+    this.destroy();
+  }
+
   destroy() {
     // save log
     this.dispatchEvent('destroyed', this.workflow.id);
@@ -206,12 +212,25 @@ class WorkflowEngine {
             this._blockHandler(this.blocks[result.nextBlockId], result.data);
           } else {
             this.dispatchEvent('finish');
-            this.destroy();
+            this.stop();
             console.log('Done', this);
           }
         })
         .catch((error) => {
-          workflowState.console.error(error, 'new');
+          if (
+            this.workflow.settings.onError === 'keep-running' &&
+            error.nextBlockId
+          ) {
+            this._blockHandler(
+              this.blocks[error.nextBlockId],
+              error.data || ''
+            );
+          } else {
+            this.stop();
+          }
+
+          console.dir(error);
+          console.error(error, 'new');
         });
     } else {
       console.error(`"${block.name}" block doesn't have a handler`);

+ 0 - 1
src/components/newtab/workflow/WorkflowBuilder.vue

@@ -96,7 +96,6 @@ export default {
       emit('load', editor.value);
 
       if (props.data) {
-        console.log(props.data);
         /* to-do delete replace method */
         const data =
           typeof props.data === 'string'

+ 15 - 6
src/components/newtab/workflow/WorkflowDetailsCard.vue

@@ -64,6 +64,14 @@
         </ui-button>
       </template>
       <ui-list>
+        <ui-list-item
+          v-close-popover
+          class="cursor-pointer"
+          @click="$emit('rename')"
+        >
+          <v-remixicon name="riPencilLine" class="mr-2 -ml-1" />
+          <span>Rename</span>
+        </ui-list-item>
         <ui-list-item
           v-close-popover
           class="cursor-pointer"
@@ -75,10 +83,10 @@
         <ui-list-item
           v-close-popover
           class="cursor-pointer"
-          @click="$emit('rename')"
+          @click="$emit('showSettings')"
         >
-          <v-remixicon name="riPencilLine" class="mr-2 -ml-1" />
-          <span>Rename</span>
+          <v-remixicon name="riSettings3Line" class="mr-2 -ml-1" />
+          <span>Settings</span>
         </ui-list-item>
         <ui-list-item
           v-close-popover
@@ -143,12 +151,13 @@ defineProps({
   },
 });
 defineEmits([
-  'update',
-  'execute',
   'save',
-  'showDataColumns',
+  'update',
   'rename',
   'delete',
+  'execute',
+  'showSettings',
+  'showDataColumns',
 ]);
 
 const taskList = Object.keys(tasks).reduce((arr, key) => {

+ 35 - 0
src/components/newtab/workflow/WorkflowSettings.vue

@@ -0,0 +1,35 @@
+<template>
+  <p class="font-semibold mb-2">On workflow error</p>
+  <div class="space-x-4">
+    <ui-radio
+      v-for="item in onError"
+      :key="item.id"
+      :model-value="workflow.settings.onError"
+      :value="item.id"
+      class="mr-4"
+      @change="updateWorkflow({ onError: $event })"
+    >
+      {{ item.name }}
+    </ui-radio>
+  </div>
+</template>
+<script setup>
+const props = defineProps({
+  workflow: {
+    type: Object,
+    default: () => ({}),
+  },
+});
+const emit = defineEmits(['update']);
+
+const onError = [
+  { id: 'keep-running', name: 'Keep workflow running' },
+  { id: 'stop-workflow', name: 'Stop workflow' },
+];
+
+function updateWorkflow(data) {
+  emit('update', {
+    settings: { ...props.workflow.settings, ...data },
+  });
+}
+</script>

+ 83 - 0
src/components/ui/UiRadio.vue

@@ -0,0 +1,83 @@
+<template>
+  <label class="radio-ui inline-flex items-center">
+    <div
+      class="
+        relative
+        h-5
+        w-5
+        inline-block
+        focus-within:ring-2 focus-within:ring-accent
+        rounded-full
+      "
+    >
+      <input
+        type="radio"
+        class="opacity-0 radio-ui__input"
+        :value="value"
+        v-bind="{ checked: isChecked }"
+        @change="changeHandler"
+      />
+      <div
+        class="
+          border
+          rounded-full
+          absolute
+          top-0
+          left-0
+          bg-input
+          radio-ui__mark
+          cursor-pointer
+        "
+      ></div>
+    </div>
+    <span v-if="$slots.default" class="ml-2 inline-block">
+      <slot></slot>
+    </span>
+  </label>
+</template>
+<script>
+import { computed } from 'vue';
+
+export default {
+  props: {
+    modelValue: {
+      type: String,
+      default: '',
+    },
+    value: {
+      type: String,
+      default: undefined,
+    },
+  },
+  emits: ['update:modelValue', 'change'],
+  setup(props, { emit }) {
+    const isChecked = computed(() => props.value === props.modelValue);
+
+    function changeHandler({ target: { value } }) {
+      emit('update:modelValue', value);
+      emit('change', value);
+    }
+
+    return {
+      isChecked,
+      changeHandler,
+    };
+  },
+};
+</script>
+<style scoped>
+.radio-ui__input:checked ~ .radio-ui__mark {
+  border-width: 6px;
+  @apply border-accent;
+}
+.radio-ui__mark {
+  width: 100%;
+  height: 100%;
+  transition-property: background-color, border-color;
+  transition-timing-function: ease;
+  transition-duration: 200ms;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>

+ 2 - 0
src/lib/v-remixicon.js

@@ -2,6 +2,7 @@ import vRemixicon from 'v-remixicon';
 import {
   riHome5Line,
   riDatabase2Line,
+  riSettings3Line,
   riWindowLine,
   riKey2Line,
   riRestartLine,
@@ -54,6 +55,7 @@ import {
 export const icons = {
   riHome5Line,
   riDatabase2Line,
+  riSettings3Line,
   riWindowLine,
   riKey2Line,
   riRestartLine,

+ 3 - 0
src/models/workflow.js

@@ -17,6 +17,9 @@ class Workflow extends Model {
       dataColumns: this.attr([]),
       lastRunAt: this.number(),
       createdAt: this.number(),
+      settings: this.attr({
+        onError: 'keep-running',
+      }),
       tasks: this.hasMany(Task, 'workflowId'),
     };
   }

+ 7 - 0
src/newtab/pages/workflows/[id].vue

@@ -17,6 +17,7 @@
         @execute="executeWorkflow"
         @update="updateWorkflow"
         @showDataColumns="state.showDataColumnsModal = true"
+        @showSettings="state.showSettings = true"
         @rename="renameWorkflow"
         @delete="deleteWorkflow"
       />
@@ -36,6 +37,10 @@
       @close="state.showDataColumnsModal = false"
     />
   </ui-modal>
+  <ui-modal v-model="state.showSettings">
+    <template #header>Workflow settings</template>
+    <workflow-settings v-bind="{ workflow }" @update="updateWorkflow" />
+  </ui-modal>
 </template>
 <script setup>
 /* eslint-disable consistent-return */
@@ -55,6 +60,7 @@ import { debounce } from '@/utils/helper';
 import { useDialog } from '@/composable/dialog';
 import Workflow from '@/models/workflow';
 import WorkflowBuilder from '@/components/newtab/workflow/WorkflowBuilder.vue';
+import WorkflowSettings from '@/components/newtab/workflow/WorkflowSettings.vue';
 import WorkflowEditBlock from '@/components/newtab/workflow/WorkflowEditBlock.vue';
 import WorkflowDetailsCard from '@/components/newtab/workflow/WorkflowDetailsCard.vue';
 import WorkflowDataColumns from '@/components/newtab/workflow/WorkflowDataColumns.vue';
@@ -69,6 +75,7 @@ const editor = shallowRef(null);
 const state = reactive({
   blockData: {},
   isEditBlock: false,
+  showSettings: false,
   isDataChanged: false,
   showDataColumnsModal: false,
 });

+ 1 - 1
src/utils/shared.js

@@ -1,5 +1,5 @@
 /* to-do screenshot, assets, tab loaded, opened tab, and close tab block? */
-/* active-tab: execute workflow on active tab */
+/* prev and next page block? */
 
 export const tasks = {
   trigger: {