Skip to content

Commit

Permalink
Convert modals to use HTML dialog element (#808)
Browse files Browse the repository at this point in the history
* WIP: convert modal

* Convert error modal, sequence modal using dialog & fix styling

* Update modal styles: sequence, error, cloud share

* Fix jest test on cloud modal

* convert modal: advanced option

* Update advanced close modal & fix sequence modal rspec

* WIP: Fix tooltip on sequence viewer

* WIP - fix tootlip position, still needs perfecting

* Fix tooltip position & selecting bases into one line

* Fix compiled js style

---------

Co-authored-by: Tadas Tamosauskas <tadastamo@gmail.com>
  • Loading branch information
3lviend and tadast authored Oct 21, 2024
1 parent 7353a36 commit 14a8936
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 143 deletions.
5 changes: 5 additions & 0 deletions public/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ pre.indL {
transform: rotate(270deg);
}

/* Modal */
::backdrop {
@apply fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity;
}

/**
* See:
* http://stackoverflow.com/questions/11002820/why-should-we-include-ttf-eot-woff-svg-in-a-font-face
Expand Down
2 changes: 1 addition & 1 deletion public/css/app.min.css

Large diffs are not rendered by default.

103 changes: 48 additions & 55 deletions public/js/cloud_share_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,19 @@ export default class CloudShareModal extends React.Component {
return match ? match[1] : match;
}

show = () => {
this.modalRef.current?.showModal();
document.body.classList.add("overflow-hidden");
}

hide = () => {
this.modalRef.current?.close();
document.body.classList.remove("overflow-hidden");
}

renderLoading() {
return (
<div className="text-center">
<div className="text-center pt-3">
<i className="fa fa-spinner fa-3x fa-spin"></i>
<p className="my-3">Uploading the job to SequenceServer Cloud, please wait...</p>
</div>
Expand Down Expand Up @@ -118,7 +128,7 @@ export default class CloudShareModal extends React.Component {

return(
<form onSubmit={this.handleSubmit}>
<div className="px-6 mb-3">
<div className="px-6 py-4 text-sm">
<label htmlFor="emailInput" className="text-seqblue hover:text-orange cursor-pointer mb-0">Your Email Address</label>
<input
type="email"
Expand All @@ -130,33 +140,33 @@ export default class CloudShareModal extends React.Component {
required="required"
onChange={this.handleChange}
/>
<p>
<p className="mb-3">
By submitting this form you agree to upload this SequenceServer result set to <a href="https://sequenceserver.com/cloud/" target="_bank" className="text-seqblue hover:text-seqorange">SenquenceServer Cloud</a>
, where it will become available on the internet to everyone with the link. You also agree that your email address will be stored on SequenceServer databases as proof of authentication for support and similar purposes.
</p>
</div>
<div className="form-check px-6 mb-3">
<input
type="checkbox"
id="tosCheckbox"
className="form-check-input"
name="agreeToTos"
checked={agreeToTos}
onChange={this.handleChange}
/>
<label htmlFor="tosCheckbox" className="pl-2">
&nbsp;I agree to the <b><a href="https://sequenceserver.com/cloud/terms_and_conditions" target="_blank" className="text-seqblue hover:text-seqorange">Terms and Conditions of Service</a></b>
</label>
<div className="form-check">
<input
type="checkbox"
id="tosCheckbox"
className="form-check-input"
name="agreeToTos"
checked={agreeToTos}
onChange={this.handleChange}
/>
<label htmlFor="tosCheckbox" className="pl-2">
&nbsp;I agree to the <b><a href="https://sequenceserver.com/cloud/terms_and_conditions" target="_blank" className="text-seqblue hover:text-seqorange">Terms and Conditions of Service</a></b>
</label>
</div>
</div>
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button
type="submit"
style={{ backgroundColor: isSubmitDisabled ? '#C74F13' : '#1B557A' }}
className='border-seqblue py-2 px-3 rounded-md text-white'
disabled={isSubmitDisabled}
>
Submit
</button>
<button
type="submit"
style={{ backgroundColor: isSubmitDisabled ? '#C74F13' : '#1B557A' }}
className='border-seqblue py-2 px-3 rounded-md text-white'
disabled={isSubmitDisabled}
>
Submit
</button>
</div>
</form>
)
Expand All @@ -183,40 +193,23 @@ export default class CloudShareModal extends React.Component {
}

return (
<div className={`relative modal z-10 ${isModalVisible ? '' : 'hidden'}`} ref={this.modalRef} tabIndex="-1" role="dialog" aria-modal="true">
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<div className="fixed inset-0 z-10 w-screen overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
<div className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 w-full md:max-w-2xl">
<div className="bg-white pt-5">
<div className="flex justify-between px-6 mb-4">
<h3 className="text-base font-semibold leading-6 text-gray-900">Share to SequenceServer Cloud</h3>
<span className="cursor-pointer" onClick={() => this.hide()}>
<i className="fa-solid fa-xmark align-bottom"></i>
</span>
</div>
<div className="modal-content pt-6 mt-2 text-sm">
{content}
</div>
</div>
<div className="relative">
<dialog ref={this.modalRef} className="fixed p-4 w-full max-w-2xl bg-transparent focus:outline-none">
<div className="relative flex flex-col rounded-lg bg-white shadow">
<div className="flex items-start justify-between rounded-t border-b p-5">
<h3 className="text-xl font-medium text-gray-900">
Share to SequenceServer Cloud
</h3>
<button className="ml-auto inline-flex items-center rounded-lg bg-transparent p-1.5 text-sm text-gray-400 hover:bg-gray-200" onClick={this.hide}>
<i className="fa-solid fa-xmark hover:text-black"></i>
</button>
</div>
<div className="dialog-content">
{content}
</div>
</div>
</div>
</dialog>
</div>
);
}

/**
* show modal
*/
show() {
this.setState({ isModalVisible: true });
}

/**
* Hide modal.
*/
hide() {
this.setState({ isModalVisible: false });
}
}
47 changes: 24 additions & 23 deletions public/js/error_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,50 @@ export default class ErrorModal extends React.Component {
const { isModalVisible, errorData } = this.state;

return (
<div id="error" ref={this.modal} className={`relative modal z-10 ${isModalVisible ? '' : 'hidden'}`} role="dialog" aria-modal="true">
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<div className="fixed inset-0 z-10 w-screen overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
<div className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 w-full md:max-w-3xl">
<div className="bg-white pt-5">
<div className="flex justify-between px-6 mb-4">
<h3 className="text-base font-semibold leading-6 text-gray-900">{errorData.title}</h3>
<span className="cursor-pointer" onClick={() => this.hide()}><i className="fa-solid fa-xmark align-bottom"></i></span>
</div>
<div className="pt-2 px-6 pb-6 mt-2 text-sm">
<p dangerouslySetInnerHTML={{ __html: errorData.message }} className="mb-4"></p>
{
errorData.more_info &&
<pre className="p-2 bg-slate-200 overflow-auto max-h-56">{errorData.more_info}</pre>
}
</div>
</div>
<div className="relative">
<dialog ref={this.modal} className="fixed p-4 w-full max-w-2xl bg-transparent focus:outline-none">
<div className="relative flex flex-col rounded-lg bg-white shadow">
<div className="flex items-start justify-between rounded-t border-b p-5">
<h3 className="text-xl font-medium text-gray-900">
{errorData.title}
</h3>
<button className="ml-auto inline-flex items-center rounded-lg bg-transparent p-1.5 text-gray-400 hover:bg-gray-200" onClick={this.hide}>
<i className="fa-solid fa-xmark hover:text-black"></i>
</button>
</div>
<div className="pt-2 px-6 pb-6 mt-2 text-sm">
<p dangerouslySetInnerHTML={{ __html: errorData.message }} className="mb-4"></p>
{
errorData.more_info &&
<pre className="p-2 bg-slate-200 overflow-auto max-h-56">{errorData.more_info}</pre>
}
</div>
</div>
</div>
</dialog>
</div>
);
}

