@@ -61,19 +61,16 @@ interface ResourceRow {
6161 can_share ?: boolean ; // whether the current user can share this resource
6262}
6363interface TypeEntry {
64- type : string ; // fully qualified class name
65- index : string ; // name of the index to be supplied to the API as resource_type
64+ type : string ; // type of resource, e.g. `sample-resource`
6665 action_groups : string [ ] ; // known action-groups for this type
6766}
6867// Tiny API that the panel consumes
6968interface Api {
7069 listTypes : ( ) => Promise < { types : TypeEntry [ ] } | TypeEntry [ ] > ;
71- listSharingRecords : (
72- index : string
73- ) => Promise < ResourceRow [ ] | { resources : ResourceRow [ ] } | any > ;
70+ listSharingRecords : ( type : string ) => Promise < ResourceRow [ ] | { resources : ResourceRow [ ] } | any > ;
7471 getSharingRecord : (
7572 id : string ,
76- index : string
73+ type : string
7774 ) => Promise < ResourceRow | { resource : ResourceRow } | any > ;
7875 share : ( payload : {
7976 resource_id : string ;
@@ -523,28 +520,39 @@ const SharedWithExpanded: React.FC<{ sw?: ShareWith }> = ({ sw }) => {
523520 ) ;
524521} ;
525522
526- // Helpers: pick simple class name and humanize it
527- const simpleName = ( fqn : string ) => ( fqn ?. split ( '.' ) . pop ( ) || fqn || '' ) . trim ( ) ;
523+ // Helpers: pick simple name and humanize it
524+ const simpleName = ( type ?: string ) =>
525+ (
526+ ( type ?? '' )
527+ . split ( '.' )
528+ . filter ( Boolean ) // remove empty parts from trailing dots, etc.
529+ . pop ( ) ?? ''
530+ ) . trim ( ) ;
531+
532+ /** Humanize class names: e.g., "AnomalyDetector" -> "Anomaly Detector", "ADDetector" -> "AD Detector",
533+ * and kebab/underscore: "sample-resource" -> "Sample Resource", "anomaly-detector" -> "Anomaly Detector"
534+ */
535+ const normalizeResourceTypeName = ( t : string ) => {
536+ const type = simpleName ( t ) ;
528537
529- /** Humanize class names: e.g., "AnomalyDetector" -> "Anomaly Detector", "ADDetector" -> "AD Detector" */
530- const humanizeClassName = ( fqn : string ) => {
531- const cls = simpleName ( fqn ) ;
532- return (
533- cls
534- // split "ADDetector" -> "AD Detector"
535- . replace ( / ( [ A - Z ] + ) ( [ A - Z ] [ a - z ] ) / g, '$1 $2' )
536- // split camelCase "AnomalyDetector" -> "Anomaly Detector"
537- . replace ( / ( [ a - z 0 - 9 ] ) ( [ A - Z ] ) / g, '$1 $2' )
538- // underscores to spaces
539- . replace ( / _ / g, ' ' )
540- . trim ( )
541- ) ;
538+ // 1) Insert spaces at camel/acronym boundaries, and normalize separators to spaces
539+ let s = type
540+ . replace ( / ( [ A - Z ] + ) ( [ A - Z ] [ a - z ] ) / g, '$1 $2' ) // "ADDetector" -> "AD Detector"
541+ . replace ( / ( [ a - z 0 - 9 ] ) ( [ A - Z ] ) / g, '$1 $2' ) // "AnomalyDetector" -> "Anomaly Detector"
542+ . replace ( / [ - _ ] + / g, ' ' ) // "sample-resource" / "sample_resource" -> "sample resource"
543+ . replace ( / \s + / g, ' ' ) // collapse multiple spaces
544+ . trim ( ) ;
545+
546+ // 2) Title-case tokens that are all-lowercase; keep existing caps/acronyms as-is.
547+ s = s . replace ( / \b ( [ a - z ] ) ( [ a - z 0 - 9 ] * ) \b / g, ( _ , a , rest ) => a . toUpperCase ( ) + rest ) ;
548+
549+ return s ;
542550} ;
543551
544552/** ---------- Main table ---------- */
545553export const ResourceSharingPanel : React . FC < Props > = ( { api, toasts } ) => {
546554 const [ typeOptions , setTypeOptions ] = useState <
547- Array < { value : string ; text : string ; fqn : string ; actionGroups : string [ ] } >
555+ Array < { value : string ; text : string ; actionGroups : string [ ] } >
548556 > ( [ ] ) ;
549557 const [ selectedType , setSelectedType ] = useState < string > ( '' ) ; // no default selection
550558 const [ rows , setRows ] = useState < ResourceRow [ ] > ( [ ] ) ;
@@ -567,17 +575,16 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
567575 // value = index (what we send as resourceType); text = type (what we display)
568576 const options = raw
569577 . map ( ( t ) => ( {
570- value : t . index ,
571- text : humanizeClassName ( t . type ) ,
572- fqn : t . type ,
578+ value : t . type ,
579+ text : normalizeResourceTypeName ( t . type ) ,
573580 actionGroups : t . action_groups ,
574581 } ) )
575582 // sort alphabetically by text (and by value if text is equal)
576583 . sort ( ( a , b ) => {
577584 const byText = a . text . localeCompare ( b . text , undefined , { sensitivity : 'base' } ) ;
578585 return byText !== 0
579586 ? byText
580- : a . fqn . localeCompare ( b . fqn , undefined , { sensitivity : 'base' } ) ;
587+ : a . value . localeCompare ( b . value , undefined , { sensitivity : 'base' } ) ;
581588 } ) ;
582589 setTypeOptions ( options ) ;
583590 } catch ( e : any ) {
@@ -590,10 +597,10 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
590597 } , [ toasts ] ) ;
591598
592599 // GET visible resource sharing records for selected type
593- const fetchSharingRecords = async ( index : string ) => {
600+ const fetchSharingRecords = async ( type : string ) => {
594601 setLoading ( true ) ;
595602 try {
596- const res = await api . listSharingRecords ( index ) ;
603+ const res = await api . listSharingRecords ( type ) ;
597604 const data : ResourceRow [ ] = Array . isArray ( res ) ? res : res ?. resources || res ?. body || [ ] ;
598605 setRows ( Array . isArray ( data ) ? data : [ ] ) ;
599606 } catch ( e : any ) {
@@ -609,7 +616,7 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
609616 selectedType ,
610617 ] ) ;
611618 const selectedTypeLabel = selectedTypeMeta ?. text ?? ( selectedType || '—' ) ;
612- const selectedTypeTooltip = selectedTypeMeta ?. fqn ; // actual class name
619+ const selectedTypeTooltip = selectedTypeMeta ?. value ; // actual resource type
613620
614621 const currentActionGroups = useMemo (
615622 ( ) => Array . from ( new Set ( selectedTypeMeta ?. actionGroups ?? [ ] ) ) . sort ( ) ,
@@ -753,9 +760,9 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
753760 const baseOptions = useMemo < Array < EuiSuperSelectOption < string > > > (
754761 ( ) =>
755762 typeOptions . map ( ( o ) => ( {
756- value : o . value , // index you send to backend
763+ value : o . value , // type name to send to backend
757764 inputDisplay : o . text , // humanized label when selected
758- dropdownDisplay : < span title = { o . fqn } > { o . text } </ span > , // show FQN on hover
765+ dropdownDisplay : < span title = { o . value } > { o . text } </ span > , // show original resource-type on hover
759766 } ) ) ,
760767 [ typeOptions ]
761768 ) ;
@@ -798,11 +805,11 @@ export const ResourceSharingPanel: React.FC<Props> = ({ api, toasts }) => {
798805 hasDividers
799806 onChange = { async ( value ) => {
800807 if ( value === PLACEHOLDER ) return ;
801- const resourceTypeIndex = value ;
802- setSelectedType ( resourceTypeIndex ) ;
808+ const resourceType = value ;
809+ setSelectedType ( resourceType ) ;
803810 setExpandedIds ( new Set ( ) ) ;
804811 setRows ( [ ] ) ;
805- if ( resourceTypeIndex ) await fetchSharingRecords ( resourceTypeIndex ) ;
812+ if ( resourceType ) await fetchSharingRecords ( resourceType ) ;
806813 } }
807814 />
808815 </ EuiFlexItem >
0 commit comments