mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
cost module web ui improvements:
-add ribbon bar, - improve settings menu with ability to change font size for tables. - Improve cost schedule spreadsheet layout
This commit is contained in:
@@ -25,18 +25,18 @@
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
:root.blender .card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
:root.blender .card-title {
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
:root.blender .card-text {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
:root.blender .btn-primary {
|
||||
|
||||
@@ -1,36 +1,72 @@
|
||||
table {
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
border-collapse: collapse;
|
||||
user-select: none;
|
||||
:root {
|
||||
--fontSize: 14px;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
max-height: 70vh;
|
||||
margin-top: 1em;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form table {
|
||||
height: 50%;
|
||||
#cost-items {
|
||||
height: calc(100vh - var(--margin-small));
|
||||
}
|
||||
|
||||
form .table-container {
|
||||
max-height: 50vh;
|
||||
|
||||
.table-scrollable-body {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
user-select: none;
|
||||
table-layout: fixed;
|
||||
font-size: var(--fontSize);
|
||||
}
|
||||
|
||||
thead {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background-color: #727272;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
tbody {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-left: 1px solid #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
text-align: center;
|
||||
border-bottom: 0;
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
td {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
box-sizing: border-box; /* Include padding and border in the element's total width and height */
|
||||
}
|
||||
|
||||
/* first td of a row, must be flex */
|
||||
td:first-child {
|
||||
display: flex;
|
||||
@@ -65,7 +101,7 @@ select {
|
||||
height: inherit;
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
|
||||
font-size: var(--fontSize);
|
||||
min-width: 50px; /* Minimum width to prevent it from becoming too small */
|
||||
}
|
||||
|
||||
@@ -101,6 +137,7 @@ input:focus {
|
||||
background-color: #444444;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Responsive Styles */
|
||||
@media (max-width: 768px) {
|
||||
table {
|
||||
@@ -132,4 +169,4 @@ input:focus {
|
||||
padding: 1px;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
.ribbon-bar {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
|
||||
.ribbon-bar .action-button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
background-color: #444;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
border-left: 1px solid #666;
|
||||
}
|
||||
|
||||
.ribbon-bar .action-button:hover {
|
||||
background-color: #666;
|
||||
}
|
||||
|
||||
.ribbon-bar .action-button::after {
|
||||
content: attr(data-tooltip);
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
white-space: nowrap;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ribbon-bar .action-button:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
@import url("./components/card.css");
|
||||
@import url("./components/contextMenu.css");
|
||||
@import url("./components/costTable.css");
|
||||
@import url("./components/headerBar.css");
|
||||
|
||||
.form-header {
|
||||
display: flex;
|
||||
@@ -19,8 +20,8 @@ span {
|
||||
}
|
||||
|
||||
.floating-form {
|
||||
min-width: 40%;
|
||||
max-width: 80%;
|
||||
height: 40vh;
|
||||
width: 50vw;
|
||||
max-height: 80vh;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
|
||||
@@ -219,7 +219,6 @@ button:hover {
|
||||
}
|
||||
|
||||
.row-container {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
@@ -11,21 +11,22 @@ $(document).ready(function () {
|
||||
setTheme(theme);
|
||||
|
||||
connectSocket();
|
||||
|
||||
const settingsMenu = CostUI.Form({
|
||||
id: "settings-menu",
|
||||
name: "Settings",
|
||||
icon: "fa-solid fa-gear",
|
||||
shouldHide: true,
|
||||
CostUI.addSettingsMenu();
|
||||
CostUI.addRibbonButton({
|
||||
text: "Hide Schedules",
|
||||
icon: "fa-regular fa-eye-slash",
|
||||
callback: (button) => {
|
||||
CostUI.toggleSchedulesContainer(button);
|
||||
}
|
||||
});
|
||||
settingsMenu.style.display = "none";
|
||||
const picker = CostUI.createColorPicker();
|
||||
settingsMenu.appendChild(picker);
|
||||
|
||||
const settingsButton = document.getElementById("settings-button");
|
||||
settingsButton.addEventListener("click", function () {
|
||||
settingsMenu.style.display = "block";
|
||||
CostUI.addRibbonButton({
|
||||
text: "Settings",
|
||||
icon: "fas fa-cog",
|
||||
callback: (button) => {
|
||||
CostUI.toggleSettingsMenu(button);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function connectSocket() {
|
||||
@@ -85,6 +86,7 @@ function handleSelectedProducts(data) {
|
||||
}
|
||||
|
||||
function handlePredefinedTypes(data) {
|
||||
|
||||
CostUI.enableAddingCostSchedule(
|
||||
data.data["predefined_types"],
|
||||
addCostSchedule
|
||||
@@ -233,6 +235,65 @@ function setTheme(theme) {
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
|
||||
function toggleClientList() {
|
||||
var clientList = $("#client-list");
|
||||
|
||||
if (clientList.hasClass("show")) {
|
||||
clientList.removeClass("show");
|
||||
return;
|
||||
}
|
||||
|
||||
clientList.empty();
|
||||
var counter = 0;
|
||||
|
||||
$.each(connectedClients, function (id, client) {
|
||||
counter++;
|
||||
|
||||
const dropdownIcon = $("<i>")
|
||||
.addClass("fas fa-chevron-down")
|
||||
.css("margin-left", "0.5rem");
|
||||
|
||||
const clientDiv = $("<div>")
|
||||
.addClass("client")
|
||||
.text(client.ifc_file || "Blender " + counter);
|
||||
|
||||
clientDiv.append(dropdownIcon);
|
||||
|
||||
const clientDetailsDiv = $("<div>").addClass("client-details");
|
||||
|
||||
if (id) {
|
||||
const clientId = $("<div>")
|
||||
.addClass("client-detail")
|
||||
.text(`Blender ID: ${id}`);
|
||||
clientDetailsDiv.append(clientId);
|
||||
}
|
||||
|
||||
if (!client.has_drawings) {
|
||||
const clientShown = $("<div>")
|
||||
.addClass("client-detail")
|
||||
.text("No drawings exist for this IFC File yet");
|
||||
clientDetailsDiv.append(clientShown);
|
||||
} else {
|
||||
const clientNumbers = $("<div>")
|
||||
.addClass("client-detail")
|
||||
.text(
|
||||
`${allDrawings[client.ifc_file].drawings.length} Drawing(s),
|
||||
${allDrawings[client.ifc_file].sheets.length} Sheet(s)`
|
||||
);
|
||||
clientDetailsDiv.append(clientNumbers);
|
||||
}
|
||||
|
||||
clientDiv.append(clientDetailsDiv);
|
||||
|
||||
clientDiv.on("click", function () {
|
||||
clientDetailsDiv.toggleClass("show");
|
||||
});
|
||||
|
||||
clientList.append(clientDiv);
|
||||
});
|
||||
clientList.addClass("show");
|
||||
}
|
||||
|
||||
function addCostItem(costItemId) {
|
||||
executeOperator({ type: "addCostItem", costItemId: costItemId });
|
||||
}
|
||||
@@ -304,6 +365,7 @@ function handleCostSchedulesData(data) {
|
||||
}
|
||||
|
||||
function handleCostItemsData(data) {
|
||||
console.log(data);
|
||||
const cards = document.querySelectorAll("[id^='schedule-']");
|
||||
cards.forEach((card) => {
|
||||
if (card.id === "schedule-" + data.data["cost_items"]["cost_schedule_id"]) {
|
||||
|
||||
@@ -126,7 +126,10 @@ function handleWorkScheduleData(data) {
|
||||
const workSchedules = data["data"]["work_schedule_info"];
|
||||
|
||||
workSchedules.forEach((workSchedule) => {
|
||||
const mainContainer = CostUI.text(new Date(workSchedule.CreationDate).toLocaleDateString());
|
||||
const mainContainer = CostUI.Text(
|
||||
"Created On: " + new Date(workSchedule.CreationDate).toLocaleDateString(),
|
||||
"fa-solid fa-pen-nib"
|
||||
);
|
||||
const callback = () => loadWorkSchedule(workSchedule.id);
|
||||
const card = CostUI.createCard(workSchedule.id, workSchedule.Name,mainContainer, callback);
|
||||
workSchedulesDiv.append(card);
|
||||
|
||||
@@ -25,7 +25,10 @@ export class CostUI {
|
||||
"Total Cost",
|
||||
"Action",
|
||||
];
|
||||
const thead = document.createElement("thead");
|
||||
const tr = document.createElement("tr");
|
||||
thead.appendChild(tr);
|
||||
|
||||
|
||||
for (let i = 0; i < columnHeaders.length; i++) {
|
||||
const th = document.createElement("th");
|
||||
@@ -41,7 +44,7 @@ export class CostUI {
|
||||
}
|
||||
}
|
||||
|
||||
tbody.appendChild(tr);
|
||||
table.appendChild(thead);
|
||||
table.appendChild(tbody);
|
||||
document.getElementById("cost-items").appendChild(table);
|
||||
|
||||
@@ -69,7 +72,8 @@ export class CostUI {
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
static createContextMenu(callbacks) {
|
||||
|
||||
static createContextMenu(callbacks) {
|
||||
const contextMenu = document.createElement("div");
|
||||
contextMenu.id = "context-menu";
|
||||
contextMenu.classList.add("context-menu");
|
||||
@@ -144,7 +148,7 @@ export class CostUI {
|
||||
const costItemId = parseInt(targetRow.getAttribute("id"));
|
||||
let expandedState =
|
||||
JSON.parse(localStorage.getItem("expandedState")) || {};
|
||||
expandedState = CostUI.deleteRow(targetRow, expandedState);
|
||||
expandedState = CostUI.deleteCostItemRow(targetRow, expandedState);
|
||||
localStorage.setItem("expandedState", JSON.stringify(expandedState));
|
||||
callbacks.deleteCostItem(costItemId);
|
||||
}
|
||||
@@ -178,9 +182,51 @@ export class CostUI {
|
||||
});
|
||||
getSelectedProducts.hasListener = true;
|
||||
}
|
||||
|
||||
// Function to get column names from the table header
|
||||
function getColumnNames(tableId) {
|
||||
const table = document.getElementById(tableId);
|
||||
const headerRow = table.querySelector("thead tr");
|
||||
return Array.from(headerRow.children).map(headerCell => headerCell.textContent.trim());
|
||||
}
|
||||
|
||||
// Add double-click event listener
|
||||
document.getElementById("cost-items").addEventListener("dblclick", function (event) {
|
||||
const targetRow = event.target.closest("tr");
|
||||
const targetCell = event.target.closest("td");
|
||||
if (targetRow && targetCell) {
|
||||
const columnIndex = Array.from(targetRow.children).indexOf(targetCell);
|
||||
const costItemId = parseInt(targetRow.getAttribute("id"));
|
||||
const cellContent = targetCell.textContent;
|
||||
|
||||
// Get column names from the table header
|
||||
const columnNames = getColumnNames("cost-items");
|
||||
const cellName = columnNames[columnIndex];
|
||||
|
||||
console.log("Column Name: ", cellName);
|
||||
console.log("Content: ", cellContent);
|
||||
|
||||
// Implement different behaviors based on the column index
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
// Behavior for the first column
|
||||
callbacks.firstColumnDoubleClick ? callbacks.firstColumnDoubleClick(costItemId) : null;
|
||||
break;
|
||||
case 1:
|
||||
// Behavior for the second column
|
||||
callbacks.secondColumnDoubleClick ? callbacks.secondColumnDoubleClick(costItemId) : null;
|
||||
break;
|
||||
// Add more cases as needed for other columns
|
||||
default:
|
||||
// Default behavior
|
||||
callbacks.defaultDoubleClick ? callbacks.defaultDoubleClick(costItemId) : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static deleteRow(targetRow, expandedState) {
|
||||
static deleteCostItemRow(targetRow, expandedState) {
|
||||
if (!targetRow) {
|
||||
return;
|
||||
}
|
||||
@@ -188,7 +234,7 @@ export class CostUI {
|
||||
targetRow.remove();
|
||||
const subRows = document.querySelectorAll(`[parent-id='${targetRow.id}']`);
|
||||
subRows.forEach((subRow) => {
|
||||
CostUI.deleteRow(subRow, expandedState);
|
||||
CostUI.deleteCostItemRow(subRow, expandedState);
|
||||
});
|
||||
return expandedState;
|
||||
}
|
||||
@@ -258,6 +304,7 @@ export class CostUI {
|
||||
const form = CostUI.Form({
|
||||
id: "add-cost-schedule-form",
|
||||
name: name,
|
||||
icon: "fa-solid fa-money-bill-wave",
|
||||
});
|
||||
|
||||
const nameLabel = document.createElement("label");
|
||||
@@ -672,9 +719,8 @@ export class CostUI {
|
||||
const cardBody = document.createElement("div");
|
||||
cardBody.classList.add("card-body");
|
||||
|
||||
const cardTitle = document.createElement("h5");
|
||||
const cardTitle = CostUI.Text(title, "fa-solid fa-money-bill-wave", "large");
|
||||
cardTitle.classList.add("card-title");
|
||||
cardTitle.textContent = title;
|
||||
|
||||
const cardButton = document.createElement("button");
|
||||
cardButton.classList.add("action-button");
|
||||
@@ -1163,10 +1209,10 @@ export class CostUI {
|
||||
const subtotalRow = document.createElement("tr");
|
||||
|
||||
const cells = [
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: "Subtotal", colSpan: 4, style: { border: "none" } },
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: "", style: { border: "none" } },
|
||||
{ textContent: quantitySums.count },
|
||||
];
|
||||
|
||||
@@ -1202,15 +1248,25 @@ export class CostUI {
|
||||
costItemId,
|
||||
callbacks,
|
||||
}) {
|
||||
if (products.length === 0) {
|
||||
const noProductsMessage = document.createElement("p");
|
||||
noProductsMessage.textContent = "Your Blender Selection is empty! Select objects first.";
|
||||
form.appendChild(noProductsMessage);
|
||||
return;
|
||||
}
|
||||
const { tableContainer, table } = CostUI.addTable({
|
||||
headers: ["Step Id", "Class", "Name", "Type", "Count"],
|
||||
className: "product-table",
|
||||
id: "cost-values-table-" + costItemId,
|
||||
});
|
||||
form.appendChild(tableContainer);
|
||||
|
||||
const scrollableBody = document.createElement("div");
|
||||
scrollableBody.classList.add("table-scrollable-body");
|
||||
|
||||
const tbody = document.createElement("tbody");
|
||||
table.appendChild(tbody);
|
||||
form.appendChild(tableContainer);
|
||||
scrollableBody.appendChild(tbody);
|
||||
table.appendChild(scrollableBody);
|
||||
|
||||
const quantityAssigned = CostUI.getAssinedQuantity(products, costItemId);
|
||||
const areProductsSameClass = products.every(
|
||||
@@ -1343,9 +1399,12 @@ export class CostUI {
|
||||
id: "cost-values-table-" + costItemId,
|
||||
});
|
||||
|
||||
const tbody = document.createElement("tbody");
|
||||
table.appendChild(tbody);
|
||||
form.appendChild(tableContainer);
|
||||
const scrollableBody = document.createElement("div");
|
||||
scrollableBody.classList.add("table-scrollable-body");
|
||||
const tbody = document.createElement("tbody");
|
||||
scrollableBody.appendChild(tbody);
|
||||
table.appendChild(scrollableBody);
|
||||
|
||||
let quantityAssigned = CostUI.getAssinedQuantity(products, costItemId);
|
||||
const shouldAddQto = quantityAssigned ? true : false;
|
||||
@@ -1417,4 +1476,174 @@ export class CostUI {
|
||||
addProductAssignmentsButton.classList.add("action-button");
|
||||
return addProductAssignmentsButton;
|
||||
}
|
||||
|
||||
static addSettingsMenu() {
|
||||
if (document.getElementById("settings-menu")) {
|
||||
return document.getElementById("settings-menu");
|
||||
}
|
||||
const settingsMenu = CostUI.Form({
|
||||
id: "settings-menu",
|
||||
name: "Settings",
|
||||
icon: "fa-solid fa-gear",
|
||||
shouldHide: true,
|
||||
});
|
||||
|
||||
const picker = CostUI.createColorPicker();
|
||||
const tableFontSize = CostUI.createFontSizePicker();
|
||||
settingsMenu.appendChild(picker);
|
||||
settingsMenu.appendChild(tableFontSize);
|
||||
|
||||
settingsMenu.style.display = "none";
|
||||
const settingsButton = document.getElementById("settings-button");
|
||||
settingsButton.addEventListener("click", function () {
|
||||
settingsMenu.style.display = "block";
|
||||
});
|
||||
|
||||
// Apply saved settings on page load
|
||||
CostUI.applySavedSettings();
|
||||
}
|
||||
|
||||
static createFontSizePicker() {
|
||||
const div = document.createElement("div");
|
||||
const fontSizeText = document.createElement("p");
|
||||
fontSizeText.textContent = "Select a font size for the table:";
|
||||
div.appendChild(fontSizeText);
|
||||
const fontSizePicker = document.createElement("input");
|
||||
fontSizePicker.type = "number";
|
||||
fontSizePicker.id = "font-size-picker";
|
||||
fontSizePicker.value = localStorage.getItem("tableFontSize") || 14;
|
||||
div.appendChild(fontSizePicker);
|
||||
fontSizePicker.addEventListener("input", function () {
|
||||
const fontSize = fontSizePicker.value + "px";
|
||||
CostUI.saveFontSize(fontSize);
|
||||
CostUI.applyFontSizeToAllTables(fontSize);
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
static createColorPicker() {
|
||||
const div = document.createElement("div");
|
||||
const colorText = document.createElement("p");
|
||||
colorText.textContent = "Select a color for the table:";
|
||||
div.appendChild(colorText);
|
||||
const colorPicker = document.createElement("input");
|
||||
colorPicker.type = "color";
|
||||
colorPicker.id = "color-picker";
|
||||
colorPicker.value = localStorage.getItem("tableColor") || "#ffffff";
|
||||
div.appendChild(colorPicker);
|
||||
colorPicker.addEventListener("input", function () {
|
||||
const color = colorPicker.value;
|
||||
CostUI.saveColor(color);
|
||||
CostUI.applyColorToAllTables(color);
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
static saveFontSize(fontSize) {
|
||||
localStorage.setItem("tableFontSize", fontSize);
|
||||
}
|
||||
|
||||
static saveColor(color) {
|
||||
localStorage.setItem("tableColor", color);
|
||||
}
|
||||
|
||||
static applyFontSizeToAllTables(fontSize) {
|
||||
document.documentElement.style.setProperty('--fontSize', fontSize);
|
||||
}
|
||||
|
||||
static applyColorToAllTables(color) {
|
||||
const tables = document.querySelectorAll("table");
|
||||
tables.forEach((table) => {
|
||||
table.style.backgroundColor = color;
|
||||
});
|
||||
}
|
||||
|
||||
static applySavedSettings() {
|
||||
console.log("Applying saved settings");
|
||||
const savedFontSize = localStorage.getItem("tableFontSize");
|
||||
if (savedFontSize) {
|
||||
CostUI.applyFontSizeToAllTables(savedFontSize);
|
||||
const fontSizePicker = document.getElementById("font-size-picker");
|
||||
if (fontSizePicker) {
|
||||
fontSizePicker.value = parseInt(savedFontSize, 10);
|
||||
}
|
||||
}
|
||||
|
||||
const savedColor = localStorage.getItem("tableColor");
|
||||
if (savedColor) {
|
||||
CostUI.applyColorToAllTables(savedColor);
|
||||
const colorPicker = document.getElementById("color-picker");
|
||||
if (colorPicker) {
|
||||
colorPicker.value = savedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getRibbonBar() {
|
||||
return document.getElementById("ribbon-bar");
|
||||
}
|
||||
|
||||
static addRibbonButton({ text, icon, callback }) {
|
||||
const ribbonBar = CostUI.getRibbonBar();
|
||||
|
||||
const button = document.createElement("button");
|
||||
button.classList.add("action-button", ...icon.split(" "));
|
||||
button.dataset.tooltip = text; // Use dataset to set the tooltip attribute
|
||||
|
||||
button.addEventListener("click", () => callback(button));
|
||||
|
||||
ribbonBar.appendChild(button);
|
||||
}
|
||||
|
||||
static toggleSchedulesContainer(button) {
|
||||
const schedulesContainer = CostUI.getSchedulesContainer();
|
||||
const isHidden = schedulesContainer.style.display === "none";
|
||||
|
||||
if (isHidden) {
|
||||
CostUI.displaySchedulesContainer();
|
||||
button.classList.remove("fa-eye");
|
||||
button.classList.add("fa-eye-slash");
|
||||
button.dataset.tooltip = "Hide Schedules";
|
||||
} else {
|
||||
CostUI.hideSchedulesContainer();
|
||||
button.classList.remove("fa-eye-slash");
|
||||
button.classList.add("fa-eye");
|
||||
button.dataset.tooltip = "Display Schedules";
|
||||
}
|
||||
}
|
||||
|
||||
static getSchedulesContainer() {
|
||||
return document.getElementById("cost-schedules");
|
||||
}
|
||||
|
||||
static displaySchedulesContainer() {
|
||||
const schedulesContainer = CostUI.getSchedulesContainer();
|
||||
schedulesContainer.style.display = "flex";
|
||||
}
|
||||
|
||||
static hideSchedulesContainer() {
|
||||
const schedulesContainer = CostUI.getSchedulesContainer();
|
||||
schedulesContainer.style.display = "none";
|
||||
}
|
||||
|
||||
static getSettingsMenu() {
|
||||
return document.getElementById("settings-menu");
|
||||
}
|
||||
|
||||
static toggleSettingsMenu(button) {
|
||||
const settingsMenu = CostUI.getSettingsMenu();
|
||||
const isHidden = settingsMenu.style.display === "none";
|
||||
|
||||
if (isHidden) {
|
||||
settingsMenu.style.display = "block";
|
||||
button.classList.remove("fa-gear");
|
||||
button.classList.add("fa-times");
|
||||
button.dataset.tooltip = "Close Settings";
|
||||
} else {
|
||||
settingsMenu.style.display = "none";
|
||||
button.classList.remove("fa-times");
|
||||
button.classList.add("fa-gear");
|
||||
button.dataset.tooltip = "Open Settings";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>BlenderBIM Web UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/cost.css" id="index-stylesheet" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="/static/css/cost.css"
|
||||
id="index-stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="tabulator-stylesheet"
|
||||
@@ -30,9 +35,6 @@
|
||||
var SOCKET_PORT = {{port}};
|
||||
</script>
|
||||
<script type="module" defer src="./static/js/cost.js"></script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
@@ -43,12 +45,10 @@
|
||||
/>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/"
|
||||
><i class="fa-solid fa-table"></i> Schedules</a
|
||||
>
|
||||
<a href="/"><i class="fa-solid fa-table"></i> Schedules</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/costing" class="active"
|
||||
<a href="/costing" class="active"
|
||||
><i class="fa-solid fa-money-bill-trend-up"></i> Costing</a
|
||||
>
|
||||
</li>
|
||||
@@ -78,25 +78,26 @@
|
||||
<button id="settings-button">
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</button>
|
||||
<div id="connected-list-div">
|
||||
<button id="show-connected-button" onclick="toggleClientList()">
|
||||
Connected Blenders:
|
||||
<span id="blender-count">0</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div id="client-list"></div>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="connected-list-div">
|
||||
<button id="show-connected-button" onclick="toggleClientList()">
|
||||
Connected Blenders:
|
||||
<span id="blender-count">0</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div id="client-list"></div>
|
||||
<div class="row-container">
|
||||
<div id="ribbon-bar" class="ribbon-bar">
|
||||
<button
|
||||
id="add-cost-schedule"
|
||||
class="action-button fas fa-plus"
|
||||
data-tooltip="Add New Schedule"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Costing</h1>
|
||||
<div id="" >
|
||||
<li id="add-cost-schedule" class="action-button fas fa-plus"> </li>
|
||||
Add New Schedule
|
||||
</div>
|
||||
|
||||
<div id="cost-schedules" class="row-container"></div>
|
||||
|
||||
<div id="cost-items" class="table-container"></div>
|
||||
|
||||
<footer>
|
||||
<p>BlenderBIM Version: {{version}}</p>
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user