Hi
this is the full code of our Timeline.tsx file:
import React, {Fragment, useCallback, useEffect, useRef, useState} from 'react'
import {
dailyPreset,
getScheduler,
gridConfig,
histogramConfig,
monthlyPreset, project,
schedulerProConfig,
weeklyPreset
} from './config'
import {BryntumGrid, BryntumResourceHistogram, BryntumSchedulerPro, BryntumSplitter} from '@bryntum/schedulerpro-react'
import {
autoPlanStateEnum,
autoPlanStateType,
CoreType,
setPlanStateType,
} from '../../../Plansphere'
import {
CalendarModel,
DateHelper,
ResourceHistogram,
SchedulerPro,
TimeRangesConfig,
Grid,
Store,
EventStore,
EventModel,
Model,
DomClassList,
ScrollManager,
WidgetHelper,
ResourceModel, SchedulerEventModel
} from '@bryntum/schedulerpro'
import './Timeline.scss'
import {Drag} from './Drag'
import {
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
FormControlLabel,
TextField,
Grid as MuiGrid,
} from '@mui/material'
import EditPanel from '../../widgets/EditPanel/EditPanel'
import {MwoType} from '../../../models/mwo'
import {ErrorBaseEnum, ErrorType} from '../../../models/error'
import {FwoType} from '../../../models/fwo'
import {eventErrorColor, getCurrentColor} from '../../config/colors'
type TimelineProps = CoreType & {
setMwos: React.Dispatch<React.SetStateAction<MwoType[]>>,
setFwos: React.Dispatch<React.SetStateAction<FwoType[]>>,
planState: autoPlanStateType,
setPlanState: setPlanStateType,
}
type IdEvent = string
type IdResource = string
type IdDependency = string
type IdAssignment = string
type IdCalendar = string
type DependencyType = {
id: IdDependency,
from: IdEvent,
to: IdEvent,
lag: number,
lagUnit: string
}
type ResourceType = {
id: IdResource
name: string,
//iconCls: string,
calendar: CalendarModel,
}
type AssignmentType = {
id: IdAssignment,
resourceId: IdResource,
eventId: IdEvent
}
type EventType = {
id: IdEvent
name: string
startDate: Date | null
endDate: Date | null
iconCls: string
//eventColor: string
resizable: boolean
cls: string | null
//dueDate: Date
resourceId: string
}
type intervalType = {
name: string
cls?: string
endDate?: Date
iconCls?: string
isWorking: boolean
recurrentEndDate?: string
recurrentStartDate?: string
startDate?: Date
}
type CalendarType = {
id: IdCalendar
name: string
unspecifiedTimeIsWorking: boolean
cls?: string
intervals: intervalType[]
}
//SchedulerEventModel
const extractEvents = (data: CoreType): EventType[] => {
console.log('extractEvents: ' + data.mwos.length)
return data.mwos.map(mwo => {
let ed: Date | null
let cls = ''
let iconCls = ''
const fwoIndex = data.fwos.findIndex(value => value.id === mwo.fwoId)
if (mwo.startPlanned !== null && mwo.endDate !== null) {
ed = new Date(mwo.startPlanned?.getTime())
//const ed2 = DateHelper.add(ed, mwo.duration, 'seconds')
ed.setSeconds(ed.getSeconds() + mwo.duration)
mwo.endDate = ed
}
if (mwo.endDate !== null && mwo.endDate > mwo.dueDate) {
cls += eventErrorColor
} else if (fwoIndex !== -1) {
if (data.fwos[fwoIndex].color === null) {
data.fwos[fwoIndex].color = 'eventColor' + getCurrentColor()
}
cls += data.fwos[fwoIndex].color
}
if (mwo.startPlannedLocked) {
iconCls = 'b-fa b-fa-lock'
}
return {
id: mwo.id,
name: mwo.description,
startDate: mwo.startPlanned,
endDate: mwo.endDate,
image: false,
resourceId: mwo.wksId,
iconCls: iconCls,
duration: mwo.duration,
durationUnit: 'second',
resizable: false,
cls: cls
}
})
}
const extractData = (data: CoreType): EventType[] => {
return data.mwos.map(mwo => {
let ed: Date | null
if (mwo.startPlanned !== null && mwo.endDate !== null) {
ed = new Date(mwo.startPlanned?.getTime())
//const ed2 = DateHelper.add(ed, mwo.duration, 'seconds')
ed.setSeconds(ed.getSeconds() + mwo.duration)
mwo.endDate = ed
}
return {
id: mwo.id,
name: mwo.description,
startDate: mwo.startPlanned,
endDate: mwo.endDate,
image: false,
resourceId: mwo.wksId,
iconCls: 'b-fa b-fa-snowplow',
eventColor: 'orange',
duration: mwo.duration,
durationUnit: 'second',
resizable: false,
dueDate: mwo.dueDate,
cls: null,
}
})
}
const extractResources = (data: CoreType): ResourceType[] => {
return data.wks.map(wks => {
return {
id: wks.id,
name: wks.description,
calendar: wks.calendar,
image: false,
//iconCls: 'b-fa b-fa-snowplow',
}
})
}
const extractDependencies = (data: CoreType): DependencyType[] => {
let id = 0
const dependencies: DependencyType[] = []
for (const mwo of data.mwos) {
for (const d of mwo.predecessors) {
id++
dependencies.push({
id: 'D' + id.toString(),
from: d,
to: mwo.id,
lag: 0,
lagUnit: 's',
})
}
}
return dependencies
}
const extractCalendars = (data: CoreType): CalendarType[] => {
return data.calendars
}
const timeRangesSchedule: Partial<TimeRangesConfig> = {
// This displays the red line indicating the current time
showCurrentTimeLine: true,
//currentDateFormat: 'D.M',
}
const timeRangesHistogram: Partial<TimeRangesConfig> = {
// For histogram we don't want the time so we just insert empty format.
showCurrentTimeLine: true,
currentDateFormat: '',
}
const visibleDate = {
date: new Date(),
block: 'center'
}
enum View {
daily,
weekly,
monthly,
}
const ViewLength = {
[View.daily]: 1,
[View.weekly]: 7,
[View.monthly]: 31
}
const Timeline = (props: TimelineProps) => {
const [filterDialog, setFilterDialog] = useState(false)
const [createBookMarkDialog, setCreateBookMarkDialog] = useState(false)
const [hideHistogram, setHideHistogram] = useState(false)
const [editPanel, setEditPanel] = useState(false)
const [editPanelData, setEditPanelData] = useState(null)
const histogramRef = useRef<BryntumResourceHistogram>(null)
const schedulerRef = useRef<BryntumSchedulerPro>(null)
const gridRef = useRef<BryntumGrid>(null)
const histogramInstance = () => histogramRef.current?.instance as ResourceHistogram
const gridInstance = () => gridRef.current?.instance as Grid
const schedulerInstance = () => schedulerRef.current?.instance as SchedulerPro
// Toggle MWO list visibility
const onToggleOrderList = useCallback(() => {
if (gridRef !== null && gridRef.current !== null) {
gridInstance().hidden = !gridInstance().hidden
const element = document.getElementById('schedule_container')!
if (!gridInstance().hidden) {
element.style.width = '80%'
}
}
bryntumIconsClassGrid()
}, [gridRef, gridRef.current, histogramRef, histogramRef.current, schedulerRef, schedulerRef.current])
useEffect(() => {
histogramInstance().addPartner(schedulerInstance())
}, [schedulerRef, schedulerRef.current, gridRef, gridRef.current, histogramRef, histogramRef.current])
useEffect(() => {
const element = document.getElementById('schedule_container')!
element.style.width = '80%'
}, [props.mwos])
const addDraggedElement = (obj: SchedulerEventModel) => {
const index = props.mwos.findIndex(el => el.id === obj.id)
console.log(index)
props.mwos[index].startPlanned = obj.startDate as Date
const ed = new Date((obj.startDate as Date).getTime())
ed.setSeconds(ed.getSeconds() + props.mwos[index].duration)
props.mwos[index].endDate = ed
obj.endDate = ed
obj.name = props.mwos[index].description
obj.resourceId = props.mwos[index].wksId
obj.duration = props.mwos[index].duration
obj.durationUnit = 'second'
const event = schedulerInstance().eventStore.add(obj)
}
useEffect(() => {
// // Setup dragging
new Drag({
grid: gridRef?.current?.instance,
schedule: schedulerRef?.current?.instance,
constrain: false,
outerElement: gridRef?.current?.instance.element,
scheduleInstance: schedulerInstance(),
histogramInstance: histogramInstance(),
gridInstance: gridInstance(),
addDraggedElement: addDraggedElement
})
}, [props.calendars, props.fwos, props.stocks, props.calendars, schedulerRef, schedulerRef.current, gridRef, gridRef.current, histogramRef, histogramRef.current])
// Runs only once. Dependencies are not going to change
useEffect(() => {
const startDate = new Date()
const endDate = new Date()
startDate.setMonth(startDate.getMonth() - 6)
endDate.setMonth(endDate.getMonth() + 6)
if (schedulerRef !== null && schedulerRef?.current !== null) {
const scheduler = schedulerRef.current.instance
scheduler.on({
toggleOrderList: onToggleOrderList,
})
schedulerInstance().setTimeSpan(startDate, endDate)
schedulerInstance().scrollToNow({block: 'center'})
}
}, [schedulerRef, schedulerRef.current, histogramRef, histogramRef.current, props.mwos, onToggleOrderList])
const onDataChange = (event: any) => {
if (event.action === 'update') {
const index = props.mwos.findIndex(el => el.id === event.record.originalData.id)
if (event.changes.startDate !== undefined) {
props.mwos[index].startPlanned = event.changes.startDate.value
let ed = event.changes.startDate.value
if (ed !== null && ed !== undefined) {
ed = new Date(ed.getSeconds())
ed.setSeconds(props.mwos[index].duration)
props.mwos[index].endDate = ed
}
if (event.changes.endDate.value > props.mwos[index].dueDate) {
if (!props.mwos[index].errors.some((el: ErrorType) => el.base === ErrorBaseEnum.overDue)) {
props.mwos[index].errors.push(
{
description: 'Over Due',
base: ErrorBaseEnum.overDue,
}
)
}
const taskClassList = new DomClassList(event.record.cls)
taskClassList.add('overDue')
} else {
const baseIndex = props.mwos[index].errors.findIndex(el => el.base === ErrorBaseEnum.overDue)
props.mwos[index].errors.splice(baseIndex, 1)
const taskClassList = new DomClassList(event.record.cls)
taskClassList.remove('overDue')
event.record.cls = taskClassList.value
}
}
if (event.changes.duration !== undefined) {
props.mwos[index].duration = event.changes.duration.value
event.record.duration = event.changes.duration.value
}
if (event.changes.endDate !== undefined) {
event.record.endDate = event.changes.endDate.value
}
if (event.changes.draggable !== undefined) {
event.record.draggable = event.changes.draggable
}
}
}
const setNewActivePreset = (event: any) => {
const elements = document.getElementsByClassName('bryntumButtonGroup')
Array.from(elements).forEach(el => el.classList.remove('bryntumButtonGroupActive'))
event.currentTarget.classList.add('bryntumButtonGroupActive')
}
const clearSearch = () => {
const gridStore = gridInstance().store as Store
const schedulerStore = schedulerInstance().eventStore as EventStore
gridStore.clearFilters()
schedulerStore.forEach((task: SchedulerEventModel) => {
const taskClassList = new DomClassList(task.cls)
taskClassList.remove('searchedWidget')
task.cls = taskClassList.value
})
}
const searchInputChange = (value: string) => {
if (value === undefined || value === '') {
clearSearch()
return
}
const gridStore = gridInstance().store as Store
const schedulerStore = schedulerInstance().eventStore as EventStore
value = value.toLowerCase()
//Search for grid
gridStore.clearFilters()
gridStore.filter((el: Model) => {
return el.id.toString().toLowerCase().includes(value) || el.getData('name').toLowerCase().includes(value)
})
//Search for scheduler
schedulerStore.forEach((task: SchedulerEventModel) => {
const taskClassList = new DomClassList(task.cls)
taskClassList.remove('searchedWidget')
if ((task.id.toString().toLowerCase().includes(value) || task.name.toLowerCase().includes(value))) {
taskClassList.add('searchedWidget')
schedulerInstance().scrollToDate(task.startDate as Date, {block: 'center'})
}
task.cls = taskClassList.value
})
}
const onBeforeTaskEdit = (event: any): boolean => {
setEditPanelData(event.taskRecord)
setEditPanel(!editPanel)
return false
}
// Don't allow dragging events that are locked
const beforeEventDrag = ({eventRecord}: any): boolean => {
return !props.mwos.find(value => value.id === eventRecord.id)?.startPlannedLocked
}
const bryntumIconsClass = (condition: boolean): string => {
return condition ? 'bryntumIconButtonBlue' : 'bryntumIconButtonGray'
}
const bryntumIconsClassGrid = () => {
const element = document.getElementsByClassName('bGridToggle')
element[0].classList.remove('bryntumIconButtonGray')
element[0].classList.remove('bryntumIconButtonBlue')
if (gridRef === null || gridRef.current === null) {
return
}
element[0].classList.add(!gridInstance().hidden ? 'bryntumIconButtonBlue' : 'bryntumIconButtonGray')
}
return (
<div id={'scheduler_container'}
style={{flex: 'auto', flexWrap: 'nowrap', display: 'flex', flexDirection: 'row'}} className={'scheduler'}>
<Dialog open={filterDialog}>
<DialogTitle>
Workstations filter
</DialogTitle>
<DialogContent>
<MuiGrid container justifyContent={'flex-start'} alignItems={'center'}>
{
props.mwos.map(mwo => (
<MuiGrid key={mwo.id}>
<FormControlLabel value={mwo.id} control={<Checkbox checked={true}></Checkbox>}
label={mwo.id}></FormControlLabel>
</MuiGrid>
))
}
</MuiGrid>
</DialogContent>
<DialogActions>
<Button id={'filterDialogSave'} onClick={() => {
setFilterDialog(!filterDialog)
}}>
Save
</Button>
<Button id={'filterDialogCreateBookmark'} onClick={() => {
//setFilterDialog(!filterDialog)
setCreateBookMarkDialog(!createBookMarkDialog)
}}>
Create bookmark
</Button>
<Button id={'filterDialogCancel'} onClick={() => {
setFilterDialog(!filterDialog)
}}>
Cancel
</Button>
</DialogActions>
</Dialog>
<Dialog open={createBookMarkDialog}>
<DialogContent>
<TextField id={'bookMarkName'} label={'New bookmark name'} variant={'filled'}></TextField>
</DialogContent>
<DialogActions>
<Button id={'filterDialogSave'} onClick={() => {
setFilterDialog(!filterDialog)
setCreateBookMarkDialog(!createBookMarkDialog)
}}>
Create
</Button>
<Button id={'filterDialogCancel'} onClick={() => {
setCreateBookMarkDialog(!createBookMarkDialog)
}}>
Cancel
</Button>
</DialogActions>
</Dialog>
<Fragment>
<div id={'schedule_container'}>
<BryntumSchedulerPro
{...schedulerProConfig}
onBeforeTaskEdit={onBeforeTaskEdit}
tbar={[
{
icon: 'b-icon b-fa-caret-left',
cls: {'bryntumIconButtonLeft': true},
onAction: ({source}: any) => {
schedulerInstance().shiftPrevious()
}
},
{
icon: 'b-icon b-fa-caret-right',
cls: {'bryntumIconButtonRight': true},
onAction: ({source}: any) => {
schedulerInstance().shiftNext()
}
},
{
text: 'Now',
cls: {'bryntumButton': true},
onAction: ({source}: any) => {
schedulerInstance().scrollToNow({block: 'center'})
}
},
{
type: 'buttongroup',
toggleGroup: true,
cls: {'bryntumButtonGroup': true},
items: [
{
//id: 'buttonGroupDay',
text: 'Day',
value: 1,
cls: 'bryntumButtonGroup bryntumButtonGroupDay',
preset: dailyPreset,
},
{
//id: 'buttonGroupDayWeek',
text: 'Week',
cls: 'bryntumButtonGroup bryntumButtonGroupWeek bryntumButtonGroupActive',
value: 7,
preset: weeklyPreset,
},
{
//id: 'buttonGroupMonth',
text: 'Month',
cls: 'bryntumButtonGroup bryntumButtonGroupMonth',
value: 31,
preset: monthlyPreset,
},
],
onClick: ({source, event}: any) => {
setNewActivePreset(event)
const
scheduler = getScheduler(source),
value = source.value,
startDate = DateHelper.add(DateHelper.clearTime(scheduler.startDate), scheduler.extraData.startHour, 'h'),
endDate = DateHelper.add(startDate, value - 1, 'd')
endDate.setHours(scheduler.extraData.endHour)
schedulerInstance().viewPreset = source.preset
}
},
'->',
{
type: 'textfield',
cls: 'searchText',
clearable: true,
placeholder: 'Search mwos..',
maxLength: 150,
triggers: {
plug: {
cls: 'b-fa b-fa-search textFieldIcon'
}
},
onClear: ({source}: any) => {
clearSearch()
},
onInput: ({value}: any) => {
searchInputChange(value)
}
},
{
icon: 'b-icon b-icon-filter',
cls: bryntumIconsClass(filterDialog),
onAction: ({source}: any) => {
setFilterDialog(!filterDialog)
}
},
{
icon: 'b-icon b-fa-chart-column',
cls: bryntumIconsClass(!hideHistogram),
onAction: ({source}: any) => {
setHideHistogram(!hideHistogram)
}
},
{
icon: 'b-icon b-icon-menu-vertical',
cls: 'bGridToggle bryntumIconButtonBlue',
onAction: ({source}: any) => {
//getScheduler(source).trigger('toggleOrderList')
schedulerInstance().trigger('toggleOrderList')
}
}
]}
ref={schedulerRef}
events={extractEvents(props)}
resources={extractResources(props)}
//assignments={extractAssignments(props)}
dependencies={extractDependencies(props)}
calendars={extractCalendars(props)}
timeRangesFeature={timeRangesSchedule}
visibleDate={visibleDate}
scrollable={true}
onDataChange={onDataChange}
onBeforeEventDrag={beforeEventDrag}
/>
<BryntumSplitter/>
<BryntumResourceHistogram
{...histogramConfig}
hidden={hideHistogram}
ref={histogramRef}
timeRangesFeature={timeRangesHistogram}
/>
</div>
<BryntumSplitter/>
{!editPanel ? <BryntumGrid
{...gridConfig}
ref={gridRef}
data={extractData(props)}
/> : null}
{editPanel ?
<EditPanel fwos={props.fwos} setEditPanel={setEditPanel} eventRecord={editPanelData}
resources={extractResources(props)}
mwos={props.mwos}></EditPanel> : null}
</Fragment>
</div>
)
}
export default Timeline
export {View, ViewLength}
export type {CalendarType, TimelineProps, IdCalendar}
This is our config file:
import {BryntumGridProps, BryntumResourceHistogramProps, BryntumSchedulerProProps} from '@bryntum/schedulerpro-react'
import {Column, DateHelper, ProjectModel, ResourceModel, ResourceModelConfig, WidgetHelper} from '@bryntum/schedulerpro'
import EditPanel from '../../widgets/EditPanel/EditPanel'
const dailyPreset = {
base: 'hourAndDay',
tickWidth: 45,
timeResolution: { // Dates will be snapped to this resolution
unit: 'minute', // Valid values are 'millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'.
increment: 1
},
headers: [
{
unit: 'day',
align: 'center',
dateFormat: 'dddd DD.MM'
},
{
unit: 'h',
align: 'center',
dateFormat: 'HH'
}
]
}
const weeklyPreset = {
base: 'dayAndWeek',
// id: 'myPreset', // Unique id value provided to recognize your view preset. Not required, but having it you can simply set new view preset by id: scheduler.viewPreset = 'myPreset'
// name: 'My view preset', // A human-readable name provided to be used in GUI, e.i. preset picker, etc.
// tickWidth : 24, // Time column width in horizontal mode
// tickHeight : 50, // Time column height in vertical mode
displayDateFormat: 'DD HH:mm', // Controls how dates will be displayed in tooltips etc
shiftIncrement: 1, // Controls how much time to skip when calling shiftNext and shiftPrevious.
shiftUnit: 'day', // Valid values are 'millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'.
//defaultSpan: 7, // By default, if no end date is supplied to a view it will show 12 hours
timeResolution: { // Dates will be snapped to this resolution
unit: 'minute', // Valid values are 'millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'.
increment: 10
},
headers: [ // This defines your header rows from top to bottom
{ // For each row you can define 'unit', 'increment', 'dateFormat', 'renderer', 'align', and 'thisObj'
unit: 'month',
increment: 1,
dateFormat: 'MMMM'
},
{
unit: 'day',
increment: 1,
dateFormat: 'ddd DD.MM'
},
],
// columnLinesFor : 1 // Defines header level column lines will be drawn for. Defaults to the last level.
}
const monthlyPreset = {
id: 'monthlyView',
tickWidth: 35,
//rowHeight : 32,
displayDateFormat: 'DD.MM',
shiftIncrement: 1,
shiftUnit: 'day',
timeResolution: {
unit: 'day',
increment: 1
},
//defaultSpan: 31,
mainHeaderLevel: 1,
headers: [
{
unit: 'month',
increment: 1,
dateFormat: 'MMMM YYYY'
},
{
unit: 'day',
increment: 1,
dateFormat: 'DD'
}
]
}
// Upper-level SchedulerPro getter
const getScheduler = (child: any) => {
return child.up('schedulerpro')
}
class MyResource extends ResourceModel {
//https://forum.bryntum.com/viewtopic.php?t=18441&start=10
constructor(config?: Partial<ResourceModelConfig>) {
super(config)
Object.defineProperty(this, 'initials', {
get() {
return 'ABC'
}
})
}
}
const project = new ProjectModel({
resourceModelClass: MyResource,
})
const schedulerProConfig: BryntumSchedulerProProps = {
viewPreset: weeklyPreset,
allowOverlap: false,
rowHeight: 80,
flex: '1 1 60%',
enableUndoRedoKeys: true,
stripeFeature: true,
timeRangesFeature: true,
columns: [
{
type: 'resourceInfo',
text: 'Name',
field: 'name',
showEventCount: true,
width: 200,
editor: null,
}
],
project: project,
calendarHighlightFeature: true,
eventTooltipFeature: {
hoverDelay: 300,
textContent: true,
template: (event: any) => {
return `<h4>ID: ${event.eventRecord.id}</h4>`
},
},
features: {
tree: true,
//To customize arrow between mwos on timeline
//https://www.bryntum.com/docs/gantt/api/Scheduler/feature/Dependencies
dependencies: true,
//https://www.bryntum.com/docs/gantt/api/Scheduler/feature/DependencyEdit
dependencyEdit: false,
eventDrag: {
constrainDragToResource: true,
},
eventDragCreate: false,
eventDragSelect: true,
eventResize: false,
cellMenu: true,
timeAxisHeaderMenu: {
disabled: true,
},
//For right click on events
//https://www.bryntum.com/docs/gantt/api/Scheduler/feature/EventMenu
eventMenu: {
disabled: true
},
//Right click on empty space in timeline
scheduleMenu: {
disabled: true
},
nonWorkingTime: true,
resourceNonWorkingTime: {
maxTimeAxisUnit: 'week',
},
},
extraData: {
startHour: 0,
endHour: 24
},
zoomKeepsOriginalTimespan: true,
zoomOnTimeAxisDoubleClick: false,
zoomOnMouseWheel: false,
createEventOnDblClick: false,
enableDeleteKey: false,
enableEventAnimations: false,
multiEventSelect: false,
highlightPredecessors: true,
highlightSuccessors: true,
}
const histogramConfig: BryntumResourceHistogramProps = {
project: project,
hideHeaders: true,
viewPreset: weeklyPreset,
rowHeight: 60,
flex: '1 1 40%',
showBarTip: true,
showBarText: false,
columns: [
{
type: 'resourceInfo',
text: 'Name',
field: 'name',
editor: false,
//enableCellContextMenu: false,
showEventCount: true,
width: 200
},
{
type: 'scale',
hidden: true,
}
],
features: {
nonWorkingTime: true,
resourceNonWorkingTime: {
maxTimeAxisUnit: 'week',
},
},
calendarHighlightFeature: true,
eventTooltipFeature: {
hoverDelay: 300,
textContent: true,
template: (event: any) => {
return `<h4>ID: ${event.eventRecord.id}</h4>`
},
},
}
const gridConfig: BryntumGridProps = {
flex: 1,
rowHeight: 60,
readOnly: false,
minWidth: 250,
maxWidth: 431,
selectionMode: {
row: true
},
draggable: true,
stripeFeature: true,
sortFeature: 'id',
cellTooltipFeature: {
hoverDelay: 300,
textContent: true,
tooltipRenderer: ({record: order}: any) =>
order.isScheduled ?
`<h4>Type: ${order.templateName}</h4>This order is scheduled to finish by <b>${DateHelper.format(order.finishDate, 'MMM d HH:mm')}</b>`
: `<h4>Type: ${order.templateName}</h4>Try dragging this order onto the schedule`
},
// Grid top toolbar
tbar: [
{
text: 'Add order',
cls: {'tbarBryntumButton': true},
//icon: 'b-icon b-fa-plus',
toggleable: true,
// onAction : onAddClick
},
'->',
{
text: 'Hide scheduled',
toggleable: true,
cls: {'tbarBryntumButton': true},
onToggle: ({source, pressed}: any) => {
const store = source.up('grid').store
if (pressed) {
store.filter({
property: 'startDate',
operator: '=',
value: null
})
} else {
store.clearFilters()
}
}
}
],
columns: [{
type: 'template',
text: 'Order List',
flex: 1,
maxWidth: 100,
field: 'name',
editor: false,
htmlEncode: false,
cellCls: 'order-cell',
template: ({record: order}: any) =>
`<div>${'#' + order.id} </div>
<div class="customer">Descr: ${order.name}</div>`
}, {
text: 'Start',
type: 'date',
flex: 1,
align: 'right',
format: 'MMM D HH:mm',
field: 'startDate',
}, {
text: 'Finish',
type: 'date',
flex: 1,
align: 'right',
format: 'MMM D HH:mm',
editor: false,
field: 'endDate'
},
{
text: 'Due date',
type: 'date',
flex: 1,
align: 'right',
format: 'MMM D HH:mm',
editor: false,
field: 'dueDate'
},
],
disableGridRowModelWarning: true
}
export {
schedulerProConfig,
gridConfig,
dailyPreset,
weeklyPreset,
monthlyPreset,
getScheduler,
histogramConfig,
project
}