129 lines
7.4 KiB
HTML
129 lines
7.4 KiB
HTML
{% extends 'base.html' %}
|
|
{% block content %}
|
|
<div class="toolbar">
|
|
<div>
|
|
<h1>{{ t('software.title') }}</h1>
|
|
<p class="muted">{{ t('software.central_description') }}</p>
|
|
</div>
|
|
<a class="button button-secondary" href="/settings/software">{{ t('software.settings.menu') }}</a>
|
|
</div>
|
|
|
|
<div class="software-summary-cards">
|
|
<a class="software-summary-card software-summary-link" href="/software/installations">
|
|
<span>{{ t('software.total_entries') }}</span>
|
|
<strong>{{ software_entry_count }}</strong>
|
|
<small>{{ t('software.open_detailed_list') }}</small>
|
|
</a>
|
|
<a class="software-summary-card software-summary-link" href="/software/summary">
|
|
<span>{{ t('software.distinct_software') }}</span>
|
|
<strong>{{ software_summary_count }}</strong>
|
|
<small>{{ t('software.open_aggregated_list') }}</small>
|
|
</a>
|
|
<section class="software-summary-card">
|
|
<span>{{ t('software.initialized_assets') }}</span>
|
|
<strong>{{ initialized_assets }}</strong>
|
|
</section>
|
|
</div>
|
|
|
|
<section class="panel software-navigation-panel">
|
|
<h2>{{ t('software.lists') }}</h2>
|
|
<div class="software-list-links">
|
|
<a href="/software/installations" class="software-list-link">
|
|
<strong>{{ t('software.all_installations') }}</strong>
|
|
<span>{{ t('software.all_installations_help') }}</span>
|
|
<span class="button button-secondary">{{ t('software.open') }}</span>
|
|
</a>
|
|
<a href="/software/summary" class="software-list-link">
|
|
<strong>{{ t('software.aggregated_list') }}</strong>
|
|
<span>{{ t('software.aggregated_list_help') }}</span>
|
|
<span class="button button-secondary">{{ t('software.open') }}</span>
|
|
</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<div class="software-log-heading">
|
|
<h2>{{ t('software.recent_jobs') }}</h2>
|
|
<div class="software-job-heading-actions">
|
|
<a class="button button-secondary button-small" href="/software/job-states">▦ {{ t('job_states.open', 'Jobstatus je Asset') }}</a>
|
|
<button
|
|
type="button"
|
|
class="button button-secondary button-small"
|
|
id="restart-selected-jobs-button"
|
|
data-base-label="↻ {{ t('jobs.restart_selected')|e }}"
|
|
disabled
|
|
>↻ {{ t('jobs.restart_selected') }}</button>
|
|
<form method="get" action="/software" class="inline-form software-job-limit-form">
|
|
<label for="software-job-limit">{{ t('software.jobs_count') }}</label>
|
|
{% for filter_name, filter_value in job_filters.items() %}
|
|
{% if filter_value %}<input type="hidden" name="job_filter_{{ filter_name }}" value="{{ filter_value }}">{% endif %}
|
|
{% endfor %}
|
|
<select id="software-job-limit" name="job_limit" onchange="this.form.submit()">
|
|
{% for option in job_limit_options %}
|
|
<option value="{{ option }}" {% if option == job_limit %}selected{% endif %}>{{ option }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<noscript><button type="submit" class="button button-secondary button-small">{{ t('common.apply') }}</button></noscript>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<p class="muted software-job-filter-help">{{ t('software.jobs_filter_all_help') }}</p>
|
|
<form
|
|
id="restart-selected-jobs-form"
|
|
class="hidden-utility-form"
|
|
method="post"
|
|
action="/jobs/restart-selected"
|
|
data-confirm-template="{{ t('jobs.bulk_restart.confirm')|e }}"
|
|
><span id="restart-selected-job-ids"></span></form>
|
|
<div class="table-scroll management-table-scroll">
|
|
<table
|
|
class="data-table"
|
|
data-storage-key="software-jobs"
|
|
data-server-filters="1"
|
|
data-server-filter-url="/software"
|
|
data-server-filter-total="{{ jobs_filtered_total if jobs_filters_active else jobs|length }}"
|
|
data-restart-label="↻ {{ t('jobs.restart')|e }}"
|
|
data-restart-confirm="{{ t('jobs.restart.confirm')|e }}"
|
|
>
|
|
<thead><tr>
|
|
<th class="selection-column" data-no-sort="1" data-no-filter="1"><input type="checkbox" id="select-all-restartable-jobs" aria-label="{{ t('jobs.select_all_restartable')|e }}"></th>
|
|
<th data-server-filter-name="job_id" data-server-filter-value="{{ job_filters.job_id|e }}">{{ t('software.job_id') }}</th>
|
|
<th data-server-filter-name="created_at" data-server-filter-value="{{ job_filters.created_at|e }}">{{ t('software.time') }}</th>
|
|
<th data-server-filter-name="asset" data-server-filter-value="{{ job_filters.asset|e }}">{{ t('common.assets') }}</th>
|
|
<th data-server-filter-name="job_type" data-server-filter-value="{{ job_filters.job_type|e }}">{{ t('jobs.type') }}</th>
|
|
<th data-server-filter-name="package" data-server-filter-value="{{ job_filters.package|e }}">{{ t('software.package') }}</th>
|
|
<th data-server-filter-name="action" data-server-filter-value="{{ job_filters.action|e }}">{{ t('jobs.action') }}</th>
|
|
<th data-server-filter-name="priority" data-server-filter-value="{{ job_filters.priority|e }}">{{ t('jobs.priority') }}</th>
|
|
<th data-server-filter-name="platform" data-server-filter-value="{{ job_filters.platform|e }}">{{ t('software.platform') }}</th>
|
|
<th data-server-filter-name="status" data-server-filter-value="{{ job_filters.status|e }}">{{ t('software.status') }}</th>
|
|
<th>{{ t('software.details') }}</th>
|
|
<th>{{ t('jobs.actions') }}</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
{% for job in jobs %}
|
|
{% set can_bulk_restart = job.status not in ['success', 'sending', 'running'] and job.asset and job.asset.mesh_node_id %}
|
|
<tr data-job-id="{{ job.id }}" data-job-status="{{ job.status }}" data-job-has-node="{{ '1' if job.asset and job.asset.mesh_node_id else '0' }}">
|
|
<td class="selection-column"><input type="checkbox" class="software-job-restart-select" value="{{ job.id }}" aria-label="{{ t('jobs.select_for_restart', id=job.id)|e }}" {% if not can_bulk_restart %}disabled{% endif %}></td>
|
|
<td><a href="/jobs/{{ job.id }}"><code>{{ job.id }}</code></a></td>
|
|
<td>{% if job.created_at %}<time class="local-time" datetime="{{ utc_iso(job.created_at) }}" data-utc="{{ utc_iso(job.created_at) }}">{{ job.created_at }}</time>{% else %}{{ '' }}{% endif %}</td>
|
|
<td><a href="/assets/{{ job.asset.id }}?inventory_tab=software">{{ job.asset.name }}</a></td>
|
|
<td>{{ t(job.display_job_type_key, job.display_job_type_fallback) }}</td>
|
|
<td>{{ job.display_package_name }}</td>
|
|
<td>{{ t('jobs.action.' ~ job.action, job.action) }}</td>
|
|
<td>{{ job.priority }}</td>
|
|
<td>{{ job.platform }}</td>
|
|
<td><span class="job-status job-status-{{ job.status }}" data-job-status-field>{{ t('software.status.' ~ job.status, job.status) }}</span></td>
|
|
<td><a href="/jobs/{{ job.id }}">{{ t('software.open') }}</a></td>
|
|
<td data-job-restart-cell>{% if job.status not in ['sending', 'running'] %}<form method="post" action="/jobs/{{ job.id }}/restart" class="inline-form" onsubmit="return confirm({{ t('jobs.restart.confirm')|tojson }});"><button type="submit" class="button button-secondary button-small">↻ {{ t('jobs.restart') }}</button></form>{% else %}<span class="muted">—</span>{% endif %}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr><td colspan="12">{{ t('software.no_jobs') }}</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
<script src="/static/js/software-job-selection.js?v={{ app_version }}"></script>
|
|
<script src="/static/js/software-job-status.js?v={{ app_version }}"></script>
|
|
{% endblock %}
|