Our pure JavaScript Scheduler component


Post by jay.kandasamy »

Hi ,

Need to drag the external component item to scheduler , attached sample codes for your reference.We are using inline data binding .Can you let me know the right way to bind the external drag item to scheduler & also to read the resource data to schedule it to particular resource.

test1.component.html

<div class="container" style="width: 100%;">// SCHEDULE BOARD COMPONENT
    <h2>Projects</h2>
     <div class="movie-list" cdkDropList (cdkDropListDropped)="onDrop($event)"> // SUMMARY LIST COMPONENT
      <div class="movie-block" *ngFor="let projectList of ProjectList" cdkDrag [cdkDragData]="projectList">{{projectList}}</div>
    </div>
  </div>

test1.component.ts

import { Component, OnInit } from '@angular/core';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { ShareService } from '../service/share.service';

@Component({
  selector: 'app-test1',
  templateUrl: './test1.component.html',
  styleUrls: ['./test1.component.scss']
})
export class Test1Component implements OnInit {

  constructor(private ss: ShareService) { }

  ngOnInit() {
  }

  ProjectList = [
    '111-222-333',
    '222-333-444',
    '333-444-555',
    '444-555-666',
    '555-666-777',
    '666-777-888',
    '777-888-999',
    '888-999-000'    
]; onDrop(_event: CdkDragDrop<string[]>) { this.ss.drop(_event); } }

app.component.html

<div style="display: flex; height: 100vh;"  id = 'event-source' cdkDropListGroup>
<app-test1></app-test1>
<bryntum-project-model
    #project
</bryntum-project-model>

<bryntum-scheduler-pro
    #schedulerpro
    [resourceImagePath]= "schedulerProConfig.resourceImagePath!"
    [startDate] = "schedulerProConfig.startDate"
    [endDate] = "schedulerProConfig.endDate"
    [viewPreset] = "schedulerProConfig.viewPreset"
    [forceFit] = "schedulerProConfig.forceFit"
    [columns] = "schedulerProConfig.columns"
    [project] = "project"
    [taskEditFeature] = "schedulerProConfig.features.taskEdit"
    [eventColor] = "schedulerProConfig.eventColor"
    cdkDropList (cdkDropListDropped)= "onDrop($event)"
</bryntum-scheduler-pro>
</div>

app.component.ts

import { AfterViewInit, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { BryntumSchedulerProComponent } from '@bryntum/schedulerpro-angular';
import { MessageDialog, SchedulerPro } from '@bryntum/schedulerpro';
import { schedulerProConfig } from './app.config';
import { projectData } from './app.data';
import { CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';
import { ShareService } from './service/share.service';

@Component({
    selector      : 'app-root',
    templateUrl   : './app.component.html',
    styleUrls     : ['./app.component.scss'],
    encapsulation : ViewEncapsulation.None
})
export class AppComponent implements AfterViewInit {
    @ViewChild(BryntumSchedulerProComponent) schedulerProComponent!: BryntumSchedulerProComponent;

constructor(private ss: ShareService) { }
 private schedulerPro!: SchedulerPro;
 
/*
private schedulerPro = new SchedulerPro({
    features : {
        taskEdit : {
            items : {
                generalTab      : {
                    items : {
                        // Remove "Duration" and "% Complete" fields in the "General" tab
                        durationField    : false,
                        percentDoneField : false
                    }
                },
                // Remove all tabs except the "General" tab
                notesTab        : false,
                predecessorsTab : false,
                successorsTab   : false,
                advancedTab     : false
            }
        }
    }
})
  */
 /*
    private schedulerPro = new SchedulerPro({
        listeners : {
            beforeTaskEditShow({ editor, taskRecord, source }) {
                const predecessorsTab = editor.widgetMap.predecessorsTab;
                predecessorsTab.disabled = true;
                source.eventStore.on('change', () => { predecessorsTab.disabled = true }, { once : true });
            }
        }
    });
    */
    schedulerProConfig = schedulerProConfig;
    projectData = projectData;

/**
 * Called after View is initialized
 */
ngAfterViewInit(): void {
    // SchedulerPro instance
    

    this.schedulerPro = this.schedulerProComponent.instance;

    this.schedulerPro.project.on('hasChanges', () => {
        localStorage.setItem('data1', this.schedulerPro.project.json);
    });

    const savedData = localStorage.getItem('data1');
    if (!savedData) {
        console.log('JSON File Data');
        this.schedulerPro.project.inlineData = projectData;
    } else {
        console.log('Local Storage Saved data');
        this.schedulerPro.project.json = savedData;
    }   
}

async onDrop(event: CdkDragDrop<string[]>) {
    const droppedItem = event.item;  //CdkDrag<any>
    const data = event.item.data;  //any
    this.schedulerPro.project.eventStore.add
    const result = await MessageDialog.confirm({
        title        : 'The big question',
        message      : 'Are you sure, you want to add this dragged task',
        okButton     : 'Yes',
        cancelButton : 'No'
    });

if (result === 1) {
    console.log('Dragged Item Data:',droppedItem);
    console.log('Data:',data);
}
else {
    console.log('Cancelled:',data);
}
   
 
  }

        /**
 * Handles zoom-in click event
 */
        onZoomIn(): void {
            console.log('zoom in');
            this.schedulerPro.zoomIn();
        }
    
        /**
         * Handles zoom-out click event
         */
        onZoomOut(): void {
            console.log('zoom out');
            this.schedulerPro.zoomOut();
        }
}

app.config.ts

/**
 * Application config file
 */

import { SchedulerPro, StringHelper } from "@bryntum/schedulerpro";

export const schedulerProConfig={
    resourceImagePath : 'assets/images/users' ,
    type           : 'resourceInfo',
    viewPreset : 'hourAndDay',
    forceFit   : false,
    eventColor        : null,

columns : [
    { type:'resourceInfo', text : 'Name', field : 'name',showRole : true, width : 250 },
],
startDate : '2023-10-29',
endDate   : '2023-10-29',
features : {
    taskEdit : {
        items : {
            generalTab : {
                title : 'Main',
                items : {
                    // Remove "Duration" and "% Complete" fields in the "General" tab
                    durationField    : true,
                    percentDoneField : true
                }
            },
            // Remove all tabs except the "General" tab
            notesTab        : true,
            predecessorsTab : true,
            successorsTab   : true,
            advancedTab     : true
        }
    },
    externalEventSource: {
        // The id of the element to drag from.
        dragRootElement: 'event-source',

        // Selector which identifies draggable events.
        // It will use the innerText as the event name if that's
        // all we care about. We can adjust the duration in the UI.
        dragItemSelector: '.draggable-event'
    },
    // Modes are the views available in the Calendar.
// An object is used to configure the view.
modes : {
    agenda : null,
    year   : null
}
}
//*/
  
};

app.data.ts

export const projectData = {
    resourcesData : [
        {
            id   : 1,
            name : 'Jay',
            role : 'Senior Software Developer',
            eventColor : 'blue' 
          },
          {
            id   : 2,
            name : 'Renato',
            role : 'Senior Fullstack Developer',
            eventColor : 'yellow'
          },
          {
            id       : 3,
            name     : 'Rafael',
            role     : 'Senior Web Developer',
            eventColor : 'green'
          }
    ],

eventsData : [
    { id : 1, startDate  : '2023-10-29T09:00',endDate : '2023-10-29T09:30',  name : '022-123456-312',iconCls    : '',eventStyle : 'border'  },
    { id : 2, startDate  : '2023-10-29T08:15',endDate : '2023-10-29T09:00',  name : '022-654321-312',iconCls    : '',eventStyle : 'border'   },
    { id : 3, startDate  : '2023-10-29T11:00',endDate : '2023-10-29T11:30',  name : '022-565656-312',iconCls    : '',eventStyle : 'border'  }
],
assignmentsData : [
    { id : 1, eventId : 1, resourceId : 1 },
    { id : 2, eventId : 2, resourceId : 2 },
    { id : 3, eventId : 3, resourceId : 3 } 
],
dependenciesData : [
    {}
]

};

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { Test1Component } from './test1/test1.component';
import { ShareService } from './service/share.service';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { FormsModule } from '@angular/forms';
import { BryntumSchedulerProModule } from '@bryntum/schedulerpro-angular';

@NgModule({
  declarations: [
    AppComponent,
    Test1Component
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    DragDropModule,
    BryntumSchedulerProModule,
    FormsModule
  ],
  providers: [ShareService],
  bootstrap: [AppComponent]
})
export class AppModule { }

share.service.ts

import { Injectable } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';


@Injectable()
export class ShareService {

  constructor() { }

  public drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    }
  }

}

