{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "scheduler-external-drag-and-drop",
  "framework": "react",
  "type": "registry:component",
  "component": "Scheduler",
  "variant": "external-drag-and-drop",
  "dependencies": [
    "@syncfusion/ej2-navigations",
    "@syncfusion/ej2-react-navigations",
    "@syncfusion/ej2-react-schedule"
  ],
  "description": "Scheduler accepts drag-and-drop from an external tree view into its time slots.",
  "meta": {
    "essentialStudioRelease": "2026 Volume 2 (v34.1.29)",
    "license": "commercial-or-community",
    "licenseNote": "The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md",
    "requiresLicenseKey": true,
    "requiresServerEndpoint": false,
    "platformIndex": "https://ai.syncfusion.com/react/llms.txt",
    "skillPack": "syncfusion/react-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/react/js/scheduler-external-drag-and-drop.md"
  },
  "files": [
    {
      "target": "src/components/scheduler-external-drag-and-drop/Scheduler.jsx",
      "content": "import { useRef } from 'react';\nimport { ScheduleComponent, ResourcesDirective, ResourceDirective, ViewsDirective, ViewDirective, Inject, TimelineViews, Resize, DragAndDrop, TimelineMonth } from '@syncfusion/ej2-react-schedule';\nimport { extend, closest, remove, addClass } from '@syncfusion/ej2-base';\nimport { TreeViewComponent } from '@syncfusion/ej2-react-navigations';\n/**\n * schedule resources group-editing sample\n */\n\nlet waitingList = [\n  { \"Id\": 1, \"Name\": \"Steven\", \"StartTime\": \"2021-09-04T02:00:00.000Z\", \"EndTime\": \"2021-09-04T04:00:00.000Z\", \"Description\": \"Consulting\", \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 2, \"Name\": \"Milan\", \"StartTime\": \"2021-09-05T03:00:00.000Z\", \"EndTime\": \"2021-09-05T05:00:00.000Z\", \"Description\": \"Bad Breath\", \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 3, \"Name\": \"Laura\", \"StartTime\": \"2021-09-05T04:00:00.000Z\", \"EndTime\": \"2021-09-05T05:00:00.000Z\", \"Description\": \"Eye Checkup\", \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 4, \"Name\": \"Janet\", \"StartTime\": \"2021-09-04T05:30:00.000Z\", \"EndTime\": \"2021-09-04T07:00:00.000Z\", \"Description\": \"Gum Disease\", \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 5, \"Name\": \"Adams\", \"StartTime\": \"2021-09-04T05:30:00.000Z\", \"EndTime\": \"2021-09-04T07:00:00.000Z\", \"Description\": \"Observation\", \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 6, \"Name\": \"John\", \"StartTime\": \"2021-09-04T05:30:00.000Z\", \"EndTime\": \"2021-09-04T07:00:00.000Z\", \"Description\": \"Mouth Sores\", \"DepartmentName\": \"DENTAL\" }\n];\n\nlet hospitalData = [\n  { \"Id\": 10, \"Name\": \"David\", \"StartTime\": \"2021-08-02T03:30:00.000Z\", \"EndTime\": \"2021-08-02T04:30:00.000Z\", \"Description\": \"Health Checkup\", \"DepartmentID\": 1, \"ConsultantID\": 1, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 11, \"Name\": \"John\", \"StartTime\": \"2021-08-02T05:00:00.000Z\", \"EndTime\": \"2021-08-02T06:00:00.000Z\", \"Description\": \"Tooth Erosion\", \"DepartmentID\": 2, \"ConsultantID\": 2, \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 12, \"Name\": \"Peter\", \"StartTime\": \"2021-08-02T06:30:00.000Z\", \"EndTime\": \"2021-08-02T07:30:00.000Z\", \"Description\": \"Eye and Spectacles Checkup\", \"DepartmentID\": 1, \"ConsultantID\": 3, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 13, \"Name\": \"Starc\", \"StartTime\": \"2021-08-02T08:30:00.000Z\", \"EndTime\": \"2021-08-02T09:30:00.000Z\", \"Description\": \"Toothaches\", \"DepartmentID\": 2, \"ConsultantID\": 4, \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 14, \"Name\": \"James\", \"StartTime\": \"2021-08-02T04:30:00.000Z\", \"EndTime\": \"2021-08-02T05:30:00.000Z\", \"Description\": \"Surgery Appointment\", \"DepartmentID\": 1, \"ConsultantID\": 5, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 15, \"Name\": \"Jercy\", \"StartTime\": \"2021-08-02T04:00:00.000Z\", \"EndTime\": \"2021-08-02T05:00:00.000Z\", \"Description\": \"Tooth Sensitivity\", \"DepartmentID\": 2, \"ConsultantID\": 6, \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 16, \"Name\": \"Albert\", \"StartTime\": \"2021-08-03T04:30:00.000Z\", \"EndTime\": \"2021-08-03T06:00:00.000Z\", \"Description\": \"Skin care treatment\", \"DepartmentID\": 1, \"ConsultantID\": 7, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 17, \"Name\": \"Louis\", \"StartTime\": \"2021-08-03T07:00:00.000Z\", \"EndTime\": \"2021-08-03T08:15:00.000Z\", \"Description\": \"General Checkup\", \"DepartmentID\": 1, \"ConsultantID\": 9, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 18, \"Name\": \"Williams\", \"StartTime\": \"2021-08-03T06:30:00.000Z\", \"EndTime\": \"2021-08-03T08:30:00.000Z\", \"Description\": \"Mouth Sores\", \"DepartmentID\": 2, \"ConsultantID\": 10, \"DepartmentName\": \"DENTAL\" },\n  { \"Id\": 19, \"Name\": \"David\", \"StartTime\": \"2021-08-03T11:00:00.000Z\", \"EndTime\": \"2021-08-03T12:45:00.000Z\", \"Description\": \"Eye checkup and Treatment\", \"DepartmentID\": 1, \"ConsultantID\": 1, \"DepartmentName\": \"GENERAL\" },\n  { \"Id\": 20, \"Name\": \"John\", \"StartTime\": \"2021-08-03T14:00:00.000Z\", \"EndTime\": \"2021-08-03T16:15:00.000Z\", \"Description\": \"Toothaches\", \"DepartmentID\": 2, \"ConsultantID\": 2, \"DepartmentName\": \"DENTAL\" }\n];\n\nconst ExternalDragDrop = () => {\n    let scheduleObj = useRef(null);\n    let treeObj = useRef(null);\n    let isTreeItemDropped = false;\n    let draggedItemId = '';\n    const allowDragAndDrops = true;\n    const fields = { dataSource: waitingList, id: 'Id', text: 'Name' };\n    const data = extend([], hospitalData, null, true);\n    const departmentData = [\n        { Text: 'GENERAL', Id: 1, Color: '#bbdc00' },\n        { Text: 'DENTAL', Id: 2, Color: '#9e5fff' }\n    ];\n    const consultantData = [\n        { Text: 'Alice', Id: 1, GroupId: 1, Color: '#bbdc00', Designation: 'Cardiologist' },\n        { Text: 'Nancy', Id: 2, GroupId: 2, Color: '#9e5fff', Designation: 'Orthodontist' },\n        { Text: 'Robert', Id: 3, GroupId: 1, Color: '#bbdc00', Designation: 'Optometrist' },\n        { Text: 'Robson', Id: 4, GroupId: 2, Color: '#9e5fff', Designation: 'Periodontist' },\n        { Text: 'Laura', Id: 5, GroupId: 1, Color: '#bbdc00', Designation: 'Orthopedic' },\n        { Text: 'Margaret', Id: 6, GroupId: 2, Color: '#9e5fff', Designation: 'Endodontist' }\n    ];\n    const getConsultantName = (value) => {\n        return value.resourceData[value.resource.textField];\n    };\n    const getConsultantImage = (value) => {\n        return getConsultantName(value).toLowerCase();\n    };\n    const getConsultantDesignation = (value) => {\n        return value.resourceData.Designation;\n    };\n    const resourceHeaderTemplate = (props) => {\n        return (<div className=\"template-wrap\">\n        <div className=\"specialist-category\">\n          <div className={\"specialist-image \" + getConsultantImage(props)}></div>\n          <div className=\"specialist-name\"> {getConsultantName(props)}</div>\n          <div className=\"specialist-designation\">{getConsultantDesignation(props)}</div>\n        </div>\n      </div>);\n    };\n    const treeTemplate = (props) => {\n        return (<div id=\"waiting\">\n        <div id=\"waitdetails\">\n          <div id=\"waitlist\">{props.Name}</div>\n          <div id=\"waitcategory\">{props.DepartmentName} - {props.Description}</div>\n        </div>\n      </div>);\n    };\n    const onItemSelecting = (args) => {\n        args.cancel = true;\n    };\n    const onTreeDrag = (event) => {\n        if (scheduleObj.current.isAdaptive) {\n            let classElement = scheduleObj.current.element.querySelector('.e-device-hover');\n            if (classElement) {\n                classElement.classList.remove('e-device-hover');\n            }\n            if (event.target.classList.contains('e-work-cells')) {\n                addClass([event.target], 'e-device-hover');\n            }\n        }\n    };\n    const onActionBegin = (event) => {\n        if (event.requestType === 'eventCreate' && isTreeItemDropped) {\n            let treeViewData = treeObj.current.fields.dataSource;\n            const filteredPeople = treeViewData.filter((item) => item.Id !== parseInt(draggedItemId, 10));\n            treeObj.current.fields.dataSource = filteredPeople;\n            let elements = document.querySelectorAll('.e-drag-item.treeview-external-drag');\n            for (let i = 0; i < elements.length; i++) {\n                remove(elements[i]);\n            }\n        }\n    };\n    const onTreeDragStop = (event) => {\n        let treeElement = closest(event.target, '.e-treeview');\n        let classElement = scheduleObj.current.element.querySelector('.e-device-hover');\n        if (classElement) {\n            classElement.classList.remove('e-device-hover');\n        }\n        if (!treeElement) {\n            event.cancel = true;\n            let scheduleElement = closest(event.target, '.e-content-wrap');\n            if (scheduleElement) {\n                let treeviewData = treeObj.current.fields.dataSource;\n                if (event.target.classList.contains('e-work-cells')) {\n                    const filteredData = treeviewData.filter((item) => item.Id === parseInt(event.draggedNodeData.id, 10));\n                    let cellData = scheduleObj.current.getCellDetails(event.target);\n                    let resourceDetails = scheduleObj.current.getResourcesByIndex(cellData.groupIndex);\n                    let eventData = {\n                        Name: filteredData[0].Name,\n                        StartTime: cellData.startTime,\n                        EndTime: cellData.endTime,\n                        IsAllDay: cellData.isAllDay,\n                        Description: filteredData[0].Description,\n                        DepartmentID: resourceDetails.resourceData.GroupId,\n                        ConsultantID: resourceDetails.resourceData.Id\n                    };\n                    scheduleObj.current.openEditor(eventData, 'Add', true);\n                    isTreeItemDropped = true;\n                    draggedItemId = event.draggedNodeData.id;\n                }\n            }\n        }\n        document.body.classList.remove('e-disble-not-allowed');\n    };\n    const onTreeDragStart = () => {\n        document.body.classList.add('e-disble-not-allowed');\n    };\n    return (<div className='schedule-control-section'>\n      <div className='col-lg-12 control-section'>\n        <div className='control-wrapper drag-sample-wrapper'>\n          <div className=\"schedule-container\">\n            <div className=\"title-container\">\n              <h1 className=\"title-text\">Doctor's Appointments</h1>\n            </div>\n            <ScheduleComponent ref={scheduleObj} cssClass='schedule-drag-drop' width='100%' height='650px' selectedDate={new Date(2021, 7, 2)} currentView='TimelineDay' resourceHeaderTemplate={resourceHeaderTemplate} eventSettings={{ dataSource: data, fields: { subject: { title: 'Patient Name', name: 'Name' }, startTime: { title: \"From\", name: \"StartTime\" }, endTime: { title: \"To\", name: \"EndTime\" }, description: { title: 'Reason', name: 'Description' } } }} group={{ enableCompactView: false, resources: ['Departments', 'Consultants'] }} actionBegin={onActionBegin}>\n              <ResourcesDirective>\n                <ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false} dataSource={departmentData} textField='Text' idField='Id' colorField='Color'/>\n                <ResourceDirective field='ConsultantID' title='Consultant' name='Consultants' allowMultiple={false} dataSource={consultantData} textField='Text' idField='Id' groupIDField=\"GroupId\" colorField='Color'/>\n              </ResourcesDirective>\n              <ViewsDirective>\n                <ViewDirective option='TimelineDay'/>\n                <ViewDirective option='TimelineMonth'/>\n              </ViewsDirective>\n              <Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop]}/>\n            </ScheduleComponent>\n          </div>\n          <div className=\"treeview-container\">\n            <div className=\"title-container\">\n              <h1 className=\"title-text\">Waiting List</h1>\n            </div>\n            <TreeViewComponent ref={treeObj} cssClass='treeview-external-drag' dragArea=\".drag-sample-wrapper\" nodeTemplate={treeTemplate} fields={fields} nodeDragStop={onTreeDragStop} nodeSelecting={onItemSelecting} nodeDragging={onTreeDrag} nodeDragStart={onTreeDragStart} allowDragAndDrop={allowDragAndDrops}/>\n          </div>\n        </div>\n      </div>\n    </div>);\n};\nexport default ExternalDragDrop;"
    }
  ]
}