Merge branch 'feature' into 6000-cable-trace-svg

This commit is contained in:
jeremystretch 2021-07-16 16:46:32 -04:00
commit 145be09cfd
51 changed files with 468 additions and 324 deletions

View File

@ -27,7 +27,7 @@ For JavaScript, every `.ts` file in `netbox/project-static/src` is:
2. Minified 2. Minified
3. Combined into a single output file at `netbox/project-static/dist/netbox.js` (this includes any dependant libraries imported in a file) 3. Combined into a single output file at `netbox/project-static/dist/netbox.js` (this includes any dependant libraries imported in a file)
Likewise, with Sass, each `*.scss` file is: Likewise, with Sass, every `.scss` file in `netbox/project-static/styles` is:
1. Transpiled from Sass to CSS 1. Transpiled from Sass to CSS
2. Minified 2. Minified

View File

@ -27,11 +27,11 @@ if (args.includes('--no-cache')) {
// Style (SCSS) bundle jobs. Generally, everything should be bundled into netbox.css from main.scss // Style (SCSS) bundle jobs. Generally, everything should be bundled into netbox.css from main.scss
// unless there is a specific reason to do otherwise. // unless there is a specific reason to do otherwise.
const styles = [ const styles = [
['_external.scss', 'netbox-external.css'], ['styles/_external.scss', 'netbox-external.css'],
['_light.scss', 'netbox-light.css'], ['styles/_light.scss', 'netbox-light.css'],
['_dark.scss', 'netbox-dark.css'], ['styles/_dark.scss', 'netbox-dark.css'],
['_elevations.scss', 'rack_elevation.css'], ['styles/_elevations.scss', 'rack_elevation.css'],
['_cable_trace.scss', 'cable_trace.css'], ['styles/_cable_trace.scss', 'cable_trace.css'],
]; ];
// Script (JavaScript) bundle jobs. Generally, everything should be bundled into netbox.js from // Script (JavaScript) bundle jobs. Generally, everything should be bundled into netbox.js from

View File

@ -1 +1 @@
{"version":3,"sources":["_cable_trace.scss"],"names":[],"mappings":"AAAA,EACI,sBAAA,CACA,eAEJ,KACI,kBAAA,CACA,yBAEJ,UACE,gBAKA,SACE,YAAA,CACA,cAAA,CACA,eACA,sBACE,aAKJ,oBACE,kBAEF,SACE,iBAEF,sBACE,cAAA,CACA,iBAEF,oBACE,aAAA,CACA","file":"cable_trace.css","sourceRoot":"..","sourcesContent":["* {\n font-family: sans-serif;\n font-size: 14px;\n}\ntext {\n text-anchor: middle;\n dominant-baseline: middle;\n}\ntext.bold {\n font-weight: bold;\n}\n\nsvg {\n /* Boxes */\n rect {\n fill: #e0e0e0;\n stroke: #606060;\n stroke-width: 1;\n .termination {\n fill: #f0f0f0;\n }\n }\n\n /* Connectors */\n .connector text {\n text-anchor: start;\n }\n line {\n stroke-width: 5px;\n }\n line.cable-shadow {\n stroke: #303030;\n stroke-width: 7px;\n }\n line.attachment {\n stroke: #c0c0c0;\n stroke-dasharray: 5px,5px;\n }\n}\n"]} {"version":3,"sources":["_cable_trace.scss"],"names":[],"mappings":"AAAA,EACI,sBAAA,CACA,eAEJ,KACI,kBAAA,CACA,yBAEJ,UACE,gBAKA,SACE,YAAA,CACA,cAAA,CACA,eACA,sBACE,aAKJ,oBACE,kBAEF,SACE,iBAEF,sBACE,cAAA,CACA,iBAEF,oBACE,aAAA,CACA","file":"cable_trace.css","sourceRoot":"../styles","sourcesContent":["* {\n font-family: sans-serif;\n font-size: 14px;\n}\ntext {\n text-anchor: middle;\n dominant-baseline: middle;\n}\ntext.bold {\n font-weight: bold;\n}\n\nsvg {\n /* Boxes */\n rect {\n fill: #e0e0e0;\n stroke: #606060;\n stroke-width: 1;\n .termination {\n fill: #f0f0f0;\n }\n }\n\n /* Connectors */\n .connector text {\n text-anchor: start;\n }\n line {\n stroke-width: 5px;\n }\n line.cable-shadow {\n stroke: #303030;\n stroke-width: 7px;\n }\n line.attachment {\n stroke: #c0c0c0;\n stroke-dasharray: 5px,5px;\n }\n}\n"]}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -117,13 +117,41 @@ function initTabs() {
} }
} }
/**
* When accordion buttons are clicked, add a class to the parent accordion item. This is used
* for the side navigation to apply a box-shadow when the section is open.
*/
function initSidebarAccordions(): void {
const items = document.querySelectorAll<HTMLDivElement>('.sidebar .accordion-item');
function handleToggle(thisItem: HTMLDivElement) {
for (const item of items) {
if (item !== thisItem) {
// Remove the is-open class from all other accordion items, so that if one is clicked while
// another is open, the shadow is removed.
item.classList.remove('is-open');
} else {
item.classList.toggle('is-open');
}
}
}
for (const item of items) {
for (const button of item.querySelectorAll<HTMLButtonElement>('.accordion-button')) {
button.addEventListener('click', () => {
handleToggle(item);
});
}
}
}
/** /**
* Enable any defined Bootstrap Tooltips. * Enable any defined Bootstrap Tooltips.
* *
* @see https://getbootstrap.com/docs/5.0/components/tooltips * @see https://getbootstrap.com/docs/5.0/components/tooltips
*/ */
export function initBootstrap(): void { export function initBootstrap(): void {
for (const func of [initTooltips, initModals, initMasonry, initTabs]) { for (const func of [initTooltips, initModals, initMasonry, initTabs, initSidebarAccordions]) {
func(); func();
} }
} }

