Basic tables now inherit from Bootstrap Theme

Horizon tables had many hardcoded padding and colors in them, which
made them not theme-ready.  This patch vets all the old table styles
for their current usage (if any) and reimplemented the necessary
rules to inherit from the theme.

There were a number of styles that were obviously not being used any
longer. These rules were removed.  There were also many rules that
were very difficult to determine their lineage, as the scss lacks
much needed commentary on why some styles exist (if they are working
around specific browser issues, or usability glitches, etc).

A few examples of some of these removed styles include:
 * th.narrow
 * td.select
 * th span.required:after

This patch does not include refactor of the dropdowns or inline edit.

Immediate Improvements:
 * Table Actions are now all consistent heights
 * The cursor is a pointer ONLY on sortable rows now
 * The column sort indicator is now an icon font, therefore high def
 * table_header height no longer hardcoded, can grow with theme
 * Slow waiting cursor style using global selector * removed
 * Many dead styles were removed!!
 * Hovering on status_unknown rows now keeps proper color

Partially-Implements: blueprint horizon-theme-css-reorg
Partially-Implements: blueprint bootstrap-html-standards
Change-Id: I4a904704926dc50010ad480539db828eff559fa0
This commit is contained in:
Diana Whitten 2015-08-25 09:29:30 -07:00
parent d97c60c2fe
commit 8ba1a5e06a
14 changed files with 266 additions and 338 deletions

View File

@ -124,6 +124,11 @@ full use of the Bootstrap theme architecture.
* `Side Nav`_
* `Pie Charts`_
9.0.0 (Mitaka)
~~~~~~~~~~~~~~
* Tables_
Step 1
------
@ -180,6 +185,18 @@ Since there is no native element in Bootstrap specifically for pie charts,
the look and feel of the charts are inheriting from other elements of the
theme. Please see ``_pie_charts.scss`` for specifics.
.. _Tables:
Tables
------
The standard Django tables now make use of the native Bootstrap table markup.
See **Tables** section of your variables file for variables to customize.
The standard Bootstrap tables will be borderless by default. If you wish to
add a border, like the ``default`` theme, see
``openstack_dashboard/themes/default/horizon/components/_tables.scss``
Bootswatch and Material Design
------------------------------

View File

@ -37,7 +37,7 @@ from horizon.utils import html
LOG = logging.getLogger(__name__)
# For Bootstrap integration; can be overridden in settings.
ACTION_CSS_CLASSES = ("btn", "btn-default", "btn-sm")
ACTION_CSS_CLASSES = ("btn", "btn-default")
STRING_SEPARATOR = "__"

View File

@ -5,7 +5,7 @@
{% if needs_form_wrapper %}<form action="{{ table.get_full_url }}" method="POST">{% csrf_token %}{% endif %}
{% with columns=table.get_columns rows=table.get_rows %}
{% block table %}
<table id="{{ table.slugify_name }}" class="{% block table_css_classes %}table table-bordered table-striped datatable {{ table.css_classes }}{% endblock %}">
<table id="{{ table.slugify_name }}" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
<thead>
{% block table_caption %}
<tr class='table_caption'>
@ -28,7 +28,7 @@
{% endblock table_breadcrumb %}
{% block table_columns %}
{% if not table.is_browser_table %}
<tr>
<tr class="table_column_header">
{% for column in columns %}
<th {{ column.attr_string|safe }}>
{{ column }}

View File

@ -4,7 +4,7 @@
{% if filter.filter_type == 'fixed' %}
<div class="table_filter btn-group" data-toggle="buttons-radio">
{% for button in filter.fixed_buttons %}
<button name="{{ filter.get_param_name }}" type="submit" value="{{ button.value }}" class="btn btn-default btn-sm{% ifequal button.value filter.filter_string %} active{% endifequal %}">
<button name="{{ filter.get_param_name }}" type="submit" value="{{ button.value }}" class="btn btn-default{% ifequal button.value filter.filter_string %} active{% endifequal %}">
{% if button.icon %}
<span class="fa {{ button.icon }}"></span>
{% endif %}
@ -40,7 +40,7 @@
{% endfor %}
{% if table_actions_menu|length > 0 %}
<div class="btn-group table_actions_menu">
<a class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" href="#">
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">
{% if table_actions_buttons|length > 0 %}
{% trans "More Actions" %}
{% else %}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 B

View File

@ -0,0 +1,16 @@
.table_actions {
float: right;
@extend .form-inline;
}
.table_search,
.table_filter {
display: inline-block;
}
// Push the table filter padding over to compensate for that little magnifying glass icon
.table_search {
input[type="text"] {
padding-right: $input-height-base;
}
}

View File

