@@ -11,17 +11,21 @@ import {
1111 Badge ,
1212 Box ,
1313 Code ,
14+ Collapse ,
1415 Divider ,
1516 Group ,
1617 Paper ,
1718 Stack ,
1819 Text ,
1920 Title ,
21+ UnstyledButton ,
2022} from "@mantine/core" ;
2123import {
2224 IconCalendar ,
2325 IconChartBar ,
2426 IconCheck ,
27+ IconChevronDown ,
28+ IconChevronUp ,
2529 IconClipboard ,
2630 IconExternalLink ,
2731 IconFile ,
@@ -33,6 +37,7 @@ import {
3337 IconX ,
3438} from "@tabler/icons-react" ;
3539import { Link } from "@tanstack/react-router" ;
40+ import { useState } from "react" ;
3641
3742import { ICON_SIZE } from "@/config/style-constants" ;
3843import { useVersionComparison } from "@/hooks/use-version-comparison" ;
@@ -442,6 +447,30 @@ export const EntityDataDisplay = ({ data, title }: EntityDataDisplayProps) => {
442447 // Group and prepare data
443448 const sections = groupFields ( data ) ;
444449
450+ // Track collapsed state for each section
451+ // Basic Information and Identifiers are expanded by default, others collapsed
452+ const [ collapsedSections , setCollapsedSections ] = useState < Set < string > > ( ( ) => {
453+ const initial = new Set < string > ( ) ;
454+ sections . forEach ( section => {
455+ if ( section . name !== "Basic Information" && section . name !== "Identifiers" ) {
456+ initial . add ( section . name ) ;
457+ }
458+ } ) ;
459+ return initial ;
460+ } ) ;
461+
462+ const toggleSection = ( sectionName : string ) => {
463+ setCollapsedSections ( prev => {
464+ const next = new Set ( prev ) ;
465+ if ( next . has ( sectionName ) ) {
466+ next . delete ( sectionName ) ;
467+ } else {
468+ next . add ( sectionName ) ;
469+ }
470+ return next ;
471+ } ) ;
472+ } ;
473+
445474 // Version comparison for Works
446475 const workId = typeof data . id === 'string' && data . id . startsWith ( 'W' ) ? data . id : undefined ;
447476 const shouldShowComparison = Boolean ( workId && isDataVersionSelectorVisible ( ) ) ;
@@ -463,32 +492,50 @@ export const EntityDataDisplay = ({ data, title }: EntityDataDisplayProps) => {
463492 ) }
464493
465494 { /* Render sections */ }
466- { sections . map ( ( section ) => (
467- < Paper key = { section . name } withBorder p = "md" radius = "md" >
468- { /* Section header */ }
469- < Group gap = "sm" mb = "md" >
470- { section . icon }
471- < Text size = "lg" fw = { 600 } > { section . name } </ Text >
472- < Badge variant = "light" color = "gray" size = "sm" >
473- { section . fields . length } { section . fields . length === 1 ? "field" : "fields" }
474- </ Badge >
475- </ Group >
476-
477- < Divider mb = "md" />
478-
479- { /* Section fields */ }
480- < Stack gap = "md" >
481- { section . fields . map ( ( field ) => (
482- < Box key = { field . key } >
483- < Text size = "sm" fw = { 600 } c = "blue.7" mb = "xs" >
484- { humanizeFieldName ( field . key ) }
485- </ Text >
486- { renderValueContent ( field . value ) }
487- </ Box >
488- ) ) }
489- </ Stack >
490- </ Paper >
491- ) ) }
495+ { sections . map ( ( section ) => {
496+ const isCollapsed = collapsedSections . has ( section . name ) ;
497+ return (
498+ < Paper key = { section . name } withBorder p = "md" radius = "md" >
499+ { /* Clickable section header */ }
500+ < UnstyledButton
501+ onClick = { ( ) => toggleSection ( section . name ) }
502+ style = { { width : '100%' } }
503+ mb = "sm"
504+ >
505+ < Group gap = "sm" justify = "space-between" pr = "xs" >
506+ < Group gap = "sm" >
507+ { section . icon }
508+ < Text size = "lg" fw = { 600 } > { section . name } </ Text >
509+ < Badge variant = "light" color = "gray" size = "sm" >
510+ { section . fields . length } { section . fields . length === 1 ? "field" : "fields" }
511+ </ Badge >
512+ </ Group >
513+ { isCollapsed ? (
514+ < IconChevronDown size = { ICON_SIZE . MD } color = "var(--mantine-color-dimmed)" />
515+ ) : (
516+ < IconChevronUp size = { ICON_SIZE . MD } color = "var(--mantine-color-dimmed)" />
517+ ) }
518+ </ Group >
519+ </ UnstyledButton >
520+
521+ < Collapse in = { ! isCollapsed } >
522+ < Divider mb = "md" />
523+
524+ { /* Section fields */ }
525+ < Stack gap = "md" >
526+ { section . fields . map ( ( field ) => (
527+ < Box key = { field . key } >
528+ < Text size = "sm" fw = { 600 } c = "blue.7" mb = "xs" >
529+ { humanizeFieldName ( field . key ) }
530+ </ Text >
531+ { renderValueContent ( field . value ) }
532+ </ Box >
533+ ) ) }
534+ </ Stack >
535+ </ Collapse >
536+ </ Paper >
537+ ) ;
538+ } ) }
492539 </ Stack >
493540 ) ;
494541} ;
0 commit comments