View File

@ -0,0 +1,15 @@
import { isTruthy, getElements } from './util';
/**
* Allow any element to be made "clickable" with the use of the `data-href` attribute.
*/
export function initLinks() {
for (const link of getElements('*[data-href]')) {
const href = link.getAttribute('data-href');
if (isTruthy(href)) {
link.addEventListener('click', () => {
window.location.assign(href);
});
}
}
}

View File

@ -11,6 +11,7 @@ import { initTableConfig } from './tableConfig';
import { initInterfaceTable } from './tables'; import { initInterfaceTable } from './tables';
import { initSideNav } from './sidenav'; import { initSideNav } from './sidenav';
import { initRackElevation } from './racks'; import { initRackElevation } from './racks';
import { initLinks } from './links';
function init() { function init() {
for (const init of [ for (const init of [
@ -27,6 +28,7 @@ function init() {
initInterfaceTable, initInterfaceTable,
initSideNav, initSideNav,
initRackElevation, initRackElevation,
initLinks,
]) { ]) {
init(); init();
} }

View File

@ -98,7 +98,11 @@
margin-bottom: $spacer; margin-bottom: $spacer;
} }
// Use proper contrasting color for badge & progress-bar foreground color. *[data-href] {
cursor: pointer;
}
// Use proper contrasting color foreground color for special components.
@each $color, $value in $theme-colors { @each $color, $value in $theme-colors {
.badge, .badge,
.toast, .toast,
@ -107,6 +111,16 @@
color: color-contrast($value); color: color-contrast($value);
} }
} }
// Use proper foreground color in the alert body. Note: this is applied to a, p, & small because
// we *don't* want to override the h1-h6 colors for alerts, since those are set to a color
// similar to the alert color.
.alert.alert-#{$color} {
a,
p,
small {
color: color-contrast($value);
}
}
} }
// Ensure progress bars (utilization graph) in tables aren't too narrow to display the percentage. // Ensure progress bars (utilization graph) in tables aren't too narrow to display the percentage.
@ -114,6 +128,62 @@ table td > .progress {
min-width: 6rem; min-width: 6rem;
} }
.card > .table.table-flush {
margin-bottom: 0;
overflow: hidden;
border-bottom-right-radius: $card-border-radius;
border-bottom-left-radius: $card-border-radius;
thead th[scope='col'] {
background-color: $table-flush-header-bg;
vertical-align: middle;
text-transform: uppercase;
padding-top: map.get($spacers, 3);
padding-bottom: map.get($spacers, 3);
border-bottom-color: $card-border-color;
border-top: 1px solid $card-border-color;
}
th,
td {
border-left: 0;
border-right: 0;
padding-left: map.get($spacers, 4) !important;
padding-right: map.get($spacers, 4) !important;
}
tr[class] {
border-color: $card-border-color !important;
&:last-of-type {
border-bottom-color: transparent !important;
border-bottom-right-radius: $card-border-radius;
border-bottom-left-radius: $card-border-radius;
}
}
}
// Primarily used for the new release notification, but could be used for other alerts as needed.
// Wrap any alerts in .header-alert-container to ensure the layout is consistent.
.header-alert-container {
// Center-align the alert(s).
display: flex;
justify-content: center;
align-items: center;
// Apply the same spacing that's applied to the #content div's first child (.px-3).
padding: 0 $spacer;
// By default, alerts inside .header-alert-container should take up the full width.
.alert {
width: 100%;
// Adjust the max-width for larger screens so there's not a big ugly blue blob taking up the
// entire screen.
@include media-breakpoint-up(md) {
max-width: 75%;
}
@include media-breakpoint-up(lg) {
max-width: 50%;
}
}
}
span.profile-button .dropdown-menu { span.profile-button .dropdown-menu {
transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out;
display: block !important; display: block !important;
@ -441,6 +511,12 @@ div.content-container {
div.accordion-item { div.accordion-item {
border: unset; border: unset;
padding: 0 $spacer / 2;
// When an sidenav section is open, apply a shadow to provide a visual border.
&.is-open {
box-shadow: inset 0px -25px 20px -25px rgba($black, 0.25);
}
& > a.accordion-button { & > a.accordion-button {
&:not(.collapsed) { &:not(.collapsed) {
@ -483,13 +559,13 @@ div.content-container {
} }
} }
div.position-sticky { div.position-sticky {
height: calc(100vh - 8rem); height: calc(100vh - #{$sidebar-bottom-height});
} }
div.sidebar-bottom { div.sidebar-bottom {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
position: sticky; position: sticky;
height: 8rem; height: $sidebar-bottom-height;
background-color: var(--nbx-sidebar-bg); background-color: var(--nbx-sidebar-bg);
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
@ -699,10 +775,38 @@ label.required {
} }
} }
// Applied to containing element around table bulk-action buttons (bulk-edit, bulk-disconnect
// bulk-delete, etc). Each usage of .bulk-buttons needs to have groups of buttons wrapped with
// .bulk-button-group so that proper spacing is applied (even if there is only one group).
div.bulk-buttons { div.bulk-buttons {
display: flex; display: flex;
& > * { justify-content: space-between;
margin: $spacer / 4; margin: $spacer / 2 0;
// Each group of buttons needs to be contained separately for alignment purposes. This way, you
// can put some buttons in a group that aligns left, and other buttons in a group that aligns
// right.
& > div.bulk-button-group {
display: flex;
&:first-of-type:not(:last-of-type) {
// If there are multiple bulk button groups and this is the first, the first button in the
// group should *not* have left spacing applied, so the button group aligns with the rest
// of the page elements.
& > *:first-child {
margin-left: 0;
}
}
&:last-of-type:not(:first-of-type) {
// If there are multiple bulk button groups and this is the last, the last button in the
// group should *not* have right spacing applied, so the button group aligns with the rest
// of the page elements.
& > *:last-child {
margin-right: 0;
}
}
// However, the rest of the buttons should have spacing applied in all directions.
& > * {
margin: $spacer / 4;
}
} }
} }

View File

@ -245,3 +245,4 @@ $accordion-padding-y: 0.8125rem;
$accordion-padding-x: 0.8125rem; $accordion-padding-x: 0.8125rem;
$sidebar-width: 280px; $sidebar-width: 280px;
$sidebar-bottom-height: 4rem;

View File

@ -63,6 +63,7 @@ $table-active-color: $table-color;
$table-active-bg: rgba($white, $table-active-bg-factor); $table-active-bg: rgba($white, $table-active-bg-factor);
$table-hover-color: $table-color; $table-hover-color: $table-color;
$table-hover-bg: rgba($white, $table-hover-bg-factor); $table-hover-bg: rgba($white, $table-hover-bg-factor);
$table-flush-header-bg: $gray-700;
// Buttons // Buttons
$btn-box-shadow: inset 0 1px 0 rgba($black, 0.15), 0 1px 1px rgba($white, 0.075); $btn-box-shadow: inset 0 1px 0 rgba($black, 0.15), 0 1px 1px rgba($white, 0.075);

View File

@ -28,3 +28,5 @@ $code-color: $gray-900;
$list-group-color: $gray-700; $list-group-color: $gray-700;
$list-group-disabled-color: $gray-500; $list-group-disabled-color: $gray-500;
$table-flush-header-bg: $gray-100;

View File

@ -21,7 +21,7 @@
</a> </a>
</div> </div>
<ul class="nav flex-column px-1"> <ul class="nav flex-column">
{# Search bar for collapsed menu #} {# Search bar for collapsed menu #}
<div class="d-block d-md-none mx-1 my-3 search-container"> <div class="d-block d-md-none mx-1 my-3 search-container">
@ -120,7 +120,6 @@
{# Page footer #} {# Page footer #}
<footer class="footer container-fluid pb-3 pt-4 px-0"> <footer class="footer container-fluid pb-3 pt-4 px-0">
<div class="row align-items-center justify-content-end mx-0"> <div class="row align-items-center justify-content-end mx-0">
<div class="col-auto d-none d-md-block"></div>
<div class="col text-center small text-muted"> <div class="col text-center small text-muted">
<span class="fw-light d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span> <span class="fw-light d-block d-md-inline">{% annotated_now %} {% now 'T' %}</span>
<span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span> <span class="ms-md-3 d-block d-md-inline">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</span>

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceConsolePortTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceConsolePortTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table consoleport_table 'inc/table.html' %} {% render_table consoleport_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_consoleport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:consoleport_bulk_rename' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_consoleport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:consoleport_bulk_rename' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:consoleport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:consoleport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleport_bulk_disconnect' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleport_bulk_disconnect' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_consoleport %} {% endif %}
<button type="submit" name="_delete" formaction="{% url 'dcim:consoleport_bulk_delete' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_consoleport %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" name="_delete" formaction="{% url 'dcim:consoleport_bulk_delete' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_consoleport %} {% if perms.dcim.add_consoleport %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:consoleport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-sm btn-primary"> <a href="{% url 'dcim:consoleport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Console Port <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Console Port
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=consoleport_table.paginator page=consoleport_table.page %} {% include 'inc/paginator.html' with paginator=consoleport_table.paginator page=consoleport_table.page %}

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceConsoleServerPortTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceConsoleServerPortTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table consoleserverport_table 'inc/table.html' %} {% render_table consoleserverport_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_consoleserverport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:consoleserverport_bulk_rename' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_consoleserverport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:consoleserverport_bulk_rename' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:consoleserverport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:consoleserverport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleserverport_bulk_disconnect' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleserverport_bulk_disconnect' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_consoleserverport %} {% endif %}
<button type="submit" formaction="{% url 'dcim:consoleserverport_bulk_delete' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_consoleserverport %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" formaction="{% url 'dcim:consoleserverport_bulk_delete' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_consoleserverport %} {% if perms.dcim.add_consoleserverport %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:consoleserverport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:consoleserverport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Console Server Ports <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Console Server Ports
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=consoleserverport_table.paginator page=consoleserverport_table.page %} {% include 'inc/paginator.html' with paginator=consoleserverport_table.paginator page=consoleserverport_table.page %}

View File

@ -6,34 +6,31 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceDeviceBayTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceDeviceBayTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table devicebay_table 'inc/table.html' %} {% render_table devicebay_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_devicebay %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:devicebay_bulk_rename' %}?return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_devicebay %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:devicebay_bulk_rename' %}?return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:devicebay_bulk_edit' %}?device={{ object.pk }}&return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:devicebay_bulk_edit' %}?device={{ object.pk }}&return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
{% endif %} </button>
{% if perms.dcim.delete_devicebay %} {% endif %}
<button type="submit" formaction="{% url 'dcim:devicebay_bulk_delete' %}?return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-outline-danger btn-sm"> {% if perms.dcim.delete_devicebay %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete selected <button type="submit" formaction="{% url 'dcim:devicebay_bulk_delete' %}?return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-outline-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete selected
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_devicebay %} {% if perms.dcim.add_devicebay %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:devicebay_add' %}?device={{ object.pk }}&return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:devicebay_add' %}?device={{ object.pk }}&return_url={{ object.get_absolute_url }}%23tab_devicebays" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Device Bays <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Device Bays
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=devicebay_table.paginator page=devicebay_table.page %} {% include 'inc/paginator.html' with paginator=devicebay_table.paginator page=devicebay_table.page %}

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceFrontPortTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceFrontPortTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table frontport_table 'inc/table.html' %} {% render_table frontport_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_frontport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:frontport_bulk_rename' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_frontport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:frontport_bulk_rename' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:frontport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:frontport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:frontport_bulk_disconnect' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:frontport_bulk_disconnect' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_frontport %} {% endif %}
<button type="submit" formaction="{% url 'dcim:frontport_bulk_delete' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_frontport %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" formaction="{% url 'dcim:frontport_bulk_delete' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_frontport %} {% if perms.dcim.add_frontport %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:frontport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:frontport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add front ports <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add front ports
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=frontport_table.paginator page=frontport_table.page %} {% include 'inc/paginator.html' with paginator=frontport_table.paginator page=frontport_table.page %}

