@@ -8,9 +8,12 @@ import {
8
8
Tooltip ,
9
9
useDisclosure ,
10
10
} from '@invoke-ai/ui-library' ;
11
+ import { useStore } from '@nanostores/react' ;
11
12
import { EMPTY_OBJECT } from 'app/store/constants' ;
13
+ import { $projectUrl } from 'app/store/nanostores/projectId' ;
12
14
import { useAppDispatch , useAppSelector } from 'app/store/storeHooks' ;
13
15
import dateFormat , { masks } from 'dateformat' ;
16
+ import { useCopyWorkflowLinkModal } from 'features/nodes/hooks/useCopyWorkflowLinkModal' ;
14
17
import { $isWorkflowListMenuIsOpen } from 'features/nodes/store/workflowListMenu' ;
15
18
import { selectWorkflowId , workflowModeChanged } from 'features/nodes/store/workflowSlice' ;
16
19
import { useDeleteLibraryWorkflow } from 'features/workflowLibrary/hooks/useDeleteLibraryWorkflow' ;
@@ -19,15 +22,17 @@ import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/use
19
22
import type { MouseEvent } from 'react' ;
20
23
import { useCallback , useMemo , useState } from 'react' ;
21
24
import { useTranslation } from 'react-i18next' ;
22
- import { PiDownloadSimpleBold , PiPencilBold , PiTrashBold } from 'react-icons/pi' ;
25
+ import { PiDownloadSimpleBold , PiPencilBold , PiShareFatBold , PiTrashBold } from 'react-icons/pi' ;
23
26
import type { WorkflowRecordListItemDTO } from 'services/api/types' ;
24
27
28
+ import { CopyWorkflowLinkModal } from './CopyWorkflowLinkModal' ;
25
29
import { WorkflowListItemTooltip } from './WorkflowListItemTooltip' ;
26
30
27
31
export const WorkflowListItem = ( { workflow } : { workflow : WorkflowRecordListItemDTO } ) => {
28
32
const { isOpen, onOpen, onClose } = useDisclosure ( ) ;
29
33
const { t } = useTranslation ( ) ;
30
34
const dispatch = useAppDispatch ( ) ;
35
+ const projectUrl = useStore ( $projectUrl ) ;
31
36
32
37
const [ isHovered , setIsHovered ] = useState ( false ) ;
33
38
@@ -42,6 +47,8 @@ export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListIte
42
47
const workflowId = useAppSelector ( selectWorkflowId ) ;
43
48
const downloadWorkflow = useDownloadWorkflow ( ) ;
44
49
50
+ const { onOpen : onOpenCopyWorkflowLinkModal } = useCopyWorkflowLinkModal ( ) ;
51
+
45
52
const { deleteWorkflow, deleteWorkflowResult } = useDeleteLibraryWorkflow ( EMPTY_OBJECT ) ;
46
53
const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow ( {
47
54
onSuccess : ( ) => $isWorkflowListMenuIsOpen . set ( false ) ,
@@ -75,6 +82,14 @@ export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListIte
75
82
[ onOpen ]
76
83
) ;
77
84
85
+ const handleClickShare = useCallback (
86
+ ( e : MouseEvent < HTMLButtonElement > ) => {
87
+ e . stopPropagation ( ) ;
88
+ onOpenCopyWorkflowLinkModal ( ) ;
89
+ } ,
90
+ [ onOpenCopyWorkflowLinkModal ]
91
+ ) ;
92
+
78
93
return (
79
94
< >
80
95
< Flex
@@ -118,31 +133,48 @@ export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListIte
118
133
< Spacer />
119
134
120
135
< Flex alignItems = "center" gap = { 1 } opacity = { isHovered ? 1 : 0 } >
121
- < IconButton
122
- size = "sm"
123
- variant = "ghost"
124
- aria-label = "Edit"
125
- onClick = { handleClickEdit }
126
- isLoading = { deleteWorkflowResult . isLoading }
127
- icon = { < PiPencilBold /> }
128
- />
129
- < IconButton
130
- size = "sm"
131
- variant = "ghost"
132
- aria-label = "Download"
133
- onClick = { downloadWorkflow }
134
- icon = { < PiDownloadSimpleBold /> }
135
- />
136
- { workflow . category !== 'default' && (
136
+ < Tooltip label = { t ( 'workflows.edit' ) } >
137
137
< IconButton
138
138
size = "sm"
139
139
variant = "ghost"
140
- aria-label = { t ( 'stylePresets.deleteTemplate ' ) }
141
- onClick = { handleClickDelete }
140
+ aria-label = { t ( 'workflows.edit ' ) }
141
+ onClick = { handleClickEdit }
142
142
isLoading = { deleteWorkflowResult . isLoading }
143
- colorScheme = "error"
144
- icon = { < PiTrashBold /> }
143
+ icon = { < PiPencilBold /> }
145
144
/>
145
+ </ Tooltip >
146
+ < Tooltip label = { t ( 'workflows.download' ) } >
147
+ < IconButton
148
+ size = "sm"
149
+ variant = "ghost"
150
+ aria-label = { t ( 'workflows.download' ) }
151
+ onClick = { downloadWorkflow }
152
+ icon = { < PiDownloadSimpleBold /> }
153
+ />
154
+ </ Tooltip >
155
+ { ! ! projectUrl && workflow . workflow_id && (
156
+ < Tooltip label = { t ( 'workflows.copyShareLink' ) } >
157
+ < IconButton
158
+ size = "sm"
159
+ variant = "ghost"
160
+ aria-label = { t ( 'workflows.copyShareLink' ) }
161
+ onClick = { handleClickShare }
162
+ icon = { < PiShareFatBold /> }
163
+ />
164
+ </ Tooltip >
165
+ ) }
166
+ { workflow . category !== 'default' && (
167
+ < Tooltip label = { t ( 'workflows.delete' ) } >
168
+ < IconButton
169
+ size = "sm"
170
+ variant = "ghost"
171
+ aria-label = { t ( 'workflows.delete' ) }
172
+ onClick = { handleClickDelete }
173
+ isLoading = { deleteWorkflowResult . isLoading }
174
+ colorScheme = "error"
175
+ icon = { < PiTrashBold /> }
176
+ />
177
+ </ Tooltip >
146
178
) }
147
179
</ Flex >
148
180
</ Flex >
@@ -157,6 +189,7 @@ export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListIte
157
189
>
158
190
< p > { t ( 'workflows.deleteWorkflow2' ) } </ p >
159
191
</ ConfirmationAlertDialog >
192
+ < CopyWorkflowLinkModal workflowId = { workflow . workflow_id } workflowName = { workflow . name } />
160
193
</ >
161
194
) ;
162
195
} ;
0 commit comments