Signed by hanna SSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
assets/base.css +91 −15 assets/fabrica.js +2 −2 crates/web/src/layout.rs +34 −2 crates/web/src/repo.rs +5 −1 assets/base.css +91 −15 118 background : var ( --fb-bg-inset ) ; 118 background : var ( --fb-bg-inset ) ; 119 } 119 } 120 120 121 121 122 122 123 . topbar-new { 123 124 . topbar-create { 124 margin-left : auto ; 125 margin-left : auto ; 126 position : relative ; 125 } 127 } 126 . topbar-search { 128 . topbar-search { 127 display : flex ; 129 display : flex ; 128 align-items : center ; 130 align-items : center ; 129 gap : 0.25rem ; 131 gap : 0.25rem ; 130 flex : 1 ; 132 flex : 0 1 28rem ; 131 max-width : 28rem ; 133 margin-left : auto ; 132 } 134 } 133 . topbar-search input [ type = "search" ] { 135 . topbar-search input [ type = "search" ] { 134 width : 100% ; 136 width : 100% ; 139 color : var ( --fb-fg ) ; 141 color : var ( --fb-fg ) ; 140 } 142 } 141 143 144 145 . topbar-create > summary { 146 list-style : none ; 147 cursor : pointer ; 148 } 149 . topbar-create > summary :: -webkit-details-marker { 150 display : none ; 151 } 152 . menu-popover { 153 position : absolute ; 154 right : 0 ; 155 top : calc ( 100% + 0.35rem ) ; 156 z-index : 30 ; 157 min-width : 13rem ; 158 padding : 0.35rem ; 159 background : var ( --fb-bg-raised ) ; 160 border : 1px solid var ( --fb-border ) ; 161 border-radius : var ( --fb-radius ) ; 162 box-shadow : 0 10px 28px rgba ( 0 , 0 , 0 , 0.35 ) ; 163 } 164 . menu-item { 165 display : flex ; 166 align-items : center ; 167 gap : 0.55rem ; 168 padding : 0.45rem 0.6rem ; 169 border-radius : var ( --fb-radius ) ; 170 color : var ( --fb-fg ) ; 171 white-space : nowrap ; 172 } 173 . menu-item : hover { 174 background : var ( --fb-bg-inset ) ; 175 text-decoration : none ; 176 } 177 142 . icon-btn { 178 . icon-btn { 143 display : inline-flex ; 179 display : inline-flex ; 144 align-items : center ; 180 align-items : center ; 228 . page { 264 . page { 229 max-width : 76rem ; 265 max-width : 76rem ; 230 margin : 0 auto ; 266 margin : 0 auto ; 231 padding : var ( --fb-gap ) ; 267 268 padding : calc ( var ( --fb-gap ) * 1.75 ) var ( --fb-gap ) calc ( var ( --fb-gap ) * 2 ) ; 232 } 269 } 233 270 234 . card { 271 . card { 314 min-width : 10rem ; 351 min-width : 10rem ; 315 } 352 } 316 . label-add input [ type = "color" ] { 353 . label-add input [ type = "color" ] { 317 width : 2.6rem ; 354 width : 2.8rem ; 318 padding : 0.15rem ; 319 height : 2.4rem ; 355 height : 2.4rem ; 356 padding : 0 ; 357 border : 1px solid var ( --fb-border ) ; 358 border-radius : var ( --fb-radius ) ; 359 background : var ( --fb-bg-inset ) ; 360 cursor : pointer ; 361 } 362 . label-add input [ type = "color" ] :: -webkit-color-swatch-wrapper { 363 padding : 3px ; 364 } 365 . label-add input [ type = "color" ] :: -webkit-color-swatch { 366 border : none ; 367 border-radius : 3px ; 368 } 369 . label-add input [ type = "color" ] :: -moz-color-swatch { 370 border : none ; 371 border-radius : 3px ; 320 } 372 } 321 . label-add button { 373 . label-add button { 322 flex : none ; 374 flex : none ; 593 margin-bottom : 1rem ; 645 margin-bottom : 1rem ; 594 } 646 } 595 . key-list { 647 . key-list { 596 margin-bottom : 1rem ; 648 margin-bottom : 1.25rem ; 649 } 650 . key-list . entry-row { 651 align-items : center ; 652 } 653 . key-list . entry-row-title { 654 display : flex ; 655 align-items : center ; 656 gap : 0.5rem ; 657 } 658 . key-list . entry-row-meta { 659 margin-top : 0.2rem ; 660 font-size : 0.85em ; 661 } 662 . key-add { 663 padding-top : 1rem ; 664 border-top : 1px solid var ( --fb-border ) ; 597 } 665 } 598 . key-add textarea { 666 . key-add textarea { 599 font-family : var ( --fb-font-mono ) ; 667 font-family : var ( --fb-font-mono ) ; 668 font-size : 0.88em ; 600 } 669 } 601 . key-add-row { 670 . key-add-row { 602 display : flex ; 671 display : flex ; 603 align-items : center ; 672 align-items : center ; 604 gap : 0.75rem ; 673 gap : 0.6rem ; 605 flex-wrap : wrap ; 674 flex-wrap : wrap ; 606 margin-bottom : 0.5rem ; 675 margin-bottom : 0.6rem ; 607 } 676 } 608 . key-add-row select , 677 . key-add-row label { 609 . key-add-row input { 678 margin : 0 ; 679 } 680 . key-add-row select { 610 width : auto ; 681 width : auto ; 611 } 682 } 683 . key-add-row input { 684 flex : 1 ; 685 min-width : 12rem ; 686 } 612 . token-scopes { 687 . token-scopes { 613 margin : 0.75rem 0 0 ; 688 margin : 0.75rem 0 0 ; 614 padding : 0.5rem 0.85rem ; 689 padding : 0.5rem 0.85rem ; 669 display : none !important ; 744 display : none !important ; 670 } 745 } 671 746 672 747 673 . new-repo { 748 . new-repo { 674 max-width : 42rem ; 749 max-width : 40rem ; 750 margin : 0 auto ; 675 } 751 } 676 752 677 753
assets/fabrica.js +2 −2 51 51 52 52 53 document . addEventListener ( "click" , function ( e ) { 53 document . addEventListener ( "click" , function ( e ) { 54 document . querySelectorAll ( "details.clone-menu[open], details.branch-menu[open]" ) . forEach ( function ( d ) { 54 document . querySelectorAll ( "details.clone-menu[open], details.branch-menu[open], details[data-menu][open]" ) . forEach ( function ( d ) { 55 if ( ! d . contains ( e . target) ) d . removeAttribute ( "open" ) ; 55 if ( ! d . contains ( e . target) ) d . removeAttribute ( "open" ) ; 56 } ) ; 56 } ) ; 57 } ) ; 57 } ) ; 132 } 132 } 133 } else if ( e . key === "Escape" ) { 133 } else if ( e . key === "Escape" ) { 134 toggleDrawer ( false ) ; 134 toggleDrawer ( false ) ; 135 document . querySelectorAll ( "details.clone-menu[open], details.branch-menu[open]" ) . forEach ( function ( d ) { 135 document . querySelectorAll ( "details.clone-menu[open], details.branch-menu[open], details[data-menu][open]" ) . forEach ( function ( d ) { 136 d . removeAttribute ( "open" ) ; 136 d . removeAttribute ( "open" ) ; 137 } ) ; 137 } ) ; 138 } 138 }
crates/web/src/layout.rs +34 −2 75 aria-controls="drawer" aria-expanded="false" { ( icon ( Icon :: PanelLeft ) ) } 75 aria-controls="drawer" aria-expanded="false" { ( icon ( Icon :: PanelLeft ) ) } 76 span class="slug" { a href="/" { ( chrome. instance_name) } } 76 span class="slug" { a href="/" { ( chrome. instance_name) } } 77 @if chrome. user. is_some ( ) { 77 @if chrome. user. is_some ( ) { 78 a class="icon-btn topbar-new" href="/new" aria-label="New repository" 78 ( create_menu ( chrome) ) 79 title="New repository" { ( icon ( Icon :: Plus ) ) } 80 } 79 } 81 form class="topbar-search" method="get" action="/search" role="search" { 80 form class="topbar-search" method="get" action="/search" role="search" { 82 input type ="search" name="q" placeholder="Search…" aria-label="Search" ; 81 input type ="search" name="q" placeholder="Search…" aria-label="Search" ; 85 } 84 } 86 } 85 } 87 86 87 88 89 90 fn create_menu ( chrome : & Chrome ) -> Markup { 91 let repo_base = repo_base ( & chrome. path) ; 92 html ! { 93 details class="topbar-create menu" data-menu { 94 summary class="icon-btn" aria-label="Create new" title="Create new" { 95 ( icon ( Icon :: Plus ) ) 96 } 97 div class="menu-popover" role="menu" { 98 a class="menu-item" role="menuitem" href="/new" { 99 ( icon ( Icon :: Box ) ) span { "New repository" } 100 } 101 @if let Some ( base) = & repo_base { 102 a class="menu-item" role="menuitem" href=( format ! ( "{base}/-/issues/new" ) ) { 103 ( icon ( Icon :: Issue ) ) span { "New issue" } 104 } 105 a class="menu-item" role="menuitem" href=( format ! ( "{base}/-/pulls/new" ) ) { 106 ( icon ( Icon :: GitPull ) ) span { "New pull request" } 107 } 108 } 109 } 110 } 111 } 112 } 113 114 115 116 fn repo_base ( path : & str ) -> Option < String > { 117 path. split_once ( "/-/" ) . map ( |( base, _) | base. to_string ( ) ) 118 } 119 88 120 89 fn drawer ( chrome : & Chrome ) -> Markup { 121 fn drawer ( chrome : & Chrome ) -> Markup { 90 html ! { 122 html ! {
crates/web/src/repo.rs +5 −1 806 } 806 } 807 } 807 } 808 ( collaborators_section ( id, & chrome. csrf, & collaborators) ) 808 ( collaborators_section ( id, & chrome. csrf, & collaborators) ) 809 ( labels_section ( id, & chrome. csrf, & labels) ) 809 810 811 @if ctx. repo. issues_enabled || ctx. repo. pulls_enabled { 812 ( labels_section ( id, & chrome. csrf, & labels) ) 813 } 810 section class="listing" { 814 section class="listing" { 811 h2 { "Danger zone" } 815 h2 { "Danger zone" } 812 div class="card danger-zone" { 816 div class="card danger-zone" {