mirror of https://github.com/hashicorp/consul
ui: Add docs for AppView (#10265)
* ui: change coloring of secondary navigation elements * Remove top border, this was probably from older designs/iterations * ui: Move app-view styles into components also... 1. Remove dead %app-view-content-error 2. Remove TabNav border overwriting * Bring into line with our 'project standard' class/attributes pattern * Add docs for AppViewpull/10248/head
parent
be9b45588b
commit
600f857531
|
@ -0,0 +1,112 @@
|
||||||
|
---
|
||||||
|
class: ember
|
||||||
|
state: needs-love
|
||||||
|
---
|
||||||
|
# AppView
|
||||||
|
|
||||||
|
`<AppView />` is our current top level wrapping component (one level in from
|
||||||
|
the app chrome), every 'top level main section/template' should have one of
|
||||||
|
these.
|
||||||
|
|
||||||
|
It contains legacy authorization code (that can probably be removed now), and
|
||||||
|
our flash messages (that should be moved to the `<App />` or `<HashicorpConsul
|
||||||
|
/>` component and potentially be renamed to `Page` or `View` or similar now
|
||||||
|
that we don't need two words.
|
||||||
|
|
||||||
|
Other than that it provides the basic layout/slots for our main title, search
|
||||||
|
bar, top right hand actions and main content.
|
||||||
|
|
||||||
|
The large top margin that is visible when no breadcrumbs are visible is there
|
||||||
|
to ensure that the page doesn't 'jump around' when you navigate to a page with
|
||||||
|
breadcrumbs and back again.
|
||||||
|
|
||||||
|
```hbs preview-template
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
<AppView>
|
||||||
|
|
||||||
|
<BlockSlot @name="header">
|
||||||
|
<h1>
|
||||||
|
Main title <em>{{format-number "100000"}} total {{pluralize 100000 "thing" without-count=true}} in this page</em>
|
||||||
|
</h1>
|
||||||
|
</BlockSlot>
|
||||||
|
<BlockSlot @name="content">
|
||||||
|
|
||||||
|
<EmptyState>
|
||||||
|
<BlockSlot @name="body">
|
||||||
|
<p>
|
||||||
|
Nothing to see here
|
||||||
|
</p>
|
||||||
|
</BlockSlot>
|
||||||
|
</EmptyState>
|
||||||
|
|
||||||
|
</BlockSlot>
|
||||||
|
</AppView>
|
||||||
|
|
||||||
|
<figcaption>Basic list-like view</figcaption>
|
||||||
|
</figure>
|
||||||
|
```
|
||||||
|
```hbs preview-template
|
||||||
|
<figure>
|
||||||
|
|
||||||
|
<AppView>
|
||||||
|
<BlockSlot @name="breadcrumbs">
|
||||||
|
<ol>
|
||||||
|
<li><a href="">Hansel</a></li>
|
||||||
|
<li><a href="">Gretel</a></li>
|
||||||
|
</ol>
|
||||||
|
</BlockSlot>
|
||||||
|
|
||||||
|
<BlockSlot @name="header">
|
||||||
|
<h1>
|
||||||
|
Scary witch's gingerbread house <em>(run away quick!)</em>
|
||||||
|
</h1>
|
||||||
|
</BlockSlot>
|
||||||
|
|
||||||
|
<BlockSlot @name="actions">
|
||||||
|
<Action
|
||||||
|
{{on "click" (noop)}}
|
||||||
|
>
|
||||||
|
Run away!
|
||||||
|
</Action>
|
||||||
|
</BlockSlot>
|
||||||
|
|
||||||
|
<BlockSlot @name="content">
|
||||||
|
<EmptyState>
|
||||||
|
<BlockSlot @name="body">
|
||||||
|
<p>
|
||||||
|
Double, double toil and trouble
|
||||||
|
</p>
|
||||||
|
</BlockSlot>
|
||||||
|
</EmptyState>
|
||||||
|
</BlockSlot>
|
||||||
|
</AppView>
|
||||||
|
|
||||||
|
<figcaption>Basic detail-like view</figcaption>
|
||||||
|
</figure>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arguments
|
||||||
|
|
||||||
|
| Argument | Type | Default | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `authorized` | `Boolean` | `true` | Whether the View is authorized or not |
|
||||||
|
| `enabled` | `Boolean` | `true` | Whether ACLs are enabled or not |
|
||||||
|
|
||||||
|
## Slots
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `header` | The main title of the page, you probably want to put a `<h1>` in here |
|
||||||
|
| `content` | The main content of the page, and potentially an `<Outlet />` somewhere |
|
||||||
|
| `notification` | Old style notifications, also see `<Notification />` |
|
||||||
|
| `breadcrumbs` | Any breadcrumbs, you probably want an `ol/li/a` in here |
|
||||||
|
| `actions` | Any actions relevant for the entire page, probably using `<Action />` |
|
||||||
|
| `nav` | Secondary navigation goes in here, also see `<TabNav />` |
|
||||||
|
| `toolbar` | Rendered underneath the header and actions for various 'toolbar' type things, such as our SearchBars |
|
||||||
|
|
||||||
|
## Portals
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `app-view-actions` | Provides a portal to render additional page actions from any views. This is rendered **before** the contents of the `actions` slot |
|
|
@ -1,4 +1,7 @@
|
||||||
<div class="app-view">
|
<div
|
||||||
|
class="app-view"
|
||||||
|
...attributes
|
||||||
|
>
|
||||||
{{yield}}
|
{{yield}}
|
||||||
<header>
|
<header>
|
||||||
{{#each flashMessages.queue as |flash|}}
|
{{#each flashMessages.queue as |flash|}}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
@import './skin';
|
||||||
|
@import './layout';
|
||||||
|
.app-view {
|
||||||
|
@extend %app-view;
|
||||||
|
}
|
||||||
|
|
||||||
|
%app-view > header {
|
||||||
|
@extend %app-view-header;
|
||||||
|
}
|
||||||
|
%app-view-header .title {
|
||||||
|
@extend %app-view-title;
|
||||||
|
}
|
||||||
|
%app-view-header .actions {
|
||||||
|
@extend %app-view-actions;
|
||||||
|
}
|
||||||
|
%app-view > div {
|
||||||
|
@extend %app-view-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
%app-view-actions a,
|
||||||
|
%app-view-actions button {
|
||||||
|
@extend %button-compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* toggleable toolbar for short screens */
|
||||||
|
[for='toolbar-toggle'] {
|
||||||
|
@extend %with-search-color-icon;
|
||||||
|
background-position: 0 4px;
|
||||||
|
display: inline-block;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $blue-500;
|
||||||
|
}
|
||||||
|
#toolbar-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media #{$--lt-spacious-page-header} {
|
||||||
|
%app-view-actions {
|
||||||
|
margin-top: 9px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reduced search magnifying icon layout
|
||||||
|
@media #{$--horizontal-selects} {
|
||||||
|
[for='toolbar-toggle'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media #{$--lt-horizontal-selects} {
|
||||||
|
%app-view-header h1 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
// on the instance detail page we don't have the magnifier
|
||||||
|
html[data-route$='dc.services.instance.show'] h1 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#toolbar-toggle + * {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#toolbar-toggle:checked + * {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
%app-view-actions {
|
%app-view-actions {
|
||||||
margin-left: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
/* units */
|
/* units */
|
||||||
%app-view-title {
|
%app-view-title {
|
||||||
|
@ -26,11 +26,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* content */
|
/* content */
|
||||||
%app-view-content-empty {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
padding: 50px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
/* TODO: Think about an %app-form or similar */
|
/* TODO: Think about an %app-form or similar */
|
||||||
%app-view-content form:not(.filter-bar) fieldset {
|
%app-view-content form:not(.filter-bar) fieldset {
|
||||||
padding-bottom: 0.3em;
|
padding-bottom: 0.3em;
|
|
@ -1,31 +1,22 @@
|
||||||
%app-view-content-empty {
|
%app-view-title > *:first-child {
|
||||||
@extend %frame-gray-500;
|
@extend %h100;
|
||||||
}
|
}
|
||||||
%app-view-title {
|
%app-view-title {
|
||||||
border-bottom: $decor-border-100;
|
border-bottom: $decor-border-100;
|
||||||
}
|
}
|
||||||
%app-view-title > *:first-child {
|
|
||||||
@extend %h100;
|
|
||||||
}
|
|
||||||
%app-view-content form:not(.filter-bar) fieldset {
|
%app-view-content form:not(.filter-bar) fieldset {
|
||||||
border-bottom: $decor-border-200;
|
border-bottom: $decor-border-200;
|
||||||
}
|
}
|
||||||
%app-view-header h1 > em {
|
%app-view-header h1 > em {
|
||||||
color: $gray-600;
|
color: var(--gray-600);
|
||||||
}
|
}
|
||||||
%app-view-header dd > a {
|
%app-view-header dd > a {
|
||||||
color: $black;
|
color: var(--gray-999);
|
||||||
}
|
}
|
||||||
%app-view-content div > dl > dd {
|
%app-view-content div > dl > dd {
|
||||||
color: $gray-400;
|
color: var(--gray-400);
|
||||||
}
|
}
|
||||||
%app-view-title,
|
%app-view-title,
|
||||||
%app-view-content form:not(.filter-bar) fieldset {
|
%app-view-content form:not(.filter-bar) fieldset {
|
||||||
border-color: $gray-200;
|
border-color: var(--gray-200);
|
||||||
}
|
|
||||||
// We know that any sibling navs might have a top border
|
|
||||||
// by default. As its squashed up to a %app-view-title, in this
|
|
||||||
// case hide its border to avoid double border
|
|
||||||
%app-view-title ~ nav {
|
|
||||||
border-top: 0 !important;
|
|
||||||
}
|
}
|
|
@ -35,7 +35,7 @@
|
||||||
@import './components/radio-card';
|
@import './components/radio-card';
|
||||||
@import './components/tabular-dl';
|
@import './components/tabular-dl';
|
||||||
|
|
||||||
@import './components/app-view';
|
@import 'consul-ui/components/app-view';
|
||||||
@import 'consul-ui/components/brand-loader';
|
@import 'consul-ui/components/brand-loader';
|
||||||
@import 'consul-ui/components/skip-links';
|
@import 'consul-ui/components/skip-links';
|
||||||
@import 'consul-ui/components/app';
|
@import 'consul-ui/components/app';
|
||||||
|
|
|
@ -1,50 +1 @@
|
||||||
@import './app-view/index';
|
@import './app-view/index';
|
||||||
|
|
||||||
.app-view {
|
|
||||||
@extend %app-view;
|
|
||||||
}
|
|
||||||
|
|
||||||
%app-view-actions a,
|
|
||||||
%app-view-actions button {
|
|
||||||
@extend %button-compact;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* toggleable toolbar for short screens */
|
|
||||||
[for='toolbar-toggle'] {
|
|
||||||
@extend %with-search-color-icon;
|
|
||||||
background-position: 0 4px;
|
|
||||||
display: inline-block;
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: $blue-500;
|
|
||||||
}
|
|
||||||
#toolbar-toggle {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
@media #{$--lt-spacious-page-header} {
|
|
||||||
%app-view-actions {
|
|
||||||
margin-top: 9px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// reduced search magnifying icon layout
|
|
||||||
@media #{$--horizontal-selects} {
|
|
||||||
[for='toolbar-toggle'] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media #{$--lt-horizontal-selects} {
|
|
||||||
%app-view-header h1 {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
// on the instance detail page we don't have the magnifier
|
|
||||||
html[data-route$='dc.services.instance.show'] h1 {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
#toolbar-toggle + * {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#toolbar-toggle:checked + * {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
@import './skin';
|
|
||||||
@import './layout';
|
|
||||||
%app-view > header {
|
|
||||||
@extend %app-view-header;
|
|
||||||
}
|
|
||||||
%app-view-header .title {
|
|
||||||
@extend %app-view-title;
|
|
||||||
}
|
|
||||||
%app-view-header .actions {
|
|
||||||
@extend %app-view-actions;
|
|
||||||
}
|
|
||||||
%app-view > div {
|
|
||||||
@extend %app-view-content;
|
|
||||||
}
|
|
|
@ -9,16 +9,14 @@ html.is-debug body > .brand-loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
.docs {
|
.docs {
|
||||||
[role='banner'] nav:first-of-type {
|
|
||||||
height: calc(100vh - var(--chrome-height, 47px));
|
|
||||||
}
|
|
||||||
.tabular-collection,
|
.tabular-collection,
|
||||||
.list-collection {
|
.list-collection {
|
||||||
height: 300px !important;
|
height: 300px !important;
|
||||||
}
|
}
|
||||||
nav:first-of-type {
|
[role='banner'] nav:first-of-type {
|
||||||
& {
|
& {
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
|
height: calc(100vh - var(--chrome-height, 47px));
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
margin-bottom: 100px;
|
margin-bottom: 100px;
|
||||||
|
@ -48,10 +46,43 @@ html.is-debug body > .brand-loader {
|
||||||
> ul {
|
> ul {
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
}
|
}
|
||||||
|
> h1,
|
||||||
|
> h2,
|
||||||
|
> h3 {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
> h1 {
|
||||||
|
padding-top: 20px;
|
||||||
|
@extend %h100;
|
||||||
|
}
|
||||||
|
> h2 {
|
||||||
|
@extend %h200;
|
||||||
|
}
|
||||||
|
> h3 {
|
||||||
|
@extend %h300;
|
||||||
|
}
|
||||||
|
> p {
|
||||||
|
@extend %p1;
|
||||||
|
}
|
||||||
|
> table {
|
||||||
|
margin-bottom: 3em;
|
||||||
|
}
|
||||||
|
> table td {
|
||||||
|
font-weight: normal !important;
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
> table td code {
|
||||||
|
@extend %inline-code;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
> table tr:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.docfy-demo {
|
.docfy-demo {
|
||||||
& {
|
& {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
&__example {
|
&__example {
|
||||||
& {
|
& {
|
||||||
|
@ -98,32 +129,4 @@ html.is-debug body > .brand-loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
padding-top: 20px;
|
|
||||||
@extend %h100;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
@extend %h200;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
@extend %h300;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
@extend %p1;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
margin-bottom: 3em;
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
font-weight: normal !important;
|
|
||||||
cursor: default !important;
|
|
||||||
}
|
|
||||||
tr:hover {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue