import { Collection , ComponentRequestTable , ConceptDb , ConceptServer , ConceptServerBuilder , Config , Context , getReturnFields } from '@deja-vu/concept-server' ; import { IResolvers } from 'graphql-tools' ; import * as _ from 'lodash' ; import { v4 as uuid } from 'uuid' ; import { CreateTaskInput , CreateTasksForAssigneesInput , TaskDoc , TasksInput , UpdateTaskInput } from './schema' ; const componentRequestTable = { 'approve-task' : ( extraInfo ) => `
    mutation ApproveTask($id: ID!) {
      approveTask (id: $id) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'claim-task' : ( extraInfo ) => `
    mutation ClaimTask($id: ID!, $assigneeId) {
      claimTask (id: $id, assigneeId: $assigneeId) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'complete-task' : ( extraInfo ) => `
    mutation CompleteTask($id: ID!) {
      completeTask (id: $id) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'create-task' : ( extraInfo ) => `
    mutation CreateTask($input: CreateTaskInput!) {
      createTask (input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'create-tasks-for-assignees' : ( extraInfo ) => `
    mutation CreateTasksForAssignees($input: CreateTasksForAssigneesInput!) {
      createTasksForAssignees (input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'show-tasks' : ( extraInfo ) => `
    query ShowTasks($input: TasksInput!) {
      tasks(input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'show-task-count' : ( extraInfo ) => `
    query ShowTaskCount($input: TasksInput!) {
      taskCount(input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'update-task' : ( extraInfo ) => { switch ( extraInfo . action ) { case 'update' : return `
          mutation UpdateTask($input: UpdateTaskInput!) {
            updateTask(input: $input) ${ getReturnFields ( extraInfo ) }
          }
        ` ; case 'load' : return `
          query Task($id: ID!) {
            task(id: $id) ${ getReturnFields ( extraInfo ) }
          }
        ` ; default : throw new Error ( 'Need to specify extraInfo.action' ) ; } } } ; function getTaskFilter ( input ) { const filter = _ . omit ( input , [ 'assigned' ] ) ; if ( input . assigned === false ) { filter [ 'assigneeId' ] = null ; } filter [ 'pending' ] = { $in : [ null , { type : { $ne : 'create-task' } } ] } ; return filter ; } async function updateTask ( tasks , id , updateOp , _updateType , context ) { return await tasks . updateOne ( context , { id } , updateOp ) ; } function resolvers ( db , _config ) { const tasks = db . collection ( 'tasks' ) ; return { Query : { tasks : async ( _root , { input } ) => { const filterOp = _ . omit ( input , [ 'assigned' ] ) ; if ( input . assigned === false ) { filterOp [ 'assigneeId' ] = null ; } return await tasks . find ( filterOp ) ; } , task : async ( _root , { id } ) => await tasks . findOne ( { id : id } ) , taskCount : async ( _root , { input } ) => { return await tasks . countDocuments ( getTaskFilter ( input ) ) ; } } , Task : { id : ( task ) => task . id , assignerId : ( task ) => task . assignerId , assigneeId : ( task ) => task . assigneeId , dueDate : ( task ) => task . dueDate } , Mutation : { createTask : async ( _root , { input } , context ) => { const newTask = { id : input . id ? input . id : uuid ( ) , assignerId : input . assignerId , assigneeId : input . assigneeId , dueDate : input . dueDate , completed : false , approved : false } ; return await tasks . insertOne ( context , newTask ) ; } , createTasksForAssignees : async ( _root , { input } , context ) => { const newTasks = _ . map ( input . assigneeIds , ( assigneeId ) => { return { id : uuid ( ) , assignerId : input . assignerId , assigneeId : assigneeId , dueDate : input . dueDate , completed : false , approved : false } ; } ) ; return await tasks . insertMany ( context , newTasks ) ; } , updateTask : async ( _root , { input } , context ) => { return updateTask ( tasks , input . id , { $set : input } , 'update-task' , context ) ; } , claimTask : async ( _root , { id , assigneeId } , context ) => { return updateTask ( tasks , id , { $set : { assigneeId : assigneeId } } , 'claim-task' , context ) ; } , approveTask : async ( _root , { id } , context ) => { return updateTask ( tasks , id , { $set : { approved : true } } , 'approve-task' , context ) ; } , completeTask : async ( _root , { id } , context ) => { return updateTask ( tasks , id , { $set : { completed : true } } , 'complete-task' , context ) ; } } } ; } const taskConcept = new ConceptServerBuilder ( 'task' ) . initDb ( ( db , _config ) : Promise < any > => { const tasks = db . collection ( 'tasks' ) ; return tasks . createIndex ( { id : 1 } , { unique : true , sparse : true } ) ; } ) . componentRequestTable ( componentRequestTable ) . resolvers ( resolvers ) . build ( ) ; taskConcept . start ( ) ;