Add clone buttons and homepage buttons to index

6122634d2ba8175cf3dfc6ff1bd73a2c6f1e420e

Tucker McKnight | Mon Dec 29 2025

Add clone buttons and homepage buttons to index

Fix some Js errors and make buttons use classes instead of IDs
since there are multiple of them on the index page.

Some style changes.
frontend/main.js:3
Before
3
setCheckbox(currentTheme, document.getElementById('dark-mode-switch'))
After
3
if (setCheckbox) {
  setCheckbox(currentTheme, document.getElementById('dark-mode-switch'))
}
frontend/main.js:18
Before
18
19
20
21
22
const createClonePopover = () => {
  div.id = "clone-popover"
      <span class='clone overflow-hidden input-group-text'>${window.cloneUrl}</span>
      <button data-copy-text='${window.cloneUrl}' class='btn btn-primary shadow-none text-white' id='copy-button'>Copy</button>
  const popoverBtn = document.getElementById("clone-popover-btn")
After
18
19
20
21
22
const createClonePopover = (popoverBtn, url) => {
  // div.id = "clone-popover"
      <span class='clone overflow-hidden input-group-text'>${url || window.cloneUrl}</span>
      <button data-copy-text='${url || window.cloneUrl}' class='btn btn-primary shadow-none text-white' id='copy-button'>Copy</button>
  // const popoverBtn = document.querySelector(".clone-popover-btn")
frontend/main.js:40
Before
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  document.body.addEventListener('click', (event) => {
    const target = event.target
    // If they didn't click the #clone-popover-btn or if we're not inside of
    // popover, or if we *are* inside of a popover but a different one than the
    // current one, then close the popover.
    const parentPopover = target.closest(".popover")
    if (
      target.id !== "clone-popover-btn"
      && (
        parentPopover === null
        || parentPopover !== bsPopover.tip)
    ) {
      bsPopover.hide()
    }
  })
After
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  window.popovers.push(bsPopover)
frontend/main.js:99
Before
99
100
101
102
if (document.getElementById('clone-popover-btn')) {
  createClonePopover()
}
document.querySelector("#copy-button").addEventListener('click', copyCommand)
After
99
100
101
102
window.popovers ||= []
document.querySelectorAll('.clone-popover-btn').forEach((button) => {
  createClonePopover(button, button.dataset['copyText'])
})
document.querySelectorAll(".copy-button").forEach((button) => {
  button.addEventListener('click', copyCommand)
})
document.addEventListener('click', (event) => {
  const target = event.target
  // If they didn't click the .clone-popover-btn or if we're not inside of
  // popover, or if we *are* inside of a popover but a different one than the
  // current one, then close the popover.
  const parentPopover = target.closest(".popover")
  if (
    !target.classList.contains("clone-popover-btn")
    && parentPopover === null
  ) {
    window.popovers.forEach(popover => popover.hide())
  }
})
js_templates/commit.ts:13
Before
13
            <button data-copy-text='${data.patchInfo.commit.hash}' class="btn btn-info shadow-none" id="copy-button">Copy</button>
After
13
            <button data-copy-text='${data.patchInfo.commit.hash}' class="btn btn-info shadow-none copy-button">Copy</button>
js_templates/commit.ts:40
Before
40
            <span class="font-monospace fw-bold"><a href="${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${slugify(hunk.fileName)}.html">${hunk.fileName}:${hunk.lineNumber}</a></span>
After
40
            <span class="font-monospace fw-bold"><a href="${data.reposPath}/${slugify(data.patchInfo.repoName)}/branches/${slugify(data.patchInfo.branchName)}/files/${hunk.fileName.split('/').map((filePart) =&gt; slugify(filePart)).join('/')}&quot;>${hunk.fileName}:${hunk.lineNumber}</a></span>
js_templates/common/branchesListItems.ts:1
Before
1
    const currentBadge = currentBranch === branch.name ? '<div class="badge rounded-pill bg-primary mx-1">current</div>' : ''
After
1
    const currentBadge = currentBranch === branch.name ? '<div class="badge rounded-pill bg-secondary mx-1">current</div>' : ''
js_templates/common/htmlPage.ts:112
Before
112
                      <a class="nav-link ${data.navTab === 'home' ? 'active' : ''}" aria-current="page" href="${nav.repoCurrentBranchHome()}">ReadMe</a>
After
112
                      <a class="nav-link ${data.navTab === 'home' ? 'active' : ''}" aria-current="page" href="${nav.repoCurrentBranchHome()}">Home</a>
js_templates/file.ts:14
Before
14
          <span class="bezel-gray px-1"><a href="${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files">&#x1F3E0; ./</a></span>${
After
14
          <span class="bezel-gray px-1"><a href="${data.reposPath}/${data.fileInfo.repoName}/branches/${data.fileInfo.branchName}/files">./</a></span>${
js_templates/file.ts:71
Before
71
              return `<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/patches/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
After
71
              return `<a href="${data.reposPath}/${slugify(data.fileInfo.repoName)}/branches/${slugify(data.fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
js_templates/files.ts:11
Before
11
          <span>&#x1F3E0; ./</span>
After
11
          <span>./</span>
js_templates/index.ts:15
Before
15
16
17
18
                <h1>Tucker&#39;s Repositories</h1>
                    <div class="mx-2 card bezel-gray" style="width: 18rem;">
                        <h2 class="card-title fs-5">${repo.name}</h2>
                        <a href="${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}" class="btn btn-primary text-white">Go to ${repo.name}</a>
After
15
16
17
18
                <h1>${data.reposConfig.defaultTemplateConfiguration?.allRepositoriesPageTitle || &quot;All Repositories&quot;}&lt;/h1>
                    <div class="m-2 card bezel-gray flex-grow-1" style="flex-basis: 20rem;">
                      <div class="card-header">
                        <a class="card-title fs-5" href=&quot;${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}"&gt;${repo.name}</a>
                      </div>
                      </div>
                      <div class="card-footer">
                        <a href="${data.reposPath}/${slugify(repo.name)}/branches/${repo.defaultBranch}" class="mx-1 my-2 btn btn-primary text-white">Go to site</a>
                        <button class="mx-1 my-2 btn btn-outline-secondary shadow-none dropdown-toggle clone-popover-btn" data-copy-text="${repo.cloneUrl}">Clone</button>
                        ${(data.reposConfig.repos[repo.name].defaultTemplateConfiguration?.homepageButtons || []).map((button) => {
                          return `<a class="mx-1 my-2 btn btn-outline-secondary shadow-none" href="${button.url}&quot; ${button.newTab ? 'target="_blank"' : ''}>${button.text}${button.newTab ? ' &lt;span>&#x29C9;</span>' : ''}</a>`
                        }).join('')}
js_templates/index.ts:35
Before
35
After
35
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
        <script src="${data.reposPath}/frontend/main-frontend.bundle.js"></script>
js_templates/repo.ts:57
Before
57
                    <button class="btn btn-info btn-lg dropdown-toggle" id="clone-popover-btn">Clone</button>
After
57
                    <button class="btn btn-info btn-lg dropdown-toggle clone-popover-btn">Clone</button>
schemas/ReposConfiguration.json:142
Before
142
After
142
        "defaultTemplateConfiguration": {
          "additionalProperties": false,
          "properties": {
            "allRepositoriesPageTitle": {
              "type": "string"
            }
          },
          "type": "object"
        },
scss/design-board.scss:234
Before
234
235
236
237
238
239
240
.badge.bg-primary {
  background: linear-gradient(color.adjust($primary, $lightness: 10%), $primary);
  box-shadow: -1px -3px 4px inset color.adjust($primary, $lightness: -30%);
.badge.bg-info {
  background: linear-gradient(color.adjust($info, $lightness: 10%), $info);
  box-shadow: -1px -3px 4px inset color.adjust($info, $lightness: -30%);
}
After
234
235
236
237
238
239
240
@each $color, $value in $bezel-colors {
  .badge.bg-#{$color} {
    background: linear-gradient(color.adjust($value, $lightness: 10%), $value);
    box-shadow: -1px -3px 4px inset color.adjust($value, $lightness: -30%);
  }
// .badge.bg-primary {
//   background: linear-gradient(color.adjust($primary, $lightness: 10%), $primary);
//   box-shadow: -1px -3px 4px inset color.adjust($primary, $lightness: -30%);
// }
// 
// .badge.bg-info {
//   background: linear-gradient(color.adjust($info, $lightness: 10%), $info);
//   box-shadow: -1px -3px 4px inset color.adjust($info, $lightness: -30%);
// }
src/configTypes.ts:41
Before
41
After
41
  defaultTemplateConfiguration?: {
    allRepositoriesPageTitle?: string,
  },