44 */
55import type { AdminModelCardListPageBulkDeleteMutation } from '../__generated__/AdminModelCardListPageBulkDeleteMutation.graphql' ;
66import type { AdminModelCardListPageDeleteMutation } from '../__generated__/AdminModelCardListPageDeleteMutation.graphql' ;
7+ import type { AdminModelCardListPageDeleteVFolderMutation } from '../__generated__/AdminModelCardListPageDeleteVFolderMutation.graphql' ;
78import type {
89 AdminModelCardListPageQuery ,
910 AdminModelCardListPageQuery$data ,
1011 ModelCardV2Filter ,
1112 ModelCardV2OrderBy ,
1213} from '../__generated__/AdminModelCardListPageQuery.graphql' ;
1314import AdminModelCardSettingModal from '../components/AdminModelCardSettingModal' ;
15+ import { useFolderExplorerOpener } from '../components/FolderExplorerOpener' ;
1416import { convertToOrderBy , handleRowSelectionChange } from '../helper' ;
1517import { useBAIPaginationOptionStateOnSearchParam } from '../hooks/reactPaginationQueryOptions' ;
18+ import { useSetBAINotification } from '../hooks/useBAINotification' ;
1619import { useBAISettingUserState } from '../hooks/useBAISetting' ;
1720import { useCurrentProjectValue } from '../hooks/useCurrentProject' ;
1821import { SettingOutlined } from '@ant-design/icons' ;
19- import { App , Typography } from 'antd' ;
22+ import { shapes } from '@dicebear/collection' ;
23+ import { createAvatar } from '@dicebear/core' ;
24+ import { App , Checkbox , Tooltip , Typography , theme } from 'antd' ;
2025import {
2126 BAIButton ,
2227 BAIColumnType ,
2328 BAIDeleteConfirmModal ,
2429 BAIFetchKeyButton ,
2530 BAIFlex ,
2631 BAIGraphQLPropertyFilter ,
32+ BAILink ,
2733 BAINameActionCell ,
2834 BAISelectionLabel ,
2935 BAITable ,
@@ -62,7 +68,10 @@ const AdminModelCardListPage: React.FC = () => {
6268
6369 const { t } = useTranslation ( ) ;
6470 const { message } = App . useApp ( ) ;
71+ const { token } = theme . useToken ( ) ;
6572 const { logger } = useBAILogger ( ) ;
73+ const { upsertNotification } = useSetBAINotification ( ) ;
74+ const { generateFolderPath } = useFolderExplorerOpener ( ) ;
6675 const currentProject = useCurrentProjectValue ( ) ;
6776 const [ columnOverrides , setColumnOverrides ] = useBAISettingUserState (
6877 'table_column_overrides.AdminModelCardListPage' ,
@@ -77,6 +86,7 @@ const AdminModelCardListPage: React.FC = () => {
7786 ) ;
7887 const [ deletingModelCard , setDeletingModelCard ] =
7988 useState < ModelCardNode | null > ( null ) ;
89+ const [ alsoDeleteFolder , setAlsoDeleteFolder ] = useState ( false ) ;
8090 const [ isBulkDeleteOpen , setIsBulkDeleteOpen ] = useState ( false ) ;
8191 const {
8292 baiPaginationOption,
@@ -144,6 +154,13 @@ const AdminModelCardListPage: React.FC = () => {
144154 node {
145155 id
146156 name
157+ vfolderId
158+ vfolder {
159+ id
160+ metadata {
161+ name
162+ }
163+ }
147164 domainName
148165 projectId
149166 accessLevel
@@ -185,6 +202,15 @@ const AdminModelCardListPage: React.FC = () => {
185202 }
186203 ` ) ;
187204
205+ const [ commitDeleteVFolder ] =
206+ useMutation < AdminModelCardListPageDeleteVFolderMutation > ( graphql `
207+ mutation AdminModelCardListPageDeleteVFolderMutation($vfolderId: UUID!) {
208+ deleteVfolderV2(vfolderId: $vfolderId) {
209+ id
210+ }
211+ }
212+ ` ) ;
213+
188214 const [ commitBulkDeleteModelCards , isBulkDeleteInFlight ] =
189215 useMutation < AdminModelCardListPageBulkDeleteMutation > ( graphql `
190216 mutation AdminModelCardListPageBulkDeleteMutation(
@@ -428,6 +454,49 @@ const AdminModelCardListPage: React.FC = () => {
428454 description = { t ( 'adminModelCard.ConfirmDelete' , {
429455 name : deletingModelCard ?. name ,
430456 } ) }
457+ requireConfirmInput
458+ extraContent = {
459+ < Tooltip title = { t ( 'adminModelCard.AlsoDeleteModelFolderTooltip' ) } >
460+ < Checkbox
461+ checked = { alsoDeleteFolder }
462+ onChange = { ( e ) => setAlsoDeleteFolder ( e . target . checked ) }
463+ >
464+ { t ( 'adminModelCard.AlsoDeleteModelFolder' ) }
465+ { deletingModelCard ?. vfolder && (
466+ < span style = { { marginLeft : token . marginXXS } } >
467+ { '(' }
468+ < img
469+ draggable = { false }
470+ onDragStart = { ( e ) => e . preventDefault ( ) }
471+ style = { {
472+ borderRadius : '0.25em' ,
473+ width : '1em' ,
474+ height : '1em' ,
475+ borderWidth : 0.5 ,
476+ borderStyle : 'solid' ,
477+ borderColor : token . colorBorder ,
478+ userSelect : 'none' ,
479+ verticalAlign : 'middle' ,
480+ marginInline : token . marginXXS ,
481+ } }
482+ src = { createAvatar ( shapes , {
483+ seed : deletingModelCard . vfolderId ,
484+ shape3 : [ ] ,
485+ } ) . toDataUri ( ) }
486+ alt = "VFolder Identicon"
487+ />
488+ < BAILink
489+ to = { generateFolderPath ( deletingModelCard . vfolderId ) }
490+ onClick = { ( e ) => e . stopPropagation ( ) }
491+ >
492+ { deletingModelCard . vfolder . metadata . name }
493+ </ BAILink >
494+ { ')' }
495+ </ span >
496+ ) }
497+ </ Checkbox >
498+ </ Tooltip >
499+ }
431500 onOk = { ( ) => {
432501 if ( deletingModelCard ) {
433502 return new Promise < void > ( ( resolve , reject ) => {
@@ -442,10 +511,104 @@ const AdminModelCardListPage: React.FC = () => {
442511 reject ( ) ;
443512 return ;
444513 }
445- message . success ( t ( 'adminModelCard.ModelCardDeleted' ) ) ;
446- setDeletingModelCard ( null ) ;
447- updateFetchKey ( ) ;
448- resolve ( ) ;
514+
515+ const vfolderId = deletingModelCard . vfolderId ;
516+ const folderName = deletingModelCard . vfolder ?. metadata . name ;
517+ const folderTrashSearch = new URLSearchParams ( {
518+ statusCategory : 'deleted' ,
519+ ...( folderName
520+ ? { filter : `name == "${ folderName } "` }
521+ : { } ) ,
522+ } ) . toString ( ) ;
523+
524+ if ( alsoDeleteFolder && vfolderId ) {
525+ commitDeleteVFolder ( {
526+ variables : { vfolderId } ,
527+ onCompleted : ( _vfolderData , vfolderErrors ) => {
528+ if ( vfolderErrors && vfolderErrors . length > 0 ) {
529+ logger . error ( vfolderErrors [ 0 ] ) ;
530+ message . error (
531+ vfolderErrors [ 0 ] ?. message ||
532+ t ( 'general.ErrorOccurred' ) ,
533+ ) ;
534+ upsertNotification ( {
535+ type : 'success' ,
536+ message : t (
537+ 'adminModelCard.ModelCardDeletedFolderKept' ,
538+ ) ,
539+ to : {
540+ pathname : '/data' ,
541+ search : 'statusCategory=deleted' ,
542+ } ,
543+ toText : t ( 'adminModelCard.GoToTrash' ) ,
544+ open : true ,
545+ duration : 4 ,
546+ extraData : null ,
547+ } ) ;
548+ } else {
549+ upsertNotification ( {
550+ type : 'success' ,
551+ message : t (
552+ 'adminModelCard.ModelCardAndFolderDeleted' ,
553+ ) ,
554+ to : {
555+ pathname : '/data' ,
556+ search : folderTrashSearch ,
557+ } ,
558+ toText : t ( 'adminModelCard.GoToTrash' ) ,
559+ open : true ,
560+ duration : 4 ,
561+ extraData : null ,
562+ } ) ;
563+ }
564+ setDeletingModelCard ( null ) ;
565+ setAlsoDeleteFolder ( false ) ;
566+ updateFetchKey ( ) ;
567+ resolve ( ) ;
568+ } ,
569+ onError : ( error ) => {
570+ logger . error ( error ) ;
571+ message . error (
572+ error ?. message || t ( 'general.ErrorOccurred' ) ,
573+ ) ;
574+ upsertNotification ( {
575+ type : 'success' ,
576+ message : t (
577+ 'adminModelCard.ModelCardDeletedFolderKept' ,
578+ ) ,
579+ to : {
580+ pathname : '/data' ,
581+ search : 'statusCategory=deleted' ,
582+ } ,
583+ toText : t ( 'adminModelCard.GoToTrash' ) ,
584+ open : true ,
585+ duration : 4 ,
586+ extraData : null ,
587+ } ) ;
588+ setDeletingModelCard ( null ) ;
589+ setAlsoDeleteFolder ( false ) ;
590+ updateFetchKey ( ) ;
591+ resolve ( ) ;
592+ } ,
593+ } ) ;
594+ } else {
595+ upsertNotification ( {
596+ type : 'success' ,
597+ message : t ( 'adminModelCard.ModelCardDeletedFolderKept' ) ,
598+ to : {
599+ pathname : '/data' ,
600+ search : 'statusCategory=deleted' ,
601+ } ,
602+ toText : t ( 'adminModelCard.GoToTrash' ) ,
603+ open : true ,
604+ duration : 4 ,
605+ extraData : null ,
606+ } ) ;
607+ setDeletingModelCard ( null ) ;
608+ setAlsoDeleteFolder ( false ) ;
609+ updateFetchKey ( ) ;
610+ resolve ( ) ;
611+ }
449612 } ,
450613 onError : ( error ) => {
451614 logger . error ( error ) ;
@@ -456,7 +619,10 @@ const AdminModelCardListPage: React.FC = () => {
456619 } ) ;
457620 }
458621 } }
459- onCancel = { ( ) => setDeletingModelCard ( null ) }
622+ onCancel = { ( ) => {
623+ setDeletingModelCard ( null ) ;
624+ setAlsoDeleteFolder ( false ) ;
625+ } }
460626 />
461627 < BAIDeleteConfirmModal
462628 open = { isBulkDeleteOpen }
0 commit comments