2018-09-12 18:22:12 -07:00
|
|
|
import Component from '@ember/component';
|
|
|
|
|
import { get } from '@ember/object';
|
|
|
|
|
import { computed } from '@ember-decorators/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';
|
2018-09-14 16:40:45 -07:00
|
|
|
import { IFacetsSelectionsMap, IFacetsCounts } from 'wherehows-web/utils/api/search';
|
2018-09-12 18:22:12 -07:00
|
|
|
|
|
|
|
|
/**
|
2018-09-14 16:40:45 -07:00
|
|
|
* Options inside a facet
|
|
|
|
|
* @interface ISearchFacetOption
|
2018-09-12 18:22:12 -07:00
|
|
|
*/
|
2018-09-14 16:40:45 -07:00
|
|
|
interface ISearchFacetOption {
|
2018-09-12 18:22:12 -07:00
|
|
|
value: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* Interface of a facet
|
|
|
|
|
*/
|
|
|
|
|
interface ISearchFacet {
|
|
|
|
|
name: string;
|
|
|
|
|
displayName: string;
|
|
|
|
|
values: Array<ISearchFacetOption>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Container component for search facets
|
|
|
|
|
* It will store state related to search facets.
|
|
|
|
|
*/
|
2018-09-12 18:22:12 -07:00
|
|
|
export default class SearchFacetsContainer extends Component {
|
|
|
|
|
didInsertElement(this: SearchFacetsContainer) {
|
|
|
|
|
get(this, 'getPlatformsTask').perform();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The current source to narrow search results to
|
|
|
|
|
* @type {DatasetPlatform}
|
|
|
|
|
*/
|
2018-09-13 18:24:05 -07:00
|
|
|
currentSource: string;
|
2018-09-12 18:22:12 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Lists data platforms available to restrict search results by source
|
|
|
|
|
* @type {Array<DatasetPlatform>}
|
|
|
|
|
* @private
|
|
|
|
|
*/
|
|
|
|
|
_sources: Array<DatasetPlatform> = [];
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* Current state of selections of facets
|
|
|
|
|
* EI:
|
|
|
|
|
* {
|
|
|
|
|
* source: {
|
|
|
|
|
* hdfs: true
|
|
|
|
|
* },
|
|
|
|
|
* fabric: {
|
|
|
|
|
* corp: true,
|
|
|
|
|
* prod: true
|
|
|
|
|
* }
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
selections: IFacetsSelectionsMap;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Counts for the facets in a similar fashion of selections
|
|
|
|
|
*/
|
|
|
|
|
counts: IFacetsCounts;
|
|
|
|
|
|
2018-09-12 18:22:12 -07:00
|
|
|
/**
|
|
|
|
|
* 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: SearchFacetsContainer): 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);
|
|
|
|
|
});
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* I will convert a string into a facet option with counts
|
|
|
|
|
* @param facetValue
|
|
|
|
|
* @param facetName
|
|
|
|
|
*/
|
|
|
|
|
stringToFacetOption(facetValue: string): ISearchFacetOption {
|
|
|
|
|
return {
|
|
|
|
|
value: facetValue,
|
|
|
|
|
label: capitalize(facetValue)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-12 18:22:12 -07:00
|
|
|
/**
|
|
|
|
|
* Creates a list of options with radio props for the data platforms that can be selected as a search filter
|
|
|
|
|
* @type {(ComputedProperty<Array<ISearchSourceOption>>}
|
|
|
|
|
*/
|
2018-09-14 16:40:45 -07:00
|
|
|
@computed('_sources.[]', 'counts')
|
|
|
|
|
get sources(this: SearchFacetsContainer): Array<ISearchFacetOption> {
|
|
|
|
|
return this._sources.map(source => this.stringToFacetOption(source));
|
2018-09-12 18:22:12 -07:00
|
|
|
}
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* Facets that are available right now.
|
|
|
|
|
* In the future, it should be fetched from the backend
|
|
|
|
|
*/
|
|
|
|
|
@computed('sources', 'counts')
|
|
|
|
|
get facets(): Array<ISearchFacet> {
|
2018-09-12 18:22:12 -07:00
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
name: 'fabric',
|
|
|
|
|
displayName: 'Fabrics',
|
2018-09-14 16:40:45 -07:00
|
|
|
values: ['prod', 'corp', 'ei', 'dev'].map(fabric => this.stringToFacetOption(fabric))
|
2018-09-12 18:22:12 -07:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'source',
|
|
|
|
|
displayName: 'Data Platform',
|
2018-09-14 13:30:53 -07:00
|
|
|
values: this.sources
|
2018-09-12 18:22:12 -07:00
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* External closure action that triggers when facet changes
|
|
|
|
|
* @param _ Facet Selections
|
|
|
|
|
*/
|
|
|
|
|
onFacetsChange(_: IFacetsSelectionsMap) {
|
2018-09-13 18:24:05 -07:00
|
|
|
//nothing
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* Internal action triggered when facet changes. It will update
|
|
|
|
|
* the state of selections in a redux fashion.
|
|
|
|
|
* @param facet The facet that changed
|
|
|
|
|
* @param facetValue the option of the facet that changed
|
|
|
|
|
*/
|
|
|
|
|
onFacetChange(facet: ISearchFacet, facetValue: ISearchFacetOption) {
|
2018-09-12 18:22:12 -07:00
|
|
|
const currentFacetValues = this.selections[facet.name] || {};
|
|
|
|
|
this.set('selections', {
|
|
|
|
|
...this.selections,
|
|
|
|
|
[facet.name]: {
|
|
|
|
|
...currentFacetValues,
|
|
|
|
|
[facetValue.value]: !currentFacetValues[facetValue.value]
|
|
|
|
|
}
|
|
|
|
|
});
|
2018-09-13 18:24:05 -07:00
|
|
|
this.onFacetsChange(this.selections);
|
2018-09-12 18:22:12 -07:00
|
|
|
}
|
|
|
|
|
|
2018-09-14 16:40:45 -07:00
|
|
|
/**
|
|
|
|
|
* When the user clear the facet
|
|
|
|
|
* @param facet the facet that the user selects
|
|
|
|
|
*/
|
2018-09-14 16:59:57 -07:00
|
|
|
onFacetClear(facet: ISearchFacet) {
|
2018-09-12 18:22:12 -07:00
|
|
|
this.set('selections', {
|
|
|
|
|
...this.selections,
|
|
|
|
|
[facet.name]: {}
|
|
|
|
|
});
|
2018-09-13 18:24:05 -07:00
|
|
|
this.onFacetsChange(this.selections);
|
2018-09-12 18:22:12 -07:00
|
|
|
}
|
|
|
|
|
}
|