From f338f66b4bf966444b5fc2ebb5ad6e9763fb8e44 Mon Sep 17 00:00:00 2001 From: Ziad-I <68874104+Ziad-I@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:02:16 +0300 Subject: [PATCH] add gantt html/css/js --- .../bim/data/webui/static/css/gantt.css | 309 ++++++++++++++++++ .../bim/data/webui/static/js/gantt.js | 130 ++++++++ .../bim/data/webui/templates/gantt.html | 33 ++ 3 files changed, 472 insertions(+) create mode 100644 src/blenderbim/blenderbim/bim/data/webui/static/css/gantt.css create mode 100644 src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js create mode 100644 src/blenderbim/blenderbim/bim/data/webui/templates/gantt.html diff --git a/src/blenderbim/blenderbim/bim/data/webui/static/css/gantt.css b/src/blenderbim/blenderbim/bim/data/webui/static/css/gantt.css new file mode 100644 index 0000000000..3b511f653b --- /dev/null +++ b/src/blenderbim/blenderbim/bim/data/webui/static/css/gantt.css @@ -0,0 +1,309 @@ +:root { + color-scheme: dark; +} + +body { + background-color: #252525; + color: #e0e0e0; + margin: 0; + font-family: Arial, sans-serif; +} + +#container { + margin-top: 20px; + margin-left: 10px; + margin-right: 10px; + margin-bottom: 20px; +} + +h3 { + margin-top: 0; +} + +nav { + background-color: #121212; + padding: 1em 0; + display: flex; + align-items: center; + position: relative; +} + +nav .logo { + margin-left: 40px; + height: 40px; + /* Adjust height as needed */ +} + +nav ul { + list-style-type: none; + margin: 0; + margin-left: 1px; + display: flex; + flex-grow: 1; + justify-content: center; +} + +nav ul li { + margin-right: 50px; +} + +nav ul li a { + text-decoration: none; + color: #fff; + font-size: 1.2em; +} + +nav ul li a:hover, +nav ul li a.active { + color: #3fb449; +} + +nav .bottom-bar { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 2px; + background-color: #25682a; +} + + +/* ------------ Overwriting JSGantt CSS rules for Dark Mode ------------ */ + +div.gantt { + background-color: #252525; + color: #c7c7c7; +} + +.gantt table { + border-color: #464444; + ; +} + +.gantt td { + border-color: #464444; + ; +} + +/* Headings and cell defaults */ +.gmajorheading, +.gminorheading, +.gminorheadingwkend, +.gtaskcell, +.gtaskcellcurrent, +.gtaskcellwkend, +.gname, +.ggroupitem { + background-color: #252525; + border-color: #464444; + ; +} + +.gtaskheading, +.gname, +.gtaskname, +.gres, +.gdur, +.gcomp, +.gstartdate, +.gplanstartdate, +.gplanenddate, +.gcost, +.gchartlbl, +.gcontainercol, +.genddate { + background-color: #252525; + color: #c7c7c7; + border-color: #464444; + ; +} + +.gtaskname>div, +.gtaskeditable>div { + background: #252525; + color: #c7c7c7; +} + +.gtaskbarcontainer.gplan { + background: #252525; + border-color: #464444; +} + +.gtaskname div, +.gtaskheading div { + background-color: #252525; + color: #c7c7c7; +} + +/* Task bar colors */ +.gtaskblue { + background: rgb(58, 132, 195); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(58, 132, 195, 1) 0%, rgba(65, 154, 214, 1) 20%, rgba(75, 184, 240, 1) 40%, rgba(58, 139, 194, 1) 70%, rgba(38, 85, 139, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4bb8f0', endColorstr='#3a84c3', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskred { + background: rgb(196, 58, 58); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(196, 58, 58, 1) 0%, rgba(211, 65, 65, 1) 20%, rgba(239, 76, 76, 1) 40%, rgba(196, 58, 58, 1) 70%, rgba(135, 37, 37, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ef4c4c', endColorstr='#c43a3a', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskgreen { + background: rgb(80, 193, 58); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(80, 193, 58, 1) 0%, rgba(88, 209, 64, 1) 20%, rgba(102, 237, 75, 1) 40%, rgba(80, 193, 58, 1) 70%, rgba(53, 132, 37, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#66ED4B', endColorstr='#50c13a', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskyellow { + background: rgb(247, 228, 56); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(247, 228, 56, 1) 0%, rgba(239, 239, 55, 1) 20%, rgba(255, 255, 58, 1) 40%, rgba(242, 236, 55, 1) 70%, rgba(241, 218, 54, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff3a', endColorstr='#f7e438', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskpurple { + background: rgb(193, 58, 193); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(193, 58, 193, 1) 0%, rgba(211, 65, 211, 1) 20%, rgba(239, 76, 239, 1) 40%, rgba(193, 58, 193, 1) 70%, rgba(137, 38, 137, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ef4cef', endColorstr='#892689', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskpink { + background: rgb(249, 177, 245); + /* Old browsers */ + background: linear-gradient(to bottom, rgba(249, 177, 245, 1) 0%, rgba(247, 192, 243, 1) 20%, rgba(247, 202, 244, 1) 40%, rgba(249, 192, 246, 1) 70%, rgba(252, 174, 247, 1) 100%); + /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7caf4', endColorstr='#fcaef7', GradientType=0); + /* IE6-9 */ + border-color: #252525; +} + +.gtaskbluecomplete, +.gtaskredcomplete, +.gtaskgreencomplete, +.gtaskyellowcomplete, +.gtaskpurplecomplete, +.gtaskpinkcomplete { + background-color: #252525; + border-color: #464444; + ; +} + +.gchartgrid { + background-color: #252525; +} + +.glistgrid, +.glistlbl { + background-color: #252525; + border-color: #464444; + ; +} + +/* .gTaskInfo { + background-color: #2e2e2e; + color: #c7c7c7; + border-color: #c7c7c7;; +} */ + +/* Dark mode scrollbar */ +.frame::-webkit-scrollbar-thumb { + background-color: #252525; +} + +.frame::-webkit-scrollbar-track { + background-color: #252525; +} + +/* Highlight row */ +.gitemhighlight td { + background-color: #3a3a3a; + color: #ffffff; +} + +/* Differentiate Group, Milestone and Ordinary task items (applied to row) */ +.ggroupitem { + background-color: #252525; + font-weight: bold; + border-color: #464444; +} + +.gmileitem, +.glineitem { + background-color: #252525; +} + +/* Task bar caption text styles */ +.gmilecaption, +.ggroupcaption, +.gcaption { + color: #ffffff; +} + +/* Task complete %age bar */ +.gtaskcomplete { + background-color: #777777; +} + +/* Milestones */ +.gmdtop { + border-bottom: 5px solid #ffffff; +} + +.gmdbottom { + border-top: 5px solid #ffffff; +} + +.gfoldercollapse { + color: #c7c7c7; + cursor: pointer; + font-weight: bold; + + font-size: 12px; + font-family: Courier, "Courier New", monospace; +} + +/* Form label and selected highlighting */ +.gformlabel { + background-color: #2e2e2e; + color: #c7c7c7; + border: #4a4a4a 1px solid; +} + +span.gformlabel:hover { + background-color: #3a3a3a; + border-color: #565656; +} + +span.gselected { + background-color: #565656; + border-color: #777777; + color: #ffffff; +} + +.gantt-inputtable input { + background-color: #3b3b3b; + border-top: 1px solid #4a4a4a; + border-left: 1px solid #4a4a4a; + border-right: none; + border-bottom: none; + color: #c7c7c7; +} \ No newline at end of file diff --git a/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js b/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js new file mode 100644 index 0000000000..7f46c1385c --- /dev/null +++ b/src/blenderbim/blenderbim/bim/data/webui/static/js/gantt.js @@ -0,0 +1,130 @@ +// keeps track of blenders connected in form of +// shown:bool, work_sched: {}, task_json: {}, +const connectedClients = {}; +let socket; + +// Document ready function +$(document).ready(function () { + connectSocket(); +}); + +// Function to connect to Socket.IO server +function connectSocket() { + const url = "ws://localhost:" + SOCKET_PORT + "/web"; + socket = io(url); + console.log("socket: ", socket); + + // Register socket event handlers + socket.on("blender_connect", handleBlenderConnect); + socket.on("blender_disconnect", handleBlenderDisconnect); + socket.on("gantt_data", handleGanttData); +} + +// Function to handle 'blender_connect' event +function handleBlenderConnect(blenderId) { + console.log("blender_connect: ", blenderId); + if (!connectedClients.hasOwnProperty(blenderId)) { + connectedClients[blenderId] = { + shown: false, + work_sched: {}, + task_json: {}, + }; + } +} + +// Function to handle 'blender_disconnect' event +function handleBlenderDisconnect(blenderId) { + console.log("blender_disconnect: ", blenderId); + if (connectedClients.hasOwnProperty(blenderId)) { + delete connectedClients[blenderId]; + removeGanttElement(blenderId); + } +} + +// Function to handle 'gantt_data' event +function handleGanttData(data) { + const blenderId = data["blenderId"]; + const ganttTasks = data["data"]["tasks"]; + // const ganttWorkSched = data["data"]["schedule"]; + const ganttWorkSched = {}; + const filename = data["data"]["IFC_File"]; + console.log(data); + console.log(ganttTasks); + + if (connectedClients.hasOwnProperty(blenderId)) { + if (!connectedClients[blenderId].shown) { + connectedClients[blenderId] = { + shown: false, + work_sched: ganttTasks, + task_json: ganttWorkSched, + }; + addGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); + } else { + updateGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); + } + } else { + connectedClients[blenderId] = { + shown: false, + work_sched: ganttTasks, + task_json: ganttWorkSched, + }; + addGanttElement(blenderId, ganttTasks, ganttWorkSched, filename); + } +} + +// Function to add a new gantt with data and filename +function addGanttElement(blenderId, tasks, WorkSched, filename) { + const ganttContainer = $("
") + .addClass("gantt-container") + .attr("id", "container-" + blenderId); + + const ganttTitle = $("") + .attr("id", "title-" + blenderId) + .text(filename) + .css("margin-bottom", "10px"); + + const ganttDiv = $("") + .addClass("gantt-chart") + .attr("id", "gantt-" + blenderId); + + ganttContainer.append(ganttTitle); + ganttContainer.append(ganttDiv); + $("#container").append(ganttContainer); + + let g = new JSGantt.GanttChart($("#gantt-" + blenderId)[0], "week"); + g.setOptions({ + vCaptionType: "Caption", // Set to Show Caption : None,Caption,Resource,Duration,Complete, + vQuarterColWidth: 36, + vDateTaskDisplayFormat: "day dd month yyyy", // Shown in tool tip box + vDayMajorDateDisplayFormat: "mon yyyy - Week ww", // Set format to dates in the "Major" header of the "Day" view + vWeekMinorDateDisplayFormat: "dd mon", // Set format to display dates in the "Minor" header of the "Week" view + vLang: "en", + vShowTaskInfoLink: 1, // Show link in tool tip (0/1) + vShowEndWeekDate: 0, // Show/Hide the date for the last day of the week in header for daily + vUseSingleCell: 10000, // Set the threshold cell per table row (Helps performance for large data. + vFormatArr: ["Day", "Week", "Month", "Quarter"], // Even with setUseSingleCell using Hour format on such a large chart can cause issues in some browsers, + vShowRes: true, // Disable the resource column. + vShowComp: false, // Disable the completion column. + vShowDur: false, // Disable the duration column, because jsgantt doesn't calculate durations the way we want. + vAdditionalHeaders: { + ifcduration: { title: "Duration" }, + resourceUsage: { title: "Resource Usage" }, + }, + vUseToolTip: true, // Disable tooltips. + // vTooltipTemplate: createTooltip, + vTotalHeight: 900, + }); + for (var i = 0; i < tasks.length; i++) { + g.AddTaskItemObject(tasks[i]); + } + g.setEditable(true); + g.Draw(); +} + +// Function to update gantt and filename +function updateGanttElement(blenderId, ganttTasks, ganttWorkSched, filename) {} + +// Function to remove gantt element +function removeGanttElement(blenderId) { + $("#container-" + blenderId).remove(); +} diff --git a/src/blenderbim/blenderbim/bim/data/webui/templates/gantt.html b/src/blenderbim/blenderbim/bim/data/webui/templates/gantt.html new file mode 100644 index 0000000000..eb7795db5e --- /dev/null +++ b/src/blenderbim/blenderbim/bim/data/webui/templates/gantt.html @@ -0,0 +1,33 @@ + + + + + +