First Working version. I can add table

This commit is contained in:
2025-05-10 16:55:52 +02:00
parent b708ef2c46
commit 2daff83e67
157 changed files with 17282 additions and 12 deletions

View File

@@ -0,0 +1,28 @@
.drawer-layout {
display: flex;
margin: 0;
}
.sidebar {
width: 200px;
min-width : 200px;
transition: width 0.4s ease;
}
.sidebar.collapsed {
overflow: hidden;
width: 0;
min-width : 0;
padding: 0;
}
.main {
flex-grow: 1;
padding: 20px;
}
.toggle-button {
margin-bottom: 20px;
cursor: pointer;
padding: 10px 15px;
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
}

View File

@@ -0,0 +1,98 @@
// ===============================================================
// SEND INPUT BEFORE AJAX
// ===============================================================
// Select all elements with id starting with 'navItem-' within the #sidebar div
var navItems = document.querySelectorAll('[name="sidebar"] [id^="navItem-"]');
navItems.forEach(function (navItem) {
navItem.addEventListener("htmx:confirm", function (event) {
event.preventDefault();
// Get the page id
var layout_id = navItem.getAttribute("hx-target");
var pageDiv = document.querySelector(layout_id);
var current_page = pageDiv.querySelector('[name="current_page"]');
var current_page_id = current_page.id;
if (pageDiv) {
var elementsWithId = current_page.querySelectorAll("[id]");
var elementsInfo = [];
elementsWithId.forEach(function (element) {
// Skip elements with id starting with 'datagrid-'
if (element.id.startsWith("datagrid-")) {
return;
}
let value = "";
let method = "";
switch (element.tagName) {
case "INPUT":
if (element.type === "checkbox") {
value = element.checked; // For checkboxes
method = "checked";
} else if (element.type === "radio") {
value = element.checked;
method = "checked";
} else if (element.type === "file") {
value = element.files.length > 0 ? Array.from(element.files).map((file) => file.name) : []; // Array of file names
method = "files";
} else {
value = element.value; // For other input types
method = "value";
}
break;
case "TEXTAREA":
value = element.value; // For textareas
method = "value";
break;
case "SELECT":
value = element.multiple
? Array.from(element.selectedOptions).map((option) => option.value) // Multiple selections
: element.value; // Single selection
method = "value";
break;
default:
if (element.isContentEditable) {
value = element.innerText.trim(); // For contenteditable elements
method = "innerText";
} else {
value = element.textContent; // For other elements
method = "textContent";
}
break;
}
elementsInfo.push({
id: element.id,
type: element.tagName.toLowerCase(), // Element type in lowercase
value: value,
method: method,
});
});
var result = {
dl_id: layout_id.replace("#page_", ""),
page_id: current_page_id,
state: elementsInfo,
};
// Post the elementInfo to the specified URL
fetch("/pages/store_state", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(result),
})
.then((response) => {
event.detail.issueRequest(true);
})
.catch((error) => {
console.error("Error:", error); // Handle errors if any occur
event.detail.issueRequest(true);
});
}
});
});

0
src/assets/__init__.py Normal file
View File

62
src/assets/css.py Normal file
View File

@@ -0,0 +1,62 @@
from fasthtml.components import Style
my_managing_tools_style = Style("""
.icon-32 {
width: 32px;
height: 32px;
}
.icon-32 svg {
width: 100%;
height: 100%;
}
.icon-24 {
width: 24px;
min-width: 24px;
height: 24px;
}
.icon-24 svg {
width: 100%;
height: 100%;
}
.icon-20 {
width: 20px;
min-width: 20px;
height: 20px;
margin-top: auto;
margin-bottom: auto;
}
.icon-16 {
width: 16px;
min-width: 16px;
height: 16px;
margin-top: auto;
margin-bottom: 4px;
}
.icon-bool {
display: block;
width: 20px;
height: 20px;
margin: auto;
}
.icon-btn {
cursor: pointer;
}
.cursor-pointer {
cursor: pointer;
}
.cursor-default {
cursor: default;
}
""")

20
src/assets/daisyui-4.12.10-full-min.css vendored Normal file

File diff suppressed because one or more lines are too long

6
src/assets/fragments.py Normal file
View File

@@ -0,0 +1,6 @@
# <input type="text" name="q"
# hx-get="/trigger_delay"
# hx-trigger="keyup changed delay:500ms"
# hx-target="#search-results"
# placeholder="Search..."
# >