@ -0,0 +1,131 @@
.table {
& > thead,
& > tbody,
& > tfoot {
> tr {
& > th,
& > td {
vertical-align: middle;
}
}
}
.multi_select_column {
text-align: center;
}
.empty {
text-align: center;
}
// Specificity Required!
& > tbody > tr > td {
&.loading {
background-color: $gray-lighter;
}
&.success {
background-color: lighten($brand-success, 35%);
}
}
tr.terminated {
color: $gray-light;
}
th.multi_select_column, td.multi_select_column {
width: $font-size-base * 3;
text-align: center;
}
.normal_column ul {
padding: 0;
}
}
// Sometimes the header is empty, lets keep the same look either way
.table_header {
min-height: $input-height-base;
// We put headings in the table for the title, so these headings shouldn't
// function like normal Type H3's ... remove the margin on top
h3 {
display: inline-block;
margin-top: 0;
}
}
// Sort Indicator
.tablesorter-header.sortable {
cursor: pointer;
}
.tablesorter-header-inner {
display: inline;
}
.tablesorter-headerAsc:after,
.tablesorter-headerDesc:after {
@include fa-icon();
font-size: $font-size-h4;
color: $gray-light;
float: right;
}
.tablesorter-headerAsc:after {
content: $fa-var-caret-up;
}
.tablesorter-headerDesc:after {
content: $fa-var-caret-down;
}
///*
// * Bootstrap styles table backgrounds using nth-child(2n+1), which is
// * oblivious to hidden elements. The styles below allow us to override
// * the bootstrap style when necessary by setting the odd/even classes.
// */
.table-striped.datatable tbody {
td {
background-clip: padding-box;
}
tr.odd {
td {
background-color: $table-bg-odd;
}
&.status_unknown td {
background-color: lighten($brand-warning, 6%);
}
}
tr.even {
td {
background-color: inherit;
}
&.status_unknown td {
background-color: lighten($brand-warning, 10%);
}
}
// Hover stuffs!
tr.odd:hover td,
tr.even:hover td,
tr:hover th {
background-color: $table-bg-hover;
}
tr.odd.status_unknown:hover td,
tr.even.status_unknown:hover td {
background-color: lighten($brand-warning, 6%);
}
}
// Force Table Fixed
.table-fixed {
table-layout: fixed;
}
// Don't wrap a column
.nowrap-col {
white-space: nowrap;
}

View File

