splits compliance field validation computed property by creating a separate dependent property without a check for suggestion mismatch but depends on the output from a full validation

This commit is contained in:
Seyi Adebajo 2018-06-26 16:41:26 -07:00
parent 4e2f586e9c
commit 0bc10758ec
3 changed files with 94 additions and 38 deletions

View File

@ -171,9 +171,14 @@ export default class DatasetCompliance extends Component {
* @type {ComputedProperty<boolean>}
* @memberof DatasetCompliance
*/
initialStepNeedsReview = computed('isInitialEditStep', 'changeSetReview', function(this: DatasetCompliance): boolean {
const { isInitialEditStep, changeSetReview } = getProperties(this, ['isInitialEditStep', 'changeSetReview']);
const { length } = editableTags(changeSetReview);
initialStepNeedsReview = computed('isInitialEditStep', 'changeSetReviewWithoutSuggestionCheck', function(
this: DatasetCompliance
): boolean {
const { isInitialEditStep, changeSetReviewWithoutSuggestionCheck } = getProperties(this, [
'isInitialEditStep',
'changeSetReviewWithoutSuggestionCheck'
]);
const { length } = editableTags(changeSetReviewWithoutSuggestionCheck);
return isInitialEditStep && length > 0;
});
@ -771,6 +776,43 @@ export default class DatasetCompliance extends Component {
}
);
/**
* Filters out the compliance tags requiring review excluding tags that require review,
* due to a suggestion mismatch with the current tag identifierType
* This drives the initialStep review check and fulfills the use-case,
* where the user can proceed with the compliance update, without
* being required to resolve a suggestion mismatch
* @type {ComputedProperty<Array<IComplianceChangeSet>>}
* @memberof DatasetCompliance
*/
changeSetReviewWithoutSuggestionCheck = computed('changeSetReview', function(
this: DatasetCompliance
): Array<IComplianceChangeSet> {
return tagsRequiringReview(get(this, 'complianceDataTypes'), { checkSuggestions: false })(
get(this, 'changeSetReview')
);
});
/**
* The changeSet tags that require user attention
* @type {ComputedProperty<Array<IComplianceChangeSet>>}
* @memberof DatasetCompliance
*/
changeSetReview = computed(
`compliancePolicyChangeSet.@each.{${changeSetReviewableAttributeTriggers}}`,
'complianceDataTypes',
function(this: DatasetCompliance): Array<IComplianceChangeSet> {
return tagsRequiringReview(get(this, 'complianceDataTypes'))(get(this, 'compliancePolicyChangeSet'));
}
);
/**
* Returns a count of changeSet tags that require user attention
* @type {ComputedProperty<number>}
* @memberof DatasetCompliance
*/
changeSetReviewCount = alias('changeSetReview.length');
/**
* Reduces the current filtered changeSet to a list of IdentifierFieldWithFieldChangeSetTuple
* @type {Array<IdentifierFieldWithFieldChangeSetTuple>}
@ -849,26 +891,6 @@ export default class DatasetCompliance extends Component {
this.notifyOnChangeSetRequiresReview(hasChangeSetDrift);
};
/**
* The changeSet tags that require user attention
* @type {ComputedProperty<Array<IComplianceChangeSet>>}
* @memberof DatasetCompliance
*/
changeSetReview = computed(
`compliancePolicyChangeSet.@each.{${changeSetReviewableAttributeTriggers}}`,
'complianceDataTypes',
function(this: DatasetCompliance): Array<IComplianceChangeSet> {
return tagsRequiringReview(get(this, 'complianceDataTypes'))(get(this, 'compliancePolicyChangeSet'));
}
);
/**
* Returns a count of changeSet tags that require user attention
* @type {ComputedProperty<number>}
* @memberof DatasetCompliance
*/
changeSetReviewCount = alias('changeSetReview.length');
/**
* Sets the default classification for the given identifier field's tag
* Using the identifierType, determine the tag's default security classification based on a values

View File

@ -14,7 +14,8 @@ import {
ISchemaFieldsToPolicy,
ISchemaFieldsToSuggested,
IComplianceEntityWithMetadata,
ISuggestedFieldTypeValues
ISuggestedFieldTypeValues,
IComplianceTagReviewOptions
} from 'wherehows-web/typings/app/dataset-compliance';
import {
IColumnFieldProps,
@ -189,21 +190,48 @@ const tagSuggestionNeedsReview = ({ suggestion, suggestionAuthority, identifierT
? !suggestionAuthority
: false;
/**
* Checks if a compliance tag's logicalType property is missing or nonOwner flag is set
* @param {IComplianceChangeSet} tag the compliance field tag
* @return {boolean}
*/
const tagLogicalTypeNonOwnerAttributeNeedsReview = (tag: IComplianceChangeSet): boolean =>
!idTypeTagHasLogicalType(tag) || !tagOwnerIsSet(tag);
/**
* Checks if a compliance tag's valuePattern attribute is valid or otherwise
* @param {string | null} valuePattern
* @return {boolean}
*/
const tagValuePatternNeedsReview = ({ valuePattern }: IComplianceChangeSet): boolean => {
let isValid = false;
try {
({ isValid } = validateRegExp(valuePattern, isValidCustomValuePattern));
} catch {
isValid = false;
}
return !isValid;
};
/**
* Checks if a compliance policy changeSet field requires user attention: if a suggestion
* is available but the user has not indicated intent or a policy for the field does not currently exist remotely
* and the related field changeSet has not been modified on the client and isn't readonly
* @param {Array<IComplianceDataType>} complianceDataTypes
* @param {IComplianceTagReviewOptions} options an option bag with properties that modify the behaviour of the review
* checking steps
* @return {(tag: IComplianceChangeSet) => boolean}
*/
const tagNeedsReview = (complianceDataTypes: Array<IComplianceDataType>) =>
const tagNeedsReview = (complianceDataTypes: Array<IComplianceDataType>, options?: IComplianceTagReviewOptions) =>
/**
* Checks if a compliance tag needs to be reviewed against a set of rules
* @param {IComplianceChangeSet} tag
* @return {boolean}
*/
(tag: IComplianceChangeSet): boolean => {
const { isDirty, privacyPolicyExists, identifierType, logicalType, valuePattern } = tag;
const { checkSuggestions } = options || { checkSuggestions: true };
const { isDirty, privacyPolicyExists, identifierType, logicalType } = tag;
let isReviewRequired = false;
// Ensure that the tag has an identifier type specified
@ -212,22 +240,18 @@ const tagNeedsReview = (complianceDataTypes: Array<IComplianceDataType>) =>
}
// Check that a hi confidence suggestion exists and the identifierType does not match the change set item
isReviewRequired = isReviewRequired || tagSuggestionNeedsReview(tag);
if (checkSuggestions) {
isReviewRequired = isReviewRequired || tagSuggestionNeedsReview(tag);
}
// Ensure that tag has a logical type and nonOwner flag is set when tag is of id type
if (isTagIdType(complianceDataTypes)(tag)) {
isReviewRequired = isReviewRequired || !idTypeTagHasLogicalType(tag) || !tagOwnerIsSet(tag);
isReviewRequired = isReviewRequired || tagLogicalTypeNonOwnerAttributeNeedsReview(tag);
}
// If the tag has a IdLogicalType.Custom logicalType, check that the value pattern is truthy
if (logicalType === IdLogicalType.Custom) {
let isValid = false;
try {
({ isValid } = validateRegExp(valuePattern, isValidCustomValuePattern));
} catch {
isValid = false;
}
isReviewRequired = isReviewRequired || !isValid;
isReviewRequired = isReviewRequired || tagValuePatternNeedsReview(tag);
}
// If either the privacy policy doesn't exists, or user hasn't made changes, then review is required
@ -364,10 +388,11 @@ const singleTagsInChangeSet = (
/**
* Returns a list of changeSet tags that requires user attention
* @param {Array<IComplianceDataType>} complianceDataTypes
* @param {IComplianceTagReviewOptions} options
* @return {(array: Array<IComplianceChangeSet>) => Array<IComplianceChangeSet>}
*/
const tagsRequiringReview = (complianceDataTypes: Array<IComplianceDataType>) =>
arrayFilter<IComplianceChangeSet>(tagNeedsReview(complianceDataTypes));
const tagsRequiringReview = (complianceDataTypes: Array<IComplianceDataType>, options?: IComplianceTagReviewOptions) =>
arrayFilter<IComplianceChangeSet>(tagNeedsReview(complianceDataTypes, options));
/**
* Lists the tags for a specific identifier field that need to be reviewed

View File

@ -18,6 +18,14 @@ interface IDatasetComplianceActions {
[K: string]: (...args: Array<any>) => any;
}
/**
* Describes the interface for compliance tag review check function, options argument
* @interface IComplianceTagReviewOptions
*/
interface IComplianceTagReviewOptions {
checkSuggestions: boolean;
}
/**
* Alias for the properties defined on an object indicating the values for a compliance entity object in
* addition to related component metadata using in processing ui interactions / rendering for the field
@ -153,5 +161,6 @@ export {
ISecurityClassificationOption,
IIdentifierFieldWithFieldChangeSetObject,
IdentifierFieldWithFieldChangeSetTuple,
ISuggestedFieldTypeValues
ISuggestedFieldTypeValues,
IComplianceTagReviewOptions
};