{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "scheduler-external-drag-and-drop",
  "framework": "angular",
  "type": "registry:component",
  "component": "Scheduler",
  "variant": "external-drag-and-drop",
  "dependencies": [
    "@syncfusion/ej2-angular-schedule"
  ],
  "description": "Timeline scheduler that accepts dragging consultant appointments from an external tree-view list.",
  "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/angular/llms.txt",
    "skillPack": "syncfusion/angular-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/angular/scheduler-external-drag-and-drop.md"
  },
  "files": [
    {
      "target": "src/components/scheduler-external-drag-and-drop/external-drag-drop.component.ts",
      "content": "import { Component, ViewEncapsulation, Inject, ViewChild } from '@angular/core';\nimport { hospitalData, waitingList } from '../data';\nimport { extend, closest, remove, addClass } from '@syncfusion/ej2-base';\nimport { EventSettingsModel, View, GroupModel, TimelineViewsService, TimelineMonthService, ResizeService, WorkHoursModel, DragAndDropService, ResourceDetails, ScheduleComponent, ActionEventArgs, CellClickEventArgs, ScheduleModule } from '@syncfusion/ej2-angular-schedule';\nimport { DragAndDropEventArgs } from '@syncfusion/ej2-navigations';\nimport { TreeViewComponent, TreeViewModule } from '@syncfusion/ej2-angular-navigations';\nimport { NgIf } from '@angular/common';\n@Component({\n    // tslint:disable-next-line:component-selector\n    selector: 'control-content',\n    templateUrl: 'external-drag-drop.html',\n    styleUrls: ['external-drag-drop.style.css'],\n    encapsulation: ViewEncapsulation.None,\n    providers: [TimelineViewsService, TimelineMonthService, ResizeService, DragAndDropService],\n    standalone: true,\n    imports: [ScheduleModule, NgIf, TreeViewModule]\n})\nexport class ExternalDragDropComponent {\n  @ViewChild('scheduleObj') public scheduleObj!: ScheduleComponent;\n  @ViewChild('treeObj') public treeObj!: TreeViewComponent;\n\n  public isTreeItemDropped = false;\n  public draggedItemId = '';\n  public data: Record<string, any>[] = extend([], hospitalData as object[], undefined, true) as Record<string, any>[];\n  public selectedDate: Date = new Date(2021, 7, 2);\n  public currentView: View = 'TimelineDay';\n  public workHours: WorkHoursModel = { start: '08:00', end: '18:00' };\n  public departmentDataSource: Record<string, any>[] = [\n    { Text: 'GENERAL', Id: 1, Color: '#bbdc00' },\n    { Text: 'DENTAL', Id: 2, Color: '#9e5fff' }\n  ];\n  public consultantDataSource: Record<string, any>[] = [\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  public group: GroupModel = { enableCompactView: false, resources: ['Departments', 'Consultants'] };\n  public allowMultiple = false;\n  public eventSettings: EventSettingsModel = {\n    dataSource: this.data,\n    fields: {\n      subject: { title: 'Patient Name', name: 'Name' },\n      startTime: { title: 'From', name: 'StartTime' },\n      endTime: { title: 'To', name: 'EndTime' },\n      description: { title: 'Reason', name: 'Description' }\n    }\n  };\n\n  public field: Record<string, any> = { dataSource: waitingList, id: 'Id', text: 'Name' };\n  public allowDragAndDrop = true;\n\n  public getConsultantName(value: ResourceDetails): string {\n    return (value as ResourceDetails).resourceData[(value as ResourceDetails).resource.textField!] as string;\n  }\n\n  public getConsultantStatus(value: ResourceDetails): boolean {\n    const resourceName: string = this.getConsultantName(value);\n    return !(resourceName === 'GENERAL' || resourceName === 'DENTAL');\n  }\n\n  public getConsultantDesignation(value: ResourceDetails): string {\n    const resourceName: string = this.getConsultantName(value);\n    if (resourceName === 'GENERAL' || resourceName === 'DENTAL') {\n      return '';\n    } else {\n      return (value as ResourceDetails).resourceData['Designation'] as string;\n    }\n  }\n\n  public getConsultantImageName(value: ResourceDetails): string {\n    return this.getConsultantName(value).toLowerCase();\n  }\n\n  public onTreeDrag(event: any): void {\n    if (this.scheduleObj.isAdaptive) {\n      const classElement: HTMLElement | null = this.scheduleObj.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\n  public onActionBegin(event: ActionEventArgs): void {\n    if (event.requestType === 'eventCreate' && this.isTreeItemDropped) {\n      const treeViewData: Record<string, any>[] = this.treeObj.fields.dataSource as Record<string, any>[];\n      const draggedItemIdNum: number = parseInt(this.draggedItemId, 10);\n      const filteredPeople: Record<string, any>[] = treeViewData.filter((item: any) => item['Id'] !== draggedItemIdNum);\n      this.treeObj.fields.dataSource = filteredPeople;\n      const elements: NodeListOf<HTMLElement> = document.querySelectorAll('.e-drag-item.treeview-external-drag');\n      for (const element of [].slice.call(elements)) {\n        remove(element);\n      }\n    }\n  }\n\n  public onItemSelecting(args: any): void {\n    args.cancel = true;\n  }\n\n  public onTreeDragStop(event: DragAndDropEventArgs): void {\n    const treeElement: Element = closest(event.target, '.e-treeview') as Element;\n    const classElement: HTMLElement | null = this.scheduleObj.element.querySelector('.e-device-hover');\n    if (classElement) {\n      classElement.classList.remove('e-device-hover');\n    }\n    if (!treeElement) {\n      event.cancel = true;\n      const scheduleElement: Element = closest(event.target, '.e-content-wrap') as Element;\n      if (scheduleElement) {\n        const treeviewData: Record<string, any>[] = this.treeObj.fields.dataSource as Record<string, any>[];\n        if (event.target.classList.contains('e-work-cells')) {\n          const draggedId: number = parseInt(event.draggedNodeData['id'] as string, 10);\n          const filteredData: Record<string, any>[] = treeviewData.filter((item: any) =>\n            item.Id === draggedId);\n          const cellData: CellClickEventArgs = this.scheduleObj.getCellDetails(event.target);\n          const resourceDetails: ResourceDetails = this.scheduleObj.getResourcesByIndex(cellData.groupIndex!);\n          const eventData: Record<string, any> = {\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          this.scheduleObj.openEditor(eventData, 'Add', true);\n          this.isTreeItemDropped = true;\n          this.draggedItemId = event.draggedNodeData['id'] as string;\n        }\n      }\n    }\n    document.body.classList.remove('e-disble-not-allowed');\n  }\n  public onTreeDragStart() {\n    document.body.classList.add('e-disble-not-allowed');\n  }\n\n}\n"
    },
    {
      "target": "src/components/scheduler-external-drag-and-drop/external-drag-drop.html",
      "content": "<div class=\"control-section\">\n  <div class=\"drag-sample-wrapper\">\n    <div class=\"schedule-container\">\n      <div class=\"title-container\">\n        <div class=\"title-text\">Doctor's Appointments</div>\n      </div>\n      <ejs-schedule #scheduleObj cssClass='schedule-drag-drop' width='100%' height='650px' [group]=\"group\"\n        [currentView]=\"currentView\" [selectedDate]=\"selectedDate\" [workHours]=\"workHours\"\n        [eventSettings]=\"eventSettings\" (actionBegin)=\"onActionBegin($event)\">\n        <e-resources>\n          <e-resource field='DepartmentID' title='Department' name='Departments' [dataSource]='departmentDataSource'\n            textField='Text' idField='Id' colorField='Color'>\n          </e-resource>\n          <e-resource field='ConsultantID' title='Consultant' name='Consultants' [dataSource]='consultantDataSource'\n            [allowMultiple]='allowMultiple' textField='Text' idField='Id' groupIDField=\"GroupId\" colorField='Color'>\n          </e-resource>\n        </e-resources>\n        <ng-template #resourceHeaderTemplate let-data>\n          <div class=\"template-wrap\">\n            <div class=\"specialist-category\">\n              <div *ngIf=\"getConsultantStatus(data)\">\n                <img src=\"./assets/schedule/images/{{getConsultantImageName(data)}}.png\" alt=\"{{getConsultantImageName(data)}}\" class=\"specialist-image\" />\n              </div>\n              <div class=\"specialist-name\">{{getConsultantName(data)}}</div>\n              <div class=\"specialist-designation\">{{getConsultantDesignation(data)}}</div>\n            </div>\n          </div>\n        </ng-template>\n        <e-views>\n          <e-view option='TimelineDay'></e-view>\n          <e-view option='TimelineMonth'></e-view>\n        </e-views>\n      </ejs-schedule>\n    </div>\n    <div class=\"treeview-container\">\n      <div class=\"title-container\">\n        <div class=\"title-text\">Waiting List</div>\n      </div>\n      <ejs-treeview #treeObj [fields]='field' cssClass='treeview-external-drag' dragArea=\".drag-sample-wrapper\"\n        [allowDragAndDrop]='allowDragAndDrop' (nodeDragStop)=\"onTreeDragStop($event)\" (nodeDragStart)=\"onTreeDragStart()\"\n        (nodeDragging)=\"onTreeDrag($event)\" (nodeSelecting)=\"onItemSelecting($event)\">\n        <ng-template #nodeTemplate let-data>\n          <div id=\"waiting\">\n            <div id=\"waitdetails\">\n              <div id=\"waitlist\">{{data.Name}}</div>\n              <div id=\"waitcategory\">{{data.DepartmentName}} - {{data.Description}}</div>\n            </div>\n          </div>\n        </ng-template>\n      </ejs-treeview>\n    </div>\n  </div>\n</div>\n\n"
    },
    {
      "target": "src/components/scheduler-external-drag-and-drop/external-drag-drop.style.css",
      "content": ".drag-sample-wrapper {\n  display: -ms-flexbox;\n  display: flex;\n}\n\n.schedule-container {\n  padding-right: 10px;\n  width: 100%;\n}\n\n.title-container {\n  padding-bottom: 10px;\n}\n\n.e-schedule.schedule-drag-drop .e-resource-cells.e-parent-node .template-wrap {\n  padding: 3px 0px;\n}\n\n.title-text {\n  font-size: 18px;\n  margin: 0px;\n  font-weight: bold;\n  text-align: center;\n  line-height: 1.1;\n}\n\n\n.treeview-external-drag #waiting {\n  height: 100%;\n  padding: 0;\n}\n\n.treeview-external-drag #waitdetails {\n  width: 95%;\n  float: left;\n  height: 100%;\n  padding: 0;\n}\n\n.treeview-external-drag #waitlist {\n  width: 100%;\n  height: 50%;\n  font-weight: bold;\n  font-family: \"Segoe UI\";\n  font-size: 12px;\n  padding: 5px 0 0 10px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.treeview-external-drag #waitcategory {\n  height: 50%;\n  font-family: \"Segoe UI\";\n  font-size: 10px;\n  opacity: 0.6;\n  padding-left: 10px;\n  padding-top: 5px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.treeview-external-drag .e-list-text, .treeview-external-drag.e-rtl .e-list-text, .e-bigger .treeview-external-drag .e-list-text, .e-bigger .treeview-external-drag.e-rtl .e-list-text {\n  border: 0.5px solid #E1E7EC;\n  height: 50px;\n  line-height: 15px !important;\n  padding: 0 5px;\n  width: 220px;\n}\n\n.treeview-external-drag .e-list-parent, .treeview-external-drag.e-rtl .e-list-parent, .e-bigger .treeview-external-drag .e-list-parent, .e-bigger .treeview-external-drag.e-rtl .e-list-parent {\n  height: 100%;\n  padding: 0 2px;\n}\n\n.treeview-external-drag .e-list-item, .e-bigger .treeview-external-drag .e-list-item {\n  height: 100%;\n  padding: 0 0 5px 0;\n}\n\n.treeview-external-drag .e-fullrow, .e-bigger .treeview-external-drag .e-fullrow {\n  height: 55px;\n}\n\n.treeview-external-drag .e-list-item.e-hover>.e-fullrow, .treeview-external-drag .e-list-item.e-active>.e-fullrow, .treeview-external-drag .e-list-item.e-active.e-hover>.e-fullrow, .e-bigger .treeview-external-drag .e-list-item.e-hover>.e-fullrow, .e-bigger .treeview-external-drag .e-list-item.e-active>.e-fullrow, .e-bigger .treeview-external-drag .e-list-item.e-active.e-hover>.e-fullrow {\n  background-color: transparent;\n  border-color: transparent;\n  box-shadow: none !important;\n}\n\n.fluent2-highcontrast .treeview-external-drag .e-list-item.e-hover > .e-text-content .e-list-text {\n  color: #fff;\n}\n\n.treeview-external-drag .e-text-content, .e-bigger .treeview-external-drag .e-text-content, .treeview-external-drag.e-rtl .e-text-content, .e-bigger .treeview-external-drag.e-rtl .e-text-content {\n  padding: 0;\n  background-color: inherit;\n}\n\n.e-drag-item.e-treeview.treeview-external-drag, .e-bigger .e-drag-item.e-treeview.treeview-external-drag {\n  padding: 0 !important;\n}\n\n.e-schedule.schedule-drag-drop .e-timeline-view .e-resource-left-td, .e-schedule.schedule-drag-drop .e-timeline-month-view .e-resource-left-td {\n  width: 160px;\n}\n\n.e-schedule.schedule-drag-drop .e-resource-cells.e-parent-node .specialist-category {\n  padding-left: 30px\n}\n\n.e-schedule.e-rtl.schedule-drag-drop .e-resource-cells.e-parent-node .specialist-category {\n  padding-right: 30px\n}\n\n.e-schedule.schedule-drag-drop .e-resource-cells.e-child-node .specialist-category, .e-schedule.schedule-drag-drop .e-resource-cells.e-child-node .specialist-name {\n  padding: 5px\n}\n\n.e-schedule.schedule-drag-drop .e-resource-cells.e-parent-node .specialist-name {\n  padding: 0 10px\n}\n\n.e-schedule.schedule-drag-drop .specialist-name {\n  font-size: 13px;\n}\n\n.e-schedule.schedule-drag-drop .specialist-designation {\n  font-size: 10px;\n}\n\n.e-device-hover {\n  background-color: #e0e0e0 !important;\n}\n\n.e-schedule.schedule-drag-drop .specialist-image {\n  width: 40px;\n  height: 40px;\n  float: left;\n  border-radius: 50%;\n  margin-right: 10px;\n}\n\n@media (max-width: 550px) {\n  /* custom code start*/\n  .drag-sample-wrapper {\n    display: block;\n  }\n  .schedule-container {\n    padding-bottom: 10px\n  }\n  /* custom code end*/\n  .treeview-external-drag.e-treeview, .e-bigger .treeview-external-drag.e-treeview {\n    width: 250px;\n  }\n  .e-bigger .treeview-external-drag.e-treeview.e-drag-item {\n    position: relative !important;\n  }\n}\n.e-disble-not-allowed {\n  cursor: unset !important;\n}\n\n.e-drag-item.treeview-external-drag .e-icon-expandable {\n  display: none;\n}"
    }
  ]
}