Browse Source

feat: delete workflow from team

Ahmad Kholid 3 years ago
parent
commit
05bdec8062

+ 1 - 1
src/components/newtab/shared/SharedCard.vue

@@ -32,7 +32,7 @@
               v-for="item in menu"
               v-for="item in menu"
               :key="item.id"
               :key="item.id"
               v-close-popover
               v-close-popover
-              :class="menu.class"
+              v-bind="item.attrs || {}"
               class="cursor-pointer"
               class="cursor-pointer"
               @click="$emit('menuSelected', { id: item.id, data })"
               @click="$emit('menuSelected', { id: item.id, data })"
             >
             >

+ 1 - 1
src/components/newtab/shared/SharedPermissionsModal.vue

@@ -48,7 +48,7 @@ const { t } = useI18n();
 
 
 const icons = {
 const icons = {
   downloads: 'riDownloadLine',
   downloads: 'riDownloadLine',
-  cliboards: 'riClipboardLine',
+  clipboardRead: 'riClipboardLine',
   contextMenus: 'riFileListLine',
   contextMenus: 'riFileListLine',
   notifications: 'riNotification3Line',
   notifications: 'riNotification3Line',
 };
 };

+ 56 - 6
src/components/newtab/workflow/editor/EditorLocalActions.vue

@@ -165,6 +165,7 @@
         <ui-list-item
         <ui-list-item
           v-for="item in moreActions"
           v-for="item in moreActions"
           :key="item.id"
           :key="item.id"
+          v-bind="item.attrs || {}"
           v-close-popover
           v-close-popover
           class="cursor-pointer"
           class="cursor-pointer"
           @click="item.action"
           @click="item.action"
@@ -172,6 +173,15 @@
           <v-remixicon :name="item.icon" class="mr-2 -ml-1" />
           <v-remixicon :name="item.icon" class="mr-2 -ml-1" />
           {{ item.name }}
           {{ item.name }}
         </ui-list-item>
         </ui-list-item>
+        <ui-list-item
+          v-if="userStore.validateTeamAccess(teamId, ['owner', 'create'])"
+          v-close-popover
+          class="cursor-pointer text-red-400 dark:text-red-500"
+          @click="deleteFromTeam"
+        >
+          <v-remixicon name="riDeleteBin7Line" class="mr-2 -ml-1" />
+          <span>Delete from team</span>
+        </ui-list-item>
       </ui-list>
       </ui-list>
     </ui-popover>
     </ui-popover>
     <ui-button
     <ui-button
@@ -346,7 +356,7 @@ const router = useRouter();
 const dialog = useDialog();
 const dialog = useDialog();
 const userStore = useUserStore();
 const userStore = useUserStore();
 const workflowStore = useWorkflowStore();
 const workflowStore = useWorkflowStore();
