Our powerful JS Calendar component


Post by byron »

Hello Bryntum team,

I’m using the Bryntum Calendar in timeline mode, and when initializing it in our QA environment, I encounter the following console error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'groupRenderer')
    at F (TestCalendar-[hash:12].js:311:335431)
    at Dt.t [as inSet] (TestCalendar-[hash:12].js:311:336240)
    at Dt.t [as set] (TestCalendar-[hash:12].js:311:332880)
    at Dt.set [as groupRenderer] (TestCalendar-[hash:12].js:311:307633)
    at eval (TestCalendar-[hash:12].js:311:1759069)
    at eval (TestCalendar-[hash:12].js:311:1760008)
    at module (TestCalendar-[hash:12].js:311:3857906)
    at 642894f57e8efde237ee20b2c8a51e63555033af.js?meteor_js_resource=true:47:764
    at g (642894f57e8efde237ee20b2c8a51e63555033af.js?meteor_js_resource=true:7:1100)
    at d.r [as require] (642894f57e8efde237ee20b2c8a51e63555033af.js?meteor_js_resource=true:7:3658)

This error only happens in our QA environment.
Locally (localhost), the exact same code works without issues

We are using Vite + Meteor + Solid, and the library is imported from a local folder (not from npm) following the 'Non npm' installation strategy, we added the folder in the root files of the project and renamed the 'build' folder to 'calendar'.

The strange thing is that this only happens after deploying to QA.
The build and deploy process for QA/Stage is done automatically via GitHub Actions using this workflow:

name: 'Build and Deploy for QA/Stage'
on:
  push:
    branches:
      - stage

jobs:
  build-on-ubuntu:
    name: 'Build on Ubuntu'
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v4

  - name: "Update build number"
    env:
      BUILD_NUMBER:  ${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}
    run: |
      echo  "{\"version\": \"$BUILD_NUMBER\"}" > ./imports/helpers/version.json

  - name: 'Setup Meteor'
    uses: meteorengineer/setup-meteor@v2
    with:
      meteor-release: '2.13.3'

  - name: 'Install dependencies'
    run: meteor npm i

  - name: 'Build for production'
    run: meteor build build

  - name: 'Upload bundle'
    uses: appleboy/scp-action@v0.1.4
    with:
      host: scrubs-qa.ademsys.com
      username: scrubs
      source: build/scrubs.tar.gz
      target: /home/scrubs
      key: 'Key'
  
  deploy-on-success:
    name: 'Deploy on QA'
    needs: build-on-ubuntu
    runs-on: [self-hosted, Linux, X64, QA, Scrubs]
    steps:
      - name: 'Update package.json'
        run: |
          cd /home/scrubs/build
          tar -xzf scrubs.tar.gz
          cd bundle/programs/server
          npm i --production
          rm -rf /home/scrubs/bundle
          mv /home/scrubs/build/bundle /home/scrubs
      
- name: 'Reload pm2' run: | cd /home/scrubs/bundle pm2 reload main --update-env sudo systemctl restart nginx - name: 'Cleanup' run: | cd /home/scrubs/build rm -rf * - name: 'Notify' env: BUILD_NUMBER: ${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }} run: | curl --request POST \ --url https://api.sendgrid.com/v3/mail/send \ --header 'Authorization: Bearer ${{ 'Key' }}' \ --header 'Content-Type: application/json' \ --data '{"personalizations":[{"to":[{"email":"support@ademsys.com"}],"subject":"Scrubs Deployed to STAGE/QA"}],"content": [{"type": "text/plain", "value": "Hey! Scrubs version ${{ env.BUILD_NUMBER }} has been deployed to Stage/QA."}],"from":{"email":"internclic@ademsys.com","name":"InternClic Robot 🤖"},"reply_to":{"email":"internclic@ademsys.com","name":"InternClic Robot 🤖"}}'

The error seems to be related to some groupRenderer property, but I have not defined it manually anywhere.

Could you please help me understand if I am missing some setting that depends on the environment or if it is an internal problem of the plugin?

For additional context, here’s the complete component where the Calendar is instantiated (this works locally but throws the error in QA):

import { onMount } from 'solid-js'
import { Calendar, LocaleManager } from '../../../../calendar/calendar.module.js'
import { usePageContext } from '../Page'
import {
  Box,
  Button
} from '@suid/material'
import '../../../../calendar/calendar.stockholm.css'
import '../../../../calendar/locales/calendar.locale.Es.js'

