v1.0.2-beta
This commit is contained in:
parent
de4347330f
commit
f8b6bb3e05
@ -8423,4 +8423,292 @@ ol li:before {
|
|||||||
left: -20px;
|
left: -20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Image Insertion Modal Styles */
|
||||||
|
.image-modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10000;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-modal {
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||||
|
width: 90%;
|
||||||
|
max-width: 800px;
|
||||||
|
max-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-modal-header {
|
||||||
|
padding: 20px 24px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-modal-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #111827;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-modal-content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 24px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-source-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
padding: 12px 20px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: #6b7280;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn.active {
|
||||||
|
color: #4f46e5;
|
||||||
|
border-bottom-color: #4f46e5;
|
||||||
|
background: #f0f4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn:hover {
|
||||||
|
color: #4f46e5;
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-images-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-categories {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
background: white;
|
||||||
|
color: #374151;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn.active {
|
||||||
|
background: #4f46e5;
|
||||||
|
color: white;
|
||||||
|
border-color: #4f46e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-btn:hover {
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-images-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-image-item {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-image-item:hover {
|
||||||
|
border-color: #4f46e5;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-image-item.selected {
|
||||||
|
border-color: #4f46e5;
|
||||||
|
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-image-item img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-overlay {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||||
|
color: white;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property-image-item:hover .image-overlay {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.local-upload-section {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
border: 2px dashed #d1d5db;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 40px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
background: #f9fafb;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area:hover {
|
||||||
|
border-color: #4f46e5;
|
||||||
|
background: #f0f4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area.dragover {
|
||||||
|
border-color: #4f46e5;
|
||||||
|
background: #e0e7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content p {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content small {
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-modal-actions {
|
||||||
|
padding: 20px 24px;
|
||||||
|
border-top: 1px solid #e5e7eb;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
background: #f9fafb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced Draggable Image Styles */
|
||||||
|
.draggable-image-container {
|
||||||
|
position: absolute;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
cursor: move;
|
||||||
|
z-index: 1000;
|
||||||
|
min-width: 50px;
|
||||||
|
min-height: 50px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-image-container.selected {
|
||||||
|
border-color: #4f46e5;
|
||||||
|
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.draggable-image-container img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-handle {
|
||||||
|
position: absolute;
|
||||||
|
background: #4f46e5;
|
||||||
|
border: 2px solid white;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-handle.nw { top: -6px; left: -6px; cursor: nw-resize; }
|
||||||
|
.resize-handle.ne { top: -6px; right: -6px; cursor: ne-resize; }
|
||||||
|
.resize-handle.sw { bottom: -6px; left: -6px; cursor: sw-resize; }
|
||||||
|
.resize-handle.se { bottom: -6px; right: -6px; cursor: se-resize; }
|
||||||
|
.resize-handle.n { top: -6px; left: 50%; transform: translateX(-50%); cursor: n-resize; }
|
||||||
|
.resize-handle.s { bottom: -6px; left: 50%; transform: translateX(-50%); cursor: s-resize; }
|
||||||
|
.resize-handle.w { top: 50%; left: -6px; transform: translateY(-50%); cursor: w-resize; }
|
||||||
|
.resize-handle.e { top: 50%; right: -6px; transform: translateY(-50%); cursor: e-resize; }
|
||||||
|
|
||||||
|
.delete-handle {
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
right: -8px;
|
||||||
|
background: #ef4444;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 1002;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-handle:hover {
|
||||||
|
background: #dc2626;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -969,7 +969,7 @@
|
|||||||
<lightning-icon icon-name="utility:text" size="x-small"></lightning-icon>
|
<lightning-icon icon-name="utility:text" size="x-small"></lightning-icon>
|
||||||
Text
|
Text
|
||||||
</button>
|
</button>
|
||||||
<button class="toolbar-button" onclick={insertDraggableImage}>
|
<button class="toolbar-button" onclick={showImageInsertModal}>
|
||||||
<lightning-icon icon-name="utility:image" size="x-small"></lightning-icon>
|
<lightning-icon icon-name="utility:image" size="x-small"></lightning-icon>
|
||||||
Image
|
Image
|
||||||
</button>
|
</button>
|
||||||
@ -1230,4 +1230,62 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Image Insertion Modal -->
|
||||||
|
<div if:true={showImageModal} class="image-modal-overlay">
|
||||||
|
<div class="image-modal">
|
||||||
|
<div class="image-modal-header">
|
||||||
|
<h3>Insert Image</h3>
|
||||||
|
<button class="close-btn" onclick={closeImageModal}>✕</button>
|
||||||
|
</div>
|
||||||
|
<div class="image-modal-content">
|
||||||
|
<div class="image-source-tabs">
|
||||||
|
<button class={propertyTabClass} onclick={setImageSource} data-source="property">
|
||||||
|
Property Images
|
||||||
|
</button>
|
||||||
|
<button class={localTabClass} onclick={setImageSource} data-source="local">
|
||||||
|
Upload Image
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div if:true={showPropertyImagesSection} class="property-images-section">
|
||||||
|
<div class="image-categories">
|
||||||
|
<template for:each={imageCategories} for:item="category">
|
||||||
|
<button key={category.value} class="category-btn"
|
||||||
|
onclick={selectImageCategory} data-category={category.value}>
|
||||||
|
{category.label}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="property-images-grid">
|
||||||
|
<template for:each={filteredPropertyImages} for:item="image">
|
||||||
|
<div key={image.url} class="property-image-item" onclick={selectPropertyImage} data-image-url={image.url}>
|
||||||
|
<img src={image.url} alt={image.name} />
|
||||||
|
<div class="image-overlay">
|
||||||
|
<span class="image-name">{image.name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div if:true={showLocalUploadSection} class="local-upload-section">
|
||||||
|
<div class="upload-area" onclick={triggerFileUpload}>
|
||||||
|
<input type="file" class="file-input" accept="image/*" onchange={handleFileUpload} />
|
||||||
|
<div class="upload-content">
|
||||||
|
<lightning-icon icon-name="utility:upload" size="large"></lightning-icon>
|
||||||
|
<p>Click to upload image or drag and drop</p>
|
||||||
|
<small>Supports: JPG, PNG, GIF, WebP</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="image-modal-actions">
|
||||||
|
<button class="btn btn-secondary" onclick={closeImageModal}>Cancel</button>
|
||||||
|
<button class="btn btn-primary" onclick={handleInsertButtonClick} disabled={insertButtonDisabled}>
|
||||||
|
Insert Image
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -45,6 +45,7 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
|
|
||||||
// Real property images from Salesforce
|
// Real property images from Salesforce
|
||||||
@track realPropertyImages = [];
|
@track realPropertyImages = [];
|
||||||
|
@track propertyImages = [];
|
||||||
@track imagesByCategory = {
|
@track imagesByCategory = {
|
||||||
'Interior': [
|
'Interior': [
|
||||||
{ url: 'https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200', title: 'Interior View 1', category: 'Interior' },
|
{ url: 'https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200', title: 'Interior View 1', category: 'Interior' },
|
||||||
@ -116,6 +117,16 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
@track tableCols = 3;
|
@track tableCols = 3;
|
||||||
@track includeHeader = true;
|
@track includeHeader = true;
|
||||||
|
|
||||||
|
// Image insertion modal properties
|
||||||
|
@track showImageModal = false;
|
||||||
|
@track imageSource = 'property'; // 'property' or 'local'
|
||||||
|
@track selectedImageCategory = 'all';
|
||||||
|
@track selectedImageUrl = '';
|
||||||
|
@track selectedImageName = '';
|
||||||
|
@track uploadedImageData = '';
|
||||||
|
@track renderKey = 0; // For forcing re-renders
|
||||||
|
@track insertButtonDisabled = true; // Explicit button state
|
||||||
|
|
||||||
// Table Drag and Drop Variables
|
// Table Drag and Drop Variables
|
||||||
@track isDraggingTable = false;
|
@track isDraggingTable = false;
|
||||||
@track draggedTableData = null;
|
@track draggedTableData = null;
|
||||||
@ -144,6 +155,76 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
return this.replacementActiveTab === 'upload';
|
return this.replacementActiveTab === 'upload';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Image insertion modal getters
|
||||||
|
get isImageModalOpen() {
|
||||||
|
return this.showImageModal;
|
||||||
|
}
|
||||||
|
|
||||||
|
get imageCategories() {
|
||||||
|
const categories = [
|
||||||
|
{ label: 'All Images', value: 'all' },
|
||||||
|
{ label: 'Exterior', value: 'exterior' },
|
||||||
|
{ label: 'Interior', value: 'interior' },
|
||||||
|
{ label: 'Kitchen', value: 'kitchen' },
|
||||||
|
{ label: 'Bedroom', value: 'bedroom' },
|
||||||
|
{ label: 'Bathroom', value: 'bathroom' },
|
||||||
|
{ label: 'Living Room', value: 'living' },
|
||||||
|
{ label: 'Maps', value: 'maps' },
|
||||||
|
{ label: 'None', value: 'none' }
|
||||||
|
];
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
get filteredPropertyImages() {
|
||||||
|
console.log('filteredPropertyImages called');
|
||||||
|
console.log('propertyImages:', this.propertyImages);
|
||||||
|
console.log('selectedImageCategory:', this.selectedImageCategory);
|
||||||
|
|
||||||
|
if (!this.propertyImages || this.propertyImages.length === 0) {
|
||||||
|
console.log('No property images available');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.selectedImageCategory === 'all') {
|
||||||
|
console.log('Returning all images:', this.propertyImages);
|
||||||
|
return this.propertyImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filtered = this.propertyImages.filter(image => {
|
||||||
|
const category = image.category ? image.category.toLowerCase() : 'none';
|
||||||
|
return category === this.selectedImageCategory;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Filtered images:', filtered);
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
get propertyTabClass() {
|
||||||
|
return this.imageSource === 'property' ? 'tab-btn active' : 'tab-btn';
|
||||||
|
}
|
||||||
|
|
||||||
|
get localTabClass() {
|
||||||
|
return this.imageSource === 'local' ? 'tab-btn active' : 'tab-btn';
|
||||||
|
}
|
||||||
|
|
||||||
|
getCategoryButtonClass(categoryValue) {
|
||||||
|
return this.selectedImageCategory === categoryValue ? 'category-btn active' : 'category-btn';
|
||||||
|
}
|
||||||
|
|
||||||
|
get showPropertyImagesSection() {
|
||||||
|
return this.imageSource === 'property';
|
||||||
|
}
|
||||||
|
|
||||||
|
get showLocalUploadSection() {
|
||||||
|
return this.imageSource === 'local';
|
||||||
|
}
|
||||||
|
|
||||||
|
get isInsertButtonDisabled() {
|
||||||
|
const disabled = !this.selectedImageUrl || this.selectedImageUrl === '';
|
||||||
|
console.log('isInsertButtonDisabled check:', disabled, 'selectedImageUrl:', this.selectedImageUrl, 'renderKey:', this.renderKey);
|
||||||
|
return disabled;
|
||||||
|
}
|
||||||
|
|
||||||
// Computed properties for template selection
|
// Computed properties for template selection
|
||||||
get isBlankTemplateSelected() {
|
get isBlankTemplateSelected() {
|
||||||
return this.selectedTemplateId === 'blank-template';
|
return this.selectedTemplateId === 'blank-template';
|
||||||
@ -3670,6 +3751,353 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show image insertion modal
|
||||||
|
showImageInsertModal() {
|
||||||
|
this.showImageModal = true;
|
||||||
|
this.selectedImageUrl = '';
|
||||||
|
this.selectedImageName = '';
|
||||||
|
this.uploadedImageData = '';
|
||||||
|
this.selectedImageCategory = 'all';
|
||||||
|
this.insertButtonDisabled = true;
|
||||||
|
|
||||||
|
// Populate property images from the existing data
|
||||||
|
this.populatePropertyImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate property images array
|
||||||
|
populatePropertyImages() {
|
||||||
|
this.propertyImages = [];
|
||||||
|
|
||||||
|
// Add images from imagesByCategory
|
||||||
|
Object.keys(this.imagesByCategory).forEach(category => {
|
||||||
|
this.imagesByCategory[category].forEach(image => {
|
||||||
|
this.propertyImages.push({
|
||||||
|
url: image.url,
|
||||||
|
name: image.title || image.name || `${category} Image`,
|
||||||
|
category: category.toLowerCase()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add real property images if available
|
||||||
|
if (this.realPropertyImages && this.realPropertyImages.length > 0) {
|
||||||
|
this.realPropertyImages.forEach(image => {
|
||||||
|
this.propertyImages.push({
|
||||||
|
url: image.url || image.Url__c,
|
||||||
|
name: image.name || image.Name || 'Property Image',
|
||||||
|
category: (image.category || image.Category__c || 'none').toLowerCase()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Property images populated:', this.propertyImages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close image insertion modal
|
||||||
|
closeImageModal() {
|
||||||
|
this.showImageModal = false;
|
||||||
|
this.selectedImageUrl = '';
|
||||||
|
this.selectedImageName = '';
|
||||||
|
this.uploadedImageData = '';
|
||||||
|
this.insertButtonDisabled = true;
|
||||||
|
|
||||||
|
// Clear any selections
|
||||||
|
document.querySelectorAll('.property-image-item').forEach(item => {
|
||||||
|
item.classList.remove('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset upload area
|
||||||
|
this.resetUploadArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set image source (property or local)
|
||||||
|
setImageSource(event) {
|
||||||
|
const source = event.target.dataset.source;
|
||||||
|
this.imageSource = source;
|
||||||
|
this.selectedImageUrl = '';
|
||||||
|
this.selectedImageName = '';
|
||||||
|
this.uploadedImageData = '';
|
||||||
|
this.insertButtonDisabled = true;
|
||||||
|
|
||||||
|
// Clear any selections
|
||||||
|
document.querySelectorAll('.property-image-item').forEach(item => {
|
||||||
|
item.classList.remove('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset upload area
|
||||||
|
this.resetUploadArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select image category
|
||||||
|
selectImageCategory(event) {
|
||||||
|
const category = event.target.dataset.category;
|
||||||
|
this.selectedImageCategory = category;
|
||||||
|
|
||||||
|
// Update button states
|
||||||
|
document.querySelectorAll('.category-btn').forEach(btn => {
|
||||||
|
btn.classList.remove('active');
|
||||||
|
if (btn.dataset.category === category) {
|
||||||
|
btn.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select property image
|
||||||
|
selectPropertyImage(event) {
|
||||||
|
// Get the image URL from the closest element with data-image-url
|
||||||
|
const imageItem = event.target.closest('[data-image-url]');
|
||||||
|
const imageUrl = imageItem ? imageItem.dataset.imageUrl : null;
|
||||||
|
const imageName = event.target.alt || event.target.textContent || 'Property Image';
|
||||||
|
|
||||||
|
console.log('Property image selected:', imageUrl, imageName);
|
||||||
|
|
||||||
|
if (!imageUrl) {
|
||||||
|
console.error('No image URL found in selected item');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove previous selection
|
||||||
|
document.querySelectorAll('.property-image-item').forEach(item => {
|
||||||
|
item.classList.remove('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add selection to clicked item
|
||||||
|
const targetItem = event.target.closest('.property-image-item');
|
||||||
|
if (targetItem) {
|
||||||
|
targetItem.classList.add('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force reactivity by creating new objects
|
||||||
|
this.selectedImageUrl = imageUrl;
|
||||||
|
this.selectedImageName = imageName;
|
||||||
|
this.uploadedImageData = '';
|
||||||
|
this.insertButtonDisabled = false;
|
||||||
|
|
||||||
|
console.log('After selection - selectedImageUrl:', this.selectedImageUrl);
|
||||||
|
console.log('Button disabled state:', this.insertButtonDisabled);
|
||||||
|
|
||||||
|
// Log current state for debugging
|
||||||
|
this.logCurrentState();
|
||||||
|
|
||||||
|
// Reset upload area if we're on local tab
|
||||||
|
if (this.imageSource === 'local') {
|
||||||
|
this.resetUploadArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a re-render by updating a tracked property
|
||||||
|
this.forceRerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset upload area to default state
|
||||||
|
resetUploadArea() {
|
||||||
|
const uploadArea = this.template.querySelector('.upload-area');
|
||||||
|
if (uploadArea) {
|
||||||
|
// Remove existing preview if any
|
||||||
|
const existingPreview = uploadArea.querySelector('.uploaded-image-preview');
|
||||||
|
if (existingPreview) {
|
||||||
|
existingPreview.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show upload content again
|
||||||
|
const uploadContent = uploadArea.querySelector('.upload-content');
|
||||||
|
if (uploadContent) {
|
||||||
|
uploadContent.style.display = 'flex';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger file upload
|
||||||
|
triggerFileUpload() {
|
||||||
|
const fileInput = this.template.querySelector('.file-input');
|
||||||
|
if (fileInput) {
|
||||||
|
fileInput.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle file upload
|
||||||
|
handleFileUpload(event) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
console.log('File selected:', file.name);
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
this.uploadedImageData = e.target.result;
|
||||||
|
this.selectedImageUrl = e.target.result;
|
||||||
|
this.selectedImageName = file.name;
|
||||||
|
this.insertButtonDisabled = false;
|
||||||
|
|
||||||
|
console.log('Image loaded, selectedImageUrl:', this.selectedImageUrl);
|
||||||
|
console.log('Button disabled state:', this.insertButtonDisabled);
|
||||||
|
|
||||||
|
// Log current state for debugging
|
||||||
|
this.logCurrentState();
|
||||||
|
|
||||||
|
// Update the upload area to show selected image
|
||||||
|
this.updateUploadAreaWithSelectedImage(e.target.result, file.name);
|
||||||
|
|
||||||
|
// Force a re-render by updating a tracked property
|
||||||
|
this.forceRerender();
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update upload area to show selected image
|
||||||
|
updateUploadAreaWithSelectedImage(imageUrl, fileName) {
|
||||||
|
console.log('updateUploadAreaWithSelectedImage called with:', imageUrl, fileName);
|
||||||
|
const uploadArea = this.template.querySelector('.upload-area');
|
||||||
|
console.log('Upload area found:', uploadArea);
|
||||||
|
if (uploadArea) {
|
||||||
|
// Remove existing preview if any
|
||||||
|
const existingPreview = uploadArea.querySelector('.uploaded-image-preview');
|
||||||
|
if (existingPreview) {
|
||||||
|
existingPreview.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create preview container
|
||||||
|
const previewContainer = document.createElement('div');
|
||||||
|
previewContainer.className = 'uploaded-image-preview';
|
||||||
|
previewContainer.style.cssText = `
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 2px solid #4f46e5;
|
||||||
|
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.2);
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Create image element
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = imageUrl;
|
||||||
|
img.alt = fileName;
|
||||||
|
img.style.cssText = `
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
max-height: 150px;
|
||||||
|
object-fit: cover;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Create file name overlay
|
||||||
|
const fileNameOverlay = document.createElement('div');
|
||||||
|
fileNameOverlay.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||||
|
color: white;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
`;
|
||||||
|
fileNameOverlay.textContent = fileName;
|
||||||
|
|
||||||
|
previewContainer.appendChild(img);
|
||||||
|
previewContainer.appendChild(fileNameOverlay);
|
||||||
|
|
||||||
|
// Replace upload content with preview
|
||||||
|
const uploadContent = uploadArea.querySelector('.upload-content');
|
||||||
|
if (uploadContent) {
|
||||||
|
uploadContent.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadArea.appendChild(previewContainer);
|
||||||
|
|
||||||
|
// Add click handler to change image
|
||||||
|
uploadArea.onclick = () => {
|
||||||
|
this.triggerFileUpload();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle insert button click with debugging
|
||||||
|
handleInsertButtonClick() {
|
||||||
|
console.log('=== INSERT BUTTON CLICKED ===');
|
||||||
|
this.logCurrentState();
|
||||||
|
console.log('=============================');
|
||||||
|
this.insertSelectedImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert selected image
|
||||||
|
insertSelectedImage() {
|
||||||
|
console.log('insertSelectedImage called');
|
||||||
|
console.log('selectedImageUrl:', this.selectedImageUrl);
|
||||||
|
console.log('insertButtonDisabled:', this.insertButtonDisabled);
|
||||||
|
|
||||||
|
// Check if we have a valid image URL
|
||||||
|
const imageUrl = this.selectedImageUrl || this.uploadedImageData;
|
||||||
|
const imageName = this.selectedImageName || 'Uploaded Image';
|
||||||
|
|
||||||
|
if (this.insertButtonDisabled || !imageUrl) {
|
||||||
|
console.error('Please select an image first');
|
||||||
|
console.error('selectedImageUrl:', this.selectedImageUrl);
|
||||||
|
console.error('uploadedImageData:', this.uploadedImageData);
|
||||||
|
console.error('insertButtonDisabled:', this.insertButtonDisabled);
|
||||||
|
alert('Please select an image first');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const editor = this.template.querySelector('.enhanced-editor-content');
|
||||||
|
if (editor) {
|
||||||
|
// Save undo state before making changes
|
||||||
|
this.saveUndoState();
|
||||||
|
this.setupEditorClickHandler();
|
||||||
|
|
||||||
|
// Create draggable image container
|
||||||
|
const imageContainer = document.createElement('div');
|
||||||
|
imageContainer.className = 'draggable-image-container';
|
||||||
|
imageContainer.style.left = '50px';
|
||||||
|
imageContainer.style.top = '50px';
|
||||||
|
imageContainer.style.width = '200px';
|
||||||
|
imageContainer.style.height = '150px';
|
||||||
|
imageContainer.style.zIndex = '1000';
|
||||||
|
imageContainer.style.position = 'absolute';
|
||||||
|
imageContainer.style.overflow = 'hidden';
|
||||||
|
imageContainer.style.border = '2px solid transparent';
|
||||||
|
imageContainer.style.cursor = 'move';
|
||||||
|
imageContainer.style.userSelect = 'none';
|
||||||
|
|
||||||
|
// Create image element
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = imageUrl;
|
||||||
|
img.alt = imageName;
|
||||||
|
img.style.width = '100%';
|
||||||
|
img.style.height = '100%';
|
||||||
|
img.style.objectFit = 'cover';
|
||||||
|
img.style.display = 'block';
|
||||||
|
|
||||||
|
imageContainer.appendChild(img);
|
||||||
|
|
||||||
|
// Add resize handles
|
||||||
|
this.addResizeHandles(imageContainer);
|
||||||
|
|
||||||
|
// Add delete handle
|
||||||
|
this.addDeleteHandle(imageContainer);
|
||||||
|
|
||||||
|
// Add drag functionality
|
||||||
|
this.makeDraggable(imageContainer);
|
||||||
|
|
||||||
|
// Add click to select functionality
|
||||||
|
imageContainer.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.selectDraggableElement(imageContainer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Select the image after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
this.selectDraggableElement(imageContainer);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
editor.appendChild(imageContainer);
|
||||||
|
|
||||||
|
// Close modal
|
||||||
|
this.closeImageModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Insert draggable image element
|
// Insert draggable image element
|
||||||
insertDraggableImage() {
|
insertDraggableImage() {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
@ -6460,6 +6888,240 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enhanced image manipulation methods
|
||||||
|
addResizeHandles(container) {
|
||||||
|
const handles = ['nw', 'ne', 'sw', 'se', 'n', 's', 'w', 'e'];
|
||||||
|
|
||||||
|
handles.forEach(handle => {
|
||||||
|
const resizeHandle = document.createElement('div');
|
||||||
|
resizeHandle.className = `resize-handle ${handle}`;
|
||||||
|
resizeHandle.style.position = 'absolute';
|
||||||
|
resizeHandle.style.background = '#4f46e5';
|
||||||
|
resizeHandle.style.border = '2px solid white';
|
||||||
|
resizeHandle.style.borderRadius = '50%';
|
||||||
|
resizeHandle.style.width = '12px';
|
||||||
|
resizeHandle.style.height = '12px';
|
||||||
|
resizeHandle.style.zIndex = '1001';
|
||||||
|
|
||||||
|
// Position handles
|
||||||
|
switch(handle) {
|
||||||
|
case 'nw': resizeHandle.style.top = '-6px'; resizeHandle.style.left = '-6px'; resizeHandle.style.cursor = 'nw-resize'; break;
|
||||||
|
case 'ne': resizeHandle.style.top = '-6px'; resizeHandle.style.right = '-6px'; resizeHandle.style.cursor = 'ne-resize'; break;
|
||||||
|
case 'sw': resizeHandle.style.bottom = '-6px'; resizeHandle.style.left = '-6px'; resizeHandle.style.cursor = 'sw-resize'; break;
|
||||||
|
case 'se': resizeHandle.style.bottom = '-6px'; resizeHandle.style.right = '-6px'; resizeHandle.style.cursor = 'se-resize'; break;
|
||||||
|
case 'n': resizeHandle.style.top = '-6px'; resizeHandle.style.left = '50%'; resizeHandle.style.transform = 'translateX(-50%)'; resizeHandle.style.cursor = 'n-resize'; break;
|
||||||
|
case 's': resizeHandle.style.bottom = '-6px'; resizeHandle.style.left = '50%'; resizeHandle.style.transform = 'translateX(-50%)'; resizeHandle.style.cursor = 's-resize'; break;
|
||||||
|
case 'w': resizeHandle.style.top = '50%'; resizeHandle.style.left = '-6px'; resizeHandle.style.transform = 'translateY(-50%)'; resizeHandle.style.cursor = 'w-resize'; break;
|
||||||
|
case 'e': resizeHandle.style.top = '50%'; resizeHandle.style.right = '-6px'; resizeHandle.style.transform = 'translateY(-50%)'; resizeHandle.style.cursor = 'e-resize'; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add resize functionality
|
||||||
|
this.addResizeFunctionality(resizeHandle, container, handle);
|
||||||
|
|
||||||
|
container.appendChild(resizeHandle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add delete handle to image
|
||||||
|
addDeleteHandle(container) {
|
||||||
|
const deleteHandle = document.createElement('button');
|
||||||
|
deleteHandle.className = 'delete-handle';
|
||||||
|
deleteHandle.innerHTML = '×';
|
||||||
|
deleteHandle.style.position = 'absolute';
|
||||||
|
deleteHandle.style.top = '-8px';
|
||||||
|
deleteHandle.style.right = '-8px';
|
||||||
|
deleteHandle.style.background = '#ef4444';
|
||||||
|
deleteHandle.style.color = 'white';
|
||||||
|
deleteHandle.style.border = 'none';
|
||||||
|
deleteHandle.style.borderRadius = '50%';
|
||||||
|
deleteHandle.style.width = '20px';
|
||||||
|
deleteHandle.style.height = '20px';
|
||||||
|
deleteHandle.style.fontSize = '12px';
|
||||||
|
deleteHandle.style.cursor = 'pointer';
|
||||||
|
deleteHandle.style.zIndex = '1002';
|
||||||
|
deleteHandle.style.display = 'flex';
|
||||||
|
deleteHandle.style.alignItems = 'center';
|
||||||
|
deleteHandle.style.justifyContent = 'center';
|
||||||
|
deleteHandle.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)';
|
||||||
|
|
||||||
|
deleteHandle.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.saveUndoState();
|
||||||
|
container.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteHandle.addEventListener('mouseenter', () => {
|
||||||
|
deleteHandle.style.background = '#dc2626';
|
||||||
|
deleteHandle.style.transform = 'scale(1.1)';
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteHandle.addEventListener('mouseleave', () => {
|
||||||
|
deleteHandle.style.background = '#ef4444';
|
||||||
|
deleteHandle.style.transform = 'scale(1)';
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(deleteHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add resize functionality to handle
|
||||||
|
addResizeFunctionality(handle, container, direction) {
|
||||||
|
let isResizing = false;
|
||||||
|
let startX, startY, startWidth, startHeight, startLeft, startTop;
|
||||||
|
|
||||||
|
handle.addEventListener('mousedown', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
isResizing = true;
|
||||||
|
|
||||||
|
startX = e.clientX;
|
||||||
|
startY = e.clientY;
|
||||||
|
startWidth = parseInt(window.getComputedStyle(container).width, 10);
|
||||||
|
startHeight = parseInt(window.getComputedStyle(container).height, 10);
|
||||||
|
startLeft = parseInt(window.getComputedStyle(container).left, 10);
|
||||||
|
startTop = parseInt(window.getComputedStyle(container).top, 10);
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', handleResize);
|
||||||
|
document.addEventListener('mouseup', stopResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleResize = (e) => {
|
||||||
|
if (!isResizing) return;
|
||||||
|
|
||||||
|
const deltaX = e.clientX - startX;
|
||||||
|
const deltaY = e.clientY - startY;
|
||||||
|
|
||||||
|
let newWidth = startWidth;
|
||||||
|
let newHeight = startHeight;
|
||||||
|
let newLeft = startLeft;
|
||||||
|
let newTop = startTop;
|
||||||
|
|
||||||
|
switch(direction) {
|
||||||
|
case 'se':
|
||||||
|
newWidth = Math.max(50, startWidth + deltaX);
|
||||||
|
newHeight = Math.max(50, startHeight + deltaY);
|
||||||
|
break;
|
||||||
|
case 'sw':
|
||||||
|
newWidth = Math.max(50, startWidth - deltaX);
|
||||||
|
newHeight = Math.max(50, startHeight + deltaY);
|
||||||
|
newLeft = startLeft + (startWidth - newWidth);
|
||||||
|
break;
|
||||||
|
case 'ne':
|
||||||
|
newWidth = Math.max(50, startWidth + deltaX);
|
||||||
|
newHeight = Math.max(50, startHeight - deltaY);
|
||||||
|
newTop = startTop + (startHeight - newHeight);
|
||||||
|
break;
|
||||||
|
case 'nw':
|
||||||
|
newWidth = Math.max(50, startWidth - deltaX);
|
||||||
|
newHeight = Math.max(50, startHeight - deltaY);
|
||||||
|
newLeft = startLeft + (startWidth - newWidth);
|
||||||
|
newTop = startTop + (startHeight - newHeight);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
newWidth = Math.max(50, startWidth + deltaX);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
newWidth = Math.max(50, startWidth - deltaX);
|
||||||
|
newLeft = startLeft + (startWidth - newWidth);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
newHeight = Math.max(50, startHeight + deltaY);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
newHeight = Math.max(50, startHeight - deltaY);
|
||||||
|
newTop = startTop + (startHeight - newHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.style.width = newWidth + 'px';
|
||||||
|
container.style.height = newHeight + 'px';
|
||||||
|
container.style.left = newLeft + 'px';
|
||||||
|
container.style.top = newTop + 'px';
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopResize = () => {
|
||||||
|
isResizing = false;
|
||||||
|
document.removeEventListener('mousemove', handleResize);
|
||||||
|
document.removeEventListener('mouseup', stopResize);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make element draggable (enhanced version)
|
||||||
|
makeDraggable(element) {
|
||||||
|
let isDragging = false;
|
||||||
|
let startX, startY, startLeft, startTop;
|
||||||
|
|
||||||
|
element.addEventListener('mousedown', (e) => {
|
||||||
|
// Don't start drag if clicking on resize handles or delete button
|
||||||
|
if (e.target.classList.contains('resize-handle') || e.target.classList.contains('delete-handle')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDragging = true;
|
||||||
|
startX = e.clientX;
|
||||||
|
startY = e.clientY;
|
||||||
|
startLeft = parseInt(window.getComputedStyle(element).left, 10);
|
||||||
|
startTop = parseInt(window.getComputedStyle(element).top, 10);
|
||||||
|
|
||||||
|
element.style.cursor = 'grabbing';
|
||||||
|
document.addEventListener('mousemove', handleDrag);
|
||||||
|
document.addEventListener('mouseup', stopDrag);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleDrag = (e) => {
|
||||||
|
if (!isDragging) return;
|
||||||
|
|
||||||
|
const deltaX = e.clientX - startX;
|
||||||
|
const deltaY = e.clientY - startY;
|
||||||
|
|
||||||
|
element.style.left = (startLeft + deltaX) + 'px';
|
||||||
|
element.style.top = (startTop + deltaY) + 'px';
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopDrag = () => {
|
||||||
|
isDragging = false;
|
||||||
|
element.style.cursor = 'move';
|
||||||
|
document.removeEventListener('mousemove', handleDrag);
|
||||||
|
document.removeEventListener('mouseup', stopDrag);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select draggable element
|
||||||
|
selectDraggableElement(element) {
|
||||||
|
// Remove selection from all elements
|
||||||
|
document.querySelectorAll('.draggable-image-container').forEach(el => {
|
||||||
|
el.classList.remove('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add selection to clicked element
|
||||||
|
element.classList.add('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force re-render by updating a tracked property
|
||||||
|
forceRerender() {
|
||||||
|
// Update a dummy property to force reactivity
|
||||||
|
this.renderKey = this.renderKey ? this.renderKey + 1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug method to log current state
|
||||||
|
logCurrentState() {
|
||||||
|
console.log('=== CURRENT STATE ===');
|
||||||
|
console.log('selectedImageUrl:', this.selectedImageUrl);
|
||||||
|
console.log('selectedImageName:', this.selectedImageName);
|
||||||
|
console.log('uploadedImageData:', this.uploadedImageData);
|
||||||
|
console.log('insertButtonDisabled:', this.insertButtonDisabled);
|
||||||
|
console.log('imageSource:', this.imageSource);
|
||||||
|
console.log('propertyImages length:', this.propertyImages ? this.propertyImages.length : 0);
|
||||||
|
console.log('====================');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test method to manually set an image (for debugging)
|
||||||
|
testSetImage() {
|
||||||
|
console.log('Testing manual image set');
|
||||||
|
this.selectedImageUrl = 'https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200';
|
||||||
|
this.selectedImageName = 'Test Image';
|
||||||
|
this.insertButtonDisabled = false;
|
||||||
|
this.logCurrentState();
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.loadSavedTemplates();
|
this.loadSavedTemplates();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user