-const teamWorkflow = useTeamWorkflowStore();
+const teamWorkflowStore = useTeamWorkflowStore();
 const sharedWorkflowStore = useSharedWorkflowStore();
 const sharedWorkflowStore = useSharedWorkflowStore();
 const shortcuts = useShortcut([
 const shortcuts = useShortcut([
   /* eslint-disable-next-line */
   /* eslint-disable-next-line */
@@ -385,7 +395,7 @@ function updateWorkflow(data = {}, changedIndicator = false) {
   let store = null;
   let store = null;
 
 
   if (props.isTeam) {
   if (props.isTeam) {
-    store = teamWorkflow.update({
+    store = teamWorkflowStore.update({
       data,
       data,
       teamId,
       teamId,
       id: props.workflow.id,
       id: props.workflow.id,
@@ -507,6 +517,35 @@ function shareWorkflow(disabled = false) {
     });
     });
   }
   }
 }
 }
+function deleteFromTeam() {
+  dialog.confirm({
+    async: true,
+    title: 'Delete workflow from team',
+    okVariant: 'danger',
+    body: `Are you sure want to delete the "${props.workflow.name}" workflow from this team?`,
+    onConfirm: async () => {
+      try {
+        const response = await fetchApi(
+          `/teams/${teamId}/workflows/${props.workflow.id}`,
+          { method: 'DELETE' }
+        );
+        const result = await response.json();
+
+        if (!response.ok && response.status !== 404)
+          throw new Error(result.message);
+
+        await teamWorkflowStore.delete(teamId, props.workflow.id);
+        router.replace(`/workflows?active=team&teamId=${teamId}`);
+
+        return true;
+      } catch (error) {
+        toast.error('Something went wrong');
+        console.error(error);
+        return false;
+      }
+    },
+  });
+}
 function clearRenameModal() {
 function clearRenameModal() {
   Object.assign(renameState, {
   Object.assign(renameState, {
     id: '',
     id: '',
@@ -577,7 +616,12 @@ function deleteWorkflow() {
     okVariant: 'danger',
     okVariant: 'danger',
     body: t('message.delete', { name: props.workflow.name }),
     body: t('message.delete', { name: props.workflow.name }),
     onConfirm: async () => {
     onConfirm: async () => {
-      await workflowStore.delete(props.workflow.id);
+      if (props.isTeam) {
+        await teamWorkflowStore.delete(teamId, props.workflow.id);
+      } else {
+        await workflowStore.delete(props.workflow.id);
+      }
+
       router.replace('/');
       router.replace('/');
     },
     },
   });
   });
@@ -638,11 +682,14 @@ async function syncWorkflow() {
     );
     );
     const result = await response.json();
     const result = await response.json();
 
 
-    if (!response.ok) {
-      throw new Error(result.message);
+    if (response.status === 404) {
+      await teamWorkflowStore.delete(teamId, props.workflow.id);
+      router.replace(`/workflows?active=team&teamId=${teamId}`);
+      return;
     }
     }
+    if (!response.ok) throw new Error(result.message);
 
 
-    await teamWorkflow.update({
+    await teamWorkflowStore.update({
       teamId,
       teamId,
       data: result,
       data: result,
       id: props.workflow.id,
       id: props.workflow.id,
@@ -709,6 +756,9 @@ const moreActions = [
     action: deleteWorkflow,
     action: deleteWorkflow,
     name: t('common.delete'),
     name: t('common.delete'),
     icon: 'riDeleteBin7Line',
     icon: 'riDeleteBin7Line',
+    attrs: {
+      class: 'text-red-400 dark:text-gray-500',
+    },
   },
   },
 ];
 ];
 </script>
 </script>

+ 60 - 11
src/components/newtab/workflows/WorkflowsUserTeam.vue

@@ -30,7 +30,7 @@
       v-for="workflow in workflows"
       v-for="workflow in workflows"
       :key="workflow.id"
       :key="workflow.id"
       :data="workflow"
       :data="workflow"
-      :menu="menu"
+      :menu="workflowMenus"
       @menuSelected="onMenuSelected"
       @menuSelected="onMenuSelected"
       @execute="executeWorkflow(workflow)"
       @execute="executeWorkflow(workflow)"
       @click="$router.push(`/teams/${teamId}/workflows/${$event.id}`)"
       @click="$router.push(`/teams/${teamId}/workflows/${$event.id}`)"
@@ -49,6 +49,8 @@
 <script setup>
 <script setup>
 import { computed } from 'vue';
 import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useI18n } from 'vue-i18n';
+import { useToast } from 'vue-toastification';
+import { fetchApi } from '@/utils/api';
 import { useUserStore } from '@/stores/user';
 import { useUserStore } from '@/stores/user';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
 import { useTeamWorkflowStore } from '@/stores/teamWorkflow';
 import { sendMessage } from '@/utils/message';
 import { sendMessage } from '@/utils/message';
@@ -79,16 +81,36 @@ const menu = [
   {
   {
     id: 'delete',
     id: 'delete',
     name: 'Delete',
     name: 'Delete',
+    hasAccess: true,
     icon: 'riDeleteBin7Line',
     icon: 'riDeleteBin7Line',
-    class: 'text-red-400',
+    attrs: {
+      class: 'text-red-400 dark:text-gray-500',
+    },
+  },
+  {
+    id: 'delete-team',
+    name: 'Delete from team',
+    icon: 'riDeleteBin7Line',
+    permissions: ['owner', 'create'],
+    attrs: {
+      class: 'text-red-400 dark:text-gray-500',
+    },
   },
   },
 ];
 ];
 
 
 const { t } = useI18n();
 const { t } = useI18n();
+const toast = useToast();
 const dialog = useDialog();
 const dialog = useDialog();
 const userStore = useUserStore();
 const userStore = useUserStore();
 const teamWorkflowStore = useTeamWorkflowStore();
 const teamWorkflowStore = useTeamWorkflowStore();
 
 
+const workflowMenus = computed(() =>
+  menu.filter((item) => {
+    if (!item.permissions) return true;
+
+    return userStore.validateTeamAccess(props.teamId, item.permissions);
+  })
+);
 const teamWorkflows = computed(() => teamWorkflowStore.getByTeam(props.teamId));
 const teamWorkflows = computed(() => teamWorkflowStore.getByTeam(props.teamId));
 const workflows = computed(() => {
 const workflows = computed(() => {
   const filtered = teamWorkflows.value.filter(({ name }) =>
   const filtered = teamWorkflows.value.filter(({ name }) =>
@@ -106,15 +128,42 @@ function executeWorkflow(workflow) {
   sendMessage('workflow:execute', workflow, 'background');
   sendMessage('workflow:execute', workflow, 'background');
 }
 }
 function onMenuSelected({ id, data }) {
 function onMenuSelected({ id, data }) {
-  if (id !== 'delete') return;
+  if (id === 'delete') {
+    dialog.confirm({
+      title: t('workflow.delete'),
+      okVariant: 'danger',
+      body: t('message.delete', { name: data.name }),
+      onConfirm: () => {
+        teamWorkflowStore.delete(data.teamId, data.id);
+      },
+    });
+  } else if (id === 'delete-team') {
+    dialog.confirm({
+      async: true,
+      title: 'Delete workflow from team',
+      okVariant: 'danger',
+      body: `Are you sure want to delete the "${data.name}" workflow from this team?`,
+      onConfirm: async () => {
+        try {
+          const response = await fetchApi(
+            `/teams/${props.teamId}/workflows/${data.id}`,
+            { method: 'DELETE' }
+          );
+          const result = await response.json();
 
 
-  dialog.confirm({
-    title: t('workflow.delete'),
-    okVariant: 'danger',
-    body: t('message.delete', { name: data.name }),
-    onConfirm: () => {
-      teamWorkflowStore.delete(data.teamId, data.id);
-    },
-  });
+          if (!response.ok && response.status !== 404)
+            throw new Error(result.message);
+
+          await teamWorkflowStore.delete(props.teamId, data.id);
+
+          return true;
+        } catch (error) {
+          toast.error('Something went wrong');
+          console.error(error);
+          return false;
+        }
+      },
+    });
+  }
 }
 }
 </script>
 </script>

+ 1 - 1
src/locales/en/newtab.json

@@ -39,7 +39,7 @@
       "title": "Context menu",
       "title": "Context menu",
       "description": "To execute the workflow via the context menu"
       "description": "To execute the workflow via the context menu"
     },
     },
-    "clipboard": {
+    "clipboardRead": {
       "title": "Clipboard",
       "title": "Clipboard",
       "description": "For accessing the clipboard data"
       "description": "For accessing the clipboard data"
     },
     },