Premium support for our pure JavaScript UI components


Post by sudhanshu.jain »

Hi , we are trying to achieve the below thinks.

  1. How can we make all cells gray in scheduler pro. As of now, all cells look white. But we want all cells to look gray. Which props we should provide in the react scheduler pro component.?? Please find attachement.

2.How resources can have multiple calanders/intervals on the same day(here we are not talking about resourceTimeRange).

"calendars"          : {
        "rows" : [
            {
                "id"                       : "day",
                "name"                     : "Day shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 8:00",
                        "recurrentEndDate"   : "at 17:00",
                        "isWorking"          : true
                    }
                ]
            },
            {
                "id"                       : "early",
                "name"                     : "Early shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 6:00",
                        "recurrentEndDate"   : "at 14:00",
                        "isWorking"          : true
                    }
                ]
            }]}
"resources"          : {
        "rows" : [
            {
                "id"         : 1,
                "name"       : "George",
                "calendar"   : "day",
                "role"       : "Office",
                "eventColor" : "blue"
            },
            {
                "id"         : 2,
                "name"       : "Rob",
                "calendar"   : "day",
                "role"       : "Office",
                "eventColor" : "blue"
            }]}

Here in above code example , intervals is array of object . Can we pass multiple objects into intervals ?? like below

 "intervals"                : [
                    {
                        "recurrentStartDate" : "at 8:00",
                        "recurrentEndDate"   : "at 11:00",
                        "isWorking"          : true
                    },
                   {
                        "recurrentStartDate" : "at 12:00",
                        "recurrentEndDate"   : "at 13:00",
                        "isWorking"          : true
                    }
                ]
  1. Here resources only accept one calendar as value. How it can take multiple calendar values??
 {
                "id"         : 1,
                "name"       : "George",
                "calendar"   : "day",
                "role"       : "Office",
                "eventColor" : "blue"
            }

Here it resource only taking one value "calendar": "day", how it can take multiple values in calendar??

  1. Which props react scheduler pro component accept for calendars data ??
     <BryntumScheduler
            ref = {scheduler}
            autoHeight = {true}
            viewPreset = {getViewPreset(timelineView)}
           
    resources = {data.resources} calendars={data.calendars} events = {data.events} startDate = {new Date(endYear, ZERO, ONE)} endDate = {new Date(endYear, TEN, TWENTY_TWO)} emptyText = {'No matches'} columns = {getColumnsList(getLodash(jsonDef, 'columns', []))} filterBarFeature = {true} // to enable search on columns eventStyle = {'colored'} eventBodyTemplate = {(data) => getEventTemplate(data)} eventRenderer = {(eventRecord) => eventRenderer(eventRecord)} stripeFeature={true} resourceTimeRangeStore={resourceTimeRangeStore} timeRangesFeature = {{ showCurrentTimeLine: true, showHeaderElements: true, enableResizing: true }} resourceNonWorkingTimeFeature={true} nonWorkingTimeFeature = {true} resourceTimeRangesFeature={true} maxTimeAxisUnit = {'week'}

can you please tell me because "calendars={data. calendars}" is not working.

Attachments
Please open file and find comment in file.
Please open file and find comment in file.
Cells-Gray-Calander-Intervals.png (414.81 KiB) Viewed 2173 times

Post by Maxim Gorkovsky »

Hello.

How can we make all cells gray in scheduler pro. As of now, all cells look white. But we want all cells to look gray. Which props we should provide in the react scheduler pro component.?? Please find attachement.

You attachment says you want to show non working time as grey and working time as white on per resource basis. You need to use ResourceTimeRanges feature.

  1. For every resource you should manually calculate working/non-working time according to the resource calendar and add corresponding ranges to the time ranges store.
  2. You should also regenerate ranges when time span changes.
  3. To calculate non working time you can use calendar.skipNonWorkingTime method. Start from scheduler start date, stop when next working time is after scheduler end.

How resources can have multiple calanders/intervals on the same day(here we are not talking about resourceTimeRange).

Resource, events and projects can only have single calendar. You can define multiple intervals per day. There are several ways to define intervals, see calendar guide for more info.

Can we pass multiple objects into intervals ?

Yes. Array properties always can accept multiple values.

Here resources only accept one calendar as value. How it can take multiple calendar values??

Resource can only have single calendar. You can organize calendars in a tree to inherit intervals from one another. This feature is also covered in calendars guide

