Merge pull request #34 from hashicorp/ICU-189-main-header
New main content header component
This commit is contained in:
61 files changed
+622
-194
No files matched your search
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../templates/components/rose/layout/global';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { text, boolean, select } from '@storybook/addon-knobs';
|
||||
|
||||
<Meta title="Rose|Layout|Global" component="Global" />
|
||||
|
||||
# Layout|Global
|
||||
|
||||
A top-level layout/positioning component that allows three distinct sections to be configured: header, navigation, and body.
|
||||
|
||||
```htmlbars
|
||||
<Rose::Layout::Global as |global|>
|
||||
<global.header />
|
||||
<global.body />
|
||||
<global.navigation />
|
||||
</Rose::Layout::Global>
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Global">{{
|
||||
template: hbs`
|
||||
<Rose::Layout::Global as |global|>
|
||||
<global.header style="background: var(--brand-gray-5);">Header</global.header>
|
||||
<global.body style="background: var(--brand-gray-7);">Body</global.body>
|
||||
<global.navigation style="background: var(--brand-gray-6);">Navigation</global.navigation>
|
||||
</Rose::Layout::Global>
|
||||
`,
|
||||
}}</Story>
|
||||
</Preview>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/page/sidebar';
|
||||
import layout from '../../../../templates/components/rose/layout/global/body';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/global/header';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/global/navigation';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -1,30 +1,32 @@
|
||||
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { text, boolean, select } from '@storybook/addon-knobs';
|
||||
|
||||
<Meta title="Rose|Layout|Page" component="Page" />
|
||||
|
||||
# Layout|Page
|
||||
|
||||
A page layout/positioning component that allows three distinct sections to be configured: header, sidebar, and main.
|
||||
Sidebar's content width determines it's column width.
|
||||
A page layout/positioning component that allows five distinct sections to be configured: breadcrumbs, header, actions, navigation, and body.
|
||||
|
||||
```htmlbars
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.breadcrumbs />
|
||||
<page.header />
|
||||
<page.sidebar />
|
||||
<page.main />
|
||||
<page.actions />
|
||||
<page.navigation />
|
||||
<page.body />
|
||||
</Rose::Layout::Page>
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Basic">{{
|
||||
<Story name="Page">{{
|
||||
template: hbs`
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.breadcrumbs style="background: var(--brand-gray-4);">Breadcrumbs</page.breadcrumbs>
|
||||
<page.header style="background: var(--brand-gray-5);">Header</page.header>
|
||||
<page.main style="background: var(--brand-gray-7);">Main</page.main>
|
||||
<page.sidebar style="background: var(--brand-gray-6);">Sidebar</page.sidebar>
|
||||
<page.actions style="background: var(--brand-gray-8);">Actions</page.actions>
|
||||
<page.navigation style="background: var(--brand-gray-6);">Navigation</page.navigation>
|
||||
<page.body style="background: var(--brand-gray-7);">Body</page.body>
|
||||
</Rose::Layout::Page>
|
||||
`,
|
||||
}}</Story>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/page/actions';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/page/main';
|
||||
import layout from '../../../../templates/components/rose/layout/page/body';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/page/breadcrumbs';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../../../templates/components/rose/layout/page/navigation';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -4,4 +4,5 @@
|
||||
@import 'layout';
|
||||
@import 'notification';
|
||||
@import 'card';
|
||||
@import 'page-header';
|
||||
@import 'nav';
|
||||
@@ -1,22 +1,32 @@
|
||||
@use 'sass:map';
|
||||
@use '../../variables/sizing';
|
||||
@use '../../utilities/type';
|
||||
@use '../../utilities/dropdown';
|
||||
|
||||
$dropdown-chevron: (
|
||||
'default':
|
||||
"data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%23ebeef2' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'></path></svg>",
|
||||
@include dropdown.dropdown-style(
|
||||
'light',
|
||||
(
|
||||
color: var(--white),
|
||||
chevron: 'light',
|
||||
)
|
||||
);
|
||||
|
||||
@include dropdown.dropdown-style(
|
||||
'dark',
|
||||
(
|
||||
color: var(--black),
|
||||
chevron: 'dark',
|
||||
)
|
||||
);
|
||||
|
||||
.rose-header-dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.rose-header-dropdown-trigger {
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--white);
|
||||
background: url(map.get($dropdown-chevron, default)) no-repeat right center;
|
||||
background-size: sizing.rems(m);
|
||||
margin-right: sizing.rems(s);
|
||||
padding-right: sizing.rems(l) - sizing.rems(xxs);
|
||||
@@ -68,6 +78,7 @@ $dropdown-chevron: (
|
||||
background: var(--subtle);
|
||||
box-shadow: 0 $xxs $xxs rgba(var(--stark-components), var(--opacity-3)),
|
||||
0 $xxs $xs rgba(var(--stark-components), var(--opacity-4));
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
&.dropdown-right {
|
||||
|
||||
@@ -1,38 +1,2 @@
|
||||
@use '../../variables/sizing';
|
||||
@use '../../variables/media';
|
||||
|
||||
.rose-layout-page {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'header header header header'
|
||||
'sidebar main main main';
|
||||
// Define static grid column for sidebar
|
||||
grid-template-columns: 16rem auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.rose-layout-header {
|
||||
grid-area: header;
|
||||
}
|
||||
|
||||
.rose-layout-main {
|
||||
grid-area: main;
|
||||
}
|
||||
|
||||
.rose-layout-sidebar {
|
||||
grid-area: sidebar;
|
||||
border-right: sizing.rems(xxxxs) solid var(--ui-border-subtler-1);
|
||||
}
|
||||
|
||||
@media (max-width: media.width(small)) {
|
||||
.rose-layout-page {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 0.1fr auto 1fr;
|
||||
grid-template-areas:
|
||||
'header'
|
||||
'sidebar'
|
||||
'main';
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
@import 'global';
|
||||
@import 'page';
|
||||
@@ -0,0 +1,48 @@
|
||||
@use '../../variables/sizing';
|
||||
@use '../../variables/media';
|
||||
|
||||
.rose-layout-page {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'breadcrumbs breadcrumbs breadcrumbs'
|
||||
'header header actions'
|
||||
'navigation navigation navigation'
|
||||
'body body body';
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
.rose-layout-page-breadcrumbs {
|
||||
grid-area: breadcrumbs;
|
||||
}
|
||||
|
||||
.rose-layout-page-header {
|
||||
grid-area: header;
|
||||
}
|
||||
|
||||
.rose-layout-page-actions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.rose-layout-page-navigation {
|
||||
grid-area: navigation;
|
||||
}
|
||||
|
||||
.rose-layout-page-body {
|
||||
grid-area: body;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: media.width(small)) {
|
||||
.rose-layout-page {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
'breadcrumbs'
|
||||
'header'
|
||||
'actions'
|
||||
'navigation'
|
||||
'body';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.rose-layout-global-body {
|
||||
grid-area: body;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.rose-layout-global-header {
|
||||
grid-area: header;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
@use '../../../variables/sizing';
|
||||
@use '../../../variables/media';
|
||||
|
||||
@import 'header';
|
||||
@import 'body';
|
||||
@import 'navigation';
|
||||
|
||||
.rose-layout-global {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'header header header header'
|
||||
'navigation body body body';
|
||||
// Define 16rem static grid column for navigation
|
||||
grid-template-columns: (sizing.rems(m) * 16) auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
@media (max-width: media.width(small)) {
|
||||
.rose-layout-global {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 0.1fr auto 1fr;
|
||||
grid-template-areas:
|
||||
'header'
|
||||
'navigation'
|
||||
'body';
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@use '../../../variables/sizing';
|
||||
|
||||
.rose-layout-global-navigation {
|
||||
grid-area: navigation;
|
||||
border-right: sizing.rems(xxxxs) solid var(--ui-border-subtler-1);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@import 'title';
|
||||
@import 'utilities';
|
||||
@@ -0,0 +1,35 @@
|
||||
@use '../../variables/sizing';
|
||||
@use '../../utilities/type' as typography;
|
||||
|
||||
.rose-page-header-title {
|
||||
display: inline-block;
|
||||
grid-area: title;
|
||||
|
||||
.rose-page-header-title-text {
|
||||
display: inline-block;
|
||||
color: var(--stark);
|
||||
}
|
||||
|
||||
.rose-page-header-title-icon {
|
||||
vertical-align: sub;
|
||||
|
||||
svg {
|
||||
width: sizing.rems(l);
|
||||
width: sizing.rems(l);
|
||||
}
|
||||
}
|
||||
|
||||
.rose-header-dropdown {
|
||||
.rose-header-dropdown-trigger-text {
|
||||
@include typography.type(h1, bold);
|
||||
margin-top: sizing.rems(xs);
|
||||
margin-bottom: sizing.rems(xs);
|
||||
|
||||
margin-right: sizing.rems(xs);
|
||||
}
|
||||
|
||||
.rose-header-dropdown-trigger {
|
||||
background-size: sizing.rems(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
.rose-page-header-utilities {
|
||||
grid-area: utilities;
|
||||
|
||||
// Remove margin to align action buttons with h1 text
|
||||
button {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
@use 'sass:map';
|
||||
|
||||
$dropdown-chevron: (
|
||||
'light':
|
||||
"data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%23ebeef2' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'></path></svg>",
|
||||
'dark':
|
||||
"data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231b1f26' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'></path></svg>",
|
||||
);
|
||||
|
||||
@mixin dropdown-style($name, $default) {
|
||||
.rose-header-dropdown-#{$name} {
|
||||
.rose-header-dropdown-trigger {
|
||||
color: map.get($default, color);
|
||||
background: url(map.get($dropdown-chevron, map.get($default, chevron)))
|
||||
no-repeat right center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<details
|
||||
...attributes
|
||||
class="rose-header-dropdown{{if @alignRight " dropdown-right"}}"
|
||||
class="rose-header-dropdown{{if @alignRight " dropdown-right"}} {{if @style (concat "rose-header-dropdown-" @style) "rose-header-dropdown-light"}}"
|
||||
{{on-click-outside this.close}}
|
||||
>
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<div ...attributes class="rose-layout-global">
|
||||
{{yield (hash
|
||||
header=(component 'rose/layout/global/header')
|
||||
body=(component 'rose/layout/global/body')
|
||||
navigation=(component 'rose/layout/global/navigation')
|
||||
)}}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<main ...attributes class="rose-layout-global-body">
|
||||
{{yield}}
|
||||
</main>
|
||||
@@ -0,0 +1,3 @@
|
||||
<header ...attributes class="rose-layout-global-header" >
|
||||
{{yield}}
|
||||
</header>
|
||||
@@ -0,0 +1,3 @@
|
||||
<aside ...attributes class="rose-layout-global-navigation">
|
||||
{{yield}}
|
||||
</aside>
|
||||
@@ -1,7 +1,9 @@
|
||||
<div ...attributes class="rose-layout-page">
|
||||
{{yield (hash
|
||||
breadcrumbs=(component 'rose/layout/page/breadcrumbs')
|
||||
header=(component 'rose/layout/page/header')
|
||||
main=(component 'rose/layout/page/main')
|
||||
sidebar=(component 'rose/layout/page/sidebar')
|
||||
actions=(component 'rose/layout/page/actions')
|
||||
navigation=(component 'rose/layout/page/navigation')
|
||||
body=(component 'rose/layout/page/body')
|
||||
)}}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div ...attributes class="rose-layout-page-actions">
|
||||
{{yield}}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div ...attributes class="rose-layout-page-body">
|
||||
{{yield}}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div ...attributes class="rose-layout-page-breadcrumbs">
|
||||
{{yield}}
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<header ...attributes class="rose-layout-header" >
|
||||
<div ...attributes class="rose-layout-page-header">
|
||||
{{yield}}
|
||||
</header>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<main ...attributes class="rose-layout-main">
|
||||
{{yield}}
|
||||
</main>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div ...attributes class="rose-layout-page-navigation">
|
||||
{{yield}}
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<aside ...attributes class="rose-layout-sidebar">
|
||||
{{yield}}
|
||||
</aside>
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/global';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/global/body';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/global/header';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/global/navigation';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/page/actions';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/page/body';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/page/breadcrumbs';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'rose/components/rose/layout/page/main';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/page/navigation';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'rose/components/rose/layout/page/sidebar';
|
||||
@@ -1,5 +1,5 @@
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.header>
|
||||
<Rose::Layout::Global as |global|>
|
||||
<global.header>
|
||||
<Rose::Header as |header|>
|
||||
|
||||
<header.brand @logo="logo" @text="Product Name" />
|
||||
@@ -28,18 +28,25 @@
|
||||
</header.utilities>
|
||||
|
||||
</Rose::Header>
|
||||
</page.header>
|
||||
</global.header>
|
||||
|
||||
<page.sidebar>
|
||||
<global.navigation>
|
||||
<Rose::Nav::Sidebar @title="Title" as |nav|>
|
||||
<nav.link @route="index">Item Name</nav.link>
|
||||
<nav.link @route="about">Item Name</nav.link>
|
||||
<nav.link @route="about">Item Name</nav.link>
|
||||
<nav.link @route="about">Item Name</nav.link>
|
||||
</Rose::Nav::Sidebar>
|
||||
</page.sidebar>
|
||||
</global.navigation>
|
||||
|
||||
<page.main>
|
||||
<global.body>
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.breadcrumbs>Breadcrumbs</page.breadcrumbs>
|
||||
<page.header>Header</page.header>
|
||||
<page.navigation>Navigation</page.navigation>
|
||||
<page.actions>Actions</page.actions>
|
||||
<page.body>Body</page.body>
|
||||
</Rose::Layout::Page>
|
||||
|
||||
Dummy app index template
|
||||
|
||||
@@ -198,5 +205,5 @@
|
||||
<Rose::Card::Link @title="I'm a card" />
|
||||
<Rose::Card::Link @title="I'm a card" @description="I'm a description" />
|
||||
<Rose::Card::Link @title="I'm a card" @description="I'm a description" @subtitle="I'm a subtitle"/>
|
||||
</page.main>
|
||||
</Rose::Layout::Page>
|
||||
</global.body>
|
||||
</Rose::Layout::Global>
|
||||
@@ -0,0 +1,47 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/global', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global />`);
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-global'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global id="global"/>`);
|
||||
assert.ok(find('#global'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global as |global|>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Global>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
|
||||
test('it renders with header', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global as |global|>
|
||||
<global.header />
|
||||
</Rose::Layout::Global>`);
|
||||
assert.ok(find('.rose-layout-global-header'));
|
||||
});
|
||||
|
||||
test('it renders with main', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global as |global|>
|
||||
<global.body />
|
||||
</Rose::Layout::Global>`);
|
||||
assert.ok(find('.rose-layout-global-body'));
|
||||
});
|
||||
|
||||
test('it renders with sidebar', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global as |global|>
|
||||
<global.navigation />
|
||||
</Rose::Layout::Global>`);
|
||||
assert.ok(find('.rose-layout-global-navigation'));
|
||||
});
|
||||
});
|
||||
+6
-6
@@ -3,24 +3,24 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/page/main', function (hooks) {
|
||||
module('Integration | Component | rose/layout/global/body', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Main />`);
|
||||
await render(hbs`<Rose::Layout::Global::Body />`);
|
||||
assert.ok(find('main'));
|
||||
assert.ok(find('.rose-layout-main'));
|
||||
assert.ok(find('.rose-layout-global-body'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Main id="main"/>`);
|
||||
await render(hbs`<Rose::Layout::Global::Body id="main"/>`);
|
||||
assert.ok(find('#main'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Main>
|
||||
await render(hbs`<Rose::Layout::Global::Body>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page::Main>`);
|
||||
</Rose::Layout::Global::Body>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/global/header', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Header />`);
|
||||
assert.ok(find('header'));
|
||||
assert.ok(find('.rose-layout-global-header'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Header id="header"/>`);
|
||||
assert.ok(find('#header'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Header>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Global::Header>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/global/navigation', function (
|
||||
hooks
|
||||
) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Navigation />`);
|
||||
assert.ok(find('aside'));
|
||||
assert.ok(find('.rose-layout-global-navigation'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Navigation id="navigation"/>`);
|
||||
assert.ok(find('#navigation'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Global::Navigation>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Global::Navigation>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -18,30 +18,9 @@ module('Integration | Component | rose/layout/page', function (hooks) {
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page as |page|>
|
||||
await render(hbs`<Rose::Layout::Page>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
|
||||
test('it renders with header', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page as |page|>
|
||||
<page.header />
|
||||
</Rose::Layout::Page>`);
|
||||
assert.ok(find('.rose-layout-header'));
|
||||
});
|
||||
|
||||
test('it renders with main', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page as |page|>
|
||||
<page.main />
|
||||
</Rose::Layout::Page>`);
|
||||
assert.ok(find('.rose-layout-main'));
|
||||
});
|
||||
|
||||
test('it renders with sidebar', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page as |page|>
|
||||
<page.sidebar />
|
||||
</Rose::Layout::Page>`);
|
||||
assert.ok(find('.rose-layout-sidebar'));
|
||||
});
|
||||
});
|
||||
+8
-8
@@ -3,24 +3,24 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/page/sidebar', function (hooks) {
|
||||
module('Integration | Component | rose/layout/page/actions', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Sidebar />`);
|
||||
assert.ok(find('aside'));
|
||||
assert.ok(find('.rose-layout-sidebar'));
|
||||
await render(hbs`<Rose::Layout::Page::Actions />`);
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-page-actions'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Sidebar id="sidebar"/>`);
|
||||
assert.ok(find('#sidebar'));
|
||||
await render(hbs`<Rose::Layout::Page::Actions id="actions"/>`);
|
||||
assert.ok(find('#actions'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Sidebar>
|
||||
await render(hbs`<Rose::Layout::Page::Actions>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page::Sidebar>`);
|
||||
</Rose::Layout::Page::Actions>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/page/body', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Body />`);
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-page-body'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Body id="body"/>`);
|
||||
assert.ok(find('#body'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Body>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page::Body>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/page/breadcrumbs', function (
|
||||
hooks
|
||||
) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Breadcrumbs />`);
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-page-breadcrumbs'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Breadcrumbs id="breadcrumbs"/>`);
|
||||
assert.ok(find('#breadcrumbs'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Breadcrumbs>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page::Breadcrumbs>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -8,8 +8,8 @@ module('Integration | Component | rose/layout/page/header', function (hooks) {
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Header />`);
|
||||
assert.ok(find('header'));
|
||||
assert.ok(find('.rose-layout-header'));
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-page-header'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/page/navigation', function (
|
||||
hooks
|
||||
) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Navigation />`);
|
||||
assert.ok(find('div'));
|
||||
assert.ok(find('.rose-layout-page-navigation'));
|
||||
});
|
||||
|
||||
test('it renders with attributes', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Navigation id="navigation"/>`);
|
||||
assert.ok(find('#navigation'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Layout::Page::Navigation>
|
||||
<button id="content" />
|
||||
</Rose::Layout::Page::Navigation>`);
|
||||
assert.ok(find('#content'));
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,14 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { action } from '@ember/object';
|
||||
|
||||
export default class OrgsOrgProjectsIndexRoute extends Route {}
|
||||
export default class OrgsOrgProjectsIndexRoute extends Route {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Route to new project view.
|
||||
*/
|
||||
@action
|
||||
new() {
|
||||
this.transitionTo('orgs.org.projects.new');
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
<HeadLayout />
|
||||
|
||||
{{title (app-name)}}
|
||||
|
||||
<Rose::Layout::Page as |page|>
|
||||
<page.header>
|
||||
<Rose::Layout::Global as |global|>
|
||||
<global.header>
|
||||
<Rose::Header as |header|>
|
||||
<header.brand @logo="logo-hashi" @text={{app-name}} />
|
||||
<header.nav as |nav|>
|
||||
@@ -26,20 +22,20 @@
|
||||
</utilities.dropdown>
|
||||
</header.utilities>
|
||||
</Rose::Header>
|
||||
</page.header>
|
||||
</global.header>
|
||||
|
||||
<page.main>
|
||||
<global.body>
|
||||
{{outlet}}
|
||||
</page.main>
|
||||
</global.body>
|
||||
|
||||
<page.sidebar>
|
||||
<global.navigation>
|
||||
<Rose::Nav::Sidebar @title={{t 'dev.title'}} as |nav|>
|
||||
<nav.link @route="orgs" class="active">{{t 'dev.item-name'}}</nav.link>
|
||||
<nav.link @route="index">{{t 'dev.item-name'}}</nav.link>
|
||||
</Rose::Nav::Sidebar>
|
||||
</page.sidebar>
|
||||
</global.navigation>
|
||||
|
||||
</Rose::Layout::Page>
|
||||
</Rose::Layout::Global>
|
||||
|
||||
<EmberNotify @closeAfter={{4000}} as |message close|>
|
||||
<Rose::Notification
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
<div class="projects-overview">
|
||||
<Rose::Layout::Page class="projects-overview" as |page|>
|
||||
<page.header>
|
||||
<h2>{{t "resources.projects"}}</h2>
|
||||
</page.header>
|
||||
|
||||
<h2>{{t "resources.projects"}}</h2>
|
||||
<page.actions>
|
||||
<Rose::Button
|
||||
@style="primary"
|
||||
@iconLeft="plus-plain"
|
||||
{{on "click" (route-action "new")}}
|
||||
>
|
||||
{{t 'titles.new'}}
|
||||
</Rose::Button>
|
||||
</page.actions>
|
||||
|
||||
<LinkTo @route="orgs.org.projects.new">
|
||||
<Rose::Icon @name="plus-circle-outline" @size="medium" />
|
||||
{{t "titles.new"}}
|
||||
</LinkTo>
|
||||
|
||||
<ul class="projects">
|
||||
{{#each @model as |project|}}
|
||||
<li class="project">
|
||||
<Rose::Card::Link @title={{project.name}}
|
||||
@subtitle={{project.id}}
|
||||
@description={{project.description}}
|
||||
@route="orgs.org.projects.project"
|
||||
@model={{project}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<page.body>
|
||||
<ul class="projects">
|
||||
{{#each @model as |project|}}
|
||||
<li class="project">
|
||||
<Rose::Card::Link @title={{project.name}}
|
||||
@subtitle={{project.id}}
|
||||
@description={{project.description}}
|
||||
@route="orgs.org.projects.project"
|
||||
@model={{project}}
|
||||
/>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</page.body>
|
||||
</Rose::Layout::Page>
|
||||
@@ -1,18 +1,22 @@
|
||||
{{title (t "titles.new")}}
|
||||
<Rose::Layout::Page class="project-new" as |page|>
|
||||
<page.breadcrumbs>
|
||||
<div class="breadcrumbs">
|
||||
<LinkTo @route='orgs.org.projects'>{{t "resources.projects"}}</LinkTo>
|
||||
>
|
||||
<LinkTo @route='orgs.org.projects.new'>{{t "titles.new"}}</LinkTo>
|
||||
</div>
|
||||
</page.breadcrumbs>
|
||||
|
||||
<div class="project-new">
|
||||
<div class="breadcrumbs">
|
||||
<LinkTo @route='orgs.org.projects'>{{t "resources.projects"}}</LinkTo>
|
||||
>
|
||||
<LinkTo @route='orgs.org.projects.new'>{{t "titles.new"}}</LinkTo>
|
||||
</div>
|
||||
<page.header>
|
||||
<h2>{{t "titles.new"}}</h2>
|
||||
</page.header>
|
||||
|
||||
<h2>{{t "titles.new"}}</h2>
|
||||
|
||||
<Form::Project
|
||||
@model={{@model}}
|
||||
@submit={{route-action "save" @model}}
|
||||
@cancel={{route-action "cancel" @model}}
|
||||
class="project-new-form"
|
||||
/>
|
||||
</div>
|
||||
<page.body>
|
||||
<Form::Project
|
||||
@model={{@model}}
|
||||
@submit={{route-action "save" @model}}
|
||||
@cancel={{route-action "cancel" @model}}
|
||||
class="project-new-form"
|
||||
/>
|
||||
</page.body>
|
||||
</Rose::Layout::Page>
|
||||
@@ -1,35 +1,43 @@
|
||||
{{title @model.name}}
|
||||
|
||||
<div class="project-overview">
|
||||
<div class="breadcrumbs">
|
||||
<LinkTo @route='orgs.org.projects'>{{t "resources.projects"}}</LinkTo>
|
||||
<Rose::Layout::Page class="project-overview" as |page|>
|
||||
<page.breadcrumbs>
|
||||
<div class="breadcrumbs">
|
||||
<LinkTo @route='orgs.org.projects'>{{t "resources.projects"}}</LinkTo>
|
||||
>
|
||||
<LinkTo @route='orgs.org.projects.project'>{{@model.name}}</LinkTo>
|
||||
</div>
|
||||
</page.breadcrumbs>
|
||||
|
||||
<page.header>
|
||||
<h2>{{t "resources.project.settings"}}</h2>
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
<Rose::Nav::Tabs as |nav|>
|
||||
<nav.link @route='orgs.org.projects.project'>
|
||||
{{t "nav.overview"}}
|
||||
</nav.link>
|
||||
<nav.link @route='index'>
|
||||
{{t 'dev.item-name'}}
|
||||
</nav.link>
|
||||
</Rose::Nav::Tabs>
|
||||
</page.navigation>
|
||||
|
||||
<page.body>
|
||||
<Form::Project
|
||||
@model={{@model}}
|
||||
@submit={{route-action "save" @model}}
|
||||
@cancel={{route-action "cancel" @model}}
|
||||
class="project-new-form"
|
||||
/>
|
||||
|
||||
<Rose::Button
|
||||
@style="warning"
|
||||
@disabled={{@model.canSave}}
|
||||
{{on "click" (route-action "delete" @model)}}
|
||||
>
|
||||
<LinkTo @route='orgs.org.projects.project'>{{@model.name}}</LinkTo>
|
||||
</div>
|
||||
|
||||
<h2>{{t "resources.project.settings"}}</h2>
|
||||
|
||||
<Rose::Nav::Tabs as |nav|>
|
||||
<nav.link @route='orgs.org.projects.project'>
|
||||
{{t 'dev.item-name'}}
|
||||
</nav.link>
|
||||
<nav.link @route='index'>
|
||||
{{t 'dev.item-name'}}
|
||||
</nav.link>
|
||||
</Rose::Nav::Tabs>
|
||||
|
||||
<Form::Project
|
||||
@model={{@model}}
|
||||
@submit={{route-action "save" @model}}
|
||||
@cancel={{route-action "cancel" @model}}
|
||||
class="project-new-form"
|
||||
/>
|
||||
|
||||
<Rose::Button
|
||||
@style="warning"
|
||||
@disabled={{@model.canSave}}
|
||||
{{on "click" (route-action "delete" @model)}}
|
||||
>
|
||||
{{t 'actions.delete'}}
|
||||
</Rose::Button>
|
||||
</div>
|
||||
{{t 'actions.delete'}}
|
||||
</Rose::Button>
|
||||
</page.body>
|
||||
</Rose::Layout::Page>
|
||||
Reference in new issue
Block a user