diff --git a/biosimdb_interface/form/__init__.py b/biosimdb_interface/form/__init__.py index 9489b44..498f6e5 100644 --- a/biosimdb_interface/form/__init__.py +++ b/biosimdb_interface/form/__init__.py @@ -3,4 +3,4 @@ form_bp = Blueprint("form", __name__) -from . import extract, webform # noqa: E402, F401 +from . import extract, home, webform # noqa: E402, F401 diff --git a/biosimdb_interface/form/home.py b/biosimdb_interface/form/home.py new file mode 100644 index 0000000..f7f4e4a --- /dev/null +++ b/biosimdb_interface/form/home.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +""" +Home page for biosimdb-interface +""" + +from flask import ( + current_app, + render_template, + url_for, +) + +from . import form_bp + + +@form_bp.route("/", methods=["GET"]) +def home(): + """Landing page with BioSimDB overview and quick links.""" + return render_template( + "main/home.html", + links={ + "deposit": url_for("form.webform"), + "biosimdb": f"{current_app.config.get('BASE_URL', '').rstrip('/')}/communities/biosimdb", + "docs": "https://biosimdb-interface.readthedocs.io/", + "github": "https://github.com/CCPBioSim/biosimdb-interface", + "extract": "https://biosim-extractor.readthedocs.io/en/latest/", + "schema": "https://biosim-schema.readthedocs.io/en/latest/", + "aiida_gromacs": "https://aiida-gromacs.readthedocs.io/en/latest/", + "roadmap": "https://example.com/", + "zulip": "https://example.com/", + "policy": "https://data-collections.psdi.ac.uk/communities/biosimdb/curation-policy", + "instructions": "https://biosimdb-interface.readthedocs.io/en/latest/biosimdb_intro.html", + "tutorials": "https://biosimdb-interface.readthedocs.io/en/latest/biosimdb_intro.html", + }, + ) diff --git a/biosimdb_interface/schema/webform.py b/biosimdb_interface/schema/webform.py index 4e7a383..b6fef90 100644 --- a/biosimdb_interface/schema/webform.py +++ b/biosimdb_interface/schema/webform.py @@ -46,19 +46,31 @@ def get_simulation_metadata(): # ``simulation_metadata`` is loaded fresh on first access via get_simulation_metadata(). WEBFORM_SCHEMA = { "data": { - "title": "BioSim Data Extraction & Submission Form", + "title": "BioSim Deposition", "description": "This form automatically extracts useful data that describes a molecular dynamics simulation. Whenever you share your data, include this metadata with the simulation files to make your data more findable, accessible, interoperable and reuseable (FAIR).", - "guidance": { - "label": "Please Note:", - "options": [ - "To extract simulation metadata, please upload a topology and corresponding trajectory file/s. Optionally, upload an aiida archive file containing the simulation provenance, to extract further information about the simulation protocol.", - "Multiple trajectory files can be uploaded with a single associated topology file, both file types are required.", - 'Various simulation file formats are accepted and read using MDAnalysis, please ensure your files are compatible.', - 'This form uses the biosim-schema to define and group biosim metadata. Missing terms or units? Please considering raising an issue or contributing to the schema.', - 'Automatically add metadata associated with each entry using the "Extract metadata" button. Please fill in any missing metadata fields manually where applicable, click on each field name for further information about data field requirements.', - "Two options are available for your extracted simulation metadata:
  1. Download the simulation metadata as a json file and share alongside simulation files.
  2. Submit your simulation files and metadata in one step to BioSimDB, you will be directed to a login page and asked to authorize this application. Please continue and complete the data submission process in BioSimDB.
", - ], - }, + "guidance": [ + { + "label": "Instructions:", + "options": [ + "To extract simulation metadata, please upload a topology and corresponding trajectory file/s.", + # Optionally, upload an aiida archive file containing the simulation provenance, to extract further information about the simulation protocol.", + "Multiple trajectory files can be uploaded with a single associated topology file, both file types are required.", + 'Various simulation file formats are accepted and read using MDAnalysis, please ensure your files are compatible.', + 'This form uses the biosim-schema to define and group biosim metadata. Missing terms or units? Please consider raising an issue or contributing to the schema.', + 'Automatically add metadata associated with each entry using the "Extract metadata" button.', + "Please fill in any missing metadata fields manually where applicable, click on each field name for further information about data field requirements.", + "Two options are available for your extracted simulation metadata:
  1. Download the simulation metadata as a json file and share alongside simulation files.
  2. Submit your simulation files and metadata in one step to BioSimDB, you will be directed to a login page and asked to authorize this application. Please continue and complete the data submission process in BioSimDB.
