Closes #14871: Complete work on UI cleanup (#15341)

* Fix left padding of login button in top menu

* Relocate "add" buttons for embedded object tables

* Remove unused data template block & getNetboxData() utility function

* Remove bottom margin from last <p> element in rendered Markdown inside a table cell

* Prevent TomSelect from initializing on <select> elements with a size

* Fix styling of dropdown menu button for circuit commit rate

* Change .color-block to display: inline-block

* Delete unused static asset

* Improve contrast between menu group headings & items

* Remove custom color for attr-table row headings

* Fix border color of copy-to-clipboard button

* Fix toast text color in dark mode

* Fix rack elevation label/image toggles

* Increase border radius for small buttons

* Fix object selector
This commit is contained in:
Jeremy Stretch 2024-03-04 15:55:01 -05:00 committed by GitHub
parent 5a40437ef2
commit c684892a98
19 changed files with 33 additions and 50 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

View File

@ -18,11 +18,12 @@ function handleSelection(link: HTMLAnchorElement): void {
const value = link.getAttribute('data-value'); const value = link.getAttribute('data-value');
//@ts-ignore //@ts-ignore
target.slim.setData([ target.tomselect.addOption({
{text: label, value: value} id: value,
]); display: label,
const change = new Event('change'); });
target.dispatchEvent(change); //@ts-ignore
target.tomselect.addItem(value);
} }

View File

