Skip to content
This repository has been archived by the owner on May 19, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1257 from govau/ji-breadcrumbs
Browse files Browse the repository at this point in the history
Make breadcrumbs component dumb
  • Loading branch information
jcscottiii authored Oct 17, 2017
2 parents 760b10c + 7d9f566 commit 10cee55
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 132 deletions.
7 changes: 3 additions & 4 deletions static_src/components/app_container.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import React from 'react';

import Action from './action.jsx';
Expand All @@ -7,7 +6,7 @@ import { appHealth, worstAppInstanceState } from '../util/health';
import { appStates } from '../constants';
import { config } from 'skin';
import AppStore from '../stores/app_store.js';
import Breadcrumbs from './breadcrumbs.jsx';
import Breadcrumbs from './breadcrumbs';
import DomainStore from '../stores/domain_store.js';
import EnvStore from '../stores/env_store.js';
import RouteStore from '../stores/route_store.js';
Expand Down Expand Up @@ -190,7 +189,7 @@ export default class AppContainer extends React.Component {


render() {
const { app, envRequest, envUpdateError } = this.state;
const { org, space, app, envRequest, envUpdateError } = this.state;

let loading = <Loading text="Loading app" />;
let content = <div>{ loading }</div>;
Expand All @@ -208,7 +207,7 @@ export default class AppContainer extends React.Component {
<div>
<div className="grid">
<div className="grid-width-12">
<Breadcrumbs />
<Breadcrumbs org={org} space={space} app={app} />
<PageHeader title={ title }>
{ this.error }
{ this.openApp }
Expand Down
75 changes: 0 additions & 75 deletions static_src/components/breadcrumbs.jsx

This file was deleted.

51 changes: 51 additions & 0 deletions static_src/components/breadcrumbs/breadcrumbs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';

import { appPropType } from '../../stores/app_store';
import { orgPropType } from '../../stores/org_store';
import { spacePropType } from '../../stores/space_store';
import BreadcrumbsItem from './breadcrumbs_item';
import { orgHref, spaceHref } from '../../util/url';

const propTypes = {
org: orgPropType.isRequired,
space: spacePropType,
app: appPropType
};

const Breadcrumbs = ({ org, space, app }) => {
const items = [
<BreadcrumbsItem key="home" href="/" testLabel="overview">
Overview
</BreadcrumbsItem>
];

if (org && space) {
items.push(
<BreadcrumbsItem key={org.guid} href={orgHref(org)} testLabel="org">
{org.name}
</BreadcrumbsItem>
);
}

if (org && space && app) {
items.push(
<BreadcrumbsItem
key={space.guid}
href={spaceHref(org, space)}
testLabel="space"
>
{space.name}
</BreadcrumbsItem>
);
}

return (
<ol className="breadcrumbs" data-test="breadcrumbs">
{items}
</ol>
);
};

Breadcrumbs.propTypes = propTypes;

export default Breadcrumbs;
26 changes: 26 additions & 0 deletions static_src/components/breadcrumbs/breadcrumbs_item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';

const propTypes = {
children: PropTypes.node.isRequired,
href: PropTypes.string,
testLabel: PropTypes.string
};

const BreadcrumbsItem = ({ children, href, testLabel }) => (
<li className="breadcrumbs-item">
{href ? (
<a className="breadcrumbs-item-link" href={href} data-test={testLabel}>
{children}
</a>
) : (
<span className="breadcrumbs-item-current" data-test={testLabel}>
{children}
</span>
)}
</li>
);

BreadcrumbsItem.propTypes = propTypes;

export default BreadcrumbsItem;
1 change: 1 addition & 0 deletions static_src/components/breadcrumbs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './breadcrumbs';
29 changes: 0 additions & 29 deletions static_src/components/breadcrumbs_item.jsx

This file was deleted.

10 changes: 5 additions & 5 deletions static_src/components/org_container.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@

import React from 'react';

import { config } from 'skin';
import AppCountStatus from './app_count_status.jsx';
import Breadcrumbs from './breadcrumbs.jsx';
import Breadcrumbs from './breadcrumbs';
import EntityIcon from './entity_icon.jsx';
import EntityEmpty from './entity_empty.jsx';
import Loading from './loading.jsx';
Expand Down Expand Up @@ -121,12 +120,13 @@ export default class OrgContainer extends React.Component {
}

render() {
const { org } = this.state;
const state = this.state;
let loading = <Loading text="Loading organization" />;
let content = <div>{ loading }</div>;
const title = (
<span>
<EntityIcon entity="org" iconSize="large" /> { state.org.name }
<EntityIcon entity="org" iconSize="large" /> { org.name }
</span>
);
const spaces = !state.spaces.length ? this.emptyState :
Expand All @@ -142,7 +142,7 @@ export default class OrgContainer extends React.Component {

if (state.empty) {
content = <h4 className="test-none_message">No organizations</h4>;
} else if (!state.loading && state.org) {
} else if (!state.loading && org) {
const allApps = this.allApps();
const allServices = this.allServices();

Expand All @@ -151,7 +151,7 @@ export default class OrgContainer extends React.Component {
<div className="grid">
<div className="grid">
<div className="grid-width-12">
<Breadcrumbs />
<Breadcrumbs org={org} />
<PageHeader title={ title } />
</div>
</div>
Expand Down
12 changes: 6 additions & 6 deletions static_src/components/space_container.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@

import PropTypes from 'prop-types';
import React from 'react';

import AppCountStatus from './app_count_status.jsx';
import AppList from '../components/app_list.jsx';
import Breadcrumbs from './breadcrumbs.jsx';
import Breadcrumbs from './breadcrumbs';
import EntityIcon from './entity_icon.jsx';
import Loading from './loading.jsx';
import Marketplace from './marketplace.jsx';
Expand Down Expand Up @@ -74,20 +73,21 @@ export default class SpaceContainer extends React.Component {
return <Loading />;
}

const { currentOrg: org, space } = this.state;

let main = <div></div>;
const title = (
<span>
<EntityIcon entity="space" iconSize="large" /> { this.state.space.name }
<EntityIcon entity="space" iconSize="large" /> { space.name }
</span>
);

if (this.state.space && this.state.space.guid) {
const space = this.state.space;
if (space && space.guid) {
main = (
<div>
<div className="grid">
<div className="grid-width-12">
<Breadcrumbs />
<Breadcrumbs org={org} space={space} />
<PageHeader title={ title } />
</div>
</div>
Expand Down
7 changes: 6 additions & 1 deletion static_src/stores/org_store.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@

/*
* Store for org data. Will store and update org data on changes from UI and
* server.
*/
import PropTypes from 'prop-types';

import AppDispatcher from '../dispatcher';
import BaseStore from './base_store.js';
import LoginStore from './login_store.js';
import { orgActionTypes } from '../constants.js';
import Quicklook from '../models/quicklook';

export const orgPropType = PropTypes.shape({
guid: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
});

export class OrgStore extends BaseStore {
constructor() {
super();
Expand Down
6 changes: 6 additions & 0 deletions static_src/stores/space_store.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
*/

import Immutable from 'immutable';
import PropTypes from 'prop-types';

import BaseStore from './base_store.js';
import { orgActionTypes, spaceActionTypes } from '../constants.js';

export const spacePropType = PropTypes.shape({
guid: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
});

class SpaceStore extends BaseStore {
constructor() {
super();
Expand Down
16 changes: 4 additions & 12 deletions static_src/test/functional/pageobjects/breadcrumbs.element.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@

import BaseElement from './base.element';

// https://www.martinfowler.com/bliki/PageObject.html
//
// Represents a DOM element for making assertions against. This makes it
// easier to abstract some of the webdriver details from the UI component.

// TODO attach to class as static property
const breadcrumbs = '.test-breadcrumbs';
const breadcrumbs = '[data-test="breadcrumbs"]';

const selectors = {
primary: breadcrumbs,
overview: `${breadcrumbs} li:first-child a`,
org: `${breadcrumbs} li:nth-child(1) a`,
space: `${breadcrumbs} li:last-child a`
overview: `${breadcrumbs} [data-test="overview"]`,
org: `${breadcrumbs} [data-test="org"]`,
space: `${breadcrumbs} [data-test="space"]`
};

export default class Breadcrumbs extends BaseElement {
Expand All @@ -40,4 +33,3 @@ export default class Breadcrumbs extends BaseElement {
}

Breadcrumbs.primarySelector = selectors.primary;

0 comments on commit 10cee55

Please sign in to comment.