mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-25 16:05:11 +00:00
166 lines
4.9 KiB
TypeScript
166 lines
4.9 KiB
TypeScript
import Component from '@ember/component';
|
|
import { get, set } from '@ember/object';
|
|
import { computed } from '@ember/object';
|
|
import { capitalize } from '@ember/string';
|
|
import { arrayMap } from 'wherehows-web/utils/array';
|
|
import {
|
|
ISearchFacet,
|
|
ISearchFacetOption,
|
|
IFacetsSelectionsMap,
|
|
IFacetsCounts
|
|
} from '@datahub/data-models/types/entity/facets';
|
|
import { task } from 'ember-concurrency';
|
|
import { ISearchEntityRenderProps } from '@datahub/data-models/types/entity/rendering/search-entity-render-prop';
|
|
import { DatasetPlatform } from '@datahub/metadata-types/constants/entity/dataset/platform';
|
|
import { IDataPlatform } from '@datahub/metadata-types/types/entity/dataset/platform';
|
|
import { readDataPlatforms } from '@datahub/data-models/api/dataset/platforms';
|
|
import { ETaskPromise } from '@datahub/utils/types/concurrency';
|
|
|
|
/**
|
|
* Container component for search facets
|
|
* It will store state related to search facets.
|
|
*/
|
|
export default class SearchFacetsContainer extends Component {
|
|
didInsertElement(): void {
|
|
this.getPlatformsTask.perform();
|
|
}
|
|
|
|
/**
|
|
* Lists data platforms available to restrict search results by source
|
|
* @type {Array<DatasetPlatform>}
|
|
* @private
|
|
*/
|
|
_sources: Array<DatasetPlatform> = [];
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Fields available. We will read this to see what facets do we have available
|
|
*/
|
|
fields: Array<ISearchEntityRenderProps> = [];
|
|
|
|
/**
|
|
* Gets the available platforms and extracts a list of dataset sources
|
|
* @returns {IterableIterator<Promise<Array<IDataPlatform>>>}
|
|
* @memberof SearchFacetsContainer
|
|
*/
|
|
@task(function*(this: SearchFacetsContainer): IterableIterator<Promise<Array<IDataPlatform>>> {
|
|
const platforms: Array<IDataPlatform> = yield readDataPlatforms();
|
|
const getDatasetPlatform = ({ name }: IDataPlatform): DatasetPlatform => name;
|
|
const dataPlatforms = arrayMap(getDatasetPlatform)(platforms);
|
|
|
|
get(this, '_sources').setObjects(dataPlatforms);
|
|
})
|
|
getPlatformsTask!: ETaskPromise<Array<IDataPlatform>>;
|
|
|
|
/**
|
|
* 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),
|
|
count: 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a list of options with radio props for the data platforms that can be selected as a search filter
|
|
* @type {(ComputedProperty<Array<ISearchSourceOption>>}
|
|
*/
|
|
@computed('_sources.[]', 'counts')
|
|
get sources(): Array<ISearchFacetOption> {
|
|
return this._sources.map((source): ISearchFacetOption => this.stringToFacetOption(source));
|
|
}
|
|
|
|
/**
|
|
* Facets that are available right now.
|
|
* In the future, it should be fetched from the backend
|
|
*/
|
|
@computed('counts', 'fields')
|
|
get facets(): Array<ISearchFacet> {
|
|
const counts: IFacetsCounts = this.counts || {};
|
|
const facets: Array<ISearchFacet> = this.fields
|
|
.filterBy('showInFacets')
|
|
.map(
|
|
(field): ISearchFacet => {
|
|
const fieldCounts = counts[field.fieldName] || {};
|
|
return {
|
|
name: field.fieldName,
|
|
displayName: field.displayName,
|
|
values: Object.keys(fieldCounts)
|
|
.map(
|
|
(value): ISearchFacetOption => ({
|
|
...this.stringToFacetOption(value),
|
|
count: fieldCounts[value]
|
|
})
|
|
)
|
|
.sortBy('count')
|
|
.reverse()
|
|
};
|
|
}
|
|
)
|
|
.filter((field): boolean => field.values.length > 0);
|
|
|
|
return facets;
|
|
}
|
|
|
|
/**
|
|
* External closure action that triggers when facet changes
|
|
* @param _ Facet Selections
|
|
*/
|
|
onFacetsChange(_: IFacetsSelectionsMap): void {
|
|
//nothing
|
|
}
|
|
|
|
/**
|
|
* 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): void {
|
|
const currentFacetValues = this.selections[facet.name] || {};
|
|
set(this, 'selections', {
|
|
...this.selections,
|
|
[facet.name]: {
|
|
...currentFacetValues,
|
|
[facetValue.value]: !currentFacetValues[facetValue.value]
|
|
}
|
|
});
|
|
this.onFacetsChange(this.selections);
|
|
}
|
|
|
|
/**
|
|
* When the user clear the facet
|
|
* @param facet the facet that the user selects
|
|
*/
|
|
onFacetClear(facet: ISearchFacet): void {
|
|
set(this, 'selections', {
|
|
...this.selections,
|
|
[facet.name]: {}
|
|
});
|
|
this.onFacetsChange(this.selections);
|
|
}
|
|
}
|