Skip to content

Commit

Permalink
Merge pull request #2286 from opensafely-core/bootstrap-components
Browse files Browse the repository at this point in the history
Use react-bootstrap components
  • Loading branch information
tomodwyer authored Jan 7, 2025
2 parents 0caa65c + 7116cad commit 5c7f98c
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 100 deletions.
108 changes: 65 additions & 43 deletions assets/src/scripts/components/CodelistBuilder.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import PropTypes from "prop-types";
import React, { useRef } from "react";
import {
Button,
ButtonGroup,
Col,
Form,
ListGroup,
OverlayTrigger,
Row,
Tooltip,
} from "react-bootstrap";
import Modal from "react-bootstrap/Modal";
import { getCookie } from "../_utils";
import Filter from "./Filter";
Expand Down Expand Up @@ -150,43 +160,44 @@ class CodelistBuilder extends React.Component {

return (
<>
<div className="row">
<div className="col-md-3">
<Row>
<Col md="3">
{this.props.isEditable && (
<>
<this.ManagementForm complete={this.complete()} />
<hr />
</>
)}

<h6>Summary</h6>
<h3 className="h6">Summary</h3>
<Filter filter={this.props.filter} />
<Summary counts={this.counts()} />
<hr />

{this.props.searches.length > 0 && (
<>
<h6>Searches</h6>
<div className="list-group">
<h3 className="h6">Searches</h3>
<ListGroup>
{this.props.searches.map((search) => (
<Search key={search.url} search={search} />
))}
{this.props.searches.some((search) => search.active) ? (
<a
className="list-group-item list-group-item-action py-1 font-italic"
<ListGroup.Item
action
className="py-1 px-2 font-italic"
href={encodeURI(this.props.draftURL)}
>
show all
</a>
</ListGroup.Item>
) : null}
</div>
</ListGroup>
<hr />
</>
)}

{this.props.isEditable && (
<>
<h6>New search</h6>
<h3 className="h6">New search</h3>
<SearchForm
codingSystemName={this.props.metadata.coding_system_name}
searchURL={this.props.searchURL}
Expand Down Expand Up @@ -224,16 +235,16 @@ class CodelistBuilder extends React.Component {
</dl>
<hr />

<h6>Versions</h6>
<h3 className="h6">Versions</h3>
<ul className="pl-3">
{this.props.versions.map((version) => (
<Version key={version.tag_or_hash} version={version} />
))}
</ul>
</div>
</Col>

<div className="col-md-9 overflow-auto">
<h4>{this.props.resultsHeading}</h4>
<Col md="9" className="overflow-auto">
<h3 className="h4">{this.props.resultsHeading}</h3>
<hr />
<TreeTables
codeToStatus={this.state.codeToStatus}
Expand All @@ -244,8 +255,8 @@ class CodelistBuilder extends React.Component {
updateStatus={this.updateStatus}
visiblePaths={this.props.visiblePaths}
/>
</div>
</div>
</Col>
</Row>

{moreInfoModal}
</>
Expand All @@ -267,54 +278,65 @@ class CodelistBuilder extends React.Component {

return (
<>
<form ref={management_form} method="post">
<input
<Form method="POST" ref={management_form}>
<Form.Control
id="csrfmiddlewaretoken"
name="csrfmiddlewaretoken"
type="hidden"
value={getCookie("csrftoken")}
/>
<input id="action" name="action" type="hidden" value="" />
<div className="btn-group-vertical btn-block" role="group">
<Form.Control id="action" name="action" type="hidden" value="" />
<ButtonGroup
aria-label="Codelist actions"
className="d-block"
vertical
>
{complete ? (
<button
className="btn btn-outline-primary btn-block"
<Button
block
name="action"
type="submit"
value="save-for-review"
variant="outline-primary"
>
Save for review
</button>
</Button>
) : (
<button
aria-disabled="true"
className="disabled btn btn-outline-secondary btn-block"
data-toggle="tooltip"
title="You cannot save for review until all search results are included or excluded"
type="button"
>
Save for review
</button>
<>
<OverlayTrigger
placement="right"
overlay={
<Tooltip id="disabled-review">
You cannot save for review until all search results are
included or excluded
</Tooltip>
}
>
<Button block disabled variant="outline-secondary">
Save for review
</Button>
</OverlayTrigger>
</>
)}
<button
className="btn btn-outline-primary btn-block"
<Button
block
name="action"
type="submit"
value="save-draft"
variant="outline-primary"
>
Save draft
</button>
<button
className="btn btn-outline-primary btn-block"
name="action"
</Button>
<Button
block
type="button"
variant="outline-primary"
onClick={handleConfirmMsg}
type="submit"
value="discard"
>
Discard
</button>
</div>
</form>
</Button>
</ButtonGroup>
</Form>
{confirmDiscardModal}
</>
);
Expand Down
16 changes: 7 additions & 9 deletions assets/src/scripts/components/MoreInfoButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import { Button } from "react-bootstrap";

function MoreInfoButton({ code, showMoreInfoModal }) {
return (
<div className="btn-group btn-group-sm mx-2" role="group">
<Button
className="py-0 border-0"
onClick={showMoreInfoModal.bind(null, code)}
variant="outline-secondary"
>
...
</Button>
</div>
<Button
className="py-0 border-0"
onClick={showMoreInfoModal.bind(null, code)}
variant="outline-secondary"
>
&hellip;
</Button>
);
}

Expand Down
18 changes: 11 additions & 7 deletions assets/src/scripts/components/Search.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import PropTypes from "prop-types";
import React from "react";
import { Button, Form } from "react-bootstrap";
import { getCookie } from "../_utils";

function Search({ search }) {
return search.delete_url ? (
<form action={search.delete_url} className="mt-0 pt-0" method="post">
<input
<Form action={search.delete_url} className="mt-0 pt-0" method="post">
<Form.Control
name="csrfmiddlewaretoken"
type="hidden"
value={getCookie("csrftoken")}
Expand All @@ -21,15 +22,18 @@ function Search({ search }) {
>
{search.term_or_code}

<button
className="btn badge badge-secondary float-right"
<Button
aria-label="remove search"
className="float-right p-0 px-1"
name="delete-search"
type="submit"
size="sm"
variant="secondary"
>
x
</button>
&times;
</Button>
</a>
</form>
</Form>
) : (
<a
className={
Expand Down
38 changes: 18 additions & 20 deletions assets/src/scripts/components/SearchForm.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
import PropTypes from "prop-types";
import React from "react";
import { Button, Form } from "react-bootstrap";
import { getCookie } from "../_utils";

function SearchForm({ codingSystemName, searchURL }) {
return (
<form action={encodeURI(searchURL)} method="post">
<div className="form-group">
<input
<Form action={encodeURI(searchURL)} method="post">
<Form.Group>
<Form.Control
name="csrfmiddlewaretoken"
type="hidden"
value={getCookie("csrftoken")}
/>
<input
className="form-control"
name="search"
placeholder="Term or code"
type="search"
/>
</div>
<div>
<button
className="btn btn-sm btn-primary mr-1"
<Form.Control name="search" placeholder="Term or code" type="search" />
</Form.Group>
<Form.Group>
<Button
className="mr-1"
name="field"
size="sm"
type="submit"
variant="primary"
>
Search
</button>
</div>
<div>
<small className="form-text text-muted">
</Button>
</Form.Group>
<Form.Group>
<Form.Text className="text-muted">
{codingSystemName === "ICD-10" ? (
<p>
To search by code, prefix your search with <code>code:</code>. For
Expand All @@ -52,9 +50,9 @@ function SearchForm({ codingSystemName, searchURL }) {
We plan to support boolean search operators (eg{" "}
<code>ambulatory AND blood pressure</code>) in future.
</p>
</small>
</div>
</form>
</Form.Text>
</Form.Group>
</Form>
);
}

Expand Down
25 changes: 12 additions & 13 deletions assets/src/scripts/components/StatusToggle.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import PropTypes from "prop-types";
import React from "react";
import { Button } from "react-bootstrap";

function StatusToggle({ code, status, symbol, updateStatus }) {
let buttonClasses = ["btn"];
if (status === symbol) {
buttonClasses.push("btn-primary");
} else if (status === `(${symbol})`) {
buttonClasses.push("btn-secondary");
} else {
buttonClasses.push("btn-outline-secondary");
}
buttonClasses.push("py-0");
return (
<button
className={buttonClasses.join(" ")}
<Button
className="py-0"
data-symbol={symbol}
onClick={updateStatus && updateStatus.bind(null, code, symbol)}
type="button"
size="sm"
variant={
status === symbol
? "primary"
: status === `(${symbol})`
? "secondary"
: "outline-secondary"
}
>
{symbol}
</button>
</Button>
);
}

Expand Down
15 changes: 7 additions & 8 deletions assets/src/scripts/components/Version.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from "prop-types";
import React from "react";
import { Badge } from "react-bootstrap";

function Version({ version }) {
return (
Expand All @@ -11,17 +12,15 @@ function Version({ version }) {
)}

{version.status === "draft" ? (
<>
{" "}
<span className="badge badge-primary">Draft</span>
</>
<Badge className="ml-1" variant="primary">
Draft
</Badge>
) : null}

{version.status === "under review" ? (
<>
{" "}
<span className="badge badge-primary">Review</span>
</>
<Badge className="ml-1" variant="primary">
Review
</Badge>
) : null}
</li>
);
Expand Down

0 comments on commit 5c7f98c

Please sign in to comment.