Skip to content

Commit 4823c41

Browse files
Maffoochclaude
andcommitted
Add UI toggle for classic Bootstrap fallback and align form field widths
Adds a per-user UI preference (UserContactInfo.ui_use_tailwind) so users can opt into the redesigned Tailwind UI while the legacy Bootstrap templates continue to render via a parallel `templates_classic/` tree (loaded by `dojo/template_loaders.py`). Includes the migration, classic copies of dojo.css/index.js/metrics.js, and a context-processor banner inviting non-opted-in users to enable the new UI ahead of it becoming the default on September 8th in the 2.62.0 release. Also makes form widgets uniform width across the New/Edit pages for Product Type, Product, Engagement, Test, Finding, Risk Acceptance, and Finding Group: removes the legacy `width: 70% !important` boilerplate duplicated across ~38 form templates and adds a single rule in dojo.css that sizes EasyMDE, Select2 (incl. Tagulous tag inputs) and Chosen widgets to fill their `.form-group` column at every viewport. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 196da76 commit 4823c41

393 files changed

Lines changed: 42002 additions & 637 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components/package.json

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,44 @@
55
"private": true,
66
"dependencies": {
77
"@fontsource-variable/work-sans": "^5.1",
8-
"chart.js": "^4.4",
9-
"chartjs-adapter-moment": "^1.0",
8+
"JUMFlot": "jumjum123/JUMFlot#*",
109
"alpinejs": "^3.14",
10+
"bootstrap": "^3.4.1",
11+
"bootstrap-select": "^1.13.18",
12+
"bootstrap-social": "^4.0.0",
1113
"bootstrap-wysiwyg": "^2.0.0",
14+
"chart.js": "^4.4",
15+
"chartjs-adapter-moment": "^1.0",
1216
"chosen-bootstrap": "https://github.com/dbtek/chosen-bootstrap",
1317
"chosen-js": "^1.8.7",
1418
"clipboard": "^2.0.11",
15-
"htmx.org": "^2.0",
1619
"datatables.net": "^2.3.7",
20+
"datatables.net-bs": "^2.3.7",
1721
"datatables.net-buttons": "^3.2.0",
1822
"datatables.net-buttons-bs": "^3.2.6",
1923
"datatables.net-colreorder": "^2.1.2",
24+
"drmonty-datatables-plugins": "^1.0.0",
25+
"drmonty-datatables-responsive": "^1.0.0",
2026
"easymde": "^2.20.0",
2127
"flatpickr": "^4.6",
28+
"flot": "flot/flot#~0.8.3",
29+
"font-awesome": "^4.0.0",
2230
"fullcalendar": "^3.10.2",
31+
"google-code-prettify": "^1.0.0",
32+
"htmx.org": "^2.0",
2333
"jquery": "^3.7.1",
34+
"jquery-highlight": "3.5.0",
2435
"jquery-ui": "1.14.2",
36+
"jquery.cookie": "1.4.1",
37+
"jquery.flot.tooltip": "^0.9.0",
2538
"jquery.hotkeys": "jeresig/jquery.hotkeys#master",
2639
"jszip": "^3.10.1",
40+
"justgage": "^1.7.0",
41+
"metismenu": "~3.0.7",
2742
"moment": "^2.30.1",
28-
"pdfmake": "^0.3.7"
43+
"morris.js": "morrisjs/morris.js",
44+
"pdfmake": "^0.3.7",
45+
"startbootstrap-sb-admin-2": "1.0.7"
2946
},
3047
"devDependencies": {
3148
"@tailwindcss/cli": "^4.1",

components/tailwind.css

Lines changed: 94 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -214,16 +214,48 @@
214214
@apply text-lg text-text-muted font-light;
215215
}
216216

