mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
450 lines
11 KiB
SCSS
450 lines
11 KiB
SCSS
$shadow-width: 40px;
|
||
$shadow-transition-width: 10px;
|
||
|
||
.data-table-block {
|
||
position: relative;
|
||
display: inline-block;
|
||
width: 100%;
|
||
|
||
.data-table {
|
||
&__wrapper {
|
||
position: relative;
|
||
border: 1px solid $ui-fleet-black-10;
|
||
border-radius: 6px;
|
||
flex-grow: 1;
|
||
width: 100%;
|
||
|
||
// Shadow
|
||
background-image:
|
||
/* Shadows */ linear-gradient(
|
||
to right,
|
||
white,
|
||
$transparent
|
||
),
|
||
linear-gradient(to left, white, $transparent),
|
||
/* Shadow covers */
|
||
linear-gradient(to right, $ui-shadow, white $shadow-transition-width),
|
||
linear-gradient(to left, $ui-shadow, white $shadow-transition-width);
|
||
|
||
background-position: left center, right center, left center, right center;
|
||
background-repeat: no-repeat;
|
||
background-color: white;
|
||
background-size: $shadow-width 100%, $shadow-width 100%, 50% 100%,
|
||
50% 100%;
|
||
|
||
/* Opera doesn't support this in the shorthand */
|
||
background-attachment: local, local, scroll, scroll;
|
||
// End shadow
|
||
}
|
||
|
||
// applied to same element as data-table__table while loading
|
||
&__no-rows {
|
||
min-height: 272px;
|
||
}
|
||
|
||
&__table {
|
||
position: relative;
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
color: $ui-fleet-black-75;
|
||
font-size: $x-small;
|
||
}
|
||
|
||
tr {
|
||
border-bottom: 1px solid $ui-fleet-black-10;
|
||
|
||
&:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
|
||
// override styles of checkbox data cells
|
||
.form-field--checkbox {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-bottom: 0;
|
||
|
||
.fleet-checkbox__label {
|
||
padding-left: 0;
|
||
}
|
||
}
|
||
|
||
// Cleaner when tabbing
|
||
a:focus-visible {
|
||
outline-offset: 0;
|
||
border-radius: $border-radius-medium;
|
||
}
|
||
}
|
||
|
||
thead {
|
||
background-color: $ui-off-white-opaque; // opaque needed for horizontal scroll shadow
|
||
color: $core-fleet-black;
|
||
text-align: left;
|
||
border-bottom: 1px solid $ui-fleet-black-10;
|
||
|
||
// resize header icons
|
||
img {
|
||
width: 16px;
|
||
height: 16px;
|
||
vertical-align: top;
|
||
}
|
||
|
||
// do not resize button icons inside headers
|
||
.button {
|
||
img {
|
||
width: initial;
|
||
height: initial;
|
||
vertical-align: initial;
|
||
}
|
||
}
|
||
|
||
th {
|
||
padding: 0 $table-cell-padding;
|
||
white-space: nowrap;
|
||
border-left: 1px solid $ui-fleet-black-10;
|
||
font-weight: $bold;
|
||
font-size: $xx-small;
|
||
height: 40px; // Match body row height
|
||
|
||
&:first-child {
|
||
border-top-left-radius: 6px;
|
||
border-left: none;
|
||
}
|
||
|
||
&.selection__header,
|
||
&.active-selection__checkbox {
|
||
width: 16px;
|
||
padding: 0 $pad-medium;
|
||
}
|
||
|
||
&:last-child {
|
||
border-top-right-radius: 6px;
|
||
}
|
||
|
||
&.actions__header,
|
||
&.id__header // Same as actions__header on some pages
|
||
{
|
||
border-left: none;
|
||
width: 99px;
|
||
}
|
||
|
||
&.linkToFilteredHosts__header,
|
||
&.view-all-hosts__header // Same as linkToFilteredHosts__header on some pages
|
||
{
|
||
border-left: none;
|
||
width: 120px;
|
||
}
|
||
|
||
.column-header {
|
||
display: flex;
|
||
flex-direction: column; // Filters under header name
|
||
min-width: max-content;
|
||
font-weight: $bold;
|
||
|
||
span {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
}
|
||
}
|
||
|
||
.header-cell {
|
||
font-weight: $bold;
|
||
}
|
||
|
||
// Sort arrows change color on hover
|
||
.sortable-header {
|
||
.column-header {
|
||
.header-cell {
|
||
min-height: 32px; // Leave room for outline on keyboard focus
|
||
}
|
||
}
|
||
|
||
&:hover {
|
||
.header-cell:not(.ascending) {
|
||
.ascending-arrow {
|
||
border-bottom-color: $ui-fleet-black-50;
|
||
}
|
||
}
|
||
.header-cell.ascending {
|
||
.descending-arrow {
|
||
border-top-color: $ui-fleet-black-50;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
&.active-selection {
|
||
background: none;
|
||
z-index: 1;
|
||
th {
|
||
border: 0;
|
||
}
|
||
.fleet-checkbox {
|
||
opacity: 0;
|
||
}
|
||
.active-selection__container {
|
||
background-color: $ui-off-white;
|
||
width: 100% !important; // Too much specificity currently at page-level styling. Revisit after data table CSS update to remove !important.
|
||
.active-selection__inner {
|
||
justify-content: flex-start;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.active-selection {
|
||
position: absolute;
|
||
top: 0px;
|
||
width: 100%;
|
||
border: 0;
|
||
border-radius: 6px;
|
||
|
||
&__checkbox {
|
||
width: 16px;
|
||
}
|
||
|
||
&__container {
|
||
padding: 0 $table-cell-padding;
|
||
}
|
||
|
||
&__inner {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
p {
|
||
margin: 0 $pad-medium 0 0;
|
||
font-weight: $regular;
|
||
|
||
span {
|
||
font-weight: $bold;
|
||
}
|
||
}
|
||
|
||
button {
|
||
margin-right: $pad-medium;
|
||
}
|
||
}
|
||
|
||
&__inner-left,
|
||
&__inner-right {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
}
|
||
|
||
tbody {
|
||
.component__tooltip-wrapper {
|
||
margin: 10px 0; // vertical padding multiline text with tooltip
|
||
}
|
||
|
||
.component__tooltip-wrapper__element {
|
||
white-space: initial; // wraps long text with tooltip
|
||
}
|
||
|
||
tr,
|
||
.single-row {
|
||
transition: background-color 150ms ease-out;
|
||
&:hover {
|
||
background-color: $ui-off-white-opaque; // opaque needed for horizontal scroll shadow
|
||
}
|
||
&:focus-visible {
|
||
outline: 2px solid $core-focused-outline;
|
||
background: $ui-off-white;
|
||
border-radius: $border-radius;
|
||
}
|
||
}
|
||
|
||
.single-row {
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
&:active {
|
||
background-color: $ui-vibrant-blue-10-opaque; // opaque needed for horizontal scroll shadow
|
||
}
|
||
}
|
||
|
||
.clickable-row {
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
td {
|
||
height: 40px;
|
||
padding: 0 $table-cell-padding;
|
||
max-width: 500px;
|
||
word-wrap: break-word;
|
||
|
||
&.actions__cell,
|
||
&.id__cell // Same as actions__cell on some pages
|
||
{
|
||
display: flex;
|
||
justify-content: end; // Aligns actions dropdown to right of table
|
||
max-width: 99px;
|
||
}
|
||
|
||
&.linkToFilteredHosts__cell,
|
||
&.view-all-hosts__cell // Same as linkToFilteredHosts__cell on some pages
|
||
{
|
||
text-align: right;
|
||
max-width: 140px;
|
||
// display: flex causes layout issues on /software/vulnerabilities table
|
||
align-items: center;
|
||
}
|
||
|
||
&.selection__cell {
|
||
width: 0px;
|
||
padding: 0 $pad-medium;
|
||
}
|
||
.link-cell,
|
||
.text-cell {
|
||
display: block; // inline-block is not vertically centered
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
margin: 0;
|
||
.__react_component_tooltip {
|
||
white-space: normal;
|
||
}
|
||
}
|
||
|
||
// Caution: LinkCell depends on this to have animation only under text and not icons etc
|
||
.link-cell {
|
||
display: inline-block; // Underline only words
|
||
overflow: visible;
|
||
@include link;
|
||
|
||
&:not(.link-cell--tooltip-truncate) {
|
||
@include animated-bottom-border;
|
||
}
|
||
|
||
&.link-cell--tooltip-truncate {
|
||
min-width: 100%; // Take up as much of cell as possible
|
||
|
||
.data-table__tooltip-truncated-text-container {
|
||
position: relative;
|
||
@include bottom-border;
|
||
}
|
||
|
||
&:hover,
|
||
&:focus {
|
||
margin-bottom: 0; // Undo margin-bottom of animated bottom border
|
||
|
||
.data-table__tooltip-truncated-text::after,
|
||
.data-table__tooltip-truncated-text::after {
|
||
transform: scaleX(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
&:hover {
|
||
.data-table__tooltip-truncated-text-container {
|
||
@include animated-bottom-border;
|
||
margin-bottom: 0; // Undo margin-bottom of animated bottom border
|
||
|
||
&:hover {
|
||
margin-bottom: 0; // Undo margin-bottom of animated bottom border
|
||
}
|
||
|
||
&::after {
|
||
transform: scaleX(
|
||
1
|
||
); // This gets the animation on the text only when hovering over the whole link-cell
|
||
}
|
||
}
|
||
}
|
||
|
||
> div {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: $pad-small;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.truncated-tooltip {
|
||
font-weight: $regular;
|
||
}
|
||
}
|
||
|
||
// css to properly style link-cell with tooltip
|
||
.link-cell-tooltip-wrapper {
|
||
overflow: visible; // fixes tooltip overflow cut off by cell
|
||
white-space: nowrap; // single line
|
||
margin: 0; // padding applied to .link-cell for larger clickable area
|
||
.component__tooltip-wrapper {
|
||
&__element {
|
||
display: block;
|
||
white-space: nowrap; // single line
|
||
text-overflow: ellipsis; // truncates text
|
||
overflow: hidden;
|
||
// TODO – this naming is now confusing, as this .link-cell is not the outermost layer of
|
||
// the cell – it's a NameCell
|
||
.link-cell {
|
||
padding: 0;
|
||
}
|
||
}
|
||
|
||
&__tip-text {
|
||
cursor: auto;
|
||
}
|
||
}
|
||
}
|
||
.w400 {
|
||
max-width: 352px; // 400px - 48px padding
|
||
min-width: 100%;
|
||
text-align: left;
|
||
}
|
||
.w250 {
|
||
max-width: 202px; // 250px - 48px padding
|
||
min-width: 100%;
|
||
text-align: left;
|
||
}
|
||
.w150 {
|
||
max-width: 102px; // 250px - 48px padding
|
||
min-width: 100%;
|
||
text-align: left;
|
||
}
|
||
.italic-cell {
|
||
font-style: italic;
|
||
.__react_component_tooltip {
|
||
font-style: normal;
|
||
}
|
||
}
|
||
.grey-cell {
|
||
color: $ui-fleet-black-50;
|
||
}
|
||
}
|
||
|
||
.disable-highlight:hover {
|
||
background-color: initial;
|
||
}
|
||
}
|
||
}
|
||
|
||
.loading-overlay {
|
||
display: flex;
|
||
flex-grow: 1;
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background-color: rgba(255, 255, 255, 0.8);
|
||
z-index: 1;
|
||
}
|
||
|
||
&__footer {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 50px; // Match pagination height as pagination is optionally rendered
|
||
}
|
||
|
||
&__table-help-text {
|
||
font-size: $x-small;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
}
|