bryntum / support

An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
https://www.bryntum.com
53 stars 6 forks source link

Scheduler Pro Lazy Loading Exception #9661

Closed Loupi closed 1 month ago

Loupi commented 1 month ago

Hello,

On Scheduler Pro 6.0.2 trial, with react.

I am using an extended ProjectModel (CrudManager). My extended project model overrides sendRequest, encode and decode to use Graphql. It works fine, except for one thing, I had to do this to hide the saving mask after an update.

useEffect(() => {
    if (ref.current) {
      ref.current.instance.crudManager.on({
        sync() {
          ref.current?.instance.unmask()
        },
      })
    }
  }, [ref])

It might be due to changes that I am not aware of, since I based my implementation on that post that dates back from 2020: based on https://forum.bryntum.com/viewtopic.php?t=15792

However, when I enable lazyLoad and infiniteScroll, an exception is thrown in loadAssignmentStore, when it tries to call the requestData function of the assignmentStore.

For an obscure reason, assignmentStore.requestData is null. Other stores present in CrudManager (eventStore, resourceStore) have a valid function assigned to requestData.

Here is the exception:

TypeError: b[aZB(...)] is not a function at DateStoreLazyLoadPlugin.loadAssignmentStore (chunk-R5CCTKOU.js?v=64efe968:87541:35) at DateStoreLazyLoadPlugin.doLazyLoad (chunk-R5CCTKOU.js?v=64efe968:87509:25) at DateStoreLazyLoadPlugin. (chunk-R5CCTKOU.js?v=64efe968:87451:28) at chunk-R5CCTKOU.js?v=64efe968:10793:43

Here is my GraphqlProjectModel for reference, based on https://forum.bryntum.com/viewtopic.php?t=15792

class GraphqlProjectModel extends ProjectModel {
  handleRequest(
    request: TransportRequest,
    error?: any,
    data?: any,
  ): Promise<any> {
    const { success, failure } = request

    if (error) {
      const response = {
        success: false,
        requestId: (request.data as any).requestId,
      }
      const responseData = { error }
      Object.assign(response, { ...responseData })
      const responseRaw = { text: () => {
        return Promise.resolve(response)
      }}
      return failure?.call(
        request.thisObj || this,
        responseRaw,
        {},
        request,
      ) as Promise<any>
    } else if (data) {
      const response = {
        success: true,
        requestId: (request.data as any).requestId,
      }
      Object.assign(response, { ...data })
      const responseRaw = {
        text: () => {
          return Promise.resolve(response)
        },
      }
      return success?.call(
        request.thisObj || this,
        responseRaw,
        {},
        request,
      ) as Promise<any>
    }

    throw new Error("Not supposed to be here")
  }

  decode(responseText: string): object {
    return responseText as any as object
  }

  encode(requestData: object): string {
    return requestData as any as string
  }

  async sendRequest(request: TransportRequest): Promise<any> {
    const params = Object.assign({}, request.params) as any

    // Must yield, otherwise params wont be filled :(
    await AsyncHelper.yield()

    this.trigger("beforeSend", {
      params,
      requestType: request.type,
      requestConfig: {},
      config: request,
    })

    const client = getClient()

    if (request.type === "load") {
      try {
        const queryPromise = client.query<
          GetSchedulerQuery,
          GetSchedulerQueryVariables
        >({
          query: GetSchedulerDocument,
          variables: {
            args: {
              requestId: request.id.toString(),
              startDate: params.startDate
                ? new Date(params.startDate)
                : undefined,
              endDate: params.endDate ? new Date(params.endDate) : undefined,
            },
          },
        })

        const { data, error } = await queryPromise

        if (data.getScheduler.data) {
          if (data.getScheduler.data.events?.rows) {
            for (const row of data.getScheduler.data.events.rows) {
              if (row.exceptionDates) {
                row.exceptionDates = JSON.parse(row.exceptionDates)
              }
            }
          }
        }

        const result = error ? undefined : data.getScheduler.data

        return Promise.all([
          queryPromise,
          this.handleRequest(request, error, result),
        ])
      } catch (e) {
        return this.handleRequest(request, e)
      }
    } else if (request.type === "sync") {
      const requestData = request.data as any

      if (requestData.events?.added) {
        for (const added of requestData.events.added) {
          if (added.exceptionDates) {
            added.exceptionDates = JSON.stringify(added.exceptionDates)
          }
        }
      }

      if (requestData.events?.updated) {
        for (const updated of requestData.events.updated) {
          if (updated.exceptionDates) {
            updated.exceptionDates = JSON.stringify(updated.exceptionDates)
          }
        }
      }

      try {
        const mutationPromise = client.mutate<
          UpdateSchedulerMutation,
          UpdateSchedulerMutationVariables
        >({
          mutation: UpdateSchedulerDocument,
          variables: {
            data: {
              data: requestData,
            },
          },
        })

        const { data, errors } = await mutationPromise
        const result = errors ? undefined : data?.updateScheduler.data

        return Promise.all([
          mutationPromise,
          this.handleRequest(request, errors, result),
        ])
      } catch (e) {
        return this.handleRequest(request, e)
      }
    }
  }
}
marciogurka commented 1 month ago

Hey Loupi,

Thanks for reaching out.

We have a forum for support and help with those types of questions, you can access that here https://bryntum.com/forum/.

Only issues reported by our team will be discussed here, the main help channel is the forum.

Please open a new thread in our forums to receive proper assistance or to have our team working a fix. We'll be waiting for you there.

Also, if you could provide a runnable test case for us to check, it would speed up the debugging process and help us understand what could be causing the behavior you're mentioning.