From 44983236b4fc3022e36dcb5ca770fd4696940df0 Mon Sep 17 00:00:00 2001 From: rohit Date: Mon, 1 Sep 2025 02:04:27 +0530 Subject: [PATCH] v1.0.3-beta --- .../propertyTemplateSelector.css | 78 +++++ .../propertyTemplateSelector.js | 283 ++++++++++++------ 2 files changed, 276 insertions(+), 85 deletions(-) diff --git a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css index 1b6b574..141973d 100644 --- a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css +++ b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css @@ -8711,4 +8711,82 @@ ol li:before { transform: scale(1.1); } +/* Enhanced Draggable Table Styles */ +.draggable-table-container { + position: absolute; + border: 2px solid transparent; + cursor: move; + z-index: 1000; + min-width: 200px; + min-height: 150px; + user-select: none; + background: white; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: hidden; +} + +.draggable-table-container.selected { + border-color: #4f46e5; + box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2); +} + +.draggable-table-container table { + width: 100%; + height: 100%; + border-collapse: collapse; + margin: 0; + background: white; +} + +.draggable-table-container th, +.draggable-table-container td { + border: 1px solid #ddd; + padding: 8px; + text-align: left; +} + +.draggable-table-container th { + background: #f8f9fa; + font-weight: 600; +} + +.draggable-table-container td { + background: white; +} + +.draggable-table-container td:focus { + outline: 2px solid #4f46e5; + outline-offset: -2px; +} + +.table-controls-overlay { + position: absolute; + top: -40px; + left: 0; + background: white; + padding: 8px; + border-radius: 6px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + opacity: 0; + transition: opacity 0.2s ease; + display: flex; + gap: 4px; + z-index: 1002; +} + +.table-controls-overlay button { + padding: 4px 8px; + font-size: 12px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: all 0.2s ease; +} + +.table-controls-overlay button:hover { + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} + diff --git a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js index ab3fe0b..3c5b432 100644 --- a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js +++ b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js @@ -3114,141 +3114,254 @@ export default class PropertyTemplateSelector extends LightningElement { } } - // Create table element + // Create table element with enhanced drag and resize functionality createTableElement() { + // Create the main table container with absolute positioning for drag/resize + const tableContainer = document.createElement('div'); + tableContainer.className = 'draggable-table-container'; + tableContainer.style.cssText = ` + position: absolute; + left: 50px; + top: 50px; + width: 400px; + min-width: 200px; + min-height: 150px; + z-index: 1000; + border: 2px solid transparent; + cursor: move; + user-select: none; + background: white; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: hidden; + `; + + // Create the actual table const table = document.createElement('table'); - table.style.border = '1px solid #ccc'; - table.style.borderCollapse = 'collapse'; - table.style.margin = '10px 0'; - table.style.width = '100%'; - table.draggable = true; - table.style.position = 'relative'; - table.style.zIndex = '1000'; + table.style.cssText = ` + width: 100%; + height: 100%; + border-collapse: collapse; + margin: 0; + background: white; + `; // Create header row const headerRow = document.createElement('tr'); - for (let i = 0; i < 3; i++) { + for (let i = 0; i < this.tableCols; i++) { const th = document.createElement('th'); th.textContent = `Header ${i + 1}`; - th.style.border = '1px solid #ccc'; - th.style.padding = '8px'; - th.style.backgroundColor = '#f5f5f5'; + th.style.cssText = ` + border: 1px solid #ddd; + padding: 8px; + background: #f8f9fa; + font-weight: 600; + text-align: left; + `; headerRow.appendChild(th); } table.appendChild(headerRow); // Create data rows - for (let i = 0; i < 2; i++) { + const startRow = this.includeHeader ? 1 : 0; + for (let i = startRow; i < this.tableRows; i++) { const row = document.createElement('tr'); - for (let j = 0; j < 3; j++) { + for (let j = 0; j < this.tableCols; j++) { const td = document.createElement('td'); td.textContent = `Cell ${i + 1},${j + 1}`; - td.style.border = '1px solid #ccc'; - td.style.padding = '8px'; + td.style.cssText = ` + border: 1px solid #ddd; + padding: 8px; + background: white; + `; + // Make cells editable + td.contentEditable = true; + td.addEventListener('blur', () => { + // Save changes when cell loses focus + }); row.appendChild(td); } table.appendChild(row); } - // Add delete button (X mark) in top-right corner - const deleteBtn = document.createElement('button'); - deleteBtn.innerHTML = '×'; - deleteBtn.style.cssText = ` - position: absolute; - top: -10px; - right: -10px; - width: 20px; - height: 20px; - background: #dc3545; - color: white; - border: none; - border-radius: 50%; - cursor: pointer; - font-size: 14px; - font-weight: bold; - z-index: 1001; - display: flex; - align-items: center; - justify-content: center; - `; - deleteBtn.onclick = (e) => { - e.stopPropagation(); - table.parentElement.remove(); - }; - - // Add table controls - const controls = document.createElement('div'); - controls.style.cssText = ` - margin-top: 5px; - padding: 5px; - background: #f8f9fa; - border: 1px solid #dee2e6; - border-radius: 4px; - `; - controls.innerHTML = ` - - - - - `; - - const tableContainer = document.createElement('div'); - tableContainer.style.cssText = ` - position: relative; - display: inline-block; - margin: 10px 0; - `; tableContainer.appendChild(table); - tableContainer.appendChild(deleteBtn); - tableContainer.appendChild(controls); - // Make table draggable - tableContainer.draggable = true; - tableContainer.addEventListener('dragstart', this.handleTableDragStart.bind(this)); + // Add resize handles (same as images) + this.addResizeHandles(tableContainer); + + // Add delete handle (same as images) + this.addDeleteHandle(tableContainer); + + // Add drag functionality (same as images) + this.makeDraggable(tableContainer); + + // Add click to select functionality + tableContainer.addEventListener('click', (e) => { + e.stopPropagation(); + this.selectDraggableElement(tableContainer); + }); + + // Add table controls overlay + this.addTableControls(tableContainer, table); + + // Select the table after a short delay + setTimeout(() => { + this.selectDraggableElement(tableContainer); + }, 100); return tableContainer; } + + // Add table controls overlay + addTableControls(container, table) { + const controls = document.createElement('div'); + controls.className = 'table-controls-overlay'; + controls.style.cssText = ` + position: absolute; + top: -40px; + left: 0; + background: white; + padding: 8px; + border-radius: 6px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + opacity: 0; + transition: opacity 0.2s ease; + display: flex; + gap: 4px; + z-index: 1002; + `; + + // Add Row button + const addRowBtn = document.createElement('button'); + addRowBtn.innerHTML = '+ Row'; + addRowBtn.style.cssText = ` + padding: 4px 8px; + font-size: 12px; + background: #28a745; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + `; + addRowBtn.onclick = (e) => { + e.stopPropagation(); + this.addTableRow(table); + }; + + // Add Column button + const addColBtn = document.createElement('button'); + addColBtn.innerHTML = '+ Col'; + addColBtn.style.cssText = ` + padding: 4px 8px; + font-size: 12px; + background: #17a2b8; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + `; + addColBtn.onclick = (e) => { + e.stopPropagation(); + this.addTableColumn(table); + }; + + // Delete Row button + const delRowBtn = document.createElement('button'); + delRowBtn.innerHTML = '- Row'; + delRowBtn.style.cssText = ` + padding: 4px 8px; + font-size: 12px; + background: #ffc107; + color: black; + border: none; + border-radius: 4px; + cursor: pointer; + `; + delRowBtn.onclick = (e) => { + e.stopPropagation(); + this.deleteTableRow(table); + }; + + // Delete Column button + const delColBtn = document.createElement('button'); + delColBtn.innerHTML = '- Col'; + delColBtn.style.cssText = ` + padding: 4px 8px; + font-size: 12px; + background: #fd7e14; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + `; + delColBtn.onclick = (e) => { + e.stopPropagation(); + this.deleteTableColumn(table); + }; + + controls.appendChild(addRowBtn); + controls.appendChild(addColBtn); + controls.appendChild(delRowBtn); + controls.appendChild(delColBtn); + + container.appendChild(controls); + + // Show/hide controls on hover + container.addEventListener('mouseenter', () => { + controls.style.opacity = '1'; + }); + + container.addEventListener('mouseleave', () => { + controls.style.opacity = '0'; + }); + } - // Table manipulation methods - addTableRow(event) { - const table = event.target.closest('div').querySelector('table'); + // Table manipulation methods (updated for new structure) + addTableRow(table) { const newRow = document.createElement('tr'); const colCount = table.rows[0].cells.length; for (let i = 0; i < colCount; i++) { const td = document.createElement('td'); td.textContent = `New Cell`; - td.style.border = '1px solid #ccc'; - td.style.padding = '8px'; + td.style.cssText = ` + border: 1px solid #ddd; + padding: 8px; + background: white; + `; + td.contentEditable = true; newRow.appendChild(td); } table.appendChild(newRow); } - addTableColumn(event) { - const table = event.target.closest('div').querySelector('table'); + addTableColumn(table) { const rows = table.rows; for (let i = 0; i < rows.length; i++) { const cell = document.createElement(i === 0 ? 'th' : 'td'); cell.textContent = i === 0 ? `Header ${rows[i].cells.length + 1}` : `New Cell`; - cell.style.border = '1px solid #ccc'; - cell.style.padding = '8px'; - if (i === 0) cell.style.backgroundColor = '#f5f5f5'; + cell.style.cssText = ` + border: 1px solid #ddd; + padding: 8px; + background: ${i === 0 ? '#f8f9fa' : 'white'}; + font-weight: ${i === 0 ? '600' : 'normal'}; + `; + if (i > 0) { + cell.contentEditable = true; + } rows[i].appendChild(cell); } } - deleteTableRow(event) { - const table = event.target.closest('div').querySelector('table'); + deleteTableRow(table) { if (table.rows.length > 1) { table.deleteRow(-1); } } - deleteTableColumn(event) { - const table = event.target.closest('div').querySelector('table'); + deleteTableColumn(table) { const rows = table.rows; if (rows[0].cells.length > 1) { for (let i = 0; i < rows.length; i++) { @@ -7086,8 +7199,8 @@ export default class PropertyTemplateSelector extends LightningElement { // Select draggable element selectDraggableElement(element) { - // Remove selection from all elements - document.querySelectorAll('.draggable-image-container').forEach(el => { + // Remove selection from all draggable elements + document.querySelectorAll('.draggable-image-container, .draggable-table-container').forEach(el => { el.classList.remove('selected'); });