Skip to content

Commit

Permalink
#5203: Persist Show/Hide Images state in rack view
Browse files Browse the repository at this point in the history
  • Loading branch information
thatmattlove committed Jul 7, 2021
1 parent d9a6f11 commit 9c247d9
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 47 deletions.
16 changes: 12 additions & 4 deletions netbox/project-static/dist/netbox.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion netbox/project-static/dist/netbox.js.map

Large diffs are not rendered by default.

42 changes: 0 additions & 42 deletions netbox/project-static/src/buttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,6 @@ import {
findFirstAdjacent,
} from './util';

/**
* Toggle the visibility of device images and update the toggle button style.
*/
function handleRackImageToggle(event: Event) {
const target = event.target as HTMLButtonElement;
const selected = target.getAttribute('selected');

if (isTruthy(selected)) {
for (const elevation of getElements<HTMLObjectElement>('.rack_elevation')) {
const images = elevation.contentDocument?.querySelectorAll('image.device-image') ?? [];
for (const image of images) {
if (image !== null && !image.classList.contains('hidden')) {
image.classList.add('hidden');
}
}
}
target.innerHTML = `<i class="mdi mdi-file-image-outline"></i>&nbsp;Show Images`;
target.setAttribute('selected', '');
} else {
for (const elevation of getElements<HTMLObjectElement>('.rack_elevation')) {
const images = elevation.contentDocument?.querySelectorAll('image.device-image') ?? [];
for (const image of images) {
if (image !== null) {
image.classList.remove('hidden');
}
}
}
target.innerHTML = `<i class="mdi mdi-file-image-outline"></i>&nbsp;Hide Images`;
target.setAttribute('selected', 'selected');
}
return;
}
/**
* Add onClick callback for toggling rack elevation images.
*/
function initRackElevation() {
for (const button of getElements<HTMLButtonElement>('button.toggle-images')) {
button.addEventListener('click', handleRackImageToggle);
}
}

/**
* When the toggle button is clicked, swap the connection status via the API and toggle CSS
* classes to reflect the connection status.
Expand Down Expand Up @@ -280,7 +239,6 @@ function initPerPage() {

export function initButtons() {
for (const func of [
initRackElevation,
initConnectionToggle,
initReslug,
initSelectAll,
Expand Down
2 changes: 2 additions & 0 deletions netbox/project-static/src/netbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { initDateSelector } from './dateSelector';
import { initTableConfig } from './tableConfig';
import { initInterfaceTable } from './tables';
import { initSideNav } from './sidenav';
import { initRackElevation } from './racks';

function init() {
for (const init of [
Expand All @@ -25,6 +26,7 @@ function init() {
initTableConfig,
initInterfaceTable,
initSideNav,
initRackElevation,
]) {
init();
}
Expand Down
92 changes: 92 additions & 0 deletions netbox/project-static/src/racks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { rackImagesState } from './stores';
import { getElements } from './util';

import type { StateManager } from './state';

type RackToggleState = { hidden: boolean };

/**
* Toggle the Rack Image button to reflect the current state. If the current state is hidden and
* the images are therefore hidden, the button should say "Show Images". Likewise, if the current
* state is *not* hidden, and therefore the images are shown, the button should say "Hide Images".
*
* @param hidden Current State - `true` if images are hidden, `false` otherwise.
* @param button Button element.
*/
function toggleRackImagesButton(hidden: boolean, button: HTMLButtonElement): void {
const text = hidden ? 'Show Images' : 'Hide Images';
const selected = hidden ? '' : 'selected';
button.setAttribute('selected', selected);
button.innerHTML = `<i class="mdi mdi-file-image-outline"></i>&nbsp;${text}`;
}

/**
* Show all rack images.
*/
function showRackImages(): void {
for (const elevation of getElements<HTMLObjectElement>('.rack_elevation')) {
const images = elevation.contentDocument?.querySelectorAll('image.device-image') ?? [];
for (const image of images) {
image.classList.remove('hidden');
}
}
}

/**
* Hide all rack images.
*/
function hideRackImages(): void {
for (const elevation of getElements<HTMLObjectElement>('.rack_elevation')) {
const images = elevation.contentDocument?.querySelectorAll('image.device-image') ?? [];
for (const image of images) {
image.classList.add('hidden');
}
}
}

/**
* Toggle the visibility of device images and update the toggle button style.
*/
function handleRackImageToggle(
target: HTMLButtonElement,
state: StateManager<RackToggleState>,
): void {
const initiallyHidden = state.get('hidden');
state.set('hidden', !initiallyHidden);
const hidden = state.get('hidden');

if (hidden) {
hideRackImages();
} else {
showRackImages();
}
toggleRackImagesButton(hidden, target);
}

/**
* Add onClick callback for toggling rack elevation images. Synchronize the image toggle button
* text and display state of images with the local state.
*/
export function initRackElevation() {
const initiallyHidden = rackImagesState.get('hidden');
for (const button of getElements<HTMLButtonElement>('button.toggle-images')) {
toggleRackImagesButton(initiallyHidden, button);

button.addEventListener(
'click',
event => {
handleRackImageToggle(event.currentTarget as HTMLButtonElement, rackImagesState);
},
false,
);
}
for (const element of getElements<HTMLObjectElement>('.rack_elevation')) {
element.addEventListener('load', () => {
if (initiallyHidden) {
hideRackImages();
} else if (!initiallyHidden) {
showRackImages();
}
});
}
}
1 change: 1 addition & 0 deletions netbox/project-static/src/stores/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './rackImages';
6 changes: 6 additions & 0 deletions netbox/project-static/src/stores/rackImages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createState } from '../state';

export const rackImagesState = createState<{ hidden: boolean }>(
{ hidden: false },
{ persist: true },
);

0 comments on commit 9c247d9

Please sign in to comment.