
Add "remove worker" button to the worker details panel. It will show a little warning when the worker is still running, and also has an explanation of what removing a worker actually means.
661 lines
15 KiB
CSS
661 lines
15 KiB
CSS
:root {
|
|
--spacer: 1rem;
|
|
--spacer-xl: 1.5rem;
|
|
--spacer-lg: 1.33rem;
|
|
--spacer-sm: .66rem;
|
|
--spacer-xs: .33rem;
|
|
|
|
--color-background: #111;
|
|
--color-background-column: #202020;
|
|
--color-background-column-highlight: #282828;
|
|
|
|
--color-accent-hue: 246;
|
|
--color-accent: hsl(var(--color-accent-hue), 40%, 65%);
|
|
--color-accent-text: hsl(var(--color-accent-hue) 100% 84%);
|
|
--color-accent-background: hsl(var(--color-accent-hue) 18% 28%);
|
|
|
|
--color-text: #ddd;
|
|
--color-text-highlight: #fff;
|
|
--color-text-muted: #999;
|
|
--color-text-hint: #555;
|
|
|
|
--color-border: #282828;
|
|
|
|
--color-button: #bbb;
|
|
--color-button-background: #555;
|
|
|
|
--border-color: #555;
|
|
--border-radius: 4px;
|
|
--border-width: 2px;
|
|
|
|
--font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
--font-family-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro","Fira Mono", "Droid Sans Mono", "Courier New", monospace;
|
|
--font-size-base: 14px;
|
|
--font-size-sm: 12px;
|
|
--font-size-lg: 16px;
|
|
|
|
--table-color-background-row: #303030;
|
|
--table-color-background-row-odd: #2b2b2b;
|
|
--table-color-background-row-selected: hsl(var(--color-accent-hue), 16%, 30%);
|
|
--table-color-background-row-active: hsl(var(--color-accent-hue), 24%, 36%);
|
|
|
|
--table-color-border: var(--color-border);
|
|
|
|
--header-height: 25px;
|
|
--footer-height: 25px;
|
|
--grid-gap: 6px;
|
|
|
|
--transition-speed: 240ms;
|
|
--transition-speed-fast: 60ms;
|
|
|
|
--color-danger: hsl(352 100% 56%);
|
|
--color-success: hsl(102 70% 56%);
|
|
|
|
--color-status-active: hsl(166 100% 46%);
|
|
--color-status-completed: hsl(166 100% 46%);
|
|
|
|
--color-status-archived: hsl(0 0% 25%);
|
|
--color-status-archiving: hsl(0 50% 50%);
|
|
|
|
--color-status-construction-failed: hsl(356 100% 59%);
|
|
--color-status-failed: hsl(356 100% 59%);
|
|
--color-status-soft-failed: hsl(356 70% 40%);
|
|
|
|
--color-status-queued: hsl(194 100% 46%);
|
|
--color-status-requeueing: hsl(194 100% 46%);
|
|
--color-status-canceled: hsl(0 0% 46%);
|
|
--color-status-paused: hsl(0 0% 66%);
|
|
|
|
--color-status-cancel-requested: hsl(194 30% 50%);
|
|
--color-status-under-construction: hsl(194 30% 50%);
|
|
|
|
--color-worker-status-starting: hsl(68, 100%, 30%);
|
|
--color-worker-status-awake: var(--color-status-active);
|
|
--color-worker-status-asleep: hsl(208, 80%, 55%);
|
|
--color-worker-status-error: var(--color-status-failed);
|
|
--color-worker-status-shutdown: var(--color-status-paused);
|
|
--color-worker-status-testing: hsl(166 100% 46%);
|
|
--color-worker-status-offline: var(--color-status-canceled);
|
|
|
|
--color-connection-lost-text: hsl(0, 90%, 60%);
|
|
--color-connection-lost-bg: hsl(0, 50%, 20%);
|
|
}
|
|
|
|
html,
|
|
body {
|
|
accent-color: var(--color-accent);
|
|
background-color: var(--color-background);
|
|
color: var(--color-text);
|
|
color-scheme: dark;
|
|
font-family: var(--font-family-body);
|
|
font-size: var(--font-size-base);
|
|
height: 100vh;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
#app {
|
|
display: grid;
|
|
grid-gap: var(--grid-gap);
|
|
grid-template-areas:
|
|
"header header header"
|
|
"col-1 col-2 col-3"
|
|
"footer footer footer";
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
grid-template-rows: var(--header-height) 1fr var(--footer-height);
|
|
height: 100%;
|
|
padding-left: var(--grid-gap);
|
|
padding-right: var(--grid-gap);
|
|
width: calc(100% - calc(var(--grid-gap) * 2));
|
|
}
|
|
|
|
body.is-two-columns #app {
|
|
grid-template-areas:
|
|
"header header"
|
|
"col-1 col-2"
|
|
"footer footer";
|
|
grid-template-columns: 1fr 1fr;
|
|
grid-template-rows: var(--header-height) 1fr var(--footer-height);
|
|
}
|
|
|
|
@media (max-width: 1280px) {
|
|
#app {
|
|
grid-template-areas:
|
|
"header header"
|
|
"col-1 col-2"
|
|
"col-3 col-3"
|
|
"footer footer";
|
|
grid-template-columns: 1fr 1fr;
|
|
grid-template-rows: var(--header-height) 1fr 1fr var(--footer-height);
|
|
}
|
|
}
|
|
|
|
@media (max-width: 960px) {
|
|
body.is-two-columns #app {
|
|
grid-template-areas:
|
|
"header"
|
|
"col-1"
|
|
"col-2"
|
|
"footer";
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: var(--header-height) 1fr 1fr var(--footer-height);
|
|
}
|
|
}
|
|
|
|
.col {
|
|
background-color: var(--color-background-column);
|
|
border-radius: var(--border-radius);
|
|
padding: var(--spacer-sm);
|
|
|
|
/* These two are necessary for the automatic resizing of the tasks table: */
|
|
/* Ensures that the table cannot push down the bottom of the column element,
|
|
* and thus the column height is a stable reference. */
|
|
/* Firefox does not recognize "overlay" currently, so have "auto" as fallback. */
|
|
overflow-y: auto;
|
|
overflow-y: overlay;
|
|
/* Ensures the offsetParent of the table is the column itself; without this,
|
|
* offsetParent would be <body>. */
|
|
position: relative;
|
|
}
|
|
|
|
.col-1 {
|
|
grid-area: col-1;
|
|
}
|
|
|
|
.col-2 {
|
|
grid-area: col-2;
|
|
}
|
|
|
|
.col-3 {
|
|
grid-area: col-3;
|
|
}
|
|
|
|
.app-version {
|
|
font-family: var(--font-family-mono);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
a {
|
|
color: currentColor;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover {
|
|
color: var(--color-accent);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
a.router-link-active {
|
|
color: var(--color-accent);
|
|
}
|
|
|
|
header {
|
|
align-items: center;
|
|
color: var(--color-text-muted);
|
|
display: flex;
|
|
grid-area: header;
|
|
padding: 0 var(--spacer-sm);
|
|
}
|
|
|
|
header nav {
|
|
margin-right: auto;
|
|
}
|
|
|
|
.navbar-brand {
|
|
margin-right: var(--spacer);
|
|
}
|
|
|
|
nav > ul {
|
|
align-items: center;
|
|
display: flex;
|
|
list-style-type: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
nav > ul > li > a {
|
|
display: block;
|
|
padding: var(--spacer-xs) var(--spacer-sm);
|
|
}
|
|
|
|
h2.column-title {
|
|
border-bottom: var(--border-width) solid var(--color-border);
|
|
color: var(--color-text-hint);
|
|
font-size: var(--font-size-base);
|
|
margin: 0;
|
|
padding-bottom: var(--spacer-sm);
|
|
}
|
|
|
|
h3.sub-title {
|
|
border-bottom: var(--border-width) solid var(--color-border);
|
|
color: var(--color-text-hint);
|
|
font-size: var(--font-size-base);
|
|
margin: var(--spacer) 0 0;
|
|
padding: 0 0 var(--spacer-sm);
|
|
}
|
|
|
|
dl {
|
|
display: grid;
|
|
font-family: var(--font-family-mono);
|
|
font-size: var(--font-size-sm);
|
|
grid-template-columns: max-content auto;
|
|
}
|
|
|
|
dl dt {
|
|
font-weight: bold;
|
|
text-align: right;
|
|
width: 100px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
dl dd {
|
|
margin-bottom: .133rem;
|
|
margin-left: var(--spacer-sm);
|
|
padding-bottom: .133rem;
|
|
transition: color var(--transition-speed-fast) ease-out;
|
|
word-break: break-word;
|
|
}
|
|
|
|
dl dd:hover {
|
|
color: var(--color-text-highlight);
|
|
}
|
|
|
|
dl dd:empty {
|
|
border-color: transparent;
|
|
}
|
|
|
|
.dl-no-data {
|
|
color: var(--color-text-hint);
|
|
font-family: var(--font-family-mono);
|
|
font-size: var(--font-size-sm);
|
|
padding: var(--spacer-lg) var(--spacer);
|
|
text-align: center;
|
|
cursor: default;
|
|
}
|
|
|
|
.app-footer {
|
|
align-items: center;
|
|
background-color: var(--color-background-column);
|
|
border-radius: var(--border-radius);
|
|
color: var(--color-text-muted);
|
|
cursor: pointer;
|
|
display: flex;
|
|
font-size: var(--font-size-sm);
|
|
grid-area: footer;
|
|
padding: var(--spacer-sm);
|
|
transition: background-color var(--transition-speed) ease-in-out;
|
|
}
|
|
|
|
.app-footer:hover {
|
|
background-color: var(--color-background-column-highlight);
|
|
}
|
|
|
|
.app-footer:hover .app-footer-expand {
|
|
margin-top: -5px;
|
|
}
|
|
|
|
.app-footer-expand {
|
|
position: relative;
|
|
stroke: var(--color-text-hint);
|
|
transform: scale(.8);
|
|
transition: stroke var(--transition-speed) ease-in-out, margin-top var(--transition-speed) ease-in-out;
|
|
}
|
|
|
|
.btn-bar {
|
|
align-items: center;
|
|
display: flex;
|
|
padding: var(--spacer-sm) 0;
|
|
}
|
|
|
|
.btn-bar .align-right,
|
|
.btn-bar-group .align-right {
|
|
margin-left: auto;
|
|
}
|
|
|
|
.btn-bar .align-center,
|
|
.btn-bar-group .align-center {
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
.btn-bar-group {
|
|
align-items: center;
|
|
display: flex;
|
|
padding: var(--spacer-sm) 0;
|
|
}
|
|
|
|
.btn-bar-group .btn-bar {
|
|
padding: 0;
|
|
}
|
|
|
|
.btn-bar-group select+.btn,
|
|
.btn-bar-group select+button,
|
|
.btn-bar-group .btn+select,
|
|
.btn-bar-group button+select {
|
|
margin-left: var(--spacer-sm)
|
|
}
|
|
|
|
label {
|
|
display: block;
|
|
}
|
|
|
|
fieldset {
|
|
background-color: var(--color-background-column-highlight);
|
|
border: none;
|
|
margin-bottom: var(--spacer);
|
|
border-radius: var(--border-radius);
|
|
}
|
|
|
|
input[type="text"] {
|
|
appearance: none;
|
|
background-color: var(--color-background);
|
|
border-radius: var(--border-radius);
|
|
border: var(--border-width) solid var(--border-color);
|
|
box-sizing: border-box;
|
|
display: block;
|
|
outline: none;
|
|
padding: var(--spacer-sm);
|
|
transition: border-color var(--transition-speed) ease-in-out;
|
|
width: 100%;
|
|
}
|
|
|
|
input[type="text"]:focus {
|
|
border-color: var(--color-accent);
|
|
}
|
|
|
|
input[type="text"].is-invalid {
|
|
border-color: var(--color-danger);
|
|
}
|
|
|
|
.input-help-text {
|
|
display: inline-block;
|
|
}
|
|
.input-help-text, .hint {
|
|
color: var(--color-text-muted);
|
|
font-size: var(--font-size-sm);
|
|
margin: var(--spacer-xs);
|
|
}
|
|
|
|
select {
|
|
background-color: var(--color-button-background);
|
|
border-radius: var(--border-radius);
|
|
border: calc(var(--border-width) / 2) solid var(--color-button-background);
|
|
display: inline-flex;
|
|
font-size: var(--font-size-sm);
|
|
justify-content: center;
|
|
padding: var(--spacer-xs) var(--spacer-sm);
|
|
}
|
|
|
|
button, input[type='button'], .btn {
|
|
align-items: center;
|
|
background-color: var(--color-button-background);
|
|
border-radius: var(--border-radius);
|
|
border: var(--border-width) solid var(--color-button-background);
|
|
color: var(--color-button);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
font-size: var(--font-size-sm);
|
|
justify-content: center;
|
|
padding: var(--spacer-xs) var(--spacer-sm);
|
|
touch-action: manipulation;
|
|
transition-duration: var(--transition-speed);
|
|
transition-property: background-color, border-color, color;
|
|
user-select: none;
|
|
}
|
|
|
|
.btn-lg {
|
|
font-size: var(--font-size-base);
|
|
}
|
|
|
|
.btn-bar.btn-bar-wide {
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
}
|
|
|
|
.btn-bar .btn+.btn,
|
|
.btn-bar button+button {
|
|
margin-left: var(--spacer-sm);
|
|
}
|
|
|
|
button[disabled],
|
|
input[type='button'][disabled],
|
|
.btn[disabled] {
|
|
background-color: transparent;
|
|
border-color: var(--color-button-background);
|
|
color: var(--color-text-muted);
|
|
opacity: .5;
|
|
pointer-events: none;
|
|
}
|
|
|
|
button:hover:not([disabled]),
|
|
input[type='button']:hover:not([disabled]),
|
|
.btn:hover:not([disabled]) {
|
|
transition: all 100ms;
|
|
color: white;
|
|
}
|
|
|
|
button:focus,
|
|
.btn:focus {
|
|
/* Make sure the outline is clearly visible inside the button. */
|
|
outline-offset: -0.5em;
|
|
}
|
|
|
|
.btn-primary {
|
|
background-color: var(--color-accent-background);
|
|
border-color: var(--color-accent-background);
|
|
color: var(--color-accent-text);
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background-color: var(--color-accent);
|
|
border-color: var(--color-accent);
|
|
color: var(--color-accent-text);
|
|
}
|
|
|
|
.btn-secondary {
|
|
background-color: transparent;
|
|
color: var(--color-text-muted);
|
|
border-color: var(--color-text-muted);
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
border-color: var(--color-text);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
.btn-bar .btn.dangerous {
|
|
background-color: #7c4d41;
|
|
color: #e4c5c0;
|
|
margin-left: 1rem;
|
|
}
|
|
|
|
.btn-bar .btn.dangerous[disabled] {
|
|
background-color: #53413e;
|
|
}
|
|
|
|
.details-no-item-selected {
|
|
align-items: center;
|
|
color: var(--color-text-hint);
|
|
display: flex;
|
|
user-select: none;
|
|
height: 50%;
|
|
justify-content: center;
|
|
}
|
|
|
|
.indicator {
|
|
--indicator-color: var(--color-background);
|
|
--indicator-size: 6px;
|
|
|
|
background-color: var(--indicator-color);
|
|
border: calc(var(--indicator-size)/2) solid var(--indicator-color);
|
|
border-radius: 50%;
|
|
display: inline-block;
|
|
height: var(--indicator-size);
|
|
vertical-align: middle;
|
|
width: var(--indicator-size);
|
|
}
|
|
|
|
.status-filter-bar {
|
|
align-items: center;
|
|
display: flex;
|
|
list-style-type: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.status-filter-indicator {
|
|
cursor: pointer;
|
|
margin: .2rem;
|
|
}
|
|
|
|
.status-filter-indicator .indicator {
|
|
--indicator-size: 10px;
|
|
transition: transform var(--transition-speed-fast) ease-in-out;
|
|
}
|
|
|
|
.status-filter-indicator .indicator:hover {
|
|
transform: scale(1.2)
|
|
}
|
|
|
|
.is-filtered .status-filter-indicator {
|
|
opacity: .33;
|
|
}
|
|
|
|
.status-filter-indicator.active {
|
|
opacity: 1.0;
|
|
}
|
|
|
|
.status-active {
|
|
--indicator-color: var(--color-status-active);
|
|
}
|
|
.status-canceled {
|
|
--indicator-color: var(--color-status-canceled);
|
|
}
|
|
.status-completed {
|
|
--indicator-color: var(--color-status-completed);
|
|
}
|
|
.status-construction-failed {
|
|
--indicator-color: var(--color-status-construction-failed);
|
|
}
|
|
.status-failed {
|
|
--indicator-color: var(--color-status-failed);
|
|
}
|
|
.status-soft-failed {
|
|
--indicator-color: var(--color-status-soft-failed);
|
|
}
|
|
.status-paused {
|
|
--indicator-color: var(--color-status-paused);
|
|
}
|
|
.status-queued {
|
|
--indicator-color: var(--color-status-queued);
|
|
}
|
|
.status-archived {
|
|
--indicator-color: var(--color-status-archived);
|
|
}
|
|
.status-archiving {
|
|
--indicator-color: var(--color-status-archiving);
|
|
}
|
|
.status-cancel-requested {
|
|
--indicator-color: var(--color-status-cancel-requested);
|
|
}
|
|
.status-requeueing {
|
|
--indicator-color: var(--color-status-requeueing);
|
|
}
|
|
.status-under-construction {
|
|
--indicator-color: var(--color-status-under-construction);
|
|
}
|
|
|
|
.worker-status-starting {
|
|
--indicator-color: var(--color-worker-status-starting);
|
|
}
|
|
.worker-status-awake {
|
|
--indicator-color: var(--color-worker-status-awake);
|
|
}
|
|
.worker-status-asleep {
|
|
--indicator-color: var(--color-worker-status-asleep);
|
|
}
|
|
.worker-status-error {
|
|
--indicator-color: var(--color-worker-status-error);
|
|
}
|
|
.worker-status-shutdown {
|
|
--indicator-color: var(--color-worker-status-shutdown);
|
|
}
|
|
.worker-status-testing {
|
|
--indicator-color: var(--color-worker-status-testing);
|
|
}
|
|
.worker-status-offline {
|
|
--indicator-color: var(--color-worker-status-offline);
|
|
}
|
|
|
|
[class^='worker-status'] {
|
|
color: var(--indicator-color);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.status-archiving,
|
|
.status-active,
|
|
.status-queued,
|
|
.status-under-construction,
|
|
.status-cancel-requested {
|
|
background-color: transparent;
|
|
}
|
|
|
|
.with-clickable-row .tabulator-row {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.tabulator-row.active-row,
|
|
.tabulator-row.tabulator-row-even.active-row {
|
|
background-color: var(--table-color-background-row-active);
|
|
font-weight: bold;
|
|
}
|
|
|
|
span.state-transition-arrow {
|
|
display: inline-block;
|
|
font-weight: bold;
|
|
transform: scale(1.4);
|
|
}
|
|
span.state-transition-arrow.lazy {
|
|
color: var(--color-text-muted);
|
|
}
|
|
|
|
.preview-container {
|
|
align-items: center;
|
|
background-color: var(--color-background);
|
|
border-radius: var(--border-radius);
|
|
display: flex;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
padding-top: 56.25%;
|
|
position: relative;
|
|
}
|
|
|
|
.preview-container div:first-child {
|
|
align-items: center;
|
|
display: flex;
|
|
height: 100%;
|
|
justify-content: center;
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
}
|
|
|
|
.preview-container img {
|
|
max-height: 100%;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.click-to-copy {
|
|
/* The transition plays together with the duration set in clipboard.js */
|
|
--transition-duration: var(--transition-speed-fast);
|
|
cursor: pointer;
|
|
transition: var(--transition-duration);
|
|
}
|
|
.click-to-copy.copied {
|
|
background-color: var(--color-accent-background);
|
|
color: var(--color-accent-text);
|
|
transition: var(--transition-duration);
|
|
}
|