diff --git a/src/App.vue b/src/App.vue
index d0f06f24..da2ce8ac 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -106,7 +106,7 @@ watchEffect(() => {
 
 <template>
   <v-app class="text-noselect">
-    <component v-for="dialog in dialogStore.dialogs" :is="dialog.component" v-bind="{ guid: dialog.guid, ...dialog.props }" />
+    <component v-for="dialog in dialogStore.dialogs.values()" :is="dialog.component" v-bind="{ guid: dialog.guid, ...dialog.props }" />
     <Navbar v-if="authStore.isAuthenticated" />
     <v-main>
       <router-view />
diff --git a/src/components/DnDZone.vue b/src/components/DnDZone.vue
index a5517013..6f71f6fe 100644
--- a/src/components/DnDZone.vue
+++ b/src/components/DnDZone.vue
@@ -36,7 +36,7 @@ function onDrop(files: File[] | null, event: DragEvent) {
   links.forEach(addTorrentStore.pushTorrentToQueue)
 
   if (!dialogStore.hasActiveDialog) {
-    dialogStore.createDialog(AddTorrentDialog, {})
+    dialogStore.createDialog(AddTorrentDialog)
   }
 }
 
diff --git a/src/components/Settings/TagsAndCategories.vue b/src/components/Settings/TagsAndCategories.vue
index 023b6bee..a53224ba 100644
--- a/src/components/Settings/TagsAndCategories.vue
+++ b/src/components/Settings/TagsAndCategories.vue
@@ -3,14 +3,11 @@ import CategoryFormDialog from '@/components/Dialogs/CategoryFormDialog.vue'
 import TagFormDialog from '@/components/Dialogs/TagFormDialog.vue'
 import { useDialogStore, useMaindataStore } from '@/stores'
 import { Category } from '@/types/qbit/models'
-import { onBeforeMount, ref, watch } from 'vue'
+import { onBeforeMount } from 'vue'
 
 const dialogStore = useDialogStore()
 const maindataStore = useMaindataStore()
 
-const tagDialog = ref('')
-const categoryDialog = ref('')
-
 async function deleteTag(tagName: string) {
   await maindataStore.deleteTags([tagName])
   await maindataStore.fetchTags()
@@ -22,35 +19,17 @@ async function deleteCategory(category: Category) {
 }
 
 function openTagFormDialog(initialTag?: string) {
-  tagDialog.value = dialogStore.createDialog(TagFormDialog, { initialTag })
+  dialogStore.createDialog(TagFormDialog, { initialTag }, maindataStore.fetchTags)
 }
 
 function openCategoryFormDialog(initialCategory?: Category) {
-  categoryDialog.value = dialogStore.createDialog(CategoryFormDialog, { initialCategory })
+  dialogStore.createDialog(CategoryFormDialog, { initialCategory }, maindataStore.fetchCategories)
 }
 
 onBeforeMount(async () => {
   await maindataStore.fetchCategories()
   await maindataStore.fetchTags()
 })
-
-watch(
-  () => dialogStore.isDialogOpened(tagDialog.value),
-  value => {
-    if (!value) {
-      maindataStore.fetchTags()
-    }
-  }
-)
-
-watch(
-  () => dialogStore.isDialogOpened(categoryDialog.value),
-  value => {
-    if (!value) {
-      maindataStore.fetchCategories()
-    }
-  }
-)
 </script>
 
 <template>
diff --git a/src/pages/MagnetHandler.vue b/src/pages/MagnetHandler.vue
index d47455e8..0a6af71c 100644
--- a/src/pages/MagnetHandler.vue
+++ b/src/pages/MagnetHandler.vue
@@ -14,7 +14,7 @@ onBeforeMount(async () => {
   if (magnetLink.startsWith('magnet:')) {
     addTorrentStore.isFirstInit = false
     addTorrentStore.pushTorrentToQueue(magnetLink)
-    dialogStore.createDialog(AddTorrentDialog, {})
+    dialogStore.createDialog(AddTorrentDialog)
   }
   await router.push({ name: 'dashboard' })
 })
diff --git a/src/stores/content.ts b/src/stores/content.ts
index 6c14415b..c323a3ee 100644
--- a/src/stores/content.ts
+++ b/src/stores/content.ts
@@ -8,7 +8,7 @@ import { TorrentFile } from '@/types/qbit/models'
 import { RightClickMenuEntryType, RightClickProperties, TreeFolder, TreeNode } from '@/types/vuetorrent'
 import { useIntervalFn } from '@vueuse/core'
 import { defineStore, storeToRefs } from 'pinia'
-import { computed, nextTick, reactive, ref, toRaw, watch } from 'vue'
+import { computed, nextTick, reactive, ref, toRaw } from 'vue'
 import { useI18n } from 'vue-i18n'
 import { useRoute } from 'vue-router'
 
@@ -104,28 +104,20 @@ export const useContentStore = defineStore('content', () => {
     await nextTick()
   }
 
-  const renameDialog = ref('')
-
-  const renamePayload = reactive({
-    hash: '',
-    isFolder: false,
-    oldName: ''
-  })
-
   async function renameNode(node: TreeNode) {
     const { default: MoveTorrentFileDialog } = await import('@/components/Dialogs/MoveTorrentFileDialog.vue')
-    renamePayload.hash = hash.value
-    renamePayload.isFolder = node.type === 'folder'
-    renamePayload.oldName = node.fullName
-    renameDialog.value = dialogStore.createDialog(MoveTorrentFileDialog, renamePayload)
+    const payload = {
+      hash: hash.value,
+      isFolder: node.type === 'folder',
+      oldName: node.fullName
+    }
+    dialogStore.createDialog(MoveTorrentFileDialog, payload, updateFileTree)
   }
 
   async function bulkRename(node: TreeFolder) {
     const { default: BulkRenameFilesDialog } = await import('@/components/Dialogs/BulkRenameFilesDialog.vue')
-    renameDialog.value = dialogStore.createDialog(BulkRenameFilesDialog, {
-      hash: hash.value,
-      node
-    })
+    const payload = { hash: hash.value, node }
+    dialogStore.createDialog(BulkRenameFilesDialog, payload, updateFileTree)
   }
 
   async function renameTorrentFile(hash: string, oldPath: string, newPath: string) {
@@ -141,15 +133,6 @@ export const useContentStore = defineStore('content', () => {
     await updateFileTree()
   }
 
-  watch(
-    () => dialogStore.isDialogOpened(renameDialog.value),
-    async v => {
-      if (!v) {
-        await updateFileTree()
-      }
-    }
-  )
-
   return {
     rightClickProperties,
     internalSelection,
diff --git a/src/stores/dialog.ts b/src/stores/dialog.ts
index 5f2b517e..21884869 100644
--- a/src/stores/dialog.ts
+++ b/src/stores/dialog.ts
@@ -8,33 +8,38 @@ type DialogTemplate<C extends Component> = {
   component: C
   props: ComponentProps<C>
   guid: string
+  onClose?: () => any | Promise<any>
 }
 
 export const useDialogStore = defineStore('dialogs', () => {
-  const dialogs = shallowRef<DialogTemplate<any>[]>([])
+  const dialogs = shallowRef<Map<string, DialogTemplate<any>>>(new Map())
 
-  const hasActiveDialog = computed(() => dialogs.value.length > 0)
+  const hasActiveDialog = computed(() => dialogs.value.size > 0)
 
   function isDialogOpened(guid: string) {
-    return !!dialogs.value.find(dialog => dialog.guid === guid)
+    return dialogs.value.has(guid)
   }
 
-  function createDialog<C extends Component>(component: C, props?: Omit<ComponentProps<C>, 'guid'>) {
+  function createDialog<C extends Component>(component: C, props?: Omit<ComponentProps<C>, 'guid'>, onClose?: () => any | Promise<any>) {
     const guid = uuidv4()
-    const template = {
+    dialogs.value.set(guid, {
       component,
       props: props || {},
-      guid
-    }
-
-    dialogs.value.push(template)
+      guid,
+      onClose
+    })
     triggerRef(dialogs)
 
     return guid
   }
 
   function deleteDialog(guid: string) {
-    dialogs.value = dialogs.value.filter(dialog => dialog.guid !== guid)
+    const template = dialogs.value.get(guid)
+    if (template && template.onClose) {
+      template.onClose()
+    }
+    dialogs.value.delete(guid)
+    triggerRef(dialogs)
   }
 
   return {
@@ -44,7 +49,8 @@ export const useDialogStore = defineStore('dialogs', () => {
     createDialog,
     deleteDialog,
     $reset: () => {
-      dialogs.value = []
+      dialogs.value.clear()
+      triggerRef(dialogs)
     }
   }
 })
diff --git a/src/stores/rss.ts b/src/stores/rss.ts
index 9184a23f..26fc2f4c 100644
--- a/src/stores/rss.ts
+++ b/src/stores/rss.ts
@@ -66,7 +66,6 @@ export const useRssStore = defineStore(
 
     async function setFeedUrl(feedName: string, feedUrl: string) {
       await qbit.setFeedUrl(feedName, feedUrl).catch((error: AxiosError) => {
-        console.log(error)
         if (error.response?.status === 404) {
           toast.error(t('toast.qbit.not_supported', { version: '4.6.0' }))
         }