Files
nomad/ui/app/styles/components/job-status-panel.scss
Phil Renaud e1e59455e4 [ui, feature] Job Page Redesign (#16932)
* [ui] Service job status panel (#16134)

* it begins

* Hacky demo enabled

* Still very hacky but seems deece

* Floor of at least 3 must be shown

* Width from on-high

* Other statuses considered

* More sensible allocTypes listing

* Beginnings of a legend

* Total number of allocs running now maps over job.groups

* Lintfix

* base the number of slots to hold open on actual tallies, which should never exceed totalAllocs

* Versions get yer versions here

* Versions lookin like versions

* Mirage fixup

* Adds Remaining as an alloc chart status and adds historical status option

* Get tests passing again by making job status static for a sec

* Historical status panel click actions moved into their own component class

* job detail tests plz chill

* Testing if percy is fickle

* Hyper-specfic on summary distribution bar identifier

* Perhaps the 2nd allocSummary item no longer exists with the more accurate afterCreate data

* UI Test eschewing the page pattern

* Bones of a new acceptance test

* Track width changes explicitly with window-resize

* testlintfix

* Alloc counting tests

* Alloc grouping test

* Alloc grouping with complex resizing

* Refined the list of showable statuses

* PR feedback addressed

* renamed allocation-row to allocation-status-row

* [ui, job status] Make panel status mode a queryParam (#16345)

* queryParam changing

* Test for QP in panel

* Adding @tracked to legacy controller

* Move the job of switching to Historical out to larger context

* integration test mock passed func

* [ui] Service job deployment status panel (#16383)

* A very fast and loose deployment panel

* Removing Unknown status from the panel

* Set up oldAllocs list in constructor, rather than as a getter/tracked var

* Small amount of template cleanup

* Refactored latest-deployment new logic back into panel.js

* Revert now-unused latest-deployment component

* margin bottom when ungrouped also

* Basic integration tests for job deployment status panel

* Updates complete alloc colour to green for new visualizations only (#16618)

* Updates complete alloc colour to green for new visualizations only

* Pale green instead of dark green for viz in general

* [ui] Job Deployment Status: History and Update Props (#16518)

* Deployment history wooooooo

* Styled deployment history

* Update Params

* lintfix

* Types and groups for updateParams

* Live-updating history

* Harden with types, error states, and pending states

* Refactor updateParams to use trigger component

* [ui] Deployment History search (#16608)

* Functioning searchbox

* Some nice animations for history items

* History search test

* Fixing up some old mirage conventions

* some a11y rule override to account for scss keyframes

* Split panel into deploying and steady components

* HandleError passed from job index

* gridified panel elements

* TotalAllocs added to deploying.js

* Width perc to px

* [ui] Splitting deployment allocs by status, health, and canary status (#16766)

* Initial attempt with lots of scratchpad work

* Style mods per UI discussion

* Fix canary overflow bug

* Dont show canary or health for steady/prev-alloc blocks

* Steady state

* Thanks Julie

* Fixes steady-state versions

* Legen, wait for it...

* Test fixes now that we have a minimum block size

* PR prep

* Shimmer effect on pending and unplaced allocs (#16801)

* Shimmer effect on pending and unplaced

* Dont show animation in the legend

* [ui, deployments] Linking allocblocks and legends to allocation / allocations index routes (#16821)

* Conditional link-to component and basic linking to allocations and allocation routes

* Job versions filter added to allocations index page

* Steady state legends link

* Legend links

* Badge count links for versions

* Fix: faded class on steady-state legend items

* version link now wont show completed ones

* Fix a11y violations with link labels

* Combining some template conditional logic

* [ui, deployments] Conversions on long nanosecond update params (#16882)

* Conversions on long nanosecond nums

* Early return in updateParamGroups comp prop

* [ui, deployments] Mirage Actively Deploying Job and Deployment Integration Tests (#16888)

* Start of deployment alloc test scaffolding

* Bit of test cleanup and canary for ungrouped allocs

* Flakey but more robust integrations for deployment panel

* De-flake acceptance tests and add an actively deploying job to mirage

* Jitter-less alloc status distribution removes my bad math

* bugfix caused by summary.desiredTotal non-null

* More interesting mirage active deployment alloc breakdown

* Further tests for previous-allocs row

* Previous alloc legend tests

* Percy snapshots added to integration test

* changelog
2023-04-24 22:45:39 -04:00

443 lines
8.5 KiB
SCSS

.job-status-panel {
// #region layout
&.steady-state.current-state .boxed-section-body {
display: grid;
grid-template-areas:
'title'
'allocation-status-row'
'legend-and-summary';
gap: 1rem;
grid-auto-columns: 100%;
& > h3 {
grid-area: title;
margin: 0;
}
& > .allocation-status-row {
grid-area: allocation-status-row;
}
}
&.active-deployment .boxed-section-body {
display: grid;
grid-template-areas:
'deployment-allocations'
'legend-and-summary'
'history-and-params';
gap: 1rem;
grid-auto-columns: 100%;
& > .deployment-allocations {
grid-area: deployment-allocations;
display: grid;
gap: 1rem;
grid-auto-columns: 100%;
& > h4 {
margin-bottom: -0.5rem;
}
}
& > .history-and-params {
grid-area: history-and-params;
}
}
.legend-and-summary {
// grid-area: legend-and-summary;
// TODO: may revisit this grid-area later, but is currently used in 2 competing ways
display: grid;
gap: 0.5rem;
grid-template-columns: 50% 50%;
legend {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.5rem;
}
.versions {
display: grid;
gap: 0.5rem;
& > ul {
display: grid;
grid-template-columns: repeat(auto-fit, 100px);
gap: 0.5rem;
& > li {
white-space: nowrap;
& a {
text-decoration: none;
}
}
}
}
}
// #endregion layout
.select-mode {
border: 1px solid $grey-blue;
background: rgba(0, 0, 0, 0.05);
border-radius: 2px;
display: grid;
gap: 0.5rem;
grid-template-columns: 1fr 1fr;
padding: 0.25rem 0.5rem;
margin-left: 1rem;
button {
height: auto;
padding: 0 0.5rem;
background: transparent;
transition: 0.1s;
&:hover {
background: rgba(255, 255, 255, 0.5);
}
&.is-active {
background: $white;
}
}
}
.running-allocs-title {
strong {
font-weight: 800;
}
}
.ungrouped-allocs {
display: grid;
gap: 10px;
grid-auto-flow: column;
grid-auto-columns: 32px;
& > .represented-allocation {
width: 32px;
}
}
.alloc-status-summaries {
display: flex;
height: 32px;
gap: 1.5rem;
.allocation-status-block {
display: grid;
grid-template-columns: auto 50px;
gap: 10px;
&.rest-only {
grid-template-columns: auto;
}
& > .ungrouped-allocs {
display: grid;
grid-auto-flow: column;
gap: 10px;
grid-auto-columns: unset;
& > .represented-allocation {
width: 32px;
}
}
.represented-allocation.rest {
// TODO: we eventually want to establish a minimum width here. However, we need to also include this in the allocation-status-block width computation.
font-size: 0.8rem;
font-weight: bold;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
width: 100%;
& > .rest-count {
position: relative;
z-index: 2;
}
&.unplaced {
color: black;
}
}
}
}
.represented-allocation {
background: $green;
border-radius: 4px;
height: 32px;
width: 32px;
color: white;
position: relative;
display: grid;
align-content: center;
justify-content: center;
$queued: $grey;
$pending: $grey-lighter;
$running: $primary;
$complete: $nomad-green-pale;
$failed: $danger;
$lost: $dark;
// Client Statuses
&.running {
background: $running;
}
&.failed {
background: $failed;
}
&.unknown {
background: $unknown;
}
&.queued {
background: $queued;
}
&.complete {
background: $complete;
color: black;
}
&.pending {
background: $pending;
color: black;
position: relative;
overflow: hidden;
&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(-60deg, $pending, #eee, $pending);
animation: shimmer 2s ease-in-out infinite;
}
}
&.lost {
background: $lost;
}
&.unplaced {
background: $grey-lighter;
position: relative;
overflow: hidden;
&:before {
background: linear-gradient(-60deg, $pending, #eee, $pending);
animation: shimmer 2s ease-in-out infinite;
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: calc(100% - 4px);
height: calc(100% - 4px);
margin: 2px;
background: white;
border-radius: 3px;
}
}
&.legend-example {
background: #eee;
}
// Health Statuses
.alloc-health-indicator {
width: 100%;
height: 100%;
position: absolute;
display: grid;
align-content: center;
justify-content: center;
}
&.running {
.alloc-health-indicator {
position: absolute;
width: 100%;
height: 100%;
display: grid;
align-content: center;
justify-content: center;
}
&.rest .alloc-health-indicator {
top: -7px;
right: -7px;
border-radius: 20px;
background: white;
box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.5);
width: 20px;
height: 20px;
box-sizing: border-box;
transform: scale(0.75);
}
}
// Canary Status
&.canary > .alloc-canary-indicator {
overflow: hidden;
width: 16px;
height: 16px;
position: absolute;
bottom: 0;
left: 0;
border-radius: 4px;
&:after {
content: '';
position: absolute;
left: -8px;
bottom: -8px;
width: 16px;
height: 16px;
transform: rotate(45deg);
background-color: $orange;
}
}
}
.legend-item .represented-allocation .flight-icon {
animation: none;
}
& > .boxed-section-body > .deployment-allocations {
margin-bottom: 1rem;
}
.legend-item {
display: grid;
gap: 0.5rem;
grid-template-columns: auto 1fr;
&.faded {
opacity: 0.5;
}
.represented-allocation {
width: 20px;
height: 20px;
animation: none;
&:before,
&:after {
animation: none;
}
}
}
.history-and-params {
display: grid;
grid-template-columns: 70% auto;
gap: 1rem;
margin-top: 1rem;
}
.deployment-history {
& > header {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1rem;
margin-bottom: 1rem;
align-items: end;
& > .search-box {
max-width: unset;
}
}
& > ol {
max-height: 300px;
overflow-y: auto;
}
& > ol > li {
@for $i from 1 through 50 {
&:nth-child(#{$i}) {
animation-name: historyItemSlide;
animation-duration: 0.2s;
animation-fill-mode: both;
animation-delay: 0.1s + (0.05 * $i);
}
&:nth-child(#{$i}) > div {
animation-name: historyItemShine;
animation-duration: 1s;
animation-fill-mode: both;
animation-delay: 0.1s + (0.05 * $i);
}
}
& > div {
gap: 0.5rem;
}
&.error > div {
border: 1px solid $danger;
background: rgba($danger, 0.1);
}
}
}
.update-parameters {
& > code {
max-height: 300px;
overflow-y: auto;
display: block;
}
ul,
span.notification {
display: block;
background: #1a2633;
padding: 1rem;
color: white;
.key {
color: #1caeff;
&:after {
content: '=';
color: white;
margin-left: 0.5rem;
}
}
.value {
color: #06d092;
}
}
}
}
@keyframes historyItemSlide {
from {
opacity: 0;
top: -40px;
}
to {
opacity: 1;
top: 0px;
}
}
@keyframes historyItemShine {
from {
box-shadow: inset 0 0 0 100px rgba(255, 200, 0, 0.2);
}
to {
box-shadow: inset 0 0 0 100px rgba(255, 200, 0, 0);
}
}
@keyframes shimmer {
0% {
transform: translate3d(-100%, 0, 0);
}
30% {
transform: translate3d(100%, 0, 0);
}
100% {
transform: translate3d(100%, 0, 0);
}
}