From 166e75db3f1571ee657f0b4b938e1d8ea63cd28a Mon Sep 17 00:00:00 2001 From: Ziad-I <68874104+Ziad-I@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:22:55 +0300 Subject: [PATCH] add editing of gantt chart from webui --- .../bim/data/webui/static/js/gantt.js | 22 ++++++++----- src/blenderbim/blenderbim/tool/web.py | 33 ++++++++++++++++++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js b/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js index c2188359c0..7399c72504 100644 --- a/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js +++ b/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js @@ -1,5 +1,5 @@ // keeps track of blenders connected in form of -// shown:bool, work_schedule: {}, task_json: {}, +// shown:bool, workSchedule: {}, ganttTasks: {}, const connectedClients = {}; let socket; @@ -40,8 +40,8 @@ function handleBlenderConnect(blenderId) { if (!connectedClients.hasOwnProperty(blenderId)) { connectedClients[blenderId] = { shown: false, - work_schedule: {}, - task_json: {}, + workSchedule: {}, + ganttTasks: {}, }; } } @@ -70,18 +70,20 @@ function handleGanttData(data) { if (!connectedClients[blenderId].shown) { connectedClients[blenderId] = { shown: true, - task_json: ganttTasks, - work_schedule: ganttWorkSched, + ganttTasks: ganttTasks, + workSchedule: ganttWorkSched, }; addGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); } else { updateGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); + connectedClients[blenderId].workSchedule = ganttWorkSched; + connectedClients[blenderId].ganttTasks = ganttTasks; } } else { connectedClients[blenderId] = { shown: true, - task_json: ganttTasks, - work_schedule: ganttWorkSched, + ganttTasks: ganttTasks, + workSchedule: ganttWorkSched, }; addGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); } @@ -208,6 +210,10 @@ function addGanttElement(blenderId, tasks, workSched, filename) { // Function to update gantt and filename function updateGanttElement(blenderId, tasks, workSched, filename) { + if (workSched != undefined) { + //TODO: handle updating work schedule table + } + let g = connectedClients[blenderId]["gantt"]; g.ClearTasks(); g.Draw(); @@ -250,7 +256,7 @@ function editValue(list, task, event, cell, column) { const ganttId = task.getGantt()["vDiv"].id; const index = ganttId.indexOf("-") + 1; const blenderId = ganttId.substring(index); - const workSchedId = connectedClients[blenderId].work_schedule.id; + const workSchedId = connectedClients[blenderId].workSchedule.id; // update data object reprsenting the task const dataObj = task.getDataObject(); diff --git a/src/blenderbim/blenderbim/tool/web.py b/src/blenderbim/blenderbim/tool/web.py index 90dd03f450..3d7649dac7 100644 --- a/src/blenderbim/blenderbim/tool/web.py +++ b/src/blenderbim/blenderbim/tool/web.py @@ -20,6 +20,7 @@ import bpy from blenderbim.bim.module.web.data import WebData import blenderbim.core.tool import blenderbim.tool as tool +import ifcopenshell.api.sequence import socket import os import subprocess @@ -35,6 +36,13 @@ ws_process = None ws_thread = None web_operator_queue = queue.Queue() +IFC_TASK_ATTRIBUTE_MAP = { + "pStart": "ScheduleStart", + "pEnd": "ScheduleFinish", + "pName": "", + "pRes": "", +} + class Web(blenderbim.core.tool.Web): @classmethod @@ -164,7 +172,30 @@ class Web(blenderbim.core.tool.Web): @classmethod def handle_gantt_operator(cls, operator_data): - print(operator_data) + ifc_file = tool.Ifc.get() + if operator_data["type"] == "editTask": + task_id = int(operator_data["taskId"]) + task_time = ifc_file.by_id(task_id).TaskTime + column = operator_data["column"] + new_value = operator_data["value"] + + # editing a parent task time will throw an exception + try: + ifcopenshell.api.sequence.edit_task_time( + ifc_file, task_time=task_time, attributes={IFC_TASK_ATTRIBUTE_MAP[column]: str(new_value)} + ) + except AttributeError: + pass + + bpy.ops.bim.load_task_properties() + + # after updating, send new gantt data to handle the case where + # changing a task cascades and changes other tasks. as this wouldn't + # be reflected in the web ui + work_schedule = ifc_file.by_id(operator_data["workScheduleId"]) + task_json = tool.Sequence.create_tasks_json(work_schedule) + gantt_data = {"tasks": task_json, "work_schedule": work_schedule.get_info(recursive=True)} + cls.send_webui_data(extra_data=gantt_data, extra_data_key="gantt_data", event="gantt_data") @classmethod def open_web_browser(cls, port):