mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-30 18:26:58 +00:00
Add dropdown and filter functionality to the dataset health table
This commit is contained in:
parent
8f49e5e7fd
commit
a3ac2b014f
@ -144,7 +144,7 @@ export default class DatasetHealthContainer extends Component {
|
|||||||
'currentCategoryFilter',
|
'currentCategoryFilter',
|
||||||
'currentSeverityFilter'
|
'currentSeverityFilter'
|
||||||
);
|
);
|
||||||
const newFilterName = filterDatum.name;
|
const newFilterName = filterDatum.name || filterDatum.value.toString();
|
||||||
|
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
currentCategoryFilter: filterType === 'category' && newFilterName !== currentCategoryFilter ? newFilterName : '',
|
currentCategoryFilter: filterType === 'category' && newFilterName !== currentCategoryFilter ? newFilterName : '',
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import { IHealthScore } from 'wherehows-web/typings/api/datasets/health';
|
import { IHealthScore } from 'wherehows-web/typings/api/datasets/health';
|
||||||
import { computed, setProperties, getProperties } from '@ember/object';
|
import { computed, setProperties, getProperties, get } from '@ember/object';
|
||||||
import ComputedProperty from '@ember/object/computed';
|
import ComputedProperty from '@ember/object/computed';
|
||||||
|
import { IDropDownOption } from 'wherehows-web/typings/app/dataset-compliance';
|
||||||
|
import { noop } from 'wherehows-web/utils/helpers/functions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds properties specifically to help the table render each row to the basic health score
|
* Adds properties specifically to help the table render each row to the basic health score
|
||||||
@ -11,6 +13,25 @@ interface IRenderedHealthScore extends IHealthScore {
|
|||||||
isHidden: boolean;
|
isHidden: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties that define a useful header object to be rendered in the template
|
||||||
|
*/
|
||||||
|
interface IHealthTableHeader {
|
||||||
|
label: string;
|
||||||
|
class: string;
|
||||||
|
dropdownOptions: 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 {
|
export default class DatasetsHealthScoreTable extends Component {
|
||||||
/**
|
/**
|
||||||
* Sets the class names binded to the html element generated by this component
|
* Sets the class names binded to the html element generated by this component
|
||||||
@ -25,16 +46,52 @@ export default class DatasetsHealthScoreTable extends Component {
|
|||||||
tagName = 'table';
|
tagName = 'table';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected headers for the detailed table
|
* Expected headers for the detailed table. It contains the wording for each header as well as
|
||||||
* @type {Array<string>}
|
* additional properties
|
||||||
|
* @type {Array<IHealthTableHeader>}
|
||||||
*/
|
*/
|
||||||
headers = ['Category', 'Description', 'Score', 'Severity'];
|
headers = computed('dropdownOptions', function(this: DatasetsHealthScoreTable): Array<IHealthTableHeader> {
|
||||||
|
const dropdownOptions = get(this, 'dropdownOptions');
|
||||||
|
const onDropdownSelect = get(this, '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)
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classes for each header element based on the actual header column title
|
* Uses the passed in table data to calculate a dropdown list of options available for filtering by category
|
||||||
* @type {Array<string>}
|
* and severity for the table's rows.
|
||||||
|
* @type {ComputedProperty<IHealthTableDropdowns>}
|
||||||
*/
|
*/
|
||||||
headerClasses = this.headers.map(header => `dataset-health__score-table__${header.toLowerCase()}`);
|
dropdownOptions: ComputedProperty<IHealthTableDropdowns> = computed('tableData', function(
|
||||||
|
this: DatasetsHealthScoreTable
|
||||||
|
) {
|
||||||
|
const tableData = get(this, 'tableData');
|
||||||
|
const includedOptions = new Set();
|
||||||
|
|
||||||
|
return tableData.reduce(
|
||||||
|
(output, row) => {
|
||||||
|
const { category, severity } = row;
|
||||||
|
|
||||||
|
!includedOptions.has(category) && output.category.push({ label: category, value: category });
|
||||||
|
severity && !includedOptions.has(severity) && output.severity.push({ label: severity, value: severity });
|
||||||
|
// Ensures we only add each option once, assumes severity will never === category
|
||||||
|
includedOptions.add(category);
|
||||||
|
includedOptions.add(severity);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: <IDropDownOption<string>[]>[{ label: 'Category', value: '' }],
|
||||||
|
severity: <IDropDownOption<string>[]>[{ label: 'Severity', value: '' }]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passed in table data, mostly raw detailed information about the compliance score details and the
|
* Passed in table data, mostly raw detailed information about the compliance score details and the
|
||||||
@ -83,13 +140,43 @@ export default class DatasetsHealthScoreTable extends Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
|
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
tableData: this.tableData || [],
|
tableData: this.tableData || [],
|
||||||
currentSeverityFilter: this.currentSeverityFilter || '',
|
currentSeverityFilter: this.currentSeverityFilter || '',
|
||||||
currentCategoryFilter: this.currentCategoryFilter || ''
|
currentCategoryFilter: this.currentCategoryFilter || '',
|
||||||
|
onCategorySelect: this.onCategorySelect || noop,
|
||||||
|
onSeveritySelect: this.onSeveritySelect || noop
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,4 +7,6 @@
|
|||||||
{{datasets/health/score-table
|
{{datasets/health/score-table
|
||||||
tableData=tableData
|
tableData=tableData
|
||||||
currentCategoryFilter=currentCategoryFilter
|
currentCategoryFilter=currentCategoryFilter
|
||||||
currentSeverityFilter=currentSeverityFilter}}
|
currentSeverityFilter=currentSeverityFilter
|
||||||
|
onCategorySelect=(action onFilterSelect "category")
|
||||||
|
onSeveritySelect=(action onFilterSelect "severity")}}
|
||||||
|
|||||||
@ -1,7 +1,18 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{{#each headers as |header index|}}
|
{{#each headers as |header|}}
|
||||||
<th class={{get headerClasses index}}>{{header}}</th>
|
<th class={{header.class}}>
|
||||||
|
{{#if header.dropdownOptions}}
|
||||||
|
{{#nacho/dropdown/hover-dropdown
|
||||||
|
selectedDropDown=header.initialDropdown
|
||||||
|
onSelect=header.onDropdownSelect
|
||||||
|
dropDownItems=header.dropdownOptions as |dd|}}
|
||||||
|
{{dd.content}}
|
||||||
|
{{/nacho/dropdown/hover-dropdown}}
|
||||||
|
{{else}}
|
||||||
|
{{header.label}}
|
||||||
|
{{/if}}
|
||||||
|
</th>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user