Skip to content

Commit

Permalink
webui: Update Bootstrap to version 5.3.2
Browse files Browse the repository at this point in the history
Upgrade Bootstrap from version 3.4.1 to version 5.3.2 (i.e. the latest
version at the moment). This is a major change, upgrading by two major
releases, to it requires a lot of adjustments in the current templates
and HTML code.

While adjusting the existing markup to be compatible with Bootstrap 5,
also rewrite parts of the markup to make better use of semantically
correct tags (e.g. not use tables for layouting only), reduce the use of
inline CSS styles (and use the proper Bootstrap classes instead), unify
the look and feel of the web UI a bit, and fix some HTML validation
errors.

Dependency-wise this removed the Glyphicon and the jQuery dependencies
completely. Bootstrap itself is moved to the webpack bundle instead of
being a set of separate files.
  • Loading branch information
MKleusberg committed Dec 25, 2023
1 parent d29b765 commit e391538
Show file tree
Hide file tree
Showing 70 changed files with 844 additions and 1,383 deletions.
4 changes: 2 additions & 2 deletions cypress/e2e/1-webui/user-preferences.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ describe('logged-in user preferences page', () => {
// Generate new API key
it('generate new API key', () => {
cy.get('[data-cy="genapibtn"]').click()
cy.get('[data-cy="apikeystbl"]').should('contain', 'created')
cy.get('[data-cy="apistatus"]').should('contain', 'created')
})
})
})
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"dependencies": {
"@popperjs/core": "^2.11.8",
"babel-preset-react": "^6.24.1",
"babel-preset-react-app": "^10.0.1",
"bootstrap": "5.2.3",
"cypress": "13.3.3",
"plotly.js-basic-dist": "^2.22.0",
"plotly.js-dist": "^2.22.0",
Expand Down Expand Up @@ -59,8 +61,12 @@
"private": false,
"devDependencies": {
"@babel/cli": "^7.20.7",
"css-loader": "^6.7.3",
"style-loader": "^3.3.2",
"autoprefixer": "^10.4.16",
"css-loader": "^6.8.1",
"postcss-loader": "^7.3.3",
"sass": "^1.69.5",
"sass-loader": "^13.3.2",
"style-loader": "^3.3.3",
"webpack": "^5.76.0",
"webpack-cli": "^5.0.1"
}
Expand Down
6 changes: 0 additions & 6 deletions webui/css/bootstrap.min.css

This file was deleted.

132 changes: 0 additions & 132 deletions webui/css/local.css
Original file line number Diff line number Diff line change
@@ -1,139 +1,7 @@
.nav, .pagination, .carousel, .panel-title a {
cursor: pointer;
}

.blackLink {
color: #181818;
cursor: pointer;
}

.blackLink:hover {
color: #23527c;
text-decoration: underline;
}

.dbMenu {
font-weight: 600;
font-family: 'arial black'
}

.dbMenuLinkActive {
border-bottom: 1px grey dashed;
}

.inBox {
color: #181818;
cursor: pointer;
}

.inBox:hover {
color: #23527c;
text-decoration: none;
}

.minHeight {
min-height: 80px;
}

.minHeightSmaller {
min-height: 60px;
}

.profileTable {
border-collapse: separate;
border: none;
margin-bottom: 20px;
}

.profileTable h4 {
margin-bottom: 8px;
margin-top: 6px;
}

.profileTable tr {
border: none;
}

.profileTable td {
border: solid 1px #DDD;
border-bottom: none;
}

.profileTable tr:first-child td:first-child {
border-top-left-radius: 7px;
}

.profileTable tr:first-child td:last-child {
border-top-right-radius: 7px;
}

.profileTable tr:last-child td:first-child {
border-bottom-left-radius: 7px;
}

.profileTable tr:last-child td:last-child {
border-bottom: solid 1px #DDD;
border-bottom-right-radius: 7px;
}

.rendered {
padding: 8px;
text-align: left;
margin-top: 2px;
}

.rendered h1:first-child {
margin-top: 0;
}

.rendered h2:first-child {
margin-top: 0;
}

.rendered h3:first-child {
margin-top: 0;
}

.rendered h4:first-child {
margin-top: 0;
}

.rendered h5:first-child {
margin-top: 0;
}

.rendered h6:first-child {
margin-top: 0;
}

.rendered h1:last-child {
margin-bottom: 0;
}

.rendered h2:last-child {
margin-bottom: 0;
}

.rendered h3:last-child {
margin-bottom: 0;
}

.rendered h4:last-child {
margin-bottom: 0;
}

.rendered h5:last-child {
margin-bottom: 0;
}

.rendered h6:last-child {
margin-bottom: 0;
}

#contents h1, #contents h2, #contents h3, #contents h4, #contents h5, #contents h6 {
margin-top: 0;
}