Which props react scheduler pro component accept for calendars data ??

  1. You're using regular scheduler here, not a pro version
  2. Calendars data can be provided via project calendarData config, like
    project : {
      calendarsData : ...,
      resourcesData : ...,
      eventsData : ...
    }

Post by sudhanshu.jain »

Hi ,

Some of the points help. But now please be specific for the REACT.

How can we achieve a calendar non working (https://bryntum.com/examples/scheduler-pro/resource-non-working-time/) for the REACT-SCHEDULE PRO . Like how to pass below calendar data to the scheduler pro component. Through which props SCHEDULER PRO REACT accept calendar data ???????

"calendars"          : {
        "rows" : [
            {
                "id"                       : "day",
                "name"                     : "Day shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 8:00",
                        "recurrentEndDate"   : "at 17:00",
                        "isWorking"          : true
                    },
                    {
                        "recurrentStartDate" : "at 8:00"
                    }
                ]
            },
            {
                "id"                       : "early",
                "name"                     : "Early shift",
                "unspecifiedTimeIsWorkingz" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 6:00",
                        "recurrentEndDate"   : "at 14:00",
                        "isWorking"          : true
                    }
                ]
            },
            {
                "id"                       : "late",
                "name"                     : "Late shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 14:00",
                        "recurrentEndDate"   : "at 22:00",
                        "isWorking"          : true
                    }
                ]
            },
            {
                "id"                       : "night",
                "name"                     : "Night shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 22:00",
                        "recurrentEndDate"   : "at 6:00",
                        "isWorking"          : true
                    }
                ]
            }
        ]
    }

You suggested to give calanderData as below but this is now working

project : {
  calendarsData : ...,
  resourcesData : ...,
  eventsData : ...
}

.

Please suggest how we can achieve https://bryntum.com/examples/scheduler-pro/resource-non-working-time/ in REACT-SCHEDULER PRO , Because non of your suggested solution is working.

