@@ -5,6 +5,7 @@ import type {
55 IBaseNodeVo ,
66 IDuplicateBaseNodeRo ,
77 IBaseNodeWorkflowResourceMeta ,
8+ IBaseNodeAppResourceMeta ,
89} from '@teable/openapi' ;
910import { BaseNodeResourceType } from '@teable/openapi' ;
1011import { LocalStorageKeys , ReactQueryKeys } from '@teable/sdk/config' ;
@@ -146,6 +147,7 @@ export const BaseNodeTree = (props: IBaseNodeTreeProps) => {
146147 const canCreateWorkflow = ! isCommunity && Boolean ( permission ?. [ 'automation|create' ] ) ;
147148 const canCreateApp = ! isCommunity && Boolean ( buildAppEnabled && permission ?. [ 'app|create' ] ) ;
148149 const canCreateFolder = Boolean ( permission ?. [ 'base|update' ] ) ;
150+ const canUpdateTable = Boolean ( permission ?. [ 'table|update' ] ) ;
149151
150152 const canCreateResource =
151153 isEditMode &&
@@ -558,26 +560,40 @@ export const BaseNodeTree = (props: IBaseNodeTreeProps) => {
558560 }
559561 return (
560562 // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
561- < div className = "cursor-pointer" onClick = { ( e ) => e . stopPropagation ( ) } >
563+ < div
564+ className = "flex size-4 shrink-0 cursor-pointer items-center justify-center"
565+ onClick = { ( e ) => e . stopPropagation ( ) }
566+ >
562567 { resourceType === BaseNodeResourceType . Table && (
563568 < EmojiPicker
564- className = "flex size-4 items-center justify-center hover:bg-muted-foreground/60"
569+ className = "flex size-full items-center justify-center hover:bg-muted-foreground/60"
565570 onChange = { ( icon : string ) => curdHooks . updateNode ( nodeId , { icon } ) }
571+ disabled = { ! canUpdateTable }
566572 >
567- { icon ? (
568- < Emoji emoji = { icon } size = { '1rem' } />
569- ) : (
570- < IconComponent className = "size-4 shrink-0" />
571- ) }
573+ { icon ? < Emoji emoji = { icon } size = "1rem" /> : < IconComponent className = "size-full" /> }
572574 </ EmojiPicker >
573575 ) }
574- { resourceType !== BaseNodeResourceType . Table && (
575- < IconComponent className = "size-4 shrink-0" />
576- ) }
576+ { resourceType !== BaseNodeResourceType . Table && < IconComponent className = "size-full" /> }
577577 </ div >
578578 ) ;
579579 } ;
580580
581+ const ItemStatus = ( { item } : { item : ItemInstance < TreeItemData > } ) => {
582+ const node = item . getItemData ( ) ;
583+ if ( ! node ) return null ;
584+ const { resourceType, resourceMeta } = node ;
585+ const isWorkflowActive =
586+ resourceType === BaseNodeResourceType . Workflow &&
587+ ( resourceMeta as IBaseNodeWorkflowResourceMeta ) ?. isActive ;
588+ const isAppPublished =
589+ resourceType === BaseNodeResourceType . App &&
590+ ( resourceMeta as IBaseNodeAppResourceMeta ) ?. publicUrl ;
591+ if ( isWorkflowActive || isAppPublished ) {
592+ return < span className = "size-1.5 shrink-0 rounded-full bg-emerald-500" /> ;
593+ }
594+ return null ;
595+ } ;
596+
581597 const renderEmpty = ( ) => {
582598 if ( isLoading ) {
583599 return (
@@ -674,10 +690,8 @@ export const BaseNodeTree = (props: IBaseNodeTreeProps) => {
674690 >
675691 { item . getItemName ( ) }
676692 </ span >
677- { node . resourceType === BaseNodeResourceType . Workflow &&
678- ( node . resourceMeta as IBaseNodeWorkflowResourceMeta ) ?. isActive && (
679- < span className = "size-1.5 shrink-0 rounded-full bg-emerald-500" />
680- ) }
693+
694+ < ItemStatus item = { item } />
681695 </ div >
682696 {
683697 // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
0 commit comments