diff --git a/wherehows-web/app/components/dataset-compliance.js b/wherehows-web/app/components/dataset-compliance.js index e30b3da357..72f501d672 100644 --- a/wherehows-web/app/components/dataset-compliance.js +++ b/wherehows-web/app/components/dataset-compliance.js @@ -142,13 +142,63 @@ export default Component.extend({ * Flag indicating that the component is in edit mode * @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 * @type {String} */ 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 * @type {Ember.Service} @@ -156,9 +206,7 @@ export default Component.extend({ notifications: service(), didReceiveAttrs() { - this._super(...arguments); - // If a compliance policy does not exist for this dataset, place it in edit mode by default - set(this, 'isEditing', get(this, 'isNewComplianceInfo')); + this._super(...Array.from(arguments)); // Perform validation step on the received component attributes this.validateAttrs(); }, @@ -593,7 +641,7 @@ export default Component.extend({ { formatted: [], unformatted: [] } ); - const actions = {}; + const dialogActions = {}; let isConfirmed = true; let unformattedComplianceEntities = []; @@ -608,8 +656,8 @@ export default Component.extend({ const confirmHandler = (function() { return new Promise((resolve, reject) => { - actions['didConfirm'] = () => resolve(); - actions['didDismiss'] = () => reject(); + dialogActions['didConfirm'] = () => resolve(); + dialogActions['didDismiss'] = () => reject(); }); })(); @@ -620,7 +668,7 @@ export default Component.extend({ `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` + `Name, Email, Phone, Address, Location, IP Address, Payment Info, Password, National ID, Device ID etc.`, - dialogActions: actions + dialogActions: dialogActions }); try { @@ -683,10 +731,24 @@ export default Component.extend({ /** * Sets each datasetClassification value as false */ - markDatasetAsNotContainingMemberData() { - const willMarkAllAsNo = confirm( - 'Are you sure that any this dataset does not contain any of the listed types of member data' - ); + async markDatasetAsNotContainingMemberData() { + const dialogActions = {}; + 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 ( 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() { - set(this, 'isEditing', true); + onEditCompliancePolicy() { + 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,29 +923,22 @@ export default Component.extend({ */ async saveCompliance() { 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 { - const isSaving = true; - const onSave = get(this, 'onSave'); - setSaveFlag(isSaving); - await this.validateFields(); + try { + const isSaving = true; + const onSave = get(this, 'onSave'); + setSaveFlag(isSaving); + await this.validateFields(); - return await this.whenRequestCompletes(onSave(), { isSaving }); - } catch (e) { - // Flag this dataset's data as problematic - if (e instanceof Error && e.message === complianceDataException) { - set(this, '_hasBadData', true); - window.scrollTo(0, 0); - } - } finally { - setSaveFlag(); + return await this.whenRequestCompletes(onSave(), { isSaving }); + } catch (e) { + // Flag this dataset's data as problematic + if (e instanceof Error && e.message === complianceDataException) { + set(this, '_hasBadData', true); + window.scrollTo(0, 0); } + } finally { + setSaveFlag(); } }, diff --git a/wherehows-web/app/styles/components/dataset-compliance/_all.scss b/wherehows-web/app/styles/components/dataset-compliance/_all.scss index 2ae6e6641f..f558a35ee5 100644 --- a/wherehows-web/app/styles/components/dataset-compliance/_all.scss +++ b/wherehows-web/app/styles/components/dataset-compliance/_all.scss @@ -2,3 +2,4 @@ @import "compliance-prompts"; @import "compliance-table"; @import "compliance-auto-suggester-action"; +@import "dataset-compliance-step"; diff --git a/wherehows-web/app/styles/components/dataset-compliance/_compliance-table.scss b/wherehows-web/app/styles/components/dataset-compliance/_compliance-table.scss index 8ad8e45065..6dfe4768a7 100644 --- a/wherehows-web/app/styles/components/dataset-compliance/_compliance-table.scss +++ b/wherehows-web/app/styles/components/dataset-compliance/_compliance-table.scss @@ -8,4 +8,8 @@ &__notification-column { width: 5% } + + &__classification-column { + width: 17%; + } } diff --git a/wherehows-web/app/styles/components/dataset-compliance/_dataset-compliance-step.scss b/wherehows-web/app/styles/components/dataset-compliance/_dataset-compliance-step.scss new file mode 100644 index 0000000000..5bcf514456 --- /dev/null +++ b/wherehows-web/app/styles/components/dataset-compliance/_dataset-compliance-step.scss @@ -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; +} diff --git a/wherehows-web/app/styles/components/notifications/_notification-confirm-modal.scss b/wherehows-web/app/styles/components/notifications/_notification-confirm-modal.scss index 1d29d7b59b..2c04f02ab2 100644 --- a/wherehows-web/app/styles/components/notifications/_notification-confirm-modal.scss +++ b/wherehows-web/app/styles/components/notifications/_notification-confirm-modal.scss @@ -15,7 +15,7 @@ &__header, &__content, &__footer { - padding: item-spacing(2 4); + padding: item-spacing(4 4); } &__header { @@ -24,6 +24,9 @@ &__heading-text { margin-top: 0; + font-weight:fw(normal, 4); + font-size: 24px; + color: set-color(grey, dark); } &__footer { diff --git a/wherehows-web/app/templates/components/dataset-compliance.hbs b/wherehows-web/app/templates/components/dataset-compliance.hbs index 55a67aba88..59bd8231b4 100644 --- a/wherehows-web/app/templates/components/dataset-compliance.hbs +++ b/wherehows-web/app/templates/components/dataset-compliance.hbs @@ -14,30 +14,45 @@ {{else}}
{{/if}} @@ -52,8 +67,9 @@ {{#unless isEditing}} + @@ -65,16 +81,27 @@ Download compliance metadata {{/unless}} + {{/unless}} - {{#if (and isEditing (not _hasBadData))}} + {{#if isEditing}} +