|
| 1 | +<script> |
| 2 | + /** |
| 3 | + * @type {any[]} |
| 4 | + */ |
| 5 | + export let tasks; |
| 6 | +
|
| 7 | + /** |
| 8 | + * @param {number} index |
| 9 | + */ |
| 10 | + function isOldVersion(index) { |
| 11 | + if (index === 0) { |
| 12 | + return false; |
| 13 | + } |
| 14 | + const currentTask = tasks[index]; |
| 15 | + const previousTask = tasks[index - 1]; |
| 16 | + return previousTask.name === currentTask.name && previousTask.owner === currentTask.owner; |
| 17 | + } |
| 18 | +
|
| 19 | + /** |
| 20 | + * @param {number} index |
| 21 | + */ |
| 22 | + function isLastOldVersion(index) { |
| 23 | + if (!isOldVersion(index)) { |
| 24 | + return false; |
| 25 | + } |
| 26 | + if (index === tasks.length - 1) { |
| 27 | + return false; |
| 28 | + } |
| 29 | + const currentTask = tasks[index]; |
| 30 | + const nextTask = tasks[index + 1]; |
| 31 | + return nextTask.name !== currentTask.name || nextTask.owner !== currentTask.owner; |
| 32 | + } |
| 33 | +
|
| 34 | + /** |
| 35 | + * @param {number} index |
| 36 | + */ |
| 37 | + function isMainVersion(index) { |
| 38 | + if (isOldVersion(index)) { |
| 39 | + return false; |
| 40 | + } |
| 41 | + if (index === tasks.length - 1) { |
| 42 | + return false; |
| 43 | + } |
| 44 | + const currentTask = tasks[index]; |
| 45 | + const nextTask = tasks[index + 1]; |
| 46 | + return nextTask.name === currentTask.name && nextTask.owner === currentTask.owner; |
| 47 | + } |
| 48 | +
|
| 49 | + /** |
| 50 | + * @param {Event} event |
| 51 | + */ |
| 52 | + function handleToggleOldVersions(event) { |
| 53 | + const element = /** @type {HTMLElement} */ (event.target); |
| 54 | + /** @type {HTMLElement|null} */ |
| 55 | + let row = /** @type {HTMLElement} */ (element.closest('tr')); |
| 56 | + if (!row.classList.contains('expanded')) { |
| 57 | + closeAllOldVersions(/** @type {HTMLElement} */ (row.closest('table'))); |
| 58 | + } |
| 59 | + toggleOldVersions(row); |
| 60 | + } |
| 61 | +
|
| 62 | + /** |
| 63 | + * @param {HTMLElement} table |
| 64 | + */ |
| 65 | + function closeAllOldVersions(table) { |
| 66 | + const rows = table.querySelectorAll('tr'); |
| 67 | + for (const row of rows) { |
| 68 | + if (row.classList.contains('expanded')) { |
| 69 | + toggleOldVersions(row); |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | +
|
| 74 | + /** |
| 75 | + * @param {HTMLElement} mainRow |
| 76 | + */ |
| 77 | + function toggleOldVersions(mainRow) { |
| 78 | + mainRow.classList.toggle('expanded'); |
| 79 | + /** @type {HTMLElement|null} */ |
| 80 | + let row = mainRow; |
| 81 | + while ((row = /** @type {HTMLElement|null} */ (row?.nextSibling))) { |
| 82 | + if (!row.classList) { |
| 83 | + continue; |
| 84 | + } |
| 85 | + if (row.classList.contains('old-version')) { |
| 86 | + row.classList.toggle('collapsed'); |
| 87 | + } else { |
| 88 | + break; |
| 89 | + } |
| 90 | + } |
| 91 | + } |
| 92 | +</script> |
| 93 | +
|
| 94 | +<table class="table align-middle"> |
| 95 | + <slot name="thead" /> |
| 96 | + <tbody> |
| 97 | + {#key tasks} |
| 98 | + {#each tasks as task, i} |
| 99 | + <tr |
| 100 | + class:old-version={isOldVersion(i)} |
| 101 | + class:last-old-version={isLastOldVersion(i)} |
| 102 | + class:is-main-version={isMainVersion(i)} |
| 103 | + class:collapsed={isOldVersion(i)} |
| 104 | + > |
| 105 | + <slot name="custom-columns-left" {task} /> |
| 106 | + <td>{isOldVersion(i) ? '' : task.name}</td> |
| 107 | + <td> |
| 108 | + {task.version || '–'} |
| 109 | + {#if isMainVersion(i)} |
| 110 | + <button class="btn btn-link" on:click={handleToggleOldVersions} aria-label="Expand old versions"> |
| 111 | + <i class="bi bi-plus-circle" /> |
| 112 | + </button> |
| 113 | + {/if} |
| 114 | + </td> |
| 115 | + <slot name="custom-columns-right" {task} /> |
| 116 | + </tr> |
| 117 | + {/each} |
| 118 | + {/key} |
| 119 | + </tbody> |
| 120 | +</table> |
| 121 | +
|
| 122 | +<style> |
| 123 | + :global(.is-main-version.expanded td) { |
| 124 | + border-bottom-style: dashed; |
| 125 | + } |
| 126 | +
|
| 127 | + :global(.old-version.collapsed) { |
| 128 | + display: none; |
| 129 | + } |
| 130 | +
|
| 131 | + :global(.old-version) { |
| 132 | + display: table-row; |
| 133 | + } |
| 134 | +
|
| 135 | + :global(.old-version td) { |
| 136 | + border-bottom-style: dashed; |
| 137 | + } |
| 138 | +
|
| 139 | + :global(.last-old-version td) { |
| 140 | + border-bottom-style: solid; |
| 141 | + } |
| 142 | +</style> |
0 commit comments