loading multiple cost schedules in the web ui is now more responsive, clean up and organise css code #5369

This commit is contained in:
myoualid
2024-09-24 12:13:18 +01:00
parent 0c70d4c828
commit 7692b910f4
8 changed files with 346 additions and 324 deletions
@@ -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;
@@ -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;
}
@@ -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%;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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(
@@ -94,7 +94,7 @@
</div>
</div>
<div id="cost-schedules" class="row-container"></div>
<div id="cost-items" class="table-container"></div>
<div id="cost-items" class="cost-tables"></div>
<footer>
<p>BlenderBIM Version: {{version}}</p>
</footer>