mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-02 03:39:03 +00:00
184 lines
6.8 KiB
TypeScript
184 lines
6.8 KiB
TypeScript
import Component from '@ember/component';
|
|
import { IHealthScore } from 'wherehows-web/typings/api/datasets/health';
|
|
import { computed, setProperties, getProperties, get } from '@ember/object';
|
|
import ComputedProperty from '@ember/object/computed';
|
|
import { IDropDownOption } from 'wherehows-web/typings/app/dataset-compliance';
|
|
import { noop } from 'wherehows-web/utils/helpers/functions';
|
|
import { capitalize } from '@ember/string';
|
|
import { HealthDataFields } from 'wherehows-web/components/datasets/containers/dataset-health';
|
|
|
|
/**
|
|
* Adds properties specifically to help the table render each row to the basic health score
|
|
*/
|
|
interface IRenderedHealthScore extends IHealthScore {
|
|
highlightClass: string;
|
|
isHidden: boolean;
|
|
}
|
|
|
|
/**
|
|
* Properties that define a useful header object to be rendered in the template
|
|
*/
|
|
interface IHealthTableHeader {
|
|
label: string;
|
|
class: string;
|
|
dropdownOptions: Array<IDropDownOption<string>> | undefined;
|
|
initialDropdown: IDropDownOption<string>;
|
|
onDropdownSelect: (type: string, selection: IDropDownOption<string>) => void;
|
|
}
|
|
|
|
/**
|
|
* Defining a loose interface for the dropdowns object calculated for category and severity based on
|
|
* the received table data
|
|
*/
|
|
interface IHealthTableDropdowns {
|
|
[key: string]: Array<IDropDownOption<string>>;
|
|
}
|
|
|
|
export default class DatasetsHealthScoreTable extends Component {
|
|
/**
|
|
* Sets the class names binded to the html element generated by this component
|
|
* @type {Array<string>}
|
|
*/
|
|
classNames = ['nacho-table', 'dataset-health__score-table'];
|
|
|
|
/**
|
|
* Sets the tag to be rendered for the html element generated by this component
|
|
* @type {string}
|
|
*/
|
|
tagName = 'table';
|
|
|
|
/**
|
|
* Passed in table data, mostly raw detailed information about the compliance score details and the
|
|
* breakdown of such.
|
|
* @type {Array<IHealthScore>}
|
|
*/
|
|
tableData: Array<IHealthScore>;
|
|
|
|
/**
|
|
* Passed in severity filter. This property lives on the dataset-health container component and its
|
|
* modification is triggered by a click in the graphing component
|
|
* @type {string}
|
|
*/
|
|
currentSeverityFilter: string;
|
|
|
|
/**
|
|
* Passed in category filter. This property lives on the dataset-health container component and its
|
|
* modification is triggered by a click in the graphing component
|
|
* @type {string}
|
|
*/
|
|
currentCategoryFilter: string;
|
|
|
|
/**
|
|
* Expected headers for the detailed table. It contains the wording for each header as well as
|
|
* additional properties
|
|
* @type {Array<IHealthTableHeader>}
|
|
*/
|
|
headers = computed('dropdownOptions', function(this: DatasetsHealthScoreTable): Array<IHealthTableHeader> {
|
|
const { dropdownOptions, onDropdownSelect } = getProperties(this, 'dropdownOptions', 'onDropdownSelect');
|
|
|
|
return ['Category', 'Description', 'Score', 'Severity'].map(header => ({
|
|
label: header,
|
|
class: `dataset-health__score-table__${header.toLowerCase()}`,
|
|
dropdownOptions: dropdownOptions[header.toLowerCase()],
|
|
initialDropdown: { label: header, value: '' },
|
|
onDropdownSelect: onDropdownSelect.bind(this, header)
|
|
}));
|
|
});
|
|
|
|
/**
|
|
* Passed in function from the dataset health container that helps us handle when the user clicks on a
|
|
* specific category from the dropdown menu in the table header
|
|
* @param {IDropDownOption} selection - the selected option from the dropdown
|
|
*/
|
|
onCategorySelect: (selection: IDropDownOption<string>) => void;
|
|
|
|
/**
|
|
* Passed in function from the dataset health container that helps us handle when the user clicks on a
|
|
* specific severity from the dropdown menu on the table header
|
|
* @param {IDropDownOption} selection - the selected option from the dropdown
|
|
*/
|
|
onSeveritySelect: (section: IDropDownOption<string>) => void;
|
|
|
|
/**
|
|
* Uses the passed in table data to calculate a dropdown list of options available for filtering by category
|
|
* and severity for the table's rows.
|
|
* @type {ComputedProperty<IHealthTableDropdowns>}
|
|
*/
|
|
dropdownOptions = computed('tableData', function(this: DatasetsHealthScoreTable): IHealthTableDropdowns {
|
|
const tableData = get(this, 'tableData');
|
|
const includedOptions = new Set();
|
|
// Starting with a default ALL/NO FILTER option
|
|
const categoryOptions: Array<IDropDownOption<string>> = [{ label: HealthDataFields.category, value: '' }];
|
|
const severityOptions: Array<IDropDownOption<string>> = [{ label: HealthDataFields.severity, value: '' }];
|
|
|
|
tableData.forEach(row => {
|
|
const { category, severity } = row;
|
|
|
|
if (!includedOptions.has(category)) {
|
|
categoryOptions.push({ label: capitalize(category), value: category });
|
|
}
|
|
|
|
if (severity && !includedOptions.has(severity)) {
|
|
severityOptions.push({ label: capitalize(severity), value: severity });
|
|
}
|
|
// Ensures no repeats
|
|
includedOptions.add(category);
|
|
includedOptions.add(severity);
|
|
});
|
|
|
|
return { category: categoryOptions, severity: severityOptions };
|
|
});
|
|
|
|
/**
|
|
* Calculates table data from the passed in information by appending each row with information that helps to
|
|
* style the table.
|
|
* @type {ComputedProperty<Array<IRenderedHealthScore>>}
|
|
*/
|
|
renderedTableData: ComputedProperty<Array<IRenderedHealthScore>> = computed(
|
|
'tableData',
|
|
'currentCategoryFilter',
|
|
'currentSeverityFilter',
|
|
function(this: DatasetsHealthScoreTable): Array<IRenderedHealthScore> {
|
|
const { tableData, currentCategoryFilter: categoryFilter, currentSeverityFilter: severityFilter } = getProperties(
|
|
this,
|
|
'tableData',
|
|
'currentCategoryFilter',
|
|
'currentSeverityFilter'
|
|
);
|
|
return tableData.map(healthScore => ({
|
|
...healthScore,
|
|
isHidden:
|
|
(!!categoryFilter && healthScore.category !== categoryFilter) ||
|
|
(!!severityFilter && healthScore.severity !== severityFilter),
|
|
highlightClass: `dataset-health__score-table__row--${(healthScore.severity || 'normal').toLowerCase()}`
|
|
}));
|
|
}
|
|
);
|
|
|
|
/**
|
|
* This is attached to each header object so that we can pass into the dropdown option for that header
|
|
* and allow the user to select from it with a handler
|
|
* @param type - lets us know which dropdown called this function
|
|
* @param selection - the actual dropdown option passed in from the child component
|
|
*/
|
|
onDropdownSelect(type: string, selection: IDropDownOption<string>) {
|
|
if (type === 'Category') {
|
|
this.onCategorySelect(selection);
|
|
} else if (type === 'Severity') {
|
|
this.onSeveritySelect(selection);
|
|
}
|
|
}
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
|
|
setProperties(this, {
|
|
tableData: this.tableData || [],
|
|
currentSeverityFilter: this.currentSeverityFilter || '',
|
|
currentCategoryFilter: this.currentCategoryFilter || '',
|
|
onCategorySelect: this.onCategorySelect || noop,
|
|
onSeveritySelect: this.onSeveritySelect || noop
|
|
});
|
|
}
|
|
}
|