adds container and presentation components for browser-rail component which composes filter-rail. adds styling doc. adds browse route template. todo: move to browse.entity

This commit is contained in:
Seyi Adebajo 2017-04-26 13:05:30 -07:00 committed by Mars Lan
parent e08f9c7685
commit b275c329fb
5 changed files with 119 additions and 1 deletions

View File

@ -0,0 +1,3 @@
import Ember from 'ember';
const { Component } = Ember;
export default Component.extend({});

View File

@ -0,0 +1,100 @@
import Ember from 'ember';
import connect from 'ember-redux/components/connect';
const { Component } = Ember;
/**
* Matches string representing a url path segment that contains a `page` segment followed by a page number
* The page number is retained
* @type {RegExp}
*/
const pageRegex = /\/page\/([0-9]+)/i;
/**
* Matches a url string with a `urn` query. urn query starts with letters or underscore segment of any length greater
* than 1 followed by colon and 3 forward slashes and a segment containing letters, _ or /, or none
* The value following the urn key is retained
* @type {RegExp}
*/
const urnRegex = /urn=([a-z_]+[:\/]{3}[a-z_\/]*)/i;
/**
* Matches a url string path segment that optionally starts with a hash followed by forward slash, at least one
* alphabet, forward slash, number of varying length and optional trailing slash
* The number is retained
* @type {RegExp}
*/
const entityRegex = /^#?\/[a-z]+\/([0-9]+)\/?/i;
/**
* Takes a node url and parses out the query params and path spec to be included in the link component
* @param {String} nodeUrl url linking to the node
* @return {Object}
*/
const nodeUrlToQueryParams = nodeUrl => {
const pageMatch = nodeUrl.match(pageRegex);
const urnMatch = nodeUrl.match(urnRegex);
let queryParams = null;
// If we have a page match, append the page number to eventual urn object
// in most cases this page is usually, 1. Might be safe to remove the page pattern
// search in its entirety if this is the case
if (Array.isArray(pageMatch)) {
queryParams = Object.assign({}, queryParams, {
page: pageMatch[1]
});
}
// If we have a urn match, append the urn to eventual query params object
if (Array.isArray(urnMatch)) {
queryParams = Object.assign({}, queryParams, {
urn: urnMatch[1]
});
}
return queryParams;
};
/**
* Selector function that takes a Redux Store to extract
* state props for the browser-rail
* @param state
* @return {{nodes: (*|Array)}}
*/
const stateToComputed = state => {
// Extracts the current entity active in the browse view
const { browseEntity: { currentEntity = '' } = {} } = state;
// Retrieves properties for the current entity from the state tree
const { [currentEntity]: { nodesByUrn = {}, query: { urn } = {} } } = state;
// Removes `s` from the end of each entity name. Ember routes for individual entities are singular, and also
// returned entities contain id prop that is the singular type name, suffixed with Id, e.g. metricId
// datasets -> dataset, metrics -> metric, flows -> flow
const singularName = currentEntity.slice(0, -1);
let nodes = nodesByUrn[urn] || [];
/**
* Creates dynamic query link params for each node
* @type {Array} list of child nodes or datasets to render
*/
nodes = nodes.map(({ nodeName, nodeUrl, [`${singularName}Id`]: id }) => {
nodeUrl = String(nodeUrl);
// If the id prop (datasetId|metricId|flowId) is truthy, then it is a standalone entity
if (id) {
return {
title: nodeName,
text: nodeName,
route: `${currentEntity}.${singularName}`,
model: nodeUrl.match(entityRegex)[1]
};
}
return {
title: nodeName,
text: nodeName,
route: `browse.entity`,
model: currentEntity,
queryParams: nodeUrlToQueryParams(nodeUrl)
};
});
return { nodes };
};
export default connect(stateToComputed)(Component.extend({}));

View File

@ -46,6 +46,8 @@ $pad-width: 16px;
padding: 0 0 $pad-width/2;
}
/// Node link is a filter rail component that navigates to mode details about the
/// selected node
&__node-link {
display: block;
margin: 2px 0;

View File

@ -0,0 +1,13 @@
<div class="row">
{{browser/containers/browser-view}}
</div>
<div class="row">
<div class="col-md-3">
{{browser/containers/browser-rail}}
</div>
<div class="col-md-9">
</div>
</div>
{{outlet}}

View File

@ -1,7 +1,7 @@
<nav role="navigation">
<ul class="nav navbar-nav browse-nav">
{{#each-in browseData as |entity data|}}
{{#nav-link "browse.entity" entity tagName="li" class="col-md-4 browse-nav__entity"}}
{{#nav-link "browse.entity" entity (query-params page=1 urn="") tagName="li" class="col-md-4 browse-nav__entity"}}
<div class="browse-nav__item">
<p class="browse-nav__count">{{data.count}}</p>
<p class="browse-nav__title">{{entity}}</p>