@sienklogic/plan-build-run 2.26.2 → 2.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +29 -0
  3. package/dashboard/public/css/layout.css +7 -283
  4. package/dashboard/public/css/status-colors.css +7 -0
  5. package/dashboard/public/css/tokens.css +3 -3
  6. package/dashboard/public/js/sidebar-toggle.js +9 -31
  7. package/dashboard/public/js/theme-toggle.js +4 -4
  8. package/dashboard/src/views/partials/activity-feed.ejs +17 -9
  9. package/dashboard/src/views/partials/analytics-content.ejs +178 -88
  10. package/dashboard/src/views/partials/audit-detail-content.ejs +6 -4
  11. package/dashboard/src/views/partials/audits-content.ejs +28 -26
  12. package/dashboard/src/views/partials/breadcrumbs.ejs +8 -4
  13. package/dashboard/src/views/partials/config-content.ejs +98 -95
  14. package/dashboard/src/views/partials/dashboard-content.ejs +69 -60
  15. package/dashboard/src/views/partials/dependencies-content.ejs +5 -3
  16. package/dashboard/src/views/partials/empty-state.ejs +10 -5
  17. package/dashboard/src/views/partials/footer.ejs +8 -2
  18. package/dashboard/src/views/partials/head.ejs +2 -1
  19. package/dashboard/src/views/partials/header.ejs +16 -19
  20. package/dashboard/src/views/partials/layout-bottom.ejs +5 -40
  21. package/dashboard/src/views/partials/layout-top.ejs +6 -5
  22. package/dashboard/src/views/partials/logs-content.ejs +26 -29
  23. package/dashboard/src/views/partials/milestone-detail-content.ejs +5 -5
  24. package/dashboard/src/views/partials/milestones-content.ejs +40 -31
  25. package/dashboard/src/views/partials/note-detail-content.ejs +7 -5
  26. package/dashboard/src/views/partials/notes-content.ejs +4 -4
  27. package/dashboard/src/views/partials/phase-content.ejs +6 -8
  28. package/dashboard/src/views/partials/phase-doc-content.ejs +13 -15
  29. package/dashboard/src/views/partials/phase-timeline.ejs +22 -15
  30. package/dashboard/src/views/partials/phases-content.ejs +98 -84
  31. package/dashboard/src/views/partials/quick-content.ejs +34 -32
  32. package/dashboard/src/views/partials/quick-detail-content.ejs +20 -19
  33. package/dashboard/src/views/partials/requirements-content.ejs +6 -6
  34. package/dashboard/src/views/partials/research-content.ejs +14 -14
  35. package/dashboard/src/views/partials/research-detail-content.ejs +13 -11
  36. package/dashboard/src/views/partials/roadmap-content.ejs +145 -128
  37. package/dashboard/src/views/partials/sidebar.ejs +86 -140
  38. package/dashboard/src/views/partials/todo-create-content.ejs +51 -46
  39. package/dashboard/src/views/partials/todo-detail-content.ejs +26 -25
  40. package/dashboard/src/views/partials/todos-content.ejs +65 -62
  41. package/dashboard/src/views/partials/todos-done-content.ejs +33 -31
  42. package/package.json +1 -1
  43. package/plugins/copilot-pbr/plugin.json +1 -1
  44. package/plugins/copilot-pbr/skills/build/SKILL.md +12 -0
  45. package/plugins/copilot-pbr/skills/quick/SKILL.md +12 -0
  46. package/plugins/copilot-pbr/skills/review/SKILL.md +14 -0
  47. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
  48. package/plugins/cursor-pbr/README.md +20 -0
  49. package/plugins/cursor-pbr/skills/build/SKILL.md +12 -0
  50. package/plugins/cursor-pbr/skills/quick/SKILL.md +12 -0
  51. package/plugins/cursor-pbr/skills/review/SKILL.md +14 -0
  52. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  53. package/plugins/pbr/scripts/local-llm/metrics.js +121 -33
  54. package/plugins/pbr/skills/build/SKILL.md +12 -0
  55. package/plugins/pbr/skills/quick/SKILL.md +12 -0
  56. package/plugins/pbr/skills/review/SKILL.md +14 -0
