@@ -30,13 +30,16 @@ import {
3030 BAITableProps ,
3131 BAIFlex ,
3232 BAINameActionCell ,
33+ BAIText ,
3334 toLocalId ,
3435 useErrorMessageResolver ,
3536 BAILink ,
3637 BAIConfirmModalWithInput ,
3738 BAITag ,
39+ bytesToGB ,
3840} from 'backend.ai-ui' ;
3941import type { BAINameActionCellAction } from 'backend.ai-ui' ;
42+ import dayjs from 'dayjs' ;
4043import _ from 'lodash' ;
4144import React , { useState } from 'react' ;
4245import { useTranslation } from 'react-i18next' ;
@@ -59,6 +62,25 @@ export const statusTagColor = {
5962
6063export type VFolderNodeInList = NonNullable < VFolderNodesFragment$data [ number ] > ;
6164
65+ const availableVFolderSorterKeys = [
66+ 'name' ,
67+ 'host' ,
68+ 'quota_scope_id' ,
69+ 'usage_mode' ,
70+ 'ownership_type' ,
71+ 'max_files' ,
72+ 'max_size' ,
73+ 'created_at' ,
74+ 'last_used' ,
75+ 'cloneable' ,
76+ 'status' ,
77+ 'cur_size' ,
78+ ] as const ;
79+
80+ const isEnableSorter = ( key : string ) => {
81+ return _ . includes ( availableVFolderSorterKeys , key ) ;
82+ } ;
83+
6284interface VFolderNameCellProps {
6385 vfolder : VFolderNodeInList ;
6486 onShare : ( ) => void ;
@@ -207,12 +229,20 @@ const VFolderNodes: React.FC<VFolderNodesProps> = ({
207229 status
208230 name
209231 host
232+ quota_scope_id
210233 ownership_type
211234 user
212235 user_email
213236 group
214237 group_name
215238 usage_mode
239+ max_files
240+ max_size
241+ created_at
242+ last_used
243+ num_files
244+ cur_size
245+ cloneable
216246 permissions @since(version: "24.09.0")
217247 ...VFolderPermissionCellFragment
218248 ...VFolderNodeIdenticonFragment
@@ -357,7 +387,7 @@ const VFolderNodes: React.FC<VFolderNodesProps> = ({
357387 />
358388 ) ;
359389 } ,
360- sorter : true ,
390+ sorter : isEnableSorter ( 'name' ) ,
361391 } ,
362392 {
363393 key : 'status' ,
@@ -376,13 +406,13 @@ const VFolderNodes: React.FC<VFolderNodesProps> = ({
376406 </ BAITag >
377407 ) ;
378408 } ,
379- sorter : true ,
409+ sorter : isEnableSorter ( 'status' ) ,
380410 } ,
381411 {
382412 key : 'host' ,
383413 title : t ( 'data.folders.Location' ) ,
384414 dataIndex : 'host' ,
385- sorter : true ,
415+ sorter : isEnableSorter ( 'host' ) ,
386416 } ,
387417 {
388418 key : 'permissions' ,
@@ -410,7 +440,7 @@ const VFolderNodes: React.FC<VFolderNodesProps> = ({
410440 </ BAIFlex >
411441 ) ;
412442 } ,
413- sorter : true ,
443+ sorter : isEnableSorter ( 'ownership_type' ) ,
414444 } ,
415445
416446 {
@@ -421,6 +451,99 @@ const VFolderNodes: React.FC<VFolderNodesProps> = ({
421451 ? vfolder ?. user_email
422452 : vfolder ?. group_name ,
423453 } ,
454+ {
455+ key : 'usage_mode' ,
456+ title : t ( 'data.UsageMode' ) ,
457+ dataIndex : 'usage_mode' ,
458+ defaultHidden : true ,
459+ sorter : isEnableSorter ( 'usage_mode' ) ,
460+ render : ( mode : string ) => {
461+ switch ( mode ) {
462+ case 'general' :
463+ return t ( 'data.General' ) ;
464+ case 'data' :
465+ return t ( 'webui.menu.Data' ) ;
466+ case 'model' :
467+ return t ( 'data.Models' ) ;
468+ default :
469+ return mode ;
470+ }
471+ } ,
472+ } ,
473+ {
474+ key : 'num_files' ,
475+ title : t ( 'data.folders.NumberOfFiles' ) ,
476+ dataIndex : 'num_files' ,
477+ defaultHidden : true ,
478+ sorter : isEnableSorter ( 'num_files' ) ,
479+ render : ( value : number ) =>
480+ value != null ? value . toLocaleString ( ) : '-' ,
481+ } ,
482+ {
483+ key : 'cur_size' ,
484+ title : t ( 'data.folders.FolderUsage' ) ,
485+ dataIndex : 'cur_size' ,
486+ defaultHidden : true ,
487+ sorter : isEnableSorter ( 'cur_size' ) ,
488+ render : ( value : string ) =>
489+ value != null ? `${ bytesToGB ( Number ( value ) ) } GB` : '-' ,
490+ } ,
491+ {
492+ key : 'max_files' ,
493+ title : t ( 'data.folders.MaxFolderQuota' ) ,
494+ dataIndex : 'max_files' ,
495+ defaultHidden : true ,
496+ sorter : isEnableSorter ( 'max_files' ) ,
497+ render : ( value : number ) =>
498+ value != null && value > 0 ? value . toLocaleString ( ) : '-' ,
499+ } ,
500+ {
501+ key : 'max_size' ,
502+ title : t ( 'data.folders.MaxSize' ) ,
503+ dataIndex : 'max_size' ,
504+ defaultHidden : true ,
505+ sorter : isEnableSorter ( 'max_size' ) ,
506+ render : ( value : string ) =>
507+ value != null && Number ( value ) > 0
508+ ? `${ bytesToGB ( Number ( value ) ) } GB`
509+ : '-' ,
510+ } ,
511+ {
512+ key : 'cloneable' ,
513+ title : t ( 'data.folders.Cloneable' ) ,
514+ dataIndex : 'cloneable' ,
515+ defaultHidden : true ,
516+ sorter : isEnableSorter ( 'cloneable' ) ,
517+ render : ( value : boolean ) =>
518+ value ? t ( 'button.Yes' ) : t ( 'button.No' ) ,
519+ } ,
520+ {
521+ key : 'quota_scope_id' ,
522+ title : t ( 'data.QuotaScopeId' ) ,
523+ dataIndex : 'quota_scope_id' ,
524+ defaultHidden : true ,
525+ sorter : isEnableSorter ( 'quota_scope_id' ) ,
526+ render : ( value : string ) =>
527+ value ? < BAIText copyable > { value } </ BAIText > : '-' ,
528+ } ,
529+ {
530+ key : 'last_used' ,
531+ title : t ( 'credential.LastUsed' ) ,
532+ dataIndex : 'last_used' ,
533+ defaultHidden : true ,
534+ sorter : isEnableSorter ( 'last_used' ) ,
535+ render : ( value : string ) =>
536+ value ? dayjs ( value ) . format ( 'll LT' ) : '-' ,
537+ } ,
538+ {
539+ key : 'created_at' ,
540+ title : t ( 'data.folders.CreatedAt' ) ,
541+ dataIndex : 'created_at' ,
542+ defaultHidden : true ,
543+ sorter : isEnableSorter ( 'created_at' ) ,
544+ render : ( value : string ) =>
545+ value ? dayjs ( value ) . format ( 'll LT' ) : '-' ,
546+ } ,
424547 ] }
425548 { ...tableProps }
426549 />
0 commit comments