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 ,
@@ -13,17 +14,21 @@ import type {
1314import AdminModelCardSettingModal from '../components/AdminModelCardSettingModal' ;
1415import { convertToOrderBy , handleRowSelectionChange } from '../helper' ;
1516import { useBAIPaginationOptionStateOnSearchParam } from '../hooks/reactPaginationQueryOptions' ;
17+ import { useSetBAINotification } from '../hooks/useBAINotification' ;
1618import { useBAISettingUserState } from '../hooks/useBAISetting' ;
1719import { useCurrentProjectValue } from '../hooks/useCurrentProject' ;
1820import { SettingOutlined } from '@ant-design/icons' ;
19- import { App , Typography } from 'antd' ;
21+ import { shapes } from '@dicebear/collection' ;
22+ import { createAvatar } from '@dicebear/core' ;
23+ import { App , Checkbox , Tooltip , Typography , theme } from 'antd' ;
2024import {
2125 BAIButton ,
2226 BAIColumnType ,
2327 BAIDeleteConfirmModal ,
2428 BAIFetchKeyButton ,
2529 BAIFlex ,
2630 BAIGraphQLPropertyFilter ,
31+ BAILink ,
2732 BAINameActionCell ,
2833 BAISelectionLabel ,
2934 BAITable ,
@@ -62,7 +67,9 @@ const AdminModelCardListPage: React.FC = () => {
6267
6368 const { t } = useTranslation ( ) ;
6469 const { message } = App . useApp ( ) ;
70+ const { token } = theme . useToken ( ) ;
6571 const { logger } = useBAILogger ( ) ;
72+ const { upsertNotification } = useSetBAINotification ( ) ;
6673 const currentProject = useCurrentProjectValue ( ) ;
6774 const [ columnOverrides , setColumnOverrides ] = useBAISettingUserState (
6875 'table_column_overrides.AdminModelCardListPage' ,
@@ -77,6 +84,7 @@ const AdminModelCardListPage: React.FC = () => {
7784 ) ;
7885 const [ deletingModelCard , setDeletingModelCard ] =
7986 useState < ModelCardNode | null > ( null ) ;
87+ const [ alsoDeleteFolder , setAlsoDeleteFolder ] = useState ( false ) ;
8088 const [ isBulkDeleteOpen , setIsBulkDeleteOpen ] = useState ( false ) ;
8189 const {
8290 baiPaginationOption,
@@ -144,6 +152,13 @@ const AdminModelCardListPage: React.FC = () => {
144152 node {
145153 id
146154 name
155+ vfolderId
156+ vfolder {
157+ id
158+ metadata {
159+ name
160+ }
161+ }
147162 domainName
148163 projectId
149164 accessLevel
@@ -185,6 +200,15 @@ const AdminModelCardListPage: React.FC = () => {
185200 }
186201 ` ) ;
187202
203+ const [ commitDeleteVFolder ] =
204+ useMutation < AdminModelCardListPageDeleteVFolderMutation > ( graphql `
205+ mutation AdminModelCardListPageDeleteVFolderMutation($vfolderId: UUID!) {
206+ deleteVfolderV2(vfolderId: $vfolderId) {
207+ id
208+ }
209+ }
210+ ` ) ;
211+
188212 const [ commitBulkDeleteModelCards , isBulkDeleteInFlight ] =
189213 useMutation < AdminModelCardListPageBulkDeleteMutation > ( graphql `
190214 mutation AdminModelCardListPageBulkDeleteMutation(
@@ -428,6 +452,51 @@ const AdminModelCardListPage: React.FC = () => {
428452 description = { t ( 'adminModelCard.ConfirmDelete' , {
429453 name : deletingModelCard ?. name ,
430454 } ) }
455+ extraContent = {
456+ < BAIFlex direction = "column" gap = { 'xs' } >
457+ { deletingModelCard ?. vfolder && (
458+ < BAIFlex align = "center" gap = { 'xs' } >
459+ < img
460+ draggable = { false }
461+ onDragStart = { ( e ) => e . preventDefault ( ) }
462+ style = { {
463+ borderRadius : '0.25em' ,
464+ width : '1em' ,
465+ height : '1em' ,
466+ borderWidth : 0.5 ,
467+ borderStyle : 'solid' ,
468+ borderColor : token . colorBorder ,
469+ userSelect : 'none' ,
470+ flexShrink : 0 ,
471+ } }
472+ src = { createAvatar ( shapes , {
473+ seed : deletingModelCard . vfolderId ,
474+ shape3 : [ ] ,
475+ } ) . toDataUri ( ) }
476+ alt = "VFolder Identicon"
477+ />
478+ < BAILink
479+ to = { {
480+ pathname : '/data' ,
481+ search : new URLSearchParams ( {
482+ folder : deletingModelCard . vfolderId ,
483+ } ) . toString ( ) ,
484+ } }
485+ >
486+ { deletingModelCard . vfolder . metadata . name }
487+ </ BAILink >
488+ </ BAIFlex >
489+ ) }
490+ < Tooltip title = { t ( 'adminModelCard.AlsoDeleteModelFolderTooltip' ) } >
491+ < Checkbox
492+ checked = { alsoDeleteFolder }
493+ onChange = { ( e ) => setAlsoDeleteFolder ( e . target . checked ) }
494+ >
495+ { t ( 'adminModelCard.AlsoDeleteModelFolder' ) }
496+ </ Checkbox >
497+ </ Tooltip >
498+ </ BAIFlex >
499+ }
431500 onOk = { ( ) => {
432501 if ( deletingModelCard ) {
433502 return new Promise < void > ( ( resolve , reject ) => {
@@ -442,10 +511,101 @@ 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 folderTrashSearch = new URLSearchParams ( {
517+ statusCategory : 'deleted' ,
518+ filter : `row_id == "${ vfolderId } "` ,
519+ } ) . toString ( ) ;
520+
521+ if ( alsoDeleteFolder && vfolderId ) {
522+ commitDeleteVFolder ( {
523+ variables : { vfolderId } ,
524+ onCompleted : ( _vfolderData , vfolderErrors ) => {
525+ if ( vfolderErrors && vfolderErrors . length > 0 ) {
526+ logger . error ( vfolderErrors [ 0 ] ) ;
527+ message . error (
528+ vfolderErrors [ 0 ] ?. message ||
529+ t ( 'general.ErrorOccurred' ) ,
530+ ) ;
531+ upsertNotification ( {
532+ type : 'success' ,
533+ message : t (
534+ 'adminModelCard.ModelCardDeletedFolderKept' ,
535+ ) ,
536+ to : {
537+ pathname : '/data' ,
538+ search : 'statusCategory=deleted' ,
539+ } ,
540+ toText : t ( 'adminModelCard.GoToTrash' ) ,
541+ open : true ,
542+ duration : 4 ,
543+ extraData : null ,
544+ } ) ;
545+ } else {
546+ upsertNotification ( {
547+ type : 'success' ,
548+ message : t (
549+ 'adminModelCard.ModelCardAndFolderDeleted' ,
550+ ) ,
551+ to : {
552+ pathname : '/data' ,
553+ search : folderTrashSearch ,
554+ } ,
555+ toText : t ( 'adminModelCard.GoToTrash' ) ,
556+ open : true ,
557+ duration : 4 ,
558+ extraData : null ,
559+ } ) ;
560+ }
561+ setDeletingModelCard ( null ) ;
562+ setAlsoDeleteFolder ( false ) ;
563+ updateFetchKey ( ) ;
564+ resolve ( ) ;
565+ } ,
566+ onError : ( error ) => {
567+ logger . error ( error ) ;
568+ message . error (
569+ error ?. message || t ( 'general.ErrorOccurred' ) ,
570+ ) ;
571+ upsertNotification ( {
572+ type : 'success' ,
573+ message : t (
574+ 'adminModelCard.ModelCardDeletedFolderKept' ,
575+ ) ,
576+ to : {
577+ pathname : '/data' ,
578+ search : 'statusCategory=deleted' ,
579+ } ,
580+ toText : t ( 'adminModelCard.GoToTrash' ) ,
581+ open : true ,
582+ duration : 4 ,
583+ extraData : null ,
584+ } ) ;
585+ setDeletingModelCard ( null ) ;
586+ setAlsoDeleteFolder ( false ) ;
587+ updateFetchKey ( ) ;
588+ resolve ( ) ;
589+ } ,
590+ } ) ;
591+ } else {
592+ upsertNotification ( {
593+ type : 'success' ,
594+ message : t ( 'adminModelCard.ModelCardDeletedFolderKept' ) ,
595+ to : {
596+ pathname : '/data' ,
597+ search : 'statusCategory=deleted' ,
598+ } ,
599+ toText : t ( 'adminModelCard.GoToTrash' ) ,
600+ open : true ,
601+ duration : 4 ,
602+ extraData : null ,
603+ } ) ;
604+ setDeletingModelCard ( null ) ;
605+ setAlsoDeleteFolder ( false ) ;
606+ updateFetchKey ( ) ;
607+ resolve ( ) ;
608+ }
449609 } ,
450610 onError : ( error ) => {
451611 logger . error ( error ) ;
@@ -456,7 +616,10 @@ const AdminModelCardListPage: React.FC = () => {
456616 } ) ;
457617 }
458618 } }
459- onCancel = { ( ) => setDeletingModelCard ( null ) }
619+ onCancel = { ( ) => {
620+ setDeletingModelCard ( null ) ;
621+ setAlsoDeleteFolder ( false ) ;
622+ } }
460623 />
461624 < BAIDeleteConfirmModal
462625 open = { isBulkDeleteOpen }
0 commit comments