diff --git a/wherehows-web/app/components/datasets/containers/upstream-dataset.ts b/wherehows-web/app/components/datasets/containers/upstream-dataset.ts index 34facbc81d..f7221edbfd 100644 --- a/wherehows-web/app/components/datasets/containers/upstream-dataset.ts +++ b/wherehows-web/app/components/datasets/containers/upstream-dataset.ts @@ -1,55 +1,205 @@ import Component from '@ember/component'; -import { task } from 'ember-concurrency'; -import { get, setProperties } from '@ember/object'; +import { task, TaskInstance } from 'ember-concurrency'; +import { get, set, computed, setProperties, getProperties } from '@ember/object'; +import ComputedProperty from '@ember/object/computed'; +import { inject } from '@ember/service'; import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; -import { readDatasetByUrn } from 'wherehows-web/utils/api/datasets/dataset'; import { assert } from '@ember/debug'; +import { readUpstreamDatasetsByUrn } from 'wherehows-web/utils/api/datasets/lineage'; +import { IUpstreamWithComplianceMetadata } from 'wherehows-web/typings/app/datasets/lineage'; +import { datasetsWithComplianceMetadata } from 'wherehows-web/constants/datasets/lineage'; +import { arraySome } from 'wherehows-web/utils/array'; +import { IDatasetRetention, IGetDatasetRetentionResponse } from 'wherehows-web/typings/api/datasets/retention'; +import { readDatasetRetentionByUrn, saveDatasetRetentionByUrn } from 'wherehows-web/utils/api/datasets/retention'; +import { readPlatforms } from 'wherehows-web/utils/api/list/platforms'; +import { getSupportedPurgePolicies, PurgePolicy } from 'wherehows-web/constants'; +import { IDataPlatform } from 'wherehows-web/typings/api/list/platforms'; +import { action } from '@ember-decorators/object'; +import { retentionObjectFactory } from 'wherehows-web/constants/datasets/retention'; +import Notifications, { NotificationEvent } from 'wherehows-web/services/notifications'; + +/** + * Aliases the yieldable values for the container task + * @alias {IterableIterator> | Promise> | TaskInstance> | TaskInstance>>} + */ +type ContainerYieldableResult = IterableIterator< + | TaskInstance> | Promise> + | TaskInstance> + | TaskInstance> +>; export default class UpstreamDatasetContainer extends Component { /** - * urn for the parent dataset + * References the application notifications service + * @memberof UpstreamDatasetContainer + * @type {ComputedProperty} + */ + notifications = >inject(); + + /** + * urn for the child dataset * @type {string} * @memberof UpstreamDatasetContainer */ - upstreamUrn: string; + urn: string; /** - * The name of the upstream dataset - * @type {IDatasetView.nativeName} + * The plaform this dataset is stored on + * @type {IDatasetView.platform} * @memberof UpstreamDatasetContainer */ - nativeName: IDatasetView['nativeName']; + platform: IDatasetView['platform']; /** - * A description of the upstream dataset - * @type {IDatasetView.description} + * The list of supported purge policies for the related platform + * @type {Array} * @memberof UpstreamDatasetContainer */ - description: IDatasetView['description']; + supportedPurgePolicies: Array = []; + + /** + * The list of upstream datasets for the related urn + * @type {Array} + */ + upstreamDatasets: Array = []; + + /** + * List of metadata properties for upstream datasets + * @type {Array} + * @memberof UpstreamDatasetContainer + */ + upstreamsMetadata: Array = []; + + /** + * Retention policy for the dataset with set urn + * @type {IDatasetRetention} + * @memberof UpstreamDatasetContainer + */ + retention: IDatasetRetention; constructor() { super(...arguments); - assert('A valid upstreamUrn must be provided on instantiation', typeof this.upstreamUrn === 'string'); + assert(`A valid child urn must be provided on instantiation, got ${this.urn}`, !!this.urn); + assert(`A valid dataset platform must be provided on instantiation, got ${this.platform}`, !!this.platform); + this.retention = retentionObjectFactory(this.urn); } didUpdateAttrs() { this._super(...arguments); - get(this, 'getUpstreamPropertiesTask').perform(); + get(this, 'getContainerDataTask').perform(); } didInsertElement() { this._super(...arguments); - get(this, 'getUpstreamPropertiesTask').perform(); + get(this, 'getContainerDataTask').perform(); } /** - * Task to get properties for the upstream dataset - * @type {Task>, (a?: {} | undefined) => TaskInstance>>} + * Flags if any of the upstream datasets has an incomplete compliance policy + * @type ComputedProperty * @memberof UpstreamDatasetContainer */ - getUpstreamPropertiesTask = task(function*(this: UpstreamDatasetContainer): IterableIterator> { - const { nativeName, description }: IDatasetView = yield readDatasetByUrn(get(this, 'upstreamUrn')); - setProperties(this, { nativeName, description }); + hasIncompleteUpstream = computed('upstreamsMetadata.[]', function(this: UpstreamDatasetContainer): boolean { + const upstreamsMetadata = get(this, 'upstreamsMetadata'); + const upstreamIsIncomplete = ({ hasCompliance }: IUpstreamWithComplianceMetadata): boolean => !hasCompliance; + + return arraySome(upstreamIsIncomplete)(upstreamsMetadata); }); + + /** + * Performs tasks related to container data instantiation + * @type {Task} + * @memberof UpstreamDatasetContainer + */ + getContainerDataTask = task(function*(this: UpstreamDatasetContainer): ContainerYieldableResult { + yield get(this, 'getUpstreamMetadataTask').perform(); + yield get(this, 'getPlatformPoliciesTask').perform(); + yield get(this, 'getRetentionTask').perform(); + }); + + /** + * Task to get properties for the upstream dataset + * @type {Task>>, (a?: {} | undefined) => TaskInstance>>>} + * @memberof UpstreamDatasetContainer + */ + getUpstreamDatasetsTask = task(function*( + this: UpstreamDatasetContainer + ): IterableIterator>> { + const upstreamDatasets: Array = yield readUpstreamDatasetsByUrn(get(this, 'urn')); + return set(this, 'upstreamDatasets', upstreamDatasets); + }); + + /** + * Task to get and set upstream metadata for upstream datasets + * @type {Task>> | Promise>>} + * @memberof UpstreamDatasetContainer + */ + getUpstreamMetadataTask = task(function*( + this: UpstreamDatasetContainer + ): IterableIterator>> | Promise>> { + const upstreamDatasets: Array = yield get(this, 'getUpstreamDatasetsTask').perform(); + const upstreamMetadataPromises = datasetsWithComplianceMetadata(upstreamDatasets); + const upstreamsMetadata: Array = yield Promise.all(upstreamMetadataPromises); + + set(this, 'upstreamsMetadata', upstreamsMetadata); + }).restartable(); + + /** + * Task to retrieve platform policies and set supported policies for the current platform + * @type {Task>, () => TaskInstance>>>} + * @memberof UpstreamDatasetContainer + */ + getPlatformPoliciesTask = task(function*( + this: UpstreamDatasetContainer + ): IterableIterator>> { + const platform = get(this, 'platform'); + + if (platform) { + set(this, 'supportedPurgePolicies', getSupportedPurgePolicies(platform, yield readPlatforms())); + } + }).restartable(); + + /** + * Task to get the retention policy for the related child dataset + * @type {Task, () => TaskInstance>>} + * @memberof UpstreamDatasetContainer + */ + getRetentionTask = task(function*( + this: UpstreamDatasetContainer + ): IterableIterator> { + const retentionResponse: IGetDatasetRetentionResponse | null = yield readDatasetRetentionByUrn(get(this, 'urn')); + const retention = + retentionResponse !== null ? retentionResponse.retentionPolicy : retentionObjectFactory(get(this, 'urn')); + + setProperties(get(this, 'retention'), retention); + }).restartable(); + + /** + * Task to update the dataset's retention policy with the user entered changes + * @type {Task, () => TaskInstance>>} + * @memberof UpstreamDatasetContainer + */ + saveRetentionTask = task(function*(this: UpstreamDatasetContainer): IterableIterator> { + const { + retention, + notifications: { notify } + } = getProperties(this, ['retention', 'notifications']); + + setProperties(retention, yield saveDatasetRetentionByUrn(get(this, 'urn'), retention)); + + notify(NotificationEvent.success, { + content: 'Successfully updated retention policy for dataset' + }); + }).drop(); + + /** + * Handles user action to change the dataset retention policy purgeType + * @param {PurgePolicy} purgePolicy + * @memberof UpstreamDatasetContainer + */ + @action + onRetentionPolicyChange(purgePolicy: PurgePolicy) { + set(get(this, 'retention'), 'purgeType', purgePolicy); + } } diff --git a/wherehows-web/app/components/datasets/upstream-dataset.ts b/wherehows-web/app/components/datasets/upstream-dataset.ts index 9256c690a3..6cdbdc4bea 100644 --- a/wherehows-web/app/components/datasets/upstream-dataset.ts +++ b/wherehows-web/app/components/datasets/upstream-dataset.ts @@ -1,7 +1,25 @@ import Component from '@ember/component'; +import { set } from '@ember/object'; +import { action } from '@ember-decorators/object'; export default class UpstreamDataset extends Component { tagName = 'section'; classNames = ['upstream-dataset-banner']; + + /** + * Flag indicating the component is in view only mode and not editable + * @type {boolean} + * @memberof UpstreamDataset + */ + isReadOnly: boolean = true; + + /** + * Action handler to set component in edit mode + * @memberof UpstreamDataset + */ + @action + onEdit() { + set(this, 'isReadOnly', false); + } } diff --git a/wherehows-web/app/components/purge-policy.ts b/wherehows-web/app/components/purge-policy.ts index 7a99d78e87..867f82f5a0 100644 --- a/wherehows-web/app/components/purge-policy.ts +++ b/wherehows-web/app/components/purge-policy.ts @@ -7,7 +7,6 @@ import { DatasetPlatform, exemptPolicy, isExempt, - missingPolicyText, PurgePolicy, purgePolicyProps } from 'wherehows-web/constants'; @@ -24,7 +23,7 @@ export default class PurgePolicyComponent extends Component { * Reference to the informational text if the dataset does not have a saved purge policy * @type {string} */ - missingPolicyText = missingPolicyText; + missingPolicyText: string = ''; /** * Reference to client options for each purge policy diff --git a/wherehows-web/app/constants/dataset-purge-policy.ts b/wherehows-web/app/constants/dataset-purge-policy.ts index 2f089bb023..a11d751d40 100644 --- a/wherehows-web/app/constants/dataset-purge-policy.ts +++ b/wherehows-web/app/constants/dataset-purge-policy.ts @@ -82,10 +82,4 @@ const exemptPolicy = PurgePolicy.PurgeExempt; */ const isExempt = (policy: PurgePolicy) => policy === PurgePolicy.PurgeExempt; -/** - * User informational text for datasets without a purge policy - * @type {string} - */ -const missingPolicyText = 'This dataset does not have a current compliance purge policy.'; - -export { PurgePolicy, purgePolicyProps, isExempt, exemptPolicy, missingPolicyText, getSupportedPurgePolicies }; +export { PurgePolicy, purgePolicyProps, isExempt, exemptPolicy, getSupportedPurgePolicies }; diff --git a/wherehows-web/app/constants/datasets/lineage.ts b/wherehows-web/app/constants/datasets/lineage.ts new file mode 100644 index 0000000000..71557a2741 --- /dev/null +++ b/wherehows-web/app/constants/datasets/lineage.ts @@ -0,0 +1,32 @@ +import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; +import { IReadComplianceResult, readDatasetComplianceByUrn } from 'wherehows-web/utils/api/datasets/compliance'; +import { IUpstreamWithComplianceMetadata } from 'wherehows-web/typings/app/datasets/lineage'; +import { arrayMap } from 'wherehows-web/utils/array'; +import { encodeUrn } from 'wherehows-web/utils/validators/urn'; + +/** + * Maps a dataset urn/uri, other props with a property indicating if the dataset compliance policy exists + * @param {(Pick)} { + * uri, + * nativeName + * } + * @returns {Promise} + */ +const datasetWithComplianceMetadata = async ({ + uri, + nativeName +}: Pick): Promise => { + const { isNewComplianceInfo }: IReadComplianceResult = await readDatasetComplianceByUrn(encodeUrn(uri)); + return { urn: uri, hasCompliance: !isNewComplianceInfo, nativeName }; +}; + +/** + * Takes a list of datasets and maps into a list of IUpstreamWithComplianceMetadata objects + * @param {Array} datasets + * @returns {Array>} + */ +const datasetsWithComplianceMetadata = ( + datasets: Array +): Array> => arrayMap(datasetWithComplianceMetadata)(datasets); + +export { datasetsWithComplianceMetadata }; diff --git a/wherehows-web/app/constants/datasets/retention.ts b/wherehows-web/app/constants/datasets/retention.ts new file mode 100644 index 0000000000..f3e937d46c --- /dev/null +++ b/wherehows-web/app/constants/datasets/retention.ts @@ -0,0 +1,14 @@ +import { IDatasetRetention } from 'wherehows-web/typings/api/datasets/retention'; + +/** + * 'News' a IDatasetRetention instance with the provided dataset urn + * @param {string} urn + * @returns {IDatasetRetention} + */ +const retentionObjectFactory = (urn: string): IDatasetRetention => ({ + datasetUrn: urn, + purgeNote: '', + purgeType: '' +}); + +export { retentionObjectFactory }; diff --git a/wherehows-web/app/styles/components/_all.scss b/wherehows-web/app/styles/components/_all.scss index 1263c7b0e2..d9e918ca3c 100644 --- a/wherehows-web/app/styles/components/_all.scss +++ b/wherehows-web/app/styles/components/_all.scss @@ -32,3 +32,4 @@ @import 'nacho/nacho-breadcrumbs'; @import 'nacho/nacho-uploader'; @import 'nacho/nacho-container'; +@import 'nacho/nacho-divider'; diff --git a/wherehows-web/app/styles/components/dataset-purge-policy/_purge-policy-list.scss b/wherehows-web/app/styles/components/dataset-purge-policy/_purge-policy-list.scss index f88ccd1951..aacef70bf6 100644 --- a/wherehows-web/app/styles/components/dataset-purge-policy/_purge-policy-list.scss +++ b/wherehows-web/app/styles/components/dataset-purge-policy/_purge-policy-list.scss @@ -5,7 +5,6 @@ &__item { @include nacho-container; list-style-type: none; - margin-bottom: item-spacing(4); &--disabled { color: set-color(grey, mid); diff --git a/wherehows-web/app/styles/components/ivy-tabs/_tabs.scss b/wherehows-web/app/styles/components/ivy-tabs/_tabs.scss index 361fdd3f7c..820aef7fd2 100644 --- a/wherehows-web/app/styles/components/ivy-tabs/_tabs.scss +++ b/wherehows-web/app/styles/components/ivy-tabs/_tabs.scss @@ -86,7 +86,8 @@ padding: 9px $item-spacing-2 11px; margin-left: $item-spacing-5; &:first-child { - margin-left: $item-spacing-4; + margin-left: 0; + padding-left: 0; } // The underline will exist on all tabs, but be transparent diff --git a/wherehows-web/app/styles/components/nacho/_nacho-divider.scss b/wherehows-web/app/styles/components/nacho/_nacho-divider.scss new file mode 100644 index 0000000000..dda31f2dde --- /dev/null +++ b/wherehows-web/app/styles/components/nacho/_nacho-divider.scss @@ -0,0 +1,5 @@ +.nacho-divider { + margin: item-spacing(5 0); + border: 0; + border-bottom: 1px solid rgba(0, 0, 0, 0.15); +} diff --git a/wherehows-web/app/styles/components/upstream-dataset/_upstream-dataset.scss b/wherehows-web/app/styles/components/upstream-dataset/_upstream-dataset.scss index 0b86a3a135..43289e94bf 100644 --- a/wherehows-web/app/styles/components/upstream-dataset/_upstream-dataset.scss +++ b/wherehows-web/app/styles/components/upstream-dataset/_upstream-dataset.scss @@ -1,9 +1,4 @@ .upstream-dataset-banner { - @include nacho-container; - display: flex; - flex-direction: row; - align-items: center; - &:hover { .upstream-dataset-banner__description { height: item-spacing(7); @@ -28,3 +23,51 @@ } } } + +.upstream-dataset { + @include nacho-container; + padding: item-spacing(2 5); + display: flex; + align-items: center; + + &__compliance-status { + &__complete { + color: get-color(green5); + } + + &__incomplete { + color: get-color(orange5); + } + } + + &__upstream-link { + margin-left: item-spacing(3); + } + + &__upstream-link-chevron { + margin-left: auto; + } +} + +.downstream-purge-policy-header { + display: flex; + align-items: center; + margin: item-spacing(6 0 5); +} + +.downstream-purge-policy { + &__no-policy { + @include nacho-container; + } + + &__edit { + margin-left: auto; + display: flex; + align-items: center; + + &--label { + margin-right: item-spacing(4); + font-weight: fw(normal, 2); + } + } +} diff --git a/wherehows-web/app/templates/components/dataset-compliance.hbs b/wherehows-web/app/templates/components/dataset-compliance.hbs index 21eaadc1f5..f3d8253216 100644 --- a/wherehows-web/app/templates/components/dataset-compliance.hbs +++ b/wherehows-web/app/templates/components/dataset-compliance.hbs @@ -164,10 +164,23 @@ {{/if}} {{#if getPlatformPoliciesTask.last.isSuccessful}} + {{purge-policy isEditable=(not isReadOnly) platform=platform + missingPolicyText="This dataset does not have a current compliance purge policy." supportedPurgePolicies=supportedPurgePolicies purgeNote=complianceInfo.compliancePurgeNote purgePolicy=(readonly complianceInfo.complianceType) diff --git a/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs b/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs index 94955da10c..66a8187ffe 100644 --- a/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs +++ b/wherehows-web/app/templates/components/datasets/containers/dataset-compliance.hbs @@ -12,7 +12,10 @@ {{#if complianceInfo.fromUpstream}} - {{datasets/containers/upstream-dataset upstreamUrn=complianceInfo.datasetUrn}} + {{datasets/containers/upstream-dataset + urn=urn + platform=platform + }} {{else}} diff --git a/wherehows-web/app/templates/components/datasets/containers/upstream-dataset.hbs b/wherehows-web/app/templates/components/datasets/containers/upstream-dataset.hbs index 786a52181e..db6a342a04 100644 --- a/wherehows-web/app/templates/components/datasets/containers/upstream-dataset.hbs +++ b/wherehows-web/app/templates/components/datasets/containers/upstream-dataset.hbs @@ -1,13 +1,17 @@ -{{#if getUpstreamPropertiesTask.isRunning}} +{{#if getUpstreamMetadataTask.isRunning}} {{pendulum-ellipsis-animation}} {{else}} {{datasets/upstream-dataset - nativeName=nativeName - description=description - upstreamUrn=upstreamUrn + upstreamsMetadata=upstreamsMetadata + platform=platform + retention=retention + hasIncompleteUpstream=hasIncompleteUpstream + supportedPurgePolicies=supportedPurgePolicies + saveRetentionTask=saveRetentionTask + onChange=(action "onRetentionPolicyChange") }} {{/if}} diff --git a/wherehows-web/app/templates/components/datasets/upstream-dataset.hbs b/wherehows-web/app/templates/components/datasets/upstream-dataset.hbs index 3b24763fe5..166ca49ff4 100644 --- a/wherehows-web/app/templates/components/datasets/upstream-dataset.hbs +++ b/wherehows-web/app/templates/components/datasets/upstream-dataset.hbs @@ -1,32 +1,101 @@
-
- +

Compliance Info

+

+ Compliance Policy on this dataset is inherited from it's parent dataset(s). To make modifications on the purge +
+ policy on this page, please complete the Compliance Metadata on all of the parent datasets. +

-

- Compliance Policy on this dataset is inherited from a parent dataset. -
- To make modifications, please update the Compliance on the parent dataset. -
-

-
+
+ +

Parent Dataset

+ + {{#each upstreamsMetadata as |parent|}} +
+ + {{tooltip-on-element + text=(if parent.hasCompliance "Compliance completed for parent dataset" "Please complete the Compliance on this parent dataset") + }} + + {{#if parent.hasCompliance}} + {{fa-icon "check" class="upstream-dataset__compliance-status__complete"}} + {{else}} + {{fa-icon "exclamation" class="upstream-dataset__compliance-status__incomplete"}} + {{/if}} + + + {{#link-to + "datasets.dataset" + "urn" + (query-params urn=parent.urn) + class="upstream-dataset__upstream-link" + }} + {{parent.nativeName}} + {{/link-to}} + + {{#link-to + "datasets.dataset" + "urn" + (query-params urn=parent.urn) + class="upstream-dataset__upstream-link-chevron" + }} + + {{/link-to}} + +
+ {{/each}} + +
+

Compliance Purge Policy

+
+ {{#unless hasIncompleteUpstream}} + + + {{#if isReadOnly}} + + {{else}} + + {{/if}} + {{/unless}} +
-
- Parent Dataset Name: - {{#link-to - "datasets.dataset" - "urn" - (query-params urn=upstreamUrn) - }} - {{nativeName}} - {{/link-to}}
- {{#if description}} +
+ {{#if hasIncompleteUpstream}} +

+ This dataset does not have a current compliance purge policy. To update, please complete the Compliance Metadata + on the parent dataset(s). +

+ {{else}} -

- Parent Dataset Description: - {{description}} -

- - {{/if}} + {{purge-policy + isEditable=(not isReadOnly) + platform=platform + supportedPurgePolicies=supportedPurgePolicies + purgeNote=retention.purgeNote + purgePolicy=(readonly retention.purgeType) + missingPolicyText="This dataset does not have a current compliance purge policy" + onPolicyChange=onChange + }} + {{/if}} +
diff --git a/wherehows-web/app/templates/components/purge-policy.hbs b/wherehows-web/app/templates/components/purge-policy.hbs index c7c15c09dd..a4cb81e40e 100644 --- a/wherehows-web/app/templates/components/purge-policy.hbs +++ b/wherehows-web/app/templates/components/purge-policy.hbs @@ -1,16 +1,3 @@ - -
    {{#if isEditable}} @@ -51,17 +38,16 @@ {{else}} - {{#if purgePolicy}} -
  • +
  • + {{#if purgePolicy}} {{get (get purgePolicyProps purgePolicy) "displayAs"}} -
  • - {{else}} + {{else}} -

    {{missingPolicyText}}

    - To update, click edit and follow the steps + {{missingPolicyText}} - {{/if}} + {{/if}} + {{/if}}
diff --git a/wherehows-web/app/typings/api/datasets/retention.d.ts b/wherehows-web/app/typings/api/datasets/retention.d.ts new file mode 100644 index 0000000000..fb6e4a89ea --- /dev/null +++ b/wherehows-web/app/typings/api/datasets/retention.d.ts @@ -0,0 +1,31 @@ +import { IComplianceInfo } from 'wherehows-web/typings/api/datasets/compliance'; + +/** + * Describes the interface for a dataset retention policy + * + * @interface IDatasetRetention + */ +interface IDatasetRetention { + // Unused attribute for the id of the dataset, use datasetUrn instead + datasetId?: number | null; + // Urn string identifying the dataset that owns this policy + datasetUrn: string; + // Purge Policy for the dataset + purgeType: IComplianceInfo['complianceType']; + // User entered purge notation for a dataset with a purge exempt policy + purgeNote: IComplianceInfo['compliancePurgeNote']; + // Who modified this retention policy + modifiedBy?: string; + // When this policy was last modified + modifiedTime?: number; +} + +/** + * Desribes the return type for requests to the endpoint returning the dataset retention policy + * @interface IGetDatasetRetentionResponse + */ +interface IGetDatasetRetentionResponse { + retentionPolicy: IDatasetRetention; +} + +export { IDatasetRetention, IGetDatasetRetentionResponse }; diff --git a/wherehows-web/app/typings/app/datasets/lineage.d.ts b/wherehows-web/app/typings/app/datasets/lineage.d.ts new file mode 100644 index 0000000000..dcc65da406 --- /dev/null +++ b/wherehows-web/app/typings/app/datasets/lineage.d.ts @@ -0,0 +1,14 @@ +import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; + +/** + * Defines the interface for the attributes used by the app to render the upstream datasets for a child + * dataset + * @interface IUpstreamWithComplianceMetadata + */ +interface IUpstreamWithComplianceMetadata { + urn: IDatasetView['uri']; + nativeName: IDatasetView['nativeName']; + hasCompliance: boolean; +} + +export { IUpstreamWithComplianceMetadata }; diff --git a/wherehows-web/app/utils/api/datasets/lineage.ts b/wherehows-web/app/utils/api/datasets/lineage.ts new file mode 100644 index 0000000000..057327c2fc --- /dev/null +++ b/wherehows-web/app/utils/api/datasets/lineage.ts @@ -0,0 +1,20 @@ +import { getJSON } from 'wherehows-web/utils/api/fetcher'; +import { datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared'; +import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; + +/** + * Constructs the url for a datasets upstreams + * @param {string} urn the urn for the child dataset + * @return {string} + */ +const datasetUpstreamUrlByUrn = (urn: string): string => `${datasetUrlByUrn(urn)}/upstreams`; + +/** + * Fetches the list of upstream datasets for a dataset by urn + * @param {string} urn urn for the child dataset + * @return {Promise>} + */ +const readUpstreamDatasetsByUrn = (urn: string): Promise> => + getJSON>({ url: datasetUpstreamUrlByUrn(urn) }); + +export { readUpstreamDatasetsByUrn }; diff --git a/wherehows-web/app/utils/api/datasets/retention.ts b/wherehows-web/app/utils/api/datasets/retention.ts new file mode 100644 index 0000000000..a51c2f9e6d --- /dev/null +++ b/wherehows-web/app/utils/api/datasets/retention.ts @@ -0,0 +1,39 @@ +import { getJSON, postJSON } from 'wherehows-web/utils/api/fetcher'; +import { datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared'; +import { IDatasetRetention, IGetDatasetRetentionResponse } from 'wherehows-web/typings/api/datasets/retention'; +import { notFoundApiError } from 'wherehows-web/utils/api'; + +/** + * Constructs the url for a datasets retention policy + * @param {string} urn the urn for the dataset + * @return {string} + */ +const datasetRetentionUrlByUrn = (urn: string): string => `${datasetUrlByUrn(urn)}/retention`; + +/** + * Fetches the list of retention policy for a dataset by urn + * @param {string} urn urn for the dataset + * @return {Promise>} + */ +const readDatasetRetentionByUrn = async (urn: string): Promise => { + try { + return await getJSON({ url: datasetRetentionUrlByUrn(urn) }); + } catch (e) { + if (notFoundApiError(e)) { + return null; + } + + throw e; + } +}; + +/** + * Persists the dataset retention policy remotely + * @param {string} urn the urn of the dataset to save + * @param {IDatasetRetention} retention the dataset retention policy to updae + * @return {Promise} + */ +const saveDatasetRetentionByUrn = (urn: string, retention: IDatasetRetention): Promise => + postJSON({ url: datasetRetentionUrlByUrn(urn), data: retention }); + +export { readDatasetRetentionByUrn, saveDatasetRetentionByUrn };