v2 init
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Dashboard · CalMiner{% endblock %} {%
|
||||
block content %}
|
||||
<div class="dashboard-header">
|
||||
<div>
|
||||
<h2>Operations Overview</h2>
|
||||
<p class="dashboard-subtitle">
|
||||
Unified insight across scenarios, costs, production, maintenance, and
|
||||
simulations.
|
||||
</p>
|
||||
</div>
|
||||
<div class="dashboard-actions">
|
||||
<button id="refresh-dashboard" type="button" class="btn primary">
|
||||
Refresh Dashboard
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id="dashboard-status" class="feedback" hidden></p>
|
||||
|
||||
<section>
|
||||
<div id="summary-metrics" class="dashboard-metrics-grid">
|
||||
{% for metric in summary_metrics %}
|
||||
<article class="metric-card">
|
||||
<span class="metric-label">{{ metric.label }}</span>
|
||||
<span class="metric-value">{{ metric.value }}</span>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p id="summary-empty" class="empty-state" {% if summary_metrics|length>
|
||||
0 %} hidden{% endif %}> Add project inputs to populate summary metrics.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="dashboard-charts">
|
||||
<article class="panel chart-card">
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h3>Scenario Cost Mix</h3>
|
||||
<p class="chart-subtitle">CAPEX vs OPEX totals per scenario</p>
|
||||
</div>
|
||||
</header>
|
||||
<canvas
|
||||
id="cost-chart"
|
||||
height="220"
|
||||
{%
|
||||
if
|
||||
not
|
||||
cost_chart_has_data
|
||||
%}
|
||||
hidden{%
|
||||
endif
|
||||
%}
|
||||
></canvas>
|
||||
<p
|
||||
id="cost-chart-empty"
|
||||
class="empty-state"
|
||||
{%
|
||||
if
|
||||
cost_chart_has_data
|
||||
%}
|
||||
hidden{%
|
||||
endif
|
||||
%}
|
||||
>
|
||||
Add CAPEX or OPEX entries to display this chart.
|
||||
</p>
|
||||
</article>
|
||||
<article class="panel chart-card">
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h3>Production vs Consumption</h3>
|
||||
<p class="chart-subtitle">Throughput comparison by scenario</p>
|
||||
</div>
|
||||
</header>
|
||||
<canvas
|
||||
id="activity-chart"
|
||||
height="220"
|
||||
{%
|
||||
if
|
||||
not
|
||||
activity_chart_has_data
|
||||
%}
|
||||
hidden{%
|
||||
endif
|
||||
%}
|
||||
></canvas>
|
||||
</article>
|
||||
</section>
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="dashboard-data" type="application/json">
|
||||
{{ {"summary_metrics": summary_metrics, "scenario_rows": scenario_rows, "overall_report_metrics": overall_report_metrics, "recent_simulations": recent_simulations, "upcoming_maintenance": upcoming_maintenance} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/dashboard.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,51 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Process Parameters · CalMiner{%
|
||||
endblock %} {% block content %}
|
||||
<section class="panel">
|
||||
<h2>Scenario Parameters</h2>
|
||||
{% if scenarios %}
|
||||
<form id="parameter-form" class="form-grid">
|
||||
<label>
|
||||
<span>Scenario</span>
|
||||
<select name="scenario_id" id="scenario_id">
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Name</span>
|
||||
<input type="text" name="name" id="name" required />
|
||||
</label>
|
||||
<label>
|
||||
<span>Value</span>
|
||||
<input type="number" name="value" id="value" step="any" required />
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add Parameter</button>
|
||||
</form>
|
||||
<p id="parameter-feedback" class="feedback" role="status"></p>
|
||||
<div class="table-container">
|
||||
<table id="parameter-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Parameter</th>
|
||||
<th scope="col">Value</th>
|
||||
<th scope="col">Distribution</th>
|
||||
<th scope="col">Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="parameter-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
No scenarios available. Create a <a href="scenarios">scenario</a> before
|
||||
adding parameters.
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="parameters-data" type="application/json">
|
||||
{{ parameters_by_scenario | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/parameters.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,53 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Scenario Management · CalMiner{%
|
||||
endblock %} {% block content %}
|
||||
<section class="panel">
|
||||
<h2>Create a New Scenario</h2>
|
||||
<form id="scenario-form" class="form-grid">
|
||||
<label>
|
||||
<span>Name</span>
|
||||
<input type="text" name="name" id="name" required />
|
||||
</label>
|
||||
<label>
|
||||
<span>Description</span>
|
||||
<input type="text" name="description" id="description" />
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Create Scenario</button>
|
||||
</form>
|
||||
<div id="feedback" class="feedback hidden" aria-live="polite"></div>
|
||||
<div class="table-container">
|
||||
{% if scenarios %}
|
||||
<table id="scenario-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="scenario-table-body">
|
||||
{% for scenario in scenarios %}
|
||||
<tr data-scenario-id="{{ scenario.id }}">
|
||||
<td>{{ scenario.name }}</td>
|
||||
<td>{{ scenario.description or "—" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p id="empty-state" class="empty-state">
|
||||
No scenarios yet. Create one to get started.
|
||||
</p>
|
||||
<table id="scenario-table" class="hidden" aria-hidden="true">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="scenario-table-body"></tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script src="/static/js/scenario-form.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,76 +0,0 @@
|
||||
{% extends "base.html" %} {% from "partials/components.html" import
|
||||
select_field, feedback, empty_state, table_container with context %} {% block
|
||||
title %}Consumption · CalMiner{% endblock %} {% block content %}
|
||||
<section class="panel">
|
||||
<h2>Consumption Tracking</h2>
|
||||
<div class="form-grid">
|
||||
{{ select_field( "Scenario filter", "consumption-scenario-filter",
|
||||
options=scenarios, placeholder="Select a scenario" ) }}
|
||||
</div>
|
||||
{{ empty_state( "consumption-empty", "Choose a scenario to review its
|
||||
consumption records." ) }} {% call table_container(
|
||||
"consumption-table-wrapper", hidden=True, aria_label="Scenario consumption
|
||||
records" ) %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Amount</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="consumption-table-body"></tbody>
|
||||
{% endcall %}
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add Consumption Record</h2>
|
||||
{% if scenarios %}
|
||||
<form id="consumption-form" class="form-grid">
|
||||
{{ select_field( "Scenario", "consumption-form-scenario",
|
||||
name="scenario_id", options=scenarios, required=True, placeholder="Select a
|
||||
scenario", placeholder_disabled=True ) }}
|
||||
<label for="consumption-form-unit">
|
||||
Unit
|
||||
<select id="consumption-form-unit" name="unit_name" required>
|
||||
<option value="" disabled selected>Select unit</option>
|
||||
{% for unit in unit_options %}
|
||||
<option value="{{ unit.name }}" data-symbol="{{ unit.symbol }}">
|
||||
{{ unit.name }} ({{ unit.symbol }})
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<input id="consumption-form-unit-symbol" type="hidden" name="unit_symbol" />
|
||||
<label for="consumption-form-amount">
|
||||
Amount
|
||||
<input
|
||||
id="consumption-form-amount"
|
||||
type="number"
|
||||
name="amount"
|
||||
min="0"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="consumption-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="consumption-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add Record</button>
|
||||
</form>
|
||||
{{ feedback("consumption-feedback") }} {% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> before adding consumption records.
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="consumption-data" type="application/json">
|
||||
{{ {"scenarios": scenarios, "consumption": consumption_by_scenario, "unit_options": unit_options} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/consumption.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,129 +0,0 @@
|
||||
{% extends "base.html" %} {% from "partials/components.html" import
|
||||
select_field, feedback, empty_state, table_container with context %} {% block
|
||||
title %}Costs · CalMiner{% endblock %} {% block content %}
|
||||
<section class="panel">
|
||||
<h2>Cost Overview</h2>
|
||||
{% if scenarios %}
|
||||
<div class="form-grid">
|
||||
{{ select_field( "Scenario filter", "costs-scenario-filter",
|
||||
options=scenarios, placeholder="Select a scenario" ) }}
|
||||
</div>
|
||||
{% else %} {{ empty_state( "costs-scenario-empty", "Create a scenario to
|
||||
review cost information." ) }} {% endif %} {{ empty_state( "costs-empty",
|
||||
"Choose a scenario to review CAPEX and OPEX details." ) }}
|
||||
|
||||
<div id="costs-data" class="hidden">
|
||||
{% call table_container( "capex-table-container", aria_label="Scenario CAPEX
|
||||
records", heading="Capital Expenditures (CAPEX)" ) %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Amount</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="capex-table-body"></tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th scope="row">Total</th>
|
||||
<th id="capex-total">—</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
{% endcall %} {{ empty_state( "capex-empty", "No CAPEX records for this
|
||||
scenario yet.", hidden=True ) }} {% call table_container(
|
||||
"opex-table-container", aria_label="Scenario OPEX records",
|
||||
heading="Operational Expenditures (OPEX)" ) %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Amount</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="opex-table-body"></tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th scope="row">Total</th>
|
||||
<th id="opex-total">—</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
{% endcall %} {{ empty_state( "opex-empty", "No OPEX records for this
|
||||
scenario yet.", hidden=True ) }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add CAPEX Entry</h2>
|
||||
{% if scenarios %}
|
||||
<form id="capex-form" class="form-grid">
|
||||
{{ select_field( "Scenario", "capex-form-scenario", name="scenario_id",
|
||||
options=scenarios, required=True, placeholder="Select a scenario",
|
||||
placeholder_disabled=True ) }} {{ select_field( "Currency",
|
||||
"capex-form-currency", name="currency_code", options=currency_options,
|
||||
required=True, placeholder="Select currency", placeholder_disabled=True,
|
||||
value_attr="id", label_attr="name" ) }}
|
||||
<label for="capex-form-amount">
|
||||
Amount
|
||||
<input
|
||||
id="capex-form-amount"
|
||||
type="number"
|
||||
name="amount"
|
||||
min="0"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="capex-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="capex-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add CAPEX</button>
|
||||
</form>
|
||||
{{ feedback("capex-feedback") }} {% else %} {{ empty_state(
|
||||
"capex-form-empty", "Create a scenario before adding CAPEX entries." ) }} {%
|
||||
endif %}
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add OPEX Entry</h2>
|
||||
{% if scenarios %}
|
||||
<form id="opex-form" class="form-grid">
|
||||
{{ select_field( "Scenario", "opex-form-scenario", name="scenario_id",
|
||||
options=scenarios, required=True, placeholder="Select a scenario",
|
||||
placeholder_disabled=True ) }} {{ select_field( "Currency",
|
||||
"opex-form-currency", name="currency_code", options=currency_options,
|
||||
required=True, placeholder="Select currency", placeholder_disabled=True,
|
||||
value_attr="id", label_attr="name" ) }}
|
||||
<label for="opex-form-amount">
|
||||
Amount
|
||||
<input
|
||||
id="opex-form-amount"
|
||||
type="number"
|
||||
name="amount"
|
||||
min="0"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="opex-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="opex-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add OPEX</button>
|
||||
</form>
|
||||
{{ feedback("opex-feedback") }} {% else %} {{ empty_state( "opex-form-empty",
|
||||
"Create a scenario before adding OPEX entries." ) }} {% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="costs-payload" type="application/json">
|
||||
{{ {"capex": capex_by_scenario, "opex": opex_by_scenario, "currency_options": currency_options} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/costs.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,131 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "partials/components.html" import select_field, feedback, empty_state, table_container with context %}
|
||||
|
||||
{% block title %}Currencies · CalMiner{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="panel" id="currencies-overview">
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h2>Currency Overview</h2>
|
||||
<p class="chart-subtitle">
|
||||
Current availability of currencies for project inputs.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if currency_stats %}
|
||||
<div class="dashboard-metrics-grid">
|
||||
<article class="metric-card">
|
||||
<span class="metric-label">Total Currencies</span>
|
||||
<span class="metric-value" id="currency-metric-total">{{ currency_stats.total }}</span>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<span class="metric-label">Active</span>
|
||||
<span class="metric-value" id="currency-metric-active">{{ currency_stats.active }}</span>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<span class="metric-label">Inactive</span>
|
||||
<span class="metric-value" id="currency-metric-inactive">{{ currency_stats.inactive }}</span>
|
||||
</article>
|
||||
</div>
|
||||
{% else %} {{ empty_state("currencies-overview-empty", "No currency data
|
||||
available yet.") }} {% endif %} {% call table_container(
|
||||
"currencies-table-container", aria_label="Configured currencies",
|
||||
heading="Configured Currencies" ) %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Code</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Symbol</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="currencies-table-body"></tbody>
|
||||
{% endcall %} {{ empty_state( "currencies-table-empty", "No currencies
|
||||
configured yet.", hidden=currencies|length > 0 ) }}
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="panel"
|
||||
id="currencies-editor"
|
||||
data-default-code="{{ default_currency_code }}"
|
||||
>
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h2>Manage Currencies</h2>
|
||||
<p class="chart-subtitle">
|
||||
Create new currencies or update existing configurations inline.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% set status_options = [ {"id": "true", "name": "Active"}, {"id": "false",
|
||||
"name": "Inactive"} ] %}
|
||||
|
||||
<form id="currency-form" class="form-grid" novalidate>
|
||||
{{ select_field( "Currency to update (leave blank for new)",
|
||||
"currency-form-existing", name="existing_code", options=currencies,
|
||||
placeholder="Create a new currency", value_attr="code", label_attr="name" )
|
||||
}}
|
||||
|
||||
<label for="currency-form-code">
|
||||
Currency code
|
||||
<input
|
||||
id="currency-form-code"
|
||||
name="code"
|
||||
type="text"
|
||||
maxlength="3"
|
||||
required
|
||||
autocomplete="off"
|
||||
placeholder="e.g. USD"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label for="currency-form-name">
|
||||
Currency name
|
||||
<input
|
||||
id="currency-form-name"
|
||||
name="name"
|
||||
type="text"
|
||||
maxlength="128"
|
||||
required
|
||||
autocomplete="off"
|
||||
placeholder="e.g. US Dollar"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label for="currency-form-symbol">
|
||||
Currency symbol (optional)
|
||||
<input
|
||||
id="currency-form-symbol"
|
||||
name="symbol"
|
||||
type="text"
|
||||
maxlength="8"
|
||||
autocomplete="off"
|
||||
placeholder="$"
|
||||
/>
|
||||
</label>
|
||||
|
||||
{{ select_field( "Status", "currency-form-status", name="is_active",
|
||||
options=status_options, include_blank=False ) }}
|
||||
|
||||
<div class="button-row">
|
||||
<button type="submit" class="btn primary">Save Currency</button>
|
||||
<button type="button" class="btn" id="currency-form-reset">Reset</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ feedback("currency-form-feedback") }}
|
||||
</section>
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="currencies-data" type="application/json">
|
||||
{{ {
|
||||
"currencies": currencies,
|
||||
"currency_stats": currency_stats,
|
||||
"default_currency_code": default_currency_code,
|
||||
"currency_api_base": currency_api_base
|
||||
} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/currencies.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,78 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Equipment · CalMiner{% endblock %} {%
|
||||
block content %}
|
||||
<section class="panel">
|
||||
<h2>Equipment Inventory</h2>
|
||||
{% if scenarios %}
|
||||
<div class="form-grid">
|
||||
<label for="equipment-scenario-filter">
|
||||
Scenario filter
|
||||
<select id="equipment-scenario-filter">
|
||||
<option value="">Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> to view equipment inventory.
|
||||
</p>
|
||||
{% endif %}
|
||||
<div id="equipment-empty" class="empty-state">
|
||||
Choose a scenario to review the equipment list.
|
||||
</div>
|
||||
<div id="equipment-table-wrapper" class="table-container hidden">
|
||||
<table aria-label="Scenario equipment inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="equipment-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add Equipment</h2>
|
||||
{% if scenarios %}
|
||||
<form id="equipment-form" class="form-grid">
|
||||
<label for="equipment-form-scenario">
|
||||
Scenario
|
||||
<select id="equipment-form-scenario" name="scenario_id" required>
|
||||
<option value="" disabled selected>Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label for="equipment-form-name">
|
||||
Equipment name
|
||||
<input id="equipment-form-name" type="text" name="name" required />
|
||||
</label>
|
||||
<label for="equipment-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="equipment-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add Equipment</button>
|
||||
</form>
|
||||
<p id="equipment-feedback" class="feedback hidden" role="status"></p>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> before managing equipment.
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="equipment-data" type="application/json">
|
||||
{{ {"scenarios": scenarios, "equipment": equipment_by_scenario} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/equipment.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,111 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Maintenance · CalMiner{% endblock %}
|
||||
{% block content %}
|
||||
<section class="panel">
|
||||
<h2>Maintenance Schedule</h2>
|
||||
{% if scenarios %}
|
||||
<div class="form-grid">
|
||||
<label for="maintenance-scenario-filter">
|
||||
Scenario filter
|
||||
<select id="maintenance-scenario-filter">
|
||||
<option value="">Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> to view maintenance entries.
|
||||
</p>
|
||||
{% endif %}
|
||||
<div id="maintenance-empty" class="empty-state">
|
||||
Choose a scenario to review upcoming or completed maintenance.
|
||||
</div>
|
||||
<div id="maintenance-table-wrapper" class="table-container hidden">
|
||||
<table aria-label="Scenario maintenance records">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col">Equipment</th>
|
||||
<th scope="col">Cost</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="maintenance-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add Maintenance Entry</h2>
|
||||
{% if scenarios %}
|
||||
<form id="maintenance-form" class="form-grid">
|
||||
<label for="maintenance-form-scenario">
|
||||
Scenario
|
||||
<select id="maintenance-form-scenario" name="scenario_id" required>
|
||||
<option value="" disabled selected>Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label for="maintenance-form-equipment">
|
||||
Equipment
|
||||
<select
|
||||
id="maintenance-form-equipment"
|
||||
name="equipment_id"
|
||||
required
|
||||
disabled
|
||||
>
|
||||
<option value="" disabled selected>Select equipment</option>
|
||||
</select>
|
||||
</label>
|
||||
<p id="maintenance-equipment-empty" class="empty-state hidden">
|
||||
Add equipment for this scenario before scheduling maintenance.
|
||||
</p>
|
||||
<label for="maintenance-form-date">
|
||||
Date
|
||||
<input
|
||||
id="maintenance-form-date"
|
||||
type="date"
|
||||
name="maintenance_date"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="maintenance-form-cost">
|
||||
Cost
|
||||
<input
|
||||
id="maintenance-form-cost"
|
||||
type="number"
|
||||
name="cost"
|
||||
min="0"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="maintenance-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="maintenance-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add Maintenance</button>
|
||||
</form>
|
||||
<p id="maintenance-feedback" class="feedback hidden" role="status"></p>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> before managing maintenance
|
||||
entries.
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="maintenance-data" type="application/json">
|
||||
{{ {"equipment": equipment_by_scenario, "maintenance": maintenance_by_scenario} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/maintenance.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,97 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Production · CalMiner{% endblock %}
|
||||
{% block content %}
|
||||
<section class="panel">
|
||||
<h2>Production Output</h2>
|
||||
{% if scenarios %}
|
||||
<div class="form-grid">
|
||||
<label for="production-scenario-filter">
|
||||
Scenario filter
|
||||
<select id="production-scenario-filter">
|
||||
<option value="">Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> to view production output data.
|
||||
</p>
|
||||
{% endif %}
|
||||
<div id="production-empty" class="empty-state">
|
||||
Choose a scenario to review its production output.
|
||||
</div>
|
||||
<div id="production-table-wrapper" class="table-container hidden">
|
||||
<table aria-label="Scenario production records">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Amount</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="production-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<h2>Add Production Output</h2>
|
||||
{% if scenarios %}
|
||||
<form id="production-form" class="form-grid">
|
||||
<label for="production-form-scenario">
|
||||
Scenario
|
||||
<select id="production-form-scenario" name="scenario_id" required>
|
||||
<option value="" disabled selected>Select a scenario</option>
|
||||
{% for scenario in scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label for="production-form-unit">
|
||||
Unit
|
||||
<select id="production-form-unit" name="unit_name" required>
|
||||
<option value="" disabled selected>Select unit</option>
|
||||
{% for unit in unit_options %}
|
||||
<option value="{{ unit.name }}" data-symbol="{{ unit.symbol }}">
|
||||
{{ unit.name }} ({{ unit.symbol }})
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<input id="production-form-unit-symbol" type="hidden" name="unit_symbol" />
|
||||
<label for="production-form-amount">
|
||||
Amount
|
||||
<input
|
||||
id="production-form-amount"
|
||||
type="number"
|
||||
name="amount"
|
||||
min="0"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label for="production-form-description">
|
||||
Description (optional)
|
||||
<textarea
|
||||
id="production-form-description"
|
||||
name="description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Add Record</button>
|
||||
</form>
|
||||
<p id="production-feedback" class="feedback hidden" role="status"></p>
|
||||
{% else %}
|
||||
<p class="empty-state">
|
||||
Create a <a href="scenarios">scenario</a> before adding production output.
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="production-data" type="application/json">
|
||||
{{ {"scenarios": scenarios, "production": production_by_scenario, "unit_options": unit_options} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/production.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,41 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Reporting · CalMiner{% endblock %} {%
|
||||
block content %}
|
||||
<section class="panel">
|
||||
<h2>Scenario KPI Summary</h2>
|
||||
<div class="button-row">
|
||||
<button id="report-refresh" class="btn" type="button">
|
||||
Refresh Metrics
|
||||
</button>
|
||||
</div>
|
||||
<p id="report-feedback" class="feedback hidden" role="status"></p>
|
||||
|
||||
<div id="reporting-empty" class="empty-state hidden">
|
||||
No reporting data available. Run a simulation to generate metrics.
|
||||
</div>
|
||||
|
||||
<div id="reporting-table-wrapper" class="table-container hidden">
|
||||
<table aria-label="Scenario reporting summary">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Scenario</th>
|
||||
<th scope="col">Iterations</th>
|
||||
<th scope="col">Mean Result</th>
|
||||
<th scope="col">Variance</th>
|
||||
<th scope="col">Std. Dev</th>
|
||||
<th scope="col">Percentile 5</th>
|
||||
<th scope="col">Percentile 95</th>
|
||||
<th scope="col">Value at Risk (95%)</th>
|
||||
<th scope="col">Expected Shortfall (95%)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="reporting-table-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="reporting-data" type="application/json">
|
||||
{{ report_summaries | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/reporting.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,26 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Settings · CalMiner{% endblock %} {%
|
||||
block content %}
|
||||
<section class="page-header">
|
||||
<div>
|
||||
<h1>Settings</h1>
|
||||
<p class="page-subtitle">
|
||||
Configure platform defaults and administrative options.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section class="settings-grid">
|
||||
<article class="settings-card">
|
||||
<h2>Currency Management</h2>
|
||||
<p>
|
||||
Manage available currencies, symbols, and default selections from the
|
||||
Currency Management page.
|
||||
</p>
|
||||
<a class="button-link" href="/ui/currencies">Go to Currency Management</a>
|
||||
</article>
|
||||
<article class="settings-card">
|
||||
<h2>Themes</h2>
|
||||
<p>Adjust CalMiner theme colors and preview changes instantly.</p>
|
||||
<a class="button-link" href="/theme-settings">Go to Theme Settings</a>
|
||||
</article>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -1,41 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Simulations · CalMiner{% endblock %}
|
||||
{% block content %}
|
||||
<section class="panel">
|
||||
<h2>Monte Carlo Simulations</h2>
|
||||
{% if simulation_scenarios %}
|
||||
<div class="form-grid">
|
||||
<label for="simulations-scenario-filter">
|
||||
Scenario filter
|
||||
<select id="simulations-scenario-filter">
|
||||
<option value="">Select a scenario</option>
|
||||
{% for scenario in simulation_scenarios %}
|
||||
<option value="{{ scenario.id }}">{{ scenario.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">Create a <a href="scenarios">scenario</a> before running simulations.</p>
|
||||
{% endif %}
|
||||
|
||||
<div
|
||||
id="simulations-overview-wrapper"
|
||||
class="table-container{% if not simulation_scenarios %} hidden{% endif %}"
|
||||
>
|
||||
<h3>Scenario Run History</h3>
|
||||
<table aria-label="Simulation run history">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Scenario</th>
|
||||
<th scope="col">Iterations</th>
|
||||
<th scope="col">Mean Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</section>
|
||||
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="simulations-data" type="application/json">
|
||||
{{ {"scenarios": simulation_scenarios, "runs": simulation_runs} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/simulations.js"></script>
|
||||
{% endblock %}
|
||||
@@ -1,125 +0,0 @@
|
||||
{% extends "base.html" %} {% block title %}Theme Settings · CalMiner{% endblock
|
||||
%} {% block content %}
|
||||
<section class="page-header">
|
||||
<div>
|
||||
<h1>Theme Settings</h1>
|
||||
<p class="page-subtitle">
|
||||
Adjust CalMiner theme colors and preview changes instantly.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel" id="theme-settings" data-api="/api/settings/css">
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h2>Theme Colors</h2>
|
||||
<p class="chart-subtitle">
|
||||
Update global CSS variables to customize CalMiner's appearance.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
<form id="theme-settings-form" class="form-grid color-form-grid" novalidate>
|
||||
{% for key, value in css_variables.items() %} {% set env_meta =
|
||||
css_env_override_meta.get(key) %}
|
||||
<label
|
||||
class="color-form-field{% if env_meta %} is-env-override{% endif %}"
|
||||
data-variable="{{ key }}"
|
||||
>
|
||||
<span class="color-field-header">
|
||||
<span class="color-field-name">{{ key }}</span>
|
||||
<span class="color-field-default"
|
||||
>Default: {{ css_defaults[key] }}</span
|
||||
>
|
||||
</span>
|
||||
<span class="color-field-helper" id="color-helper-{{ loop.index }}"
|
||||
>Accepts hex, rgb(a), or hsl(a) values.</span
|
||||
>
|
||||
{% if env_meta %}
|
||||
<span class="color-env-flag"
|
||||
>Managed via {{ env_meta.env_var }} (read-only)</span
|
||||
>
|
||||
{% endif %}
|
||||
<span class="color-input-row">
|
||||
<input
|
||||
type="text"
|
||||
name="{{ key }}"
|
||||
class="color-value-input"
|
||||
value="{{ value }}"
|
||||
autocomplete="off"
|
||||
aria-describedby="color-helper-{{ loop.index }}"
|
||||
{%
|
||||
if
|
||||
env_meta
|
||||
%}disabled
|
||||
aria-disabled="true"
|
||||
data-env-override="true"
|
||||
{%
|
||||
endif
|
||||
%}
|
||||
/>
|
||||
<span
|
||||
class="color-preview"
|
||||
aria-hidden="true"
|
||||
style="background: {{ value }}"
|
||||
></span>
|
||||
</span>
|
||||
</label>
|
||||
{% endfor %}
|
||||
|
||||
<div class="button-row">
|
||||
<button type="submit" class="btn primary">Save Theme</button>
|
||||
<button type="button" class="btn" id="theme-settings-reset">
|
||||
Reset to Defaults
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% from "partials/components.html" import feedback with context %} {{
|
||||
feedback("theme-settings-feedback") }}
|
||||
</section>
|
||||
|
||||
<section class="panel" id="theme-env-overrides">
|
||||
<header class="panel-header">
|
||||
<div>
|
||||
<h2>Environment Overrides</h2>
|
||||
<p class="chart-subtitle">
|
||||
The following CSS variables are controlled via environment variables and
|
||||
take precedence over database values.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
{% if css_env_override_rows %}
|
||||
<div class="table-container env-overrides-table">
|
||||
<table aria-label="Environment-controlled theme variables">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">CSS Variable</th>
|
||||
<th scope="col">Environment Variable</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in css_env_override_rows %}
|
||||
<tr>
|
||||
<td><code>{{ row.css_key }}</code></td>
|
||||
<td><code>{{ row.env_var }}</code></td>
|
||||
<td><code>{{ row.value }}</code></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="empty-state">No environment overrides configured.</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %} {% block scripts %} {{ super() }}
|
||||
<script id="theme-settings-data" type="application/json">
|
||||
{{ {
|
||||
"variables": css_variables,
|
||||
"defaults": css_defaults,
|
||||
"envOverrides": css_env_overrides,
|
||||
"envSources": css_env_override_rows
|
||||
} | tojson }}
|
||||
</script>
|
||||
<script src="/static/js/settings.js"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user