Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-13 08:42:18

0001 {% extends "base.html" %}
0002 {% block title %}Production Task Catalog{% endblock %}
0003 
0004 {% block content %}
0005 <link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css">
0006 
0007 <div class="container-fluid mt-3 pcs-catalog">
0008   <div class="d-flex align-items-center mb-3">
0009     <h2 class="me-3 mb-0">Production Task Catalog</h2>
0010     <a href="{% url 'pcs:pcs_hub' %}" class="btn btn-sm btn-outline-secondary">PCS Hub</a>
0011     <form method="post" action="{% url 'pcs:pcs_catalog_csv_update' %}" class="ms-2 d-inline">
0012       {% csrf_token %}
0013       <button type="submit" class="btn btn-sm btn-outline-primary"
0014               title="Re-import eic/epic-prod/docs/_data/datasets.csv into the catalog"
0015               onclick="return confirm('Re-import the default-datasets CSV into the catalog?');">
0016         Update from CSV
0017       </button>
0018     </form>
0019     <form method="post" action="{% url 'pcs:pcs_catalog_rucio_update' %}" class="ms-2 d-inline">
0020       {% csrf_token %}
0021       <button type="submit" class="btn btn-sm btn-outline-primary"
0022               title="Refresh the JLab Rucio output snapshot for the current campaign"
0023               onclick="return confirm('Refresh the JLab Rucio output snapshot for the current campaign?');">
0024         Update from Rucio
0025       </button>
0026     </form>
0027   </div>
0028 
0029   {% if show_tabs %}
0030   <div class="pcs-tlf-tabs btn-group mb-2 flex-wrap" role="tablist" aria-label="Lifecycle tabs">
0031     {% for tab in lifecycle_tabs %}
0032       <a class="btn btn-sm btn-outline-{{ tab.color }}{% if active_lifecycle == tab.key %} active{% endif %}"
0033          href="?lifecycle={{ tab.key }}">
0034         {{ tab.label }}{% if tab.key != 'past' and tab.campaigns %} <span class="text-muted">·</span>
0035           {% for c in tab.campaigns %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}
0036         {% endif %}
0037       </a>
0038     {% endfor %}
0039   </div>
0040   {% endif %}
0041 
0042   {% if rucio_detected and rucio_detected.0.version != rucio_current_name and active_lifecycle == 'current' %}
0043     {# Current tab and current is stale: selector to switch. #}
0044     <div class="border rounded p-2 mb-3 small bg-light">
0045       <div class="mb-1 text-muted">
0046         Detected newer 26.x release in JLab Rucio
0047         (PCS current: <strong>{{ rucio_current_name }}</strong>):
0048       </div>
0049       <div class="d-flex flex-wrap align-items-center gap-2">
0050       {% for r in rucio_detected %}
0051         <span>{{ r.version }} <span class="text-muted">({{ r.count }})</span>
0052           {% if r.version != rucio_current_name %}
0053             <form method="post" action="{% url 'pcs:pcs_catalog_set_current' %}" class="d-inline">
0054               {% csrf_token %}
0055               <input type="hidden" name="name" value="{{ r.version }}">
0056               <button type="submit" class="btn btn-sm btn-outline-primary py-0 px-2 ms-1"
0057                       title="Rename PCS current campaign to {{ r.version }} and pull its Rucio snapshot in one click"
0058                       onclick="return confirm('Switch PCS current to {{ r.version }} and refresh snapshot?');">Make current</button>
0059             </form>
0060           {% else %}
0061             <span class="badge bg-success">current</span>
0062           {% endif %}
0063         </span>
0064       {% endfor %}
0065       </div>
0066     </div>
0067   {% endif %}
0068 
0069   <div id="pcs-rucio-timeline" class="mb-3" style="min-height:540px"></div>
0070 
0071   {% if rucio_unmatched %}
0072   <details class="mb-3 small">
0073     <summary class="text-muted">
0074       <strong style="color:#dc3545">&#9888; {{ rucio_unmatched|length }} unmatched Rucio output{{ rucio_unmatched|length|pluralize }}</strong>
0075       for campaign {{ rucio_unmatched_campaign }} (no request in this table matched these DIDs)
0076     </summary>
0077     <ul class="mt-2 mb-0" style="font-family:monospace; font-size:0.85em;">
0078     {% for u in rucio_unmatched %}
0079       <li>{{ u.did }} &middot; {{ u.files }} files &middot; {{ u.bytes|filesizeformat }}{% if u.incomplete %} <span style="color:#dc3545">(incomplete)</span>{% endif %}</li>
0080     {% endfor %}
0081     </ul>
0082   </details>
0083   {% endif %}
0084 
0085   {% include "pcs/_task_list_filter.html" %}
0086 </div>
0087 
0088 <script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
0089 <script>
0090 (function() {
0091   const data = {{ rucio_timeline_json|safe }};
0092   const el = document.getElementById('pcs-rucio-timeline');
0093   if (!el) return;
0094   if (!data || !data.dates || !data.dates.length) {
0095     el.innerHTML = '<div class="text-muted small">No Rucio arrivals timeline available — '
0096       + 'click <em>Update from Rucio</em> to populate the snapshot.</div>';
0097     return;
0098   }
0099   const TB = 1e12;
0100   const SIMU_COLOR = '#1f77b4';
0101   const RECO_COLOR = '#ff7f0e';
0102   const tb = bytes => bytes.map(b => b / TB);
0103   // Three stacked panes, sharing the time axis at the bottom:
0104   //   top    = cumulative datasets
0105   //   middle = cumulative files (registered)
0106   //   bottom = cumulative output (TB)
0107   // One legend entry per stage; toggling hides all three panes for
0108   // that stage via legendgroup.
0109   const traces = [
0110     // Top pane.
0111     {x: data.dates, y: data.simu.cum_datasets, name: 'Simu',
0112      legendgroup: 'simu', mode: 'lines', line: {shape: 'hv', color: SIMU_COLOR},
0113      xaxis: 'x', yaxis: 'y'},
0114     {x: data.dates, y: data.reco.cum_datasets, name: 'Reco',
0115      legendgroup: 'reco', mode: 'lines', line: {shape: 'hv', color: RECO_COLOR},
0116      xaxis: 'x', yaxis: 'y'},
0117     // Middle pane.
0118     {x: data.dates, y: data.simu.cum_files, legendgroup: 'simu',
0119      mode: 'lines', line: {shape: 'hv', color: SIMU_COLOR},
0120      xaxis: 'x', yaxis: 'y2', showlegend: false},
0121     {x: data.dates, y: data.reco.cum_files, legendgroup: 'reco',
0122      mode: 'lines', line: {shape: 'hv', color: RECO_COLOR},
0123      xaxis: 'x', yaxis: 'y2', showlegend: false},
0124     // Bottom pane.
0125     {x: data.dates, y: tb(data.simu.cum_bytes), legendgroup: 'simu',
0126      mode: 'lines', line: {shape: 'hv', color: SIMU_COLOR},
0127      xaxis: 'x', yaxis: 'y3', showlegend: false},
0128     {x: data.dates, y: tb(data.reco.cum_bytes), legendgroup: 'reco',
0129      mode: 'lines', line: {shape: 'hv', color: RECO_COLOR},
0130      xaxis: 'x', yaxis: 'y3', showlegend: false},
0131   ];
0132   const layout = {
0133     title: {text: 'Rucio arrivals — ' + (data.campaign_name || ''),
0134             font: {size: 14}},
0135     margin: {l: 70, r: 30, t: 40, b: 40},
0136     height: 540,
0137     // Single shared x axis, anchored to the bottom pane's y3.
0138     xaxis:  {anchor: 'y3', type: 'date'},
0139     yaxis:  {domain: [0.70, 1.00], title: 'datasets', rangemode: 'tozero'},
0140     yaxis2: {domain: [0.36, 0.66], title: 'files (registered)',
0141              rangemode: 'tozero'},
0142     yaxis3: {domain: [0.00, 0.32], title: 'output (TB)', rangemode: 'tozero'},
0143     legend: {orientation: 'h', y: -0.12},
0144     showlegend: true,
0145   };
0146   Plotly.newPlot(el, traces, layout, {displayModeBar: false, responsive: true});
0147 })();
0148 </script>
0149 {% endblock %}