reenable breadcumb navigation based on li urn format. support either hdfs / non-hdfs. add home

This commit is contained in:
Seyi Adebajo 2018-02-22 11:16:50 -08:00
parent 1ce7e05687
commit 86804ac2c9
9 changed files with 167 additions and 73 deletions

View File

@ -0,0 +1,29 @@
import Component from '@ember/component';
import { computed, get } from '@ember/object';
import ComputedProperty from '@ember/object/computed';
import { bakeUrnBreadcrumbs } from 'wherehows-web/utils/entities';
import { IDatasetBreadcrumb } from 'wherehows-web/utils/entities/bake-urn-breadcrumbs';
export default class UrnBreadcrumbs extends Component {
tagName = 'ul';
classNames = ['nacho-breadcrumbs'];
/**
* Urn for the dataset to be represented in the breadcrumbs
* @type {string}
* @memberof UrnBreadcrumbs
*/
urn: string;
/**
* Builds the breadcrumbs for the dataset with the related urn
* @type {ComputedProperty<Array<IDatasetBreadcrumb>>}
* @memberof UrnBreadcrumbs
*/
breadcrumbs: ComputedProperty<Array<IDatasetBreadcrumb>> = computed('urn', function(
this: UrnBreadcrumbs
): Array<IDatasetBreadcrumb> {
return bakeUrnBreadcrumbs(get(this, 'urn'));
});
}

View File

