Commit c7eb4d66 authored by vertighel's avatar vertighel
Browse files

Synoptic: embed as reusable panel in control and init tabs



- Add macros/sections/synoptic_panel.html macro (svg-container div)
- synoptic.js: fix animateBeams (remove undeclared beamPho reference);
  add shown.bs.tab listener for lazy geometry re-init when panel is hidden at load
- control.html: add Synoptic tab to right-column monitor card
- init.html: convert right column to tabbed card (Webcam + Synoptic)

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent f1afbc37
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
{% import "macros/widgets.html" as w %}
{% import "macros/sections/control_panel.html" as ctrl %}
{% import "macros/sections/webcam_panel.html" as webcam %}
{% import "macros/sections/synoptic_panel.html" as synoptic %}

{% block content %}
<div class="row g-3">
@@ -50,6 +51,7 @@
                <ul class="nav nav-tabs border-0" role="tablist">
                    <li class="nav-item"><button class="nav-link active py-2" data-bs-toggle="tab" data-bs-target="#mon-fits">FITS Viewer</button></li>
                    <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-webcam">Webcam</button></li>
                    <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-synoptic">Synoptic</button></li>
                    <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#mon-output">Output</button></li>
                </ul>
                <small class="text-muted px-3" id="active-station-id">STATION 1</small>
@@ -63,6 +65,9 @@
                    <div class="tab-pane fade" id="mon-webcam">
                        {{ webcam.webcam_panel() }}
                    </div>
                    <div class="tab-pane fade" id="mon-synoptic">
                        {{ synoptic.synoptic_panel() }}
                    </div>
                    <div class="tab-pane fade" id="mon-output">
                         <div id="sequencer-output-display" class="p-3 text-info font-monospace small">
                             Waiting for output data...
@@ -79,8 +84,9 @@
{% endblock %}

{% block scripts %}
    <!-- Include the viewer as a module -->
    <script type="module" src="{{ url_for('web.static', filename='js/control.js') }}"></script>
    <script src="{{ url_for('web.static', filename='js/webcam.js') }}"></script>
    <script>window.SYNOPTIC_SVG_URL = "{{ url_for('web.static', filename='img/synoptic.svg') }}";</script>
    <script type="module" src="{{ url_for('web.static', filename='js/synoptic.js') }}"></script>
{% endblock %}
    
+20 −2
Original line number Diff line number Diff line
{% extends "base.html" %}
{% import "macros/widgets.html" as w %}
{% import "macros/sections/webcam_panel.html" as webcam %}
{% import "macros/sections/synoptic_panel.html" as synoptic %}

