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

Make breadcrumbs component dumb #1257

Merged
merged 3 commits into from
Oct 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;