Hi Sergey thanks for replying. I tried to implement what was suggested but without any success... I'm copying the code of my component, I've added some comments for you to check where I implemented it to see if you can help me detect where is where I went wrong. My config is already inside my component:
import React, { useCallback, useRef, useEffect, useState, lazy } from 'react';
import { useDispatch, useSelector } from 'react-redux'
import {
BryntumScheduler,
} from '@bryntum/schedulerpro-react';
import { DateHelper, Menu, ResourceModel } from '@bryntum/schedulerpro'
// import ResourceModel from '@bryntum/schedulerpro/source/lib/SchedulerPro/model'
import '../../styles/styles.scss'
import {
isLoadingResourcesTypes,
isLoadingSchedulerResources,
loadResourcesTypes,
loadSchedulerResources
} from '../../redux/selectors';
import {
getResourcesSchedulerSearch,
getResourcesTypes,
setEmptyGetResourcesSchedulerSearch,
setEmptyResourcesTypes,
setFormFilters,
setLoadSpinner,
setUnLoadSpinner
} from '../../redux/actions';
import {
convertToTranslatedResourceType,
errorAlert,
getMessageTranslation
} from '../../utils';
import {
buildFiltersResourcesSchedulerSearchBusiness,
initModelResourcesSchedulerSearchBusiness
} from '../../business';
const TaskSchedulerSearchResourcesPopup = lazy(() => import('../TaskSchedulerSearchResourcesPopup'))
const Popup = lazy(() => import('../../components/Popup'))
const SchedulerPro = ({
user,
fieldsPage,
translation,
language,
scenario,
localization,
userConfiguration,
companies,
clientsClassesScenaries,
onTranslation,
messages,
usersCostCenters
}) => {
const dispatch = useDispatch()
const schedulerResources = useSelector(state => loadSchedulerResources(state))
const schedulerResourcesIsLoading = useSelector(state => isLoadingSchedulerResources(state))
const resourcesTypes = useSelector(state => loadResourcesTypes(state))
const resourcesTypesIsLoading = useSelector(state => isLoadingResourcesTypes(state))
const [schedulerResourcesResults, setSchedulerResourcesResults] = useState([])
const [openResourcesSchedulerSearchPopup, setOpenResourcesSchedulerSearchPopup] = useState(false)
const [cecos, setCecos] = useState([])
const [searchModel, setSearchModel] = useState(initModelResourcesSchedulerSearchBusiness())
useEffect(() => {
initializeSelectors()
handleSearch({ ...searchModel, scenaryId: scenario.id, userId: user.id })
}, [])
useEffect(() => {
if (resourcesTypes.length === 0 && !resourcesTypesIsLoading) {
dispatch(getResourcesTypes({ isActive: true }))
}
if (schedulerResourcesIsLoading) {
dispatch(setLoadSpinner())
} else {
setSchedulerResourcesResults(schedulerResources.map(sr => {
return {
id: sr.id,
name: sr.name,
resourceTypeId: convertToTranslatedResourceType(resourcesTypes, sr.resourceTypeId, language.id)
// initials: sr.name.getInitials().toUpperCase() // ver esto si queremos reducir a x digitos segun nombres y apellidos
}
}))
dispatch(setUnLoadSpinner())
}
}, [schedulerResources, schedulerResourcesIsLoading, resourcesTypes])
const initializeSelectors = useCallback(() => {
dispatch(setEmptyGetResourcesSchedulerSearch())
dispatch(setEmptyResourcesTypes())
}, [fieldsPage])
const handleSearch = (filters) => {
setSearchModel(filters)
dispatch(setEmptyGetResourcesSchedulerSearch())
const businessResult = buildFiltersResourcesSchedulerSearchBusiness(filters)
if (!businessResult.hasErrors) {
dispatch(setFormFilters(businessResult.content))
dispatch(getResourcesSchedulerSearch(businessResult.content))
} else {
errorAlert(getMessageTranslation(language.id, messages, 'code', businessResult.resultOperations[0].message))
}
}
const handleOnPopupSearch = (qualificationName, costCenterIds) => {
setOpenResourcesSchedulerSearchPopup(false)
handleSearch({ ...searchModel, qualificationName: qualificationName, costCenterIds: costCenterIds })
}
const handleOnOpenResourcesSchedulerSearchPopup = () => {
setOpenResourcesSchedulerSearchPopup(true)
}
const handleClearClick = () => {
setCecos([])
handleSearch({ ...initModelResourcesSchedulerSearchBusiness(), scenaryId: scenario.id, userId: user.id })
}
class MyResource extends ResourceModel { // implementation of what was suggested
get initials() {
return this.name.substring(0, 2);
}
}
const schedulerConfig = !!schedulerResources && {
eventStyle: 'colored',
eventColor: null,
resourceImagePath: null,
columns: [
{
type: 'resourceInfo',
text: onTranslation(language.id, fieldsPage, "resourceList_filter_orderBy_name", scenario.id),
width: '11.5rem',
editor: false,
filterable: {
filterField: {
placeholder: onTranslation(language.id, fieldsPage, "resourceList_filter_tooltip_orderBy", scenario.id)
}
}
},
{
text: onTranslation(language.id, fieldsPage, "resourceList_filter_orderBy_resourceType", scenario.id),
field: 'resourceTypeId',
width: '8rem',
editor: false,
filterable: {
filterField: {
placeholder: onTranslation(language.id, fieldsPage, "resourceList_filter_tooltip_resourceType", scenario.id)
}
}
},
{
width: '1rem',
type: 'widget',
widgets: [{
cls: 'b-transparent',
type: 'button',
tooltip: onTranslation(language.id, fieldsPage, "resourceList_resource_btn_members", scenario.id),
icon: 'b-fa b-fa-fw b-fa-ellipsis-v',
onAction: ({ source: btn }) => {
const menu = btn.menu || (btn.menu = new Menu({
cls: 'b-transparent',
forElement: btn.element,
items: [
{
cls: 'b-transparent',
text: onTranslation(language.id, fieldsPage, "resourceList_resource_btn_members", scenario.id),
onItem({ item }) {
console.log('showing team members', item);
}
}
],
focusOnHover: false,
}));
menu.show();
}
}]
},
],
resourceStore: {
modelClass: MyResource, // <--------- class override done see ln 121
// data: schedulerResourcesResults.map(sr => (sr)) // <--------- I try to implement this which is the same method y use in Ln 206 to load data from a local state
},
filterBarFeature: true,
stripeFeature: true,
timeRangesFeature: true,
eventEditFeature: {
items: {
locationField: {
type: 'text',
name: 'location',
label: 'Location',
dataset: { eventType: 'Meeting' },
weight: 200
}
}
},
barMargin: 5,
rowHeight: 40,
startDate: new Date(2017, 1, 7, 8), // year, monthIndex (starts with 0), day, hours
endDate: new Date(2017, 1, 7, 19),
viewPreset: 'hourAndDay',
resources: schedulerResourcesResults.map(sr => (sr)), //Here is where I insert my data
events: [ // events are still just a mockup
{
resourceId: 3132,
name: "Make marketing plan",
startDate: "2017-02-07 11:00",
endDate: "2017-02-07 14:00"
},
{
resourceId: 3131,
name: "Read spec.",
startDate: "2017-02-07 12:00",
endDate: "2017-02-07 15:00"
},
{
resourceId: 3126,
name: "Sign documents",
startDate: "2017-02-07 13:00",
endDate: "2017-02-07 16:00"
},
{
resourceId: 2705,
name: "Board meeting",
startDate: "2017-02-07 09:00",
endDate: "2017-02-07 11:00"
},
{
resourceId: 3147,
name: "Sales call",
startDate: "2017-02-07 10:00",
endDate: "2017-02-07 12:00"
},
{
resourceId: 3155,
name: "Customer visit",
startDate: "2017-02-07 11:00",
endDate: "2017-02-07 13:00",
location: "Customer office"
},
{
resourceId: 3118,
name: "Prepare happy hour",
startDate: "2017-02-07 14:00",
endDate: "2017-02-07 17:00"
},
{
resourceId: 3116,
name: "Sales call",
startDate: "2017-02-07 14:00",
endDate: "2017-02-07 17:00"
}
],
tbar: [
{
type: 'button',
tooltip: onTranslation(language.id, fieldsPage, "resourceList_filter_tooltip_popup", scenario.id),
cls: 'b-transparent',
icon: 'b-fa-search',
align: 'left',
onClick: (e) => handleOnOpenResourcesSchedulerSearchPopup()
},
{
type: 'button',
tooltip: onTranslation(language.id, fieldsPage, "resourceList_filter_tooltip_deleteFilters", scenario.id),
cls: 'b-transparent',
icon: 'b-fa-trash',
align: 'left',
onClick: (e) => handleClearClick()
},
],
// Specialized body template with header and footer
eventBodyTemplate: data => `
<div class="b-sch-event-header">${data.headerText}</div>
<div class="b-sch-event-footer">${data.footerText}</div>
`,
eventRenderer({ eventRecord, resourceRecord, renderData }) {
renderData.style = 'background-color:' + resourceRecord.color;
return {
headerText: DateHelper.format(eventRecord.startDate, this.displayDateFormat),
footerText: eventRecord.name || ''
};
},
};
const scheduler = useRef(null);
return (
<>
<BryntumScheduler
ref={scheduler} {...schedulerConfig}
style={{ headerHeight: '1rem' }}
></BryntumScheduler>
<Popup
openPopup={openResourcesSchedulerSearchPopup}
setOpenPopup={setOpenResourcesSchedulerSearchPopup}
title='Buscador de Recursos' // falta traducción del título
maxWidth={"sm"}
>
<TaskSchedulerSearchResourcesPopup
fieldsPage={fieldsPage}
translation={translation}
language={language}
scenario={scenario}
localization={localization}
userConfiguration={userConfiguration}
companies={companies}
clientsClassesScenaries={clientsClassesScenaries}
onTranslation={onTranslation}
messages={messages}
usersCostCenters={usersCostCenters}
handleOnPopupSearch={handleOnPopupSearch}
searchModel={searchModel}
cecos={cecos}
setCecos={setCecos}
/>
</Popup>
</>
)
}
export default React.memo(SchedulerPro)
Also I'm attaching a capture of the error is causing on my saga. If I remove the code you suggested and just work loading my data inside the prop 'resources' it works but of course without being able to modify or alter the initials.
Thanks and I look forward to hearing from you,