Merge pull request #81 from dod-ccpo/ui/global-navigation-frame

Ui/global navigation frame
This commit is contained in:
andrewdds 2018-07-20 11:35:28 -04:00 committed by GitHub
commit e7f1762fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 285 additions and 197 deletions

View File

@ -16,6 +16,7 @@ from atst.home import home
from atst.api_client import ApiClient
from atst.sessions import RedisSessions
from atst import ui_modules
from atst import ui_methods
ENV = os.getenv("TORNADO_ENV", "dev")
@ -101,6 +102,7 @@ def make_app(config, deps, **kwargs):
cookie_secret=config["default"]["COOKIE_SECRET"],
debug=config["default"].getboolean("DEBUG"),
ui_modules=ui_modules,
ui_methods=ui_methods,
**kwargs,
)
app.config = config

2
atst/ui_methods.py Normal file
View File

@ -0,0 +1,2 @@
def matchesPath(self, href):
return self.request.uri.startswith(href)

View File

@ -5,3 +5,12 @@ class Icon(UIModule):
with open('static/icons/%s.svg' % name) as svg:
return self.render_string(
"components/icon.html.to", svg=svg.read(), name=name, classes=classes)
class SidenavItem(UIModule):
def render(self, label, href, active=False, icon=None):
return self.render_string(
"navigation/_sidenav_item.html.to",
label=label,
href=href,
active=active,
icon=icon)

View File

@ -1,7 +1,6 @@
@import 'core/variables';
@import '../node_modules/uswds/src/stylesheets/uswds';
@import 'core/base';
@import 'core/grid';
@import 'core/util';
@ -12,12 +11,13 @@
@import 'elements/block_lists';
@import 'elements/tables';
@import 'elements/icons';
@import 'elements/sidenav';
@import 'components/layout';
@import 'components/topbar';
@import 'components/global_navigation';
@import 'components/site_action';
@import 'components/empty_state';
@import 'sections/main';
@import 'sections/topbar';
@import 'sections/sidenav';
@import 'sections/footer';
@import 'sections/login';

View File

@ -0,0 +1,30 @@
.global-navigation {
background-color: $color-white;
.sidenav__link {
padding-right: $gap;
@include media($medium-screen) {
padding-right: $gap * 2;
}
}
.sidenav__link-label {
@include hide;
@include media($medium-screen) {
@include unhide;
padding-left: $gap;
}
}
&.global-navigation__context--workspace {
.sidenav__link {
padding-right: $gap;
}
.sidenav__link-label {
@include hide;
}
}
}

View File

@ -0,0 +1,31 @@
body {
background-color: $color-gray-lightest;
display: flex;
flex-direction: column;
justify-content: flex-start;
min-height: 100vh;
> footer {
margin-top: auto;
}
}
.global-layout {
display: flex;
flex-wrap: nowrap;
flex-grow: 1;
.global-navigation {
margin-top: -1px;
}
.global-panel-container {
margin: $gap;
max-width: $site-max-width;
overflow: auto;
@include media($medium-screen) {
margin: $gap * 2;
}
}
}

View File

@ -0,0 +1,71 @@
.topbar {
background-color: $color-white;
border-bottom: 1px solid $color-black;
.topbar__navigation {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
.topbar__link {
color: $color-black;
display: inline-flex;
align-items: center;
height: $topbar-height;
padding: 0 ($gap * 2);
text-decoration: none;
.topbar__link-label {
@include h5;
}
.topbar__link-icon {
margin-left: $gap;
}
&.topbar__link--shield {
width: $icon-bar-width;
justify-content: center;
padding: 0;
.topbar__link-icon {
margin: 0;
}
}
&:hover {
background-color: $color-primary-darker;
color: $color-white;
.topbar__link-icon {
@include icon-style-inverted;
}
}
}
.topbar__context {
display: flex;
flex-grow: 1;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
&.topbar__context--workspace {
background-color: $color-primary;
.topbar__link {
color: $color-white;
.topbar__link-icon {
@include icon-style-inverted;
}
&:hover {
background-color: $color-primary-darker;
}
}
}
}
}
}

View File

@ -1,16 +0,0 @@
/*
* Base Styles
* @source https://github.com/uswds/uswds/blob/develop/src/stylesheets/core/_base.scss
*/
body {
background-color: $color-gray-lightest;
display: flex;
flex-direction: column;
justify-content: flex-start;
min-height: 100vh;
> footer {
margin-top: auto;
}
}

