mirror of
https://github.com/datahub-project/datahub.git
synced 2025-09-01 05:13:15 +00:00
Finalize handling for api for metadata health endpoint and showing results
This commit is contained in:
parent
7cc30b7e8b
commit
1ececa7c1b
@ -4,10 +4,12 @@ import { task } from 'ember-concurrency';
|
||||
import ComputedProperty from '@ember/object/computed';
|
||||
import { IChartDatum } from 'wherehows-web/typings/app/visualization/charts';
|
||||
import { IHealthScore, IDatasetHealth } from 'wherehows-web/typings/api/datasets/health';
|
||||
import { healthCategories, healthSeverity, healthDetail } from 'wherehows-web/constants/data/temp-mock/health';
|
||||
import { readDatasetHealthByUrn } from 'wherehows-web/utils/api/datasets/health';
|
||||
import { readDatasetHealthByUrn, getCategory } from 'wherehows-web/utils/api/datasets/health';
|
||||
import { Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
import { equal } from '@ember-decorators/object/computed';
|
||||
import { IObject } from 'wherehows-web/typings/generic';
|
||||
import { service } from '@ember-decorators/service';
|
||||
import DatasetMeta from 'wherehows-web/services/dataset-meta';
|
||||
|
||||
/**
|
||||
* Used for the dataset health tab, represents the fieldnames for the health score table
|
||||
@ -88,6 +90,9 @@ export default class DatasetHealthContainer extends Component {
|
||||
@equal('tabSelected', Tabs.Health)
|
||||
isActiveTab: boolean;
|
||||
|
||||
@service
|
||||
datasetMeta: ComputedProperty<DatasetMeta>;
|
||||
|
||||
/**
|
||||
* Modified categoryMetrics to add properties that will help us render our actual charts without modifying the original
|
||||
* data
|
||||
@ -145,21 +150,40 @@ export default class DatasetHealthContainer extends Component {
|
||||
* @type {Task<TaskInstance<Promise<any>>, (a?: any) => TaskInstance<TaskInstance<Promise<any>>>>}
|
||||
*/
|
||||
getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator<Promise<IDatasetHealth>> {
|
||||
const { health } = yield readDatasetHealthByUrn(get(this, 'urn'));
|
||||
// Pretend like we're getting data from somehwere
|
||||
const healthData = {
|
||||
categories: healthCategories,
|
||||
severity: healthSeverity,
|
||||
detail: healthDetail
|
||||
};
|
||||
const health = <IDatasetHealth>yield readDatasetHealthByUrn(get(this, 'urn'));
|
||||
|
||||
setProperties(this, {
|
||||
categoryMetrics: healthData.categories,
|
||||
severityMetrics: healthData.severity,
|
||||
tableData: healthData.detail
|
||||
const details = health.validations || [];
|
||||
const total = details.length;
|
||||
const categories: IObject<number> = {};
|
||||
const severities: IObject<number> = {};
|
||||
|
||||
// Go through the details and find the COUNT of severity and category groupings
|
||||
const tableData: Array<IHealthScore> = details.map(detail => {
|
||||
const category = getCategory(detail.validator);
|
||||
const severity = detail.tier || 'none';
|
||||
categories[category] = (categories[category] || 0) + 1;
|
||||
severities[severity] = (severities[severity] || 0) + 1;
|
||||
|
||||
return { category, severity, description: detail.description, score: detail.score * 100 };
|
||||
});
|
||||
|
||||
return health; // Do something with health information
|
||||
const categoryMetrics: Array<IChartDatum> = Object.keys(categories).map(category => ({
|
||||
name: category,
|
||||
value: Math.round((categories[category] / total) * 100)
|
||||
}));
|
||||
|
||||
const severityMetrics: Array<IChartDatum> = Object.keys(severities).map(severity => ({
|
||||
name: severity,
|
||||
value: Math.round((severities[severity] / total) * 100)
|
||||
}));
|
||||
|
||||
get(this, 'datasetMeta').set('healthScore', health.score * 100 || 0);
|
||||
|
||||
setProperties(this, {
|
||||
categoryMetrics,
|
||||
severityMetrics,
|
||||
tableData
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,9 @@ import { Tabs } from 'wherehows-web/constants/datasets/shared';
|
||||
import { action } from '@ember-decorators/object';
|
||||
import { DatasetPlatform } from 'wherehows-web/constants';
|
||||
import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset';
|
||||
import { alias } from '@ember-decorators/object/computed';
|
||||
import DatasetMeta from 'wherehows-web/services/dataset-meta';
|
||||
import { service } from '@ember-decorators/service';
|
||||
|
||||
export default class DatasetController extends Controller {
|
||||
queryParams = ['urn'];
|
||||
@ -102,6 +105,21 @@ export default class DatasetController extends Controller {
|
||||
*/
|
||||
datasetContainsPersonalData: boolean;
|
||||
|
||||
/**
|
||||
* Including the datasetmeta property that is connected to each child container for the routable
|
||||
* tabs. Can be used to share information between these tabs from a higher level
|
||||
* @type {Ember.Service}
|
||||
*/
|
||||
@service
|
||||
datasetMeta: ComputedProperty<DatasetMeta>;
|
||||
|
||||
/**
|
||||
* Easy access in the template to the datasetMeta health score provided by the /health endpoint
|
||||
* called in the dataset-health container
|
||||
*/
|
||||
@alias('datasetMeta.healthScore')
|
||||
datasetHealthScore: ComputedProperty<number>;
|
||||
|
||||
/**
|
||||
* Flag indicating that the compliance policy needs user attention
|
||||
* @type {ComputedProperty<boolean>}
|
||||
@ -121,6 +139,12 @@ export default class DatasetController extends Controller {
|
||||
return encodeUrn(uri);
|
||||
});
|
||||
|
||||
shouldShowHealthGauge: ComputedProperty<boolean> = computed('datasetHealthScore', function(
|
||||
this: DatasetController
|
||||
): boolean {
|
||||
return typeof get(this, 'datasetHealthScore') === 'number';
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if the current platform exists in the supported list of JIT ACL whitelisted platforms
|
||||
* @type {ComputedProperty<boolean>}
|
||||
|
15
wherehows-web/app/services/dataset-meta.ts
Normal file
15
wherehows-web/app/services/dataset-meta.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import Service from '@ember/service';
|
||||
|
||||
/**
|
||||
* The dataset meta service can be used to share information between dataset route containers.
|
||||
* Used to share health score but can be expanded to other meta informations
|
||||
*/
|
||||
export default class DatasetMeta extends Service {
|
||||
healthScore: number;
|
||||
}
|
||||
|
||||
declare module '@ember/service' {
|
||||
interface Registry {
|
||||
'dataset-meta': DatasetMeta;
|
||||
}
|
||||
}
|
@ -62,10 +62,12 @@
|
||||
class="dataset-owner-list"
|
||||
shouldShowDatasetHealth=shouldShowDatasetHealth}}
|
||||
|
||||
{{visualization/charts/score-gauge
|
||||
class="dataset-health-score"
|
||||
score=83
|
||||
title="Health Score:"}}
|
||||
{{#if shouldShowHealthGauge}}
|
||||
{{visualization/charts/score-gauge
|
||||
class="dataset-health-score"
|
||||
score=datasetHealthScore
|
||||
title="Health Score:"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
@ -9,6 +9,26 @@ import { IHealthScoreResponse, IDatasetHealth } from 'wherehows-web/typings/api/
|
||||
*/
|
||||
const datasetHealthUrlByUrn = (urn: string): string => `${datasetUrlByUrn(urn)}/health`;
|
||||
|
||||
/**
|
||||
* Constant for formatting of the validator string
|
||||
* @type {string}
|
||||
*/
|
||||
const validatorFormat = 'com.linkedin.metadata.validators';
|
||||
|
||||
/**
|
||||
* Useful for removing extraneous information outside of category
|
||||
* @type {RegExp}
|
||||
*/
|
||||
const validationRegex = new RegExp(`${validatorFormat}.|Validator`, 'gi');
|
||||
|
||||
/**
|
||||
* Given a string in the format 'com.linkedin.metadata.validators.[Category]Validator', extract
|
||||
* Category and return it.
|
||||
* @param validator - Given validator string
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getCategory = (validator: string) => validator.replace(validationRegex, '');
|
||||
|
||||
export const readDatasetHealthByUrn = async (urn: string): Promise<IDatasetHealth> => {
|
||||
const defaultResponse = { score: 0, validations: [] };
|
||||
|
||||
|
14
wherehows-web/tests/unit/services/dataset-meta-test.ts
Normal file
14
wherehows-web/tests/unit/services/dataset-meta-test.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Service | dataset-meta', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let service = this.owner.lookup('service:dataset-meta');
|
||||
assert.ok(service);
|
||||
|
||||
service.set('healthScore', 50);
|
||||
assert.equal(service.get('healthScore'), 50);
|
||||
});
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { getCategory } from 'wherehows-web/utils/api/datasets/health';
|
||||
|
||||
module('Unit | Utility | api/datasets/health', function() {
|
||||
test('extracting category from validator string works', function(assert) {
|
||||
const testSTtring = 'com.linkedin.metadata.validators.OwnershipValidator';
|
||||
|
||||
assert.equal(getCategory(testSTtring), 'Ownership');
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user