View File

@ -6,30 +6,37 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end col-md-4 noprint table-controls mw-33"> <div class="row mb-3 justify-content-between">
<div class="input-group input-group-sm"> <div class="col col-md-2 float-end noprint table-controls mb-0 mw-33">
<input type="text" class="form-control interface-filter" placeholder="Filter" title="Filter text (regular expressions supported)" /> <div class="input-group input-group-sm">
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="mdi mdi-table-cog"></i>
</button>
<ul class="dropdown-menu">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<button <button
type="button" type="button"
class="dropdown-item" class="btn btn-sm btn-outline-dark"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#DeviceInterfaceTable_config" data-bs-target="#DeviceInterfaceTable_config"
title="Configure Table"> title="Configure Table">
Configure Table <i class="mdi mdi-cog"></i> Configure Table
</button> </button>
{% endif %} {% endif %}
<button type="button" class="dropdown-item toggle-enabled" data-state="show">Hide Enabled</button> <button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<button type="button" class="dropdown-item toggle-disabled" data-state="show">Hide Disabled</button> <i class="mdi mdi-eye"></i>
</ul> </button>
<ul class="dropdown-menu">
<button type="button" class="dropdown-item toggle-enabled" data-state="show">Hide Enabled</button>
<button type="button" class="dropdown-item toggle-disabled" data-state="show">Hide Disabled</button>
</ul>
</div>
</div>
<div class="col col-md-4 float-end noprint table-controls mw-33">
<div class="input-group input-group-sm">
<input type="text" class="form-control interface-filter" placeholder="Filter" title="Filter text (regular expressions supported)" />
</div>
</div> </div>
</div> </div>
{% render_table interface_table 'inc/table.html' %} {% render_table interface_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
<div class="bulk-button-group">
{% if perms.dcim.change_interface %} {% if perms.dcim.change_interface %}
<button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> <button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
@ -46,14 +53,14 @@
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
</button> </button>
{% endif %} {% endif %}
</div>
{% if perms.dcim.add_interface %} {% if perms.dcim.add_interface %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:interface_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_interfaces' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:interface_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_interfaces' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Interfaces <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Interfaces
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=interface_table.paginator page=interface_table.page %} {% include 'inc/paginator.html' with paginator=interface_table.paginator page=interface_table.page %}

View File

@ -6,28 +6,26 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceInventoryItemTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceInventoryItemTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table inventoryitem_table 'inc/table.html' %} {% render_table inventoryitem_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_inventoryitem %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:inventoryitem_bulk_rename' %}?return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-warning btn-sm"> {% if perms.dcim.change_inventoryitem %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:inventoryitem_bulk_rename' %}?return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:inventoryitem_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:inventoryitem_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
{% endif %} </button>
{% if perms.dcim.delete_inventoryitem %} {% endif %}
<button type="submit" name="_delete" formaction="{% url 'dcim:inventoryitem_bulk_delete' %}?return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_inventoryitem %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" name="_delete" formaction="{% url 'dcim:inventoryitem_bulk_delete' %}?return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_inventoryitem %} {% if perms.dcim.add_inventoryitem %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:inventoryitem_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:inventoryitem_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Inventory Item <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Inventory Item
</a> </a>

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DevicePowerOutletTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DevicePowerOutletTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table poweroutlet_table 'inc/table.html' %} {% render_table poweroutlet_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_powerport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:poweroutlet_bulk_rename' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_powerport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:poweroutlet_bulk_rename' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:poweroutlet_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:poweroutlet_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:poweroutlet_bulk_disconnect' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:poweroutlet_bulk_disconnect' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_poweroutlet %} {% endif %}
<button type="submit" formaction="{% url 'dcim:poweroutlet_bulk_delete' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_poweroutlet %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" formaction="{% url 'dcim:poweroutlet_bulk_delete' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_poweroutlet %} {% if perms.dcim.add_poweroutlet %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:poweroutlet_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:poweroutlet_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Power Outlets <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Power Outlets
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=poweroutlet_table.paginator page=poweroutlet_table.page %} {% include 'inc/paginator.html' with paginator=poweroutlet_table.paginator page=poweroutlet_table.page %}

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DevicePowerPortTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DevicePowerPortTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table powerport_table 'inc/table.html' %} {% render_table powerport_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_powerport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:powerport_bulk_rename' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_powerport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:powerport_bulk_rename' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:powerport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:powerport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:powerport_bulk_disconnect' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:powerport_bulk_disconnect' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_powerport %} {% endif %}
<button type="submit" name="_delete" formaction="{% url 'dcim:powerport_bulk_delete' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_powerport %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" name="_delete" formaction="{% url 'dcim:powerport_bulk_delete' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_powerport %} {% if perms.dcim.add_powerport %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:powerport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-sm btn-primary"> <a href="{% url 'dcim:powerport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add power port <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Power Port
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=powerport_table.paginator page=powerport_table.page %} {% include 'inc/paginator.html' with paginator=powerport_table.paginator page=powerport_table.page %}