{% block content %}
<div class="row g-3">
@@ -219,9 +220,24 @@

    </section>

    {# ── RIGHT: Webcam ── #}
    {# ── RIGHT: Webcam + Synoptic ── #}
    <section class="col-xl-4 col-lg-12">
        <div class="card bg-dark border-secondary shadow-sm">
            <div class="card-header p-0 border-secondary">
                <ul class="nav nav-tabs border-0" role="tablist">
                    <li class="nav-item"><button class="nav-link active py-2" data-bs-toggle="tab" data-bs-target="#init-webcam">Webcam</button></li>
                    <li class="nav-item"><button class="nav-link py-2" data-bs-toggle="tab" data-bs-target="#init-synoptic">Synoptic</button></li>
                </ul>
            </div>
            <div class="tab-content">
                <div class="tab-pane fade show active" id="init-webcam">
                    {{ webcam.webcam_panel() }}
                </div>
                <div class="tab-pane fade" id="init-synoptic">
                    {{ synoptic.synoptic_panel() }}
                </div>
            </div>
        </div>
    </section>

</div>
@@ -229,4 +245,6 @@

{% block scripts %}
<script src="{{ url_for('web.static', filename='js/webcam.js') }}"></script>
<script>window.SYNOPTIC_SVG_URL = "{{ url_for('web.static', filename='img/synoptic.svg') }}";</script>
<script type="module" src="{{ url_for('web.static', filename='js/synoptic.js') }}"></script>
{% endblock %}
+16 −0
Original line number Diff line number Diff line
{#
    sections/synoptic_panel.html
    ----------------------------
    Reusable synoptic SVG panel.
    Pages that include this macro must add to their scripts block:
      <script>window.SYNOPTIC_SVG_URL = "{{ url_for('web.static', filename='img/synoptic.svg') }}";</script>
      <script type="module" src="{{ url_for('web.static', filename='js/synoptic.js') }}"></script>
#}

{% macro synoptic_panel() %}
<div class="bg-black rounded d-flex justify-content-center align-items-start p-2">
    <div id="svg-container" style="width: 100%; height: auto;">
        <!-- SVG loaded by synoptic.js -->
    </div>
</div>
{% endmacro %}
+16 −20
Original line number Diff line number Diff line
@@ -23,15 +23,15 @@
   inkscape:pageopacity="0.0"
   inkscape:pagecheckerboard="0"
   inkscape:deskcolor="#d1d1d1"
   inkscape:zoom="7.9"
   inkscape:cx="206.26582"
   inkscape:cy="202.65823"
   inkscape:zoom="2.2114286"
   inkscape:cx="350"
   inkscape:cy="257.75194"
   inkscape:window-width="2511"
   inkscape:window-height="1371"
   inkscape:window-x="0"
   inkscape:window-y="0"
   inkscape:window-maximized="1"
   inkscape:current-layer="stage"
   inkscape:current-layer="noctua-synoptic"
   inkscape:pageshadow="2"
   showgrid="false" /><defs
   id="defs2">
@@ -284,8 +284,9 @@
   inkscape:label="dom"
   data-status="dome-connection" /><path
   d="m 104.46404,228.02544 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="icon:stage-connection-status"
   style="display:inline;fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none" /><path
   id="icon:stage-power"
   style="display:inline;fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
   data-status="stage-power" /><path
   d="m 367.90784,11.679701 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="icon:telescope-power-state"
   style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
@@ -293,23 +294,24 @@
   inkscape:label="cab"
   data-status="telescope-power-status" /><path
   d="m 211.44686,155.12039 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="telemetry:stage:power:indicator"
   id="icon:stage-connection"
   style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
   sodipodi:nodetypes="ssccssscscsscscsscscsssccs" /><path
   sodipodi:nodetypes="ssccssscscsscscsscscsssccs"
   data-status="stage-connection" /><path
   d="m 365.06325,194.08714 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="icon:camera3-power-status"
   style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
   data-status="camera3-power-status" /><path
   data-status="camera3-power" /><path
   d="m 11.862962,335.2085 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="icon:camera2-power-status"
   style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
   sodipodi:nodetypes="ssccssscscsscscsscscsssccs"
   data-status="camera2-power-status" /><path
   data-status="camera2-power" /><path
   d="m 364.1034,335.2085 c 0.13195,0.49233 0.6392,0.78519 1.13155,0.6533 l 5.1697,-1.38482 0.98966,3.69249 -5.16966,1.38483 c -0.49236,0.13188 -0.78519,0.63907 -0.65322,1.1314 0.13195,0.49233 0.63921,0.7852 1.13155,0.6533 l 5.16969,-1.38482 0.65978,2.46166 c 0.13197,0.49234 0.67824,0.80773 1.13157,0.65331 l 4.67734,-1.25293 c 1.8463,-0.49459 3.43315,-1.71118 4.4017,-3.38878 0.8109,-1.40449 1.10851,-3.00129 0.91979,-4.56676 l 4.18498,-1.12105 c 0.49235,-0.13189 0.78517,-0.63907 0.65322,-1.1314 -0.0885,-0.20714 -0.23854,-0.39782 -0.47266,-0.53298 -0.23412,-0.13518 -0.47425,-0.16977 -0.72044,-0.10384 l -4.18499,1.12105 c -0.59699,-1.48908 -1.67588,-2.68418 -3.08057,-3.49518 -1.67783,-0.9687 -3.62152,-1.20658 -5.50687,-0.73453 l -4.67733,1.25295 c -0.24619,0.0659 -0.43685,0.21595 -0.57199,0.45003 -0.11263,0.19507 -0.16967,0.47426 -0.10375,0.72038 l 0.64329,2.40012 -5.16968,1.38483 c -0.3918,0.13793 -0.68462,0.6451 -0.55258,1.13748 z"
   id="icon:camera-power-status"
   style="display:inline;fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:1;stroke-dasharray:none"
   sodipodi:nodetypes="ssccssscscsscscsscscsssccs"
   data-status="camera2-power-status" /><path
   data-status="camera-power" /><path
   d="m 158.02597,231.08505 h -1.18121 c -0.75154,0 -1.68327,-0.53358 -2.168,-1.25547 l -1.41221,-0.73364 -3.23794,10e-6 -0.83433,0.48885 c -0.38616,0.85502 -1.27284,1.50023 -2.06173,1.49976 h -1.93584 c -0.42774,4.9e-4 -0.83123,-0.20739 -1.13578,-0.5863 v 0 c -0.30416,-0.37841 -0.47164,-0.87993 -0.47164,-1.41258 l 3.9e-4,-8.78252 c 3.7e-4,-1.10219 0.72113,-1.99889 1.60703,-1.99937 l 12.83126,4.8e-4 c 0.8863,6.8e-4 1.60704,0.89861 1.60742,1.99984 v 8.78108 c 0,0.53266 -0.16749,1.03418 -0.47203,1.41307 -0.30415,0.37841 -0.70725,0.58678 -1.1354,0.58679 z"
   id="path1-9"
   style="fill:#008080;fill-opacity:0.298039;stroke:#e6e6e6;stroke-width:1"
@@ -524,11 +526,11 @@
     style="fill:none;stroke:#37c8ab;stroke-width:1px"
     d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242"
     sodipodi:nodetypes="ccc" /><path
     id="structure-beam-photometry"
     id="structure-beam-imaging"
     style="fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
     d="m 202.22718,216.19623 43.3783,43.92979 m 23.12946,22.95946 7.91835,9.30074 m 37.69479,10.90406 34.60451,-0.0996 m -75.69139,-15.59218 24.38124,-24.04571 57.62634,0.0633"
     sodipodi:nodetypes="ccccccccc" /><path
     id="structure-beam-spectroscopy"
     id="structure-beam-spectro"
     style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
     d="m 200.55953,216.46393 -84.48558,84.72949 h -66.3242 m 103.4728,-37.30999 -45.85232,3e-5 -67.852326,10e-6"
     sodipodi:nodetypes="cccccc" /><path
@@ -568,13 +570,7 @@
       y="268.18268"
       rx="5.2959347"
       ry="2.9185479"
       transform="rotate(-45)" /></g><path
     style="fill:none;stroke:#ffff00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
     d="m 151.36689,128.41347 v 14.67918"
     id="path2" /><path
     style="fill:none;stroke:#ffff00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
     d="m 242.75352,127.6079 v 14.67918"
     id="path5" /></g><path
       transform="rotate(-45)" /></g></g><path
   id="icon:dome-light-status"
   style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:0.999998;stroke-dasharray:none"
   d="m 197.14131,44.062272 c 0.0241,0.729645 -0.7628,3.424269 -2.9302,3.424269 -2.1674,0 -2.9302,-2.49921 -2.9302,-3.424269 z m 3.90751,-10.42066 c 1e-4,-0.907814 -0.1805,-1.806613 -0.53144,-2.643868 -0.35094,-0.837246 -0.86499,-1.596196 -1.51237,-2.232645 -0.64738,-0.636439 -1.41499,-1.13759 -2.25811,-1.474211 -0.84301,-0.336631 -1.74473,-0.501963 -2.65241,-0.486403 -1.74249,0.05182 -3.40159,0.757963 -4.64688,1.977902 -1.24529,1.219949 -1.98543,2.86419 -2.07305,4.605265 -0.0417,1.161813 0.21363,2.315042 0.74173,3.350769 0.5281,1.035629 1.31158,1.919572 2.27636,2.56822 0.27192,0.176789 0.49553,0.418432 0.6507,0.70315 0.15518,0.284815 0.23703,0.603718 0.23814,0.927993 v 1.494401 h 5.8604 v -1.494401 c 0,-0.323396 0.0804,-0.641713 0.23383,-0.92643 0.15345,-0.284718 0.37517,-0.52685 0.64523,-0.704713 0.93005,-0.624034 1.69268,-1.467052 2.2206,-2.454822 0.52803,-0.987769 0.80522,-2.090207 0.80727,-3.210207 z"
+21 −15
Original line number Diff line number Diff line
@@ -84,26 +84,24 @@ function animateBeams(namedPosition) {
    const beamImg = document.getElementById('structure-beam-imaging');
    const beamSpc = document.getElementById('structure-beam-spectro');
    const beamEch = document.getElementById('structure-beam-echelle');
    const beamPho = document.getElementById('structure-beam-photometry'); 

    if (beamIn) {
        beamIn.setAttribute("style", BEAM_INCOMING_ON);
    }
    if (beamIn) beamIn.setAttribute("style", BEAM_INCOMING_ON);

    if (beamImg) beamImg.setAttribute("style", BEAM_OFF);
    if (beamSpc) beamSpc.setAttribute("style", BEAM_OFF);
    if (beamEch) beamEch.setAttribute("style", BEAM_OFF);
    if (beamPho) beamPho.setAttribute("style", BEAM_OFF);

    if (namedPosition === 'imaging' && beamImg) {
        beamImg.setAttribute("style", BEAM_ON);
    } else if (namedPosition === 'spectro' && beamSpc) {
        beamSpc.setAttribute("style", BEAM_ON);
    } else if (namedPosition === 'echelle' && beamEch) {
        beamEch.setAttribute("style", BEAM_ON);
    } else if ((namedPosition === 'unknown' || !namedPosition) && beamPho) {
        beamPho.setAttribute("style", BEAM_UNK);

    if (namedPosition === 'imaging') {
        if (beamImg) beamImg.setAttribute("style", BEAM_ON);
    } else if (namedPosition === 'spectro') {
        if (beamSpc) beamSpc.setAttribute("style", BEAM_ON);
    } else if (namedPosition === 'echelle') {
        if (beamEch) beamEch.setAttribute("style", BEAM_ON);
    } else if (namedPosition === 'unknown') {
        // Indeterminate or position 0: dashed imaging beam
        if (beamImg) beamImg.setAttribute("style", BEAM_UNK);
    }
    // null → all beams off (stage moving between named positions)
}

function animateDome(az) {
@@ -182,6 +180,12 @@ function updateSwitchColor(el, state) {
    });
}

// Re-initialize geometry when a tab becomes visible
// (getBBox returns 0 on hidden elements — this fires whenever any bs.tab is shown)
document.addEventListener('shown.bs.tab', () => {
    if (!stageRefGeom || stageRefGeom.widthPx === 0) initializeGeometry();
});

// 1. Fetch and inject the SVG
fetch(svgUrl)
    .then(response => response.text())
@@ -286,7 +290,9 @@ document.addEventListener('noctua-telemetry', (e) => {
        if (data.named && data.named.response) {
            animateBeams(data.named.response);
        } else {
            animateBeams('unknown');
            const stageMm = data.position?.response;
            // Position 0 or no position data → dashed imaging; moving → all off
            animateBeams(stageMm === 0 ? 'unknown' : null);
        }
    }
});