diff --git a/demo/lib/App.tsx b/demo/lib/App.tsx index f9013723e..33dd336af 100644 --- a/demo/lib/App.tsx +++ b/demo/lib/App.tsx @@ -10,6 +10,7 @@ import { Image, Input, Menu, + Message, Sidebar, } from "semantic-ui-react"; import seqparse from "seqparse"; @@ -21,6 +22,7 @@ import { chooseRandomColor } from "../../src/colors"; import { AnnotationProp, Primer, TranslationProp } from "../../src/elements"; import Header from "./Header"; import file from "./file"; +import { useEffect, useState } from "react"; const viewerTypeOptions = [ { key: "both", text: "Both", value: "both" }, @@ -29,6 +31,11 @@ const viewerTypeOptions = [ { key: "both_flip", text: "Both Flip", value: "both_flip" }, ]; +interface Message { + positive: boolean + visible: boolean +} + interface AppState { annotations: AnnotationProp[]; customChildren: boolean; @@ -45,6 +52,7 @@ interface AppState { showSidebar: boolean; translations: TranslationProp[]; viewer: string; + message: Message; zoom: number; } @@ -101,6 +109,10 @@ export default class App extends React.Component { { end: 1147, name: "", start: 736 }, { end: 1885, name: "ORF 2", start: 1165 }, ], + message: { + positive: true, + visible: false + }, viewer: "both", zoom: 50, }; @@ -123,6 +135,34 @@ export default class App extends React.Component { this.setState({ showSelectionMeta: !showSelectionMeta }); }; + sendToMPI = async () => { + try { + const { seq, name, annotations } = this.state; + const response = await fetch(`https://mpi.f4hcvcnn7c36k.us-east-1.cs.amazonlightsail.com/sequences`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ seq, name, type: "dna", annotations }), + }); + const res = await response.json(); + if (res.statusCode && res.statusCode != 201) { + throw "Not possible to export sequence." + } + this.setState({ message: { positive: true, visible: true } }) + } catch (e) { + this.setState({ message: { positive: false, visible: true } }) + } + + this.closeMessage() + }; + + closeMessage = () => { + setTimeout(() => { + this.setState({ message: { positive: true, visible: false } }); + }, 3000); + }; + handleHide = () => { this.setState({ showSidebar: false }); }; @@ -192,6 +232,7 @@ export default class App extends React.Component { return (
+ { showSelectionMeta={this.state.showSelectionMeta} toggleShowSelectionMeta={this.toggleShowSelectionMeta} toggleSidebar={this.toggleSidebar} + sendToMPI={this.sendToMPI} />
{this.state.seq && ( @@ -441,3 +483,25 @@ const SidebarFooter = () => (

); + +const Alert = ({ visible, positive }) => { + if (visible) { + if (positive) { + return ( + +

+ Sequence successfully exported to MPI. +

+
+ ); + } + return ( + +

+ Error exporting sequence to MPI. Try again later. +

+
+ ); + } +}; + diff --git a/demo/lib/Header.tsx b/demo/lib/Header.tsx index 4d1191e27..d58a0f42d 100644 --- a/demo/lib/Header.tsx +++ b/demo/lib/Header.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Button, Icon, Image, Popup } from "semantic-ui-react"; -const Header = ({ selection, showSelectionMeta, toggleShowSelectionMeta, toggleSidebar }) => ( +const Header = ({ selection, showSelectionMeta, toggleShowSelectionMeta, toggleSidebar, sendToMPI }) => (
+ @@ -40,6 +43,14 @@ const ToggleSelectionMetaButton = ({ showSelectionMeta, toggleShowSelectionMeta
); +const ExportToMPI = ({ sendToMPI }) => ( +
+ +
+); + const SelectionMetaRow = ({ selection }) => { const { end, feature, length, start } = selection; const noneSelected = start === end; diff --git a/demo/styles/global.css b/demo/styles/global.css index df2a94ba7..5a6aceab4 100644 --- a/demo/styles/global.css +++ b/demo/styles/global.css @@ -375,6 +375,19 @@ input#part-input { padding-right: 16px !important; margin: auto 0 !important; vertical-align: middle; +} + +#alert-message { + position: absolute; + bottom: 1rem; + left: 1rem; +} + +.mpi-block { + padding-left: 16px !important; + padding-right: 16px !important; + margin: auto 0 !important; + vertical-align: middle; flex: 1; } @@ -402,6 +415,21 @@ input#part-input { box-shadow: 0 1px 3px rgba(124, 124, 124, 0.12), 0 1px 2px rgba(124, 124, 124, 0.24) !important; } +#mpi-button { + margin: 0; + padding: 10px 12px; + width: 120px; + background: #f0f0f0; + border-radius: 0.25rem; + transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1) !important; + box-shadow: 0 1px 3px rgba(124, 124, 124, 0.12), 0 1px 2px rgba(124, 124, 124, 0.24) !important; + background-color: #14b7db !important; + color: white !important; +} +#mpi-button:hover { + background: #11a3c4 !important; +} + #header-meta { max-width: 100%; height: 24px;