mirror of
https://github.com/datahub-project/datahub.git
synced 2025-10-17 11:58:10 +00:00
implements purge policy feature. constants for platforms and purge types. adds styles for feature. implements ui logic for selecting purge based on platform availability.
This commit is contained in:
parent
1f3fb8b30f
commit
64c442b938
@ -1,5 +1,6 @@
|
||||
import Ember from 'ember';
|
||||
import isTrackingHeaderField from 'wherehows-web/utils/validators/tracking-headers';
|
||||
import { getPlatformFromUrn } from 'wherehows-web/utils/validators/urn';
|
||||
import {
|
||||
classifiers,
|
||||
datasetClassifiers,
|
||||
@ -189,6 +190,15 @@ export default Component.extend({
|
||||
return get(this, 'isNewComplianceInfo') ? 'showAll' : 'showReview';
|
||||
}),
|
||||
|
||||
/**
|
||||
* Extracts the dataset platform from the dataset urn
|
||||
* @type {Ember.ComputedProperty}
|
||||
* @return {string | void}
|
||||
*/
|
||||
datasetPlatform: computed('complianceInfo.datasetUrn', function() {
|
||||
return getPlatformFromUrn(get(this, 'complianceInfo.datasetUrn'));
|
||||
}),
|
||||
|
||||
/**
|
||||
* Reference to the application notifications Service
|
||||
* @type {Ember.Service}
|
||||
@ -723,6 +733,26 @@ export default Component.extend({
|
||||
return sourceDatasetClassification;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display a modal dialog requesting that the user check affirm that the purge type is exempt
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
showPurgeExemptionWarning() {
|
||||
const dialogActions = {};
|
||||
|
||||
get(this, 'notifications').notify('confirm', {
|
||||
header: 'Confirm purge exemption',
|
||||
content:
|
||||
'By choosing this option you understand that either Legal or HSEC may contact you to verify the purge exemption',
|
||||
dialogActions
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
dialogActions['didConfirm'] = () => resolve();
|
||||
dialogActions['didDismiss'] = () => reject();
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* Sets each datasetClassification value as false
|
||||
@ -957,6 +987,15 @@ export default Component.extend({
|
||||
return set(this.getDatasetClassificationRef(), classifier, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the complianceType on the compliance policy
|
||||
* @param {PurgePolicy} purgePolicy
|
||||
*/
|
||||
onDatasetPurgePolicyChange(purgePolicy) {
|
||||
// directly set the complianceType to the updated value
|
||||
return set(this, 'complianceInfo.complianceType', purgePolicy);
|
||||
},
|
||||
|
||||
/**
|
||||
* If all validity checks are passed, invoke onSave action on controller
|
||||
*/
|
||||
|
80
wherehows-web/app/components/purge-policy.ts
Normal file
80
wherehows-web/app/components/purge-policy.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import Ember from 'ember';
|
||||
import { baseCommentEditorOptions, PurgePolicy, purgePolicyProps } from 'wherehows-web/constants';
|
||||
import noop from 'wherehows-web/utils/noop';
|
||||
|
||||
const { Component, get, set } = Ember;
|
||||
|
||||
/**
|
||||
* A cache for the exempt policy
|
||||
* @type {PurgePolicy}
|
||||
*/
|
||||
const exemptPolicy = PurgePolicy.PurgeExempt;
|
||||
|
||||
/**
|
||||
* Checks that a purge policy is exempt
|
||||
* @param {PurgePolicy} policy the policy to check
|
||||
*/
|
||||
const isExempt = (policy: PurgePolicy) => policy === exemptPolicy;
|
||||
|
||||
export default Component.extend({
|
||||
tagName: 'ul',
|
||||
|
||||
classNames: ['purge-policy-list'],
|
||||
|
||||
exemptPolicy,
|
||||
|
||||
purgePolicyProps,
|
||||
|
||||
/**
|
||||
* The dataset's platform
|
||||
*/
|
||||
platform: null,
|
||||
|
||||
/**
|
||||
* The currently save policy for the dataset purge
|
||||
*/
|
||||
purgePolicy: null,
|
||||
|
||||
/**
|
||||
* An options hash for the purge exempt reason text editor
|
||||
* @type {}
|
||||
*/
|
||||
editorOptions: {
|
||||
...baseCommentEditorOptions,
|
||||
placeholder: {
|
||||
text: 'Please provide an explanation for why this dataset is marked "Purge Exempt" status'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Action to handle policy change, by default a no-op function
|
||||
* @type {Function}
|
||||
*/
|
||||
onPolicyChange: noop,
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
this.checkExemption(get(this, 'purgePolicy'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks that the selected purge policy is exempt, if so, set the
|
||||
* flag to request the exemption to true
|
||||
* @param {PurgePolicy} purgePolicy
|
||||
*/
|
||||
checkExemption(purgePolicy: PurgePolicy) {
|
||||
const exemptionReasonRequested = isExempt(purgePolicy);
|
||||
set(this, 'requestExemptionReason', exemptionReasonRequested);
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* Handles the change to the currently selected purge policy
|
||||
* @param {string} _name unused name for the radio group
|
||||
* @param {PurgePolicy} purgePolicy the selected purge policy
|
||||
*/
|
||||
onChange(_name: string, purgePolicy: PurgePolicy) {
|
||||
return get(this, 'onPolicyChange')(purgePolicy);
|
||||
}
|
||||
}
|
||||
});
|
14
wherehows-web/app/constants/dataset-platforms.ts
Normal file
14
wherehows-web/app/constants/dataset-platforms.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* The known/supported list of dataset platforms
|
||||
* @enum {string}
|
||||
*/
|
||||
enum DatasetPlatform {
|
||||
Kafka = 'KAFKA',
|
||||
Espresso = 'ESPRESSO',
|
||||
Oracle = 'ORACLE',
|
||||
MySql = 'MYSQL',
|
||||
Teradata = 'TERADATA',
|
||||
HDFS = 'HDFS'
|
||||
}
|
||||
|
||||
export { DatasetPlatform };
|
62
wherehows-web/app/constants/dataset-purge-policy.ts
Normal file
62
wherehows-web/app/constants/dataset-purge-policy.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { DatasetPlatform } from 'wherehows-web/constants/dataset-platforms';
|
||||
|
||||
/**
|
||||
* Available values for the purge policy
|
||||
* @enum {string}
|
||||
*/
|
||||
enum PurgePolicy {
|
||||
AutoPurge = 'AUTO_PURGE',
|
||||
ManualPurge = 'MANUAL_PURGE',
|
||||
AutoLimitedRetention = 'AUTO_LIMITED_RETENTION',
|
||||
ManualLimitedRetention = 'MANUAL_LIMITED_RETENTION',
|
||||
PurgeExempt = 'PURGE_EXEMPT'
|
||||
}
|
||||
|
||||
/**
|
||||
* Index signature for purge policy properties
|
||||
*/
|
||||
type PurgePolicyProperties = {
|
||||
[K in PurgePolicy]: {
|
||||
platforms: Array<DatasetPlatform>;
|
||||
desc: string;
|
||||
displayAs: string;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Client options for each purge policy
|
||||
* Lists, the available platforms, a descriptions field and a user friendly name for the purge key
|
||||
*/
|
||||
const purgePolicyProps: PurgePolicyProperties = {
|
||||
AUTO_PURGE: {
|
||||
platforms: [DatasetPlatform.Teradata, DatasetPlatform.Espresso, DatasetPlatform.HDFS],
|
||||
desc: 'A centralized system will automatically purge this dataset based on the provided metadata.',
|
||||
displayAs: 'Auto Purge'
|
||||
},
|
||||
MANUAL_PURGE: {
|
||||
platforms: [DatasetPlatform.MySql, DatasetPlatform.Espresso, DatasetPlatform.Teradata, DatasetPlatform.HDFS],
|
||||
desc: '',
|
||||
displayAs: 'Manual Purge'
|
||||
},
|
||||
AUTO_LIMITED_RETENTION: {
|
||||
platforms: [DatasetPlatform.Kafka, DatasetPlatform.Teradata, DatasetPlatform.HDFS],
|
||||
desc:
|
||||
'The data platform enforces limited retention. Only choose this option if your dataset ' +
|
||||
"complies with the platform's limited retention policy.",
|
||||
displayAs: 'Auto Limited Retention'
|
||||
},
|
||||
MANUAL_LIMITED_RETENTION: {
|
||||
platforms: [DatasetPlatform.Espresso, DatasetPlatform.Oracle, DatasetPlatform.MySql],
|
||||
desc: '',
|
||||
displayAs: 'Manual Limited Retention'
|
||||
},
|
||||
PURGE_EXEMPT: {
|
||||
platforms: Object.keys(DatasetPlatform).map((k: keyof typeof DatasetPlatform) => DatasetPlatform[k]),
|
||||
desc:
|
||||
'The dataset is exempted from purging due to legal or financial requirements.' +
|
||||
" Only choose this option if you've received an explicit exemption from legal.",
|
||||
displayAs: 'Purge Exempt'
|
||||
}
|
||||
};
|
||||
|
||||
export { PurgePolicy, purgePolicyProps };
|
@ -3,3 +3,5 @@ export * from 'wherehows-web/constants/dataset-classification';
|
||||
export * from 'wherehows-web/constants/dataset-compliance';
|
||||
export * from 'wherehows-web/constants/application';
|
||||
export * from 'wherehows-web/constants/dataset-comments';
|
||||
export * from 'wherehows-web/constants/dataset-purge-policy';
|
||||
export * from 'wherehows-web/constants/dataset-platforms';
|
||||
|
@ -44,11 +44,7 @@
|
||||
$breakpoint-query: map-get($breakpoints, $breakpoint);
|
||||
|
||||
@if $breakpoint-query {
|
||||
$query: if(
|
||||
type-of($breakpoint-query) == 'string',
|
||||
unquote($breakpoint-query),
|
||||
inspect($breakpoint-query)
|
||||
);
|
||||
$query: if(type-of($breakpoint-query) == 'string', unquote($breakpoint-query), inspect($breakpoint-query));
|
||||
|
||||
@media #{$query} {
|
||||
@content;
|
||||
@ -84,6 +80,34 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/// Proxy for AD container styles
|
||||
@mixin nacho-container {
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
|
||||
background-color: set-color(white, base);
|
||||
background-clip: padding-box;
|
||||
border-radius: 2px;
|
||||
padding: item-spacing(4);
|
||||
transition: box-shadow 83ms;
|
||||
}
|
||||
|
||||
/// Applies rules to render an element with a pill shape
|
||||
/// @param {Color} $bg-color the background color for the pill
|
||||
/// @param {Color} $color font/text color
|
||||
/// @param {Color} $border-color=$bg-color the color to apply to the pill border
|
||||
///@example - Usage
|
||||
/// .foo {
|
||||
/// @include pill(get-color(gray1), get-color(gray6));
|
||||
/// }
|
||||
@mixin pill($bg-color, $color, $border-color: $bg-color) {
|
||||
border-radius: 32px;
|
||||
background-color: $bg-color;
|
||||
border: 1px solid $border-color;
|
||||
color: $color;
|
||||
display: inline-block;
|
||||
line-height: item-spacing(3);
|
||||
padding: 1px 10px;
|
||||
}
|
||||
|
||||
/// Temp implementation before Auto Prefixer is installed
|
||||
/// @link https://github.com/postcss/autoprefixer
|
||||
|
||||
@ -99,7 +123,6 @@
|
||||
#{$property}: $value;
|
||||
}
|
||||
|
||||
|
||||
/// Maintains the aspect ratio for a wrapped element
|
||||
/// @param {Number} $width number value for the container's width ratio
|
||||
/// @param {Number} $height number value for the container's with ratio
|
||||
@ -107,7 +130,7 @@
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-top: ($height / $width) * 100%;
|
||||
|
@ -11,6 +11,7 @@
|
||||
@import 'dataset-comments/all';
|
||||
@import 'comments/all';
|
||||
@import 'empty-state/all';
|
||||
@import 'dataset-purge-policy/all';
|
||||
|
||||
@import 'nacho/nacho-button';
|
||||
@import 'nacho/nacho-global-search';
|
||||
|
@ -0,0 +1 @@
|
||||
@import 'purge-policy-list';
|
@ -0,0 +1,21 @@
|
||||
.purge-policy-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&__item {
|
||||
@include nacho-container;
|
||||
list-style-type: none;
|
||||
margin-bottom: item-spacing(4);
|
||||
|
||||
&--disabled {
|
||||
color: set-color(grey, mid);
|
||||
background-color: set-color(grey, light);
|
||||
}
|
||||
}
|
||||
|
||||
&__platform {
|
||||
&--unavailable {
|
||||
@include pill(set-color(red, maroonflush), set-color(white, base));
|
||||
}
|
||||
}
|
||||
}
|
@ -102,6 +102,15 @@
|
||||
{{#if (or isReadOnly isShowingComplianceEditMode)}}
|
||||
{{partial "datasets/dataset-compliance/dataset-compliance-entities"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if isShowingCompliancePurgePolicy}}
|
||||
{{purge-policy
|
||||
platform=datasetPlatform
|
||||
purgeNote=complianceInfo.compliancePurgeNote
|
||||
purgePolicy=(readonly complianceInfo.complianceType)
|
||||
onPolicyChange=(action "onDatasetPurgePolicyChange")
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{yield}}
|
||||
|
@ -13,12 +13,9 @@ const createInitialComplianceInfo = datasetId => ({
|
||||
datasetId,
|
||||
// default to first item in compliance types list
|
||||
complianceType: 'AUTO_PURGE',
|
||||
compliancePurgeNote: '',
|
||||
complianceEntities: [],
|
||||
fieldClassification: {},
|
||||
datasetClassification: {},
|
||||
geographicAffinity: { affinity: '' },
|
||||
recordOwnerType: '',
|
||||
retentionPolicy: { retentionType: '' }
|
||||
datasetClassification: {}
|
||||
});
|
||||
|
||||
/**
|
||||
|
4
wherehows-web/app/utils/noop.ts
Normal file
4
wherehows-web/app/utils/noop.ts
Normal file
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* exports a noop that can be used in place of Ember.K which is currently deprecated.
|
||||
*/
|
||||
export default () => {};
|
@ -14,8 +14,23 @@ const specialFlowUrnRegex = /(?:\?urn=)([a-z0-9_\-/{}\s]+)/i;
|
||||
|
||||
/**
|
||||
* Asserts that a provided string matches the urn pattern above
|
||||
* @param {String} candidateUrn the string to test on
|
||||
* @param {string} candidateUrn the string to test on
|
||||
*/
|
||||
export default (candidateUrn: string) => urnRegex.test(String(candidateUrn));
|
||||
const isUrn = (candidateUrn: string) => urnRegex.test(String(candidateUrn));
|
||||
|
||||
export { urnRegex, specialFlowUrnRegex };
|
||||
/**
|
||||
* Extracts the platform string from the candidate urn string
|
||||
* @param {string} candidateUrn the urn string with leading platform identifier
|
||||
* @returns {string | void}
|
||||
*/
|
||||
const getPlatformFromUrn = (candidateUrn: string) => {
|
||||
const matches = urnRegex.exec(candidateUrn);
|
||||
if (matches) {
|
||||
const [, platform] = matches;
|
||||
return platform.toUpperCase();
|
||||
}
|
||||
};
|
||||
|
||||
export default isUrn;
|
||||
|
||||
export { urnRegex, specialFlowUrnRegex, getPlatformFromUrn };
|
||||
|
Loading…
x
Reference in New Issue
Block a user