Add visibility toggle for object depth indicators

This commit is contained in:
Matt
2021-08-18 14:46:49 -07:00
parent 46ad68a3a0
commit a2205ebdc8
6 changed files with 99 additions and 10 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,6 @@
import { createToast } from './bs'; import { createToast } from './bs';
import { setColorMode } from './colorMode'; import { setColorMode } from './colorMode';
import { objectDepthState } from './stores';
import { import {
slugify, slugify,
isTruthy, isTruthy,
@@ -10,6 +11,10 @@ import {
findFirstAdjacent, findFirstAdjacent,
} from './util'; } from './util';
import type { StateManager } from './state';
type ObjectDepthState = { hidden: boolean };
/** /**
* When the toggle button is clicked, swap the connection status via the API and toggle CSS * When the toggle button is clicked, swap the connection status via the API and toggle CSS
* classes to reflect the connection status. * classes to reflect the connection status.
@@ -60,6 +65,79 @@ function initConnectionToggle() {
} }
} }
/**
* Change toggle button's text and attribute to reflect the current state.
*
* @param hidden `true` if the current state is hidden, `false` otherwise.
* @param button Toggle element.
*/
function toggleDepthButton(hidden: boolean, button: HTMLButtonElement): void {
button.setAttribute('data-depth-indicators', hidden ? 'hidden' : 'shown');
button.innerText = hidden ? 'Show Depth Indicators' : 'Hide Depth Indicators';
}
/**
* Show all depth indicators.
*/
function showDepthIndicators(): void {
for (const element of getElements<HTMLDivElement>('.record-depth')) {
element.style.display = '';
}
}
/**
* Hide all depth indicators.
*/
function hideDepthIndicators(): void {
for (const element of getElements<HTMLDivElement>('.record-depth')) {
element.style.display = 'none';
}
}
/**
* Update object depth local state and visualization when the button is clicked.
*
* @param state State instance.
* @param button Toggle element.
*/
function handleDepthToggle(state: StateManager<ObjectDepthState>, button: HTMLButtonElement): void {
const initiallyHidden = state.get('hidden');
state.set('hidden', !initiallyHidden);
const hidden = state.get('hidden');
if (hidden) {
hideDepthIndicators();
} else {
showDepthIndicators();
}
toggleDepthButton(hidden, button);
}
/**
* Initialize object depth toggle buttons.
*/
function initDepthToggle() {
const initiallyHidden = objectDepthState.get('hidden');
for (const button of getElements<HTMLButtonElement>('button.toggle-depth')) {
toggleDepthButton(initiallyHidden, button);
button.addEventListener(
'click',
event => {
handleDepthToggle(objectDepthState, event.currentTarget as HTMLButtonElement);
},
false,
);
}
// Synchronize local state with default DOM elements.
if (initiallyHidden) {
hideDepthIndicators();
} else if (!initiallyHidden) {
showDepthIndicators();
}
}
/** /**
* If a slug field exists, add event listeners to handle automatically generating its value. * If a slug field exists, add event listeners to handle automatically generating its value.
*/ */
@@ -239,6 +317,7 @@ function initPerPage() {
export function initButtons() { export function initButtons() {
for (const func of [ for (const func of [
initDepthToggle,
initConnectionToggle, initConnectionToggle,
initReslug, initReslug,
initSelectAll, initSelectAll,

View File

@@ -1 +1,2 @@
export * from './objectDepth';
export * from './rackImages'; export * from './rackImages';

View File

@@ -0,0 +1,6 @@
import { createState } from '../state';
export const objectDepthState = createState<{ hidden: boolean }>(
{ hidden: false },
{ persist: true, key: 'netbox-object-depth' },
);

View File

@@ -2,6 +2,9 @@
{% load helpers %} {% load helpers %}
{% block extra_controls %} {% block extra_controls %}
<button class="btn btn-sm btn-outline-secondary toggle-depth" type="button">
Hide Depth Indicators
</button>
<div class="dropdown"> <div class="dropdown">
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_depth" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_depth" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Max Depth{% if "depth__lte" in request.GET %}: {{ request.GET.depth__lte }}{% endif %} Max Depth{% if "depth__lte" in request.GET %}: {{ request.GET.depth__lte }}{% endif %}