improve styles and documentation

This commit is contained in:
checktheroads 2021-04-26 00:31:51 -07:00
parent bb55df34d7
commit aef513f038
27 changed files with 215 additions and 67 deletions

View File

@ -1,25 +1,38 @@
/**
* ParcelJS Bundle Configuration.
*
* @see https://parceljs.org/api.html
*/
const Bundler = require('parcel-bundler');
// Bundler options common to all bundle jobs.
const options = {
logLevel: 2,
cache: true,
watch: false,
minify: true,
outDir: './dist',
publicUrl: '/static',
logLevel: 2,
cache: true,
};
// Get CLI arguments for optional overrides.
const args = process.argv.slice(2);
// Allow cache disabling.
if (args.includes('--no-cache')) {
options.cache = false;
}
// Style (SCSS) bundle jobs. Generally, everything should be bundled into netbox.css from main.scss
// unless there is a specific reason to do otherwise.
const styles = [
['main.scss', 'netbox.css'],
['rack_elevation.scss', 'rack_elevation.css'],
];
// Script (JavaScript) bundle jobs. Generally, everything should be bundled into netbox.js from
// index.ts unless there is a specific reason to do otherwise.
const scripts = [
['src/index.ts', 'netbox.js'],
['src/jobs.ts', 'jobs.js'],
@ -28,6 +41,9 @@ const scripts = [
['src/device/status.ts', 'status.js'],
];
/**
* Run style bundle jobs.
*/
async function bundleStyles() {
for (const [input, outFile] of styles) {
const instance = new Bundler(input, { outFile, ...options });
@ -35,6 +51,9 @@ async function bundleStyles() {
}
}
/**
* Run script bundle jobs.
*/
async function bundleScripts() {
for (const [input, outFile] of scripts) {
const instance = new Bundler(input, { outFile, ...options });
@ -42,10 +61,15 @@ async function bundleScripts() {
}
}
/**
* Run all bundle jobs.
*/
async function bundleAll() {
if (args.includes('--styles')) {
// Only run style jobs.
return await bundleStyles();
} else if (args.includes('--scripts')) {
// Only run script jobs.
return await bundleScripts();
}
await bundleStyles();

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.

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

@ -0,0 +1,72 @@
// Dark Mode Styles for Flatpickr.
.flatpickr-calendar {
background: $gray-700;
color: $body-color;
box-shadow: 1px 0 0 $gray-600, -1px 0 0 $gray-600, 0 1px 0 $gray-600, 0 -1px 0 $gray-600,
0 3px 13px rgb(0 0 0 / 8%);
border-radius: $border-radius;
& span.flatpickr-weekday {
color: $gray-400;
}
&.arrowTop:before,
&.arrowTop:after {
border-bottom-color: $gray-700;
}
.flatpickr-months {
& .flatpickr-month {
color: $body-color;
fill: $body-color;
}
& .flatpickr-next-month,
& .flatpickr-prev-month {
color: $body-color;
fill: $body-color;
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
background: $gray-700;
}
}
.flatpickr-day {
color: $body-color;
&.today {
border-color: $gray-200;
}
&.selected,
&.startRange,
&.endRange,
&.selected.inRange,
&.startRange.inRange,
&.endRange.inRange,
&.selected:focus,
&.startRange:focus,
&.endRange:focus,
&.selected:hover,
&.startRange:hover,
&.endRange:hover,
&.selected.prevMonthDay,
&.startRange.prevMonthDay,
&.endRange.prevMonthDay,
&.selected.nextMonthDay,
&.startRange.nextMonthDay,
&.endRange.nextMonthDay {
background: $blue-300;
border-color: $blue-300;
color: color-contrast($blue-300);
}
&:hover {
border-color: $gray-200;
background: $gray-200;
color: color-contrast($gray-200);
}
&.flatpickr-disabled,
&.flatpickr-disabled:hover,
&.prevMonthDay,
&.nextMonthDay,
&.notAllowed,
&.notAllowed.prevMonthDay,
&.notAllowed.nextMonthDay {
color: $gray-500;
}
}
}

View File

@ -1,3 +1,7 @@
// Main Entry Point for all Netbox Styles.
// Note: The order of these imports is critical for proper inheritance.
// Light Mode Styles.
@import './theme-light.scss';
@import './bootstrap.scss';
@ -8,6 +12,7 @@
@import './netbox.scss';
// Dark Mode Styles.
body[data-netbox-color-mode='dark'] {
@import './theme-dark.scss';
@import './bootstrap.scss';
@ -16,6 +21,7 @@ body[data-netbox-color-mode='dark'] {
@import './select.scss';
@import 'flatpickr/dist/flatpickr.css';
@import './flatpickr-dark.scss';
@import './netbox.scss';
}

View File

@ -1,3 +1,7 @@
// Netbox-specific Styles and Overrides.
@use 'sass:map';
:root {
--nbx-logo-color-1: #9cc8f8;
--nbx-logo-color-2: #1685fc;
@ -16,7 +20,6 @@
--nbx-cable-node-border-color: #{$gray-200};
--nbx-cable-termination-bg: #{$gray-200};
--nbx-cable-termination-border-color: #{$gray-300};
--nbx-elevation-slot-bg: #{$gray-100};
body[data-netbox-color-mode='dark'] {
--nbx-logo-color-1: #{$white};
@ -36,7 +39,6 @@
--nbx-cable-node-border-color: #{$gray-600};
--nbx-cable-termination-bg: #{$gray-800};
--nbx-cable-termination-border-color: #{$gray-700};
--nbx-elevation-slot-bg: #{$gray-700};
}
}
@ -92,6 +94,23 @@ body {
}
}
div.title-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
padding-top: $spacer * 2;
margin-bottom: $spacer * 2;
border-bottom: 1px solid $border-color;
div#content-title {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding-bottom: map.get($spacers, 2);
}
}
nav.search {
background-color: var(--nbx-body-bg);
}
@ -306,6 +325,7 @@ pre {
.card {
box-shadow: $box-shadow-sm;
.card-header {
color: $body-color;
border-bottom: none;
padding: $card-cap-padding-x;
}
@ -413,6 +433,8 @@ nav.breadcrumb-container {
font-size: $font-size-sm;
width: fit-content;
background-color: var(--nbx-breadcrumb-bg);
margin-top: $spacer;
margin-bottom: $spacer;
ol.breadcrumb {
margin-bottom: 0;
@ -425,12 +447,6 @@ nav.breadcrumb-container {
}
}
div#content-title {
display: flex;
flex-direction: column;
flex: 1 0 auto;
}
div.paginator > form > div.input-group {
width: fit-content;
}

View File

@ -1,4 +1,4 @@
/* Stylesheet for rendering SVG rack elevations */
// Stylesheet for rendering SVG rack elevations
@import './theme-light.scss';
* {

View File

@ -1,3 +1,5 @@
// SlimSelect Style Overrides.
$height: $input-height;
$white: $white;
$font-color: $input-color;
@ -11,6 +13,19 @@ $spacing-l: $input-padding-x;
$spacing-m: $input-padding-x;
$spacing-s: $input-padding-x;
:root {
--nbx-select-content-bg: null;
--nbx-select-option-selected-bg: #{$gray-300};
--nbx-select-option-hover-bg: #{$blue};
--nbx-select-option-hover-color: #{$white};
& body[data-netbox-color-mode='dark'] {
--nbx-select-content-bg: #{$gray-900};
--nbx-select-option-selected-bg: #{$gray-500};
--nbx-select-option-hover-bg: #{$blue-200};
--nbx-select-option-hover-color: #{color-contrast($blue-200)};
}
}
div.form-floating div.ss-main div.ss-single-selected,
div.form-floating div.ss-main div.ss-multi-selected {
height: $form-floating-height;
@ -73,14 +88,15 @@ div.form-floating div.ss-main div.ss-multi-selected {
}
.ss-content {
background-color: $gray-900;
background-color: var(--nbx-select-content-bg);
.ss-list {
.ss-option.ss-option-selected {
background-color: $gray-600;
color: $white;
background-color: var(--nbx-select-option-selected-bg);
color: $body-color;
}
.ss-option:hover {
background-color: $blue-400;
background-color: var(--nbx-select-option-hover-bg);
color: var(--nbx-select-option-hover-color);
}
.ss-option:last-child {
border-bottom-left-radius: $form-select-border-radius;

View File

@ -1,12 +1,13 @@
import { createToast } from './bs';
import { setColorMode } from './colorMode';
import {
slugify,
isTruthy,
getElements,
apiPatch,
hasError,
slugify,
findFirstAdjacent,
getElement,
getElements,
findFirstAdjacent,
} from './util';
/**
@ -131,6 +132,34 @@ function initReslug(): void {
});
}
/**
* Perform actions in the UI based on the value of user profile updates.
*
* @param event Form Submit
*/
function handlePreferenceSave(event: Event): void {
// Create a FormData instance to access the form values.
const form = event.currentTarget as HTMLFormElement;
const formData = new FormData(form);
// Update the UI color mode immediately when the user preference changes.
if (formData.get('ui.colormode') === 'dark') {
setColorMode('dark');
} else if (formData.get('ui.colormode') === 'light') {
setColorMode('light');
}
}
/**
* Initialize handlers for user profile updates.
*/
function initPreferenceUpdate() {
const form = getElement<HTMLFormElement>('preferences-update');
if (form !== null) {
form.addEventListener('submit', handlePreferenceSave);
}
}
/**
* Show the select all card when the select all checkbox is checked, and sync the checkbox state
* with all the PK checkboxes in the table.
@ -237,7 +266,13 @@ function initSelectAll() {
}
export function initButtons() {
for (const func of [initRackElevation, initConnectionToggle, initReslug, initSelectAll]) {
for (const func of [
initRackElevation,
initConnectionToggle,
initReslug,
initSelectAll,
initPreferenceUpdate,
]) {
func();
}
}

View File

@ -56,7 +56,7 @@ function updateElements(targetMode: ColorMode): void {
*
* @param mode Target color mode.
*/
function setColorMode(mode: ColorMode): void {
export function setColorMode(mode: ColorMode): void {
for (const func of [storeColorMode, updateElements]) {
func(mode);
}

View File

@ -1,3 +1,4 @@
// Base Netbox Theme Overrides and Settings - color mode agnostic.
@import 'bootstrap/scss/functions';
$alt: #13293d;

View File

@ -1,3 +1,5 @@
// Dark Mode Theme Variables and Overrides.
@import './theme-base.scss';
$primary: $blue-300;
@ -54,24 +56,16 @@ $mark-bg: #fcf8e3;
// Tables
$table-color: $gray-100;
$table-border-color: $border-color;
// $table-bg: transparent;
$table-striped-color: $table-color;
$table-striped-bg: rgba($white, $table-striped-bg-factor);
$table-active-color: $table-color;
$table-active-bg: rgba($white, $table-active-bg-factor);
$table-hover-color: $table-color;
$table-hover-bg: rgba($white, $table-hover-bg-factor);
// $table-group-separator-color: currentColor;
// Buttons + Forms
// $input-btn-focus-color: rgba($component-active-bg, $input-btn-focus-color-opacity);
// $input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color;
// Buttons
$btn-box-shadow: inset 0 1px 0 rgba($black, 0.15), 0 1px 1px rgba($white, 0.075);
$btn-active-box-shadow: inset 0 3px 5px rgba($white, 0.125);
// $btn-link-color: $link-color;
// $btn-link-hover-color: $link-hover-color;
$btn-link-disabled-color: $gray-300;
// Forms
@ -144,18 +138,6 @@ $dropdown-link-hover-color: shade-color($gray-50, 10%);
$dropdown-link-hover-bg: $gray-500;
$dropdown-link-disabled-color: $gray-800;
$dropdown-header-color: $gray-300;
// $dropdown-dark-color: $gray-300;
// $dropdown-dark-bg: $gray-800;
// $dropdown-dark-border-color: $dropdown-border-color;
// $dropdown-dark-divider-bg: $dropdown-divider-bg;
// $dropdown-dark-box-shadow: null;
// $dropdown-dark-link-color: $dropdown-dark-color;
// $dropdown-dark-link-hover-color: $white;
// $dropdown-dark-link-hover-bg: rgba($white, .15);
// $dropdown-dark-link-active-color: $dropdown-link-active-color;
// $dropdown-dark-link-active-bg: $dropdown-link-active-bg;
// $dropdown-dark-link-disabled-color: $gray-500;
// $dropdown-dark-header-color: $gray-500;
// Pagination
$pagination-color: $link-color;
@ -184,7 +166,7 @@ $card-bg: $gray-800;
// Accordion
$accordion-color: $body-color;
// $accordion-bg: transparent;
$accordion-bg: transparent;
$accordion-border-color: rgba($white, 0.125);
$accordion-button-color: $accordion-color;
$accordion-button-bg: $accordion-bg;
@ -200,7 +182,6 @@ $accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3
// Tooltips
$tooltip-color: $body-color;
$tooltip-bg: $gray-700;
// $tooltip-opacity: .9;
$tooltip-arrow-color: $tooltip-bg;
$form-feedback-tooltip-opacity: $tooltip-opacity;
@ -229,15 +210,9 @@ $modal-content-color: null;
$modal-content-bg: $gray-800;
$modal-content-border-color: rgba($white, 0.2);
$modal-backdrop-bg: $black;
// $modal-backdrop-opacity: .5;
$modal-header-border-color: $border-color;
$modal-footer-border-color: $modal-header-border-color;
// Alerts
// $alert-bg-scale: -80%;
// $alert-border-scale: -70%;
// $alert-color-scale: 40%;
// Progress bars
$progress-bg: $gray-600;
$progress-bar-color: $white;
@ -251,7 +226,6 @@ $list-group-hover-bg: rgba($gray-50, 0.15);
$list-group-active-color: $component-active-color;
$list-group-active-bg: $component-active-bg;
$list-group-active-border-color: $list-group-active-bg;
// $list-group-disabled-color: $gray-600;
$list-group-disabled-bg: $list-group-bg;
$list-group-action-color: $gray-300;
$list-group-action-hover-color: $body-color;
@ -266,7 +240,6 @@ $thumbnail-border-color: $gray-300;
$figure-caption-color: $gray-600;
// Breadcrumbs
// $breadcrumb-bg: $gray-700;
$breadcrumb-divider-color: $gray-100;
$breadcrumb-active-color: $body-color;
$breadcrumb-divider-flipped: $breadcrumb-divider;

View File

@ -1,3 +1,5 @@
// Light Mode Theme Variables and Overrides.
@import './theme-base.scss';
$input-border-color: $gray-200;
@ -13,4 +15,7 @@ $light: $gray-100;
$card-cap-color: $gray-800;
$accordion-bg: transparent;
$accordion-button-bg: $accordion-bg;
$breadcrumb-divider: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='currentColor'/%3E%3C/svg%3E");

View File

@ -1,6 +1,7 @@
{% extends 'layout.html' %} {% load helpers %} {%block title %} Home
{%endblock%} {% block content %}
{% extends 'layout.html' %}
{% load helpers %}
{% block title_container %}{% endblock %}
{% block content %}
<div class="stats-container">
<div class="row row-cols-auto masonry">
{% for section in stats %}
@ -51,5 +52,4 @@
</div>
</div>
</div>
{% endblock %}

View File

@ -39,9 +39,8 @@
</nav>
<div class="px-4">
<div
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
>
{% block title_container %}
<div class="title-container">
<div id="content-title">
<h1 class="h2 w-100">{% block title %}{% endblock %}</h1>
{% block breadcrumb_main %}{% endblock %}
@ -49,6 +48,7 @@
{% block controls %}{% endblock %}
</div>
{% endblock %}
<div id="content" class="container-fluid p-0 m-0">
{% block tabs %}{% endblock %}
{% block content %}{% endblock %}

View File

@ -4,11 +4,11 @@
{% block title %}User Preferences{% endblock %}
{% block usercontent %}
<form method="post" action="">
<form method="post" action="" id="preferences-update">
{% csrf_token %}
<div class="field-group mb-3">
<h4>Color Mode</h4>
<p class="lead text-muted">Set your preferred UI color mode</p>
<p class="lead text-muted">Set preferred UI color mode</p>
{% with color_mode=preferences|get_key:'ui.colormode'%}
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="ui.colormode" id="color-mode-preference-dark" value="dark"{% if color_mode == 'dark'%} checked{% endif %}>
@ -22,18 +22,18 @@
</div>
<div class="row">
<div class="col">
<button type="submit" class="btn btn-success" name="_update">
<button type="submit" class="btn btn-primary" name="_update">
Save
</button>
</div>
</div>
{% if preferences %}
<div class="field-group">
<div class="field-group mb-3">
<h4>Other Preferences</h4>
<table class="table table-striped">
<thead>
<tr>
<th><input type="checkbox" class="toggle" title="Toggle all"></th>
<th><input type="checkbox" class="toggle form-check-input" title="Toggle All"></th>
<th>Preference</th>
<th>Value</th>
</tr>
@ -41,7 +41,7 @@
<tbody>
{% for key, value in preferences.items %}
<tr>
<td class="min-width"><input type="checkbox" name="pk" value="{{ key }}"></td>
<td class="min-width"><input class="form-check-input" type="checkbox" name="pk" value="{{ key }}"></td>
<td><samp>{{ key }}</samp></td>
<td><samp>{{ value }}</samp></td>
</tr>
@ -53,7 +53,7 @@
</button>
</div>
{% else %}
<h3 class="text-muted text-center">No preferences found</h3>
<h3 class="text-muted text-center">No Preferences Found</h3>
{% endif %}
</form>
{% endblock %}