/**
* Shows error viewer.
*/
show(errorData, beforeShow) {
show = (errorData, beforeShow) => {
this.setState({ errorData: errorData });

// Caller can specify an amount of time to wait for before showing the
// modal. This is helpful if the caller wants to finish some work
// before showing error modal.
setTimeout(() => {
this.setState({ isModalVisible: true });
this.modal.current?.showModal();
document.body.classList.add("overflow-hidden");
}, beforeShow || 0);
}

/**
* Hide dialogue.
*/
hide() {
this.setState({ isModalVisible: false });
hide = () => {
this.modal.current?.close();
document.body.classList.remove("overflow-hidden");
}
}
8 changes: 6 additions & 2 deletions public/js/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,19 @@ export class Options extends Component {
showAdvancedOptionsHelp(e) {
const ids = ['blastn', 'tblastn', 'blastp', 'blastx', 'tblastx'];
const method = this.props.blastMethod.toLowerCase();
const modal = document.querySelector("dialog.advanced-modal");

// hide options for other algorithms and only show for selected algorithm
for (const id of ids) {
if (id === method) {
document.getElementById(id).classList.remove('hidden')
document.getElementById(id).classList.remove('hidden');
} else {
document.getElementById(id).classList.add('hidden');
}
}
document.querySelector('[data-help-modal]').classList.remove('hidden')

modal.showModal();
document.body.classList.add("overflow-hidden");
}

render() {
Expand Down
6 changes: 4 additions & 2 deletions public/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ const root = createRoot(document.getElementById('view'));
root.render(<Page />);

document.addEventListener('DOMContentLoaded', () => {
const closeButton = document.querySelector('.js--close-help');
const closeButton = document.querySelector('button.advanced-modal-close');
const modal = document.querySelector('dialog.advanced-modal')
if (closeButton) {
closeButton.addEventListener('click', function() {
document.querySelector('[data-help-modal]').classList.add('hidden');
modal.close();
document.body.classList.add("overflow-hidden");
});
}
});
22 changes: 9 additions & 13 deletions public/js/sequence.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,9 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
//Initialize tooltip
var tooltip = 'sequenceTip' + this.opt.target;
jQuery('<div id="' + tooltip + '"></div>')
.css({
'position': 'absolute',
'z-index': '999999',
'color': '#fff',
'font-size': '12px',
'width': 'auto',
'display': 'none'
})
.addClass('tooltip')
.appendTo('body')
.hide();
.appendTo('.fastan-content')
.addClass('absolute top-0 left-0')
.show()
this.opt._tooltip = document.getElementById(tooltip);

if ((this.opt.sequence)) {
Expand Down Expand Up @@ -1328,14 +1320,18 @@ require = (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { va
jQuery(target).mouseover(function (e) {

var offset = jQuery(e.target).offset();
var containerOffset = jQuery(e.target).closest('.seqF').offset();

if (!jQuery(tipId).is(':visible')) {
jQuery(tipId)
.css({
'background-color': '#000',
'padding': '3px 10px 3px 10px',
'top': offset.top + jQuery(e.target).height() + 'px',
'left': offset.left + jQuery(e.target).width() + 'px'
'top': offset.top - containerOffset.top + jQuery(e.target).height() + 15 + 'px',
'left': offset.left - containerOffset.left + jQuery(e.target).width() + 70 + 'px',
'color': '#fff',
'font-size': '12px',
'position': 'absolute'
})
.animate({ opacity: '0.85' }, 10)
.html(cbGetMessageFunction.call(target))
Expand Down
Loading

0 comments on commit 14a8936

Please sign in to comment.