View File

@ -9,12 +9,9 @@
// We are implementing a simple flexbox row/column system
@mixin grid-row {
@include media($medium-screen) {
display: flex;
flex-direction: row;
flex-wrap: wrap;
max-width: $site-max-width;
}
flex-wrap: nowrap;
}
@mixin grid-pad {

View File

@ -1,3 +1,25 @@
.nowrap {
white-space: nowrap;
}
@mixin hide {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
@mixin unhide {
border: unset;
clip: unset;
height: unset;
margin: unset;
overflow: unset;
padding: unset;
position: unset;
width: unset;
}

View File

@ -3,9 +3,11 @@
* ===================================================
*/
$gap: .8rem; // 8px at 10px $em-base
$gap: 0.8rem; // 8px at 10px $em-base
$topbar-height: 4.8rem;
$icon-bar-width: 4.0rem;
$icon-size-small: 2.4rem;
$hover-transition-time: 0.2s;
/*
* USWDS Variables

View File

@ -1,17 +1,19 @@
@mixin icon {
display: inline-block;
vertical-align: bottom;
display: inline-flex;
> svg {
width: 100%;
height: 100%;
* {
transition: fill $hover-transition-time;
}
}
}
@mixin icon-size($size) {
$icon-size: $size * .1rem;
width: $icon-size;
height: $icon-size;
height: auto;
margin: $icon-size / 4;
}
@ -21,8 +23,24 @@
}
}
@mixin icon-style-active {
> svg * {
fill: $color-primary;
}
}
@mixin icon-style-inverted {
> svg * {
fill: $color-white;
}
}
.icon {
@include icon;
@include icon-size(16);
@include icon-style-default;
&.icon--tiny {
@include icon-size(10);
}
}

View File

@ -44,36 +44,3 @@
}
}
}
/*
* Panel Container
* Grid container for panel blocks
*/
.panel-container {
@include grid-row;
@include grid-pad;
@include margin(($site-margins-mobile * 2) null);
@include media($medium-screen) {
@include margin(($site-margins * 2) null);
}
@include media($large-screen) {
flex-wrap: nowrap;
}
> .col {
@include grid-pad;
}
h1 {
margin-bottom: 0;
}
h2 {
color: $color-gray;
}
}

View File

@ -1,15 +1,13 @@
.sidenav {
@include grid-pad;
@include panel-margin;
width: 100%;
flex-shrink: 0;
ul {
list-style: none;
margin: 0;
padding: 0;
@include media($large-screen) {
width: 21rem;
li {
margin: 0;
display: block;
}
@include media($xlarge-screen) {
width: 30rem;
}
.sidenav__link {
@ -18,10 +16,10 @@
padding: $gap ($gap * 2);
color: $color-black;
text-decoration: none;
white-space: nowrap;
&:hover {
background-color: $color-white;
color: $color-primary;
.sidenav__link-icon {
margin-left: - ($gap * .5);
}
&.sidenav__link--disabled {
@ -35,60 +33,42 @@
color: $color-primary;
box-shadow: inset .4rem 0 0 0 $color-primary;
.sidenav__link-icon {
@include icon-style-active;
}
+ ul {
background-color: $color-white;
.sidenav__link {
&--active {
@include h5;
box-shadow: none;
color: $color-primary;
}
}
}
}
+ ul {
padding-bottom: $gap / 2;
li {
.sidenav__link {
@include h5;
padding: ($gap * .75) ($gap * 3);
border: 0;
@include h5;
font-weight: normal;
}
&:last-child {
.sidenav__link {
padding-bottom: $gap * 1.5;
}
}
}
}
}
ul {
list-style: none;
margin: 0;
padding: 0;
li {
margin: 0;
display: block;
}
}
> ul {
@include panel-margin;
&:hover {
color: $color-primary;
&:last-child {
margin: 0;
.sidenav__link-icon {
@include icon-style-active;
}
> li {
&:last-child {
> .sidenav__link {
border-bottom: 1px solid $color-black;
}
}
}
}
}

View File

@ -4,6 +4,11 @@
* @source https://github.com/uswds/uswds/blob/develop/src/stylesheets/elements/_typography.scss
*/
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
font-family: $font-sans;
@ -25,12 +30,12 @@ h2 {
a,
a > span {
a:hover {
transition:
background 0.2s,
border 0.2s,
box-shadow 0.2s,
color 0.2s,
background $hover-transition-time,
border $hover-transition-time,
box-shadow $hover-transition-time,
color $hover-transition-time,
}
dt {

View File

@ -1,3 +0,0 @@
section {
margin-bottom: 10rem;
}

View File

@ -1,54 +0,0 @@
.topbar {
background-color: $color-white;
height: $topbar-height;
border-bottom: 1px solid $color-black;
.topbar__navigation {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: flex-end;
> .topbar__link {
@include h5;
color: $color-primary;
display: inline-block;
height: $topbar-height;
line-height: $topbar-height;
padding: 0 ($gap * 2);
text-decoration: none;
> span {
display: inline-block;
height: $topbar-height;
line-height: $topbar-height;
}
&.topbar__link--primary {
margin-right: auto;
> span {
@include nav-border;
}
&:hover {
color: $color-white;
background-color: $color-primary-darkest;
}
}
&.topbar__link--secondary {
font-weight: normal;
> span {
@include nav-border;
border-bottom-width: 0;
}
&:hover {
> span {
@include nav-border;
}
}
}
}
}
}

View File

@ -1,3 +1,7 @@
{# TODO: set this context elsewhere #}
{# set context='workspace' #}
{% set context='global' %}
<!DOCTYPE html>
<html>
<head>
@ -10,18 +14,19 @@
<link rel="icon" type="image/x-icon" href="/static/img/favicon.ico">
</head>
<body>
{% include 'navigation/topbar.html.to' %}
{% include 'header.html.to' %}
<div class='global-layout'>
{% include 'navigation/global_navigation.html.to' %}
<div class='panel-container'>
<div class='global-panel-container'>
{% block sidenav %}{% end %}
{% block content %}
these are not the droids you are looking for
{% end %}
</div>
</div>
{% include 'footer.html.to' %}
</body>

View File

@ -1,9 +1,5 @@
{% extends "base.html.to" %}
{% block sidenav %}
{% include 'nav-side.html.to' %}
{% end %}
{% block content %}
<main class="usa-section usa-content">

View File

@ -0,0 +1,9 @@
<li>
<a class="sidenav__link {% if active %}sidenav__link--active{% end %}" href="{{href}}" title="{{label}}">
{% if icon %}
{% module Icon(icon, classes="sidenav__link-icon") %}
{% end %}
<span class="sidenav__link-label">{{label}}</span>
</a>
</li>

View File

@ -0,0 +1,6 @@
<div class="global-navigation sidenav global-navigation__context--{{context}}">
<ul>
{% module SidenavItem("Requests", href="/requests", icon="document", active=matchesPath('/requests')) %}
{% module SidenavItem("Workspaces", href="/workspaces", icon="cloud", active=matchesPath('/workspaces')) %}
</ul>
</div>

View File

@ -0,0 +1,19 @@
<header class="topbar">
<nav class="topbar__navigation">
<a href="/home" class="topbar__link topbar__link--shield" title="JEDI Home">
{% module Icon('shield', classes='topbar__link-icon') %}
</a>
<div class="topbar__context topbar__context--{{context}}">
<a href="/" class="topbar__link">
<span class="topbar__link-label">JEDI</span>
{% module Icon('caret_down', classes='topbar__link-icon icon--tiny') %}
</a>
<a href="/" class="topbar__link">
<span class="topbar__link-label">Sam Seeceepio</span>
{% module Icon('avatar', classes='topbar__link-icon') %}
</a>
</div>
</nav>
</header>

View File

@ -1,9 +1,5 @@
{% extends "base.html.to" %}
{% block sidenav %}
{% include 'nav-side.html.to' %}
{% end %}
{% block content %}

View File

@ -1,12 +1,8 @@
{% extends "base.html.to" %}
{% block content %}
<main class="usa-section usa-content usa-width-one-whole">
<h1>Workspaces</h1>
<table class="usa-table-borderless" width="100%">
<div class='col'>
<table>
<thead>
<tr>
<th scope="col" width="50%">Workspace Name</th>
@ -29,8 +25,6 @@
{% end %}
</tbody>
</table>
</main>
</div>
{% end %}