UNPKG

@finos/legend-application-marketplace

Version:
242 lines (228 loc) 7.82 kB
/** * Copyright (c) 2020-present, Goldman Sachs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ActionState, assertErrorThrown, type GeneratorFn, type PlainObject, } from '@finos/legend-shared'; import { deserialize } from 'serializr'; import { type V1_ContractUserEventRecord, type V1_TaskStatusChangeResponse, V1_TaskStatusChangeResponseModelSchema, type V1_TaskStatus, type V1_DataContract, V1_DataContractsRecordModelSchema, type V1_DataContractsRecord, type V1_PendingTasksRespond, V1_pendingTasksRespondModelSchema, type V1_UserPendingContractsRecord, type V1_TaskMetadata, } from '@finos/legend-graph'; import { makeObservable, flow, observable, flowResult, action } from 'mobx'; import { type LakehouseEntitlementsStore, TEST_USER, } from './LakehouseEntitlementsStore.js'; import { LakehouseViewerState } from './LakehouseViewerState.js'; import { buildTaskGridItemDetail, type GridItemDetail, } from '../LakehouseUtils.js'; import { generateLakehouseContractPath } from '../../../__lib__/LegendMarketplaceNavigation.js'; export class EntitlementsTaskViewerState extends LakehouseViewerState { readonly value: V1_ContractUserEventRecord; readonly approvalStatus = ActionState.create(); canApprove: boolean | undefined; dataContract: V1_DataContract | undefined; pendingAssociatedContractEvent: V1_UserPendingContractsRecord[] | undefined; changingTaskState = ActionState.create(); taskAssignees: string[] | undefined; constructor(value: V1_TaskMetadata, state: LakehouseEntitlementsStore) { super(state); this.value = value.rec; this.taskAssignees = value.assignees; makeObservable(this, { canApprove: observable, pendingAssociatedContractEvent: observable, setPendingAssociatedContractEvent: action, setCanApprove: action, approve: flow, deny: flow, init: flow, calculateApprovalRights: flow, fetchContract: flow, dataContract: observable, taskAssignees: observable, }); this.observeContract(); } get id(): string { return this.value.taskId; } setPendingAssociatedContractEvent( pendingAssociatedContractEvent: V1_UserPendingContractsRecord[] | undefined, ): void { this.pendingAssociatedContractEvent = pendingAssociatedContractEvent; } *init(token: string | undefined): GeneratorFn<void> { this.initializationState.inProgress(); Promise.all([ flowResult(this.calculateApprovalRights(token)).catch( this.lakehouseEntitlementsStore.applicationStore.alertUnhandledError, ), flowResult(this.fetchContract(token)).catch( this.lakehouseEntitlementsStore.applicationStore.alertUnhandledError, ), ]) .catch( this.lakehouseEntitlementsStore.applicationStore.alertUnhandledError, ) .finally(() => this.initializationState.complete()); } setCanApprove(val: boolean | undefined): void { this.canApprove = val; } observeContract(): void { makeObservable(this.value, { status: observable, }); } *approve(token: string | undefined): GeneratorFn<void> { try { this.approvalStatus.inProgress(); const response = (yield this.lakehouseEntitlementsStore.lakehouseServerClient.approveTask( this.value.taskId, token, )) as PlainObject<V1_TaskStatusChangeResponse>; const change = deserialize( V1_TaskStatusChangeResponseModelSchema, response, ); if (change.errorMessage) { this.approvalStatus.fail(); throw new Error( `Unable to approve task: ${this.value.taskId}: ${change.errorMessage}`, ); } this.value.status = change.status; this.setCanApprove(false); this.approvalStatus.pass(); this.lakehouseEntitlementsStore.applicationStore.notificationService.notifySuccess( 'Approval succeeded', ); } catch (error) { this.approvalStatus.fail(); assertErrorThrown(error); this.lakehouseEntitlementsStore.applicationStore.notificationService.notifyError( `${error.message}`, ); } } *deny(token: string | undefined): GeneratorFn<void> { try { this.changingTaskState.inProgress(); this.lakehouseEntitlementsStore.applicationStore.alertService.setBlockingAlert( { message: 'Denying Task', prompt: 'Denying task...', showLoading: true, }, ); const response = (yield this.lakehouseEntitlementsStore.lakehouseServerClient.denyTask( this.value.taskId, token, )) as PlainObject<V1_TaskStatus>; const change = deserialize( V1_TaskStatusChangeResponseModelSchema, response, ); if (change.errorMessage) { throw new Error( `Unable to deny task: ${this.value.taskId}: ${change.errorMessage}`, ); } this.value.status = change.status; this.setCanApprove(false); this.lakehouseEntitlementsStore.applicationStore.notificationService.notifySuccess( `Task has been denied`, ); } catch (error) { assertErrorThrown(error); this.lakehouseEntitlementsStore.applicationStore.notificationService.notifyError( `${error.message}`, ); } finally { this.changingTaskState.complete(); this.changingTaskState.setMessage(undefined); this.lakehouseEntitlementsStore.applicationStore.alertService.setBlockingAlert( undefined, ); } } *calculateApprovalRights(token: string | undefined): GeneratorFn<void> { this.canApprove = undefined; try { const rawTasks = (yield this.lakehouseEntitlementsStore.lakehouseServerClient.getPendingTasks( TEST_USER, token, )) as PlainObject<V1_PendingTasksRespond>; const tasks = deserialize(V1_pendingTasksRespondModelSchema, rawTasks); const allTasks = [...tasks.dataOwner, ...tasks.privilegeManager]; const canApprove = Boolean( allTasks.find((e) => e.taskId === this.value.taskId), ); this.setCanApprove(canApprove); } catch (error) { assertErrorThrown(error); } } *fetchContract(token: string | undefined): GeneratorFn<void> { try { const contractId = this.value.dataContractId; const dataContracts = (yield this.lakehouseEntitlementsStore.lakehouseServerClient.getDataContract( contractId, token, )) as PlainObject<V1_DataContractsRecord>; const dataContract = deserialize( V1_DataContractsRecordModelSchema, dataContracts, ).dataContracts?.[0]?.dataContract; this.dataContract = dataContract; } catch (error) { assertErrorThrown(error); } } get taskDetails(): GridItemDetail[] { return buildTaskGridItemDetail( this.value, this.taskAssignees, this.dataContract, (id: string): void => { this.lakehouseEntitlementsStore.applicationStore.navigationService.navigator.updateCurrentLocation( generateLakehouseContractPath(id), ); }, this.lakehouseEntitlementsStore.directoryCallBack, this.lakehouseEntitlementsStore.applicationCallBack, ); } }