textarea {
margin-top: 2px;
width: 100%;
Expand Down
Binary file removed webui/fonts/glyphicons-halflings-regular.eot
Binary file not shown.
288 changes: 0 additions & 288 deletions webui/fonts/glyphicons-halflings-regular.svg

This file was deleted.

Binary file removed webui/fonts/glyphicons-halflings-regular.ttf
Binary file not shown.
Binary file removed webui/fonts/glyphicons-halflings-regular.woff
Binary file not shown.
Binary file removed webui/fonts/glyphicons-halflings-regular.woff2
Binary file not shown.
6 changes: 0 additions & 6 deletions webui/js/bootstrap.min.js

This file was deleted.

2 changes: 0 additions & 2 deletions webui/js/jquery-3.6.4.min.js

This file was deleted.

5 changes: 5 additions & 0 deletions webui/jsx/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import UploadForm from "./upload-form";
import UserPage from "./user-page";
import { Visualisation, VisualisationEditor } from "./visualisation-editor";

// Import Bootstrap
import "../jsx/bootstrap.scss"
import * as bootstrap from "bootstrap"


{
const rootNode = document.getElementById("db-header-root");
if (rootNode) {
Expand Down
18 changes: 9 additions & 9 deletions webui/jsx/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@ export default function Auth() {
if (authInfo.loggedInUser) {
let avatar = null;
if (authInfo.avatarUrl) {
avatar = <img src={authInfo.avatarUrl} height="18" width="18" style={{border: "1px solid #8c8c8c"}}/>;
avatar = <img src={authInfo.avatarUrl} height="18" width="18" className="border border-secondary" />;
}

let updates = null;
if (authInfo.numStatusUpdates === 0) {
updates = <a href="/updates" className="inBox" style={{verticalAlign: "middle"}}><i className="fa fa-inbox fa-fw" style={{fontSize: "large"}}></i></a>;
updates = <a href="/updates" className="align-middle"><i className="fa fa-inbox fa-fw fs-5"></i></a>;
} else {
updates = <a href="/updates" className="inBox" style={{verticalAlign: "middle", borderBottom: "1px grey dotted"}}><i className="fa fa-inbox fa-fw" style={{fontSize: "large"}}></i>{authInfo.numStatusUpdates}</a>;
updates = <a href="/updates" className="align-middle border-bottom border-info"><i className="fa fa-inbox fa-fw fs-5"></i>{authInfo.numStatusUpdates}</a>;
}

return (
<>
{avatar}
&nbsp;
{updates}
&nbsp;
<a href={"/" + authInfo.loggedInUser} style={{color: "black", verticalAlign: "middle"}}>Home</a> | <a href="/pref" style={{color: "black", verticalAlign: "middle"}}>Preferences</a> | <a href="/logout" style={{color: "black", verticalAlign: "middle"}}>Log out</a>
{avatar}
&nbsp;
{updates}
&nbsp;
<a href={"/" + authInfo.loggedInUser} className="align-middle">Home</a> | <a href="/pref" className="align-middle">Preferences</a> | <a href="/logout" className="align-middle">Log out</a>
</>
);
} else {
return <a onClick={() => {return login()}} className="blackLink" data-cy="loginlnk">Login / Register</a>;
return <a onClick={() => {return login()}} data-cy="loginlnk" className="align-middle">Login / Register</a>;
}
}
16 changes: 16 additions & 0 deletions webui/jsx/bootstrap.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$secondary: rgb(205, 205, 205);

@import "~bootstrap/scss/bootstrap";

a:not([rel~="external"]):not(.btn):not(.list-group-item) {
color: #181818;
}

a:not([rel~="external"]):not(.btn):not(.nav-link):not(.list-group-item) {
text-decoration: none;
}

a:not([rel~="external"]):not(.btn):not(.nav-link):not(.list-group-item):hover {
color: #23527c;
text-decoration: underline;
}
34 changes: 14 additions & 20 deletions webui/jsx/branches.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,36 +88,32 @@ function BranchesTableRow({name, commit, description, setStatus}) {

return (<>
<tr>
<td style={{borderStyle: "none"}}>
<td>
{authInfo.loggedInUser === meta.owner ? <button className="btn btn-primary" onClick={() => {return updateBranch()}} data-cy="savebtn">Save Changes</button> : null}
</td>
<td style={{borderStyle: "none"}}>
<td>
<div>
{authInfo.loggedInUser === meta.owner && name !== defaultBranch ? <button className="btn btn-primary" onClick={() => {return setDefaultBranch()}} data-cy="setdefaultbtn">Set Default</button> : null }
{name === defaultBranch ? <i>Default branch</i> : null}
</div>
</td>
<td style={{borderStyle: "none"}}>
<td>
{authInfo.loggedInUser === meta.owner ?
<input name={name + "_name"} id={name + "_name"} size="20" maxlength="20" value={branchName} data-cy="nameinput" onChange={(e) => setName(e.target.value)} required />
<input className="form-control" name={name + "_name"} id={name + "_name"} size="20" maxlength="20" value={branchName} data-cy="nameinput" onChange={(e) => setName(e.target.value)} required />
:
<div style={{paddingTop: "8px"}}>
<a className="blackLink" href={"/" + meta.owner + "/" + meta.database + "?branch=" + name}>{name}</a>
</div>
<a href={"/" + meta.owner + "/" + meta.database + "?branch=" + name}>{name}</a>
}
</td>
<td style={{borderStyle: "none"}}>
<div style={{paddingTop: "8px"}}>
<a className="blackLink" href={"/" + meta.owner + "/" + meta.database + "?branch=" + name + "&commit=" + commit} data-cy="commitlnk">{commit}</a>
</div>
<td>
<a href={"/" + meta.owner + "/" + meta.database + "?branch=" + name + "&commit=" + commit} data-cy="commitlnk">{commit.substring(0, 8)}</a>
</td>
</tr>
<tr>
<td style={{borderStyle: "none"}}>
{name !== defaultBranch ? <button className="btn btn-default" onClick={() => {return viewChanges()}} data-cy="comparebtn">{"Compare with " + defaultBranch}</button> : null}
<td>
{name !== defaultBranch ? <button className="btn btn-info me-1" onClick={() => {return viewChanges()}} data-cy="comparebtn">{"Compare with " + defaultBranch}</button> : null}
{authInfo.loggedInUser === meta.owner ? <button className="btn btn-danger" onClick={() => {return deleteBranch()}} data-cy="delbtn">Delete</button> : null}
</td>
<td style={{borderStyle: "none", padding: 0}} colSpan={3}>
<td colSpan={3}>
<MarkdownEditor editorId={name + "_desc"} rows={10} placeholder="A description for this branch" defaultIndex={1} initialValue={description} viewOnly={meta.owner !== authInfo.loggedInUser} />
</td>
</tr>
Expand Down Expand Up @@ -156,17 +152,15 @@ export default function BranchesTable() {
<div>
{statusMessage !== "" ? (
<div className="row">
<div className="col-md-12">
<div style={{textAlign: "center", paddingBottom: "8px"}}>
<h4 style={{color: statusMessageColour}}>&nbsp;{statusMessage}</h4>
</div>
<div className="col-md-12 text-center mb-2">
<h6 style={{color: statusMessageColour}}>&nbsp;{statusMessage}</h6>
</div>
</div>
) : null}
<div className="row">
<div className="col-md-12">
<div style={{border: "1px solid #DDD", borderRadius: "7px", marginBottom: "10px", padding: "0"}}>
<table id="contents" className="table table-striped table-responsive" style={{margin: "0"}}>
<div className="border border-secondary rounded">
<table id="contents" className="table table-striped table-responsive table-borderless m-0">
<thead>
<tr>
<th colSpan={2}>Actions</th><th>Name</th><th>Head Commit ID</th>
Expand Down
6 changes: 3 additions & 3 deletions webui/jsx/commit-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ export default function CommitList({commits, owner, database}) {
const commitRows = (commits === null ? null : commits.map(row => (
<tr>
<td>
<a href={"/" + row.author_username} className="blackLink">
{row.author_avatar !== "" ? <img src={row.author_avatar} height="18" width="18" style={{border: "1px solid #8c8c8c"}} /> : null}&nbsp;
<a href={"/" + row.author_username}>
{row.author_avatar !== "" ? <img src={row.author_avatar} height="18" width="18" className="border border-secondary" /> : null}&nbsp;
{row.author_name}
</a>
</td>
<td>
<a className="blackLink" href={"/diffs/" + owner + "/" + database + "?commit_a=" + row.parent + "&commit_b=" + row.id}>
<a href={"/diffs/" + owner + "/" + database + "?commit_a=" + row.parent + "&commit_b=" + row.id}>
{row.id.substring(0, 8)}
</a>
</td>
Expand Down
36 changes: 18 additions & 18 deletions webui/jsx/database-commits.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ function DatabaseCommitRow({data, index, branch, setStatusMessage, setStatusMess
<td dangerouslySetInnerHTML={{__html: data.message}}>
</td>
<td>
{data.avatar_url !== "" ? <img src={data.avatar_url} height="30" width="30" style={{border: "1px solid #8c8c8c"}} /> : null}&nbsp;
<a className="blackLink" href={"/" + data.author_user_name}>{data.author_name}</a>
{data.avatar_url !== "" ? <img src={data.avatar_url} height="30" width="30" className="border border-secondary" /> : null}&nbsp;
<a href={"/" + data.author_user_name}>{data.author_name}</a>
</td>
<td>
<span title={new Date(data.timestamp).toLocaleString()}>{getTimePeriod(data.timestamp, false)}</span>
</td>
<td>
<a className="blackLink" href={"/" + meta.owner + "/" + meta.database + "?branch=" + branch + "&commit=" + data.id} data-cy="commitlnk">{data.id.substring(0, 8)}</a>
<a href={"/" + meta.owner + "/" + meta.database + "?branch=" + branch + "&commit=" + data.id} data-cy="commitlnk">{data.id.substring(0, 8)}</a>
</td>
</tr>
);
Expand Down Expand Up @@ -105,29 +105,29 @@ export default function DatabaseCommits() {
<div className="row">
<div className="col-md-12 text-center">
<span data-cy="commithist">Commit history for branch</span>&nbsp;
<div style={{display: "inline-block"}}>
<div className="d-inline-block">
<Select name="branchname" required={true} labelField="name" valueField="name" onChange={(values) => changeBranch(values[0].name)} options={branches} values={[{name: branch}]} />
</div>
</div>
</div>
{statusMessage !== "" ? (
<div className="row">
<div className="col-md-12">
<div style={{textAlign: "center", paddingBottom: "8px"}}>
<h4 style={{color: statusMessageColour}}>{statusMessage}</h4>
</div>
<div className="col-md-12 text-center mb-2">
<h6 style={{color: statusMessageColour}}>{statusMessage}</h6>
</div>
</div>
) : null}
<table id="contents" className="table table-striped table-responsive">
<thead>
<tr>
<th>Actions</th><th>Message</th><th>Author</th><th>Date</th><th>Commit ID</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
<div className="border border-secondary rounded">
<table id="contents" className="table table-striped table-responsive m-0">
<thead>
<tr>
<th>Actions</th><th>Message</th><th>Author</th><th>Date</th><th>Commit ID</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
</div>
</>);
}
Loading

8 comments on commit e391538

@MKleusberg
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short disclaimer: I'm not saying it looks better than before 😄 While I think this could be put on the production server without any issues, I'm also happy to do further fine-tuning of this before.

@justinclift
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. I'll take a look at it tomorrow during the day, and probably deploy it if nothing weird jumps out at me. 😄

@justinclift
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticing this in the build part of Cypress test logs for one of the dependabot changes today:

WARNING in ./webui/jsx/bootstrap.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js!./webui/jsx/bootstrap.scss)
Module Warning (from ./node_modules/sass-loader/dist/cjs.js):
Deprecation Passing percentage units to the global abs() function is deprecated.
In the future, this will emit a CSS abs() function to be resolved by the browser.
To preserve current behavior: math.abs(40%)
To emit a CSS abs() now: abs(#{40%})
More info: https://sass-lang.com/d/abs-percent

It's just a warning rather than a hard error, but we should probably look into it. 😄

@justinclift
Copy link
Member

@justinclift justinclift commented on e391538 Dec 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nearly the end of today here, and I still haven't looked at this change (been merging dependabot PRs).

It'll have to be a tomorrow thing instead, as I'm too sleepy atm for it to be a safe thing to do. 😇

@justinclift
Copy link
Member

@justinclift justinclift commented on e391538 Dec 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MKleusberg I've just taken a look at this in my local dev setup. The front page and user preferences pages (maybe others too) are pretty broken with Firefox. 😦

Haven't investigated why yet, as I'm working on a different issue. There's nothing obvious in the javascript console though.


Nope, my mistake. I needed to properly rebuild my local Docker image for this to show up fully. Looks fine so far. 😄


The Upload page looks a bit weird though, as the width of everything seems to be close to 100%.

@MKleusberg
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticing this in the build part of Cypress test logs for one of the dependabot changes today:

WARNING in ./webui/jsx/bootstrap.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js!./webui/jsx/bootstrap.scss)
Module Warning (from ./node_modules/sass-loader/dist/cjs.js):
Deprecation Passing percentage units to the global abs() function is deprecated.
In the future, this will emit a CSS abs() function to be resolved by the browser.
To preserve current behavior: math.abs(40%)
To emit a CSS abs() now: abs(#{40%})
More info: https://sass-lang.com/d/abs-percent

It's just a warning rather than a hard error, but we should probably look into it. 😄

Ah, I get the same warnings locally. They are coming from the Bootstrap code being compiled to CSS - so not really a problem on our end.

@MKleusberg
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Upload page looks a bit weird though, as the width of everything seems to be close to 100%.

Should be fixed now 😄

@justinclift
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This has been deployed to production. 😄

Please sign in to comment.