mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
## PR 1/2 for #32037 - Implements update for the Linux setup experience from the IT admin's point of view. Updates for the end-user ("My device" page) to follow - Works in concert with the new endpoints implemented in https://github.com/fleetdm/fleet/pull/32493 - Splits Controls > Setup experience > Install software into 3 tabbed sections, one for each of macOS, Windows (placeholder state for now, to be implemented in following iteration), and Linux. - Dynamically calls new GET and PUT endpoints and routes data accordingly depending on which platform software for install is being updated for. - Update the software selection modal to display software package versions, including the package type (deb, rpm, or tar) for Linux software packges. - New activity feed item - Update relevant tests  _Note that the lower-right-hand image in this GIF is outdated and will be updated with new content once this entire feature is integrated_ ~- [ ] Changes file added for user-visible changes in `changes/`~ will include in PR 2/2 - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually - [x] Verified that any relevant UI is disabled when GitOps mode is enabled --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
467 lines
9.2 KiB
SCSS
467 lines
9.2 KiB
SCSS
$min-width: $break-xs;
|
|
$medium-width: 1024px;
|
|
$desktop-width: 1200px;
|
|
$max-width: 2560px;
|
|
|
|
@mixin breakpoint($size: desktop) {
|
|
@if ($size == tablet) {
|
|
@media (max-width: $medium-width) {
|
|
@content;
|
|
}
|
|
} @else if ($size == ltdesktop) {
|
|
@media (max-width: ($desktop-width - 1)) {
|
|
@content;
|
|
}
|
|
} @else if ($size == desktop) {
|
|
@media (min-width: ($medium-width + 1)) {
|
|
@content;
|
|
}
|
|
} @else if ($size == smalldesk) {
|
|
@media (max-width: 1185px) {
|
|
@content;
|
|
}
|
|
} @else {
|
|
@content;
|
|
}
|
|
}
|
|
|
|
// Used to normalize styling of team header wrapper on various pages
|
|
@mixin normalize-team-header {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 38px;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
// Used to keep the settings description sticky under the main nav and sub nav.
|
|
// TODO: figure out how to calculate these values with variables. Will be tedious to change otherwise
|
|
@mixin sticky-settings-description {
|
|
position: sticky;
|
|
// this is the current spacing needed to keep the description looking correct under the sub nav when scrolling.
|
|
top: 104px;
|
|
z-index: 2;
|
|
background-color: $core-white;
|
|
margin: 0;
|
|
padding: $pad-xxlarge 0 54px 0;
|
|
}
|
|
|
|
@mixin grey-badge {
|
|
background-color: $ui-fleet-black-25;
|
|
color: $core-white;
|
|
font-size: $xx-small;
|
|
font-weight: $bold;
|
|
padding: 0 $pad-xsmall;
|
|
border-radius: $border-radius;
|
|
position: relative;
|
|
margin-left: $pad-xsmall;
|
|
}
|
|
|
|
// Used to create a list item with the item data (name, created at, etc...) on
|
|
// the left and the item actions (download, delete, etc...) on the right.
|
|
@mixin list-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
&__list-item-data {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
&__list-item-info {
|
|
margin-left: $pad-medium;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
&__list-item-name {
|
|
font-size: $x-small;
|
|
font-weight: $bold;
|
|
}
|
|
|
|
&__list-item-uploaded {
|
|
font-size: $xx-small;
|
|
}
|
|
|
|
&__list-item-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
&__list-item-button {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
|
|
&__list-item-button:not(:last-child) {
|
|
margin-right: $pad-medium;
|
|
}
|
|
}
|
|
|
|
// used to share styles across the manual enroll mdm modal and the auto enroll mdm modal.
|
|
@mixin enroll-mdm-modal {
|
|
&__description {
|
|
margin: $pad-large 0;
|
|
}
|
|
|
|
&__download-button {
|
|
margin-top: 12px;
|
|
}
|
|
|
|
ol {
|
|
padding-left: 0;
|
|
}
|
|
|
|
li {
|
|
margin-bottom: $pad-large;
|
|
list-style-position: inside;
|
|
}
|
|
}
|
|
|
|
@mixin disabled {
|
|
opacity: 0.5;
|
|
filter: grayscale(0.5);
|
|
pointer-events: none;
|
|
cursor: default;
|
|
|
|
// Must override
|
|
&:hover,
|
|
&:focus {
|
|
cursor: default;
|
|
}
|
|
}
|
|
|
|
@mixin disabled-checkbox {
|
|
background-color: $ui-fleet-black-25;
|
|
border-color: $ui-fleet-black-25;
|
|
pointer-events: none;
|
|
cursor: default;
|
|
}
|
|
|
|
@mixin grey-text {
|
|
color: $ui-fleet-black-75;
|
|
}
|
|
|
|
@mixin help-text {
|
|
font-size: $xx-small;
|
|
font-weight: $regular;
|
|
@include grey-text;
|
|
|
|
.custom-link,
|
|
button {
|
|
font-size: inherit;
|
|
}
|
|
}
|
|
|
|
@mixin link {
|
|
color: $core-vibrant-blue;
|
|
font-weight: $bold;
|
|
font-size: $x-small;
|
|
text-decoration: none;
|
|
&:focus-visible {
|
|
outline-color: #d9d9fe;
|
|
outline-offset: 3px;
|
|
outline-style: solid;
|
|
outline-width: 2px;
|
|
border-radius: 2px;
|
|
}
|
|
}
|
|
|
|
@mixin table-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: $pad-small $pad-xxsmall; // larger clickable area
|
|
gap: $pad-small;
|
|
white-space: nowrap;
|
|
@include link;
|
|
|
|
&:hover {
|
|
text-decoration: underline;
|
|
}
|
|
}
|
|
|
|
@mixin cell-with-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
}
|
|
|
|
@mixin direction-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: $pad-small $pad-xxsmall; // larger clickable area
|
|
border-radius: 3px; // Visible while tabbing;
|
|
gap: $pad-xsmall;
|
|
|
|
&:hover {
|
|
color: $core-vibrant-blue-over;
|
|
text-decoration: underline;
|
|
|
|
svg {
|
|
path {
|
|
stroke: $core-vibrant-blue-over;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin ellipse-text($max-width: auto) {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
max-width: $max-width;
|
|
}
|
|
|
|
@mixin copy-message {
|
|
font-weight: $regular;
|
|
font-size: $x-small;
|
|
vertical-align: top;
|
|
background-color: $ui-light-grey;
|
|
border: solid 1px #e2e4ea;
|
|
border-radius: 10px;
|
|
padding: 2px 6px;
|
|
}
|
|
|
|
@mixin color-contrasted-sections {
|
|
background-color: $ui-off-white;
|
|
.section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: $core-white;
|
|
border-radius: 16px;
|
|
border: 1px solid $ui-fleet-black-10;
|
|
padding: $pad-xxlarge;
|
|
box-shadow: 0px 3px 0px rgba(226, 228, 234, 0.4);
|
|
}
|
|
}
|
|
|
|
@mixin tooltip-text {
|
|
width: max-content;
|
|
max-width: 360px;
|
|
padding: 6px;
|
|
color: $core-white;
|
|
background-color: $tooltip-bg;
|
|
font-weight: $regular;
|
|
font-size: $xx-small;
|
|
border-radius: 4px;
|
|
box-sizing: border-box;
|
|
z-index: 100;
|
|
line-height: 1.375;
|
|
white-space: initial;
|
|
|
|
// Hyphenated words will still break at hyphens first
|
|
// while non-hyphenated strings will break only when necessary
|
|
overflow-wrap: break-word; // Preferred property for modern browsers
|
|
word-wrap: break-word; // Fallback for older browsers e.g. IE
|
|
word-break: break-word; // Ensures words break when necessary
|
|
|
|
p {
|
|
margin: 0;
|
|
}
|
|
}
|
|
|
|
@mixin flex-column-1rem-gap {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
@mixin page {
|
|
@include flex-column-1rem-gap;
|
|
}
|
|
|
|
@mixin form-button-extra-clickable-area-compensation {
|
|
// compensate in layout for extra clickable area button height
|
|
margin: -8px 0;
|
|
}
|
|
|
|
@mixin button-dropdown {
|
|
.form-field {
|
|
margin: 0;
|
|
}
|
|
|
|
.Select {
|
|
position: relative;
|
|
border: 0;
|
|
height: auto;
|
|
|
|
&.is-focused,
|
|
&:hover {
|
|
border: 0;
|
|
}
|
|
|
|
&.is-focused:not(.is-open) {
|
|
.Select-control {
|
|
background-color: initial;
|
|
}
|
|
}
|
|
|
|
.Select-control {
|
|
display: flex;
|
|
background-color: initial;
|
|
height: auto;
|
|
justify-content: space-between;
|
|
border: 0;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
box-shadow: none;
|
|
}
|
|
|
|
&:hover .Select-placeholder {
|
|
color: $core-vibrant-blue;
|
|
}
|
|
|
|
.Select-placeholder {
|
|
font-size: 14px;
|
|
line-height: normal;
|
|
padding-left: 0;
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.Select-input {
|
|
height: auto;
|
|
|
|
// When tabbing
|
|
&:focus-visible {
|
|
outline: 2px solid $ui-vibrant-blue-25;
|
|
outline-offset: 1px;
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
|
|
.Select-arrow-zone {
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
.Select-placeholder {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.Select-menu-outer {
|
|
margin-top: $pad-xsmall;
|
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
border-radius: $border-radius;
|
|
z-index: 6;
|
|
overflow: hidden;
|
|
border: 0;
|
|
width: 188px;
|
|
left: unset;
|
|
top: unset;
|
|
max-height: none;
|
|
padding: $pad-small;
|
|
position: absolute;
|
|
|
|
.Select-menu {
|
|
max-height: none;
|
|
}
|
|
}
|
|
|
|
.Select-arrow {
|
|
transition: transform 0.25s ease;
|
|
}
|
|
|
|
&:not(.is-open) {
|
|
.Select-control:hover .Select-arrow {
|
|
content: url("../assets/images/icon-chevron-blue-16x16@2x.png");
|
|
}
|
|
}
|
|
|
|
&.is-open {
|
|
.Select-control .Select-placeholder {
|
|
color: $core-vibrant-blue;
|
|
}
|
|
|
|
.Select-arrow {
|
|
transform: rotate(180deg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin tooltip5-arrow-styles {
|
|
// arrow styles directly from react-tooltip-5 css
|
|
.react-tooltip-arrow {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
[class*="react-tooltip__place-top"] > .styles-module_arrow__K0L3T {
|
|
transform: rotate(45deg);
|
|
}
|
|
[class*="react-tooltip__place-right"] > .styles-module_arrow__K0L3T {
|
|
transform: rotate(135deg);
|
|
}
|
|
[class*="react-tooltip__place-bottom"] > .styles-module_arrow__K0L3T {
|
|
transform: rotate(225deg);
|
|
}
|
|
[class*="react-tooltip__place-left"] > .styles-module_arrow__K0L3T {
|
|
transform: rotate(315deg);
|
|
}
|
|
}
|
|
|
|
@mixin side-nav-list {
|
|
position: -webkit-sticky;
|
|
position: sticky;
|
|
// this is the spacing needed to make the sticky form nav position correctly when scrolling
|
|
// TODO: find a way to calculate these sticky positions this and use variables.
|
|
// will be tedious to update otherwise.
|
|
top: 217px;
|
|
width: 260px;
|
|
padding: 0 64px 0 0;
|
|
list-style: none;
|
|
font-size: $x-small;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: $pad-small;
|
|
margin: 0;
|
|
}
|
|
|
|
@mixin side-nav-item {
|
|
white-space: nowrap;
|
|
height: 32px;
|
|
border-radius: 4px;
|
|
|
|
a {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
padding: 0 16px;
|
|
color: $core-fleet-black;
|
|
font-weight: $regular;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
color: $core-vibrant-blue;
|
|
}
|
|
}
|
|
|
|
&--active {
|
|
background-color: $ui-fleet-black-5;
|
|
a {
|
|
font-weight: $bold;
|
|
color: $ui-fleet-black-75;
|
|
* > .__react_component_tooltip {
|
|
font-weight: initial;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin tab-empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
border: 1px solid $ui-fleet-black-10;
|
|
border-radius: $pad-xsmall;
|
|
padding: $pad-xxlarge;
|
|
gap: $pad-small;
|
|
font-size: $small;
|
|
p {
|
|
margin: 0;
|
|
@include help-text;
|
|
}
|
|
}
|