const TestCalendar = () => {
  console.log('Start TestCalendar.jsx...') // not printed in QA

  let calendarEl

  const [, setPageTitle] = usePageContext()
  setPageTitle('TestCalendar -- Run on QA')

  onMount(() => {
    console.log('On Mount') // not printed in QA

LocaleManager.locale = 'En'
const tickWidth = 70
const calendar = new Calendar({
  appendTo: 'calendarEl',

  // Start life looking at this date
  date: new Date(),
  createEventOnDblClick: false,
  dragCreateTime: true,
  onBeforeDragCreateEnd: ({ context }) => {
    console.log('onBeforeDragCreateEnd', context)

    if (context) {
      const tempEvent = {
        id: Date.now(),
        name: 'Nuevo Evento', // Nombre predeterminado
        startDate: context.startDate,
        endDate: context.endDate,
        resourceId: context.resourceRecord ? context.resourceRecord.id : 1
      }
      alert(tempEvent)
    }

    return false
  },
  features: {
    eventMenu: {
      items: {
        editEvent: {
          text: 'Edit',
          weight: 100
        }
      }
    }
  },
  resources: [],
  events: [],

  tbar: {
    items: {
      scale: {
        type: 'slider',
        text: 'Scale',
        min: 25,
        max: 100,
        value: tickWidth,
        weight: 650,
        // eslint-disable-next-line no-return-assign
        onInput: ({ value }) => calendar.modes.timeline.tickSize = value
      }
    }
  },

  mode: 'timeline',

  modes: {
    day: null,
    week: null, // { dayStartTime: 0, dayEndTime: 23 },
    month: null,
    year: null,

    timeline: {
      type: 'scheduler',
      title: 'Timeline',
      eventStyle: 'calendar',
      useInitialAnimation: false,

      columns: [
        {
          field: 'name',
          text: 'Filter',
          flex: 1
        }
      ],

      features: {
        filterBar: false,
        nonWorkingTime: true,
        timeRanges: true,
        resourceTimeRanges: true
      },

      workingTime: {
        fromHour: 8,
        toHour: 22
      },

      barMargin: 3,

      viewPreset: {
        base: 'hourAndDay',
        tickWidth,
        headers: [
          { unit: 'day', dateFormat: 'ddd MM/DD' },
          { unit: 'hour', dateFormat: 'h a' }
        ]
      },

      listeners: {
        beforeDragCreate: ({ eventRecord }) => {
          console.log('Before Drag Create')
          return true
        },
        // Cuando se hace clic en un evento existente
        eventClick: ({ eventRecord }) => {
          console.log('Edit')
          return false
        },
        eventRenderer: ({ eventRecord, renderData }) => {
          console.log('Expand')
          renderData.enableExpand = false
          return renderData
        },
        beforeEventAdd: ({ eventRecord }) => {
          console.log('Before Event Add')
          alert(eventRecord)
          return false
        }
      }
    }
  }
})
  })

  return (
    <>
      <Box sx={{ height: '98%', width: '98%', background: '#eeeeee', display: 'flex', flexDirection: 'column' }}>
        <Box sx={{ padding: 1, display: 'flex', justifyContent: 'flex-end' }}>
          <Button
            variant="contained"
            color="primary"
            onClick={() => alert('Open Form')}
          >
            {'Add'}
          </Button>
        </Box>

    <div
      ref={calendarEl}
      id="calendarEl"
      style={{
        height: '90%',
        'will-change': 'transform'
      }}
    />

  </Box>
</>
  )
}

export default TestCalendar

Any help or ideas on what could be causing this difference between local and QA would be greatly appreciated!

Thank you very much in advance.


Post by marcio »

Hello Byron,

Thanks for reaching out and welcome to our forums!

Since this issue only occurs in your QA environment, it could be related to differences in the build or deployment process.

Here are a few things you can check:

  1. Environment Differences: Ensure that the QA environment has the same version of all dependencies as your local environment. Sometimes, differences in package versions can lead to unexpected behavior.

  2. Build Process: Verify that the build process in your GitHub Actions workflow is correctly handling all files and dependencies. Ensure that the Bryntum Calendar files are correctly included and not altered during the build.

  3. Configuration: Double-check your configuration settings for the Calendar. Ensure that all required properties are set correctly and consistently across environments.

  4. Console Logs: Since your console logs are not printed in QA, it might indicate that the component is not being mounted correctly. Check if there are any errors or issues during the component's lifecycle that might prevent it from initializing.

  5. Deployment Artifacts: Ensure that the deployment artifacts are correctly transferred and unpacked in the QA environment. Sometimes, files might be missing or corrupted during the transfer.

If none of these steps resolve the issue, you might need to provide more information about the differences between your local and QA environments, or check if there are any specific configurations or settings that might be affecting the Calendar's behavior.

Feel free to reach out if you need further assistance!

Best regards,
Márcio

How to ask for help? Please read our Support Policy


Post by sergey.maltsev »

Hi!

I suppose that error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'groupRenderer')
    at F (TestCalendar-[hash:12].js:311:335431)

occurs when running tests in a CI/CD environment.

Our components require a fully functional DOM to work properly. If your tests rely on a virtual DOM, it may lack essential features.
Please consider using a testing solution that operates with a real browser environment, such as Puppeteer or Playwright.

You may set a debugger at the line where this error happens (if possible) and see what is there.

To give more precise answer we need more information on what you use for that and how we can test it.


Post by Animal »

Note that createEventOnDblClick is not a configuration property of the Calendar product.

You are using two products there.

The outermost UI (and the Agenda view) are the Calendar product.

The timeline view is an instance of the Scheduler product.

Only Scheduler has createEventOnDblClick, so the timeline view must use that (for now).

Calendar has the more granular autoCreate option, so the Agenda view must use that.

I suggest using modeDefaults to set these up while there is this discrepancy:

modeDefaults : {
    // Timeline mode will act upon this
    createEventOnDblClick : false,

    // Calendar modes will act upon this
    autoCreate : false
}

We have a ticket to unify these two under the more functional configuration: https://github.com/bryntum/support/issues/4399

When this is released, you may simply configure the Calendar with autoCreate : false

Note that this does not prevent all event creation through the UI. You may still drag-create events. You may still right-click and use the menu to create events. You may still copy/paste to create new events.

https://bryntum.com/products/calendar/docs/api/Calendar/view/Calendar#config-modeDefaults
https://bryntum.com/products/calendar/docs/api/Calendar/widget/mixin/CalendarMixin#config-autoCreate


Post Reply