diff --git a/wherehows-web/app/components/dataset-compliance.ts b/wherehows-web/app/components/dataset-compliance.ts index fa2ecb3107..dc01580a64 100644 --- a/wherehows-web/app/components/dataset-compliance.ts +++ b/wherehows-web/app/components/dataset-compliance.ts @@ -117,8 +117,6 @@ const { complianceDataException, complianceFieldNotUnique, missingTypes, - successUpdating, - failedUpdating, helpText, successUploading, invalidPolicyData, @@ -790,43 +788,6 @@ export default class DatasetCompliance extends ObservableDecorator { }); } - /** - * Helper method to update user when an async server update to the - * security specification is handled. - * @template T - * @param {Promise} request the server request - * @param {{successMessage?: string, isSaving?: boolean}} [{ successMessage = successUpdating, isSaving = false }={}] - * @prop {successMessage} optional message for successful response - * @prop {isSaving} optional flag indicating when the user intends to persist / save - * @returns {Promise} - * @memberof DatasetCompliance - */ - whenRequestCompletes( - this: DatasetCompliance, - request: Promise, - { successMessage = successUpdating, isSaving = false }: { successMessage?: string; isSaving?: boolean } = {} - ): Promise { - const { notify } = get(this, 'notifications'); - - return Promise.resolve(request) - .then(({ status = ApiStatus.ERROR }): void | Promise => { - return status === ApiStatus.OK - ? notify(NotificationEvent.success, { content: successMessage }) - : Promise.reject(new Error(`Reason code for this is ${status}`)); - }) - .catch((err: string) => { - let message = `${failedUpdating} \n ${err}`; - - if (get(this, 'isNewComplianceInfo') && !isSaving) { - return notify(NotificationEvent.info, { - content: 'This dataset does not have any previously saved fields with a identifying information.' - }); - } - - notify(NotificationEvent.error, { content: message }); - }); - } - /** * Sets the default classification for the given identifier field * Using the identifierType, determine the field's default security classification based on a values @@ -1409,7 +1370,7 @@ export default class DatasetCompliance extends ObservableDecorator { const onSave = get(this, 'onSave'); setSaveFlag(isSaving); - await this.whenRequestCompletes(onSave(), { isSaving }); + await onSave(); return this.updateStep(-1); } finally { setSaveFlag(); @@ -1419,10 +1380,7 @@ export default class DatasetCompliance extends ObservableDecorator { // Rolls back changes made to the compliance spec to current // server state resetCompliance(this: DatasetCompliance) { - const options = { - successMessage: 'Field classification has been reset to the previously saved state.' - }; - this.whenRequestCompletes(get(this, 'onReset')(), options); + get(this, 'onReset')(); } }; } diff --git a/wherehows-web/app/components/datasets/containers/dataset-compliance.ts b/wherehows-web/app/components/datasets/containers/dataset-compliance.ts index 83ff4675be..3dfe51dd96 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-compliance.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-compliance.ts @@ -1,13 +1,17 @@ import Component from '@ember/component'; import { get, set, setProperties, getProperties } from '@ember/object'; +import ComputedProperty from '@ember/object/computed'; +import { inject } from '@ember/service'; import { task, TaskInstance } from 'ember-concurrency'; import { action } from 'ember-decorators/object'; +import Notifications, { NotificationEvent } from 'wherehows-web/services/notifications'; import { IDatasetColumn } from 'wherehows-web/typings/api/datasets/columns'; import { IComplianceInfo, IComplianceSuggestion } from 'wherehows-web/typings/api/datasets/compliance'; import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; import { IDatasetSchema } from 'wherehows-web/typings/api/datasets/schema'; import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes'; import { + ApiResponseStatus, IReadComplianceResult, readDatasetComplianceByUrn, readDatasetComplianceSuggestionByUrn, @@ -15,7 +19,11 @@ import { } from 'wherehows-web/utils/api'; import { columnDataTypesAndFieldNames } from 'wherehows-web/utils/api/datasets/columns'; import { readDatasetSchemaByUrn } from 'wherehows-web/utils/api/datasets/schema'; +import { ApiError } from 'wherehows-web/utils/api/errors/errors'; import { readComplianceDataTypes } from 'wherehows-web/utils/api/list/compliance-datatypes'; +import { compliancePolicyStrings } from 'wherehows-web/constants'; + +const { successUpdating, failedUpdating } = compliancePolicyStrings; export default class DatasetComplianceContainer extends Component { /** @@ -42,6 +50,12 @@ export default class DatasetComplianceContainer extends Component { */ complianceSuggestion: IComplianceSuggestion | void; + /** + * Reference to the application notifications Service + * @type {ComputedProperty} + */ + notifications: ComputedProperty = inject(); + /** * Object containing the compliance information for the dataset * @type {IComplianceInfo | void} @@ -140,12 +154,38 @@ export default class DatasetComplianceContainer extends Component { * @type {Task, (a?: any) => TaskInstance>>} */ getDatasetSchemaTask = task(function*(this: DatasetComplianceContainer): IterableIterator> { - const { columns, schemaless } = yield readDatasetSchemaByUrn(get(this, 'urn')); - const schemaFieldNamesMappedToDataTypes = columnDataTypesAndFieldNames(columns); - - setProperties(this, { schemaFieldNamesMappedToDataTypes, schemaless }); + try { + const { columns, schemaless } = yield readDatasetSchemaByUrn(get(this, 'urn')); + const schemaFieldNamesMappedToDataTypes = columnDataTypesAndFieldNames(columns); + setProperties(this, { schemaFieldNamesMappedToDataTypes, schemaless }); + } catch (e) { + // If this schema is missing, silence exception, otherwise propagate + if (!(e instanceof ApiError && e.status === ApiResponseStatus.NotFound)) { + throw e; + } + } }); + /** + * Handles user notifications when save succeeds or fails + * @template T the return type for the save request + * @param {Promise} request async policy save request + * @returns {Promise} + * @memberof DatasetComplianceContainer + */ + async notifyOnSave(this: DatasetComplianceContainer, request: Promise): Promise { + const { notify } = get(this, 'notifications'); + + try { + await request; + notify(NotificationEvent.success, { content: successUpdating }); + } catch (e) { + notify(NotificationEvent.error, { content: failedUpdating }); + } + + return request; + } + /** * Persists the updates to the compliance policy on the remote host * @return {Promise} @@ -154,7 +194,7 @@ export default class DatasetComplianceContainer extends Component { async savePrivacyCompliancePolicy(this: DatasetComplianceContainer): Promise { const complianceInfo = get(this, 'complianceInfo'); if (complianceInfo) { - return saveDatasetComplianceByUrn(get(this, 'urn'), complianceInfo); + return this.notifyOnSave(saveDatasetComplianceByUrn(get(this, 'urn'), complianceInfo)); } } diff --git a/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs b/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs index 34ce07c3be..64f9b44d4b 100644 --- a/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs +++ b/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs @@ -1,12 +1,20 @@ -{{dataset-compliance - datasetName=datasetName - schemaless=schemaless - platform=platform - complianceInfo=complianceInfo - complianceSuggestion=complianceSuggestion - isNewComplianceInfo=isNewComplianceInfo - schemaFieldNamesMappedToDataTypes=schemaFieldNamesMappedToDataTypes - complianceDataTypes=complianceDataTypes - onSave=(action "savePrivacyCompliancePolicy") - onReset=(action "resetPrivacyCompliancePolicy") -}} +{{#if getContainerDataTask.last.isError}} + + {{empty-state heading="An error occurred getting this dataset's compliance policy"}} + +{{else}} + + {{dataset-compliance + datasetName=datasetName + schemaless=schemaless + platform=platform + complianceInfo=complianceInfo + complianceSuggestion=complianceSuggestion + isNewComplianceInfo=isNewComplianceInfo + schemaFieldNamesMappedToDataTypes=schemaFieldNamesMappedToDataTypes + complianceDataTypes=complianceDataTypes + onSave=(action "savePrivacyCompliancePolicy") + onReset=(action "resetPrivacyCompliancePolicy") + }} + +{{/if}} diff --git a/wherehows-web/app/utils/api/datasets/compliance.ts b/wherehows-web/app/utils/api/datasets/compliance.ts index 6f9f812cde..9e8a22377c 100644 --- a/wherehows-web/app/utils/api/datasets/compliance.ts +++ b/wherehows-web/app/utils/api/datasets/compliance.ts @@ -101,6 +101,8 @@ const readDatasetComplianceByUrn = async (urn: string): Promise