Extract error handling with toast message as hook (#825)

This commit is contained in:
Chenlei Hu
2024-09-14 11:25:08 +09:00
committed by GitHub
parent c98ea5ba01
commit ebdcd92977
4 changed files with 78 additions and 35 deletions

View File

@@ -40,8 +40,10 @@ import type {
RenderedTreeExplorerNode,
TreeExplorerNode
} from '@/types/treeExplorerTypes'
import type { MenuItem } from 'primevue/menuitem'
import type { MenuItem, MenuItemCommandEvent } from 'primevue/menuitem'
import { useI18n } from 'vue-i18n'
import { useToast } from 'primevue/usetoast'
import { useErrorHandling } from '@/hooks/errorHooks'
const expandedKeys = defineModel<Record<string, boolean>>('expandedKeys')
provide('expandedKeys', expandedKeys)
@@ -105,25 +107,31 @@ const deleteCommand = (node: RenderedTreeExplorerNode) => {
node.handleDelete?.(node)
emit('nodeDelete', node)
}
const menuItems = computed<MenuItem[]>(() => [
{
label: t('rename'),
icon: 'pi pi-file-edit',
command: () => renameCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleRename !== undefined
},
{
label: t('delete'),
icon: 'pi pi-trash',
command: () => deleteCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleDelete !== undefined
},
...(props.extraMenuItems
? typeof props.extraMenuItems === 'function'
? props.extraMenuItems(menuTargetNode.value)
: props.extraMenuItems
: [])
])
const menuItems = computed<MenuItem[]>(() =>
[
{
label: t('rename'),
icon: 'pi pi-file-edit',
command: () => renameCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleRename !== undefined
},
{
label: t('delete'),
icon: 'pi pi-trash',
command: () => deleteCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleDelete !== undefined
},
...(props.extraMenuItems
? typeof props.extraMenuItems === 'function'
? props.extraMenuItems(menuTargetNode.value)
: props.extraMenuItems
: [])
].map((menuItem) => ({
...menuItem,
command: wrapCommandWithErrorHandler(menuItem.command)
}))
)
const handleContextMenu = (node: RenderedTreeExplorerNode, e: MouseEvent) => {
menuTargetNode.value = node
emit('contextMenu', node, e)
@@ -131,6 +139,17 @@ const handleContextMenu = (node: RenderedTreeExplorerNode, e: MouseEvent) => {
menu.value?.show(e)
}
}
const errorHandling = useErrorHandling()
const wrapCommandWithErrorHandler = (
command: (event: MenuItemCommandEvent) => void
) => {
return errorHandling.wrapWithErrorHandling(
command,
menuTargetNode.value?.handleError
)
}
defineExpose({
renameCommand,
deleteCommand
@@ -145,6 +164,7 @@ defineExpose({
margin-left: var(--p-tree-node-gap);
flex-grow: 1;
}
/*
* The following styles are necessary to avoid layout shift when dragging nodes over folders.
* By setting the position to relative on the parent and using an absolutely positioned pseudo-element,
@@ -153,6 +173,7 @@ defineExpose({
:deep(.p-tree-node-content:has(.tree-folder)) {
position: relative;
}
:deep(.p-tree-node-content:has(.tree-folder.can-drop))::after {
content: '';
position: absolute;

View File

@@ -36,12 +36,12 @@ import type {
TreeExplorerNode
} from '@/types/treeExplorerTypes'
import type { TreeNode } from 'primevue/treenode'
import { useToast } from 'primevue/usetoast'
import { computed, nextTick, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useTreeExpansion } from '@/hooks/treeHooks'
import { app } from '@/scripts/app'
import { findNodeByKey } from '@/utils/treeUtil'
import { useErrorHandling } from '@/hooks/errorHooks'
import { useI18n } from 'vue-i18n'
const props = defineProps<{
filteredNodeDefs: ComfyNodeDefImpl[]
@@ -182,22 +182,13 @@ defineExpose({
addNewBookmarkFolder
})
const toast = useToast()
const { t } = useI18n()
const handleRename = (node: TreeNode, newName: string) => {
if (node.data && node.data.isDummyFolder) {
try {
const handleRename = useErrorHandling().wrapWithErrorHandling(
(node: TreeNode, newName: string) => {
if (node.data && node.data.isDummyFolder) {
nodeBookmarkStore.renameBookmarkFolder(node.data, newName)
} catch (e) {
toast.add({
severity: 'error',
summary: t('error'),
detail: e.message,
life: 3000
})
}
}
}
)
const showCustomizationDialog = ref(false)
const initialIcon = ref(nodeBookmarkStore.defaultBookmarkIcon)
@@ -212,6 +203,7 @@ const updateCustomization = (icon: string, color: string) => {
}
}
const { t } = useI18n()
const extraMenuItems = computed(
() => (menuTargetNode: RenderedTreeExplorerNode<ComfyNodeDefImpl>) => [
{

28
src/hooks/errorHooks.ts Normal file
View File

@@ -0,0 +1,28 @@
import { useToast } from 'primevue/usetoast'
import { useI18n } from 'vue-i18n'
export function useErrorHandling() {
const toast = useToast()
const { t } = useI18n()
const wrapWithErrorHandling =
(action: (...args: any[]) => any, errorHandler?: (error: any) => void) =>
(...args: any[]) => {
try {
return action(...args)
} catch (e) {
if (errorHandler) {
errorHandler(e)
} else {
toast.add({
severity: 'error',
summary: t('error'),
detail: e.message,
life: 3000
})
}
}
}
return { wrapWithErrorHandling }
}

View File

@@ -24,6 +24,8 @@ export interface TreeExplorerNode<T = any> {
node: TreeExplorerNode<T>,
data: TreeExplorerDragAndDropData
) => void
// Function to handle errors
handleError?: (error: Error) => void
}
export interface RenderedTreeExplorerNode<T = any> extends TreeExplorerNode<T> {