diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/components/contextMenu.css b/src/bonsai/bonsai/bim/data/webui/static/css/components/contextMenu.css index be67990261..4cc83a77a2 100644 --- a/src/bonsai/bonsai/bim/data/webui/static/css/components/contextMenu.css +++ b/src/bonsai/bonsai/bim/data/webui/static/css/components/contextMenu.css @@ -2,15 +2,7 @@ th { position: relative; } -.resizer { - position: absolute; - right: 0; - top: 0; - width: 5px; - height: 100%; - cursor: col-resize; - user-select: none; -} + .context-menu { display: none; position: absolute; diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/components/floatingForm.css b/src/bonsai/bonsai/bim/data/webui/static/css/components/floatingForm.css new file mode 100644 index 0000000000..b546803bf1 --- /dev/null +++ b/src/bonsai/bonsai/bim/data/webui/static/css/components/floatingForm.css @@ -0,0 +1,71 @@ +.floating-form { + width: 50vw; + max-height: 80vh; + position: absolute; + background-color: var(--background-color); + border: 1px solid black; + z-index: 9999; + cursor: move; + user-select: none; + padding-bottom: var(--padding-medium); +} + +[id^="enable-editing-quantities"].floating-form { + height: 70vh; +} + +.form-header { + display: flex; + justify-content: center; + align-items: center; + background-color: #323936; + padding: var(--padding-medium); + font-size: large; + border-bottom: 1px solid #ddd; + border-radius: 6px 6px 0 0; + height: 5%; + position: relative; +} + +.form-container { + height: 95%; + padding-left: var(--padding-medium); + padding-right: var(--padding-medium); +} + +.form-section { + margin-bottom: 1em; + height: 70%; +} + +.form-section h3 { + margin-bottom: 0.5em; +} + +.summary-section { + margin-top: 1em; +} + +.summary-table { + width: 100%; + border-collapse: collapse; + font-size: 14px; + text-align: left; +} + +.floating-form tr { + margin-bottom: 10px; +} + +.floating-form td { + padding: 3px; +} + +.table-container { + display: flex; + flex-direction: column; + border: 1px solid #ccc; + border-radius: 5px; + overflow: auto; + max-height: 400px; +} diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/components/layeredViewPanel.css b/src/bonsai/bonsai/bim/data/webui/static/css/components/layeredViewPanel.css new file mode 100644 index 0000000000..b564940b5f --- /dev/null +++ b/src/bonsai/bonsai/bim/data/webui/static/css/components/layeredViewPanel.css @@ -0,0 +1,43 @@ + +.selected { + border-color: #28a745; + outline: none; + box-shadow: 0 0 0 3px #28a745; + color: #ddd; + } + + + .classificationView { + border-left: 5px solid #28a745; + min-height: 200px; + overflow-y: auto; + overflow-x: hidden; + padding: 5px; + max-height: 400px; + } + + .selectedClassificationText { + color: #28a745; + } + + .back-button { + margin-bottom: 20px; + } + + .back-button:disabled { + cursor: not-allowed; + background-color: #ccc; + } + + .classification-cell { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; + } + + .classification { + height: 100%; + } + \ No newline at end of file diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/components/message.css b/src/bonsai/bonsai/bim/data/webui/static/css/components/message.css new file mode 100644 index 0000000000..2c34fcd34f --- /dev/null +++ b/src/bonsai/bonsai/bim/data/webui/static/css/components/message.css @@ -0,0 +1,67 @@ + +.message { + position: relative; + padding: 10px; + border-radius: 5px; + margin: 10px 0; + display: flex; + align-items: center; + justify-content: flex-start; + } + + .message span { + width: 80%; + } + + .message .icon { + margin-right: 10px; + } + + .message .close-button { + width: 24px; + height: 24px; + display: flex; + align-items: center; + transition: background-color 0.3s, color 0.3s; + padding-left: 5px; + } + + .message .close-button:hover { + background-color: #ffcccc; + } + + .error { + color: red; + border: 1px solid red; + background-color: #ffe6e6; + } + + .error .close-button { + color: red; + } + + .error .close-button:hover { + color: darkred; + } + + .success { + color: green; + border: 1px solid green; + background-color: #e6ffe6; + } + + .success .close-button { + color: green; + } + + .success .close-button:hover { + background-color: #ccffcc; + color: darkgreen; + } + + .card { + margin: 10px; + } + .card-body { + height: 10vh; + } \ No newline at end of file diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/components/table.css b/src/bonsai/bonsai/bim/data/webui/static/css/components/table.css new file mode 100644 index 0000000000..32e17746ae --- /dev/null +++ b/src/bonsai/bonsai/bim/data/webui/static/css/components/table.css @@ -0,0 +1,117 @@ +.cost-tables { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(700px, 2fr)); + grid-auto-rows: minmax(350px, auto); + gap: 10px; + font-size: var(--fontSize); +} + +.schedule { + border: 1px solid #ccc; + position: relative; + overflow: hidden; /* Ensure content doesn't overflow */ + display: flex; + flex-direction: column; +} + +.table-wrapper { + flex: 1; + overflow-y: auto; /* Enables vertical scrolling */ +} + +thead .resizer { + position: absolute; + right: 0; + top: 0; + width: 5px; + height: 100%; + cursor: col-resize; + user-select: none; +} + +table { + table-layout: auto; + width: 100%; + border-collapse: collapse; + border: 1px solid #ccc; /* Optional: adds a border around the table */ +} + +thead { + background-color: #727272; + position: sticky; + top: 0; + z-index: 1; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +tbody { + width: 100%; /* Ensure full width for alignment */ +} + +th, +td { + padding: 5px; + border-right: 1px solid #ccc; + text-align: left; +} + +th, +td { + word-wrap: break-word; + border-right: 1px solid #ddd; + text-align: center; + height: 100%; + width: auto; + overflow: hidden; +} + +th { + border-bottom: 1px solid #ddd; +} + +td { + align-items: center; +} + +.actions-column { + transition: opacity 0.3s ease-in-out; + opacity: 0; + width: fit-content; + min-width: fit-content; + max-width: 50%; +} + +[id^="cost-items"] tr:hover .actions-column { + opacity: 1; +} + +.selected-cell, +.clickable-cell:hover { + border: 2px solid var(--highlight-over); + cursor: pointer; +} + +td { + position: relative; +} + +@media (max-width: 1024px) { + .cost-tables { + grid-template-columns: 2fr; /* One column on smaller screens */ + } +} + +@media (max-width: 768px) { + .cost-tables { + grid-template-columns: 1fr; /* One column on smaller screens */ + } +} + +.table-wrapper.collapsed { + max-height: 40px; + overflow: hidden; +} + +.table-wrapper .form-header { + cursor: pointer; +} diff --git a/src/bonsai/bonsai/bim/data/webui/static/css/cost.css b/src/bonsai/bonsai/bim/data/webui/static/css/cost.css index 5378135184..a64a3690d4 100644 --- a/src/bonsai/bonsai/bim/data/webui/static/css/cost.css +++ b/src/bonsai/bonsai/bim/data/webui/static/css/cost.css @@ -2,6 +2,10 @@ @import url("./components/card.css"); @import url("./components/contextMenu.css"); @import url("./components/headerBar.css"); +@import url("./components/table.css"); +@import url("./components/floatingForm.css"); +@import url("./components/message.css"); +@import url("./components/layeredViewPanel.css"); :root { --fontSize: 14px; @@ -15,74 +19,32 @@ --padding-small: 5px; --padding-medium: 10px; } + body { margin: 0; padding: 0; box-sizing: border-box; height: 100vh; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -.floating-form { - width: 50vw; - max-height: 80vh; - position: absolute; - background-color: var(--background-color); - border: 1px solid black; - z-index: 9999; - cursor: move; - user-select: none; - padding-bottom: var(--padding-medium); +.floating-form .table-container { + max-height: 80%; + box-shadow: 0 5px 5px 0 #254e3c; } -[id^="enable-editing-quantities"].floating-form { - height: 70vh; +#cost-items { + max-height: calc(100vh - var(--margin-small)); } -.form-header { - display: flex; - justify-content: center; - align-items: center; - background-color: #323936; - padding: var(--padding-medium); - font-size: large; - border-bottom: 1px solid #ddd; - border-radius: 6px 6px 0 0; - height: 5%; - position: relative; +[id^="cost-values-form"] table { + max-height: 50%; + table-layout: fixed; } -.form-container { - height: 95%; - padding-left: var(--padding-medium); - padding-right: var(--padding-medium); -} - -.form-section { - margin-bottom: 1em; - height: 70%; -} - -.form-section h3 { - margin-bottom: 0.5em; -} - -.summary-section { - margin-top: 1em; -} - -.summary-table { - width: 100%; - border-collapse: collapse; - font-size: 14px; - text-align: left; -} - -.floating-form tr { - margin-bottom: 10px; -} - -.floating-form td { - padding: 3px; +[id^="selected-products"] .form-container { + height: 50vh; } .action-button { @@ -168,84 +130,6 @@ body { background: var(--scrollbar-thumb-hover-color); } -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.table-container { - margin-top: 1em; - display: flex; - flex-direction: row; -} - -.table-wrapper { - flex: 1; - overflow: auto; - border: 2px solid #254e3c; -} - -.floating-form .table-container { - max-height: 80%; - overflow: auto; - box-shadow: 0 5px 5px 0 #254e3c; -} - -#cost-items { - max-height: calc(100vh - var(--margin-small)); -} - -[id^="cost-values-form"] table { - max-height: 50%; - table-layout: fixed; -} - -[id^="selected-products"] .form-container { - height: 50vh; -} - -tr, -td, -th { - height: 100%; -} - -table { - width: 100%; - border-collapse: collapse; - font-size: var(--fontSize); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -thead { - position: sticky; - top: 0; - z-index: 1; - background-color: #727272; -} - -tbody { - width: 100%; - height: 100%; - overflow: auto; -} - -td, -th { - border-right: 1px solid #ddd; - text-align: center; - height: 100%; -} - -th { - border-bottom: 1px solid #ddd; -} - -td { - align-items: center; -} - .flex-container { display: flex; justify-content: space-between; @@ -329,39 +213,6 @@ form select { text-align: center; } -@media (max-width: 768px) { - table { - font-size: 12px; - } - - td, - th { - padding: 2px; - font-size: 12px; - } - - input { - padding: 2px; - font-size: 12px; - } -} - -@media (max-width: 480px) { - table { - font-size: 10px; - } - - td, - th { - padding: 2px; - } - - input { - padding: 1px; - font-size: 10px; - } -} - form table { max-height: 50%; } @@ -371,36 +222,6 @@ form table { font-weight: bold; } -[id^="cost-items"] th:nth-child(1), -[id^="cost-items"] td:nth-child(1) { - width: auto; -} - -[id^="cost-items"] th:last-child, -[id^="cost-items"] td:last-child { - width: fit-content; - min-width: fit-content; - max-width: 50%; -} - -.actions-column { - transition: opacity 0.3s ease-in-out; - opacity: 0; -} - -[id^="cost-items"] tr:hover .actions-column { - opacity: 1; -} - -.selected-cell, .clickable-cell:hover { - border: 2px solid var(--highlight-over); - cursor: pointer; -} - -td { - position: relative; -} - .append-right { right: 0; top: 50%; @@ -412,46 +233,6 @@ i { margin-right: 5px; } -.classificationView { - border-left: 5px solid #28a745; - min-height: 200px; - overflow-y: auto; - overflow-x: hidden; - padding: 5px; - max-height: 400px; -} - -.selected { - border-color: #28a745; - outline: none; - box-shadow: 0 0 0 3px #28a745; - color: #ddd; -} - -.selectedClassificationText { - color: #28a745; -} - -.back-button { - margin-bottom: 20px; -} - -.back-button:disabled { - cursor: not-allowed; - background-color: #ccc; -} - -.classification-cell { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 100%; -} - -.classification { - height: 100%; -} #column-selector { display: flex; @@ -501,69 +282,8 @@ i { margin-left: -5px; } -.message { - position: relative; - padding: 10px; - border-radius: 5px; - margin: 10px 0; - display: flex; - align-items: center; - justify-content: flex-start; -} -.message span { - width: 80%; -} -.message .icon { - margin-right: 10px; -} -.message .close-button { - width: 24px; - height: 24px; - display: flex; - align-items: center; - transition: background-color 0.3s, color 0.3s; - padding-left: 5px; -} -.message .close-button:hover { - background-color: #ffcccc; -} -.error { - color: red; - border: 1px solid red; - background-color: #ffe6e6; -} - -.error .close-button { - color: red; -} - -.error .close-button:hover { - color: darkred; -} - -.success { - color: green; - border: 1px solid green; - background-color: #e6ffe6; -} - -.success .close-button { - color: green; -} - -.success .close-button:hover { - background-color: #ccffcc; - color: darkgreen; -} - -.card { - margin: 10px; -} -.card-body { - height: 10vh; -} \ No newline at end of file diff --git a/src/bonsai/bonsai/bim/data/webui/static/js/utilities/costui.js b/src/bonsai/bonsai/bim/data/webui/static/js/utilities/costui.js index 9cabf9e3d9..7c9f5ed1a1 100644 --- a/src/bonsai/bonsai/bim/data/webui/static/js/utilities/costui.js +++ b/src/bonsai/bonsai/bim/data/webui/static/js/utilities/costui.js @@ -420,13 +420,15 @@ export class CostUI { } static isCostScheduleLoaded(id) { - const existingTable = document.getElementById("cost-items-" + id); + const existingTable = document.getElementById( + "cost-schedule-container-" + id + ); return existingTable !== null; } static removeCostSchedule(id) { - const table = document.getElementById("cost-items-" + id); - table ? table.parentElement.remove() : null; + const container = document.getElementById("cost-schedule-container-" + id); + container.remove(); } static createCostTree({ @@ -531,25 +533,35 @@ export class CostUI { tableWrapper = table.parentElement; table.remove(); } else { - tableWrapper = document.createElement("div"); - tableWrapper.classList.add("table-wrapper"); - document.getElementById("cost-items").appendChild(tableWrapper); - const tableHeader = document.createElement("div"); - tableHeader.classList.add("form-header"); - const text = CostUI.Text( + const scheduleDiv = document.createElement("div"); + scheduleDiv.classList.add("schedule"); + scheduleDiv.id = "cost-schedule-container-" + id; + + const scheduleHeader = document.createElement("div"); + scheduleHeader.classList.add("form-header"); + + const scheduleName = CostUI.Text( costSchedule.Name, "fa-solid fa-money-bill-wave", "x-large" ); + tableWrapper = document.createElement("div"); + tableWrapper.classList.add("table-wrapper"); + const callback = () => { - tableWrapper.remove(); + scheduleDiv.remove(); }; let closeButton = CostUI.createCloseButton(callback); - tableHeader.appendChild(text); - tableHeader.appendChild(closeButton); - tableWrapper.appendChild(tableHeader); + + scheduleHeader.appendChild(scheduleName); + scheduleHeader.appendChild(closeButton); + + scheduleDiv.appendChild(scheduleHeader); + scheduleDiv.appendChild(tableWrapper); + document.getElementById("cost-items").appendChild(scheduleDiv); } + const table = document.createElement("table"); table.id = "cost-items-" + id; const tbody = document.createElement("tbody"); @@ -573,9 +585,9 @@ export class CostUI { (header) => header.name !== "Linked Rate" ); columnHeaders = columnHeaders.map((header) => { - if (header.name === "Unit") { + if (header.name === "Cost") { return { name: "Rate (" + currency + ")", visible: preferences.Cost }; - } else if (header.name === "Cost (" + currency + ")") { + } else if (header.name === "Total Cost (" + currency + ")") { return { name: "Total Rate (" + currency + ")", visible: preferences.TotalCost, @@ -2735,14 +2747,14 @@ export class CostUI { addButton.addEventListener("click", function (e) { e.preventDefault(); - let type = CostUI.getQuantityTypeAttribute(quantityType); + let type = CostUI.getQuantityTypeAttribute(costItemId, quantityType); callbacks.addQuantity(costItemId, type); }); return addButton; } - static getQuantityTypeAttribute(quantityType) { + static getQuantityTypeAttribute(costItemId, quantityType) { let type = quantityType; if (!type) { const qtoSection = document.getElementById( diff --git a/src/bonsai/bonsai/bim/data/webui/templates/costing.html b/src/bonsai/bonsai/bim/data/webui/templates/costing.html index 3e607757af..0351bd978c 100644 --- a/src/bonsai/bonsai/bim/data/webui/templates/costing.html +++ b/src/bonsai/bonsai/bim/data/webui/templates/costing.html @@ -94,7 +94,7 @@
-
+