So could you check at your end that how this feature (https://bryntum.com/examples/scheduler-pro/resource-non-working-time/) works in REACT OR it works or not in REACT and please give a specific solution .

Hoping for a solution in REACT

Thanks


Post by saki »

Actually, the same approach is used for React. You define project with the above data entries. The only difference is that data should be array of objects without rows key. For example:

project : {
  calendarsData : [
            {
                "id"                       : "day",
                "name"                     : "Day shift",
                "unspecifiedTimeIsWorking" : false,
                "intervals"                : [
                    {
                        "recurrentStartDate" : "at 8:00",
                        "recurrentEndDate"   : "at 17:00",
                        "isWorking"          : true
                    },
                    {
                        "recurrentStartDate" : "at 8:00"
                    }
                ]
            },
            // ... etc
  ]

Post by sudhanshu.jain »

Hi ,

Above solution is still not helpful.

Please find our scheduler wrapper below. This is REACT Scheduler Pro Wrraper .

<BryntumScheduler
        ref = {scheduler}
        autoHeight = {true}
        zoomOnMouseWheel={false}
        zoomOnTimeAxisDoubleClick={false}
        viewPreset = {getViewPreset(timelineView)}
        project= { {
          calendarsData: data.calendarsData
        } }
        events = {data.events}
        resources = {data.resources}
        timeRanges={data.timeRanges}
        resourceTimeRangeStore={resourceTimeRangeStore}
        resourceTimeRangesFeature={true}
        nonWorkingTimeFeature={true}
        startDate = {startDate}
        visibleDate = {new Date()}
        emptyText = {'No matches'}
        columns = {getColumnsList(getLodash(jsonDef, 'columns', []))}
        filterBarFeature = {true} // to enable search on column
        eventStyle = {'colored'}
        eventLayout = {'stack'}
        eventBodyTemplate = {(data) => getEventTemplate(data)}
        eventRenderer = {(eventRecord) => eventRenderer(eventRecord)}
        eventMenuFeature = {false} // disable contextmenu on rgt click of events
        eventEditFeature = {{
          disabled: true // disable event edit popup on double click of events
        }}
        eventDragCreateFeature = {{
          disabled: true // disable event creation on drag
        }}
        eventDragFeature = {{
          disabled: !jsonDef?.dragAllow,
          validatorFn ({ startDate }) {
            if(moment().isAfter(startDate, 'second')) {
              return {
                valid: false,
                message: ErrorMessageForPastDate
              };
            }
            return {
              valid: true
            };
          }
        }}
        eventResizeFeature = {{
          disabled: true
        }}
        stripeFeature={true}
        timeRangesFeature = {{
          showCurrentTimeLine: true,
          showHeaderElements: true,
          enableResizing: true
        }}
      />

.

And above Scheduler wrapper pointing to your SchedulerPro Wrapper as below.

/* eslint-disable */
/**
 * React Scheduler wrapper
 */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// We import schedulerpro.umd for IE11 compatibility only. If you don't use IE import:
// import { Scheduler, ObjectHelper, Widget } from 'bryntum-schedulerpro';
import { Scheduler, ObjectHelper, Widget } from '@bryntum/schedulerpro';

// Defines a React component that wraps Bryntum Scheduler
class BryntumScheduler extends Component {

  /**
     * @deprecated in favor of schedulerInstance
     */
  get schedulerEngine () {
    console.warn('schedulerEngine is deprecated. Use schedulerInstance instead.');
    return this.schedulerInstance;
  }

// Defaults for scheduler the scheduler wrapper
static defaultProps = {
  viewPreset: 'hourAndDay',
  barMargin: 2,
  /**
     * The number of React portals equals the scrolling buffer size
     * if set to true. The unused portals are removed from memory and DOM
     * at the cost of rendering performances (scrolling speed).
     * If set to false (default) the portals and their elements are kept
     * in memory and DOM.
     * @config {Boolean}
     * @default
     */
  discardPortals: false
};

featureRe = /Feature$/;

/* #region Features */
features = [
  'cellEditFeature',
  'cellMenuFeature',
  'cellTooltipFeature',
  'columnDragToolbarFeature',
  'columnLinesFeature',
  'columnPickerFeature',
  'columnReorderFeature',
  'columnResizeFeature',
  'dependenciesFeature',
  'dependencyEditFeature',
  'eventDragCreateFeature',
  'eventDragFeature',
  'eventDragSelectFeature',
  'eventEditFeature',
  'eventFilterFeature',
  'eventMenuFeature',
  'eventResizeFeature',
  'eventTooltipFeature',
  'filterBarFeature',
  'filterFeature',
  'groupFeature',
  'groupSummaryFeature',
  'headerMenuFeature',
  'headerZoomFeature',
  'labelsFeature',
  'nonWorkingTimeFeature',
  'panFeature',
  'pdfExportFeature',
  'quickFindFeature',
  'regionResizeFeature',
  'resourceTimeRangesFeature',
  'rowReorderFeature',
  'scheduleMenuFeature',
  'scheduleTooltipFeature',
  'searchFeature',
  'simpleEventEditFeature',
  'sortFeature',
  'stripeFeature',
  'summaryFeature',
  'timeAxisHeaderMenuFeature',
  'timeRangesFeature',
  'treeFeature'
];
/* #endregion */

/* #region Configs */
configs = [
  'allowOverlap',
  'animateRemovingRows',
  'assignments',
  'assignmentStore',
  'autoAdjustTimeAxis',
  'autoHeight',
  'barMargin',
  'columnLines',
  'columns',
  'contextMenuTriggerEvent',
  'createEventOnDblClick',
  'crudManager',
  'defaultResourceImageName',
  'dependencyStore',
  'disableGridRowModelWarning',
  'displayDateFormat',
  'emptyText',
  'enableDeleteKey',
  'enableEventAnimations',
  'enableRecurringEvents',
  'enableTextSelection',
  'endDate',
  'endParamName',
  'eventBarTextField',
  'eventBodyTemplate',
  'eventColor',
  'eventLayout',
  'eventRenderer',
  'events',
  'eventSelectionDisabled',
  'eventStore',
  'eventStyle',
  'fillLastColumn',
  'fillTicks',
  'fullRowRefresh',
  'hasVisibleEvents',
  'height',
  'hideHeaders',
  'horizontalEventSorterFn',
  'loadMask',
  'longPressTime',
  'maintainSelectionOnDatasetChange',
  'managedEventSizing',
  'maxHeight',
  'maxWidth',
  'maxZoomLevel',
  'milestoneAlign',
  'milestoneCharWidth',
  'milestoneLayoutMode',
  'minHeight',
  'minWidth',
  'minZoomLevel',
  'mode',
  'multiEventSelect',
  'partner',
  'passStartEndParameters',
  'presets',
  'readOnly',
  'removeUnassignedEvent',
  'resizeToFitIncludesHeader',
  'resourceColumns',
  'resourceImagePath',
  'resourceMargin',
  'resources',
  'resourceStore',
  'resourceTimeRanges',
  'responsiveLevels',
  'rowHeight',
  'scrollLeft',
  'scrollTop',
  'selectedEvents',
  'selectionMode',
  'showDirty',
  'snap',
  'snapRelativeToEventStartDate',
  'startDate',
  'startParamName',
  'subGridConfigs',
  'tickWidth',
  'timeRanges',
  'timeResolution',
  'triggerSelectionChangeOnRemove',
  'useInitialAnimation',
  'viewportCenterDate',
  'viewPreset',
  'weekStartDay',
  'width',
  'workingTime',
  'zoomLevel',
  'zoomOnMouseWheel',
  'zoomOnTimeAxisDoubleClick'
];
/* #endregion */

state = {
  portals: new Set(),
  // Needed to trigger refresh when portals change
  generation: 0
};

/**
 * Removes the unused portal (if discardPortals prop is true) or
 * hides the unused portal (if discardPortals is falsie - default)
 * @param {HTMLElement} cellElement
 * @private
 */
releaseReactCell (cellElement) {
  if(!cellElement) {
    return;
  }

  const { _domData: cellElementData, _domData: { portalHolder } } = cellElement;

  // Cell already has a react component in it; hide it or remove it
  if (portalHolder) {
    // Remove portal and its element
    if (this.props.discardPortals) {
      const { state, portalHolderMap } = this;

      // Remove React portal
      state.portals.delete(portalHolder.portal);

      // Remove portalHolder from both map and DOM
      portalHolderMap.delete(portalHolder.portal.key);
      portalHolder.remove();
      cellElementData.portalHolder = null;

      // Update state so that React knows something changed
      this.setState({ generation: state.generation++ });
    } else {
      // Hide the portal
      portalHolder.style.display = 'none';
    }
  }
}

// React component rendered to DOM, render scheduler to it
componentDidMount () {
  const
    { props } = this,
    config = {
      // Use this element as our encapsulating element
      adopt: this.el,
      callOnFunctions: true,
      features: {},

      // Hook called by engine when requesting a cell editor
      processCellEditor: ({ editor, field }) => {
        // String etc handled by feature, only care about fns returning React components here
        if (typeof editor !== 'function') {
          return;
        }

        // Wrap React editor in an empty widget, to match expectations from CellEdit/Editor and make alignment
        // etc. work out of the box
        const wrapperWidget = new Widget({
          name: field // For editor to be hooked up to field correctly
        });

        // Ref for accessing the React editor later
        wrapperWidget.reactRef = React.createRef();

        // column.editor is expected to be a function returning a React component (can be JSX). Function is
        // called with the ref from above, it has to be used as the ref for the editor to wire things up
        const reactComponent = editor(wrapperWidget.reactRef);
        if (reactComponent.$$typeof !== Symbol.for('react.element')) {
          throw new Error('Expect a React element');
        }

        let editorValidityChecked = false;

        // Add getter/setter for value on the wrapper, relaying to getValue()/setValue() on the React editor
        Object.defineProperty(wrapperWidget, 'value', {
          enumerable: true,
          get: function () {
            return wrapperWidget.reactRef.current.getValue();
          },
          set: function (value) {
            const component = wrapperWidget.reactRef.current;

            if (!editorValidityChecked) {
              const misses = ['setValue', 'getValue', 'isValid', 'focus'].filter(fn => !(fn in component));

              if (misses.length) {
                throw new Error(`
                                    Missing function${misses.length > 1 ? 's' : ''} ${misses.join(', ')} in ${component.constructor.name}.
                                    Cell editors must implement setValue, getValue, isValid and focus
                                `);
              }

              editorValidityChecked = true;
            }

            const context = wrapperWidget.owner.cellEditorContext;
            component.setValue(value, context);
          }
        });

        // Add getter for isValid to the wrapper, mapping to isValid() on the React editor
        Object.defineProperty(wrapperWidget, 'isValid', {
          enumerable: true,
          get: function () {
            return wrapperWidget.reactRef.current.isValid();
          }
        });

        // Override widgets focus handling, relaying it to focus() on the React editor
        wrapperWidget.focus = () => {
          wrapperWidget.reactRef.current.focus && wrapperWidget.reactRef.current.focus();
        };

        // Create a portal, making the React editor belong to the React tree although displayed in a Widget
        const portal = ReactDOM.createPortal(reactComponent, wrapperWidget.element);
        wrapperWidget.reactPortal = portal;

        const { state } = this;
        // Store portal in state to let React keep track of it (inserted into the Grid component)
        state.portals.add(portal);
        this.setState({
          portals: state.portals,
          generation: state.generation + 1
        });

        return { editor: wrapperWidget };
      },

      // Hook called by engine when rendering cells, creates portals for JSX supplied by renderers
      processCellContent: ({
        cellContent,
        cellElement,
        cellElementData,
        record
      }) => {
        let shouldSetContent = cellContent != null;

        // Release any existing React component (remove or hide)
        this.releaseReactCell(cellElement);

        // Detect React component
        if (
          cellContent &&
                    cellContent.$$typeof === Symbol.for('react.element')
        ) {
          // Excluding special rows for now to keep renderers simpler
          if (!record.meta.specialRow) {
            const { state, portalHolderMap } = this,
              portalId = `portal-${record.id}-${cellElementData.columnId}`;
            // Get already existing portal holder, exists if cell was previously rendered
            let existingPortalHolder = portalHolderMap.get(
              portalId
            );

            // Record changed, we need a new portal
            if (
              existingPortalHolder &&
                            record.generation !==
                                existingPortalHolder.generation
            ) {
              // Remove the old
              state.portals.delete(
                existingPortalHolder.portal
              );

              this.setState({
                generation: state.generation++
              });

              existingPortalHolder = null;
            }

            // Cell not previously rendered, create a portal for it
            if (!existingPortalHolder) {
              // Create a portal holder, an element that we will render the portal to.
              // Separate since we are going to hide it or remove it when no longer visible
              cellElement.innerHTML = `<div class="b-react-portal-holder" data-portal="${portalId}"></div>`;

              // Get the portal holder created above
              const portalHolder =
                                cellElement.firstElementChild;

              // Create a portal targeting the holder (will belong to the existing React tree)
              const portal = ReactDOM.createPortal(
                cellContent,
                portalHolder,
                portalId
              );

              // Link to element, for easy retrieval later
              cellElementData.hasReactPortal = true;
              cellElementData.portalHolder = portalHolder;
              portalHolder.portal = portal;

              // Store record generation, to be able to detect a change later
              portalHolder.generation = record.generation;

              // Put holder in a map, to be able to reuse/move it later
              portalHolderMap.set(portalId, portalHolder);

              // Store portal in state for React to not loose track of it
              state.portals.add(portal);
              this.setState({
                generation: state.generation++
              });
            }
            // Cell that already has a portal, reuse it
            else {
              // Move it to the cell
              cellElement.appendChild(existingPortalHolder);
              // Show it
              existingPortalHolder.style.display = '';
              // Link it
              cellElementData.portalHolder = existingPortalHolder;
            }
          }
          shouldSetContent = false;
        }

        return shouldSetContent;
      }
    };

  this.portalHolderMap = new Map();

  // Relay properties with names matching this.featureRe to features
  this.features.forEach(featureName => {
    if (featureName in props) {
      config.features[featureName.replace(this.featureRe, '')] = props[featureName];
    }
  });

  // Handle config (relaying all props except those used for features to scheduler)
  Object.keys(props).forEach(propName => {
    if (!propName.match(this.featureRe) && undefined !== props[propName]) {
      if (propName === 'features') {
        console.warn('Passing "features" object as prop is not supported. Set features one-by-one with "Feature" suffix, for example "timeRangesFeature".');
      } else {
        config[propName] = props[propName];
      }
    }
  });

  // console.log(config);

  // Create the actual scheduler, used as engine for the wrapper
  const engine = this.schedulerInstance = props.schedulerClass ? new props.schedulerClass(config) : new Scheduler(config);

  // Release any contained React components when a row is removed
  engine.rowManager.on({
    removeRow: ({ row }) => row.cells.forEach(cell => this.releaseReactCell(cell))
  });

  // Make stores easier to access
  this.resourceStore = engine.resourceStore;
  this.eventStore = engine.eventStore;

  // Map all features from schedulerInstance to scheduler to simplify calls
  Object.keys(engine.features).forEach(key => {
    const featureName = key + 'Feature';
    if (!this[featureName]) {
      this[featureName] = engine.features[key];
    }
  });

  // Shortcut to set syncDataOnLoad on the stores
  if (props.syncDataOnLoad) {
    engine.resourceStore.syncDataOnLoad = true;
    engine.eventStore.syncDataOnLoad = true;
  }

  if (config.events) {
    this.lastEvents = config.events.slice();
  }

  if (config.resources) {
    this.lastResources = config.resources.slice();
  }
}

// React component removed, destroy engine
componentWillUnmount () {
  this.schedulerInstance.destroy();
}

// Component about to be updated, from changing a prop using state. React to it depending on what changed and
// prevent react from re-rendering our component.
shouldComponentUpdate (nextProps, nextState) {
  const
    { props, schedulerInstance: engine } = this,
    // These props are ignored or has special handling below
    excludeProps = [
      'adapter',
      'children',
      'columns',
      'events',
      'eventsVersion',
      'features', // #445 React: Scheduler crashes when features object passed as prop
      'listeners', // #9114 prevents the crash when listeners are changed at runtime
      'ref',
      'resources',
      'resourcesVersion',
      'timeRanges',
      ...this.features
    ];

  // Reflect configuration changes. Since most scheduler configs are reactive the scheduler will update automatically
  Object.keys(props).forEach(propName => {
    // Only apply if prop has changed
    if (!excludeProps.includes(propName) && !ObjectHelper.isEqual(props[propName], nextProps[propName])) {
      engine[propName] = nextProps[propName];
    }
  });

  if (
  // resourceVersion used to flag that data has changed
    nextProps.resourcesVersion !== props.resourcesVersion ||
        // If not use do deep equality check against previous dataset
        // TODO: Might be costly for large datasets
        (!('resourcesVersion' in nextProps) && !('resourcesVersion' in props) && !ObjectHelper.isDeeplyEqual(this.lastResources, nextProps.resources))) {
    engine.resources = nextProps.resources;
    this.lastResources = nextProps.resources && nextProps.resources.slice();
  }

  if (
  // eventVersion used to flag that data has changed
    nextProps.eventsVersion !== props.eventsVersion ||
        // If not use do deep equality check against previous dataset
        // TODO: Might be costly for large datasets
        (!('eventsVersion' in nextProps) && !('eventsVersion' in props) && !ObjectHelper.isDeeplyEqual(this.lastEvents, nextProps.events))) {
    engine.events = nextProps.events;
    this.lastEvents = nextProps.events && nextProps.events.slice();
  }

  // Reflect feature config changes
  this.features.forEach(featureName => {
    const currentProp = props[featureName],
      nextProp = nextProps[featureName];

    if (featureName in props && !ObjectHelper.isDeeplyEqual(currentProp, nextProp)) {
      engine.features[featureName.replace(this.featureRe, '')].setConfig(nextProp);
    }
  });

  // Reflect JSX cell changes
  return (nextState.generation !== this.state.generation);
}

render () {
  return <div className={'b-react-schedulerpro-container'} ref={el => this.el = el}>{this.state.portals}</div>;
}

}

export default BryntumScheduler;

Now can please tell is there anything we are missing? How this feature((https://bryntum.com/examples/scheduler-pro/resource-non-working-time/)) will work along with

resources, timeRanges,events, resourceTimeRangeStore

????????????/

Caan you please check at your end with this feature (((https://bryntum.com/examples/scheduler-pro/resource-non-working-time/))) and provide a sample code for it.


Post by saki »

What I can see in the above code:

  • You use standard Scheduler, not Scheduler Pro, because you import Scheduler, not Scheduler Pro in the wrapper.
  • The wrapper seems to be old. Have you previously copied a wrapper to your project tree?

Starting from version 4.1.0 we provide Bryntum components and wrappers as NPM packages from private Bryntum repository.

The React integration guide describes how to use the new wrappers in the application and Pro React demos (resource-histogram and timeline) have been updated too.

So the first advise would be to upgrade Scheduler Pro to the latest version 4.1.3, remove any copied wrappers, take care to use SchedulerPro (not Scheduler) and try again. If this fails then we need a showcase that we could run, investigate and debug.


Post by sudhanshu.jain »

Hey,

I just wonder, have you ever tried this feature in REACT ?


Post by sudhanshu.jain »

Hey ,

Can you please try this feature(https://bryntum.com/examples/scheduler-pro/resource-non-working-time/) at your-end in React and provide the complete solution in the react code. As we are using a premium subscription, we have to escalate this ticket.


Post by saki »

Yes, the feature does work in React. Use the following example please.

Attachments
resource-non-working-time.zip
(1.68 MiB) Downloaded 127 times

Post by mats »

@sudhanshu.jain Is everything working now? Please let us know if you have face any other friction or things blocking your development.


Post Reply