", + "Clear all fields when uploading new files, as manually filled in fields are preserved unless cleared.", + ], + }, + { + "label": "Any Problems?", + "options": [ + "This deposition form is in active development, with new features being added, there may be a few bugs 🐞 that have crept in!", + 'If you experience any errors or warnings when using this form, please report them here.', + ], + }, + ], "repeatable": True, "max": 1, "files": { @@ -72,10 +84,12 @@ def get_simulation_metadata(): "multiple": True, "required": True, }, - "aiida": { - "label": "Upload AiiDA archive file", - "multiple": False, - }, + # Future option to include aiida archive files + # for extraction. + # "aiida": { + # "label": "Upload AiiDA archive file", + # "multiple": False, + # }, }, } } diff --git a/biosimdb_interface/static/images/logos/CCPBioSim-logo.png b/biosimdb_interface/static/images/logos/CCPBioSim-logo.png new file mode 100644 index 0000000..7707537 Binary files /dev/null and b/biosimdb_interface/static/images/logos/CCPBioSim-logo.png differ diff --git a/biosimdb_interface/static/images/logos/biosimdb-logo-black.png b/biosimdb_interface/static/images/logos/biosimdb-logo-black.png new file mode 100644 index 0000000..315ca6c Binary files /dev/null and b/biosimdb_interface/static/images/logos/biosimdb-logo-black.png differ diff --git a/biosimdb_interface/static/images/logos/biosimdb-logo-white.png b/biosimdb_interface/static/images/logos/biosimdb-logo-white.png new file mode 100644 index 0000000..013ad7c Binary files /dev/null and b/biosimdb_interface/static/images/logos/biosimdb-logo-white.png differ diff --git a/biosimdb_interface/static/images/logos/cosec-logo.png b/biosimdb_interface/static/images/logos/cosec-logo.png new file mode 100644 index 0000000..f46ec6f Binary files /dev/null and b/biosimdb_interface/static/images/logos/cosec-logo.png differ diff --git a/biosimdb_interface/static/images/logos/psdi-logo.png b/biosimdb_interface/static/images/logos/psdi-logo.png new file mode 100644 index 0000000..5513421 Binary files /dev/null and b/biosimdb_interface/static/images/logos/psdi-logo.png differ diff --git a/biosimdb_interface/static/js/form/metadata.js b/biosimdb_interface/static/js/form/metadata.js index 930ed40..f12967d 100644 --- a/biosimdb_interface/static/js/form/metadata.js +++ b/biosimdb_interface/static/js/form/metadata.js @@ -236,8 +236,14 @@ function renumberInstances(container) { const newIndex = index + 1; // Update header text - const header = instance.querySelector('h6'); - header.textContent = header.textContent.replace(/\d+/, newIndex); + const header = instance.querySelector('.biosimdb-subsection-title'); + const numberEl = instance.querySelector('.instance-number'); + + if (numberEl) { + numberEl.textContent = newIndex; + } else if (header) { + header.textContent = header.textContent.replace(/\d+$/, newIndex); + } // Update input names instance.querySelectorAll('input, select, textarea').forEach(input => { diff --git a/biosimdb_interface/static/styles/home.css b/biosimdb_interface/static/styles/home.css new file mode 100644 index 0000000..b316e48 --- /dev/null +++ b/biosimdb_interface/static/styles/home.css @@ -0,0 +1,300 @@ +/* ============================================================ + Home Page Layout Shell + ============================================================ */ + +.biosimdb-page { + background-color: var(--color-page-shell); +} + +.biosimdb-container { + max-width: 900px; +} + +.biosimdb-card { + overflow: hidden; + border: 0; + border-radius: 12px; + background-color: var(--color-surface); + box-shadow: var(--shadow-card); +} + +/* ============================================================ + Header + Hero + ============================================================ */ + +.biosimdb-header { + padding: 22px 35px; + background-color: var(--color-brand-dark); + color: var(--color-text-on-dark); +} + +.biosimdb-header-label { + margin: 0; + font-size: 0.85rem; + font-weight: 700; + letter-spacing: 0.15rem; + text-transform: uppercase; +} + +.biosimdb-hero { + padding: 50px 55px 15px; +} + +.biosimdb-hero-header { + display: flex; + align-items: center; + justify-content: center; + gap: 1.5rem; +} + +.biosimdb-logo-container { + flex-shrink: 0; +} + +.biosimdb-logo { + width: 120px; + height: auto; + display: block; +} + +.biosimdb-title-container { + text-align: left; +} + +.biosimdb-eyebrow { + margin-bottom: 12px; + color: var(--color-brand); + font-size: 0.9rem; + font-weight: 700; + letter-spacing: 0.1rem; + text-transform: uppercase; +} + +.biosimdb-title { + margin: 0 0 20px; + color: var(--color-text-main) !important; + font-size: clamp(2.2rem, 5vw, 3.4rem); + font-weight: 700; + line-height: 1.1; +} + +.biosimdb-lead { + max-width: 720px; + margin: 2rem auto 0; + color: var(--color-text-muted); + font-size: 1.2rem; + line-height: 1.65; +} + +/* ============================================================ + CTA Actions + ============================================================ */ + +.biosimdb-actions { + padding: 0 55px 40px; +} + +.biosimdb-primary-btn { + padding: 12px 25px; + background-color: var(--color-brand); + border-color: var(--color-brand); + border-radius: 5px; + font-weight: 700; +} + +.biosimdb-primary-btn:hover { + background-color: var(--color-brand-hover); + border-color: var(--color-brand-hover); +} + +.biosimdb-secondary-btn { + padding: 12px 25px; + border-radius: 5px; + font-weight: 600; +} + +/* ============================================================ + Information + Feature Cards + ============================================================ */ + +.biosimdb-details { + margin: 0 55px 40px; + padding: 22px 25px; + background-color: var(--color-info-bg); + border-left: 4px solid var(--color-brand); + border-radius: 2px; +} + +.biosimdb-details h2 { + margin-bottom: 12px; + color: var(--color-text-main); + font-size: 1.25rem; +} + +.biosimdb-details p { + margin: 0; + color: var(--color-text-muted); + line-height: 1.6; +} + +.biosimdb-divider { + height: 1px; + margin: 0 55px; + background-color: var(--color-divider); +} + +.biosimdb-features { + padding: 35px 45px 45px; +} + +.biosimdb-section-title { + margin-bottom: 25px; + color: var(--color-text-main); + font-size: 1.6rem; + font-weight: 700; + text-align: center; +} + +.biosimdb-feature { + height: 100%; + padding: 25px 20px; + background-color: var(--color-surface-muted); + border: 1px solid var(--color-border-subtle); + border-radius: 6px; + text-align: center; +} + +.biosimdb-feature h3 { + margin-bottom: 10px; + color: var(--color-text-main); + font-size: 1.05rem; + font-weight: 700; +} + +.biosimdb-feature p { + margin: 0; + color: var(--color-text-soft); + font-size: 0.9rem; + line-height: 1.55; +} + +.biosimdb-feature-link { + text-decoration: none; + color: inherit; +} + +.biosimdb-feature-link h3 { + display: inline-flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.75rem; + transition: color 0.2s ease; +} + +.biosimdb-feature-link:hover h3 { + color: var(--color-brand); +} + +/* ============================================================ + Footer + ============================================================ */ + +.biosimdb-footer { + padding: 30px 40px; + background-color: var(--color-surface); + text-align: center; +} + +.biosimdb-footer p { + margin-bottom: 15px; + color: var(--color-text-soft); + font-size: 0.9rem; +} + +.biosimdb-footer-links { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 20px; +} + +.biosimdb-footer-links a { + color: var(--color-brand); + font-size: 0.9rem; + text-decoration: none; +} + +.biosimdb-footer-links a:hover { + text-decoration: underline; +} + +.biosimdb-footer-title { + margin-top: 50px; + margin-bottom: 20px; + color: var(--color-text-main); + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.12rem; + text-transform: uppercase; +} + +.biosimdb-sponsors { + display: flex; + align-items: center; + justify-content: center; + gap: 40px; + flex-wrap: wrap; +} + +.biosimdb-sponsors a { + display: flex; + align-items: center; + justify-content: center; + min-width: 120px; + height: 55px; +} + +.biosimdb-sponsors img { + display: block; + max-width: 200px; + max-height: 100px; + width: auto; + height: auto; + object-fit: contain; +} + +/* ============================================================ + Responsive Overrides + ============================================================ */ + +@media (max-width: 767px) { + .biosimdb-hero { + padding: 35px 25px 25px; + } + + .biosimdb-actions { + padding: 0 25px 30px; + } + + .biosimdb-details { + margin-left: 25px; + margin-right: 25px; + } + + .biosimdb-divider { + margin-left: 25px; + margin-right: 25px; + } + + .biosimdb-features { + padding: 30px 25px 35px; + } + + .biosimdb-footer { + padding: 25px; + } + + .biosimdb-actions .btn { + width: 100%; + } +} diff --git a/biosimdb_interface/static/styles/styles.css b/biosimdb_interface/static/styles/styles.css index 0fc82ab..c3f1784 100644 --- a/biosimdb_interface/static/styles/styles.css +++ b/biosimdb_interface/static/styles/styles.css @@ -1,114 +1,96 @@ -/* Variables */ -:root { - --background-color: rgb(7, 64, 121); - --bg-light: #f8f9fa; - --psdi-color: #041e42; - --hover-color: #0154c92b; - --link-color: #b369fd; - --highlight-color: #e2fffeb2; - --hide-color: #ffd0c59c; - --text-color: black; - --ref-color: #236efa; - --font-family: monospace; - --font-size-large: 11pt; - --font-size-main: 10pt; -} - -body { - background-color: var(--bg-light); - color: var(--text-color); -} - -h3, h1, th, b { - /*color: var(--psdi-color) !important;*/ - color: var(--text-color) !important; -} - -/* -.navbar { - background-color: var(--link-color); -} -*/ - - -#highlight { - background-color: var(--bg-light); -} - - -/* Add colour to asterisks in web form */ -.required { - color: #B94A48; - } +/* ============================================================ + BioSimDB Theme Tokens + - Keep all shared color decisions in one place. + - home.css and webform.css consume these variables. + ============================================================ */ -/* Allow rows of table to be clicakble */ -.clickable:hover { - background: var(--hover-color); - cursor: pointer; +:root { + /* Core palette */ + --color-brand-dark: #17324d; + --color-brand: #2878b5; + --color-brand-hover: #1f6498; + --color-brand-soft: #5387b0; + --color-link: #b369fd; + + /* Surfaces and borders */ + --color-page-bg: #f8f9fa; + --color-page-shell: #f2f4f7; + --color-surface: #ffffff; + --color-surface-muted: #f7f8fa; + --color-info-bg: #f2f7fb; + --color-border-subtle: #edf0f3; + --color-border-soft: #dfe5ea; + --color-border-field: #d9dee5; + --color-divider: #e5e7eb; + + /* Text and state */ + --color-text-main: #17324d; + --color-text-muted: #4b5563; + --color-text-soft: #6b7280; + --color-text-on-dark: #ffffff; + --color-text-on-dark-muted: hsla(0, 0%, 100%, 0.85); + --color-placeholder: #adb5bd; + --color-hover-overlay: #0154c92b; + + /* Guidance block */ + --color-guidance-bg: #e8f4fd; + --color-guidance-border: #b8d9f0; + --color-guidance-text: #1a3a5c; + + /* Effects */ + --shadow-card: 0 4px 18px rgba(0, 0, 0, 0.08); + --shadow-panel: 0 2px 8px rgba(0, 0, 0, 0.04); + --focus-ring: 0 0 0 0.2rem rgba(40, 120, 181, 0.15); + + /* Typography */ + --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + + /* Backward-compat alias consumed by Joomla head partial */ + --link-color: var(--color-link); } +/* ============================================================ + Base Document Styling + ============================================================ */ -/* Truncate text over multiple lines */ -.multi-line { - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - overflow: hidden; +body { + background-color: var(--color-page-bg); + color: var(--color-text-main); + font-family: var(--bs-font-sans-serif) !important; } -.trunc { - width: 10%; +h6, h5, h4, h3, h2, h1, th, b { + color: var(--color-text-main) !important; + font-family: var(--bs-font-sans-serif); } +/* ============================================================ + Shared Utility Styling + ============================================================ */ -th, td { +th, +td { padding-top: 5px; - /* padding-bottom: 1%; - padding-left: 3%; - padding-right: 4%; */ } - .page-item.active .page-link { - color: #fff !important; - background: var(--hover-color) !important; - border: var(--hover-color) !important; - } - - - .scrollx { - height: 40px; - max-width: 500px; - overflow-x: scroll; - white-space: nowrap; - } - - .spinner { - display: inline-block; - width: 12px; - height: 12px; - border: 2px solid #f3f3f3; - border-top: 2px solid #3498db; - border-radius: 50%; - animation: spin 1s linear infinite; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + color: var(--color-text-on-dark) !important; + background: var(--color-hover-overlay) !important; + border: var(--color-hover-overlay) !important; } input::placeholder, textarea::placeholder { - color: #adb5bd !important; /* Bootstrap gray-300 */ + color: var(--color-placeholder) !important; opacity: 1; font-style: italic; } .guidance-box { - background-color: #e8f4fd; - border: 1px solid #b8d9f0; - border-radius: 0.375rem; /* matches Bootstrap's default */ - color: #1a3a5c; + background-color: var(--color-guidance-bg); + border: 1px solid var(--color-guidance-border); + border-radius: 0.375rem; + color: var(--color-guidance-text); padding: 1rem; } diff --git a/biosimdb_interface/static/styles/webform.css b/biosimdb_interface/static/styles/webform.css new file mode 100644 index 0000000..159d480 --- /dev/null +++ b/biosimdb_interface/static/styles/webform.css @@ -0,0 +1,185 @@ + +/* ============================================================ + Webform Card + Buttons + ============================================================ */ + +.biosimdb-form-card { + overflow: hidden; + border: 0; + border-radius: 12px; + background-color: var(--color-surface); + box-shadow: var(--shadow-card); +} + +.biosimdb-btn { + border-radius: 5px; + font-weight: 600; +} + +.biosimdb-btn-primary { + background-color: var(--color-brand); + border-color: var(--color-brand); +} + +.biosimdb-btn-primary:hover { + background-color: var(--color-brand-hover); + border-color: var(--color-brand-hover); +} + +/* match thickness of header in home.html */ +.biosimdb-form-card > .biosimdb-header { + padding: 17px 35px; +} + +/* ============================================================ + Stage Sections + ============================================================ */ + +.biosimdb-stage { + margin-bottom: 28px; + overflow: hidden; + border: 1px solid var(--color-border-soft); + border-radius: 9px; + background-color: var(--color-surface); + box-shadow: var(--shadow-panel); +} + +.biosimdb-stage-header { + display: flex; + align-items: center; + gap: 15px; + padding: 18px 25px; + background-color: var(--color-brand-dark); + color: var(--color-text-on-dark); +} + +.biosimdb-stage-number { + display: flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + width: 36px; + height: 36px; + border-radius: 50%; + background-color: var(--color-brand-soft); + color: var(--color-text-on-dark); + font-size: 0.9rem; + font-weight: 700; +} + +.biosimdb-stage-title { + margin: 0; + font-size: 1.25rem; + font-weight: 700; +} + +.biosimdb-stage-hint { + margin: 3px 0 0; + color: var(--color-text-on-dark-muted); + font-size: 0.85rem; +} + +.biosimdb-stage-body { + padding: 28px; +} + +/* ============================================================ + Metadata Accordion Sections + ============================================================ */ + +.biosimdb-metadata-header .accordion-button { + background: transparent; + color: var(--color-text-on-dark); + box-shadow: none; +} + +.biosimdb-metadata-header .accordion-button::after { + filter: brightness(0) invert(1); +} + +.biosimdb-metadata-header .accordion-button:not(.collapsed) { + box-shadow: none; +} + +.biosimdb-section { + margin-bottom: 28px; + overflow: hidden; + border: 1px solid var(--color-border-soft); + border-radius: 9px; + background-color: var(--color-surface); + box-shadow: var(--shadow-panel); +} + +.biosimdb-section-header { + padding: 18px 25px; + background-color: var(--color-brand); + color: var(--color-text-on-dark); +} + +.biosimdb-section-title { + margin: 0; + font-size: 1.2rem; + font-weight: 700; + text-align: left; + color: var(--color-text-on-dark) !important; +} + +.biosimdb-section-hint { + margin: 4px 0 0; + color: var(--color-text-on-dark-muted); + font-size: 0.85rem; +} + +.biosimdb-section-body { + padding: 28px; +} + +.biosimdb-guidance { + margin-bottom: 25px; + padding: 18px 20px; + background-color: var(--color-info-bg); + border-left: 4px solid var(--color-brand); + border-radius: 2px; + color: var(--color-text-muted); +} + +/* ============================================================ + Form Controls + ============================================================ */ + +.biosimdb-form-card .form-label { + color: var(--color-text-main); + font-weight: 600; +} + +.biosimdb-form-card .form-control, +.biosimdb-form-card .form-select { + border-color: var(--color-border-field); + border-radius: 5px; +} + +.biosimdb-form-card .form-control:focus, +.biosimdb-form-card .form-select:focus { + border-color: var(--color-brand); + box-shadow: var(--focus-ring); +} + +.biosimdb-form-card .form-text { + color: var(--color-text-soft); +} + +/* ============================================================ + Responsive Overrides + ============================================================ */ + +@media (max-width: 767px) { + .biosimdb-stage-body, + .biosimdb-section-body { + padding: 22px; + } + + .biosimdb-stage-header, + .biosimdb-section-header { + padding: 17px 20px; + } +} diff --git a/biosimdb_interface/templates/form/webform.html b/biosimdb_interface/templates/form/webform.html index 4867061..d4e6c86 100644 --- a/biosimdb_interface/templates/form/webform.html +++ b/biosimdb_interface/templates/form/webform.html @@ -2,100 +2,381 @@ webform.html Main simulation metadata extraction and submission form. - Extends: main/base.html - Macros: macros/webform.html (render_fields, render_files, render_metadata, - render_simulation_metadata, render_guidance, render_simulation_modal) - - Context variables: - schema (dict): Ordered dict of form sections, each containing: - title (str), description (str), guidance (str, optional), - files, fields, metadata, simulation_metadata (optional subsections) - BASE_URL (str): Base URL of the BioSimDB instance, used for the community link. - session (dict): Flask session; checked for 'access_token' to show login/logout button. - - Behaviour: - - Renders one card per schema section with file uploads, fields, and metadata subsections. - - Save button (name="save") triggers a JSON dry-run via fetch and downloads metadata as JSON. - - Submit button (name="submit") validates then posts to BioSimDB; redirects to login if needed. - - Form state and extracted metadata are persisted in sessionStorage via metadata.js. - - Fields are disabled until metadata is extracted; Bootstrap popovers explain this on click. + The BioSimDB schema contains a special top-level "stages" class. + Its child classes are the actual simulation stages: + + setup + minimisation + equilibration + production + analysis + + Other top-level schema classes (settings, topology, composition, + potentials, compute, etc.) are rendered as normal metadata sections. #} + {% extends "main/base.html" %} -{% from "macros/webform.html" import render_fields, render_files, render_metadata, render_simulation_metadata, render_guidance, render_simulation_modal with context %} +{% from "macros/webform.html" import + render_fields, + render_files, + render_metadata, + render_simulation_metadata, + render_guidance + with context +%} {% block content %} + + -
-
-
- BioSimDB ↗ - - {% if session.get('access_token') %} - Log out - {% if session.get('user_email') %} - {{ session.get('user_email') }} - {% endif %} - - {% else %} - Log in - {% endif %} -
+
- {% for section_key, section in schema.items() %} -
+
-
- -
{{ section.title }}
-
+ + +
+ + + + +
+ + + BioSimDB ↗ + + + +
+ + {% if session.get('access_token') %} + + + Log out + {% if session.get('user_email') %} + {{ session.get('user_email') }} + {% endif %} + + + {% else %} -
-

