Put all header content in one row (if it can fit)

eeb992ced3b4b19b6b09746f614c9e75f8cacf60

Tucker McKnight <tmcknight@instructure.com> | Sun Mar 08 2026

Put all header content in one row (if it can fit)

Also wraps all if it in a div.col, instead of having the navbar
and theme selector being in different columns. (They are still in
different columns inside of a nested row now, but there is an overall
.col that they are in.) This should make future styling easier.
js_templates/common/commonPage.ts:18
Before
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45


46
47
48
49
50
51
52
        ]),
        m('body', [
          m('div', {class: "container-fluid container-lg"}, [
            m('div', {class: "row"}, [
⁣
⁣
              m('div', {class: "col"}, [
                opts.navbarContent || null,
              ]),
              m('div', {class: "col-auto pt-2"}, [
                m('div', {class: "dropdown"}, [
                  m('button', {class: "dropdown-toggle btn btn-bg", id: "dark-mode-switch", type: "button", 'data-bs-toggle': "dropdown", 'aria-expanded': 'false'},
                    m('span', m.trust('&#xFE0F;'))
                  ),
                  m('ul', {class: "dropdown-menu"}, [
                    m('li',
                      m('button', {class: "btn shadow-none", 'data-theme-pref': "light", onclick: "toggleDarkMode(this)"}, [
                        m('span', {class: "me-1"}, m.trust('&#x1F31E;')),
                        'Light'
                      ])
                    ),
                    m('li',
                      m('button', {class: "btn shadow-none", 'data-theme-pref': "dark", onclick: "toggleDarkMode(this)"}, [
                        m('span', {class: "me-1"}, m.trust('&#x1F319;')),
                        'Dark'
                      ])
                    ),
                    m('li',
                      m('button', {class: "btn shadow-none", 'data-theme-pref': "auto", onclick: "toggleDarkMode(this)"}, [
                        m('span', {class: "me-1"}, m.trust('&#x1F5A5;&#xFE0F;')),
                        'Match OS'
⁣
⁣
                      ])
                    )
                  ])
                ])
              ])
            ]),
            await opts.pageContent,
          ]),
After
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        ]),
        m('body', [
          m('div', {class: "container-fluid container-lg"}, [
            m('div', {class: "row mb-1"}, [
              m('div', {class: "col"},
                m('div', {class: "row"},
                  m('div', {class: "col"}, [
                    opts.navbarContent || null,
                  ]),
                  m('div', {class: "col-auto pt-2"}, [
                    m('div', {class: "dropdown"}, [
                      m('button', {class: "dropdown-toggle btn btn-bg", id: "dark-mode-switch", type: "button", 'data-bs-toggle': "dropdown", 'aria-expanded': 'false'},
                        m('span', m.trust('&#xFE0F;'))
                      ),
                      m('ul', {class: "dropdown-menu"}, [
                        m('li',
                          m('button', {class: "btn shadow-none", 'data-theme-pref': "light", onclick: "toggleDarkMode(this)"}, [
                            m('span', {class: "me-1"}, m.trust('&#x1F31E;')),
                            'Light'
                          ])
                        ),
                        m('li',
                          m('button', {class: "btn shadow-none", 'data-theme-pref': "dark", onclick: "toggleDarkMode(this)"}, [
                            m('span', {class: "me-1"}, m.trust('&#x1F319;')),
                            'Dark'
                          ])
                        ),
                        m('li',
                          m('button', {class: "btn shadow-none", 'data-theme-pref': "auto", onclick: "toggleDarkMode(this)"}, [
                            m('span', {class: "me-1"}, m.trust('&#x1F5A5;&#xFE0F;')),
                            'Match OS'
                          ])
                        )
                      ])
                    ])
                  ])
                )
              )
            ]),
            await opts.pageContent,
          ]),
js_templates/common/htmlPage.ts:41
Before
40
41
42
43
44
45
46
47
48
49
50
51
        href: `${data.reposPath}/vendor/prism.css`
      }),
    ],
    navbarContent: m('nav', {class: "navbar navbar-expand"}, [
      m('ul', {class: "navbar-nav flex-wrap"}, [
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.rootPath()
          }, m.trust('&#10094; Repos'))
        ),
        m('li', {class: "nav-item"},
          m('a', {
After
40
41
42
43
44
45
46
47
48
49
50
51
        href: `${data.reposPath}/vendor/prism.css`
      }),
    ],
    navbarContent: m('nav', {class: "navbar navbar-expand flex-wrap"}, [
      m('ul', {class: "navbar-nav flex-wrap"}, [
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.rootPath()
          }, m.trust('&#10094; repos'))
        ),
        m('li', {class: "nav-item"},
          m('a', {
js_templates/common/htmlPage.ts:55
Before
54
55
56
57
58
59
60
            href: nav.repoCurrentBranchHome()
          }, repo.name)
        ),
        m('li', {class: "nav-item"}, [
          m('span', {class: "nav-link d-inline-block"}, 'Branch:'),
          m('div', {class: "branch-selector dropdown-center d-inline-block"}, [
            m('button', {
              class: "branches nav-link d-inline-block btn btn-bg dropdown-toggle",
After
54
55
56
57
58
59
60
            href: nav.repoCurrentBranchHome()
          }, repo.name)
        ),
        m('li', {class: "nav-item me-4 mb-1"}, [
          m('span', {class: "nav-link d-inline-block"}, 'ref:'),
          m('div', {class: "branch-selector dropdown-center d-inline-block"}, [
            m('button', {
              class: "branches nav-link d-inline-block btn btn-bg dropdown-toggle",
js_templates/common/htmlPage.ts:75
Before
74
75
76
77
78
79
80
81
82
83
                  ),
                  m('div', {class: "sortRadioButtons"}, [
                    m('div', {class: "sortRadioButton pe-1"}, [
                      m('input', {class: "form-check-input sort-filter", type: "radio", name: "branchSort", value: 'date', id: "branchSortByDate", checked: true}),
                      m('label', {class: "form-check-label", for: "branchSortByDate"}, 'Last commit')
                    ]),
                    m('div', {class: "sortRadioButton ps-1"}, [
                      m('input', {class: "form-check-input sort-filter", type: "radio", name: "branchSort", value: 'name', id: "branchSortByName"}),
                      m('label', {class: "form-check-label", for: "branchSortByName"}, 'Name')
                    ])
                  ])
After
74
75
76
77
78
79
80
81
82
83
                  ),
                  m('div', {class: "sortRadioButtons"}, [
                    m('div', {class: "sortRadioButton pe-1"}, [
                      m('input', {class: "form-check-input sort-filter me-1", type: "radio", name: "branchSort", value: 'date', id: "branchSortByDate", checked: true}),
                      m('label', {class: "form-check-label", for: "branchSortByDate"}, 'Last commit')
                    ]),
                    m('div', {class: "sortRadioButton ps-1"}, [
                      m('input', {class: "form-check-input sort-filter me-1", type: "radio", name: "branchSort", value: 'name', id: "branchSortByName"}),
                      m('label', {class: "form-check-label", for: "branchSortByName"}, 'Name')
                    ])
                  ])
js_templates/common/htmlPage.ts:91
Before
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116


117
118
              )
            ])
          ])
        ])
      ])
    ]),
    pageContent: [
      m('div', {class: "row"},
        m('div', {class: "col"},
          m('nav', {class: "navbar navbar-expand"},
            m('ul', {class: "main-nav navbar-nav flex-wrap"}, [
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'home' ? 'active' : ''}`, 'aria-current': "page", href: nav.repoCurrentBranchHome()}, 'Home')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'files' ? 'active' : ''}`, href: nav.repoCurrentBranchFiles()}, 'Files')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'commits' ? 'active' : ''}`, href: nav.repoCurrentBranchCommits()}, 'Commits')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
              )
            ])
          )
        )
      ),
⁣
⁣
      m('div', {class: "row"},
        m('div', {class: "col-12"},
          await pageContent
After
90
91
92


93




94
95
96
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112
              )
            ])
          ])
⁣
⁣
        ]),
⁣
⁣
⁣
⁣
        m('ul', {class: "main-nav navbar-nav flex-wrap"}, [
          m('li', {class: "nav-item"},
            m('a', {class: `nav-link ${data.navTab === 'home' ? 'active' : ''}`, 'aria-current': "page", href: nav.repoCurrentBranchHome()}, 'Home')
          ),
          m('li', {class: "nav-item"},
            m('a', {class: `nav-link ${data.navTab === 'files' ? 'active' : ''}`, href: nav.repoCurrentBranchFiles()}, 'Files')
          ),
          m('li', {class: "nav-item"},
            m('a', {class: `nav-link ${data.navTab === 'commits' ? 'active' : ''}`, href: nav.repoCurrentBranchCommits()}, 'Commits')
          ),
          m('li', {class: "nav-item"},
            m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
⁣
⁣
          )
        ])
      ]),
    ]),
    pageContent: [
      m('div', {class: "row"},
        m('div', {class: "col-12"},
          await pageContent
js_templates/index.ts:10
Before
9
10
11
12
13
14
15

16
17
18
        m('h1', data.reposConfig.defaultTemplateConfiguration?.allRepositoriesPageTitle || "All Repositories")
      )
    ),
    m('div', {class: "row"},
      m('div', {class: "col d-flex flex-wrap"},
        data.repos.map((repo) => {
          return (
⁣
            m('div', {class: "m-2 card bezel-gray flex-grow-1", style: "flex-basis: 20rem;"},
              m('div', {class: "card-header"},
                m('a', {class: "card-title fs-5", href: `${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}`}, repo.name)
              ),
After
9
10
11

12
13
14
15
16
17
18
        m('h1', data.reposConfig.defaultTemplateConfiguration?.allRepositoriesPageTitle || "All Repositories")
      )
    ),
⁣
    m('div', {class: "row d-flex flex-wrap"},
      data.repos.map((repo) => {
        return (
          m('div', {class: "col", style: "flex-basis: 50%; max-width: 50%;"},
            m('div', {class: "my-2 card bezel-gray flex-grow-1"},
              m('div', {class: "card-header"},
                m('a', {class: "card-title fs-5", href: `${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}`}, repo.name)
              ),
js_templates/index.ts:40
Before
39
40
41
42
43
44
45
              ])
            )
          )
        })
      )
    )
  ])
After
39
40
41
42
43
44
45
              ])
            )
          )
        )
      })
    )
  ])
src/repos.ts:14
Before
13
14
15
16
17
18

const exec = util.promisify(childProcess.exec)

const branchesForReposMap: Map<string, Array<{name: string, description?: string, compareTO?: string}>> = new Map()

const getBranches = async (repoConfig: GitConfig, repoName: string): Promise<Array<{name: string, description?: string, compareTo?: string}>> => {
  const cachedBranchNames = branchesForReposMap.get(repoName)
After
13
14
15
16
17
18

const exec = util.promisify(childProcess.exec)

const branchesForReposMap: Map<string, Array<{name: string, description?: string, compareTo?: string}>> = new Map()

const getBranches = async (repoConfig: GitConfig, repoName: string): Promise<Array<{name: string, description?: string, compareTo?: string}>> => {
  const cachedBranchNames = branchesForReposMap.get(repoName)