@ -24,6 +24,8 @@
@import "components/context_selection";
@import "components/pie_charts";
@import "/framework/framework";
@import "components/tables";
@import "components/table_actions";
/* new clearfix */
@ -204,109 +206,6 @@ a.current_item:hover h4 {
padding: 0 0 0 1px;
}
.table_wrapper > form.wait,
.table_wrapper > form.wait * {
cursor: wait !important;
}
.table-bordered {
border: none;
}
.table_header {
min-height: 35px;
padding: 5px 0;
}
.table_caption th {
background-color: transparent;
border: none;
}
.table-bordered th.table_header { border: none; }
.table-bordered tr.table_caption + tr th {
border-top: 1px solid $table-border-color;
}
.table-bordered tr.table_caption + tr th:first-child,
.table-bordered tr.table_caption + tr th.hide + th {
border-top-left-radius: 4px;
border-left: 1px solid $table-border-color;
}
.table-bordered tr.table_caption + tr th:last-child {
border-top-right-radius: 4px;
border-right: 1px solid $table-border-color;
}
.table-bordered tbody tr td:first-child,
.table-bordered tfoot tr td:first-child {
border-left: 1px solid $table-border-color;
}
.table-bordered tbody tr td:last-child,
.table-bordered tfoot tr td:last-child {
border-right: 1px solid $table-border-color;
}
.table-bordered tfoot tr td:first-child {
border-bottom: 1px solid $table-border-color;
border-bottom-left-radius: 4px;
}
.table-bordered tfoot tr td:last-child {
border-bottom: 1px solid $table-border-color;
border-bottom-right-radius: 4px;
}
.table_title h3,
.table_header h3 {
font-weight: normal;
font-size: 24px;
margin: 0 0 5px 0;
float: left;
}
.table th.header {
cursor: pointer;
}
.table th.header:hover {
background-color: #e8e8e8;
text-decoration: underline;
}
.table tbody td.anchor a {
display: block;
}
.table tr.table_caption th.header:hover {
background-color: transparent;
cursor: default;
}
.table th.headerSortUp:hover,
.table th.headerSortDown:hover {
background-color: #dfdfdf;
}
.table th.headerSortUp,
.table th.headerSortDown {
background-color: #dfdfdf;
background-repeat: no-repeat;
background-position: 98% center;
}
.table th.headerSortDown {
background-image: url(../img/drop_arrow.png);
}
.table th.headerSortUp {
background-image: url(../img/up_arrow.png);
}
.table tr.summation td:first-child,
.table tr.summation td:last-child {
border-radius: 0;
border-bottom: 0 none;
}
.table li {
list-style-position: inside;
}
th {
background: #f1f1f1;
}
td.anchor {
padding: 0;
}
.main_nav {
list-style: none;
width: 222px;
@ -328,11 +227,6 @@ td.anchor {
border-bottom-color: #ccc;
}
table form {
margin-bottom: 0;
width: 1px;
}
.messages {
position: fixed;
z-index: 9999;
@ -378,172 +272,16 @@ table form {
width: 90px;
}
.table-striped tr td {
@include transition(background 0.2s);
}
.inspect {
float: left;
display: block;
margin-top: 5px;
margin-right: 25px;
}
.table {
margin-bottom: 25px;
> thead,
> tbody,
> tfoot {
> tr {
> th,
> td {
vertical-align: middle;
}
}
}
}
.table tr td {
vertical-align: middle;
}
.table tr.empty td {
text-align: center;
}
.table tfoot tr td {
border-top: 1px solid $table-border-color;
background-color: #f1f1f1;
font-size: 11px;
line-height: 14px;
}
.table_actions {
float: right;
min-width: 400px;
@extend .form-inline;
}
.table_actions .table_search,
.table_actions .table_filter {
display: inline-flex;
display: -ms-inline-flexbox;
-ms-flex-direction: row;
display: -webkit-inline-flex;
display: -moz-inline-flex;
}
.table_search {
input[type="text"] {
padding-right: 26px;
}
select {
width: auto;
}
}
.table_actions .table_actions_menu {
display: inline-block;
position: relative;
margin-left: 5px;
.dropdown-menu {
left: auto;
right: 0;
a, button {
margin-left: 0px;
padding-left: 22px;
.fa {
margin-left: -14px;
}
}
}
}
td.no-transition {
@include transition(none !important);
}
td.success {
background-color: #dff0d8 !important;
}
td.loading {
background-color: #e6e6e6 !important;
}
.table_header .table_actions {
display: inline-flex;
display: -ms-inline-flexbox;
-ms-flex-direction: row;
display: -webkit-inline-flex;
display: -moz-inline-flex;
min-width: 0;
}
.table_header .table_actions a,
.table_header .table_actions > button,
.table_header .table_actions .table_search button {
display: inline-block;
float: none;
max-height: 32px;
}
.table_header .table_actions .table_search select {
margin-bottom: 0;
line-height: 22px;
}
.table_header .table_filter {
vertical-align: bottom;
margin-right: 20px;
}
.table_header .table_filter i {
vertical-align: middle;
}
.table_actions form {
float: right;
margin-left: 10px;
}
.hidden {
display: none;
}
/*
* Bootstrap styles table backgrounds using nth-child(2n+1), which is
* oblivious to hidden elements. The styles below allow us to override
* the bootstrap style when necessary by setting the odd/even classes.
*/
.table-striped.datatable tbody {
td {
background-clip: padding-box;
}
tr.odd td {
background-color: $table-bg-odd;
}
tr.even td {
background-color: inherit;
}
tr.odd:hover td,
tr.even:hover td,
tr:hover th {
background-color: $table-bg-hover;
}
}
.table-striped tbody tr.status_unknown:nth-child(odd) td {
background-color: #ffffb5;
}
.table-striped tbody tr.status_unknown:nth-child(even) td {
background-color: #ffffc6;
}
.nowrap-col {
white-space: nowrap;
}
.overview {
font-size: 24px;
}
@ -570,27 +308,6 @@ td.loading {
#external_links li { margin: 0 0 0 15px; }
/* Formset data tables. */
.datatable {
th.narrow {
width: 1em;
}
th span.required:after {
content: "*";
font-weight: bold;
line-height: 0;
padding-left: 4px;
color: $brand-primary;
}
.normal_column ul {
padding-left: 0;
}
}
/* Forms */
.datepicker {
@ -746,15 +463,11 @@ form label {
.form-inline {
display: inline;
input, button, a.btn {
input, button, a.btn, .btn-group {
margin-left: 5px;
}
}
td.select {
width: 10px;
}
/* Actions dropdown */
.actions_column {
@ -763,6 +476,13 @@ td.select {
position: relative;
width: 1em;
background-clip: padding-box;
// We want the actions column to be a small button, but
// we can't get to the class attribute yet to customize
// that outside of every action, including table header
.btn {
@extend .btn-sm;
}
}
form.actions_column {
@ -770,6 +490,7 @@ form.actions_column {
font-family: $font-family-base;
}
// TODO(hurgleburgler): We need to fix this, we still support IE8+
.actions_column .btn-group {
display: inline-flex;
display: -ms-inline-flexbox;
@ -876,27 +597,11 @@ tr:hover .actions_column ul.row_actions.single,
color: $text-color;
}
th.multi_select_column, td.multi_select_column {
width: 41px;
text-align: center;
}
.table-fixed {
table-layout: fixed;
}
div.input input[type="checkbox"] {
float: left;
width: 25px;
}
.table_title a {
font-size: 11px;
float: right;
margin-left: 10px;
margin-top: 10px;
}
tr.terminated {
color: #999999;
}
@ -1838,24 +1543,6 @@ label.log-length {
}
}
/**** Sort Indicator ****/
.tablesorter thead tr th
{
&.tablesorter-header {
cursor: pointer;
background-repeat: no-repeat;
background-position: 99% center;
background-position: right 5px center;
}
&.tablesorter-headerAsc {
background-image: url(../img/up_arrow.png);
}
&.tablesorter-headerDesc {
background-image: url(../img/drop_arrow.png);
}
}
/* Read only text fields */
.form-control[readonly], .view-credentials input {

View File

@ -1,3 +1,4 @@
@import 'components/dropdowns';
@import 'components/navbar';
@import 'components/navs';
@import 'components/tables';

View File

@ -24,7 +24,7 @@ $gray-lighter: lighten(#000, 93.5%) !default; // #eee
$brand-primary: #428bca !default;
$brand-success: #5cb85c !default;
$brand-info: #5bc0de !default;
$brand-warning: #f0ad4e !default;
$brand-warning: #ffffb5 !default;
$brand-danger: #d9534f !default;
@ -54,20 +54,20 @@ $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace !def
$font-family-base: $font-family-sans-serif !default;
$font-size-base: 13px !default;
$font-size-large: ceil(($font-size-base * 1.25)) !default; // ~18px
$font-size-small: ceil(($font-size-base * 0.85)) !default; // ~12px
$font-size-large: ceil(($font-size-base * 1.25)) !default;
$font-size-small: ceil(($font-size-base * 0.85)) !default;
$font-size-h1: floor(($font-size-base * 2.6)) !default; // ~36px
$font-size-h2: floor(($font-size-base * 2.15)) !default; // ~30px
$font-size-h3: ceil(($font-size-base * 1.7)) !default; // ~24px
$font-size-h4: ceil(($font-size-base * 1.25)) !default; // ~18px
$font-size-h1: floor(($font-size-base * 2.6)) !default;
$font-size-h2: floor(($font-size-base * 2.15)) !default;
$font-size-h3: ceil(($font-size-base * 1.7)) !default;
$font-size-h4: ceil(($font-size-base * 1.25)) !default;
$font-size-h5: $font-size-base !default;
$font-size-h6: ceil(($font-size-base * 0.85)) !default; // ~12px
$font-size-h6: ceil(($font-size-base * 0.85)) !default;
//** Unit-less `line-height` for use in components like buttons.
$line-height-base: 1.428571429 !default; // 20/14
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
$line-height-computed: floor(($font-size-base * $line-height-base)) !default; // ~20px
$line-height-computed: floor(($font-size-base * $line-height-base)) !default;
//** By default, this inherits from the `<body>`.
$headings-font-family: inherit !default;

View File

@ -0,0 +1,25 @@
.table {
& > tbody tr,
& > tbody td,
& > tfoot {
border: 1px solid $table-border-color;
}
& > tfoot {
font-size: $font-size-small * .9;
}
& > thead,
& > tfoot {
background: $gray-lighter;
}
& > thead {
border-left: 1px solid $table-border-color;
border-right: 1px solid $table-border-color;
border-top: 1px solid $table-border-color;
th {
border-left: 1px solid $table-border-color;
}
}
}

View File

@ -2,6 +2,8 @@
@import 'components/_context_selection';
@import 'components/sidebar';
@import 'components/tables';
@import 'components/table_actions';
@import 'components/pie_charts';
.navbar-brand {

View File

@ -0,0 +1,3 @@
.table_actions .btn {
font-size: $font-size-small;
}

View File

@ -0,0 +1,46 @@
.table {
& > thead {
border-left: none;
border-right: none;
border-top: none;
// Specificity Override
& > tr > .table_header {
border-bottom: 1px solid $table-border-color;
}
}
tr td {
@include transition(background 0.2s);
// TODO: we can make this a mixin if we want it use it more often
&.no-transition {
@include transition(none);
}
}
.table_caption {
background-color: $body-bg;
th {
border-left: none;
}
}
}
.table_column_header {
border-right: 1px solid $table-border-color;
}
// Table sort indicator
.tablesorter-header {
position: relative;
}
.tablesorter-headerAsc:after,
.tablesorter-headerDesc:after {
position: absolute;
color: $gray-darker;
opacity: .25;
right: $padding-small-vertical;
}