{{ section.description }}

+ + Log in + - {% if section.guidance %} - {{ render_guidance(section.guidance) }} {% endif %} -
- {% if section.files %} - {{ render_files(section.files) }} - {% endif %} - {% if section.fields %} - {{ render_fields(section.fields, section_key) }} - {% endif %} - {% if section.metadata %} - {{ render_metadata(section.metadata) }} - {% endif %} - {% if section.simulation_metadata %} - {{ render_simulation_metadata(section.simulation_metadata) }} - {% endif %} +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ +
+ Biomolecular Simulation Database
+ +

+ BioSimDB +

+
+
- {% endfor %} +
+ +
+ + + + +
+ + + {# + ===================================================== + STAGES + + The schema explicitly defines: + + stages + ├── setup + ├── minimisation + ├── equilibration + ├── production + └── analysis + + These are the numbered stages. + ===================================================== + #} + + {% if schema.get('stages') %} + + {% set stages = schema['stages'] %} + + {% if stages.fields %} + + {% for stage_key, stage in stages.fields.items() %} + +
+ + + +
+ +
+ {{ loop.index }} +
+ +
+ +

+ {{ stage.label or stage_key | replace('_', ' ') | title }} +

+ + {% if stage.hint %} +

+ {{ stage.hint }} +

+ {% endif %} + +
+ +
+ + + + +
+ + {% if stage.fields %} + + {{ render_fields( + stage.fields, + 'stages[' ~ stage_key ~ ']' + ) }} + + {% endif %} + +
+ +
+ + {% endfor %} + + {% endif %} + + {% endif %} + + + {# + ===================================================== + OTHER TOP-LEVEL SCHEMA CLASSES + + These are NOT simulation stages. + + Examples from the schema include: + + settings + observables + topology + composition + potentials + compute + + They therefore receive normal section headings, + without stage numbers. + ===================================================== + #} + + {% for section_key, section in schema.items() %} + + {% if section_key != 'stages' %} + +
+ + + + +
+ +

+ {{ section.label + or section.title + or section_key | replace('_', ' ') | title }} +

+ + {% if section.hint %} + +

+ {{ section.hint }} +

+ + {% elif section.description %} + +

+ {{ section.description }} +

+ + {% endif %} + +
+ + + + +
+ + + {% if section.guidance %} + +
+ + {{ render_guidance(section.guidance) }} + +
+ + {% endif %} + + +
+ + + {% if section.files %} + + {{ render_files(section.files) }} + + {% endif %} + + + {% if section.fields %} + + {{ render_fields( + section.fields, + section_key + ) }} + + {% endif %} + + + {% if section.metadata %} + + {{ render_metadata( + section.metadata + ) }} + + {% endif %} + + + {% if section.simulation_metadata %} + + {{ render_simulation_metadata( + section.simulation_metadata + ) }} + + {% endif %} + + +
+ +
+ +
+ + {% endif %} + + {% endfor %} + - - + + + +
+
{% endblock %} + {% block scripts %} + {{ super() }} - - + + + + {% endblock %} diff --git a/biosimdb_interface/templates/macros/webform.html b/biosimdb_interface/templates/macros/webform.html index 562d9ad..ad3599f 100644 --- a/biosimdb_interface/templates/macros/webform.html +++ b/biosimdb_interface/templates/macros/webform.html @@ -4,7 +4,7 @@ Extends: main/base.html Macros: macros/webform.html (render_fields, render_files, render_metadata, - render_simulation_metadata, render_guidance, render_simulation_modal) + render_simulation_metadata, render_guidance) Context variables: schema (dict): Ordered dict of form sections, each containing: @@ -57,7 +57,7 @@ {% if field.type == "textarea" %} {% set col_class = "col-12" %} {% elif field.type == "checkbox" %} - {% set col_class = "col-md-4 col-lg-3" %} + {% set col_class = "col-md-4 col-lg-4" %} {% elif field.fields %} {% set col_class = "col-12" %} {% else %} @@ -170,15 +170,19 @@ Args: field (dict): Field definition with `label` (str) and `options` (list of str). #} -{% macro render_guidance(field) %} -
- {{ field.label }} -
    - {% for opt in field.options %} -
  • {{ opt | safe }}
  • - {% endfor %} -
-
+{% macro render_guidance(guidance) %} + + {% for field in guidance %} +
+ {{ field.label }} +
    + {% for opt in field.options %} +
  • {{ opt | safe }}
  • + {% endfor %} +
+
+ {% endfor %} + {% endmacro %} {# @@ -192,7 +196,7 @@
{% for file_key, file in files.items() %} -
+
each with a `label` and `fields` dict. #} {% macro render_simulation_metadata(simulation_metadata) %} -