217+
/* ---- Inline code & code blocks ----
218+
Inline <code>: pink/red on a tinted background like GitHub-flavored
219+
markdown. Block <pre>: light gray surface, padded, with horizontal
220+
scroll inside the box so long single-line commands (e.g. curl) do
221+
NOT overflow the page wrapper and push content under the sidebar. */
222+
code {
223+
@apply px-1.5 py-0.5 rounded bg-red-50 text-red-600 text-[0.85em];
224+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco,
225+
Consolas, "Liberation Mono", "Courier New", monospace;
226+
}
227+
pre {
228+
@apply block bg-surface-3 border border-border rounded-md
229+
px-4 py-3 my-3 text-sm leading-relaxed overflow-x-auto;
230+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco,
231+
Consolas, "Liberation Mono", "Courier New", monospace;
232+
/* `<pre>` inside should stay raw; clear the inline-code styling so
233+
a <code> nested inside a <pre> doesn't get the pink background. */
234+
}
235+
pre code {
236+
@apply p-0 bg-transparent text-inherit text-sm;
237+
}
238+
217239
/* ---- Tables ---- */
218240
.table {
219241
@apply w-full text-sm text-left border-collapse;
220242
}
221243
.table th {
244+
/* Title-case headers (no uppercase / letter-spacing) keep column widths
245+
compact so wide tables fit in the viewport — matches the classic UI's
246+
responsive flow at common laptop widths. */
222247
@apply px-3 py-2.5 bg-surface-2 font-semibold text-text-muted border-b-2 border-border
223-
text-left text-xs uppercase tracking-wide sticky top-0 z-10;
248+
text-left text-xs sticky top-0 z-10;
224249
}
225250
.table td {
226251
@apply px-3 py-2.5 border-b border-border/50;
252+
/* Allow long values (e.g. URLs, finding titles) to wrap inside their
253+
cell so columns can shrink with the viewport instead of forcing the
254+
table to overflow horizontally. Use `break-word` (not `anywhere`)
255+
so the browser only breaks inside a word when that word is too long
256+
to fit on its own line — preventing mid-word splits when normal
257+
space-wrap opportunities are available. */
258+
overflow-wrap: break-word;
227259
}
228260
.table tbody tr {
229261
@apply transition-colors duration-100;
@@ -238,7 +270,27 @@
238270
@apply px-2 py-1;
239271
}
240272
.table-responsive {
241-
@apply overflow-x-auto;
273+
/* `overflow-x: scroll` keeps the horizontal scrollbar slot reserved at
274+
all times so users on macOS / iOS — where overlay scrollbars hide
275+
until interaction — can see the scroll affordance for wide tables.
276+
Combined with thin webkit styling to keep it unobtrusive. */
277+
overflow-x: scroll;
278+
scrollbar-width: thin;
279+
scrollbar-color: rgb(203 213 225) transparent;
280+
}
281+
.table-responsive::-webkit-scrollbar {
282+
height: 10px;
283+
width: 10px;
284+
}
285+
.table-responsive::-webkit-scrollbar-track {
286+
background: transparent;
287+
}
288+
.table-responsive::-webkit-scrollbar-thumb {
289+
background: rgb(203 213 225);
290+
border-radius: 6px;
291+
}
292+
.table-responsive::-webkit-scrollbar-thumb:hover {
293+
background: rgb(148 163 184);
242294
}
243295
/* Sort indicators for tablesorter-bootstrap (non-DataTables tables) */
244296
.tablesorter-bootstrap thead th {
@@ -275,15 +327,16 @@
275327
font-size: 0.65rem;
276328
}
277329
}
278-
@media (max-width: 768px) {
279-
.table-responsive {
280-
background:
281-
linear-gradient(to right, white 30%, rgba(255,255,255,0)) left,
282-
linear-gradient(to left, white 30%, rgba(255,255,255,0)) right;
283-
background-size: 40px 100%;
284-
background-repeat: no-repeat;
285-
background-attachment: local, local;
286-
}
330+
/* Visual fade hint at the right edge so users always see that there is
331+
more content to scroll, regardless of viewport width or whether the
332+
OS is rendering an overlay scrollbar. */
333+
.table-responsive {
334+
background:
335+
linear-gradient(to right, white 30%, rgba(255,255,255,0)) left,
336+
linear-gradient(to left, white 30%, rgba(255,255,255,0)) right;
337+
background-size: 40px 100%;
338+
background-repeat: no-repeat;
339+
background-attachment: local, local;
287340
}
288341

289342
/* ---- Forms ---- */
@@ -513,6 +566,16 @@
513566
.nav-tabs::-webkit-scrollbar {
514567
display: none;
515568
}
569+
/* The horizontal-bar variant (product / engagement / test tab strips)
570+
hosts dropdown menus inside its tab items. Per CSS spec a single
571+
overflow-x: auto forces overflow-y to clip too, which would hide the
572+
dropdown menus that pop down below the bar. Switch to flex-wrap so
573+
tabs wrap onto a second row on narrow viewports while dropdowns can
574+
still escape the tab strip vertically. */
575+
.nav-tabs.horizontal-bar {
576+
@apply flex-wrap;
577+
overflow: visible;
578+
}
516579
.nav-tabs > li {
517580
@apply -mb-px flex-shrink-0;
518581
}
@@ -801,7 +864,10 @@
801864
@apply text-3xl font-bold text-text leading-none;
802865
}
803866
.stat-card .stat-card-label {
804-
@apply text-sm text-text-muted mt-1 truncate;
867+
/* Allow long labels (e.g. "Risk Accepted In Last Seven Days") to wrap
868+
inside the card instead of truncating with an ellipsis — matches the
869+
classic UI's behavior at 1200-1400 widths. */
870+
@apply text-sm text-text-muted mt-1 leading-tight;
805871
}
806872
.stat-card .stat-card-link {
807873
@apply flex items-center justify-between px-5 py-2.5 text-sm
@@ -1069,6 +1135,10 @@
10691135
font-size: 0.75rem;
10701136
line-height: 1.4;
10711137
border-radius: 4px;
1138+
/* width: max-content lets the popover expand beyond its tiny icon parent
1139+
(which is `position: relative` and otherwise constrains the absolute
1140+
child to ~icon width, forcing text to wrap one char per line). */
1141+
width: max-content;
10721142
max-width: 320px;
10731143
white-space: normal;
10741144
z-index: 9999;
@@ -1160,30 +1230,16 @@ input[type="radio"] {
11601230
flex-shrink: 0;
11611231
}
11621232

1163-
/* ============================================================
1164-
Bootstrap col-* standalone fallback — percentage widths for
1165-
col-* classes used OUTSIDE a .row (grid) context. Inside
1166-
.row the grid-column property takes over; outside, these
1167-
percentage widths replicate Bootstrap 3 float behaviour.
1168-
============================================================ */
1169-
:not(.row) > .col-xs-1, :not(.row) > .col-sm-1, :not(.row) > .col-md-1, :not(.row) > .col-lg-1 { width: 8.333%; }
1170-
:not(.row) > .col-xs-2, :not(.row) > .col-sm-2, :not(.row) > .col-md-2, :not(.row) > .col-lg-2 { width: 16.667%; }
1171-
:not(.row) > .col-xs-3, :not(.row) > .col-sm-3, :not(.row) > .col-md-3, :not(.row) > .col-lg-3 { width: 25%; }
1172-
:not(.row) > .col-xs-4, :not(.row) > .col-sm-4, :not(.row) > .col-md-4, :not(.row) > .col-lg-4 { width: 33.333%; }
1173-
:not(.row) > .col-xs-5, :not(.row) > .col-sm-5, :not(.row) > .col-md-5, :not(.row) > .col-lg-5 { width: 41.667%; }
1174-
:not(.row) > .col-xs-6, :not(.row) > .col-sm-6, :not(.row) > .col-md-6, :not(.row) > .col-lg-6 { width: 50%; }
1175-
:not(.row) > .col-xs-7, :not(.row) > .col-sm-7, :not(.row) > .col-md-7, :not(.row) > .col-lg-7 { width: 58.333%; }
1176-
:not(.row) > .col-xs-8, :not(.row) > .col-sm-8, :not(.row) > .col-md-8, :not(.row) > .col-lg-8 { width: 66.667%; }
1177-
:not(.row) > .col-xs-9, :not(.row) > .col-sm-9, :not(.row) > .col-md-9, :not(.row) > .col-lg-9 { width: 75%; }
1178-
:not(.row) > .col-xs-10, :not(.row) > .col-sm-10, :not(.row) > .col-md-10, :not(.row) > .col-lg-10 { width: 83.333%; }
1179-
:not(.row) > .col-xs-11, :not(.row) > .col-sm-11, :not(.row) > .col-md-11, :not(.row) > .col-lg-11 { width: 91.667%; }
1180-
:not(.row) > .col-xs-12, :not(.row) > .col-sm-12, :not(.row) > .col-md-12, :not(.row) > .col-lg-12 { width: 100%; }
1233+
/* The Bootstrap 3 standalone-column width fallback used to live here. The new
1234+
Tailwind UI uses a vertical-label form layout where the form-group children
1235+
should fill the available column width and adapt to viewport size. Fixed
1236+
percentage widths on standalone col-* classes prevented inputs from
1237+
stretching on wide screens and forced labels to wrap on narrow ones, so the
1238+
fallback was removed. The in-grid behaviour (.row > .col-*) is unaffected
1239+
and continues to be applied via grid-column above. */
11811240

1182-
/* Standalone offset fallback — margin-left for col-*-offset-* outside .row */
1183-
:not(.row) > .col-xs-offset-1, :not(.row) > .col-sm-offset-1, :not(.row) > .col-md-offset-1, :not(.row) > .col-lg-offset-1 { margin-left: 8.333%; }
1184-
:not(.row) > .col-xs-offset-2, :not(.row) > .col-sm-offset-2, :not(.row) > .col-md-offset-2, :not(.row) > .col-lg-offset-2 { margin-left: 16.667%; }
1185-
:not(.row) > .col-xs-offset-3, :not(.row) > .col-sm-offset-3, :not(.row) > .col-md-offset-3, :not(.row) > .col-lg-offset-3 { margin-left: 25%; }
1186-
:not(.row) > .col-xs-offset-4, :not(.row) > .col-sm-offset-4, :not(.row) > .col-md-offset-4, :not(.row) > .col-lg-offset-4 { margin-left: 33.333%; }
1187-
:not(.row) > .col-xs-offset-5, :not(.row) > .col-sm-offset-5, :not(.row) > .col-md-offset-5, :not(.row) > .col-lg-offset-5 { margin-left: 41.667%; }
1188-
:not(.row) > .col-xs-offset-6, :not(.row) > .col-sm-offset-6, :not(.row) > .col-md-offset-6, :not(.row) > .col-lg-offset-6 { margin-left: 50%; }
1189-
:not(.row) > .col-xs-offset-10, :not(.row) > .col-sm-offset-10, :not(.row) > .col-md-offset-10, :not(.row) > .col-lg-offset-10 { margin-left: 83.333%; }
1241+
/* The Bootstrap 3 horizontal-form offset fallback (margin-left: N% on standalone
1242+
col-*-offset-*) used to be applied here. The new Tailwind UI stacks labels on
1243+
top of inputs (vertical layout), so the offset would push checkboxes, submit
1244+
buttons and other action rows out of alignment with the form fields. The
1245+
in-grid behaviour (.row > .col-*-offset-*) defined above is unaffected. */

0 commit comments

Comments
 (0)