@@ -576,32 +576,65 @@ fn PlanCard(state: PlansState, plan: PlanMeta) -> impl IntoView {
576576 class: blx-sr-card--open=move || expanded. get( )
577577 data-state=bucket. key( )
578578 >
579- <button
580- type ="button"
581- class="blx-sr-card__row"
582- aria-expanded=move || if expanded. get( ) { "true" } else { "false" }
583- on: click=on_toggle_card
584- >
585- <span class="blx-sr-card__chevron" aria-hidden="true" >
586- <LxIcon icon=icondata:: LuChevronRight width="14px" height="14px" />
587- </span>
588- <span class="blx-sr-card__icon" aria-hidden="true" >
589- <LxIcon icon=icondata:: LuClipboardList width="16px" height="16px" />
590- </span>
591- <span class="blx-sr-card__main" >
592- <span class="blx-sr-card__title-row" >
593- <span class="blx-sr-card__title" >{ title} </span>
594- <span class="blx-sr-card__badge" data-kind="plan" >"plan" </span>
595- { is_index. then( || view! {
596- <span class="blx-plans-card__protected" >{ i18n. tr( I18nKey :: PlansProtectedIndex ) } </span>
597- } ) }
579+ <div class="blx-sr-card__row blx-plans-card__row" >
580+ <button
581+ type ="button"
582+ class="blx-plans-card__row-main"
583+ aria-expanded=move || if expanded. get( ) { "true" } else { "false" }
584+ on: click=on_toggle_card
585+ >
586+ <span class="blx-sr-card__chevron" aria-hidden="true" >
587+ <LxIcon icon=icondata:: LuChevronRight width="14px" height="14px" />
598588 </span>
599- <span class="blx-sr-card__summary blx-plans-card__summary" >
600- <span class="blx-plans-card__path" >{ path. clone( ) } </span>
601- <PlanTaskSummaryIcons summary=summary. clone( ) />
589+ <span class="blx-sr-card__icon" aria-hidden="true" >
590+ <LxIcon icon=icondata:: LuClipboardList width="16px" height="16px" />
602591 </span>
603- </span>
604- </button>
592+ <span class="blx-sr-card__main" >
593+ <span class="blx-sr-card__title-row" >
594+ <span class="blx-sr-card__title" >{ title} </span>
595+ <span class="blx-sr-card__badge" data-kind="plan" >"plan" </span>
596+ { is_index. then( || view! {
597+ <span class="blx-plans-card__protected" >{ i18n. tr( I18nKey :: PlansProtectedIndex ) } </span>
598+ } ) }
599+ </span>
600+ <span class="blx-sr-card__summary blx-plans-card__summary" >
601+ <span class="blx-plans-card__path" >{ path. clone( ) } </span>
602+ <PlanTaskSummaryIcons summary=summary. clone( ) />
603+ </span>
604+ </span>
605+ </button>
606+ <button
607+ type ="button"
608+ class="blx-sr-btn blx-sr-btn--icon blx-plans-card__edit-toggle"
609+ disabled=move || body_loading. get( ) || saving. get( )
610+ aria-label=move || {
611+ if editing. get( ) {
612+ i18n. tr( I18nKey :: PlansPreview ) ( )
613+ } else {
614+ i18n. tr( I18nKey :: PlansEdit ) ( )
615+ }
616+ }
617+ title=move || {
618+ if editing. get( ) {
619+ i18n. tr( I18nKey :: PlansPreview ) ( )
620+ } else {
621+ i18n. tr( I18nKey :: PlansEdit ) ( )
622+ }
623+ }
624+ on: click=move |ev: web_sys:: MouseEvent | {
625+ ev. stop_propagation( ) ;
626+ toggle_plan_edit_from_header( state, card_path. get_value( ) , expanded, editing, body, draft, body_loading) ;
627+ }
628+ >
629+ { move || {
630+ if editing. get( ) {
631+ view! { <LxIcon icon=icondata:: LuEye width="13px" height="13px" /> } . into_any( )
632+ } else {
633+ view! { <LxIcon icon=icondata:: LuPencil width="13px" height="13px" /> } . into_any( )
634+ }
635+ } }
636+ </button>
637+ </div>
605638
606639 { move || expanded. get( ) . then( || {
607640 let is_loading = body_loading. get( ) ;
@@ -697,19 +730,6 @@ fn PlanCard(state: PlansState, plan: PlanMeta) -> impl IntoView {
697730 } . into_any( )
698731 } else {
699732 view! {
700- <button
701- type ="button"
702- class="blx-sr-btn"
703- disabled=!has_body
704- on: click=move |ev: web_sys:: MouseEvent | {
705- ev. stop_propagation( ) ;
706- draft. set( body. with( |b| b. clone( ) . unwrap_or_default( ) ) ) ;
707- editing. set( true ) ;
708- }
709- >
710- <LxIcon icon=icondata:: LuPencil width="13px" height="13px" />
711- <span>{ i18n. tr( I18nKey :: SrEdit ) } </span>
712- </button>
713733 <button
714734 type ="button"
715735 class="blx-sr-btn blx-sr-btn--primary"
@@ -782,6 +802,47 @@ fn read_plan_into(
782802 } ) ;
783803}
784804
805+ fn toggle_plan_edit_from_header (
806+ state : PlansState ,
807+ path : String ,
808+ expanded : RwSignal < bool > ,
809+ editing : RwSignal < bool > ,
810+ body : RwSignal < Option < String > > ,
811+ draft : RwSignal < String > ,
812+ loading : RwSignal < bool > ,
813+ ) {
814+ expanded. set ( true ) ;
815+ if editing. get_untracked ( ) {
816+ draft. set ( body. with_untracked ( |b| b. clone ( ) . unwrap_or_default ( ) ) ) ;
817+ editing. set ( false ) ;
818+ return ;
819+ }
820+ if let Some ( content) = body. get_untracked ( ) {
821+ draft. set ( content) ;
822+ editing. set ( true ) ;
823+ return ;
824+ }
825+ if loading. get_untracked ( ) {
826+ return ;
827+ }
828+ let Some ( ws) = state. workspace_cwd . get_untracked ( ) else {
829+ return ;
830+ } ;
831+ loading. set ( true ) ;
832+ spawn_local ( async move {
833+ match plan_read ( & ws, & path) . await {
834+ Ok ( PlanContent { content, .. } ) => {
835+ draft. set ( content. clone ( ) ) ;
836+ body. set ( Some ( content) ) ;
837+ editing. set ( true ) ;
838+ state. error . set ( None ) ;
839+ }
840+ Err ( e) => state. error . set ( Some ( e) ) ,
841+ }
842+ loading. set ( false ) ;
843+ } ) ;
844+ }
845+
785846fn write_plan_body (
786847 state : PlansState ,
787848 path : String ,
0 commit comments