mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-27 18:45:50 +00:00
creates container component for search sources. refactors search controller
This commit is contained in:
parent
a0e8eef9a7
commit
035ea922ae
@ -0,0 +1,68 @@
|
|||||||
|
import Component from '@ember/component';
|
||||||
|
import { get, computed } from '@ember/object';
|
||||||
|
import { capitalize } from '@ember/string';
|
||||||
|
import { task } from 'ember-concurrency';
|
||||||
|
import { DatasetPlatform } from 'wherehows-web/constants';
|
||||||
|
import { IDataPlatform } from 'wherehows-web/typings/api/list/platforms';
|
||||||
|
import { readPlatforms } from 'wherehows-web/utils/api/list/platforms';
|
||||||
|
import { arrayMap } from 'wherehows-web/utils/array';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the interface of the object passed as radio option for source
|
||||||
|
* @interface ISearchSourceOption
|
||||||
|
*/
|
||||||
|
interface ISearchSourceOption {
|
||||||
|
name: 'source';
|
||||||
|
value: DatasetPlatform;
|
||||||
|
label: string;
|
||||||
|
group: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class SearchSourcesContainer extends Component {
|
||||||
|
didInsertElement(this: SearchSourcesContainer) {
|
||||||
|
get(this, 'getPlatformsTask').perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current source to narrow search results to
|
||||||
|
* @type {DatasetPlatform}
|
||||||
|
*/
|
||||||
|
currentSource: DatasetPlatform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists data platforms available to restrict search results by source
|
||||||
|
* @type {Array<DatasetPlatform>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_sources: Array<DatasetPlatform> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the available platforms and extracts a list of dataset sources
|
||||||
|
* @type {(Task<Promise<Array<IDataPlatform>>, (a?: any) => TaskInstance<Promise<Array<IDataPlatform>>>>)}
|
||||||
|
*/
|
||||||
|
getPlatformsTask = task(function*(this: SearchSourcesContainer): IterableIterator<Promise<Array<IDataPlatform>>> {
|
||||||
|
const platforms: Array<IDataPlatform> = yield readPlatforms();
|
||||||
|
const getDatasetPlatform = ({ name }: IDataPlatform): DatasetPlatform => name;
|
||||||
|
const dataPlatforms = arrayMap(getDatasetPlatform)(platforms);
|
||||||
|
|
||||||
|
get(this, '_sources').setObjects(dataPlatforms);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a list of options with radio props for the data platforms that can be selected as a search filter
|
||||||
|
* @type {(ComputedProperty<Array<ISearchSourceOption>>}
|
||||||
|
*/
|
||||||
|
sources = computed('currentSource', '_sources.[]', function(
|
||||||
|
this: SearchSourcesContainer
|
||||||
|
): Array<ISearchSourceOption> {
|
||||||
|
const allSource = <DatasetPlatform>'all';
|
||||||
|
const sourceAsOption = (source: DatasetPlatform): ISearchSourceOption => ({
|
||||||
|
name: 'source',
|
||||||
|
value: source,
|
||||||
|
label: capitalize(source),
|
||||||
|
group: String(get(this, 'currentSource')).toLowerCase()
|
||||||
|
});
|
||||||
|
|
||||||
|
return arrayMap(sourceAsOption)([allSource, ...get(this, '_sources')]);
|
||||||
|
});
|
||||||
|
}
|
@ -1,55 +1,10 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
import { computed, set, get } from '@ember/object';
|
import { computed, set, get } from '@ember/object';
|
||||||
import { capitalize } from '@ember/string';
|
import { capitalize } from '@ember/string';
|
||||||
|
import { action } from 'ember-decorators/object';
|
||||||
|
|
||||||
const sources = ['all', 'dali', 'espresso', 'hive', 'hdfs', 'kafka', 'oracle', 'teradata', 'voldemort'];
|
// gradual refactor into es class, hence extends EmberObject instance
|
||||||
|
export default class Search extends Controller.extend({
|
||||||
export default Controller.extend({
|
|
||||||
queryParams: ['keyword', 'category', 'source', 'page'],
|
|
||||||
keyword: '',
|
|
||||||
category: 'datasets',
|
|
||||||
source: 'all',
|
|
||||||
page: 1,
|
|
||||||
header: 'Refine By',
|
|
||||||
|
|
||||||
sources: computed('source', function() {
|
|
||||||
return sources.map(source => ({
|
|
||||||
name: 'source',
|
|
||||||
value: source,
|
|
||||||
label: capitalize(source),
|
|
||||||
group: String(get(this, 'source')).toLowerCase()
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
|
|
||||||
isMetric: false,
|
|
||||||
|
|
||||||
datasetTitle: computed('model.source', function() {
|
|
||||||
var model = this.get('model');
|
|
||||||
if (model && model.source) {
|
|
||||||
if (model.source.toLocaleLowerCase() != 'all') {
|
|
||||||
return model.source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'Datasets';
|
|
||||||
}),
|
|
||||||
isDatasets: computed('model.category', function() {
|
|
||||||
var model = this.get('model');
|
|
||||||
if (model && model.category) {
|
|
||||||
if (model.category.toLocaleLowerCase() === 'datasets') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}),
|
|
||||||
isComments: computed('model.category', function() {
|
|
||||||
var model = this.get('model');
|
|
||||||
if (model && model.category) {
|
|
||||||
if (model.category.toLocaleLowerCase() === 'comments') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}),
|
|
||||||
isMetrics: computed('model.category', function() {
|
isMetrics: computed('model.category', function() {
|
||||||
var model = this.get('model');
|
var model = this.get('model');
|
||||||
if (model && model.category) {
|
if (model && model.category) {
|
||||||
@ -59,24 +14,7 @@ export default Controller.extend({
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}),
|
}),
|
||||||
isFlows: computed('model.category', function() {
|
|
||||||
var model = this.get('model');
|
|
||||||
if (model && model.category) {
|
|
||||||
if (model.category.toLocaleLowerCase() === 'flows') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}),
|
|
||||||
isJobs: computed('model.category', function() {
|
|
||||||
var model = this.get('model');
|
|
||||||
if (model && model.category) {
|
|
||||||
if (model.category.toLocaleLowerCase() === 'jobs') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}),
|
|
||||||
previousPage: computed('model.page', function() {
|
previousPage: computed('model.page', function() {
|
||||||
var model = this.get('model');
|
var model = this.get('model');
|
||||||
if (model && model.page) {
|
if (model && model.page) {
|
||||||
@ -130,19 +68,47 @@ export default Controller.extend({
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
}) {
|
||||||
|
queryParams = ['keyword', 'category', 'source', 'page'];
|
||||||
|
|
||||||
actions: {
|
/**
|
||||||
sourceDidChange(groupName, value) {
|
* Search keyword to look for
|
||||||
set(this, groupName, value);
|
* @type {string}
|
||||||
},
|
*/
|
||||||
|
keyword = '';
|
||||||
|
|
||||||
startDateDidChange(date = null) {
|
/**
|
||||||
set(this, 'startDate', date);
|
* The category to narrow/ filter search results
|
||||||
},
|
* @type {string}
|
||||||
|
*/
|
||||||
|
category = 'datasets';
|
||||||
|
|
||||||
endDateDidChange(date = null) {
|
/**
|
||||||
set(this, 'endDate', date);
|
* Dataset Platform to restrict search results to
|
||||||
}
|
* @type {'all'|DatasetPlatform}
|
||||||
|
*/
|
||||||
|
source = 'all';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current search page
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
page = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header text for search sidebar
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
header = 'Refine By';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the response to changing the source platform to search through
|
||||||
|
* @param _groupName is radioGroup name i.e. binding to Search.source
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
@action
|
||||||
|
sourceDidChange(_groupName, value) {
|
||||||
|
set(this, 'source', value);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
{{#if getPlatformsTask.isRunning}}
|
||||||
|
{{pendulum-ellipsis-animation}}
|
||||||
|
{{else}}
|
||||||
|
{{yield (hash radioSources=sources)}}
|
||||||
|
{{/if}}
|
@ -1,10 +1,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3 wh-sidebar">
|
<div class="col-md-3 wh-sidebar">
|
||||||
{{#search/filter-rail header=header as |rail|}}
|
{{#search/filter-rail header=header as |rail|}}
|
||||||
{{rail.radioGroup
|
|
||||||
radioOptions=sources
|
{{#search/containers/search-sources currentSource=source as |searchSource|}}
|
||||||
title="Source"
|
{{rail.radioGroup
|
||||||
changed=(action "sourceDidChange")}}
|
radioOptions=searchSource.radioSources
|
||||||
|
title="Source"
|
||||||
|
changed=(action "sourceDidChange")}}
|
||||||
|
{{/search/containers/search-sources}}
|
||||||
|
|
||||||
{{!--Api for date range not currently available--}}
|
{{!--Api for date range not currently available--}}
|
||||||
{{!--rail.dateRange
|
{{!--rail.dateRange
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
import { moduleForComponent, test } from 'ember-qunit';
|
||||||
|
import hbs from 'htmlbars-inline-precompile';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import { waitUntil, find } from 'ember-native-dom-helpers';
|
||||||
|
|
||||||
|
const platformsResponse = {
|
||||||
|
platforms: [
|
||||||
|
{
|
||||||
|
name: 'platform1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'platform2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
moduleForComponent('search/containers/search-sources', 'Integration | Component | search/containers/search sources', {
|
||||||
|
integration: true,
|
||||||
|
|
||||||
|
beforeEach() {
|
||||||
|
this.server = sinon.createFakeServer();
|
||||||
|
this.server.respondImmediately = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
afterEach() {
|
||||||
|
this.server.restore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it renders', async function(assert) {
|
||||||
|
this.server.respondWith('GET', /\/api\/v2\/list\/platforms/, [
|
||||||
|
200,
|
||||||
|
{ 'Content-Type': 'application/json' },
|
||||||
|
JSON.stringify(platformsResponse)
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#search/containers/search-sources}}
|
||||||
|
<div class="inner-content">Yielded Content</div>
|
||||||
|
{{/search/containers/search-sources}}
|
||||||
|
`);
|
||||||
|
|
||||||
|
await waitUntil(() => find('.inner-content'));
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
this.$()
|
||||||
|
.text()
|
||||||
|
.trim(),
|
||||||
|
'Yielded Content',
|
||||||
|
'inner content is rendered'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Platform sources yielded', async function(assert) {
|
||||||
|
this.server.respondWith('GET', /\/api\/v2\/list\/platforms/, [
|
||||||
|
200,
|
||||||
|
{ 'Content-Type': 'application/json' },
|
||||||
|
JSON.stringify(platformsResponse)
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#search/containers/search-sources as |container|}}
|
||||||
|
<span class="inner-content">
|
||||||
|
{{#each container.radioSources as |source|}}
|
||||||
|
{{source.value}}
|
||||||
|
{{/each}}
|
||||||
|
</span>
|
||||||
|
{{/search/containers/search-sources}}
|
||||||
|
`);
|
||||||
|
|
||||||
|
await waitUntil(() => find('.inner-content'));
|
||||||
|
|
||||||
|
const text = document.querySelector('.inner-content').textContent.trim();
|
||||||
|
assert.ok(
|
||||||
|
['all', 'platform1', 'platform2'].reduce((acc, curr) => acc && text.includes(curr), true),
|
||||||
|
'it yields platform sources and `all`'
|
||||||
|
);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user