mirror of
https://github.com/datahub-project/datahub.git
synced 2025-09-01 13:23:09 +00:00
Merge pull request #714 from theseyi/compliance-dataset-field-split
updates notification confirm dialog. splits dataset field level quest…
This commit is contained in:
commit
364af9c4b9
@ -142,13 +142,63 @@ export default Component.extend({
|
|||||||
* Flag indicating that the component is in edit mode
|
* Flag indicating that the component is in edit mode
|
||||||
* @type {String}
|
* @type {String}
|
||||||
*/
|
*/
|
||||||
isEditing: false,
|
isEditing: computed('isNewComplianceInfo', 'isEditingDatasetClassification', 'isEditingCompliancePolicy', function() {
|
||||||
|
const { isNewComplianceInfo, isEditingDatasetClassification, isEditingCompliancePolicy } = getProperties(
|
||||||
|
this,
|
||||||
|
'isNewComplianceInfo',
|
||||||
|
'isEditingDatasetClassification',
|
||||||
|
'isEditingCompliancePolicy'
|
||||||
|
);
|
||||||
|
return isNewComplianceInfo || isEditingDatasetClassification || isEditingCompliancePolicy;
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience flag indicating the policy is not currently being edited
|
||||||
|
* @type {Ember.computed}
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isReadOnly: computed.not('isEditing'),
|
||||||
/**
|
/**
|
||||||
* Flag indicating that the component is currently saving / attempting to save the privacy policy
|
* Flag indicating that the component is currently saving / attempting to save the privacy policy
|
||||||
* @type {String}
|
* @type {String}
|
||||||
*/
|
*/
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the the compliance policy update form should be shown
|
||||||
|
* @type {Ember.computed}
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isShowingComplianceEditMode: computed('isNewComplianceInfo', 'isEditingCompliancePolicy', function() {
|
||||||
|
const { isNewComplianceInfo, isEditingCompliancePolicy, isEditingDatasetClassification } = getProperties(
|
||||||
|
this,
|
||||||
|
'isNewComplianceInfo',
|
||||||
|
'isEditingCompliancePolicy',
|
||||||
|
'isEditingDatasetClassification'
|
||||||
|
);
|
||||||
|
|
||||||
|
return (isNewComplianceInfo || isEditingCompliancePolicy) && !isEditingDatasetClassification;
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to the check if the dataset classification form is being edited and should be shown
|
||||||
|
* @type {Ember.computed}
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isShowingDatasetClassificationEditMode: computed.bool('isEditingDatasetClassification'),
|
||||||
|
|
||||||
|
datasetComplianceSteps: computed('isEditingCompliancePolicy', 'isEditingDatasetClassification', function() {
|
||||||
|
const { isEditingCompliancePolicy, isEditingDatasetClassification } = getProperties(
|
||||||
|
this,
|
||||||
|
'isEditingCompliancePolicy',
|
||||||
|
'isEditingDatasetClassification'
|
||||||
|
);
|
||||||
|
|
||||||
|
return [isEditingCompliancePolicy, isEditingDatasetClassification].map((_step, index) => ({
|
||||||
|
done: !index ? !!isEditingDatasetClassification : false
|
||||||
|
}));
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the application notifications Service
|
* Reference to the application notifications Service
|
||||||
* @type {Ember.Service}
|
* @type {Ember.Service}
|
||||||
@ -156,9 +206,7 @@ export default Component.extend({
|
|||||||
notifications: service(),
|
notifications: service(),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...Array.from(arguments));
|
||||||
// If a compliance policy does not exist for this dataset, place it in edit mode by default
|
|
||||||
set(this, 'isEditing', get(this, 'isNewComplianceInfo'));
|
|
||||||
// Perform validation step on the received component attributes
|
// Perform validation step on the received component attributes
|
||||||
this.validateAttrs();
|
this.validateAttrs();
|
||||||
},
|
},
|
||||||
@ -593,7 +641,7 @@ export default Component.extend({
|
|||||||
{ formatted: [], unformatted: [] }
|
{ formatted: [], unformatted: [] }
|
||||||
);
|
);
|
||||||
|
|
||||||
const actions = {};
|
const dialogActions = {};
|
||||||
let isConfirmed = true;
|
let isConfirmed = true;
|
||||||
let unformattedComplianceEntities = [];
|
let unformattedComplianceEntities = [];
|
||||||
|
|
||||||
@ -608,8 +656,8 @@ export default Component.extend({
|
|||||||
|
|
||||||
const confirmHandler = (function() {
|
const confirmHandler = (function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
actions['didConfirm'] = () => resolve();
|
dialogActions['didConfirm'] = () => resolve();
|
||||||
actions['didDismiss'] = () => reject();
|
dialogActions['didDismiss'] = () => reject();
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -620,7 +668,7 @@ export default Component.extend({
|
|||||||
`There are ${unformatted.length} non-ID fields that have no field format specified. ` +
|
`There are ${unformatted.length} non-ID fields that have no field format specified. ` +
|
||||||
`Are you sure they don't contain any of the following PII?\n\n` +
|
`Are you sure they don't contain any of the following PII?\n\n` +
|
||||||
`Name, Email, Phone, Address, Location, IP Address, Payment Info, Password, National ID, Device ID etc.`,
|
`Name, Email, Phone, Address, Location, IP Address, Payment Info, Password, National ID, Device ID etc.`,
|
||||||
dialogActions: actions
|
dialogActions: dialogActions
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -683,10 +731,24 @@ export default Component.extend({
|
|||||||
/**
|
/**
|
||||||
* Sets each datasetClassification value as false
|
* Sets each datasetClassification value as false
|
||||||
*/
|
*/
|
||||||
markDatasetAsNotContainingMemberData() {
|
async markDatasetAsNotContainingMemberData() {
|
||||||
const willMarkAllAsNo = confirm(
|
const dialogActions = {};
|
||||||
'Are you sure that any this dataset does not contain any of the listed types of member data'
|
const confirmMarkAllHandler = new Promise((resolve, reject) => {
|
||||||
);
|
dialogActions.didDismiss = () => reject();
|
||||||
|
dialogActions.didConfirm = () => resolve();
|
||||||
|
});
|
||||||
|
let willMarkAllAsNo = true;
|
||||||
|
|
||||||
|
get(this, 'notifications').notify('confirm', {
|
||||||
|
content: 'Are you sure that any this dataset does not contain any of the listed types of member data',
|
||||||
|
dialogActions
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await confirmMarkAllHandler;
|
||||||
|
} catch (e) {
|
||||||
|
willMarkAllAsNo = false;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
willMarkAllAsNo &&
|
willMarkAllAsNo &&
|
||||||
@ -708,10 +770,24 @@ export default Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the user intent to place this compliance component in edit mode
|
* Handler for setting the compliance policy into edit mode and rendering
|
||||||
*/
|
*/
|
||||||
onEdit() {
|
onEditCompliancePolicy() {
|
||||||
set(this, 'isEditing', true);
|
setProperties(this, { isEditingCompliancePolicy: true, isEditingDatasetClassification: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for setting the dataset classification into edit mode and rendering into DOM
|
||||||
|
*/
|
||||||
|
async onEditDatasetClassification() {
|
||||||
|
const isConfirmed = await this.confirmUnformattedFields();
|
||||||
|
|
||||||
|
// If user provides confirmation for unformatted fields or there are none,
|
||||||
|
// then validate fields against expectations
|
||||||
|
// otherwise inform user of validation exception
|
||||||
|
if (isConfirmed) {
|
||||||
|
setProperties(this, { isEditingCompliancePolicy: false, isEditingDatasetClassification: true });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -847,13 +923,7 @@ export default Component.extend({
|
|||||||
*/
|
*/
|
||||||
async saveCompliance() {
|
async saveCompliance() {
|
||||||
const setSaveFlag = (flag = false) => set(this, 'isSaving', flag);
|
const setSaveFlag = (flag = false) => set(this, 'isSaving', flag);
|
||||||
// If fields are confirmed as unique we can proceed with saving compliance entities
|
|
||||||
const saveConfirmed = await this.confirmUnformattedFields();
|
|
||||||
|
|
||||||
// If user provides confirmation for unformatted fields or there are none,
|
|
||||||
// then validate fields against expectations
|
|
||||||
// otherwise inform user of validation exception
|
|
||||||
if (saveConfirmed) {
|
|
||||||
try {
|
try {
|
||||||
const isSaving = true;
|
const isSaving = true;
|
||||||
const onSave = get(this, 'onSave');
|
const onSave = get(this, 'onSave');
|
||||||
@ -870,7 +940,6 @@ export default Component.extend({
|
|||||||
} finally {
|
} finally {
|
||||||
setSaveFlag();
|
setSaveFlag();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Rolls back changes made to the compliance spec to current
|
// Rolls back changes made to the compliance spec to current
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
@import "compliance-prompts";
|
@import "compliance-prompts";
|
||||||
@import "compliance-table";
|
@import "compliance-table";
|
||||||
@import "compliance-auto-suggester-action";
|
@import "compliance-auto-suggester-action";
|
||||||
|
@import "dataset-compliance-step";
|
||||||
|
@ -8,4 +8,8 @@
|
|||||||
&__notification-column {
|
&__notification-column {
|
||||||
width: 5%
|
width: 5%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__classification-column {
|
||||||
|
width: 17%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/// Specifies the width x height for the circle
|
||||||
|
$dataset-compliance-step-circle-size: 30px;
|
||||||
|
/// Specifies the base color for the step indicator
|
||||||
|
$dataset-compliance-step-color-base: set-color(grey, mid);
|
||||||
|
/// Specifies the completion color for the step indicator
|
||||||
|
$dataset-compliance-step-color-complete: set-color(blue, blue5);
|
||||||
|
|
||||||
|
/// Defines rules for the dataset compliance step indicator
|
||||||
|
/// A circle containing the step number, with a separating dash between successive steps
|
||||||
|
.dataset-compliance-step {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: fw(normal, 4);
|
||||||
|
height: $dataset-compliance-step-circle-size;
|
||||||
|
width: $dataset-compliance-step-circle-size;
|
||||||
|
color: $dataset-compliance-step-color-base;
|
||||||
|
background-color: set-color(white, base);
|
||||||
|
border: 2px solid $dataset-compliance-step-color-base;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
&--complete {
|
||||||
|
color: transparent;
|
||||||
|
border-color: $dataset-compliance-step-color-complete;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '\f00c';
|
||||||
|
font-family: $font-awesome-stack;
|
||||||
|
color: $dataset-compliance-step-color-complete;
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-left: item-spacing(5);
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
width: 16px;
|
||||||
|
margin-left: -28px;
|
||||||
|
border: 1px solid $dataset-compliance-step-color-base;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the styles for a wrapping container
|
||||||
|
.dataset-compliance-step-container {
|
||||||
|
margin: item-spacing(4) 0;
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
&__header,
|
&__header,
|
||||||
&__content,
|
&__content,
|
||||||
&__footer {
|
&__footer {
|
||||||
padding: item-spacing(2 4);
|
padding: item-spacing(4 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
@ -24,6 +24,9 @@
|
|||||||
|
|
||||||
&__heading-text {
|
&__heading-text {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
font-weight:fw(normal, 4);
|
||||||
|
font-size: 24px;
|
||||||
|
color: set-color(grey, dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
&__footer {
|
&__footer {
|
||||||
|
@ -14,7 +14,25 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<section class="action-bar">
|
<section class="action-bar">
|
||||||
{{#if isEditing}}
|
{{#if isEditing}}
|
||||||
|
|
||||||
|
{{#if _message}}
|
||||||
|
<div class="alert alert-{{_alertType}} post-action-notification action-footer-notification" role="alert">
|
||||||
|
{{_message}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class="container action-bar__content">
|
<div class="container action-bar__content">
|
||||||
|
{{#if isShowingComplianceEditMode}}
|
||||||
|
<button
|
||||||
|
class="nacho-button nacho-button--large-inverse action-bar__item"
|
||||||
|
title="Next"
|
||||||
|
{{action "onEditDatasetClassification"}}>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isShowingDatasetClassificationEditMode}}
|
||||||
|
|
||||||
<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
|
||||||
@ -25,19 +43,16 @@
|
|||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="nacho-button nacho-button--large action-bar__item"
|
<button
|
||||||
{{action "resetCompliance"}}>
|
class="nacho-button--large nacho-button--secondary action-bar__item"
|
||||||
<i class="fa fa-times" title="Cancel">
|
title="Back"
|
||||||
</i>
|
{{action "onEditCompliancePolicy"}}>
|
||||||
Cancel
|
Back
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{{#if _message}}
|
|
||||||
<div class="alert alert-{{_alertType}} post-action-notification action-footer-notification" role="alert">
|
|
||||||
{{_message}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@ -52,8 +67,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#unless isEditing}}
|
{{#unless isEditing}}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
{{action "onEdit"}}
|
{{action "onEditCompliancePolicy"}}
|
||||||
class="nacho-button--large nacho-button--secondary secondary-actions__action">
|
class="nacho-button--large nacho-button--secondary secondary-actions__action">
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
@ -65,16 +81,27 @@
|
|||||||
Download compliance metadata
|
Download compliance metadata
|
||||||
</button>
|
</button>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if (and isEditing (not _hasBadData))}}
|
{{#if isEditing}}
|
||||||
|
<div class="dataset-compliance-step-container">
|
||||||
|
{{partial "datasets/dataset-compliance/-dataset-compliance-step-indicator"}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and isShowingComplianceEditMode (not _hasBadData))}}
|
||||||
{{json-upload receiveJsonFile=(action "onComplianceJsonUpload") class="secondary-actions__action"}}
|
{{json-upload receiveJsonFile=(action "onComplianceJsonUpload") class="secondary-actions__action"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (or isReadOnly isShowingDatasetClassificationEditMode)}}
|
||||||
{{partial "datasets/dataset-compliance/dataset-classification"}}
|
{{partial "datasets/dataset-compliance/dataset-classification"}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (or isReadOnly isShowingComplianceEditMode)}}
|
||||||
{{partial "datasets/dataset-compliance/dataset-compliance-entities"}}
|
{{partial "datasets/dataset-compliance/dataset-compliance-entities"}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{yield}}
|
{{yield}}
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
value="{{table.searchTerm}}"
|
value="{{table.searchTerm}}"
|
||||||
oninput={{action table.filterDidChange value="target.value"}}>
|
oninput={{action table.filterDidChange value="target.value"}}>
|
||||||
|
|
||||||
{{#if hasRecentSuggestions}}
|
{{#if (and hasRecentSuggestions (not isNewComplianceInfo))}}
|
||||||
<span class="dataset-compliance-fields__has-suggestions">
|
<span class="dataset-compliance-fields__has-suggestions">
|
||||||
{{complianceSuggestion.complianceSuggestions.length}} fields to be reviewed
|
{{complianceSuggestion.complianceSuggestions.length}} fields to be reviewed
|
||||||
</span>
|
</span>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
</sup>
|
</sup>
|
||||||
</a>
|
</a>
|
||||||
{{/head.column}}
|
{{/head.column}}
|
||||||
{{#head.column class="nacho-table-cell-wrapped"}}
|
{{#head.column class="nacho-table-cell-wrapped dataset-compliance-fields__classification-column"}}
|
||||||
Security Classification
|
Security Classification
|
||||||
<sup>
|
<sup>
|
||||||
<span
|
<span
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
{{#each datasetComplianceSteps as |step index|}}
|
||||||
|
<span class="dataset-compliance-step dataset-compliance-step--{{if step.done "complete" "incomplete"}}">
|
||||||
|
{{inc index}}
|
||||||
|
</span>
|
||||||
|
{{/each}}
|
Loading…
x
Reference in New Issue
Block a user