@ -42,7 +42,7 @@ function renderItem(data: TomOption, escape: typeof escape_html) {
// Initialize <select> elements which are populated via a REST API call // Initialize <select> elements which are populated via a REST API call
export function initDynamicSelects(): void { export function initDynamicSelects(): void {
for (const select of getElements<HTMLSelectElement>('select.api-select')) { for (const select of getElements<HTMLSelectElement>('select.api-select:not(.tomselected)')) {
new DynamicTomSelect(select, { new DynamicTomSelect(select, {
...config, ...config,
valueField: VALUE_FIELD, valueField: VALUE_FIELD,

View File

@ -7,7 +7,7 @@ import { getElements } from '../util';
// Initialize <select> elements with statically-defined options // Initialize <select> elements with statically-defined options
export function initStaticSelects(): void { export function initStaticSelects(): void {
for (const select of getElements<HTMLSelectElement>( for (const select of getElements<HTMLSelectElement>(
'select:not(.api-select):not(.color-select)', 'select:not(.tomselected):not(.no-ts):not([size]):not(.api-select):not(.color-select)',
)) { )) {
new TomSelect(select, { new TomSelect(select, {
...config, ...config,
@ -24,7 +24,7 @@ export function initColorSelects(): void {
)}"></span> ${escape(item.text)}</div>`; )}"></span> ${escape(item.text)}</div>`;
} }
for (const select of getElements<HTMLSelectElement>('select.color-select')) { for (const select of getElements<HTMLSelectElement>('select.color-select:not(.tomselected)')) {
new TomSelect(select, { new TomSelect(select, {
...config, ...config,
maxOptions: undefined, maxOptions: undefined,

View File

@ -244,29 +244,6 @@ export function getSelectedOptions<E extends HTMLElement>(
return selected; return selected;
} }
/**
* Get data that can only be accessed via Django context, and is thus already rendered in the HTML
* template.
*
* @see Templates requiring Django context data have a `{% block data %}` block.
*
* @param key Property name, which must exist on the HTML element. If not already prefixed with
* `data-`, `data-` will be prepended to the property.
* @returns Value if it exists, `null` if not.
*/
export function getNetboxData(key: string): string | null {
if (!key.startsWith('data-')) {
key = `data-${key}`;
}
for (const element of getElements('body > div#netbox-data > *')) {
const value = element.getAttribute(key);
if (isTruthy(value)) {
return value;
}
}
return null;
}
/** /**
* Toggle visibility of an element. * Toggle visibility of an element.
*/ */

View File

@ -28,6 +28,13 @@
} }
// Remove the bottom margin of <p> elements inside a table cell
td > .rendered-markdown {
p:last-of-type {
margin-bottom: 0;
}
}
// Markdown preview // Markdown preview
.markdown-widget { .markdown-widget {
.preview { .preview {

View File

@ -2,7 +2,7 @@
// Color labels // Color labels
span.color-label { span.color-label {
display: block; display: inline-block;
width: 5rem; width: 5rem;
height: 1rem; height: 1rem;
padding: $badge-padding-y $badge-padding-x; padding: $badge-padding-y $badge-padding-x;

View File

@ -9,6 +9,10 @@ pre {
// Tabler sets display: flex // Tabler sets display: flex
display: inline-block; display: inline-block;
} }
.btn-sm {
// $border-radius-sm (2px) is too small
border-radius: $border-radius;
}
// Tabs // Tabs
.nav-tabs { .nav-tabs {

View File

@ -23,7 +23,6 @@ table.attr-table {
// Restyle row header // Restyle row header
th { th {
color: $gray-700;
font-weight: normal; font-weight: normal;
width: min-content; width: min-content;
} }

View File

@ -70,10 +70,5 @@
{# User messages #} {# User messages #}
{% include 'inc/messages.html' %} {% include 'inc/messages.html' %}
{# Data container #}
<div id="netbox-data" style="display: none!important; visibility: hidden!important">
{% block data %}{% endblock %}
</div>
</body> </body>
</html> </html>

View File

@ -163,7 +163,7 @@
</div> </div>
<div class="col col-12 col-xl-7"> <div class="col col-12 col-xl-7">
<div class="text-end mb-4"> <div class="text-end mb-4">
<select class="btn btn-outline-dark rack-view"> <select class="btn btn-outline-secondary no-ts rack-view">
<option value="images-and-labels" selected="selected">{% trans "Images and Labels" %}</option> <option value="images-and-labels" selected="selected">{% trans "Images and Labels" %}</option>
<option value="images-only">{% trans "Images only" %}</option> <option value="images-only">{% trans "Images only" %}</option>
<option value="labels-only">{% trans "Labels only" %}</option> <option value="labels-only">{% trans "Labels only" %}</option>

View File

@ -11,13 +11,11 @@
<a href="{% url 'dcim:rack_list' %}{% querystring request %}" class="btn btn-primary"> <a href="{% url 'dcim:rack_list' %}{% querystring request %}" class="btn btn-primary">
<i class="mdi mdi-format-list-checkbox"></i> {% trans "View List" %} <i class="mdi mdi-format-list-checkbox"></i> {% trans "View List" %}
</a> </a>
<div class="btn-group" role="group"> <select class="btn btn-outline-secondary no-ts rack-view">
<select class="btn btn-outline-secondary rack-view">
<option value="images-and-labels" selected="selected">{% trans "Images and Labels" %}</option> <option value="images-and-labels" selected="selected">{% trans "Images and Labels" %}</option>
<option value="images-only">{% trans "Images only" %}</option> <option value="images-only">{% trans "Images only" %}</option>
<option value="labels-only">{% trans "Labels only" %}</option> <option value="labels-only">{% trans "Labels only" %}</option>
</select> </select>
</div>
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='front' %}" class="btn btn-outline-secondary{% if rack_face == 'front' %} active{% endif %}">{% trans "Front" %}</a> <a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='front' %}" class="btn btn-outline-secondary{% if rack_face == 'front' %} active{% endif %}">{% trans "Front" %}</a>
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='rear' %}" class="btn btn-outline-secondary{% if rack_face == 'rear' %} active{% endif %}">{% trans "Rear" %}</a> <a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='rear' %}" class="btn btn-outline-secondary{% if rack_face == 'rear' %} active{% endif %}">{% trans "Rear" %}</a>

View File

@ -1,6 +1,6 @@
{% load helpers %} {% load helpers %}
<div class="toast shadow-sm" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="10000"> <div class="toast toast-dark border-0 shadow-sm" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="10000">
<div class="toast-header text-bg-{{ status }}"> <div class="toast-header text-bg-{{ status }}">
<i class="mdi mdi-{{ status|icon_from_status }} me-1"></i> <i class="mdi mdi-{{ status|icon_from_status }} me-1"></i>
{{ title }} {{ title }}

View File

@ -36,7 +36,7 @@
{% elif 'data-clipboard' in field.field.widget.attrs %} {% elif 'data-clipboard' in field.field.widget.attrs %}
<div class="input-group"> <div class="input-group">
{{ field }} {{ field }}
<button type="button" title="{% trans "Copy to clipboard" %}" class="btn btn-outline-dark copy-content" data-clipboard-target="#{{ field.id_for_label }}"> <button type="button" title="{% trans "Copy to clipboard" %}" class="btn copy-content" data-clipboard-target="#{{ field.id_for_label }}">
<i class="mdi mdi-content-copy"></i> <i class="mdi mdi-content-copy"></i>
</button> </button>
</div> </div>

View File

@ -19,7 +19,7 @@
<div class="dropdown-menu-columns"> <div class="dropdown-menu-columns">
<div class="dropdown-menu-column pb-2"> <div class="dropdown-menu-column pb-2">
{% for group, items in groups %} {% for group, items in groups %}
<div class="text-uppercase fw-bold fs-5 ps-3 pt-3 pb-1"> <div class="text-uppercase text-secondary fw-bold fs-5 ps-3 pt-3 pb-1">
{{ group.label }} {{ group.label }}
</div> </div>
{% for item, buttons in items %} {% for item, buttons in items %}

View File

@ -1,6 +1,8 @@
<div class="input-group"> <div class="input-group">
{% include 'django/forms/widgets/number.html' %} {% include 'django/forms/widgets/number.html' %}
<button type="button" class="btn btn-outline-dark dropdown-toggle" data-bs-toggle="dropdown"></button> <button type="button" class="btn" data-bs-toggle="dropdown">
<i class="mdi mdi-chevron-down"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end"> <ul class="dropdown-menu dropdown-menu-end">
{% for value, label in widget.options %} {% for value, label in widget.options %}
<li> <li>