mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
The page where a user changes their own password and the one where an administrator sets a user's password shared an old card: a horizontal form, a blue Cancel and a green Change. The administrator's had Django's "Password-based authentication: Enabled/Disabled" with a paragraph about other backends, and its password fields stayed while Disabled was chosen. Both pages now have the user and group forms' layout, each its own template. The administrator chooses how the user signs in, With a password or Without a password (such as LDAP), and the password fields and "must change it" show only with a password; Cancel goes back to the user. A user's own page says that their other sessions end, or, when they must change it, that they choose one before going on, without a Cancel. A refused password is said at its field only, without the general "Wrong Data Provided". The section styles of these forms move into webvirtcloud.css.
306 lines
9.1 KiB
CSS
306 lines
9.1 KiB
CSS
/*!
|
|
* WebVirtCloud (http://github.com/retspen/webvirtcloud)
|
|
* Code licensed under the Apache License v2.0.
|
|
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
|
|
*/
|
|
|
|
/* pages stop at Bootstrap's lg container width (960px): its xl and xxl
|
|
widths (1140px, 1320px) leave the panel's forms and lists too wide */
|
|
@media (min-width: 1200px) {
|
|
.container {
|
|
max-width: 960px;
|
|
}
|
|
}
|
|
|
|
/* a count or label badge: text-bg-light keeps a light background with the
|
|
theme's light-text colour, white on grey in Darkly, Superhero and Vapor;
|
|
the page's own colours read in every theme */
|
|
.badge.text-bg-light.border {
|
|
color: var(--bs-body-color) !important;
|
|
background-color: var(--bs-body-bg) !important;
|
|
}
|
|
|
|
/* an outlined secondary button (Cancel, a row's menu): Bootstrap draws it
|
|
in the theme's secondary colour, near the page background in Cyborg,
|
|
Darkly, Slate, Solar, Superhero and Vapor; the page's own text colours
|
|
read in every theme, its hover stays the theme's */
|
|
.btn-outline-secondary {
|
|
color: var(--bs-body-color);
|
|
border-color: var(--bs-secondary-color);
|
|
}
|
|
|
|
#editor {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
}
|
|
|
|
/* Tom Select's control keeps the text colour of the select it replaces:
|
|
its own stylesheet fixes one, unreadable on some Bootswatch themes */
|
|
.ts-wrapper.form-select .ts-control,
|
|
.ts-wrapper.form-select .ts-control input {
|
|
color: inherit;
|
|
}
|
|
|
|
.xmlheight {
|
|
height: 364px;
|
|
}
|
|
|
|
.ace_editor {
|
|
height: 350px;
|
|
}
|
|
|
|
/* the VM's XML editor: as tall as most of the window, framed like a form field */
|
|
.xml-editor .ace_editor {
|
|
height: max(350px, 65vh);
|
|
border: var(--bs-border-width) solid var(--bs-border-color);
|
|
border-radius: var(--bs-border-radius);
|
|
}
|
|
|
|
/* the review dialog's diff: added and removed lines on a tint, a hunk starts with its line number */
|
|
.xml-diff > div {
|
|
padding: 0 .5rem;
|
|
}
|
|
.xml-diff .diff-add {
|
|
background-color: rgba(var(--bs-success-rgb), .12);
|
|
}
|
|
.xml-diff .diff-del {
|
|
background-color: rgba(var(--bs-danger-rgb), .12);
|
|
}
|
|
.xml-diff .diff-hunk:not(:first-child) {
|
|
margin-top: .75rem;
|
|
}
|
|
|
|
/* headers of sortable tables (static/js/sort_tables.js): the sorted one shows
|
|
its direction, up for ascending */
|
|
th[role=columnheader]:not([data-sort-method="none"]) {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
th[aria-sort]:not([data-sort-method="none"])::after {
|
|
content: "";
|
|
display: inline-block;
|
|
margin-left: 0.4em;
|
|
vertical-align: middle;
|
|
border: 0.3em solid transparent;
|
|
border-top-color: currentColor;
|
|
}
|
|
|
|
th[aria-sort="ascending"]:not([data-sort-method="none"])::after {
|
|
border-top-color: transparent;
|
|
border-bottom-color: currentColor;
|
|
}
|
|
|
|
/* a phone keeps Bootstrap's own cell padding: some themes (Zephyr) double
|
|
it, and a list's last column no longer fits the screen */
|
|
@media (max-width: 575.98px) {
|
|
.table > :not(caption) > * > * {
|
|
padding-left: 0.5rem;
|
|
padding-right: 0.5rem;
|
|
}
|
|
}
|
|
|
|
/* a choice shown as a card around its radio button (the VM's disk source,
|
|
a new pool's type): the chosen card by its border only, as the
|
|
Bootswatch dark themes keep light "subtle" backgrounds */
|
|
.source-option {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.source-option:has(input:checked) {
|
|
border-color: var(--bs-primary) !important;
|
|
box-shadow: inset 0 0 0 1px var(--bs-primary);
|
|
}
|
|
|
|
.source-option:has(input:focus-visible) {
|
|
outline: 2px solid var(--bs-primary);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.host-collapsed tr[host] {
|
|
display: none;
|
|
}
|
|
|
|
/* a live chart (static/js/charts.js) fills the width of its card at this height */
|
|
.chart {
|
|
height: 160px;
|
|
}
|
|
|
|
/* the host's sections (computes/host_nav.html) on one line in every theme:
|
|
one font size, and the divider spaced alike on its two sides (Zephyr
|
|
doubles the space after it) */
|
|
.host-nav .breadcrumb {
|
|
--bs-breadcrumb-item-padding-x: .5rem;
|
|
font-size: .875rem;
|
|
}
|
|
|
|
.host-nav .breadcrumb-item + .breadcrumb-item::before {
|
|
padding-right: var(--bs-breadcrumb-item-padding-x);
|
|
}
|
|
|
|
/* the power tab's states: the current one filled, the others a ring */
|
|
.power-dot {
|
|
width: .8rem;
|
|
height: .8rem;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
border: 2px solid var(--bs-border-color);
|
|
}
|
|
.power-dot.bg-success, .power-dot.bg-warning, .power-dot.bg-secondary { border-color: transparent; }
|
|
/* the access tab's two login buttons line up */
|
|
.access-act { min-width: 9rem; }
|
|
|
|
/* the options tab: one row per device the guest sees, its name, its control and a note */
|
|
.option-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
column-gap: 1rem;
|
|
row-gap: .25rem;
|
|
padding: .6rem 0;
|
|
}
|
|
.option-name { flex: 0 0 8rem; }
|
|
|
|
/* the resize tab: one cell per vCPU up to the maximum, filled when on; memory now within its maximum */
|
|
.vcpu-cell {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 2.25rem;
|
|
height: 2.25rem;
|
|
padding: 0 .4rem;
|
|
border-radius: var(--bs-border-radius);
|
|
border: 2px solid var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
color: var(--bs-primary);
|
|
font-size: .875rem;
|
|
font-weight: 600;
|
|
}
|
|
.vcpu-cell.on { background: var(--bs-primary); color: #fff; }
|
|
button.vcpu-cell:not(:disabled):hover { box-shadow: 0 0 0 .2rem rgba(var(--bs-primary-rgb), .25); }
|
|
button.vcpu-cell:disabled { opacity: .65; }
|
|
.memory-bar {
|
|
width: min(18rem, 100%);
|
|
height: .9rem;
|
|
border: 2px solid var(--bs-primary);
|
|
border-radius: var(--bs-border-radius);
|
|
overflow: hidden;
|
|
}
|
|
.memory-bar-now { height: 100%; background: var(--bs-primary); }
|
|
.resize-act { min-width: 9rem; }
|
|
|
|
/* the boot order: the devices the VM tries in turn, numbered and joined by a line */
|
|
.boot-chain { counter-reset: boot; }
|
|
.boot-node { position: relative; padding: .5rem 0; }
|
|
.boot-chain > .boot-node { counter-increment: boot; }
|
|
.boot-step {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
width: 1.75rem;
|
|
height: 1.75rem;
|
|
border-radius: 50%;
|
|
border: 2px solid var(--bs-primary);
|
|
color: var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
font-size: .8rem;
|
|
font-weight: 600;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
.boot-chain .boot-step::before { content: counter(boot); }
|
|
.boot-chain > .boot-node:not(:last-child)::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(.875rem - 1px);
|
|
top: calc(50% + .875rem);
|
|
height: calc(100% - 1.75rem);
|
|
border-left: 2px solid var(--bs-border-color);
|
|
}
|
|
.boot-spare .boot-step { visibility: hidden; }
|
|
/* on a narrow screen a device's buttons go below its name, not over it */
|
|
.boot-text { min-width: 10rem; flex-basis: 10rem; }
|
|
.boot-chain .boot-spare-only, .boot-spare .boot-chain-only { display: none !important; }
|
|
|
|
/* the snapshots tab: the VM's history as a line, newest first; now on top, the snapshot the VM goes on from filled */
|
|
.snap-line { position: relative; padding-left: 1.75rem; }
|
|
.snap-line::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(.5rem - 1px);
|
|
top: .75rem;
|
|
bottom: .75rem;
|
|
border-left: 2px solid var(--bs-border-color);
|
|
}
|
|
.snap-node { position: relative; padding: .5rem 0; }
|
|
.snap-dot {
|
|
position: absolute;
|
|
left: -1.75rem;
|
|
top: .75rem;
|
|
width: 1rem;
|
|
height: 1rem;
|
|
border-radius: 50%;
|
|
border: 2px solid var(--bs-primary);
|
|
background: var(--bs-body-bg);
|
|
}
|
|
.snap-dot.bg-success, .snap-dot.bg-warning, .snap-dot.bg-secondary { border-color: transparent; }
|
|
.snap-dot.snap-current { background: var(--bs-primary); }
|
|
.snap-dot.snap-none { border-color: var(--bs-border-color); }
|
|
|
|
/* the network tab: a NIC as a cable to its source, solid while its link is up, dashed while down */
|
|
.nic-wire {
|
|
position: relative;
|
|
flex: 0 0 3.5rem;
|
|
margin-inline: .25rem;
|
|
color: var(--bs-secondary-color);
|
|
border-top: 2px dashed currentColor;
|
|
}
|
|
.nic-wire::before, .nic-wire::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: -4px;
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
}
|
|
.nic-wire::before { left: -3px; }
|
|
.nic-wire::after { right: -3px; }
|
|
.nic-wire.nic-up { color: var(--bs-success); border-top-style: solid; }
|
|
|
|
/* a log message keeps a readable width when its table scrolls on a phone */
|
|
.log-message {
|
|
min-width: 16rem;
|
|
}
|
|
|
|
/* the VM's new console password: only with "Set a new one" */
|
|
fieldset:not(:has(input[value="set"]:checked)) > .console-new-password {
|
|
display: none;
|
|
}
|
|
|
|
/* the account forms (user, group, password): each section says what it is
|
|
about on the left, its fields on the right, with a rule between sections */
|
|
.form-section {
|
|
border-top: 1px solid var(--bs-border-color);
|
|
padding: 1.5rem 0;
|
|
}
|
|
.form-section:first-of-type {
|
|
border-top: 0;
|
|
padding-top: .5rem;
|
|
}
|
|
.form-section-fields {
|
|
max-width: 52rem;
|
|
}
|
|
/* a choice drawn as a card (the user's role, how a user signs in) */
|
|
.form-choice:has(input:checked) {
|
|
border-color: var(--bs-primary) !important;
|
|
box-shadow: inset 0 0 0 1px var(--bs-primary);
|
|
}
|
|
/* a user's password fields: only while With a password is chosen */
|
|
.form-section-fields:has(input[name="usable_password"][value="false"]:checked) > .with-password {
|
|
display: none;
|
|
}
|