Browse Source

feat: send error to team

Ahmad Kholid 3 years ago
parent
commit
b6e75877a5

+ 64 - 19
src/background/index.js

@@ -6,6 +6,7 @@ import { fetchApi } from '@/utils/api';
 import getFile from '@/utils/getFile';
 import decryptFlow, { getWorkflowPass } from '@/utils/decryptFlow';
 import convertWorkflowData from '@/utils/convertWorkflowData';
+import getBlockMessage from '@/utils/getBlockMessage';
 import {
   registerSpecificDay,
   registerContextMenu,
@@ -108,26 +109,70 @@ const workflow = {
     });
 
     engine.init();
-    engine.on('destroyed', ({ id, status }) => {
-      if (status === 'stopped') return;
-
-      browser.permissions
-        .contains({ permissions: ['notifications'] })
-        .then((hasPermission) => {
-          if (!hasPermission || !workflowData.settings.notification) return;
-
-          const name = workflowData.name.slice(0, 32);
-
-          browser.notifications.create(`logs:${id}`, {
-            type: 'basic',
-            iconUrl: browser.runtime.getURL('icon-128.png'),
-            title: status === 'success' ? 'Success' : 'Error',
-            message: `${
-              status === 'success' ? 'Successfully' : 'Failed'
-            } to run the "${name}" workflow`,
+    engine.on(
+      'destroyed',
+      ({ id, status, history, startedTimestamp, endedTimestamp }) => {
+        if (
+          workflowData.id.startsWith('team_') &&
+          workflowData.teamId &&
+          status === 'error'
+        ) {
+          let message = '';
+
+          const historyItem = history.at(-1);
+          if (historyItem && historyItem.type === 'error') {
+            message = getBlockMessage(historyItem);
+          }
+
+          const workflowHistory = history.map((item) => {
+            delete item.blockId;
+            delete item.logId;
+            delete item.prevBlockData;
+            delete item.workerId;
+
+            item.description = item.description || '';
+
+            return item;
           });
-        });
-    });
+          const payload = {
+            status,
+            message,
+            endedTimestamp,
+            startedTimestamp,
+            history: workflowHistory,
+          };
+
+          fetchApi(`/teams/${workflowData.teamId}/workflows/logs`, {
+            method: 'POST',
+            body: JSON.stringify({
+              workflowLog: payload,
+              workflowId: workflowData.id,
+            }),
+          }).catch((error) => {
+            console.error(error);
+          });
+        }
+
+        if (status !== 'stopped') {
+          browser.permissions
+            .contains({ permissions: ['notifications'] })
+            .then((hasPermission) => {
+              if (!hasPermission || !workflowData.settings.notification) return;
+
+              const name = workflowData.name.slice(0, 32);
+
+              browser.notifications.create(`logs:${id}`, {
+                type: 'basic',
+                iconUrl: browser.runtime.getURL('icon-128.png'),
+                title: status === 'success' ? 'Success' : 'Error',
+                message: `${
+                  status === 'success' ? 'Successfully' : 'Failed'
+                } to run the "${name}" workflow`,
+              });
+            });
+        }
+      }
+    );
 
     const lastCheckStatus = localStorage.getItem('check-status');
     const isSameDay = dayjs().isSame(lastCheckStatus, 'day');

+ 3 - 11
src/background/workflowEngine/engine.js

@@ -203,16 +203,6 @@ class WorkflowEngine {
     }
   }
 
-  resume({ id, state }) {
-    this.id = id;
-
-    Object.keys(state).forEach((key) => {
-      this[key] = state[key];
-    });
-
-    this.init(state.currentBlock);
-  }
-
   addWorker(detail) {
     this.workerId += 1;
 
@@ -363,7 +353,9 @@ class WorkflowEngine {
         status,
         message,
         id: this.id,
-        currentBlock: this.currentBlock,
+        endedTimestamp,
+        history: this.history,
+        startedTimestamp: this.startedTimestamp,
       });
 
       if (this.workflow.settings.reuseLastState) {

+ 5 - 3
src/components/newtab/workflow/editor/EditorUsedCredentials.vue

@@ -6,7 +6,7 @@
   >
     <ui-popover v-tooltip="t('credential.use.title')" @show="checkCredentials">
       <template #trigger>
-        <button class="p-2 hoverable transition">
+        <button class="p-2 hoverable transition rounded-lg">
           <v-remixicon name="riKey2Line" />
         </button>
       </template>
@@ -50,7 +50,7 @@
   </ui-card>
 </template>
 <script setup>
-import { shallowRef } from 'vue';
+import { ref, onMounted } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { tasks } from '@/utils/shared';
 
@@ -63,7 +63,7 @@ const props = defineProps({
 
 const { t } = useI18n();
 
-const credentials = shallowRef([]);
+const credentials = ref([]);
 
 function checkCredentials() {
   const regex = /\{\{\s*secrets@(.*?)\}\}/;
@@ -113,4 +113,6 @@ function jumpToBlock(nodeId) {
     editorContainer.classList.remove('add-transition');
   }, 300);
 }
+
+onMounted(checkCredentials);
 </script>

+ 2 - 2
src/components/newtab/workflows/WorkflowsUserTeam.vue

@@ -90,7 +90,7 @@ const menu = [
     hasAccess: true,
     icon: 'riDeleteBin7Line',
     attrs: {
-      class: 'text-red-400 dark:text-gray-500',
+      class: 'text-red-400 dark:text-red-500',
     },
   },
   {
@@ -99,7 +99,7 @@ const menu = [
     icon: 'riDeleteBin7Line',
     permissions: ['owner', 'create'],
     attrs: {
-      class: 'text-red-400 dark:text-gray-500',
+      class: 'text-red-400 dark:text-red-500',
     },
   },
 ];

+ 19 - 15
src/components/popup/home/HomeTeamWorkflows.vue

@@ -3,7 +3,7 @@
     <ui-card
       v-for="workflow in workflows"
       :key="workflow.id"
-      class="w-full flex items-center space-x-2 hover:ring-2 hover:ring-gray-900"
+      class="w-full flex items-center relative space-x-2 hover:ring-2 hover:ring-gray-900"
     >
       <div
         class="flex-1 text-overflow cursor-pointer mr-4"
@@ -12,12 +12,13 @@
         <p class="leading-tight text-overflow">{{ workflow.name }}</p>
         <div class="text-gray-500 flex items-center">
           <span>{{ dayjs(workflow.createdAt).fromNow() }}</span>
+          <div class="flex-grow" />
           <span
-            :title="`Team name: ${workflow.teamName}`"
-            class="inline-block text-overflow px-2 text-sm ml-2 text-gray-600 py-1 rounded-md bg-box-transparent w-full"
+            :class="tagColors[workflow.tag]"
+            class="text-overflow px-2 text-sm ml-2 text-gray-600 py-1 rounded-md"
             style="max-width: 120px"
           >
-            {{ workflow.teamName }}
+            {{ workflow.tag }}
           </span>
         </div>
       </div>
@@ -33,6 +34,7 @@ import { computed, onMounted, shallowRef } from 'vue';
 import { useUserStore } from '@/stores/user';
 import { sendMessage } from '@/utils/message';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
+import { tagColors } from '@/utils/shared';
 import dayjs from '@/lib/dayjs';
 
 const props = defineProps({
@@ -64,18 +66,20 @@ function executeWorkflow(workflow) {
 onMounted(() => {
   if (!userStore.user?.teams) return;
 
-  teamWorkflows.value = userStore.user.teams.reduce((acc, team) => {
-    const currentWorkflows = teamWorkflowStore
-      .getByTeam(team.id)
-      .map((workflow) => {
-        workflow.teamId = team.id;
-        workflow.teamName = team.name;
+  teamWorkflows.value = userStore.user.teams
+    .reduce((acc, team) => {
+      const currentWorkflows = teamWorkflowStore
+        .getByTeam(team.id)
+        .map((workflow) => {
+          workflow.teamId = team.id;
+          workflow.teamName = team.name;
 
-        return workflow;
-      });
-    acc.push(...currentWorkflows);
+          return workflow;
+        });
+      acc.push(...currentWorkflows);
 
-    return acc;
-  }, []);
+      return acc;
+    }, [])
+    .sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1));
 });
 </script>

+ 1 - 1
src/content/commandPalette/App.vue

@@ -248,7 +248,7 @@ function onKeydown(event) {
     return;
   }
 
-  if (!(ctrlKey || metaKey) || !shiftKey || key !== 'A') return;
+  if ((!(ctrlKey || metaKey) && !shiftKey) || key.toLowerCase() !== 'a') return;
 
   event.preventDefault();
   state.active = true;

+ 1 - 1
src/utils/shared.js

@@ -1195,7 +1195,7 @@ export const tasks = {
     outputs: 1,
     allowedInputs: true,
     maxConnection: 1,
-    refDataKeys: ['html'],
+    refDataKeys: ['html', 'css'],
     data: {
       disableBlock: false,
       description: '',