mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
The VM page's thirteen inline script blocks and its inline handlers move to static files: instance_page.js (tabs, OS details, clone names and MACs, Add disk dialog, boot order, host devices, migrate plan, console window, switches that send their form), instance_stats.js (charts and the Logs view) and instance_status.js (the reload when the VM's state changes). Their values and messages come as data attributes of the elements they belong to, page-wide ones on #vm-summary; a form marked data-please-wait shows the please-wait dialog. Three blocks that did nothing are dropped: popovers (the page has none), the video model preselection (the server selects it) and the delete form's poll stop (that form is on the destroy page). The HTML sink inventory now also reads the app's own scripts.
139 lines
8.9 KiB
HTML
139 lines
8.9 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
{% load vm_states %}
|
|
{% load i18n %}
|
|
{% load operations %}
|
|
{% load bootstrap_icons %}
|
|
|
|
{% block title %}{% trans "Instance" %} - {{ instance.name }}{% endblock %}
|
|
|
|
{% block page_header %}{% endblock page_header %}{# the card below has the heading #}
|
|
|
|
{% block content %}
|
|
{% include 'pleasewaitdialog.html' %}
|
|
{# the VM at a glance in one card: who and where it is, what it has, and its sections as the card's footer #}
|
|
<section class="card mb-3" aria-labelledby="vm-name" id="vm-summary" data-status="{{ instance.status }}"
|
|
data-status-url="{% url 'instances:status' instance.id %}" data-osinfo-url="{% url 'instances:osinfo' instance.id %}"
|
|
data-opens-on="{% if instance.is_template and can_clone %}#clone{% endif %}"
|
|
data-random-mac-url="{% url 'instances:random_mac_address' %}"
|
|
{% if can_open_console and vdi_reachable %}data-vdi-url="{% url 'vdi_url' compute.id instance.name %}"{% endif %}>
|
|
<div class="card-body p-3">
|
|
<div class="d-flex flex-wrap justify-content-between align-items-start gap-2">
|
|
<div>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<h1 class="h4 mb-0" id="vm-name">{{ instance.name }}</h1>
|
|
{% vm_state instance.status as state %}
|
|
<span class="badge text-bg-{{ state.1 }}">{{ state.0 }}</span>
|
|
{% if instance.is_template %}<span class="badge text-bg-light border">{% trans "Template" %}</span>{% endif %}
|
|
</div>
|
|
{% if instance.title %}<p class="text-body-secondary mb-1">{{ instance.title }}</p>{% endif %}
|
|
{% include 'instances/host_link.html' %}
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
{% if instance.is_template and can_clone %}
|
|
<button type="button" class="btn btn-sm btn-primary" id="clone-button">{% bs_icon 'copy' %} {% trans "Clone" %}</button>
|
|
{% endif %}
|
|
{% if instance.guest_agent_ready %}
|
|
<button type="button" class="btn btn-sm btn-secondary" id="os-details-button">{% bs_icon 'info-circle' %} {% trans "OS details" %}</button>
|
|
{% endif %}
|
|
<a class="btn btn-sm btn-secondary" href="{% url 'instances:instance' instance.id %}">{% bs_icon 'arrow-clockwise' %} {% trans "Refresh" %}</a>
|
|
</div>
|
|
</div>
|
|
{% if not instance.is_template %}
|
|
<div class="d-flex flex-wrap column-gap-3 row-gap-1 small mt-2">
|
|
{% if not instance.guest_agent %}
|
|
<span>{% bs_icon 'dash-circle' %} {% trans "Guest agent off" %}</span>
|
|
{% elif instance.guest_agent_ready %}
|
|
<span><span class="text-success">{% bs_icon 'check-circle' %}</span> {% trans "Guest agent connected" %}</span>
|
|
{% else %}
|
|
<span><span class="text-warning">{% bs_icon 'exclamation-circle' %}</span> {% trans "Guest agent not connected" %}</span>
|
|
{% endif %}
|
|
<span>{% bs_icon 'camera' %} {% blocktrans count counter=instance.snapshots|length %}{{ counter }} snapshot{% plural %}{{ counter }} snapshots{% endblocktrans %}</span>
|
|
</div>
|
|
{% endif %}
|
|
<dl class="row g-2 small mb-0 mt-1">
|
|
<div class="col-6 col-lg-2">
|
|
<dt class="fw-normal text-body-secondary">{% trans "CPU" %}</dt>
|
|
<dd class="mb-0">{% firstof instance.cur_vcpu instance.vcpu %} {% trans "of" %} {{ instance.vcpu }} {% trans "vCPU" %}</dd>
|
|
</div>
|
|
<div class="col-6 col-lg-2">
|
|
<dt class="fw-normal text-body-secondary">{% trans "Memory" %}</dt>
|
|
<dd class="mb-0">{{ instance.cur_memory }} MiB</dd>
|
|
</div>
|
|
<div class="col-6 col-lg-5">
|
|
<dt class="fw-normal text-body-secondary">{% trans "Disks" %}</dt>
|
|
<dd class="mb-0">{% for disk in instance.disks %}{{ disk.dev }} {{ disk.size|filesizeformat }}{% if not forloop.last %} · {% endif %}{% empty %}{% trans "None" %}{% endfor %}</dd>
|
|
</div>
|
|
{% if not instance.is_template %}
|
|
<div class="col-6 col-lg-3">
|
|
<dt class="fw-normal text-body-secondary">{% trans "IPv4" %}</dt>
|
|
<dd class="mb-0 font-monospace">{{ ipv4_addresses|join:", "|default:"—" }}</dd>
|
|
</div>
|
|
{% endif %}
|
|
</dl>
|
|
</div>
|
|
<div class="card-footer p-2">
|
|
<ul class="nav nav-pills nav-fill flex-wrap flex-lg-nowrap gap-1 small" id="navbtn" role="tablist" aria-label="{% trans "Instance actions" %}">
|
|
{# a template is cloned, not run: no power, access, snapshots or stats #}
|
|
{% if not instance.is_template %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap active" id="power-tab" aria-controls="power" data-bs-toggle="pill" data-bs-target="#power" type="button" role="tab" aria-selected="true">{% bs_icon 'power' %} {% trans "Power" %}</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="access-tab" aria-controls="access" data-bs-toggle="pill" data-bs-target="#access" type="button" role="tab" aria-selected="false">{% bs_icon 'lock' %} {% trans "Access" %}</button>
|
|
</li>
|
|
{% endif %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="resize-tab" aria-controls="resize" data-bs-toggle="pill" data-bs-target="#resize" type="button" role="tab" aria-selected="false">{% bs_icon 'arrows-angle-expand' %} {% trans "Resize" %}</button>
|
|
</li>
|
|
{% if can_snapshot and not instance.is_template %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="snapshots-tab" aria-controls="snapshots" data-bs-toggle="pill" data-bs-target="#snapshots" type="button" role="tab" aria-selected="false">{% bs_icon 'camera' %} {% trans "Snapshot" %}</button>
|
|
</li>
|
|
{% endif %}
|
|
{% if show_settings %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="settings-tab" aria-controls="settings" data-bs-toggle="pill" data-bs-target="#settings" type="button" role="tab" aria-selected="false">{% bs_icon 'gear-wide-connected' %} {% trans "Settings" %}</button>
|
|
</li>
|
|
{% endif %}
|
|
{% if not instance.is_template %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="graphics-tab" aria-controls="graphics" data-bs-toggle="pill" data-bs-target="#graphics" type="button" role="tab" aria-selected="false">{% bs_icon 'bar-chart-line' %} {% trans "Stats" %}</button>
|
|
</li>
|
|
{% endif %}
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link text-nowrap" id="undefine-tab" aria-controls="undefine" data-bs-toggle="pill" data-bs-target="#undefine" type="button" role="tab" aria-selected="false">{% bs_icon 'trash' %} {% trans "Destroy" %}</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
<div id="job-panel" aria-live="polite"></div>
|
|
<div id="mainTabMenu">
|
|
<!-- Tab panes -->
|
|
<div class="tab-content" id=mainTabMenuContent>
|
|
{% if not instance.is_template %}
|
|
{% include 'instances/power_tab.html' %}
|
|
{% include 'instances/access_tab.html' %}
|
|
{% endif %}
|
|
{% include 'instances/resize_tab.html' %}
|
|
{% if can_snapshot and not instance.is_template %}{% include 'instances/snapshots_tab.html' %}{% endif %}
|
|
{% if show_settings %}{% include 'instances/settings_tab.html' %}{% endif %}
|
|
{% if not instance.is_template %}{% include 'instances/stats_tab.html' %}{% endif %}
|
|
{% include 'instances/destroy_tab.html' %}
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
{% block script %}
|
|
<script src="{% static 'js/ace/ace.js' %}" type="text/javascript" charset="utf-8"></script>
|
|
<script src="{% static 'js/xml_editor.js' %}"></script>
|
|
<script src="{% static 'js/chart.umd.min.js' %}"></script>
|
|
<script src="{% static 'js/charts.js' %}"></script>
|
|
<script src="{% static 'js/poll.js' %}"></script>
|
|
{% if not instance.is_template %}<script src="{% static 'js/instance_stats.js' %}"></script>{% endif %}
|
|
<script src="{% static 'js/instance_status.js' %}"></script>
|
|
{% job_panel_script job_resource %}
|
|
<script src="{% static 'js/instance_tabs.js' %}"></script>
|
|
<script src="{% static 'js/instance_page.js' %}"></script>
|
|
{% endblock %}
|