chore: 🤖 Refactor global and page layouts

This commit is contained in:
Susmitha Girumala committed 2020-06-07 21:03:29 -04:00
1 parent 6b15aeda1d
commit c4023abf81
51 files changed
+433 -186

No files matched your search

@@ -1,24 +0,0 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { hbs } from 'ember-cli-htmlbars';
import { action } from '@storybook/addon-actions';
<Meta title="Rose|Layout" component="PageHeader" />
# Layout|Page Header
A page layout/positioning component that configures a two column grid with defined areas: title and utilities
```htmlbars
<Rose::Layout::PageHeader />
```
<Preview>
<Story name="Page Header">{{
template: hbs`
<Rose::Layout::PageHeader>
<div style="grid-area: title; background: var(--brand-gray-7)">Grid area: title</div>
<div style="grid-area: utilities; background: var(--brand-gray-5)">Grid area: utilities</div>
</Rose::Layout::PageHeader>
`,
}}</Story>
</Preview>
@@ -1,5 +1,5 @@
import Component from '@ember/component';
import layout from '../../../templates/components/rose/layout/page-header';
import layout from '../../../templates/components/rose/layout/page';
export default Component.extend({
layout,
@@ -0,0 +1,33 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { hbs } from 'ember-cli-htmlbars';
import { action } from '@storybook/addon-actions';
<Meta title="Rose|Layout|Page" component="Page" />
# Layout|Page
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.actions />
<page.navigation />
<page.body />
</Rose::Layout::Page>
```
<Preview>
<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.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>
</Preview>
@@ -0,0 +1,7 @@
import Component from '@ember/component';
import layout from '../../../../templates/components/rose/layout/page/actions';
export default Component.extend({
layout,
tagName: '',
});
@@ -0,0 +1,7 @@
import Component from '@ember/component';
import layout from '../../../../templates/components/rose/layout/page/body';
export default Component.extend({
layout,
tagName: '',
});
@@ -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/header';
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: '',
});
@@ -10,33 +10,29 @@ import { text, select } from '@storybook/addon-knobs';
A header title component with ability to configure dropdown using `Rose::Header::Dropdown`. To be used with `Rose::Layout::PageHeader`.
```html
<Rose::Layout::PageHeader style="border: 1px solid var(--brand-gray-5);">
<Rose::PageHeader::Title as |title| >
<title.dropdown
@text="Page Header Title"
@icon="user-square-fill" as |dropdown|
>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.button>Button menu item</dropdown.button>
</title.dropdown>
</Rose::PageHeader::Title>
</Rose::Layout::PageHeader>
<Rose::PageHeader::Title as |title| >
<title.dropdown
@text="Page Header Title"
@icon="user-square-fill" as |dropdown|
>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.button>Button menu item</dropdown.button>
</title.dropdown>
</Rose::PageHeader::Title>
```
<Preview>
<Story name="Title">{{
template: hbs`
<Rose::Layout::PageHeader style="border: 1px solid var(--brand-gray-5);">
<Rose::PageHeader::Title as |title| >
<title.dropdown
@text={{pageTitle}}
@icon={{dropdownIcon}} as |dropdown|
>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.button>Button menu item</dropdown.button>
</title.dropdown>
</Rose::PageHeader::Title>
</Rose::Layout::PageHeader>
<Rose::PageHeader::Title as |title| >
<title.dropdown
@text={{pageTitle}}
@icon={{dropdownIcon}} as |dropdown|
>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.button>Button menu item</dropdown.button>
</title.dropdown>
</Rose::PageHeader::Title>
`,
context: {
pageTitle: text('pageTitle', 'Page Section Title'),
@@ -9,23 +9,19 @@ import { action } from '@storybook/addon-actions';
An component comprised of `Rose::Button` as actions. To be used with `Rose::Layout::PageHeader`.
```html
<Rose::Layout::PageHeader style="border: 1px solid var(--brand-gray-5);">
<Rose::PageHeader::Utilities as |utilities|>
<utilities.action @style="secondary">Secondary</utilities.action>
<utilities.action @style="primary">Primary</utilities.action>
</Rose::PageHeader::Utilities>
</Rose::Layout::PageHeader>
<Rose::PageHeader::Utilities as |utilities|>
<utilities.action @style="secondary">Secondary</utilities.action>
<utilities.action @style="primary">Primary</utilities.action>
</Rose::PageHeader::Utilities>
```
<Preview>
<Story name="Utilities">{{
template: hbs`
<Rose::Layout::PageHeader style="border: 1px solid var(--brand-gray-5);">
<Rose::PageHeader::Utilities as |utilities|>
<utilities.action @style="secondary">Secondary</utilities.action>
<utilities.action @style="primary">Primary</utilities.action>
</Rose::PageHeader::Utilities>
</Rose::Layout::PageHeader>
<Rose::PageHeader::Utilities as |utilities|>
<utilities.action @style="secondary">Secondary</utilities.action>
<utilities.action @style="primary">Primary</utilities.action>
</Rose::PageHeader::Utilities>
`,
}}</Story>
</Preview>
@@ -1,2 +1,2 @@
@import 'global';
@import 'page-header';
@import 'page';
@@ -1,24 +0,0 @@
@use '../../variables/media';
.rose-layout-page-header {
display: grid;
grid-template-areas: 'title title utilities';
grid-template-columns: 1fr auto;
grid-template-rows: auto 1fr;
.rose-page-header-utilities {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
}
}
@media (max-width: media.width(small)) {
.rose-layout-page-header {
grid-template-columns: 1fr;
grid-template-areas:
'title'
'utilities';
}
}
@@ -0,0 +1,3 @@
.rose-layout-page-actions {
grid-area: actions;
}
@@ -0,0 +1,3 @@
.rose-layout-page-body {
grid-area: body;
}
@@ -0,0 +1,3 @@
.rose-layout-page-breadcrumbs {
grid-area: breadcrumbs;
}
@@ -0,0 +1,3 @@
.rose-layout-page-header {
grid-area: header;
}
@@ -0,0 +1,31 @@
@use '../../../variables/sizing';
@use '../../../variables/media';
@import 'breadcrumbs';
@import 'header';
@import 'actions';
@import 'navigation';
@import 'body';
.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;
}
@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-page-navigation {
grid-area: navigation;
}
@@ -0,0 +1,9 @@
<div ...attributes class="rose-layout-page">
{{yield (hash
breadcrumbs=(component 'rose/layout/page/breadcrumbs')
header=(component 'rose/layout/page/header')
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>
@@ -0,0 +1,3 @@
<div ...attributes class="rose-layout-page-navigation">
{{yield}}
</div>
@@ -0,0 +1,11 @@
import EmberObject from '@ember/object';
import ComponentAutoIdMixin from 'rose/mixins/component-auto-id';
import { module, test } from 'qunit';
module('Unit | Mixin | component-auto-id', function () {
test('it generates an ID and assigns it to the object', function (assert) {
let ComponentAutoIdObject = EmberObject.extend(ComponentAutoIdMixin);
let subject = ComponentAutoIdObject.create();
assert.ok(subject.id);
});
});
@@ -1 +1 @@
export { default } from 'rose/components/rose/layout/global';
export { default } from 'rose/components/rose/layout/global';
@@ -1 +1 @@
export { default } from 'rose/components/rose/layout/global/body';
export { default } from 'rose/components/rose/layout/global/body';
@@ -1 +1 @@
export { default } from 'rose/components/rose/layout/global/header';
export { default } from 'rose/components/rose/layout/global/header';
@@ -1 +1 @@
export { default } from 'rose/components/rose/layout/global/navigation';
export { default } from 'rose/components/rose/layout/global/navigation';
@@ -1 +0,0 @@
export { default } from 'rose/components/rose/layout/page-header';
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/layout/page';
@@ -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';
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/layout/page/header';
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/layout/page/navigation';
@@ -40,6 +40,13 @@
</global.navigation>
<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
@@ -3,7 +3,7 @@ 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) {
module('Integration | Component | rose/layout/global', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
@@ -3,7 +3,7 @@ import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | rose/layout/global/body', function(hooks) {
module('Integration | Component | rose/layout/global/body', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
@@ -3,7 +3,7 @@ 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) {
module('Integration | Component | rose/layout/global/header', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
@@ -3,7 +3,9 @@ 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) {
module('Integration | Component | rose/layout/global/navigation', function (
hooks
) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
@@ -1,28 +0,0 @@
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-header', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Layout::PageHeader />`);
assert.ok(find('.rose-layout-page-header'));
});
test('it renders with html attributes', async function (assert) {
await render(hbs`<Rose::Layout::PageHeader id="page-header"/>`);
assert.ok(find('#page-header'));
});
test('it renders with content', async function (assert) {
await render(
hbs`<Rose::Layout::PageHeader>Page header content</Rose::Layout::PageHeader>`
);
assert.equal(
find('.rose-layout-page-header').textContent.trim(),
'Page header 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', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Layout::Page />`);
assert.ok(find('div'));
assert.ok(find('.rose-layout-page'));
});
test('it renders with attributes', async function (assert) {
await render(hbs`<Rose::Layout::Page id="page"/>`);
assert.ok(find('#page'));
});
test('it renders with content', async function (assert) {
await render(hbs`<Rose::Layout::Page>
<button id="content" />
</Rose::Layout::Page>`);
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/actions', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
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::Actions id="actions"/>`);
assert.ok(find('#actions'));
});
test('it renders with content', async function (assert) {
await render(hbs`<Rose::Layout::Page::Actions>
<button id="content" />
</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'));
});
});
@@ -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/header', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Layout::Page::Header />`);
assert.ok(find('div'));
assert.ok(find('.rose-layout-page-header'));
});
test('it renders with attributes', async function (assert) {
await render(hbs`<Rose::Layout::Page::Header id="header"/>`);
assert.ok(find('#header'));
});
test('it renders with content', async function (assert) {
await render(hbs`<Rose::Layout::Page::Header>
<button id="content" />
</Rose::Layout::Page::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/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,6 +1,9 @@
<div class="projects-overview">
<Rose::Layout::PageHeader>
<Rose::Layout::Page class="projects-overview" as |page|>
<page.header>
<Rose::PageHeader::Title @text={{t "resources.projects"}} />
</page.header>
<page.actions>
<Rose::PageHeader::Utilities as |utility|>
<utility.action
@style="primary"
@@ -10,18 +13,20 @@
{{t 'titles.new'}}
</utility.action>
</Rose::PageHeader::Utilities>
</Rose::Layout::PageHeader>
</page.actions>
<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>
+19 -17
View File
@@ -1,20 +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>
<Rose::Layout::PageHeader>
<page.header>
<Rose::PageHeader::Title @text={{t "titles.new"}} />
</Rose::Layout::PageHeader>
</page.header>
<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,37 +1,41 @@
{{title @model.name}}
<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>
<div class="project-overview">
<div class="breadcrumbs">
<LinkTo @route='orgs.org.projects'>{{t "resources.projects"}}</LinkTo>
>
<LinkTo @route='orgs.org.projects.project'>{{@model.name}}</LinkTo>
</div>
<Rose::Layout::PageHeader>
<page.header>
<Rose::PageHeader::Title @text={{t "resources.project.settings"}} />
</Rose::Layout::PageHeader>
</page.header>
<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>
<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>
<Form::Project
@model={{@model}}
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
class="project-new-form"
/>
<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)}}
>
{{t 'actions.delete'}}
</Rose::Button>
</div>
<Rose::Button
@style="warning"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
{{t 'actions.delete'}}
</Rose::Button>
</page.body>
</Rose::Layout::Page>