diff --git a/wherehows-web/app/components/datasets/containers/dataset-health.ts b/wherehows-web/app/components/datasets/containers/dataset-health.ts index 9a53adff9a..ffa848b04b 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-health.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-health.ts @@ -1,6 +1,6 @@ import Component from '@ember/component'; import { get, computed, setProperties, getProperties } from '@ember/object'; -import { task, TaskInstance } from 'ember-concurrency'; +import { task } from 'ember-concurrency'; import ComputedProperty from '@ember/object/computed'; import { IChartDatum } from 'wherehows-web/typings/app/visualization/charts'; import healthCategories from 'wherehows-web/mirage/fixtures/health-categories'; @@ -8,6 +8,16 @@ import healthSeverity from 'wherehows-web/mirage/fixtures/health-severity'; import healthDetail from 'wherehows-web/mirage/fixtures/health-detail'; import { IHealthScore } from 'wherehows-web/typings/api/datasets/health'; +/** + * Used for the dataset health tab, represents the fieldnames for the health score table + */ +export enum HealthDataFields { + category = 'Category', + severity = 'Severity', + description = 'Description', + score = 'Score' +} + /** * This is the container component for the dataset health tab. It should contain the health bar graphs and a table * depicting the detailed health scores. Aside from fetching the data, it also handles click interactions between @@ -116,7 +126,7 @@ export default class DatasetHealthContainer extends Component { * An async parent task to group all data tasks for this container component * @type {Task>, (a?: any) => TaskInstance>>>} */ - getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator>> { + getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator { // Pretend like we're getting data from somehwere const healthData = { categories: healthCategories, diff --git a/wherehows-web/app/components/datasets/health/score-table.ts b/wherehows-web/app/components/datasets/health/score-table.ts index f308a4c99c..254c89098f 100644 --- a/wherehows-web/app/components/datasets/health/score-table.ts +++ b/wherehows-web/app/components/datasets/health/score-table.ts @@ -4,6 +4,8 @@ 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 @@ -19,7 +21,7 @@ interface IRenderedHealthScore extends IHealthScore { interface IHealthTableHeader { label: string; class: string; - dropdownOptions: IDropDownOption[] | undefined; + dropdownOptions: Array> | undefined; initialDropdown: IDropDownOption; onDropdownSelect: (type: string, selection: IDropDownOption) => void; } @@ -45,54 +47,6 @@ export default class DatasetsHealthScoreTable extends Component { */ tagName = 'table'; - /** - * Expected headers for the detailed table. It contains the wording for each header as well as - * additional properties - * @type {Array} - */ - headers = computed('dropdownOptions', function(this: DatasetsHealthScoreTable): Array { - 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) - })); - }); - - /** - * 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} - */ - dropdownOptions: ComputedProperty = 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: []>[{ label: 'Category', value: '' }], - severity: []>[{ label: 'Severity', value: '' }] - } - ); - }); - /** * Passed in table data, mostly raw detailed information about the compliance score details and the * breakdown of such. @@ -114,6 +68,67 @@ export default class DatasetsHealthScoreTable extends Component { */ currentCategoryFilter: string; + /** + * Expected headers for the detailed table. It contains the wording for each header as well as + * additional properties + * @type {Array} + */ + headers = computed('dropdownOptions', function(this: DatasetsHealthScoreTable): Array { + 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) => 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) => 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} + */ + 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> = [{ label: HealthDataFields.category, value: '' }]; + const severityOptions: Array> = [{ 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. @@ -140,32 +155,6 @@ 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) => 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) => void; - - constructor() { - super(...arguments); - - setProperties(this, { - tableData: this.tableData || [], - currentSeverityFilter: this.currentSeverityFilter || '', - 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 @@ -179,4 +168,16 @@ export default class DatasetsHealthScoreTable extends Component { 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 + }); + } } diff --git a/wherehows-web/app/styles/components/dataset-health/_metrics-charts.scss b/wherehows-web/app/styles/components/dataset-health/_metrics-charts.scss index 6725fbd1ec..cb356619bb 100644 --- a/wherehows-web/app/styles/components/dataset-health/_metrics-charts.scss +++ b/wherehows-web/app/styles/components/dataset-health/_metrics-charts.scss @@ -2,7 +2,7 @@ &__metrics-charts { @include nacho-container; display: flex; - margin-bottom: 24px; + margin-bottom: item-spacing(5); } &__chart-container {