@ -2,17 +2,6 @@ import Route from '@ember/routing/route';
import { set, get, setProperties } from '@ember/object';
import { inject } from '@ember/service';
import { makeUrnBreadcrumbs } from 'wherehows-web/utils/entities';
import { readDatasetCompliance, readDatasetComplianceSuggestion } from 'wherehows-web/utils/api/datasets/compliance';
import { readNonPinotProperties, readPinotProperties } from 'wherehows-web/utils/api/datasets/properties';
import { readDatasetComments } from 'wherehows-web/utils/api/datasets/comments';
import { readComplianceDataTypes } from 'wherehows-web/utils/api/list/compliance-datatypes';
import {
readDatasetColumns,
columnDataTypesAndFieldNames,
augmentObjectsWithHtmlComments
} from 'wherehows-web/utils/api/datasets/columns';
import { readDatasetOwners, getUserEntities } from 'wherehows-web/utils/api/datasets/owners';
import { isRequiredMinOwnersNotConfirmed } from 'wherehows-web/constants/datasets/owner';
import { readDatasetById, readDatasetByUrn } from 'wherehows-web/utils/api/datasets/dataset';
import isUrn, { isWhUrn, isLiUrn, convertWhUrnToLiUrn, encodeUrn, decodeUrn } from 'wherehows-web/utils/validators/urn';
@ -74,18 +63,8 @@ export default Route.extend({
set(controller, 'model', model);
setProperties(controller, {
isInternal: await get(this, 'configurator').getConfig('isInternal')
// ...properties,
// requiredMinNotConfirmed: isRequiredMinOwnersNotConfirmed(owners)
});
// If urn exists, create a breadcrumb list
// TODO: DSS-7068 Refactoring in progress , move this to a computed prop on a container component
// FIXME: DSS-7068 browse.entity?urn route does not exist for last item in breadcrumb i.e. the dataset
// currently being viewed. Should this even be a link in the first place?
if (model.uri) {
set(controller, 'breadcrumbs', makeUrnBreadcrumbs(model.uri));
}
// TODO: Get current user ACL permission info for ACL access tab
Promise.resolve(currentUser())
.then(userInfo => {

View File

@ -0,0 +1,25 @@
<li class="nacho-breadcrumbs__crumb">
{{link-to
"datasets"
"browse.entity"
"datasets"
(query-params page=1 prefix="" platform="")
class="nacho-breadcrumbs__crumb__grain"
}}
</li>
{{#each breadcrumbs as |crumb|}}
<li class="nacho-breadcrumbs__crumb">
{{link-to
crumb.crumb
"browse.entity"
"datasets"
(query-params page=1 prefix=crumb.prefix platform=crumb.platform)
class="nacho-breadcrumbs__crumb__grain"
}}
</li>
{{/each}}

View File

@ -1,13 +1,6 @@
<div class="container">
<div id="dataset">
<ul class="nacho-breadcrumbs">
{{#each breadcrumbs as |crumb|}}
<li class="nacho-breadcrumbs__crumb">
{{link-to crumb.crumb "browse.entity" "datasets" (query-params page=1 urn=crumb.urn)
class="nacho-breadcrumbs__crumb__grain"}}
</li>
{{/each}}
</ul>
{{datasets/urn-breadcrumbs urn=model.uri}}
<div class="row">
<div class="col-xs-5">
@ -51,6 +44,7 @@
<h3>{{ model.nativeName }}</h3>
</div>
</div>
{{dataset-owner-list owners=owners datasetName=model.nativeName}}
</div>

View File

@ -0,0 +1,48 @@
import { DatasetPlatform } from 'wherehows-web/constants';
import { datasetUrnRegexLI } from 'wherehows-web/utils/validators/urn';
/**
* Describes the interface for a breadcrumb object
* @interface IDatasetBreadcrumb
*/
export interface IDatasetBreadcrumb {
crumb: string;
platform: DatasetPlatform;
prefix: string;
}
/**
* Takes a urn string and parses it into an array of breadcrumb objects with crumb, and query params, prefix and/or platform as
* properties.
* Hierarchy is implied in element ordering
* @param {string} urn the dataset urn in li format
* @returns {Array<IDatasetBreadcrumb>}
*/
export default (urn: string): Array<IDatasetBreadcrumb> => {
const liDatasetUrn = datasetUrnRegexLI.exec(urn);
const breadcrumbs: Array<IDatasetBreadcrumb> = [];
if (liDatasetUrn) {
const [, platform, segments] = liDatasetUrn;
const isHdfs = String(platform).toLowerCase() === DatasetPlatform.HDFS;
// For HDFS drop leading slash
const hierarchy = isHdfs ? segments.split('/').slice(1) : segments.split('.');
return [platform, ...hierarchy].reduce((breadcrumbs, crumb, index) => {
const previousCrumb = breadcrumbs[index - 1];
// if hdfs, precede with slash, otherwise trailing period
const prefix = !index ? '' : isHdfs ? `${previousCrumb.prefix}/${crumb}` : `${previousCrumb.prefix}${crumb}.`;
return [
...breadcrumbs,
{
crumb,
prefix,
platform: <DatasetPlatform>platform
}
];
}, breadcrumbs);
}
return breadcrumbs;
};

View File

@ -1,3 +1,3 @@
import makeUrnBreadcrumbs from 'wherehows-web/utils/entities/make-urn-breadcrumbs';
import bakeUrnBreadcrumbs from 'wherehows-web/utils/entities/bake-urn-breadcrumbs';
export { makeUrnBreadcrumbs };
export { bakeUrnBreadcrumbs };

View File

@ -1,41 +0,0 @@
import { datasetUrnRegexWH } from 'wherehows-web/utils/validators/urn';
interface IBreadCrumb {
crumb: string;
urn: string;
}
/**
* Takes a urn string and parse it into an array of breadcrumb objects with crumb, and urn as
* properties.
* Hierarchy is implied in element ordering
* @param {String} urn
* @return {Array.<{crumb, urn}>|null}
*/
export default (urn: string): Array<{ crumb: string; urn: string }> | null => {
const urnMatch = datasetUrnRegexWH.exec(urn);
if (urnMatch) {
// Initial element in a match array from RegExp#exec is the full match, not needed here
const urnParts = urnMatch.filter((_match, index) => index);
// Splits the 2nd captured group into an array of urn names and spreads into a new list
const crumbs = [urnParts[0], ...urnParts[1].split('/')];
// Reduces the crumbs into a list of crumb names and urn paths
return crumbs.reduce(
(breadcrumbs, crumb, index) => {
const previousCrumb = breadcrumbs[index - 1];
const breadcrumb: IBreadCrumb = {
crumb,
// First item is root
urn: !index ? `${crumb}:///` : `${previousCrumb.urn}${crumb}/`
};
return [...breadcrumbs, breadcrumb];
},
<Array<IBreadCrumb>>[]
);
}
return null;
};

View File

@ -1,4 +1,8 @@
import { decodeUrn } from 'wherehows-web/utils/validators/urn';
const urn = 'urn:li:dataset:(urn:li:dataPlatform:hdfs,%2Fseg1s%2Fseg2%2Fseg3%2Fseg4%2Fdataset-node,PROD)';
const nonHdfsUrn = 'urn:li:dataset:(urn:li:dataPlatform:db,ABOOK.ABOOK_DATA,PROD)';
const hdfsUrn = decodeUrn(urn);
const whUrnToLiUrnMap = [
['espresso:///ETLInfra/AllTables', 'urn:li:dataset:(urn:li:dataPlatform:espresso,ETLInfra.AllTables,PROD)'],
@ -13,4 +17,4 @@ const whUrnToLiUrnMap = [
['oracle:///ABOOK/ABOOK_DATA', 'urn:li:dataset:(urn:li:dataPlatform:oracle,ABOOK.ABOOK_DATA,PROD)']
];
export { urn, whUrnToLiUrnMap };
export { urn, whUrnToLiUrnMap, hdfsUrn, nonHdfsUrn };

View File

@ -0,0 +1,56 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { hdfsUrn, nonHdfsUrn } from 'wherehows-web/mirage/fixtures/urn';
import { datasetUrnRegexLI } from 'wherehows-web/utils/validators/urn';
moduleForComponent('datasets/urn-breadcrumbs', 'Integration | Component | datasets/urn breadcrumbs', {
integration: true
});
const home = ['datasets'];
test('it renders only the home breadcrumb without a valid urn', function(assert) {
this.render(hbs`{{datasets/urn-breadcrumbs}}`);
const homeCrumb = document.querySelector('.nacho-breadcrumbs__crumb');
assert.equal(homeCrumb.textContent.trim(), 'datasets', 'shows the home breadcrumb');
assert.equal(
document.querySelectorAll('.nacho-breadcrumbs__crumb').length,
1,
'only one breadcrumb is rendered when a urn is not provided'
);
});
test('it renders breadcrumbs with a valid hdfs urn', function(assert) {
const [, platform, segments] = datasetUrnRegexLI.exec(hdfsUrn);
const segmentParts = segments.split('/').slice(1);
let crumbs;
this.set('urn', hdfsUrn);
this.render(hbs`{{datasets/urn-breadcrumbs urn=urn}}`);
crumbs = document.querySelectorAll('.nacho-breadcrumbs__crumb');
assert.equal(crumbs.length, home.length + [platform].length + segmentParts.length, '');
[...home, platform, ...segmentParts].forEach((node, index) =>
assert.equal(node, crumbs[index].textContent.trim(), `breadcrumb ${index} has expected text ${node}`)
);
});
test('it renders breadcrumbs with a valid non hdfs urn', function(assert) {
const [, platform, segments] = datasetUrnRegexLI.exec(nonHdfsUrn);
const segmentParts = segments.split('.');
let crumbs;
this.set('urn', nonHdfsUrn);
this.render(hbs`{{datasets/urn-breadcrumbs urn=urn}}`);
crumbs = document.querySelectorAll('.nacho-breadcrumbs__crumb');
assert.equal(crumbs.length, home.length + [platform].length + segmentParts.length, '');
[...home, platform, ...segmentParts].forEach((node, index) =>
assert.equal(node, crumbs[index].textContent.trim(), `breadcrumb ${index} has expected text ${node}`)
);
});