@@ -1272,7 +1272,7 @@ fn draw_detail(f: &mut Frame, area: Rect, app: &mut App) {
12721272 . border_style ( Style :: default ( ) . fg ( border_color) ) ;
12731273
12741274 // build the content lines first, collecting all needed data
1275- let lines = build_detail_lines ( app) ;
1275+ let lines = build_detail_lines ( app, app . detail_dep_selected ) ;
12761276
12771277 if lines. is_empty ( ) {
12781278 let text = Paragraph :: new ( "no issue selected" ) . block ( block. clone ( ) . title ( " Detail " ) ) ;
@@ -1324,7 +1324,8 @@ fn draw_detail(f: &mut Frame, area: Rect, app: &mut App) {
13241324}
13251325
13261326/// build content lines for the detail pane, returning empty vec if no issue selected.
1327- fn build_detail_lines ( app : & App ) -> Vec < Line < ' static > > {
1327+ /// `selected_dep` enables numbered prefixes and preview for the detail pane; pass None for overlay.
1328+ fn build_detail_lines ( app : & App , selected_dep : Option < usize > ) -> Vec < Line < ' static > > {
13281329 let Some ( issue) = app. selected_issue ( ) else {
13291330 return Vec :: new ( ) ;
13301331 } ;
@@ -1397,19 +1398,22 @@ fn build_detail_lines(app: &App) -> Vec<Line<'static>> {
13971398
13981399 // deps
13991400 if !issue. deps ( ) . is_empty ( ) {
1400- let selected_dep = app. detail_dep_selected ;
14011401 lines. push ( Line :: from ( "" ) ) ;
14021402 lines. push ( Line :: from ( Span :: styled (
14031403 "Dependencies:" ,
14041404 Style :: default ( ) . fg ( Color :: DarkGray ) ,
14051405 ) ) ) ;
14061406 for ( idx, dep_id) in issue. deps ( ) . iter ( ) . enumerate ( ) {
1407- let is_selected = Some ( idx) == selected_dep;
1408- // show number for selection (1-9), or bullet for overflow
1409- let prefix = if idx < 9 {
1410- format ! ( "{}" , idx + 1 )
1407+ let is_selected = selected_dep == Some ( idx) ;
1408+ // show number for selection (1-9) when selection enabled, otherwise bullet
1409+ let prefix = if selected_dep. is_some ( ) {
1410+ if idx < 9 {
1411+ format ! ( "{}" , idx + 1 )
1412+ } else {
1413+ "-" . to_string ( )
1414+ }
14111415 } else {
1412- "- " . to_string ( )
1416+ " " . to_string ( )
14131417 } ;
14141418
14151419 let ( symbol, status_text, base_color) = if let Some ( dep_issue) = app. issues . get ( dep_id)
@@ -1536,155 +1540,11 @@ fn draw_detail_overlay(f: &mut Frame, area: Rect, app: &App) {
15361540 . borders ( Borders :: ALL )
15371541 . border_style ( Style :: default ( ) . fg ( Color :: Yellow ) ) ;
15381542
1539- let Some ( issue) = app. selected_issue ( ) else {
1543+ let lines = build_detail_lines ( app, None ) ;
1544+ if lines. is_empty ( ) {
15401545 let text = Paragraph :: new ( "no issue selected" ) . block ( block) ;
15411546 f. render_widget ( text, overlay_area) ;
15421547 return ;
1543- } ;
1544-
1545- let derived = app. derived_state ( issue) ;
1546-
1547- let mut lines: Vec < Line > = vec ! [
1548- Line :: from( vec![
1549- Span :: styled( "ID: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1550- Span :: raw( issue. id( ) ) ,
1551- ] ) ,
1552- Line :: from( vec![
1553- Span :: styled( "Title: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1554- Span :: raw( issue. title( ) ) ,
1555- ] ) ,
1556- Line :: from( vec![
1557- Span :: styled( "Priority: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1558- Span :: raw( issue. priority( ) . to_string( ) ) ,
1559- ] ) ,
1560- Line :: from( vec![
1561- Span :: styled( "Status: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1562- Span :: styled(
1563- issue. status( ) . to_string( ) ,
1564- match issue. status( ) {
1565- crate :: issue:: Status :: Done => Style :: default ( ) . fg( Color :: Green ) ,
1566- crate :: issue:: Status :: Doing => Style :: default ( ) . fg( Color :: Yellow ) ,
1567- crate :: issue:: Status :: Open => Style :: default ( ) ,
1568- crate :: issue:: Status :: Skip => Style :: default ( ) . fg( Color :: DarkGray ) ,
1569- } ,
1570- ) ,
1571- ] ) ,
1572- ] ;
1573-
1574- if let Some ( owner) = & issue. frontmatter . owner {
1575- lines. push ( Line :: from ( vec ! [
1576- Span :: styled( "Owner: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1577- Span :: raw( owner. as_str( ) ) ,
1578- ] ) ) ;
1579- }
1580-
1581- // tags
1582- if !issue. frontmatter . tags . is_empty ( ) {
1583- let tags = issue
1584- . frontmatter
1585- . tags
1586- . iter ( )
1587- . map ( |t| format ! ( "#{}" , t) )
1588- . collect :: < Vec < _ > > ( )
1589- . join ( " " ) ;
1590- lines. push ( Line :: from ( vec ! [
1591- Span :: styled( "Tags: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1592- Span :: styled( tags, Style :: default ( ) . fg( Color :: Cyan ) ) ,
1593- ] ) ) ;
1594- }
1595-
1596- // state
1597- let state_text = if derived. is_ready {
1598- Span :: styled ( "READY" , Style :: default ( ) . fg ( Color :: Green ) )
1599- } else if derived. is_blocked {
1600- Span :: styled ( "BLOCKED" , Style :: default ( ) . fg ( Color :: Red ) )
1601- } else {
1602- Span :: raw ( "" )
1603- } ;
1604- if !state_text. content . is_empty ( ) {
1605- lines. push ( Line :: from ( vec ! [
1606- Span :: styled( "State: " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
1607- state_text,
1608- ] ) ) ;
1609- }
1610-
1611- // deps
1612- if !issue. deps ( ) . is_empty ( ) {
1613- lines. push ( Line :: from ( "" ) ) ;
1614- lines. push ( Line :: from ( Span :: styled (
1615- "Dependencies:" ,
1616- Style :: default ( ) . fg ( Color :: DarkGray ) ,
1617- ) ) ) ;
1618- for dep_id in issue. deps ( ) {
1619- let ( symbol, status_text, base_color) = if let Some ( dep_issue) = app. issues . get ( dep_id)
1620- {
1621- match dep_issue. status ( ) {
1622- Status :: Done => ( "✓" , "done" , Color :: Green ) ,
1623- Status :: Skip => ( "⊘" , "skip" , Color :: DarkGray ) ,
1624- Status :: Doing => ( "→" , "doing" , Color :: Yellow ) ,
1625- Status :: Open => ( "○" , "open" , Color :: White ) ,
1626- }
1627- } else {
1628- ( "?" , "missing" , Color :: Red )
1629- } ;
1630-
1631- lines. push ( Line :: from ( Span :: styled (
1632- format ! ( " {} {} ({})" , symbol, dep_id, status_text) ,
1633- Style :: default ( ) . fg ( base_color) ,
1634- ) ) ) ;
1635- }
1636- }
1637-
1638- // dependents (reverse deps - issues that depend on this one)
1639- let dependents = get_dependents ( issue. id ( ) , & app. issues ) ;
1640- if !dependents. is_empty ( ) {
1641- lines. push ( Line :: from ( "" ) ) ;
1642- lines. push ( Line :: from ( Span :: styled (
1643- "Dependents:" ,
1644- Style :: default ( ) . fg ( Color :: DarkGray ) ,
1645- ) ) ) ;
1646- for dep_id in & dependents {
1647- let ( symbol, status_text, base_color) = if let Some ( dep_issue) = app. issues . get ( dep_id)
1648- {
1649- match dep_issue. status ( ) {
1650- Status :: Done => ( "✓" , "done" , Color :: Green ) ,
1651- Status :: Skip => ( "⊘" , "skip" , Color :: DarkGray ) ,
1652- Status :: Doing => ( "→" , "doing" , Color :: Yellow ) ,
1653- Status :: Open => ( "○" , "open" , Color :: White ) ,
1654- }
1655- } else {
1656- ( "?" , "missing" , Color :: Red )
1657- } ;
1658-
1659- lines. push ( Line :: from ( Span :: styled (
1660- format ! ( " {} {} ({})" , symbol, dep_id, status_text) ,
1661- Style :: default ( ) . fg ( base_color) ,
1662- ) ) ) ;
1663- }
1664- }
1665-
1666- // acceptance
1667- if !issue. frontmatter . acceptance . is_empty ( ) {
1668- lines. push ( Line :: from ( "" ) ) ;
1669- lines. push ( Line :: from ( Span :: styled (
1670- "Acceptance:" ,
1671- Style :: default ( ) . fg ( Color :: DarkGray ) ,
1672- ) ) ) ;
1673- for ac in & issue. frontmatter . acceptance {
1674- lines. push ( Line :: from ( format ! ( " - {}" , ac) ) ) ;
1675- }
1676- }
1677-
1678- // body
1679- if !issue. body . is_empty ( ) {
1680- lines. push ( Line :: from ( "" ) ) ;
1681- lines. push ( Line :: from ( Span :: styled (
1682- "Description:" ,
1683- Style :: default ( ) . fg ( Color :: DarkGray ) ,
1684- ) ) ) ;
1685- for line in issue. body . lines ( ) {
1686- lines. push ( Line :: from ( format ! ( " {}" , line) ) ) ;
1687- }
16881548 }
16891549
16901550 let text = Text :: from ( lines) ;
0 commit comments