@@ -2,33 +2,39 @@
2
2
  <h1>Project Roadmap</h1>
3
3
 
4
4
  <% if (phases.length === 0 && (typeof milestones === 'undefined' || milestones.length === 0)) { %>
5
- <article>
6
- <p>No phases found. Add a ROADMAP.md file to your .planning/ directory to see the roadmap here.</p>
7
- </article>
5
+ <div class="card mb-3">
6
+ <div class="card-body">
7
+ <p>No phases found. Add a ROADMAP.md file to your .planning/ directory to see the roadmap here.</p>
8
+ </div>
9
+ </div>
8
10
  <% } else if (phases.length === 0 && typeof milestones !== 'undefined' && milestones.length > 0) { %>
9
11
  <!-- All milestones completed — show summary -->
10
- <article>
11
- <header><strong>All Milestones Completed</strong></header>
12
- <p>All phases have been archived into milestones.</p>
13
- </article>
12
+ <div class="card mb-3">
13
+ <div class="card-header"><strong>All Milestones Completed</strong></div>
14
+ <div class="card-body">
15
+ <p>All phases have been archived into milestones.</p>
16
+ </div>
17
+ </div>
14
18
  <% milestones.forEach(function(ms) { %>
15
- <article>
16
- <header>
19
+ <div class="card mb-3">
20
+ <div class="card-header">
17
21
  <strong><%= ms.name %></strong>
18
22
  <% if (ms.startPhase && ms.endPhase) { %>
19
23
  <small>(Phases <%= String(ms.startPhase).padStart(2, '0') %>&ndash;<%= String(ms.endPhase).padStart(2, '0') %>)</small>
20
24
  <% } %>
21
25
  &mdash;
22
26
  <span class="status-badge" data-status="complete">complete</span>
23
- </header>
24
- <% if (ms.goal && ms.goal !== 'Completed') { %>
25
- <p><small><%= ms.goal %></small></p>
26
- <% } %>
27
- <p><a href="/milestones"
28
- hx-get="/milestones"
29
- hx-target="#main-content"
30
- hx-push-url="true">View in Milestones</a></p>
31
- </article>
27
+ </div>
28
+ <div class="card-body">
29
+ <% if (ms.goal && ms.goal !== 'Completed') { %>
30
+ <p><small><%= ms.goal %></small></p>
31
+ <% } %>
32
+ <p><a href="/milestones"
33
+ hx-get="/milestones"
34
+ hx-target="#main-content"
35
+ hx-push-url="true">View in Milestones</a></p>
36
+ </div>
37
+ </div>
32
38
  <% }); %>
33
39
  <% } else { %>
34
40
 
@@ -46,20 +52,27 @@
46
52
  %>
47
53
 
48
54
  <!-- Overall Progress -->
49
- <article>
50
- <header><strong>Overall Progress</strong></header>
51
- <%
52
- const totalComplete = phases.filter(p => p.status === 'complete').length;
53
- const totalPhases = phases.length;
54
- const pct = totalPhases > 0 ? Math.round((totalComplete / totalPhases) * 100) : 0;
55
- %>
56
- <progress value="<%= totalComplete %>" max="<%= totalPhases %>"></progress>
57
- <p><%= pct %>% complete (<%= totalComplete %> of <%= totalPhases %> phases)</p>
58
- </article>
55
+ <div class="card mb-3">
56
+ <div class="card-header"><strong>Overall Progress</strong></div>
57
+ <div class="card-body">
58
+ <%
59
+ const totalComplete = phases.filter(p => p.status === 'complete').length;
60
+ const totalPhases = phases.length;
61
+ const pct = totalPhases > 0 ? Math.round((totalComplete / totalPhases) * 100) : 0;
62
+ %>
63
+ <div class="progress mb-2" style="height:0.5rem">
64
+ <div class="progress-bar" role="progressbar"
65
+ style="width:<%= pct %>%"
66
+ aria-valuenow="<%= totalComplete %>" aria-valuemin="0" aria-valuemax="<%= totalPhases %>">
67
+ </div>
68
+ </div>
69
+ <p><%= pct %>% complete (<%= totalComplete %> of <%= totalPhases %> phases)</p>
70
+ </div>
71
+ </div>
59
72
 
60
73
  <% msGroups.forEach(function(group) { %>
61
- <article>
62
- <header>
74
+ <div class="card mb-3">
75
+ <div class="card-header">
63
76
  <strong><%= group.name %></strong>
64
77
  <% if (group.startPhase && group.endPhase < 9999) { %>
65
78
  <small>(Phases <%= String(group.startPhase).padStart(2, '0') %>&ndash;<%= String(group.endPhase).padStart(2, '0') %>)</small>
@@ -72,109 +85,113 @@
72
85
  <span class="status-badge" data-status="<%= gc === gt ? 'complete' : (gc > 0 ? 'in-progress' : 'not-started') %>">
73
86
  <%= gc %>/<%= gt %>
74
87
  </span>
75
- </header>
76
- <% if (group.goal) { %>
77
- <p><small><%= group.goal %></small></p>
78
- <% } %>
79
- <div class="table-wrap">
80
- <table>
81
- <thead>
82
- <tr>
83
- <th scope="col">Phase</th>
84
- <th scope="col">Name</th>
85
- <th scope="col">Plans</th>
86
- <th scope="col">Status</th>
87
- <th scope="col">Depends On</th>
88
- </tr>
89
- </thead>
90
- <tbody>
91
- <% group.phases.forEach(function(phase) { %>
92
- <tr>
93
- <td><%= String(phase.id).padStart(2, '0') %></td>
94
- <td>
95
- <a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
96
- hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
97
- hx-target="#main-content"
98
- hx-push-url="true">
99
- <%= phase.name %>
100
- </a>
101
- </td>
102
- <td><%= phase.planCount %></td>
103
- <td>
104
- <span class="status-badge" data-status="<%= phase.status %>">
105
- <%= phase.status.replace('-', ' ') %>
106
- </span>
107
- </td>
108
- <td>
109
- <% if (phase.dependencies && phase.dependencies.length > 0) { %>
110
- <% phase.dependencies.forEach(function(dep, idx) { %>
111
- <a href="/phases/<%= String(dep).padStart(2, '0') %>"
112
- hx-get="/phases/<%= String(dep).padStart(2, '0') %>"
113
- hx-target="#main-content"
114
- hx-push-url="true"><%= String(dep).padStart(2, '0') %></a><% if (idx < phase.dependencies.length - 1) { %>, <% } %>
115
- <% }); %>
116
- <% } else { %>
117
- <small>None</small>
118
- <% } %>
119
- </td>
120
- </tr>
121
- <% }); %>
122
- </tbody>
123
- </table>
124
88
  </div>
125
- </article>
89
+ <div class="card-body">
90
+ <% if (group.goal) { %>
91
+ <p><small><%= group.goal %></small></p>
92
+ <% } %>
93
+ <div class="table-responsive">
94
+ <table class="table table-vcenter">
95
+ <thead>
96
+ <tr>
97
+ <th scope="col">Phase</th>
98
+ <th scope="col">Name</th>
99
+ <th scope="col">Plans</th>
100
+ <th scope="col">Status</th>
101
+ <th scope="col">Depends On</th>
102
+ </tr>
103
+ </thead>
104
+ <tbody>
105
+ <% group.phases.forEach(function(phase) { %>
106
+ <tr>
107
+ <td><%= String(phase.id).padStart(2, '0') %></td>
108
+ <td>
109
+ <a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
110
+ hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
111
+ hx-target="#main-content"
112
+ hx-push-url="true">
113
+ <%= phase.name %>
114
+ </a>
115
+ </td>
116
+ <td><%= phase.planCount %></td>
117
+ <td>
118
+ <span class="status-badge" data-status="<%= phase.status %>">
119
+ <%= phase.status.replace('-', ' ') %>
120
+ </span>
121
+ </td>
122
+ <td>
123
+ <% if (phase.dependencies && phase.dependencies.length > 0) { %>
124
+ <% phase.dependencies.forEach(function(dep, idx) { %>
125
+ <a href="/phases/<%= String(dep).padStart(2, '0') %>"
126
+ hx-get="/phases/<%= String(dep).padStart(2, '0') %>"
127
+ hx-target="#main-content"
128
+ hx-push-url="true"><%= String(dep).padStart(2, '0') %></a><% if (idx < phase.dependencies.length - 1) { %>, <% } %>
129
+ <% }); %>
130
+ <% } else { %>
131
+ <small>None</small>
132
+ <% } %>
133
+ </td>
134
+ </tr>
135
+ <% }); %>
136
+ </tbody>
137
+ </table>
138
+ </div>
139
+ </div>
140
+ </div>
126
141
  <% }); %>
127
142
 
128
143
  <% if (ungroupedPhases.length > 0) { %>
129
- <article>
130
- <header><strong>Other Phases</strong></header>
131
- <div class="table-wrap">
132
- <table>
133
- <thead>
134
- <tr>
135
- <th scope="col">Phase</th>
136
- <th scope="col">Name</th>
137
- <th scope="col">Plans</th>
138
- <th scope="col">Status</th>
139
- <th scope="col">Depends On</th>
140
- </tr>
141
- </thead>
142
- <tbody>
143
- <% ungroupedPhases.forEach(function(phase) { %>
144
- <tr>
145
- <td><%= String(phase.id).padStart(2, '0') %></td>
146
- <td>
147
- <a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
148
- hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
149
- hx-target="#main-content"
150
- hx-push-url="true">
151
- <%= phase.name %>
152
- </a>
153
- </td>
154
- <td><%= phase.planCount %></td>
155
- <td>
156
- <span class="status-badge" data-status="<%= phase.status %>">
157
- <%= phase.status.replace('-', ' ') %>
158
- </span>
159
- </td>
160
- <td>
161
- <% if (phase.dependencies && phase.dependencies.length > 0) { %>
162
- <% phase.dependencies.forEach(function(dep, idx) { %>
163
- <a href="/phases/<%= String(dep).padStart(2, '0') %>"
164
- hx-get="/phases/<%= String(dep).padStart(2, '0') %>"
165
- hx-target="#main-content"
166
- hx-push-url="true"><%= String(dep).padStart(2, '0') %></a><% if (idx < phase.dependencies.length - 1) { %>, <% } %>
167
- <% }); %>
168
- <% } else { %>
169
- <small>None</small>
170
- <% } %>
171
- </td>
172
- </tr>
173
- <% }); %>
174
- </tbody>
175
- </table>
144
+ <div class="card mb-3">
145
+ <div class="card-header"><strong>Other Phases</strong></div>
146
+ <div class="card-body">
147
+ <div class="table-responsive">
148
+ <table class="table table-vcenter">
149
+ <thead>
150
+ <tr>
151
+ <th scope="col">Phase</th>
152
+ <th scope="col">Name</th>
153
+ <th scope="col">Plans</th>
154
+ <th scope="col">Status</th>
155
+ <th scope="col">Depends On</th>
156
+ </tr>
157
+ </thead>
158
+ <tbody>
159
+ <% ungroupedPhases.forEach(function(phase) { %>
160
+ <tr>
161
+ <td><%= String(phase.id).padStart(2, '0') %></td>
162
+ <td>
163
+ <a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
164
+ hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
165
+ hx-target="#main-content"
166
+ hx-push-url="true">
167
+ <%= phase.name %>
168
+ </a>
169
+ </td>
170
+ <td><%= phase.planCount %></td>
171
+ <td>
172
+ <span class="status-badge" data-status="<%= phase.status %>">
173
+ <%= phase.status.replace('-', ' ') %>
174
+ </span>
175
+ </td>
176
+ <td>
177
+ <% if (phase.dependencies && phase.dependencies.length > 0) { %>
178
+ <% phase.dependencies.forEach(function(dep, idx) { %>
179
+ <a href="/phases/<%= String(dep).padStart(2, '0') %>"
180
+ hx-get="/phases/<%= String(dep).padStart(2, '0') %>"
181
+ hx-target="#main-content"
182
+ hx-push-url="true"><%= String(dep).padStart(2, '0') %></a><% if (idx < phase.dependencies.length - 1) { %>, <% } %>
183
+ <% }); %>
184
+ <% } else { %>
185
+ <small>None</small>
186
+ <% } %>
187
+ </td>
188
+ </tr>
189
+ <% }); %>
190
+ </tbody>
191
+ </table>
192
+ </div>
176
193
  </div>
177
- </article>
194
+ </div>
178
195
  <% } %>
179
196
 
180
197
  <% } %>
@@ -1,152 +1,98 @@
1
- <aside class="sidebar">
2
- <% if (typeof currentPhase !== 'undefined' && currentPhase) { %>
3
- <div class="sidebar-current-phase">
4
- <small>Current Phase</small>
5
- <a href="/phases/<%= currentPhase.number %>"
6
- hx-get="/phases/<%= currentPhase.number %>"
7
- hx-target="#main-content"
8
- hx-push-url="true">
9
- <strong>Phase <%= currentPhase.number %></strong>
10
- <span><%= currentPhase.name %></span>
11
- <span class="phase-status"><%= currentPhase.status %></span>
12
- </a>
13
- </div>
14
- <% } %>
15
-
16
- <% if (typeof currentPhase !== 'undefined' && currentPhase && currentPhase.nextAction) { %>
17
- <div class="sidebar-next-action">
18
- <small>Suggested next</small>
19
- <code class="sidebar-next-action__cmd"><%= currentPhase.nextAction %></code>
20
- </div>
21
- <% } %>
22
-
23
- <nav aria-label="Main navigation">
24
- <details open>
25
- <summary>Project</summary>
26
- <ul>
27
- <li>
28
- <a href="/"
29
- hx-get="/"
30
- hx-target="#main-content"
31
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'dashboard' ? ' aria-current="page"' : '' %>>
32
- Dashboard
33
- </a>
34
- </li>
35
- <li>
36
- <a href="/roadmap"
37
- hx-get="/roadmap"
38
- hx-target="#main-content"
39
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'roadmap' ? ' aria-current="page"' : '' %>>
40
- Roadmap
41
- </a>
42
- </li>
43
- <li>
44
- <a href="/phases"
45
- hx-get="/phases"
46
- hx-target="#main-content"
47
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'phases' ? ' aria-current="page"' : '' %>>
48
- Phases
49
- </a>
50
- </li>
51
- <li>
52
- <a href="/dependencies"
53
- hx-get="/dependencies"
54
- hx-target="#main-content"
55
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'dependencies' ? ' aria-current="page"' : '' %>>
56
- Dependencies
57
- </a>
58
- </li>
59
- </ul>
60
- </details>
61
-
62
- <details open>
63
- <summary>Planning</summary>
64
- <ul>
65
- <li>
66
- <a href="/config"
67
- hx-get="/config"
68
- hx-target="#main-content"
69
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'config' ? ' aria-current="page"' : '' %>>
70
- Config
1
+ <aside class="navbar navbar-vertical navbar-expand-md" id="sidebar">
2
+ <div class="container-fluid">
3
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu">
4
+ <span class="navbar-toggler-icon"></span>
5
+ </button>
6
+ <div class="collapse navbar-collapse" id="sidebar-menu">
7
+ <% if (typeof currentPhase !== 'undefined' && currentPhase) { %>
8
+ <div class="navbar-brand mb-2">
9
+ <div class="small text-muted text-uppercase fw-bold" style="font-size:0.65rem;letter-spacing:.06em;">Current Phase</div>
10
+ <a href="/phases/<%= currentPhase.number %>"
11
+ hx-get="/phases/<%= currentPhase.number %>"
12
+ hx-target="#main-content"
13
+ hx-push-url="true"
14
+ class="d-block text-decoration-none mt-1">
15
+ <strong>Phase <%= currentPhase.number %></strong>
16
+ <span class="d-block text-muted small"><%= currentPhase.name %></span>
17
+ <span class="d-block small text-primary"><%= currentPhase.status %></span>
18
+ </a>
19
+ </div>
20
+ <% } %>
21
+ <% if (typeof currentPhase !== 'undefined' && currentPhase && currentPhase.nextAction) { %>
22
+ <div class="navbar-brand mb-2 border-top pt-2">
23
+ <div class="small text-muted text-uppercase fw-bold" style="font-size:0.65rem;letter-spacing:.06em;">Suggested next</div>
24
+ <code class="small d-block text-truncate mt-1"><%= currentPhase.nextAction %></code>
25
+ </div>
26
+ <% } %>
27
+ <ul class="navbar-nav pt-lg-3">
28
+ <%# Project section %>
29
+ <li class="nav-item dropdown">
30
+ <a href="#navbar-project" class="nav-link dropdown-toggle" data-bs-toggle="collapse" role="button" aria-expanded="true">
31
+ <span class="nav-link-title">Project</span>
71
32
  </a>
33
+ <div class="dropdown-menu show" id="navbar-project">
34
+ <div class="dropdown-menu-columns">
35
+ <div class="dropdown-menu-column">
36
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'dashboard' ? ' active' : '' %>" href="/" hx-get="/" hx-target="#main-content" hx-push-url="true">Dashboard</a>
37
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'roadmap' ? ' active' : '' %>" href="/roadmap" hx-get="/roadmap" hx-target="#main-content" hx-push-url="true">Roadmap</a>
38
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'phases' ? ' active' : '' %>" href="/phases" hx-get="/phases" hx-target="#main-content" hx-push-url="true">Phases</a>
39
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'dependencies' ? ' active' : '' %>" href="/dependencies" hx-get="/dependencies" hx-target="#main-content" hx-push-url="true">Dependencies</a>
40
+ </div>
41
+ </div>
42
+ </div>
72
43
  </li>
73
- <li>
74
- <a href="/research"
75
- hx-get="/research"
76
- hx-target="#main-content"
77
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'research' ? ' aria-current="page"' : '' %>>
78
- Research
44
+ <%# Planning section %>
45
+ <li class="nav-item dropdown">
46
+ <a href="#navbar-planning" class="nav-link dropdown-toggle" data-bs-toggle="collapse" role="button" aria-expanded="true">
47
+ <span class="nav-link-title">Planning</span>
79
48
  </a>
49
+ <div class="dropdown-menu show" id="navbar-planning">
50
+ <div class="dropdown-menu-columns">
51
+ <div class="dropdown-menu-column">
52
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'config' ? ' active' : '' %>" href="/config" hx-get="/config" hx-target="#main-content" hx-push-url="true">Config</a>
53
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'research' ? ' active' : '' %>" href="/research" hx-get="/research" hx-target="#main-content" hx-push-url="true">Research</a>
54
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'requirements' ? ' active' : '' %>" href="/requirements" hx-get="/requirements" hx-target="#main-content" hx-push-url="true">Requirements</a>
55
+ </div>
56
+ </div>
57
+ </div>
80
58
  </li>
81
- <li>
82
- <a href="/requirements"
83
- hx-get="/requirements"
84
- hx-target="#main-content"
85
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'requirements' ? ' aria-current="page"' : '' %>>
86
- Requirements
59
+ <%# Work section %>
60
+ <li class="nav-item dropdown">
61
+ <a href="#navbar-work" class="nav-link dropdown-toggle" data-bs-toggle="collapse" role="button" aria-expanded="true">
62
+ <span class="nav-link-title">Work</span>
87
63
  </a>
64
+ <div class="dropdown-menu show" id="navbar-work">
65
+ <div class="dropdown-menu-columns">
66
+ <div class="dropdown-menu-column">
67
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'todos' ? ' active' : '' %>" href="/todos" hx-get="/todos" hx-target="#main-content" hx-push-url="true">Todos</a>
68
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'quick' ? ' active' : '' %>" href="/quick" hx-get="/quick" hx-target="#main-content" hx-push-url="true">Quick Tasks</a>
69
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'notes' ? ' active' : '' %>" href="/notes" hx-get="/notes" hx-target="#main-content" hx-push-url="true">Notes</a>
70
+ </div>
71
+ </div>
72
+ </div>
88
73
  </li>
89
- </ul>
90
- </details>
91
-
92
- <details open>
93
- <summary>Work</summary>
94
- <ul>
95
- <li>
96
- <a href="/todos"
97
- hx-get="/todos"
98
- hx-target="#main-content"
99
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'todos' ? ' aria-current="page"' : '' %>>
100
- Todos
101
- </a>
102
- </li>
103
- <li>
104
- <a href="/quick"
105
- hx-get="/quick"
106
- hx-target="#main-content"
107
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'quick' ? ' aria-current="page"' : '' %>>
108
- Quick Tasks
74
+ <%# History section %>
75
+ <li class="nav-item dropdown">
76
+ <a href="#navbar-history" class="nav-link dropdown-toggle" data-bs-toggle="collapse" role="button" aria-expanded="false">
77
+ <span class="nav-link-title">History</span>
109
78
  </a>
79
+ <div class="dropdown-menu" id="navbar-history">
80
+ <div class="dropdown-menu-columns">
81
+ <div class="dropdown-menu-column">
82
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'milestones' ? ' active' : '' %>" href="/milestones" hx-get="/milestones" hx-target="#main-content" hx-push-url="true">Milestones</a>
83
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'analytics' ? ' active' : '' %>" href="/analytics" hx-get="/analytics" hx-target="#main-content" hx-push-url="true">Analytics</a>
84
+ <a class="dropdown-item<%= typeof activePage !== 'undefined' && activePage === 'audits' ? ' active' : '' %>" href="/audits" hx-get="/audits" hx-target="#main-content" hx-push-url="true">Audit Reports</a>
85
+ </div>
86
+ </div>
87
+ </div>
110
88
  </li>
111
- <li>
112
- <a href="/notes"
113
- hx-get="/notes"
114
- hx-target="#main-content"
115
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'notes' ? ' aria-current="page"' : '' %>>
116
- Notes
89
+ <%# Logs %>
90
+ <li class="nav-item">
91
+ <a class="nav-link<%= typeof activePage !== 'undefined' && activePage === 'logs' ? ' active' : '' %>" href="/logs" hx-get="/logs" hx-target="#main-content" hx-push-url="true">
92
+ <span class="nav-link-title">Logs</span>
117
93
  </a>
118
94
  </li>
119
95
  </ul>
120
- </details>
121
-
122
- <details>
123
- <summary>History</summary>
124
- <ul>
125
- <li>
126
- <a href="/milestones"
127
- hx-get="/milestones"
128
- hx-target="#main-content"
129
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'milestones' ? ' aria-current="page"' : '' %>>
130
- Milestones
131
- </a>
132
- </li>
133
- <li>
134
- <a href="/analytics"
135
- hx-get="/analytics"
136
- hx-target="#main-content"
137
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'analytics' ? ' aria-current="page"' : '' %>>
138
- Analytics
139
- </a>
140
- </li>
141
- <li>
142
- <a href="/audits"
143
- hx-get="/audits"
144
- hx-target="#main-content"
145
- hx-push-url="true"<%= typeof activePage !== 'undefined' && activePage === 'audits' ? ' aria-current="page"' : '' %>>
146
- Audit Reports
147
- </a>
148
- </li>
149
- </ul>
150
- </details>
151
- </nav>
96
+ </div>
97
+ </div>
152
98
  </aside>