View File

@ -6,37 +6,34 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end noprint"> {% include 'inc/table_controls.html' with table_modal="DeviceRearPortTable_config" %}
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#DeviceRearPortTable_config" title="Configure table"><i class="mdi mdi-cog"></i> Configure</button>
{% endif %}
</div>
{% render_table rearport_table 'inc/table.html' %} {% render_table rearport_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint bulk-buttons">
{% if perms.dcim.change_rearport %} <div class="bulk-button-group">
<button type="submit" name="_rename" formaction="{% url 'dcim:rearport_bulk_rename' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-outline-warning btn-sm"> {% if perms.dcim.change_rearport %}
<i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename <button type="submit" name="_rename" formaction="{% url 'dcim:rearport_bulk_rename' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-outline-warning btn-sm">
</button> <i class="mdi mdi-pencil-outline" aria-hidden="true"></i> Rename
<button type="submit" name="_edit" formaction="{% url 'dcim:rearport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-warning btn-sm"> </button>
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit <button type="submit" name="_edit" formaction="{% url 'dcim:rearport_bulk_edit' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
<button type="submit" name="_disconnect" formaction="{% url 'dcim:rearport_bulk_disconnect' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-outline-danger btn-sm"> </button>
<span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect <button type="submit" name="_disconnect" formaction="{% url 'dcim:rearport_bulk_disconnect' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-outline-danger btn-sm">
</button> <span class="mdi mdi-ethernet-cable-off" aria-hidden="true"></span> Disconnect
{% endif %} </button>
{% if perms.dcim.delete_rearport %} {% endif %}
<button type="submit" formaction="{% url 'dcim:rearport_bulk_delete' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-danger btn-sm"> {% if perms.dcim.delete_rearport %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete <button type="submit" formaction="{% url 'dcim:rearport_bulk_delete' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
{% endif %} </button>
{% endif %}
</div>
{% if perms.dcim.add_rearport %} {% if perms.dcim.add_rearport %}
<div class="float-end"> <div class="bulk-button-group">
<a href="{% url 'dcim:rearport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-primary btn-sm"> <a href="{% url 'dcim:rearport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add rear ports <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add rear ports
</a> </a>
</div> </div>
{% endif %} {% endif %}
<div class="clearfix"></div>
</div> </div>
</form> </form>
{% include 'inc/paginator.html' with paginator=rearport_table.paginator page=rearport_table.page %} {% include 'inc/paginator.html' with paginator=rearport_table.paginator page=rearport_table.page %}

View File

@ -23,17 +23,17 @@
<i class="mdi mdi-file-image-outline"></i> <i class="mdi mdi-file-image-outline"></i>
Hide Images Hide Images
</button> </button>
<a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-sm btn-primary m-1"> <a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}{% endif %}" class="btn btn-sm btn-primary m-1{% if not prev_rack %} disabled{% endif %}">
<i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous Rack <i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous Rack
</a> </a>
<a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}"{% else %}disabled="disabled"{% endif %} class="btn btn-sm btn-primary m-1"> <a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}{% endif %}" class="btn btn-sm btn-primary m-1{% if not next_rack %} disabled{% endif %}">
<i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next Rack <i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next Rack
</a> </a>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col col-md-6"> <div class="col col-12 col-xl-6">
<div class="card"> <div class="card">
<h5 class="card-header"> <h5 class="card-header">
Rack Rack
@ -310,7 +310,7 @@
</div> </div>
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-6"> <div class="col col-12 col-xl-6">
<div class="row" style="margin-bottom: 20px"> <div class="row" style="margin-bottom: 20px">
<div class="col col-md-6 col-sm-6 col-xs-12 text-center"> <div class="col col-md-6 col-sm-6 col-xs-12 text-center">
<div style="margin-left: 30px"> <div style="margin-left: 30px">

View File

@ -15,23 +15,6 @@
<li class="breadcrumb-item">{{ object }}</li> <li class="breadcrumb-item">{{ object }}</li>
{% endblock %} {% endblock %}
{% block header %}
<div class="row noprint">
<div class="col col-sm-4 col-md-3">
<form action="{% url 'extras:objectchange_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="mdi mdi-magnify" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
{% endblock %}
{% block content %} {% block content %}
<div class="row mb-3"> <div class="row mb-3">
<div class="col col-md-5"> <div class="col col-md-5">

View File

@ -58,27 +58,7 @@
{% endif %} {% endif %}
{# Object list filter, table config #} {# Object list filter, table config #}
<div class="row mb-3"> {% include 'inc/table_controls.html' with table_modal="ObjectTable_config" %}
<div class="col col-md-4 offset-md-8 d-flex noprint table-controls">
<div class="input-group input-group-sm">
<input type="text" class="form-control object-filter" placeholder="Filter" title="Filter text (regular expressions supported)" />
{% if request.user.is_authenticated and table_config_form %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#ObjectTable_config" title="Configure Table">
<i class="mdi mdi-table-eye"></i>
</button>
{% endif %}
{% if filter_form %}
<button
type="button"
class="btn btn-sm btn-outline-dark"
data-bs-toggle="collapse"
data-bs-target="#advanced-search-content">
Advanced Search
</button>
{% endif %}
</div>
</div>
</div>
{# Object table #} {# Object table #}
<div class="row"> <div class="row">
@ -91,18 +71,20 @@
<div class="table-responsive"> <div class="table-responsive">
{% render_table table 'inc/table.html' %} {% render_table table 'inc/table.html' %}
</div> </div>
<div class="float-start noprint bulk-buttons"> <div class="noprint bulk-buttons">
{% block bulk_buttons %}{% endblock %} <div class="bulk-button-group">
{% if bulk_edit_url and permissions.change %} {% block bulk_buttons %}{% endblock %}
<button type="submit" name="_edit" formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-warning btn-sm"> {% if bulk_edit_url and permissions.change %}
<i class="mdi mdi-pencil" aria-hidden="true"></i> Edit Selected <button type="submit" name="_edit" formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-warning btn-sm">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit Selected
{% endif %} </button>
{% if bulk_delete_url and permissions.delete %} {% endif %}
<button type="submit" name="_delete" formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-sm"> {% if bulk_delete_url and permissions.delete %}
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete Selected <button type="submit" name="_delete" formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-sm">
</button> <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete Selected
{% endif %} </button>
{% endif %}
</div>
</div> </div>
</form> </form>
{% else %} {% else %}

View File

@ -2,7 +2,25 @@
{% load get_status %} {% load get_status %}
{% load helpers %} {% load helpers %}
{% block header %}{% endblock %} {% block header %}
{{ block.super }}
{% if new_release %}
{# new_release is set only if the current user is a superuser or staff member #}
<div class="header-alert-container">
<div class="alert alert-info text-center mw-md-50" role="alert">
<h6 class="alert-heading">
<i class="mdi mdi-information-outline"></i><br/>New Release Available
</h6>
<small><a href="{{ new_release.url }}">NetBox v{{ new_release.version }}</a> is available.</small>
<hr class="my-2" />
<small class="mb-0">
<a href="https://netbox.readthedocs.io/en/stable/installation/upgrading/">Upgrade Instructions</a>
</small>
</div>
</div>
{% endif %}
{% endblock %}
{% block title %}Home{% endblock %} {% block title %}Home{% endblock %}
{% block content %} {% block content %}
@ -35,47 +53,42 @@
{# Changelog #} {# Changelog #}
<div class="row my-4 flex-grow-1 changelog-container"> <div class="row my-4 flex-grow-1 changelog-container">
<div class="col"> <div class="col">
<h5 class="text-center">Changelog</h5> <div class="card">
{% if changelog and perms.extras.view_objectchange %} <h6 class="card-header text-primary text-center">Changelog</h6>
{# TODO: Replace this with a django-tables2 Table #} {% if changelog and perms.extras.view_objectchange %}
<table class="table align-middle table-hover"> {# TODO: Replace this with a django-tables2 Table #}
<thead> <table class="table table-flush align-middle table-hover">
<tr> <thead>
<th scope="col">User</th> <tr>
<th scope="col">Action</th> <th scope="col">User</th>
<th scope="col">Type</th> <th scope="col">Action</th>
<th scope="col">Object</th> <th scope="col">Type</th>
<th scope="col">Time</th> <th scope="col">Object</th>
<th scope="col" align="right"></th> <th scope="col">Time</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for change in changelog %} {% for change in changelog %}
<tr class="{% get_status change.get_action_display %}"> <tr class="{% get_status change.get_action_display %}" data-href="{{ change.get_absolute_url }}">
<th scope="row">{{ change.user|default:change.user_name }}</th> <th scope="row">{{ change.user|default:change.user_name }}</th>
<td>{{ change.get_action_display|bettertitle }}</td> <td>{{ change.get_action_display|bettertitle }}</td>
<td>{{ change.changed_object_type.name|bettertitle }}</td> <td>{{ change.changed_object_type.name|bettertitle }}</td>
<td> <td>
{% if change.changed_object.get_absolute_url %} {% if change.changed_object.get_absolute_url %}
<a class="text-body" href="{{ change.changed_object.get_absolute_url }}">{{ change.changed_object }}</a> <a class="text-body" href="{{ change.changed_object.get_absolute_url }}">{{ change.changed_object }}</a>
{% else %} {{ change.changed_object|default:change.object_repr }} {% endif %} {% else %} {{ change.changed_object|default:change.object_repr }} {% endif %}
</td> </td>
<td>{{ change.time|date:'SHORT_DATETIME_FORMAT' }}</td>
<td>{{ change.time|date:'SHORT_DATETIME_FORMAT' }}</td> </tr>
<td> {% endfor %}
<a role="button" class="text-body" href="{{ change.get_absolute_url }}"> </tbody>
<i class="mdi mdi-dots-horizontal" data-bs-toggle="tooltip" data-bs-placement="left" title="View Change Details"></i> </table>
</a> {% elif perms.extras.view_objectchange %}
</td> <div class="alert alert-secondary mt-4" role="alert">
</tr> No change history found.
{% endfor %} </div>
</tbody> {% endif %}
</table>
{% elif perms.extras.view_objectchange %}
<div class="alert alert-secondary mt-4" role="alert">
No change history found.
</div> </div>
{% endif %}
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,37 @@
<div class="row mb-3 justify-content-between">
<div class="col col-md-2 mb-0 d-flex noprint table-controls">
{% if request.user.is_authenticated %}
<div class="input-group input-group-sm">
<button
type="button"
data-bs-toggle="modal"
title="Configure Table"
data-bs-target="#{{ table_modal }}"
class="btn btn-sm btn-outline-dark"
>
<i class="mdi mdi-cog"></i> Configure Table
</button>
</div>
{% endif %}
</div>
<div class="col col-md-4 d-flex noprint table-controls">
<div class="input-group input-group-sm">
<input
type="text"
class="form-control object-filter"
placeholder="Filter"
title="Filter text (regular expressions supported)"
/>
{% if filter_form %}
<button
type="button"
class="btn btn-sm btn-outline-dark"
data-bs-toggle="collapse"
data-bs-target="#advanced-search-content"
>
Advanced Search
</button>
{% endif %}
</div>
</div>
</div>

View File

@ -6,14 +6,7 @@
{% block content %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="float-end col-md-4 noprint table-controls mw-33"> {% include 'inc/table_controls.html' with table_modal="VirtualMachineVMInterfaceTable_config" %}
<div class="input-group input-group-sm">
<input type="text" class="form-control interface-filter" placeholder="Filter" title="Filter text (regular expressions supported)" />
{% if request.user.is_authenticated %}
<button type="button" class="btn btn-outline-dark btn-sm" data-bs-toggle="modal" data-bs-target="#VirtualMachineVMInterfaceTable_config" title="Configure Table"><i class="mdi mdi-table-eye"></i></button>
{% endif %}
</div>
</div>
{% render_table interface_table 'inc/table.html' %} {% render_table interface_table 'inc/table.html' %}
<div class="noprint"> <div class="noprint">
{% if perms.virtualization.change_vminterface %} {% if perms.virtualization.change_vminterface %}