import Component from '@ember/component'; import { set } from '@ember/object'; import { assert } from '@ember/debug'; import { readDatasetSchemaComments, createDatasetSchemaComment, updateDatasetSchemaComment, deleteDatasetSchemaComment } from 'wherehows-web/utils/api/datasets/schema-comments'; import { augmentObjectsWithHtmlComments } from 'wherehows-web/utils/api/datasets/columns'; import { IDatasetComment } from 'wherehows-web/typings/api/datasets/comments'; import { IDatasetColumn } from 'wherehows-web/typings/api/datasets/columns'; import Notifications from '@datahub/utils/services/notifications'; import { NotificationEvent } from '@datahub/utils/constants/notifications'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import { TaskInstance, task } from 'ember-concurrency'; import { ETask } from '@datahub/utils/types/concurrency'; enum SchemaCommentActions { modify = 'modify', destroy = 'destroy', add = 'add' } interface IGetCommentsTaskArgs { datasetId: number; columnId: number; comments: Array; } export class SchemaComment extends Component { comments: Array = []; count = 0; datasetId = 0; columnId = 0; isShowingFieldComment = false; /** * Local reference to the notifications service * @memberof SchemaComment */ @service notifications: Notifications; /** * Enum of applicable values for schema comment actions * @type {SchemaCommentActions} */ SchemaCommentActions = SchemaCommentActions; /** * Task to get related schema comments * TODO: refactor move to container component */ @task(function*({ datasetId, columnId, comments }: IGetCommentsTaskArgs): IterableIterator>> { const schemaComments: Array = yield readDatasetSchemaComments(datasetId, columnId); if (Array.isArray(schemaComments)) { const withHtmlComments = augmentObjectsWithHtmlComments(schemaComments.map( ({ text }): Partial => ({ comment: text }) ) as Array); comments.setObjects.call(comments, withHtmlComments); } }) getCommentsTask!: ETask>, IGetCommentsTaskArgs>; @action showComments(): TaskInstance>> { const { datasetId, columnId, comments } = this; set(this, 'isShowingFieldComment', true); return this.getCommentsTask.perform({ datasetId, columnId, comments }); } @action hideComments(): boolean { return set(this, 'isShowingFieldComment', false); } /** * Given a schema comment action, invokes the related action to process the schema comment * @param {SchemaCommentActions} strategy * @return {Promise} */ @action async handleSchemaComment(strategy: SchemaCommentActions): Promise { const [, { text }] = arguments; const { datasetId, columnId, notifications, comments, getCommentsTask } = this; const { notify } = notifications; assert(`Expected action to be one of ${Object.keys(SchemaCommentActions)}`, strategy in SchemaCommentActions); const action = { add: (): Promise => createDatasetSchemaComment(datasetId, columnId, text), modify: (): Promise => updateDatasetSchemaComment(datasetId, columnId, text), destroy: (): Promise => deleteDatasetSchemaComment(datasetId, columnId) }[strategy]; try { await action(); notify({ type: NotificationEvent.success, content: 'Success!' }); // @ts-ignore ts limitation with the ember object model, fixed in ember 3.1 with es5 getters getCommentsTask.perform({ datasetId, columnId, comments }); } catch (e) { notify({ type: NotificationEvent.error, content: e.message }); } return false; } }