diff --git a/frontend/src/js/component/wb-project-crumbs.js b/frontend/src/js/component/wb-project-crumbs.js
new file mode 100644
index 0000000..41a74e1
--- /dev/null
+++ b/frontend/src/js/component/wb-project-crumbs.js
@@ -0,0 +1,34 @@
+import { h, Component } from 'preact';
+import WBBreadcrumbs from 'wb-breadcrumbs';
+import fetchProjectParents from 'fetch-project-parents';
+
+class WBProjectCrumbs extends Component {
+ constructor(...args) {
+ super(...args);
+ this.state.items = [];
+ }
+
+ fetchCrumbs() {
+ let { arvHost, arvToken } = this.props.appState;
+ let prom = fetchProjectParents(arvHost, arvToken, this.props.uuid);
+ prom = prom.then(parents => this.setState({ 'items': parents }));
+ }
+
+ componentDidMount() {
+ this.fetchCrumbs();
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.props = nextProps;
+ this.fetchCrumbs();
+ }
+
+ render({ onItemClicked }, { items }) {
+ return (
+
+ );
+ }
+}
+
+export default WBProjectCrumbs;
diff --git a/frontend/src/js/misc/fetch-project-parents.js b/frontend/src/js/misc/fetch-project-parents.js
new file mode 100644
index 0000000..57127bd
--- /dev/null
+++ b/frontend/src/js/misc/fetch-project-parents.js
@@ -0,0 +1,43 @@
+import makeArvadosRequest from 'make-arvados-request';
+
+function fetchProjectParents(arvHost, arvToken, uuid) {
+ let parents = [];
+
+ let cb = xhr => {
+ let objectType = xhr.response['uuid'].split('-')[1];
+
+ if (objectType === 'tpzed') {
+ let name = xhr.response['first_name'] + ' ' + xhr.response['last_name'];
+ parents.push({ 'name': name, 'uuid': xhr.response['uuid'] });
+ } else {
+ parents.push({ 'name': xhr.response['name'],
+ 'uuid': xhr.response['uuid'] });
+ }
+
+ if (!xhr.response['owner_uuid'] ||
+ xhr.response['owner_uuid'].endsWith('-tpzed-000000000000000')) {
+
+ return parents.reverse();
+ }
+
+ objectType = xhr.response['owner_uuid'].split('-')[1];
+
+ if (objectType === 'tpzed') {
+ return makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/users/' + xhr.response['owner_uuid']).then(cb);
+
+ } else {
+ return makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/groups/' + xhr.response['owner_uuid']).then(cb);
+ }
+ };
+
+ let objectType = uuid.split('-')[1];
+ let prom = makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/' + (objectType === 'tpzed' ? 'users' : 'groups') + '/' + uuid);
+ prom = prom.then(cb);
+
+ return prom;
+}
+
+export default fetchProjectParents;
diff --git a/frontend/src/js/page/wb-app.js b/frontend/src/js/page/wb-app.js
index 54f305e..2a95d2e 100644
--- a/frontend/src/js/page/wb-app.js
+++ b/frontend/src/js/page/wb-app.js
@@ -12,6 +12,10 @@ class WBApp extends Component {
this.appCallbacks = {
'navbarItemClicked': this.navbarItemClicked
};
+ this.appState = {
+ 'arvHost': this.state.arvHost,
+ 'arvToken': this.state.arvToken
+ };
}
navbarItemClicked(item) {
@@ -23,14 +27,16 @@ class WBApp extends Component {
}
}
- render({}, { activePage, arvHost, arvToken }) {
+ render() {
return (
-
+
);
}
diff --git a/frontend/src/js/page/wb-browse.js b/frontend/src/js/page/wb-browse.js
index f14e59b..a9f754f 100644
--- a/frontend/src/js/page/wb-browse.js
+++ b/frontend/src/js/page/wb-browse.js
@@ -3,9 +3,10 @@ import { route } from 'preact-router';
import WBNavbar from 'wb-navbar';
import WBProjectListing from 'wb-project-listing';
import WBInlineSearch from 'wb-inline-search';
+import WBProjectCrumbs from 'wb-project-crumbs';
class WBBrowse extends Component {
- render({ ownerUuid, activePage, appCallbacks }) {
+ render({ ownerUuid, activePage, appCallbacks, appState }) {
return (