mirror of
				https://github.com/datahub-project/datahub.git
				synced 2025-10-31 10:49:00 +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
	 cptran777
						cptran777