mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-29 09:52:40 +00:00
Merge pull request #1428 from cptran777/refactor-schema-entities
Refactor schema entities
This commit is contained in:
commit
1c7df4fa2a
@ -1,8 +1,7 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import { computed, set, get, setProperties, getProperties, getWithDefault } from '@ember/object';
|
import { computed, set, get, setProperties, getProperties, getWithDefault } from '@ember/object';
|
||||||
import ComputedProperty, { not, or, alias } from '@ember/object/computed';
|
import ComputedProperty, { not, or, alias } from '@ember/object/computed';
|
||||||
import { run, schedule, next } from '@ember/runloop';
|
import { run, next } from '@ember/runloop';
|
||||||
import { classify, htmlSafe } from '@ember/string';
|
|
||||||
import { assert } from '@ember/debug';
|
import { assert } from '@ember/debug';
|
||||||
import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset';
|
import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset';
|
||||||
import { IDataPlatform } from 'wherehows-web/typings/api/list/platforms';
|
import { IDataPlatform } from 'wherehows-web/typings/api/list/platforms';
|
||||||
@ -14,7 +13,6 @@ import {
|
|||||||
getFieldIdentifierOptions,
|
getFieldIdentifierOptions,
|
||||||
getDefaultSecurityClassification,
|
getDefaultSecurityClassification,
|
||||||
compliancePolicyStrings,
|
compliancePolicyStrings,
|
||||||
getComplianceSteps,
|
|
||||||
isExempt,
|
isExempt,
|
||||||
ComplianceFieldIdValue,
|
ComplianceFieldIdValue,
|
||||||
IDatasetClassificationOption,
|
IDatasetClassificationOption,
|
||||||
@ -101,12 +99,6 @@ const datasetClassificationKey = 'complianceInfo.datasetClassification';
|
|||||||
*/
|
*/
|
||||||
const datasetClassifiersKeys = <Array<keyof typeof DatasetClassifiers>>Object.keys(DatasetClassifiers);
|
const datasetClassifiersKeys = <Array<keyof typeof DatasetClassifiers>>Object.keys(DatasetClassifiers);
|
||||||
|
|
||||||
/**
|
|
||||||
* The initial state of the compliance step for a zero based array
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
const initialStepIndex = -1;
|
|
||||||
|
|
||||||
export default class DatasetCompliance extends Component {
|
export default class DatasetCompliance extends Component {
|
||||||
isNewComplianceInfo: boolean;
|
isNewComplianceInfo: boolean;
|
||||||
datasetName: string;
|
datasetName: string;
|
||||||
@ -300,12 +292,6 @@ export default class DatasetCompliance extends Component {
|
|||||||
* @memberof DatasetCompliance
|
* @memberof DatasetCompliance
|
||||||
*/
|
*/
|
||||||
schemaless: boolean;
|
schemaless: boolean;
|
||||||
/**
|
|
||||||
* Tracks the current index of the compliance policy update wizard flow
|
|
||||||
* @type {number}
|
|
||||||
* @memberof DatasetCompliance
|
|
||||||
*/
|
|
||||||
editStepIndex: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of complianceDataType values
|
* List of complianceDataType values
|
||||||
@ -393,7 +379,6 @@ export default class DatasetCompliance extends Component {
|
|||||||
super(...arguments);
|
super(...arguments);
|
||||||
|
|
||||||
//sets default values for class fields
|
//sets default values for class fields
|
||||||
this.editStepIndex = initialStepIndex;
|
|
||||||
this.sortColumnWithName || set(this, 'sortColumnWithName', 'identifierField');
|
this.sortColumnWithName || set(this, 'sortColumnWithName', 'identifierField');
|
||||||
this.filterBy || set(this, 'filterBy', '0'); // first element in field type is identifierField
|
this.filterBy || set(this, 'filterBy', '0'); // first element in field type is identifierField
|
||||||
this.sortDirection || set(this, 'sortDirection', 'asc');
|
this.sortDirection || set(this, 'sortDirection', 'asc');
|
||||||
@ -404,20 +389,6 @@ export default class DatasetCompliance extends Component {
|
|||||||
set(this, 'suggestionConfidenceThreshold', lowQualitySuggestionConfidenceThreshold);
|
set(this, 'suggestionConfidenceThreshold', lowQualitySuggestionConfidenceThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Lists the compliance wizard edit steps based on the datasets schemaless property
|
|
||||||
* @memberof DatasetCompliance
|
|
||||||
*/
|
|
||||||
editSteps = computed('schemaless', function(this: DatasetCompliance): Array<{ name: string }> {
|
|
||||||
const hasSchema = !getWithDefault(this, 'schemaless', false);
|
|
||||||
const steps = getComplianceSteps(hasSchema);
|
|
||||||
|
|
||||||
// Ensure correct step ordering
|
|
||||||
return Object.keys(steps)
|
|
||||||
.sort()
|
|
||||||
.map((key: string): { name: string } => steps[+key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the complianceDataTypes property and transforms into a list of drop down options for the field
|
* Reads the complianceDataTypes property and transforms into a list of drop down options for the field
|
||||||
* identifier type
|
* identifier type
|
||||||
@ -490,78 +461,6 @@ export default class DatasetCompliance extends Component {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* e-c Task to update the current edit step in the wizard flow.
|
|
||||||
* Handles the transitions between steps, including performing each step's
|
|
||||||
* post processing action once a user has completed a step, or reverting the step
|
|
||||||
* and stepping backward if the post process fails
|
|
||||||
* @type {Task<void, (a?: void) => TaskInstance<void>>}
|
|
||||||
* @memberof DatasetCompliance
|
|
||||||
*/
|
|
||||||
updateEditStepTask = (function() {
|
|
||||||
// initialize the previous action with a no-op function
|
|
||||||
let previousAction = noop;
|
|
||||||
// initialize the last seen index to the same value as editStepIndex
|
|
||||||
let lastIndex = initialStepIndex;
|
|
||||||
|
|
||||||
return task(function*(this: DatasetCompliance): IterableIterator<void> {
|
|
||||||
const { editStepIndex: currentIndex, editSteps } = getProperties(this, ['editStepIndex', 'editSteps']);
|
|
||||||
// the current step in the edit sequence
|
|
||||||
const editStep = editSteps[currentIndex] || { name: '' };
|
|
||||||
const { name } = editStep;
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
// using the steps name, construct a reference to the step process handler
|
|
||||||
const nextAction = this.actions[`did${classify(name)}`];
|
|
||||||
let previousActionResult: void;
|
|
||||||
|
|
||||||
// if the transition is backward, then the previous action is ignored
|
|
||||||
currentIndex > lastIndex && (previousActionResult = previousAction.call(this));
|
|
||||||
lastIndex = currentIndex;
|
|
||||||
|
|
||||||
try {
|
|
||||||
yield previousActionResult;
|
|
||||||
// if the previous action is resolved successfully, then replace with the next processor
|
|
||||||
previousAction = typeof nextAction === 'function' ? nextAction : noop;
|
|
||||||
|
|
||||||
set(this, 'editStep', editStep);
|
|
||||||
} catch {
|
|
||||||
// if the previous action settles in a rejected state, replace with no-op before
|
|
||||||
// invoking the previousStep action to go back in the sequence
|
|
||||||
// batch previousStep invocation in a afterRender queue due to editStepIndex update
|
|
||||||
previousAction = noop;
|
|
||||||
run(
|
|
||||||
(): void => {
|
|
||||||
if (this.isDestroyed || this.isDestroying) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
schedule('afterRender', this, this.actions.previousStep);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).enqueue();
|
|
||||||
})();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds a reference to the current step in the compliance edit wizard flow
|
|
||||||
* @type {{ name: string }}
|
|
||||||
*/
|
|
||||||
editStep: { name: string } = { name: '' };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of ui values and labels for review filter drop-down
|
|
||||||
* @type {Array<{value: TagFilter, label:string}>}
|
|
||||||
* @memberof DatasetCompliance
|
|
||||||
*/
|
|
||||||
fieldReviewOptions: Array<{ value: DatasetCompliance['fieldReviewOption']; label: string }> = [
|
|
||||||
{ value: TagFilter.showAll, label: ' Show all fields' },
|
|
||||||
{ value: TagFilter.showReview, label: '? Show fields missing a data type' },
|
|
||||||
{ value: TagFilter.showSuggested, label: '! Show fields that need review' },
|
|
||||||
//@ts-ignore htmlSafe type definition is incorrect in @types/ember contains TODO: to return Handlebars.SafeStringStatic
|
|
||||||
{ value: TagFilter.showCompleted, label: <string>htmlSafe(`✓ Show completed fields`) }
|
|
||||||
];
|
|
||||||
|
|
||||||
didReceiveAttrs(): void {
|
didReceiveAttrs(): void {
|
||||||
// Perform validation step on the received component attributes
|
// Perform validation step on the received component attributes
|
||||||
this.validateAttrs();
|
this.validateAttrs();
|
||||||
|
|||||||
@ -1,7 +1,130 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
import { action } from '@ember-decorators/object';
|
||||||
|
import { set } from '@ember/object';
|
||||||
|
import { noop } from 'wherehows-web/utils/helpers/functions';
|
||||||
|
import { ComplianceEdit, TagFilter, ComplianceFieldIdValue } from 'wherehows-web/constants';
|
||||||
|
import { htmlSafe } from '@ember/string';
|
||||||
|
import { IComplianceChangeSet, IDropDownOption } from 'wherehows-web/typings/app/dataset-compliance';
|
||||||
|
import { TrackableEventCategory, trackableEvent } from 'wherehows-web/constants/analytics/event-tracking';
|
||||||
|
|
||||||
export default class DatasetsComplianceSchemaEntities extends Component.extend({
|
/**
|
||||||
// anything which *must* be merged to prototype here
|
* The DatasetComplianceEntities component allows the user to individually tag fields to annotate the
|
||||||
}) {
|
* data contained in the dataset schema, found in the Compliance tab for datasets.
|
||||||
// normal class body definition here
|
*/
|
||||||
|
export default class DatasetComplianceEntities extends Component.extend({}) {
|
||||||
|
/**
|
||||||
|
* Passed in flag determining whether or not we are in an editing mode for the schema entities.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
isEditing: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed in computed prop, Lists the IComplianceChangeSet / tags without an identifierType value
|
||||||
|
* @type {Array<IComplianceChangeSet>}
|
||||||
|
*/
|
||||||
|
unspecifiedTags: Array<IComplianceChangeSet>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed in action/method from parent, updates the editing mode and corresponding target
|
||||||
|
*/
|
||||||
|
toggleEditing: (isEditing: boolean, target?: ComplianceEdit) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed in action from parent, updates showGuidedEditMode state on parent
|
||||||
|
*/
|
||||||
|
// Note: [REFACTOR-COMPLIANCE] This passed in function is to maintain status quo while we migrate the
|
||||||
|
// refactor logic and should eventually no longer be required
|
||||||
|
showGuidedEditMode: (isShowingGuidedEditMode: boolean) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed in action from parent, updates fieldReviewOption state on parent
|
||||||
|
*/
|
||||||
|
// Note: [REFACTOR-COMPLIANCE] Same as above showGuidedEditMode
|
||||||
|
fieldReviewChange: (o: { value: TagFilter }) => IDropDownOption<TagFilter>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the filter to be applied on the list of fields shown in the compliance policy table
|
||||||
|
* @type {TagFilter}
|
||||||
|
*/
|
||||||
|
// Note: [REFACTOR-COMPLIANCE] This value will currently be passed in from the parent but should
|
||||||
|
// eventually live only on this component
|
||||||
|
fieldReviewOption!: TagFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in the template to help pass values for the edit target
|
||||||
|
* @type {ComplianceEdit}
|
||||||
|
*/
|
||||||
|
ComplianceEdit = ComplianceEdit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* References the ComplianceFieldIdValue enum, which specifies hardcoded values for field
|
||||||
|
* identifiers
|
||||||
|
* @type {ComplianceFieldIdValue}
|
||||||
|
*/
|
||||||
|
ComplianceFieldIdValue = ComplianceFieldIdValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum of categories that can be tracked for this component
|
||||||
|
* @type {TrackableEventCategory}
|
||||||
|
*/
|
||||||
|
trackableCategory = TrackableEventCategory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of events that can be tracked
|
||||||
|
* @type {ITrackableEventCategoryEvent}
|
||||||
|
*/
|
||||||
|
trackableEvent = trackableEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag indicating the current compliance policy edit-view mode. Guided edit mode allows users
|
||||||
|
* to go through a wizard to edit the schema entities while the other method is direct JSON editing
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof DatasetComplianceEntities
|
||||||
|
*/
|
||||||
|
showGuidedComplianceEditMode = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of ui values and labels for review filter drop-down
|
||||||
|
* @type {Array<{value: TagFilter, label:string}>}
|
||||||
|
* @memberof DatasetComplianceEntities
|
||||||
|
*/
|
||||||
|
fieldReviewOptions: Array<IDropDownOption<DatasetComplianceEntities['fieldReviewOption']>> = [
|
||||||
|
{ value: TagFilter.showAll, label: ' Show all fields' },
|
||||||
|
{ value: TagFilter.showReview, label: '? Show fields missing a data type' },
|
||||||
|
{ value: TagFilter.showSuggested, label: '! Show fields that need review' },
|
||||||
|
//@ts-ignore htmlSafe type definition is incorrect in @types/ember contains TODO: to return Handlebars.SafeStringStatic
|
||||||
|
{ value: TagFilter.showCompleted, label: <string>htmlSafe(`✓ Show completed fields`) }
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
|
||||||
|
// Default values for undefined properties
|
||||||
|
this.unspecifiedTags || (this.unspecifiedTags = []);
|
||||||
|
this.toggleEditing || (this.toggleEditing = noop);
|
||||||
|
this.showGuidedEditMode || (this.showGuidedEditMode = noop);
|
||||||
|
this.fieldReviewChange || (this.fieldReviewChange = noop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the visibility of the guided compliance edit view vs the advanced (json) edit view modes
|
||||||
|
* @param {boolean} toggle flag ,if true, show guided edit mode, otherwise, advanced
|
||||||
|
*/
|
||||||
|
@action
|
||||||
|
onShowGuidedEditMode(this: DatasetComplianceEntities, toggle: boolean): void {
|
||||||
|
const isShowingGuidedEditMode = set(this, 'showGuidedComplianceEditMode', toggle);
|
||||||
|
// Note: [REFACTOR-COMPLIANCE] Should be deleted once full functionality lives on this component
|
||||||
|
this.showGuidedEditMode(isShowingGuidedEditMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the external action to update the tagFilter query
|
||||||
|
* @param {{value: TagFilter}} { value }
|
||||||
|
* @returns {TagFilter}
|
||||||
|
*/
|
||||||
|
@action
|
||||||
|
onFieldReviewChange(this: DatasetComplianceEntities, option: { value: TagFilter }): IDropDownOption<TagFilter> {
|
||||||
|
// Note: [REFACTOR-COMPLIANCE] The passed in effects should eventually live only on this component
|
||||||
|
return this.fieldReviewChange(option);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,22 +118,6 @@ enum ComplianceEdit {
|
|||||||
ExportPolicy = 'editExportPolicy'
|
ExportPolicy = 'editExportPolicy'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes a map of dataset options and constructs the relevant compliance edit wizard steps to build the wizard flow
|
|
||||||
* @param {boolean} [hasSchema=true] flag indicating if the dataset has a schema or otherwise
|
|
||||||
* @returns {({ [x: number]: { name: string } })}
|
|
||||||
*/
|
|
||||||
const getComplianceSteps = (hasSchema: boolean = true): { [x: number]: { name: string } } => {
|
|
||||||
// Step to tag dataset with PII data, this is at the dataset level for schema-less datasets
|
|
||||||
const piiTaggingStep = { 0: { name: 'editDatasetLevelCompliancePolicy' } };
|
|
||||||
|
|
||||||
if (!hasSchema) {
|
|
||||||
return { ...complianceSteps, ...piiTaggingStep };
|
|
||||||
}
|
|
||||||
|
|
||||||
return complianceSteps;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if argument of type IComplianceEntity has its readonly attribute not set to true
|
* Returns true if argument of type IComplianceEntity has its readonly attribute not set to true
|
||||||
* @param {IComplianceEntity} { readonly }
|
* @param {IComplianceEntity} { readonly }
|
||||||
@ -705,7 +689,6 @@ export {
|
|||||||
getFieldIdentifierOption,
|
getFieldIdentifierOption,
|
||||||
getFieldIdentifierOptions,
|
getFieldIdentifierOptions,
|
||||||
complianceSteps,
|
complianceSteps,
|
||||||
getComplianceSteps,
|
|
||||||
editableTags,
|
editableTags,
|
||||||
isTagFilter,
|
isTagFilter,
|
||||||
isAutoGeneratedPolicy,
|
isAutoGeneratedPolicy,
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
{{#if showAdvancedEditApplyStep}}
|
{{#if showAdvancedEditApplyStep}}
|
||||||
|
|
||||||
{{#track-ui-event category=trackableCategory.Compliance action=trackableEvent.Compliance.ManualApply
|
{{#track-ui-event category=trackableCategory.Compliance action=trackableEvent.Compliance.ManualApply
|
||||||
name=editStep.name as |metrics|}}
|
name=editTarget as |metrics|}}
|
||||||
<button
|
<button
|
||||||
class="nacho-button nacho-button--large-inverse action-bar__item"
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
title="Apply JSON"
|
title="Apply JSON"
|
||||||
@ -172,7 +172,19 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
|
|
||||||
{{#if (or isReadOnly (eq editTarget ComplianceEdit.CompliancePolicy))}}
|
{{#if (or isReadOnly (eq editTarget ComplianceEdit.CompliancePolicy))}}
|
||||||
|
{{#datasets/compliance/schema-entities
|
||||||
|
isEditing=(readonly isEditing)
|
||||||
|
wikiLinks=(readonly wikiLinks)
|
||||||
|
fieldReviewOption=(readonly fieldReviewOption)
|
||||||
|
foldedChangeSet=(readonly foldedChangeSet)
|
||||||
|
unspecifiedTags=(readonly unspecifiedTags)
|
||||||
|
setUnspecifiedTagsAsNoneTask=setUnspecifiedTagsAsNoneTask
|
||||||
|
toggleEditing=toggleEditing
|
||||||
|
showGuidedEditMode=(action "onShowGuidedEditMode")
|
||||||
|
fieldReviewChange=(action "onFieldReviewChange")}}
|
||||||
{{partial "datasets/dataset-compliance/dataset-compliance-entities"}}
|
{{partial "datasets/dataset-compliance/dataset-compliance-entities"}}
|
||||||
|
{{/datasets/compliance/schema-entities}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@ -1 +1,92 @@
|
|||||||
|
<section class="metadata-prompt">
|
||||||
|
<header class="metadata-prompt__header">
|
||||||
|
<p>
|
||||||
|
{{if isEditing
|
||||||
|
"Does any field in the schema contain an IDs (e.g. Member ID, Enterprise Profile ID etc) or other PII
|
||||||
|
information?"
|
||||||
|
"IDs and PII in the schema"}}
|
||||||
|
|
||||||
|
{{more-info
|
||||||
|
link=@wikiLinks.gdprPii
|
||||||
|
tooltip="Click for more information on Schema field format and types"
|
||||||
|
}}
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="compliance-entities-meta">
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button{{if showGuidedComplianceEditMode '--inverse' '--secondary'}}"
|
||||||
|
onclick={{action "onShowGuidedEditMode" true}}>
|
||||||
|
{{tooltip-on-element
|
||||||
|
text="Show Guided View"
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{fa-icon "table" aria-label="Show Guided View"}}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button{{if showGuidedComplianceEditMode '--secondary' '--inverse'}}"
|
||||||
|
onclick={{action "onShowGuidedEditMode" false}}>
|
||||||
|
{{tooltip-on-element
|
||||||
|
text="Show Advanced View"
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{fa-icon "code" aria-label="Show Advanced View"}}
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="compliance-entities-meta">
|
||||||
|
{{#if showGuidedComplianceEditMode}}
|
||||||
|
{{ember-selector
|
||||||
|
values=fieldReviewOptions
|
||||||
|
selected=(readonly fieldReviewOption)
|
||||||
|
selectionDidChange=(action "onFieldReviewChange")
|
||||||
|
}}
|
||||||
|
|
||||||
|
<span class="dataset-compliance-fields__filter-count">
|
||||||
|
{{pluralize foldedChangeSet.length "field"}}
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isEditing}}
|
||||||
|
|
||||||
|
<div class="compliance-entities-meta__secondary">
|
||||||
|
{{#if (and unspecifiedTags showGuidedComplianceEditMode)}}
|
||||||
|
<p class="set-fields-to-none-text">Set all unspecified field types to {{ComplianceFieldIdValue.None}}</p>
|
||||||
|
|
||||||
|
{{#track-ui-event category=trackableCategory.Compliance
|
||||||
|
action=trackableEvent.Compliance.SetUnspecifiedAsNone as |metrics|}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large nacho-button--secondary action-bar__item"
|
||||||
|
onclick={{action metrics.trackOnAction (perform setUnspecifiedTagsAsNoneTask)}}>
|
||||||
|
|
||||||
|
{{#if setUnspecifiedTagsAsNoneTask.isRunning}}
|
||||||
|
{{pendulum-ellipsis-animation}}
|
||||||
|
{{else}}
|
||||||
|
Set {{pluralize unspecifiedTags.length "tag"}} to {{ComplianceFieldIdValue.None}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</button>
|
||||||
|
{{/track-ui-event}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
|
||||||
|
<div class="compliance-entities-meta__secondary">
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--tertiary"
|
||||||
|
onclick={{action toggleEditing true ComplianceEdit.CompliancePolicy}}>
|
||||||
|
|
||||||
|
<i class="fa fa-pencil" aria-label="Edit Compliance Policy"></i>
|
||||||
|
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
</section>
|
||||||
|
|
||||||
{{yield}}
|
{{yield}}
|
||||||
@ -2,6 +2,44 @@
|
|||||||
{{#if isEditing}}
|
{{#if isEditing}}
|
||||||
|
|
||||||
<div class="container action-bar__content">
|
<div class="container action-bar__content">
|
||||||
|
{{#if showApplyButton}}
|
||||||
|
|
||||||
|
{{#if trackApplyEvent}}
|
||||||
|
{{#track-ui-event category=trackApplyEvent.category action=trackApplyEvent.action
|
||||||
|
name=trackApplyEvent.name as |metrics|}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
|
title={{applyButton.title}}
|
||||||
|
onclick={{action metrics.trackOnAction (action "onApplyComplianceJson")}}
|
||||||
|
disabled={{shouldDisableManualApply}}>
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
{{/track-ui-event}}
|
||||||
|
{{else}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
|
title={{applyButton.title}}
|
||||||
|
onclick={{action "onApplyComplianceJson"}}
|
||||||
|
disabled={{shouldDisableManualApply}}>
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
|
||||||
|
{{#if trackSaveEvent}}
|
||||||
|
{{#track-ui-event category=trackSaveEvent.category action=trackSaveEvent.action
|
||||||
|
name=trackSaveEvent.name as |metrics|}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
|
title="{{unless isDatasetFullyClassified
|
||||||
|
'Ensure you have provided a yes/no value for all dataset tags'
|
||||||
|
'Save'}}"
|
||||||
|
onclick={{action metrics.trackOnAction (action "saveCompliance")}} disabled={{shouldDisableEditSaving}}>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
{{/track-ui-event}}
|
||||||
|
{{else}}
|
||||||
<button
|
<button
|
||||||
class="nacho-button nacho-button--large-inverse action-bar__item"
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
title="{{unless isDatasetFullyClassified
|
title="{{unless isDatasetFullyClassified
|
||||||
@ -10,12 +48,36 @@
|
|||||||
onclick={{action "saveCompliance"}} disabled={{shouldDisableEditSaving}}>
|
onclick={{action "saveCompliance"}} disabled={{shouldDisableEditSaving}}>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if trackCancelEvent}}
|
||||||
|
{{#track-ui-event category=trackCancelEvent.category action=trackCancelEvent.action
|
||||||
|
name=trackCancelEvent.name as |metrics|}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large nacho-button--secondary action-bar__item"
|
||||||
|
onclick={{action metrics.trackOnAction (action "onCancel")}}>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
{{/track-ui-event}}
|
||||||
|
{{else}}
|
||||||
<button
|
<button
|
||||||
class="nacho-button nacho-button--large nacho-button--secondary action-bar__item"
|
class="nacho-button nacho-button--large nacho-button--secondary action-bar__item"
|
||||||
onclick={{action "onCancel"}}>
|
onclick={{action "onCancel"}}>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and manualParseError (not hideManualParseErrors))}}
|
||||||
|
<div class="action-bar__content__error-messages">
|
||||||
|
{{fa-icon "times-circle-o"}}
|
||||||
|
|
||||||
|
<span class="dataset-compliance-fields__manual-entry-errors">
|
||||||
|
{{manualParseError}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
@ -1,92 +1,3 @@
|
|||||||
<section class="metadata-prompt">
|
|
||||||
<header class="metadata-prompt__header">
|
|
||||||
<p>
|
|
||||||
{{if isEditing
|
|
||||||
"Does any field in the schema contain an IDs (e.g. Member ID, Enterprise Profile ID etc) or other PII information?"
|
|
||||||
"IDs and PII in the schema"}}
|
|
||||||
|
|
||||||
{{more-info
|
|
||||||
link=@wikiLinks.gdprPii
|
|
||||||
tooltip="Click for more information on Schema field format and types"
|
|
||||||
}}
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="compliance-entities-meta">
|
|
||||||
<button
|
|
||||||
class="nacho-button nacho-button{{if showGuidedComplianceEditMode '--inverse' '--secondary'}}"
|
|
||||||
onclick={{action "onShowGuidedEditMode" true}}>
|
|
||||||
{{tooltip-on-element
|
|
||||||
text="Show Guided View"
|
|
||||||
}}
|
|
||||||
|
|
||||||
{{fa-icon "table" aria-label="Show Guided View"}}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="nacho-button nacho-button{{if showGuidedComplianceEditMode '--secondary' '--inverse'}}"
|
|
||||||
onclick={{action "onShowGuidedEditMode" false}}>
|
|
||||||
{{tooltip-on-element
|
|
||||||
text="Show Advanced View"
|
|
||||||
}}
|
|
||||||
|
|
||||||
{{fa-icon "code" aria-label="Show Advanced View"}}
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="compliance-entities-meta">
|
|
||||||
{{#if showGuidedComplianceEditMode}}
|
|
||||||
{{ember-selector
|
|
||||||
values=fieldReviewOptions
|
|
||||||
selected=(readonly fieldReviewOption)
|
|
||||||
selectionDidChange=(action "onFieldReviewChange")
|
|
||||||
}}
|
|
||||||
|
|
||||||
<span class="dataset-compliance-fields__filter-count">
|
|
||||||
{{pluralize foldedChangeSet.length "field"}}
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if isEditing}}
|
|
||||||
|
|
||||||
<div class="compliance-entities-meta__secondary">
|
|
||||||
{{#if (and unspecifiedTags showGuidedComplianceEditMode)}}
|
|
||||||
<p class="set-fields-to-none-text">Set all unspecified field types to {{ComplianceFieldIdValue.None}}</p>
|
|
||||||
|
|
||||||
{{#track-ui-event category=trackableCategory.Compliance
|
|
||||||
action=trackableEvent.Compliance.SetUnspecifiedAsNone as |metrics|}}
|
|
||||||
<button
|
|
||||||
class="nacho-button nacho-button--large nacho-button--secondary action-bar__item"
|
|
||||||
onclick={{action metrics.trackOnAction (perform setUnspecifiedTagsAsNoneTask)}}>
|
|
||||||
|
|
||||||
{{#if setUnspecifiedTagsAsNoneTask.isRunning}}
|
|
||||||
{{pendulum-ellipsis-animation}}
|
|
||||||
{{else}}
|
|
||||||
Set {{pluralize unspecifiedTags.length "tag"}} to {{ComplianceFieldIdValue.None}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
</button>
|
|
||||||
{{/track-ui-event}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if isReadOnly}}
|
|
||||||
<div class="compliance-entities-meta__secondary">
|
|
||||||
<button
|
|
||||||
class="nacho-button nacho-button--tertiary"
|
|
||||||
onclick={{action toggleEditing true ComplianceEdit.CompliancePolicy}}>
|
|
||||||
|
|
||||||
<i class="fa fa-pencil" aria-label="Edit Compliance Policy"></i>
|
|
||||||
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="dataset-compliance-fields__subtitle">
|
<div class="dataset-compliance-fields__subtitle">
|
||||||
<div class="dataset-compliance-fields__review-hint">
|
<div class="dataset-compliance-fields__review-hint">
|
||||||
{{fieldReviewHint}}
|
{{fieldReviewHint}}
|
||||||
|
|||||||
@ -62,24 +62,6 @@ module('Unit | Constants | dataset compliance', function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getComplianceSteps function should behave as expected', function(assert) {
|
|
||||||
assert.expect(3);
|
|
||||||
const piiTaggingStep = { 0: { name: 'editDatasetLevelCompliancePolicy' } };
|
|
||||||
let result;
|
|
||||||
|
|
||||||
assert.equal(typeof getComplianceSteps, 'function', 'getComplianceSteps is a function');
|
|
||||||
result = getComplianceSteps();
|
|
||||||
|
|
||||||
assert.deepEqual(result, complianceSteps, 'getComplianceSteps result is expected shape when no args are passed');
|
|
||||||
|
|
||||||
result = getComplianceSteps(false);
|
|
||||||
assert.deepEqual(
|
|
||||||
result,
|
|
||||||
{ ...complianceSteps, ...piiTaggingStep },
|
|
||||||
'getComplianceSteps result is expected shape when hasSchema attribute is false'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getFieldIdentifierOption function should behave as expected', function(assert) {
|
test('getFieldIdentifierOption function should behave as expected', function(assert) {
|
||||||
const [complianceType] = complianceDataTypes;
|
const [complianceType] = complianceDataTypes;
|
||||||
let result;
|
let result;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user