Post by johan.isaksson »

Hi,

I recommend you take a look at the Angular drag-from-grid demo (viewtopic.php?f=44&t=27935&p=140129#p140129). Sources are available in the distribution zip found in our CustomerZone.

While it shows how to drag from a Grid, the dragging code (in initDrag()) is not bound to a Grid. With some modifications it can drag from any other element.

Best regards,
Johan Isaksson

Post by jay.kandasamy »

Hi Johan,

Thanks, yes i already referred to that document but not able to get the context for the event , that is the reason i attached sample for reference .


Post by mats »

but not able to get the context for the event

Can you please elaborate a bit, which context are you looking for? Did you study the example code carefully?


Post by jay.kandasamy »

Hi Matt,

sorry for late reply, yes i studied the example but due to app architecture not able to implement as it is mentioned in the example.
Made a work around and able to get all the events data on drop but we need to get only selected resource data - name ,id etc., instead of all the events data.

Last edited by jay.kandasamy on Wed Feb 14, 2024 3:48 pm, edited 1 time in total.

Post by tasnim »

Hi,

You could try filtering the data of resourceStore with this

To check if the resource is selected or not https://bryntum.com/products/schedulerpro/docs/api/Grid/view/mixin/GridSelection#function-isSelected
To apply filter https://bryntum.com/products/schedulerpro/docs/api/Scheduler/data/ResourceStore#function-filter

scheduler.resourceStore.filter(record => scheduler.isSelected(record) ? record.events : null);

I hope this helps

Best regards,
Tasnim


Post by jay.kandasamy »

Hi Tasnim,

Thank you, is it possible to get the mouse hover resource data instead of selected resource data.


Post by tasnim »

Hi,

Of course, you could use https://bryntum.com/products/scheduler/docs/api/Grid/view/mixin/GridElementEvents#event-cellMouseOver event to achieve it

scheduler.on('cellMouseOver', (e) => {
    if (e.target.closest('[data-region="locked"]')) {
        console.log(e.record);
    }
})

Post by jay.kandasamy »

Hi Tasnim.

Used this, scheduler.resourceStore.filter(record => scheduler.isSelected(record) ? record.events : null);
and getting no resource record.
const k = this.schedulerPro.resourceStore.filter(record => this.schedulerPro.isSelected(record) ? record.events : Null);
console.log('resourceData : ', k);

IsSelected
IsSelected
schedulerisSelected.png (7.78 KiB) Viewed 177 times

Post by tasnim »

Looks like it's not a store. Can you please share how you managed to get the resourceData so we can give you a solution according to that?


Post Reply