Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #103981

    Hey there!

    I’m trying to add a an add task button to my project and it keeps failing 🙁
    The error I’me receiving is:
    Error Image

    My current code is:

    import React, { LegacyRef } from "react";
    import ReactDOM from "react-dom";
    import {
      Button,
      RepeatButton,
      ToggleButton,
      PowerButton,
    } from "smart-webcomponents-react/button";
    import { GanttChart } from "smart-webcomponents-react/ganttchart";
    import { MultilineTextBox } from "smart-webcomponents-react/multilinetextbox";
    import { TextBox } from "smart-webcomponents-react/textbox";
    import { t } from "@lingui/macro";
    import { MinusIcon, PlusIcon } from "@heroicons/react/outline";
    
    class Gantt2 extends React.Component {
      ganttchart: LegacyRef<GanttChart> | undefined;
      description: any;
      dayInput: LegacyRef<TextBox> | undefined;
      deleteBtn: LegacyRef<Button> | undefined;
      cancelBtn: React.RefObject<unknown>;
      saveBtn: React.RefObject<unknown>;
      task: null;
      eventPicker: null;
      taskLabel: null;
      dayPicker: null;
      monthPicker: null;
      yearPicker: null;
      dayIncrementBtn: null;
      dayDecrementBtn: null;
      totalDate: null;
      constructor(props:any) {
        super(props);
    
        this.ganttchart = React.createRef();
    
        this.deleteBtn = React.createRef();
        this.cancelBtn = React.createRef();
        this.saveBtn = React.createRef();
        this.dayInput = React.createRef();
        this.description = React.createRef();
    
        this.task = null;
        this.taskLabel = null;
        this.eventPicker = null;
        this.dayPicker = null;
        this.monthPicker = null;
        this.yearPicker = null;
        this.dayIncrementBtn = null;
        this.dayDecrementBtn = null;
        this.totalDate = null;
      }
    
      durationUnit = "day";
    
      view = "month";
    
      treeSize = "30%";
    
      dateStart = "2021-04-01";
    
      taskColumns = [
        {
          label: t<code>Machines</code>,
          value: "label",
          size: "35%",
        },
        {
          label: t<code>Rent ID</code>,
          value: "rent_id",
        },
        {
          label: "Duration",
          value: "duration",
          formatFunction: (date: string) => parseInt(date),
        },
        {
          label: t<code>Supplier</code>,
          value: "supplier",
        },
        {
          label: t<code>Client</code>,
          value: "client",
        },
        {
          label: 'Add',
          value: 'addTask',
          min: 35,
          formatFunction: function () {
            return '<span class="add-task-button">+</span>';
          }
        }
      ];
    
      dataSource = [
        {
          label: "Haulotte HA18PX",
          synchronized: true,
          rent_id: "",
          expanded: true,
          type: "project",
          supplier: "",
          client: "",
          tasks: [
            {
              label: "Arriendo 1",
              rent_id: 1,
              expanded: true,
              synchronized: true,
              dateStart: "2021-01-01",
              duration: 30,
              type: "project",
              supplier: "Televa",
              client: "Armando Ayala Flores",
              tasks: [
                {
                  label: "Entrega",
                  rent_id: "",
                  type: "milestone",
                  dateStart: "2021-01-01",
                  supplier: "",
                  client: "",
                  class: "delivery",
                },
                {
                  label: "En uso",
                  rent_id: "",
                  type: "task",
                  dateStart: "2021-01-09",
                  duration: 20,
                  supplier: "",
                  client: "",
                },
                {
                  label: "Mantenimiento",
                  rent_id: "",
                  type: "task",
                  dateStart: "2021-01-12",
                  duration: 3,
                  supplier: "",
                  client: "",
                },
                {
                  label: "Retiro",
                  rent_id: "",
                  type: "milestone",
                  dateStart: "2021-01-30",
                  supplier: "",
                  client: "",
                  class: "withdraw",
                },
              ],
            },
            {
              label: "Arriendo 2",
              rent_id: 1,
              expanded: true,
              synchronized: true,
              dateStart: "2021-02-01",
              duration: 15,
              type: "project",
              supplier: "Televa",
              client: "Armando Ayala Flores",
              tasks: [
                {
                  label: "Entrega",
                  rent_id: "",
                  type: "milestone",
                  dateStart: "2021-02-01",
                  supplier: "",
                  client: "",
                  class: "delivery",
                },
                {
                  label: "En uso",
                  rent_id: "",
                  type: "task",
                  dateStart: "2021-02-02",
                  duration: 10,
                  supplier: "",
                  client: "",
                },
                {
                  label: "Retiro",
                  rent_id: "",
                  type: "milestone",
                  dateStart: "2021-02-15",
                  supplier: "",
                  client: "",
                  class: "withdraw",
                },
              ],
            },
          ],
        },
      ];
    
      updateTotalDate() {
        let newDateEnd = new Date(
          parseInt(this.yearPicker.value),
          parseInt(this.monthPicker.value),
          parseInt(this.dayPicker.value)
        );
        newDateEnd.setDate(
          newDateEnd.getDate() + parseInt(this.dayInput.current.value)
        );
    
        if (isNaN(newDateEnd.getTime())) {
          this.totalDate.innerHTML = "";
          return;
        }
        this.totalDate.innerHTML = newDateEnd.toDateString();
      }
    
      deleteTask() {
        const gantt = this.ganttchart.current;
    
        gantt.removeTask(this.task);
        gantt.closeWindow();
        this.task = undefined;
      }
    
      cancelTask() {
        this.ganttchart.current.closeWindow();
      }
    
      saveTask() {
        const gantt = this.ganttchart.current;
        let dateStart = new Date(
            parseInt(this.yearPicker.value),
            parseInt(this.monthPicker.value),
            parseInt(this.dayPicker.value)
          ),
          duration = parseInt(this.dayInput.current.value);
    
          let type
          let taskClass
    
          switch (this.eventPicker.value) {
            case 'Entrega':
              type = 'milestone'
              taskClass = 'delivery'
              break;
            case 'En uso':
              type = 'task'
              taskClass = ''
              break;
            case 'Retiro':
              type = 'milestone'
              taskClass = 'withdraw'
              break;
            default:
              break;
          }
    
          
        gantt.updateTask(this.task, {
          label: this.eventPicker.value,
          dateStart: dateStart,
          duration: duration,
          type: type,
          class: taskClass
        });
    
        gantt.closeWindow();
        this.task = undefined;
      }
    
      handleDayIncrementBtn() {
        const that = this;
    
        this.dayInput.current.value = Math.min(
          31,
          (parseInt(this.dayInput.current.value) || 0) + 1
        ).toString();
        that.updateTotalDate();
      }
    
      handleDayDecrementBtn() {
        const that = this;
    
        this.dayInput.current.value = Math.max(
          1,
          (parseInt(this.dayInput.current.value) || 0) - 1
        ).toString();
        that.updateTotalDate();
      }
    
      popupWindowCustomizationFunction(target, type, targetTask) {
        const that = this,
          gantt = that.ganttchart.current;
    
        if (type === "task" && targetTask) {
          //Hide the header
          target.headerPosition = "none";
          target.footerPosition = "none";
    
          //Create the content
          if (!that.description.current) {
            target.clear();
    
            const template = document.getElementById("myTemplate");
    
            target.appendChild(template?.content);
    
            ReactDOM.render(
              <MultilineTextBox
                ref={this.description}
                id="description"
              ></MultilineTextBox>,
              document.getElementById("multilineTextBoxContainer"),
              function () {
                that.description.current.value = targetTask.label;
              }
            );
            ReactDOM.render(
              <section>
                <RepeatButton
                  id="dayDecrementBtn"
                  onClick={this.handleDayDecrementBtn.bind(this)}
                >
                  <MinusIcon className="h-4 w-4" />
                </RepeatButton>
                <TextBox ref={this.dayInput} id="dayInput"></TextBox>
                <RepeatButton
                  id="dayIncrementBtn"
                  onClick={this.handleDayIncrementBtn.bind(this)}
                >
                  <PlusIcon className="h-4 w-4" />
                </RepeatButton>
              </section>,
              new DocumentFragment(),
              function () {
                that.dayInput.current.value = targetTask.duration.toString();
    
                while (this.children.length) {
                  document
                    .getElementById("buttonContainer")
                    .appendChild(this.firstChild);
                }
              }
            );
            ReactDOM.render(
              <section>
                <Button
                  className="text-red normal-case"
                  ref={this.deleteBtn}
                  id="deleteBtn"
                  onClick={this.deleteTask.bind(this)}
                >
                  Borrar
                </Button>
                <Button
                  className=" normal-case"
                  ref={this.cancelBtn}
                  id="cancelBtn"
                  onClick={this.cancelTask.bind(this)}
                >
                  Cancelar
                </Button>
                <Button
                  className="ml-4 inline-flex justify-center border border-transparent shadow-sm text-sm rounded-md text-white bg-primary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 normal-case"
                  ref={this.saveBtn}
                  id="saveBtn"
                  onClick={this.saveTask.bind(this)}
                >
                  Guardar
                </Button>
              </section>,
              new DocumentFragment(),
              function () {
                while (this.children.length) {
                  document?.getElementById("buttonContainer2").appendChild(this.firstChild);
                }
              }
            );
          }
    
          that.eventPicker = document.getElementById("eventPicker");
          that.taskLabel = document.getElementById("taskLabel");
          that.dayPicker = document.getElementById("dayPicker");
          that.monthPicker = document.getElementById("monthPicker");
          that.yearPicker = document.getElementById("yearPicker");
          that.dayIncrementBtn = document.getElementById("dayIncrementBtn");
          that.dayDecrementBtn = document.getElementById("dayDecrementBtn");
          that.totalDate = document.getElementById("totalDate");
    
          that.task = targetTask;
    
          //Configure the content
          const dateStart = targetTask.dateStart,
            dateEnd = targetTask.dateEnd;
    
          if (!dateStart || !dateEnd) {
            that.taskLabel.innerHTML = "";
          } else {
            that.taskLabel.innerHTML =
              dateStart.toLocaleDateString(gantt.locale) +
              " - " +
              dateEnd.toLocaleDateString(gantt.locale);
          }
    
          console.log(targetTask.type)
    
          that.dayPicker.value = dateStart.getDate().toString();
          that.monthPicker.value = dateStart.getMonth().toString();
          that.yearPicker.value = dateStart.getFullYear().toString();
          that.totalDate.innerHTML = targetTask.dateEnd.toDateString();
    
          that.eventPicker.value = targetTask.label
        }
    
        if (that.dayInput.current) {
          that.dayInput.current.value = targetTask.duration.toString();
        }
    
        const dateControls = target.querySelector(
          ".custom-window-content-section.date-control"
        );
    
        if (dateControls) {
          if (targetTask.type === "project" && targetTask.synchronized) {
            dateControls.setAttribute("disabled", true);
          } else {
            dateControls.removeAttribute("disabled");
          }
        }
      }
    
      init() {
        const template = document.createElement("template");
    
        template.id = "myTemplate";
        template.innerHTML = 

    <div class=”custom-window-content”>
    <div class=”custom-window-content-section”>
    <label id=”taskLabel”></label>
    </div>
    <div>
    <div class=”custom-window-content-section”> <b>Evento</b>
    </div>
    <div class=”custom-window-content-section w-full type-control”>
    <select id=”eventPicker” class=”w-full”>
    <option value=”Entrega”>Entrega</option>
    <option value=”En uso”>En uso</option>
    <option value=”Retiro”>Retiro</option>
    </select>
    </div>

    <div class=”grid grid-cols-2″>
    <div>
    <div class=”custom-window-content-section”>
    <b>Start date</b>
    </div>
    <div class=”custom-window-content-section”>
    <div class=”custom-window-content-section date-control”>
    <select id=”dayPicker”>
    <option value=”1″>1</option>
    <option value=”2″>2</option>
    <option value=”3″>3</option>
    <option value=”4″>4</option>
    <option value=”5″>5</option>
    <option value=”6″>6</option>
    <option value=”7″>7</option>
    <option value=”8″>8</option>
    <option value=”9″>9</option>
    <option value=”10″>10</option>
    <option value=”11″>11</option>
    <option value=”12″>12</option>
    <option value=”13″>13</option>
    <option value=”14″>14</option>
    <option value=”15″>15</option>
    <option value=”16″>16</option>
    <option value=”17″>17</option>
    <option value=”18″>18</option>
    <option value=”19″>19</option>
    <option value=”20″>20</option>
    <option value=”21″>21</option>
    <option value=”22″>22</option>
    <option value=”23″>23</option>
    <option value=”24″>24</option>
    <option value=”25″>25</option>
    <option value=”26″>26</option>
    <option value=”27″>27</option>
    <option value=”28″>28</option>
    <option value=”29″>29</option>
    <option value=”30″>30</option>
    <option value=”31″>31</option>
    </select>
    <select id=”monthPicker”>
    <option value=”0″>January</option>
    <option value=”1″>February</option>
    <option value=”2″>March</option>
    <option value=”3″>April</option>
    <option value=”4″>May</option>
    <option value=”5″>June</option>
    <option value=”6″>July</option>
    <option value=”7″>August</option>
    <option value=”8″>September</option>
    <option value=”9″>October</option>
    <option value=”10″>November</option>
    <option value=”11″>December</option>
    </select>
    <select id=”yearPicker”>
    <option value=”2013″>2016</option>
    <option value=”2014″>2017</option>
    <option value=”2015″>2018</option>
    <option value=”2016″>2019</option>
    <option value=”2020″>2020</option>
    <option value=”2021″>2021</option>
    <option value=”2021″>2021</option>
    <option value=”2020″>2020</option>
    <option value=”2021″>2021</option>
    <option value=”2022″>2022</option>
    <option value=”2022″>2023</option>
    <option value=”2022″>2024</option>
    <option value=”2022″>2025</option>
    <option value=”2022″>2026</option>
    <option value=”2022″>2027</option>
    </select>
    </div>
    </div>
    </div>
    <div>
    <div class=”custom-window-content-section”>
    <b>Qty. of days</b>
    </div>
    <div class=”custom-window-content-section flex items-center gap-1″ id=”buttonContainer”>

    </div>
    <div class=”custom-window-content-section”>
    <label id=”totalDate”></label>
    </div>
    </div>
    </div>
    <div class=”custom-window-content-section”> <b>Description</b>
    </div>
    <div class=”custom-window-content-section” id=”multilineTextBoxContainer”>

    </div>

    </div>
    <div class=”custom-window-content-section buttons” id=”buttonContainer2″>

    </div>
    </div>
    `;

    document.body.appendChild(template);
    }

    handleGanttClick(event:any) {
    const ganttChart = document.getElementById(‘gantt’);
    console.log(event.target)
    const eventDetails = event.detail,
    target = event.target;

    console.log(eventDetails.item)

    if (target.classList.contains(‘add-task-button’)) {
    const itemIndex = parseInt(ganttChart.getItemPath(eventDetails.item).split(‘.’).slice(-1)[0]) + 1,
    itemProject = ganttChart.getItemPath(ganttChart.getTaskProject(eventDetails.item));

    //Add a new Task
    const newItemId = ganttChart.insertTask({
    label: ‘New Task’,
    dateStart: ganttChart.dateStart
    }, itemProject, itemIndex);

    //Open the Editor to configure
    ganttChart.openWindow(newItemId);
    }
    }

    componentDidMount() {
    this.init();
    }

    render() {
    return (
    <div>
    <GanttChart
    ref={this.ganttchart}
    id=”gantt”
    durationUnit={this.durationUnit}
    dataSource={this.dataSource}
    view={this.view}
    treeSize={this.treeSize}
    dateStart={this.dateStart}
    taskColumns={this.taskColumns}
    popupWindowCustomizationFunction={this.popupWindowCustomizationFunction.bind(
    this
    )}
    onClick={this.handleGanttClick.bind(this)}
    ></GanttChart>
    </div>
    );
    }
    }

    export default Gantt2;

    `

    #103985

    Hi,

    You are using the onClick event in which there isn’t event.detail or event.detail.item.
    You should you onItemClick and also get the target from here: event.detail.originalEvent.target

    Here is the desired method:

    handleGanttClick(event: CustomEvent) {
    const ganttChart = this.ganttchart?.current;
    const eventDetails = event.detail;
    const target = event.detail.originalEvent.target;
    if (target.classList.contains(‘add-task-button’)) {
    const itemIndex = parseInt(
    ganttChart?.getItemPath(eventDetails.item).split(‘.’).slice(-1)[0]) + 1,
    itemProject = ganttChart?.getItemPath(ganttChart.getTaskProject(eventDetails.item)
    );
    //Add a new Task
    const newItemId = ganttChart?.insertTask(
    {
    label: ‘New Task’,
    dateStart: ganttChart.dateStart
    },
    itemProject,
    itemIndex
    );
    //Open the Editor to configure
    ganttChart?.openWindow(newItemId);
    }
    }

    I hope this helps!

    Best Regards,
    Svetoslav Borislavov

    Smart UI Team
    https://www.htmlelements.com/

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.