mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-31 12:52:13 +00:00
Merge pull request #961 from theseyi/tabbed-routes
implements tabbed routes for datasets
This commit is contained in:
commit
068cf873ba
52
wherehows-web/app/constants/datasets/shared.ts
Normal file
52
wherehows-web/app/constants/datasets/shared.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { assert } from '@ember/debug';
|
||||
import { set } from '@ember/object';
|
||||
import DatasetController from 'wherehows-web/controllers/datasets/dataset';
|
||||
|
||||
/**
|
||||
* Defines id strings for page tabs available on the dataset page,
|
||||
* these also match up with their respective route names
|
||||
* @type {string}
|
||||
*/
|
||||
enum Tabs {
|
||||
Properties = 'properties',
|
||||
Access = 'access',
|
||||
Comments = 'comments',
|
||||
Schema = 'schema',
|
||||
Ownership = 'ownership',
|
||||
Compliance = 'compliance',
|
||||
SampleData = 'sample',
|
||||
Relations = 'relations'
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tab selection property on the provided route with the currently selected tab
|
||||
* @param {Route} route the route instance to update
|
||||
* @param {Tabs} tabSelected identifier for the selected tab
|
||||
* @returns {Tabs}
|
||||
*/
|
||||
const setTabSelectedOnAncestorController = (route: Route, tabSelected: Tabs): Tabs => {
|
||||
const { routeName, controllerFor } = route;
|
||||
assert('route should be a descendant of datasets.dataset', !routeName.indexOf('datasets.dataset.'));
|
||||
const ancestorController = <DatasetController>controllerFor.call(route, 'datasets.dataset');
|
||||
|
||||
return set(ancestorController, 'tabSelected', tabSelected);
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory creates a dataset Route class that sets the currently selected tab on the parent controller
|
||||
* @param {{ selectedTab: Tabs }} { selectedTab } options bag contains identifier for the current tab
|
||||
* @returns {typeof Route} the descendant route class
|
||||
*/
|
||||
const descendantDatasetRouteClassFactory = ({ selectedTab }: { selectedTab: Tabs }): typeof Route => {
|
||||
return class DatasetDescendantRoute extends Route {
|
||||
actions = {
|
||||
didTransition(this: DatasetDescendantRoute) {
|
||||
// on successful route transition
|
||||
setTabSelectedOnAncestorController(this, selectedTab);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export { Tabs, descendantDatasetRouteClassFactory, setTabSelectedOnAncestorController };
|
@ -14,10 +14,13 @@ import {
|
||||
import { updateDatasetDeprecation } from 'wherehows-web/utils/api/datasets/properties';
|
||||
import { readDatasetView } from 'wherehows-web/utils/api/datasets/dataset';
|
||||
import { readDatasetOwners, updateDatasetOwners } from 'wherehows-web/utils/api/datasets/owners';
|
||||
import { Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
import { action } from 'ember-decorators/object';
|
||||
|
||||
const { post, getJSON } = $;
|
||||
|
||||
export default Controller.extend({
|
||||
// gradual refactor into es class, hence extends EmberObject instance
|
||||
export default class extends Controller.extend({
|
||||
queryParams: ['urn'],
|
||||
/**
|
||||
* Reference to the application notifications Service
|
||||
@ -202,20 +205,6 @@ export default Controller.extend({
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* Renders the properties tab elements.
|
||||
* temporary workaround to query parameters, the file is a holdover from the legacy WH app
|
||||
*/
|
||||
showProperties() {
|
||||
// FIXME: this is a stop gap pending transition to queryParams tabbed nav in datasets.
|
||||
// :facepalm:
|
||||
run(() => {
|
||||
scheduleOnce('afterRender', null, () => {
|
||||
$('.tabbed-navigation-list li.active:not(#properties)').removeClass('active');
|
||||
$('.tabbed-navigation-list #properties').addClass('active');
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Updates the dataset's deprecation properties
|
||||
* @param {boolean} isDeprecated
|
||||
@ -334,4 +323,25 @@ export default Controller.extend({
|
||||
.catch(this.exceptionOnSave);
|
||||
}
|
||||
}
|
||||
});
|
||||
}) {
|
||||
tabIds = Tabs;
|
||||
|
||||
tabSelected;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.tabSelected || (this.tabSelected = Tabs.Ownership);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles user generated tab selection action by transitioning to specified route
|
||||
* @param {Tabs} tabSelected the currently selected tab
|
||||
*/
|
||||
@action
|
||||
tabSelectionChanged(tabSelected) {
|
||||
// if the tab selection is same as current, noop
|
||||
return get(this, 'tabSelected') === tabSelected
|
||||
? void 0
|
||||
: this.transitionToRoute(`datasets.dataset.${tabSelected}`, get(this, 'datasetId'));
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,21 @@ AppRouter.map(function() {
|
||||
path: '/*wildcard'
|
||||
});
|
||||
this.route('datasets', function() {
|
||||
this.route('dataset', {
|
||||
path: '/:dataset_id'
|
||||
});
|
||||
this.route(
|
||||
'dataset',
|
||||
{
|
||||
path: '/:dataset_id'
|
||||
},
|
||||
function() {
|
||||
this.route('properties');
|
||||
this.route('comments');
|
||||
this.route('schema');
|
||||
this.route('ownership');
|
||||
this.route('compliance');
|
||||
this.route('sample');
|
||||
this.route('relations');
|
||||
}
|
||||
);
|
||||
});
|
||||
this.route('search');
|
||||
this.route('metrics', function() {
|
||||
|
3
wherehows-web/app/routes/datasets/dataset/comments.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/comments.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Comments });
|
3
wherehows-web/app/routes/datasets/dataset/compliance.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/compliance.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Compliance });
|
3
wherehows-web/app/routes/datasets/dataset/ownership.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/ownership.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Ownership });
|
3
wherehows-web/app/routes/datasets/dataset/properties.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/properties.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Properties });
|
3
wherehows-web/app/routes/datasets/dataset/relations.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/relations.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Relations });
|
3
wherehows-web/app/routes/datasets/dataset/sample.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/sample.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.SampleData });
|
3
wherehows-web/app/routes/datasets/dataset/schema.ts
Normal file
3
wherehows-web/app/routes/datasets/dataset/schema.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { descendantDatasetRouteClassFactory, Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default descendantDatasetRouteClassFactory({ selectedTab: Tabs.Schema });
|
@ -29,7 +29,8 @@
|
||||
{{/if}}
|
||||
|
||||
{{#if datasetView.deprecated}}
|
||||
<a data-toggle="tab" href="#propertiestab" {{action "showProperties" preventDefault=false}}>
|
||||
{{#link-to "datasets.dataset.properties" datasetId}}
|
||||
|
||||
<span class="deprecated-dataset">
|
||||
DEPRECATED
|
||||
</span>
|
||||
@ -43,7 +44,8 @@
|
||||
}}
|
||||
</span>
|
||||
</sup>
|
||||
</a>
|
||||
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
|
||||
<h3>{{ model.name }}</h3>
|
||||
@ -152,32 +154,35 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#ivy-tabs selection=selection as |tabs|}}
|
||||
{{#ivy-tabs selection=tabSelected as |tabs|}}
|
||||
|
||||
{{#tabs.tablist as |tablist|}}
|
||||
|
||||
{{#unless isPinot}}
|
||||
{{#tablist.tab "Properties" on-select=(action (mut selection))}}Properties{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.Properties on-select=(action "tabSelectionChanged")}}
|
||||
Properties
|
||||
{{/tablist.tab}}
|
||||
{{/unless}}
|
||||
|
||||
{{!--feature not available--}}
|
||||
<span style="display:none">
|
||||
{{#tablist.tab "Access" on-select=(action (mut selection))}}ACL Access{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.Access on-select=(action "tabSelectionChanged")}}ACL Access{{/tablist.tab}}
|
||||
</span>
|
||||
|
||||
{{#tablist.tab "Comments" on-select=(action (mut selection))}}Comments{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.Comments on-select=(action "tabSelectionChanged")}}Comments{{/tablist.tab}}
|
||||
|
||||
{{#tablist.tab "Schema" on-select=(action (mut selection))}}Schema{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.Schema on-select=(action "tabSelectionChanged")}}Schema{{/tablist.tab}}
|
||||
|
||||
{{#tablist.tab "Ownership" on-select=(action (mut selection))}}
|
||||
{{#tablist.tab tabIds.Ownership on-select=(action "tabSelectionChanged")}}
|
||||
Ownership
|
||||
|
||||
{{#if requiredMinNotConfirmed}}
|
||||
<span class="notification-dot notification-dot--on-tab" aria-hidden="true"></span>
|
||||
{{/if}}
|
||||
{{/tablist.tab}}
|
||||
|
||||
{{#if isInternal}}
|
||||
{{#tablist.tab "Compliance" on-select=(action (mut selection))}}
|
||||
{{#tablist.tab tabIds.Compliance on-select=(action "tabSelectionChanged")}}
|
||||
Compliance
|
||||
|
||||
{{#if isNewComplianceInfo}}
|
||||
@ -187,14 +192,16 @@
|
||||
{{/if}}
|
||||
|
||||
{{#unless isSFDC}}
|
||||
{{#tablist.tab "Sample Data" on-select=(action (mut selection))}}Sample Data{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.SampleData on-select=(action "tabSelectionChanged")}}
|
||||
Sample Data{{/tablist.tab}}
|
||||
{{/unless}}
|
||||
|
||||
{{#tablist.tab "Relations" on-select=(action (mut selection))}}Relations{{/tablist.tab}}
|
||||
{{#tablist.tab tabIds.Relations on-select=(action "tabSelectionChanged")}}
|
||||
Relations{{/tablist.tab}}
|
||||
|
||||
{{/tabs.tablist}}
|
||||
|
||||
{{#tabs.tabpanel "Properties"}}
|
||||
{{#tabs.tabpanel tabIds.Properties}}
|
||||
{{#unless isPinot}}
|
||||
{{dataset-deprecation
|
||||
deprecated=datasetView.deprecated
|
||||
@ -206,7 +213,7 @@
|
||||
{{/unless}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Comments"}}
|
||||
{{#tabs.tabpanel tabIds.Comments}}
|
||||
{{dataset-comments
|
||||
comments=datasetComments
|
||||
updateDatasetComment=(action "updateDatasetComment")
|
||||
@ -215,7 +222,7 @@
|
||||
}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Schema"}}
|
||||
{{#tabs.tabpanel tabIds.Schema}}
|
||||
{{dataset-schema
|
||||
isTable=isTable
|
||||
json=model.schema
|
||||
@ -223,7 +230,7 @@
|
||||
}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Ownership"}}
|
||||
{{#tabs.tabpanel tabIds.Ownership}}
|
||||
{{dataset-authors
|
||||
owners=owners
|
||||
ownerTypes=ownerTypes
|
||||
@ -231,19 +238,19 @@
|
||||
}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Sample Data"}}
|
||||
{{#tabs.tabpanel tabIds.SampleData}}
|
||||
{{#unless isSFDC}}
|
||||
{{dataset-sample hasSamples=hasSamples isPinot=isPinot columns=columns samples=samples}}
|
||||
{{/unless}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Relations"}}
|
||||
{{#tabs.tabpanel tabIds.Relations}}
|
||||
{{#unless isSFDC}}
|
||||
{{dataset-relations hasDepends=hasDepends depends=depends hasReferences=hasReferences references=references}}
|
||||
{{/unless}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Compliance"}}
|
||||
{{#tabs.tabpanel tabIds.Compliance}}
|
||||
{{dataset-compliance
|
||||
datasetName=model.name
|
||||
schemaless=schemaless
|
||||
@ -258,7 +265,7 @@
|
||||
}}
|
||||
{{/tabs.tabpanel}}
|
||||
|
||||
{{#tabs.tabpanel "Access"}}
|
||||
{{#tabs.tabpanel tabIds.Access}}
|
||||
{{dataset-aclaccess
|
||||
accessInfo=aclAccessResponse
|
||||
currentUser=currentUserInfo
|
||||
|
@ -25,6 +25,14 @@ declare module 'ember-simple-auth/services/session' {
|
||||
}
|
||||
|
||||
declare module 'wherehows-web/utils/datasets/compliance-policy';
|
||||
declare module 'wherehows-web/controllers/datasets/dataset' {
|
||||
import Controller from '@ember/controller';
|
||||
import { Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
|
||||
export default class extends Controller {
|
||||
tabSelected: Tabs;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'ember-cli-mirage';
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { test } from 'qunit';
|
||||
import { delay } from 'wherehows-web/utils/promise-delay';
|
||||
import moduleForAcceptance from 'wherehows-web/tests/helpers/module-for-acceptance';
|
||||
import { authenticationUrl, testUser, testPassword } from 'wherehows-web/tests/helpers/login/constants';
|
||||
import {
|
||||
@ -8,7 +7,7 @@ import {
|
||||
loginSubmitButton
|
||||
} from 'wherehows-web/tests/helpers/login/page-element-constants';
|
||||
|
||||
moduleForAcceptance('Acceptance | login', {
|
||||
moduleForAcceptance('Acceptance | browse', {
|
||||
beforeEach() {
|
||||
visit(authenticationUrl);
|
||||
fillIn(loginUserInput, testUser);
|
||||
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/comments', 'Unit | Route | datasets/dataset/comments', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/compliance', 'Unit | Route | datasets/dataset/compliance', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/ownership', 'Unit | Route | datasets/dataset/ownership', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/properties', 'Unit | Route | datasets/dataset/properties', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/relations', 'Unit | Route | datasets/dataset/relations', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/sample', 'Unit | Route | datasets/dataset/sample', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { moduleFor, test } from 'ember-qunit';
|
||||
|
||||
moduleFor('route:datasets/dataset/schema', 'Unit | Route | datasets/dataset/schema', {
|
||||
needs: ['service:metrics']
|
||||
});
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.subject();
|
||||
assert.ok(route);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user