Skip to content

Commit

Permalink
Hotfix/v1.6.0 (#314)
Browse files Browse the repository at this point in the history
* #313: added spinner for deleting slice

* #313: added delete/ extend slice function to slice viewer error boundary component

* #313: lifted state up for slice viewer error boundary component

* #313: updated homepage carousel for more responsive design
  • Loading branch information
yaxue1123 authored Jan 16, 2024
1 parent cf240ec commit bc20fff
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 92 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fabric-portal",
"version": "1.6.0",
"version": "1.6.1",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.32",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Footer extends React.Component {
<Link to="/aup">Acceptable Use Policy</Link>
</li>
<li><Link to="/cookie-policy">Cookie Policy</Link></li>
<li><Link to="/privacy-policy">Privacy Policy</Link></li>
{/* <li><Link to="/privacy-policy">Privacy Policy</Link></li> */}
<li><Link to="/branding">Branding Resources</Link></li>
</ul>
</div>
Expand Down
20 changes: 17 additions & 3 deletions src/components/Home/Carousel.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import React from "react";
import { getActiveCarouselItems } from "../../services/announcementService";
import { toast } from "react-toastify";
import Parser from 'html-react-parser';

class Carousel extends React.Component {
state = {
items: [],
};

placeholderItems = [
{
"announcement_type": "carousel",
"background_image_url": "https://github.com/fabric-testbed/fabric-portal/assets/37635744/f2365fff-d40e-4204-9a74-a4697ddefc08",
"button": "Learn More",
"content": "<ul><li>Build Community: Inspire others with your research, discover collaborators, and find opportunities to showcase your project.</li><li>Conduct Experiments: Take advantage of FABRIC resources to design, deploy, execute, and monitor your experiments.</li><li>Browse the Library: Learn more about FABRIC through publications and user documentation. Discover additional complimentary facilities and testbeds to expand your research.</li></ul>",
"is_active": true,
"link": "https://portal.fabric-testbed.net/about/about-fabric",
"sequence": 1,
"start_date": "2023-11-02 18:49:51.339756+00:00",
"title": "FABRIC Portal is your guide, helping make your experiment a success.",
"uuid": "e0d53c5f-0922-4e3d-8f43-8cd520921ea4"
}
]

async componentDidMount() {
try {
const { data: res } = await getActiveCarouselItems();
let items = res.results;
this.setState({ items });
} catch (err) {
toast.error("Failed to load carousel items. Please reload this page.");
this.setState({ items: this.placeholderItems });
}
}

Expand Down Expand Up @@ -49,7 +63,7 @@ class Carousel extends React.Component {
items && items.length > 0 && items.map((item, index) =>
<div className={`carousel-item ${index === 0? "active" : ""}`}>
<img src={item.background_image_url} alt={`FABRIC Portal Homepage Slide ${index}`} className="d-block w-100"/>
<div className="carousel-caption d-none d-md-block">
<div className="carousel-caption d-md-block">
<div className="carousel-caption-content">
<h3>{item.title}</h3>
<div className="homepage-carousel-content">
Expand Down
2 changes: 1 addition & 1 deletion src/components/Home/Partners.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const Partners = () => {
<span className="homepage-partner-header">Our Partners</span>
</div>
<span className="homepage-partner-text">FABRIC is made possible by collaborations with the following organizations.</span>
<div className="homepage-partner-logo-containter my-1">
<div className="homepage-partner-logo-containter">
<img
src={RENCI}
key={`partners-logo-renci`}
Expand Down
11 changes: 2 additions & 9 deletions src/components/Project/Personnel/ProjectTokenHolders.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class ProjectTokenHolders extends Component {
<div>
<h4>Long-lived Token Holders</h4>
<div className="alert alert-primary mb-2" role="alert">
{"Users running long-lived experiments supported by unattended automated tools can now request non-renewable long-lived API Tokens (lifetime up to 5 weeks)."}
{"Users running long-lived experiments supported by unattended automated tools can now request non-renewable long-lived API Tokens (lifetime up to 9 weeks)."}
{"For more information, please read this guide article: "}
<a
href={portalData.learnArticles.guideToLongLivedTokens}
Expand Down Expand Up @@ -94,18 +94,11 @@ class ProjectTokenHolders extends Component {
operation="remove"
/> :
<div className="alert alert-primary" role="alert">
{`This project has no ${personnelType}.`}
{`This project has no long-lived ${personnelType}.`}
</div>
}
</div>
</div>

{
token_holders.length === 0 && !isFO &&
<div className="alert alert-primary" role="alert">
{`This project has no ${personnelType}.`}
</div>
}
{
!isTokenHolder && !isFO && !projectExpired && <button
className="btn btn-sm btn-outline-success mr-2 my-3"
Expand Down
4 changes: 2 additions & 2 deletions src/components/Resource/DetailTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ const DetailTable = props => {
},
"PreMaint": {
state: "Pre-Maintenance",
colorName: "info",
colorName: "warning",
colorHex: "#ffb670",
labelColorHex: "#212529"
},
"PartMaint": {
state: "Partial Maintenance",
colorName: "info",
colorName: "warning",
colorHex: "#ffb670",
labelColorHex: "#212529"
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/Resource/SummaryTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ class SummaryTable extends Component {
{
resource.status && resource.status.state === "PreMaint" &&
<div>
<span className="badge badge-pill badge-info px-2">
<span className="badge badge-pill badge-warning px-2">
Pre-Maintenance
</span>
</div>
}
{
resource.status && resource.status.state === "PartMaint" &&
<div>
<span className="badge badge-pill badge-info px-2">
<span className="badge badge-pill badge-warning px-2">
Partial Maintenance
</span>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/SliceViewer/SideNodes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,12 @@ class SideNodes extends React.Component {
</span>
}
{
selectedSite.status.state === "PreMaint" && <span className="badge badge-pill badge-info px-2">
selectedSite.status.state === "PreMaint" && <span className="badge badge-pill badge-warning px-2">
Pre-Maintenance
</span>
}
{
selectedSite.status.state === "PartMaint" && <span className="badge badge-pill badge-info px-2">
selectedSite.status.state === "PartMaint" && <span className="badge badge-pill badge-warning px-2">
Partial Maintenance
</span>
}
Expand Down
77 changes: 17 additions & 60 deletions src/components/SliceViewer/SliceViewerErrorBoundary.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { Component } from "react";
import CopyButton from "../common/CopyButton";
import { Link } from "react-router-dom";
// import DeleteModal from "../common/DeleteModal";
import DeleteModal from "../common/DeleteModal";
import { toast } from "react-toastify";
import { default as portalData } from "../../services/portalData.json";
import sleep from "../../utils/sleep";
import moment from 'moment';
import { deleteSlice, extendSlice } from "../../services/sliceService.js";
import { deleteSlice} from "../../services/sliceService.js";
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
// import Calendar from "../../components/common/Calendar";
import Calendar from "../../components/common/Calendar";
import utcToLocalTimeParser from "../../utils/utcToLocalTimeParser.js";

export default class SliceViewerErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
leaseEndTime: this.props.slice.lease_end_time
hasError: false
};
}

Expand All @@ -36,59 +34,21 @@ export default class SliceViewerErrorBoundary extends Component {
}
}

handleLeaseEndChange = (value) => {
const inputTime = moment(value).format();
// input format e.g. 2022-05-25T10:49:03-04:00
// output format should be 2022-05-25 10:49:03 -0400
const date = inputTime.substring(0, 10);
const time = inputTime.substring(11, 19);
const offset = inputTime.substring(19).replace(":", "");
const outputTime = [date, time, offset].join(" ");
this.setState({ leaseEndTime: outputTime });
}

handleSliceExtend = async () => {
this.setState({
showSpinner: true,
spinnerText: "Extending slice..."
})
try {
const { slice, leaseEndTime } = this.state;
await extendSlice(slice.slice_id, leaseEndTime);
// toast message to users when the api call is successfully done.
toast.success("Slice has been successfully renewed.");
await sleep(1000);
window.location.reload();
} catch (err) {
toast.error("Failed to renew the slice.");
this.setState({
leaseEndTime: this.state.slice.lease_end_time,
showSpinner: false,
spinnerText: ""
});
}
}

handleDeleteSlice = async (id) => {
try {
await deleteSlice(id);
// toast message to users when the api call is successfully done.
toast.success("Slice deleted successfully.");
// change slice state to Dead.
this.setState(prevState => ({
slice: {
...prevState.slice,
"state": "Dead"
}
}))
await sleep(1000);
window.location.reload();
} catch (err) {
toast.error("Failed to delete the slice.");
}
}

render() {
const { hasError } = this.state;
const { slice } = this.props;
const { slice, leaseEndTime } = this.props;

const stateColors = {
"Nascent": "primary-dark",
Expand Down Expand Up @@ -131,15 +91,15 @@ export default class SliceViewerErrorBoundary extends Component {
</h2>
</div>
<div className="d-flex flex-row justify-content-between align-items-center">
{/* {
{
["StableOK", "ModifyOK", "StableError", "ModifyError"].includes(slice.state) &&
<DeleteModal
name={"Delete Slice"}
text={'Are you sure you want to delete this slice? This process cannot be undone but you can find deleted slices by checking the "Include Dead Slices" radio button on Experiments -> Slices page.'}
id={"delete-a-slice"}
onDelete={() => this.handleDeleteSlice(slice.slice_id)}
/>
} */}
}
<Link to="/experiments#slices">
<button
className="btn btn-sm btn-outline-primary my-3 ml-3"
Expand Down Expand Up @@ -207,7 +167,7 @@ export default class SliceViewerErrorBoundary extends Component {
<div className="row d-flex flex-column mb-2">
<label>
Lease End at
{/* {
{
slice.state === "StableOK" &&
<OverlayTrigger
placement="right"
Expand All @@ -216,37 +176,34 @@ export default class SliceViewerErrorBoundary extends Component {
>
<i className="fa fa-question-circle text-secondary ml-2"></i>
</OverlayTrigger>
} */}
}
</label>
<div className="slice-form-element">
{utcToLocalTimeParser(this.props.slice.lease_end_time)}
</div>
{/* {
{
slice.state !=="StableOK" &&
<div className="slice-form-element">
{utcToLocalTimeParser(leaseEndTime)}
</div>
} */}
{/* {
}
{
leaseEndTime && slice.state ==="StableOK" &&
<div>
<div className="slice-form-element mb-1">
<Calendar
id="sliceViewerCalendar"
name="sliceViewerCalendar"
onTimeChange={this.handleLeaseEndChange}
onTimeChange={this.props.onLeaseEndChange}
parent={"sliceDetailForm"}
currentTime={new Date(utcToLocalTimeParser(leaseEndTime).replace(/-/g, "/"))}
/>
</div>
<button
className="btn btn-sm btn-outline-primary mt-2 mr-3"
onClick={this.handleSliceExtend}
onClick={this.props.onSliceExtend}
>
Extend
</button>
</div>
} */}
}
</div>
</div>
</div>
Expand Down
17 changes: 9 additions & 8 deletions src/pages/SliceViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,13 @@ class SliceViewer extends Component {
}

handleDeleteSlice = async (id) => {
this.setState({ showSpinner: true, spinnerText: "Deleting Slice" });
try {
await deleteSlice(id);
// toast message to users when the api call is successfully done.
toast.success("Slice deleted successfully.");
// change slice state to Dead.
this.setState(prevState => ({
slice: {
...prevState.slice,
"state": "Dead"
}
}))
await sleep(1000);
window.location.reload();
} catch (err) {
toast.error("Failed to delete the slice.");
}
Expand Down Expand Up @@ -159,7 +155,12 @@ class SliceViewer extends Component {
let showSlice = !showSpinner && hasProject;

return(
<SliceViewerErrorBoundary slice={slice}>
<SliceViewerErrorBoundary
slice={slice}
leaseEndTime={leaseEndTime}
onLeaseEndChange={this.handleLeaseEndChange}
onSliceExtend={this.handleSliceExtend}
>
<div className="slice-page-container">
<TerminalFormModal
vmData={selectedData}
Expand Down
2 changes: 1 addition & 1 deletion src/services/mockData/fakeAnnoucements.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const updates = [
{
"announcement_type": "facility",
"button": "Learn More",
"content": "<p>We are pleased to announce the deployment of Release 1.6 of our software stack on FABRIC production infrastructure. The new features include:</p><p><ul><li>Long-lived tokens: users with long-lived token permissions can now create tokens with a lifetime up to 5 weeks.</li><li>POA (Perform Operational Action) Add/Remove SSH Keys: users can request to add/remove SSH keys to/from the slivers using POA API.</li><li>Internet2 AL2S/CloudConnect updated as per new AL2S API.</li><li>List Resources enhanced to return more granular information for sites including the resource information per worker on each site.</li></p>",
"content": "<p>We are pleased to announce the deployment of Release 1.6 of our software stack on FABRIC production infrastructure. The new features include:</p><p><ul><li>Long-lived tokens: users with long-lived token permissions can now create tokens with a lifetime up to 9 weeks.</li><li>POA (Perform Operational Action) Add/Remove SSH Keys: users can request to add/remove SSH keys to/from the slivers using POA API.</li><li>Internet2 AL2S/CloudConnect updated as per new AL2S API.</li><li>List Resources enhanced to return more granular information for sites including the resource information per worker on each site.</li></p>",
"display_date": "2024-01-11 00:00:00+00:00",
"is_active": true,
"link": "https://learn.fabric-testbed.net/knowledge-base/fabric-testbed-release-1-6/",
Expand Down
2 changes: 1 addition & 1 deletion src/services/portalData.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.6.0",
"version": "1.6.1",
"defaultFacility": "FABRIC",
"facilityOptions": ["FABRIC"],
"keyLimit": 10,
Expand Down
Loading

0 comments on commit bc20fff

Please sign in to comment.