12
src/assets/icons.py Normal file
View File

@@ -0,0 +1,12 @@
# fluent DismissCircle24Regular
from fastcore.basics import NotStr
# DismissCircle20Regular
icon_dismiss_regular = NotStr(
"""<svg name="close" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M10 2a8 8 0 1 1 0 16a8 8 0 0 1 0-16zm0 1a7 7 0 1 0 0 14a7 7 0 0 0 0-14zM7.81 7.114l.069.058L10 9.292l2.121-2.12a.5.5 0 0 1 .638-.058l.07.058a.5.5 0 0 1 .057.637l-.058.07L10.708 10l2.12 2.121a.5.5 0 0 1 .058.638l-.058.07a.5.5 0 0 1-.637.057l-.07-.058L10 10.708l-2.121 2.12a.5.5 0 0 1-.638.058l-.07-.058a.5.5 0 0 1-.057-.637l.058-.07L9.292 10l-2.12-2.121a.5.5 0 0 1-.058-.638l.058-.07a.5.5 0 0 1 .637-.057z" fill="currentColor">
</path>
</g>
</svg>"""
)

25
src/assets/main.css Normal file
View File

@@ -0,0 +1,25 @@
:root {
--theme-controller-zindex: 1000;
--datagrid-sidebar-zindex: 900;
--datagrid-scrollbars-zindex: 800;
}
.mmt-tooltip-container {
background: var(--color-base-200);
padding: 5px 10px;
border-radius: 4px;
pointer-events: none; /* Prevent interfering with mouse events */
font-size: 12px;
white-space: nowrap;
opacity: 0; /* Default to invisible */
visibility: hidden; /* Prevent interaction when invisible */
transition: opacity 0.3s ease, visibility 0s linear 0.3s; /* Delay visibility removal */
position: fixed; /* Keep it above other content and adjust position */
z-index: 10; /* Ensure it's on top */
}
.mmt-tooltip-container[data-visible="true"] {
opacity: 1;
visibility: visible; /* Show tooltip */
transition: opacity 0.3s ease; /* No delay when becoming visible */
}

51
src/assets/main.js Normal file
View File

@@ -0,0 +1,51 @@
function bindTooltipsWithDelegation(elementId) {
console.debug("bindTooltips on element " + elementId);
const element = document.getElementById(elementId);
const tooltipContainer = document.getElementById(`tt_${elementId}`);
if (!element || !tooltipContainer) {
console.error("Invalid element or tooltip container");
return;
}
// Add a single mouseenter and mouseleave listener to the parent element
element.addEventListener("mouseenter", (event) => {
const cell = event.target.closest("div[data-tooltip]");
if (!cell) return;
const content = cell.querySelector(".truncate") || cell;
const isOverflowing = content.scrollWidth > content.clientWidth;
const forceShow = cell.classList.contains("mmt-tooltip");
if (isOverflowing || forceShow) {
const tooltipText = cell.getAttribute("data-tooltip");
if (tooltipText) {
const rect = cell.getBoundingClientRect();
const tooltipRect = tooltipContainer.getBoundingClientRect();
let top = rect.top - 30; // Above the cell
let left = rect.left;
// Adjust tooltip position to prevent it from going off-screen
if (top < 0) top = rect.bottom + 5; // Move below if no space above
if (left + tooltipRect.width > window.innerWidth) {
left = window.innerWidth - tooltipRect.width - 5; // Prevent overflow right
}
// Apply styles for tooltip positioning
tooltipContainer.textContent = tooltipText;
tooltipContainer.setAttribute("data-visible", "true");
tooltipContainer.style.top = `${top}px`;
tooltipContainer.style.left = `${left}px`;
}
}
}, true); // Use capture phase for better delegation if needed
element.addEventListener("mouseleave", (event) => {
const cell = event.target.closest("div[data-tooltip]");
if (cell) {
tooltipContainer.setAttribute("data-visible", "false");
}
}, true); // Use capture phase for better delegation if needed
}

View File

@@ -0,0 +1,16 @@
// THis does not work as module is not defined !!!
module.exports = {
//...
daisyui: {
themes: [
{
light: {
...require("daisyui/src/theming/themes")["light"],
"primary": "blue",
"secondary": "teal",
"accent": "#37cdbe",
},
},
],
},
}

83
src/assets/tailwindcss.js Normal file

File diff suppressed because one or more lines are too long