update
This commit is contained in:
		| @@ -65,26 +65,42 @@ Implemented an advanced editor for complex properties (Arrays and Objects) that | |||||||
|  |  | ||||||
| ### Features | ### Features | ||||||
| 1. **Dynamic Layout**: Frame shrinks by 300px from bottom when editor opens | 1. **Dynamic Layout**: Frame shrinks by 300px from bottom when editor opens | ||||||
| 2. **JSON Editor**:  | 2. **Multiple Editors**: Can edit multiple properties simultaneously side by side | ||||||
|  | 3. **JSON Editor**:  | ||||||
|    - Monospace font for code editing |    - Monospace font for code editing | ||||||
|    - Tab key support for indentation |    - Tab key support for indentation | ||||||
|    - Syntax validation with error messages |    - Syntax validation with error messages | ||||||
|    - Live preview of changes |    - Live preview of changes | ||||||
| 3. **Smooth Transitions**: Animated opening/closing with 0.3s ease | 4. **Smooth Transitions**: Animated opening/closing with 0.3s ease | ||||||
| 4. **Error Handling**: Invalid JSON shows clear error messages that disappear on typing | 5. **Error Handling**: Invalid JSON shows clear error messages that disappear on typing | ||||||
|  | 6. **Close All Button**: Single button to close all open editors at once | ||||||
|  |  | ||||||
| ### Technical Implementation | ### Technical Implementation (Updated) | ||||||
| - **State Management**: Added showAdvancedEditor, editingProperty, editorValue, editorError states | - **State Management**: Changed from single editor to array of editors with unique IDs | ||||||
|  | - **Editor Structure**: Each editor instance contains: | ||||||
|  |   - `id`: Unique identifier (`propertyName-timestamp`) | ||||||
|  |   - `name`: Property name | ||||||
|  |   - `value`: Original value | ||||||
|  |   - `element`: Reference to the element | ||||||
|  |   - `editorValue`: Current JSON string | ||||||
|  |   - `editorError`: Validation error message | ||||||
| - **Event System**: Uses custom 'editorStateChanged' event to communicate with parent dashboard | - **Event System**: Uses custom 'editorStateChanged' event to communicate with parent dashboard | ||||||
| - **Dynamic Styling**: wcc-frame's bottom position changes from 100px to 400px when editor is open | - **Dynamic Styling**: wcc-frame's bottom position changes from 100px to 400px when any editor is open | ||||||
| - **Property Types**: Object and Array properties show "Edit Object/Array" button instead of inline controls | - **Property Types**: Object and Array properties show "Edit Object/Array" button instead of inline controls | ||||||
|  |  | ||||||
| ### User Flow | ### User Flow | ||||||
| 1. Click "Edit Object/Array" button on complex property | 1. Click "Edit Object/Array" button on complex property | ||||||
| 2. Editor slides up between properties panel and frame | 2. Editor slides up between properties panel and frame | ||||||
| 3. Edit JSON with live validation | 3. Click additional "Edit" buttons to open more properties side by side | ||||||
| 4. Save applies changes and refreshes properties, Cancel discards changes | 4. Each editor can be saved/cancelled independently | ||||||
| 5. Frame automatically resizes back when editor closes | 5. "Close All" button dismisses all editors at once | ||||||
|  | 6. Frame automatically resizes back when all editors are closed | ||||||
|  |  | ||||||
|  | ### Layout Details | ||||||
|  | - **Container**: Flexbox with horizontal scrolling when multiple editors overflow | ||||||
|  | - **Editor Width**: Min 300px, max 500px, flexible between | ||||||
|  | - **Scrollbar**: Custom styled thin scrollbar for horizontal overflow | ||||||
|  | - **Header Bar**: Fixed top bar with "Property Editors" title and "Close All" button | ||||||
|  |  | ||||||
| ## Properties Panel Element Detection Issue (Fixed) | ## Properties Panel Element Detection Issue (Fixed) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,16 +35,14 @@ export class WccProperties extends DeesElement { | |||||||
|   propertyContent: TemplateResult[] = []; |   propertyContent: TemplateResult[] = []; | ||||||
|  |  | ||||||
|   @state() |   @state() | ||||||
|   showAdvancedEditor: boolean = false; |   editingProperties: Array<{ | ||||||
|  |     id: string; | ||||||
|   @state() |     name: string; | ||||||
|   editingProperty: { name: string; value: any; element: HTMLElement } = null; |     value: any; | ||||||
|  |     element: HTMLElement; | ||||||
|   @state() |     editorValue: string; | ||||||
|   editorValue: string = ''; |     editorError: string; | ||||||
|  |   }> = []; | ||||||
|   @state() |  | ||||||
|   editorError: string = ''; |  | ||||||
|  |  | ||||||
|   public editorHeight: number = 300; |   public editorHeight: number = 300; | ||||||
|  |  | ||||||
| @@ -76,7 +74,7 @@ export class WccProperties extends DeesElement { | |||||||
|           box-sizing: border-box; |           box-sizing: border-box; | ||||||
|           position: absolute; |           position: absolute; | ||||||
|           left: 200px; |           left: 200px; | ||||||
|           height: ${this.showAdvancedEditor ? 100 + this.editorHeight : 100}px; |           height: ${this.editingProperties.length > 0 ? 100 + this.editorHeight : 100}px; | ||||||
|           bottom: 0px; |           bottom: 0px; | ||||||
|           right: 0px; |           right: 0px; | ||||||
|           overflow: hidden; |           overflow: hidden; | ||||||
| @@ -286,99 +284,244 @@ export class WccProperties extends DeesElement { | |||||||
|           backdrop-filter: blur(8px); |           backdrop-filter: blur(8px); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .advanced-editor { |         .advanced-editor-container { | ||||||
|           position: absolute; |           position: absolute; | ||||||
|           left: 0; |           left: 0; | ||||||
|           right: 0; |           right: 0; | ||||||
|           top: 0; |           top: 0; | ||||||
|           height: ${this.editorHeight}px; |           height: ${this.editorHeight}px; | ||||||
|           background: var(--background); |           background: #050505; | ||||||
|           border-bottom: 1px solid rgba(255, 255, 255, 0.08); |           border-bottom: 1px solid rgba(255, 255, 255, 0.1); | ||||||
|           display: flex; |           display: flex; | ||||||
|           flex-direction: column; |           flex-direction: column; | ||||||
|           transition: all 0.3s ease; |           transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | ||||||
|  |           box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-header { |         .editor-header-bar { | ||||||
|           padding: 0.75rem 1rem; |           padding: 0.75rem 1.25rem; | ||||||
|           background: rgba(59, 130, 246, 0.03); |           background: linear-gradient(to bottom, rgba(59, 130, 246, 0.05), transparent); | ||||||
|           border-bottom: 1px solid var(--border); |           border-bottom: 1px solid rgba(59, 130, 246, 0.1); | ||||||
|           display: flex; |           display: flex; | ||||||
|           justify-content: space-between; |           justify-content: space-between; | ||||||
|           align-items: center; |           align-items: center; | ||||||
|  |           height: 48px; | ||||||
|  |           backdrop-filter: blur(8px); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-header-title { | ||||||
|  |           font-size: 0.875rem; | ||||||
|  |           font-weight: 600; | ||||||
|  |           color: var(--foreground); | ||||||
|  |           text-transform: uppercase; | ||||||
|  |           letter-spacing: 0.1em; | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |           gap: 0.5rem; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-header-title::before { | ||||||
|  |           content: ''; | ||||||
|  |           display: inline-block; | ||||||
|  |           width: 3px; | ||||||
|  |           height: 16px; | ||||||
|  |           background: var(--primary); | ||||||
|  |           border-radius: 1px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-close-all { | ||||||
|  |           padding: 0.375rem 0.75rem; | ||||||
|  |           background: rgba(239, 68, 68, 0.05); | ||||||
|  |           border: 1px solid rgba(239, 68, 68, 0.2); | ||||||
|  |           border-radius: var(--radius); | ||||||
|  |           color: #f87171; | ||||||
|  |           font-size: 0.75rem; | ||||||
|  |           font-weight: 500; | ||||||
|  |           cursor: pointer; | ||||||
|  |           transition: all 0.15s ease; | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |           gap: 0.375rem; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-close-all:hover { | ||||||
|  |           background: rgba(239, 68, 68, 0.15); | ||||||
|  |           border-color: rgba(239, 68, 68, 0.4); | ||||||
|  |           transform: translateY(-1px); | ||||||
|  |           box-shadow: 0 2px 4px rgba(239, 68, 68, 0.2); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-close-all::before { | ||||||
|  |           content: '×'; | ||||||
|  |           font-size: 1.125rem; | ||||||
|  |           line-height: 1; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editors-container { | ||||||
|  |           flex: 1; | ||||||
|  |           display: flex; | ||||||
|  |           overflow-x: auto; | ||||||
|  |           overflow-y: hidden; | ||||||
|  |           gap: 0; | ||||||
|  |           background: rgba(255, 255, 255, 0.02); | ||||||
|  |           padding: 0.75rem; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editors-container::-webkit-scrollbar { | ||||||
|  |           height: 8px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editors-container::-webkit-scrollbar-track { | ||||||
|  |           background: rgba(255, 255, 255, 0.02); | ||||||
|  |           border-radius: 4px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editors-container::-webkit-scrollbar-thumb { | ||||||
|  |           background: rgba(255, 255, 255, 0.08); | ||||||
|  |           border-radius: 4px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editors-container::-webkit-scrollbar-thumb:hover { | ||||||
|  |           background: rgba(255, 255, 255, 0.12); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-instance { | ||||||
|  |           min-width: 320px; | ||||||
|  |           flex: 1; | ||||||
|  |           max-width: 480px; | ||||||
|  |           background: rgba(10, 10, 10, 0.6); | ||||||
|  |           display: flex; | ||||||
|  |           flex-direction: column; | ||||||
|  |           border-radius: var(--radius); | ||||||
|  |           overflow: hidden; | ||||||
|  |           margin-right: 0.75rem; | ||||||
|  |           border: 1px solid rgba(255, 255, 255, 0.06); | ||||||
|  |           transition: all 0.2s ease; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-instance:hover { | ||||||
|  |           border-color: rgba(255, 255, 255, 0.1); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-instance:last-child { | ||||||
|  |           margin-right: 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-header { | ||||||
|  |           padding: 0.5rem 0.75rem; | ||||||
|  |           background: rgba(255, 255, 255, 0.02); | ||||||
|  |           border-bottom: 1px solid rgba(255, 255, 255, 0.05); | ||||||
|  |           display: flex; | ||||||
|  |           justify-content: space-between; | ||||||
|  |           align-items: center; | ||||||
|  |           height: 36px; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-title { |         .editor-title { | ||||||
|           font-size: 0.875rem; |           font-size: 0.75rem; | ||||||
|           font-weight: 500; |           font-weight: 500; | ||||||
|           color: var(--foreground); |           color: #999; | ||||||
|  |           overflow: hidden; | ||||||
|  |           text-overflow: ellipsis; | ||||||
|  |           white-space: nowrap; | ||||||
|  |           font-family: 'Consolas', 'Monaco', monospace; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-actions { |         .editor-actions { | ||||||
|           display: flex; |           display: flex; | ||||||
|           gap: 0.5rem; |           gap: 0.25rem; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-button { |         .editor-button { | ||||||
|           padding: 0.375rem 0.75rem; |           width: 24px; | ||||||
|  |           height: 24px; | ||||||
|  |           padding: 0; | ||||||
|           background: transparent; |           background: transparent; | ||||||
|           border: 1px solid var(--border); |           border: none; | ||||||
|           border-radius: var(--radius); |           color: #666; | ||||||
|           color: #999; |           font-size: 1rem; | ||||||
|           font-size: 0.75rem; |  | ||||||
|           cursor: pointer; |           cursor: pointer; | ||||||
|           transition: all 0.15s ease; |           transition: all 0.15s ease; | ||||||
|  |           border-radius: var(--radius-sm); | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |           justify-content: center; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-button:hover { |         .editor-button:hover { | ||||||
|           background: rgba(255, 255, 255, 0.05); |           background: rgba(255, 255, 255, 0.05); | ||||||
|           color: var(--foreground); |           color: #999; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-button.primary { |         .editor-button.primary { | ||||||
|           background: var(--primary); |           color: #4ade80; | ||||||
|           color: var(--primary-foreground); |  | ||||||
|           border-color: var(--primary); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-button.primary:hover { |         .editor-button.primary:hover { | ||||||
|           background: rgba(59, 130, 246, 0.8); |           background: rgba(74, 222, 128, 0.1); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-content { |         .editor-content { | ||||||
|           flex: 1; |           flex: 1; | ||||||
|           padding: 1rem; |           display: flex; | ||||||
|           overflow: auto; |           flex-direction: column; | ||||||
|  |           overflow: hidden; | ||||||
|  |           min-height: 0; | ||||||
|  |           position: relative; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-textarea { |         .editor-textarea { | ||||||
|           width: 100%; |           width: 100%; | ||||||
|           height: 100%; |           height: 100%; | ||||||
|           background: var(--input); |           background: transparent; | ||||||
|           border: 1px solid var(--border); |           border: none; | ||||||
|           border-radius: var(--radius); |           color: #d0d0d0; | ||||||
|           color: var(--foreground); |  | ||||||
|           font-family: 'Consolas', 'Monaco', 'Courier New', monospace; |           font-family: 'Consolas', 'Monaco', 'Courier New', monospace; | ||||||
|           font-size: 0.875rem; |           font-size: 0.8125rem; | ||||||
|  |           line-height: 1.6; | ||||||
|           padding: 0.75rem; |           padding: 0.75rem; | ||||||
|           resize: none; |           resize: none; | ||||||
|           outline: none; |           outline: none; | ||||||
|           transition: all 0.15s ease; |           transition: all 0.15s ease; | ||||||
|  |           overflow: auto; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-textarea:focus { |         .editor-textarea:focus { | ||||||
|           border-color: var(--primary); |           background: rgba(255, 255, 255, 0.01); | ||||||
|           background: rgba(59, 130, 246, 0.05); |         } | ||||||
|  |  | ||||||
|  |         .editor-textarea::selection { | ||||||
|  |           background: rgba(59, 130, 246, 0.3); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .editor-error { |         .editor-error { | ||||||
|           margin-top: 0.5rem; |           position: absolute; | ||||||
|           padding: 0.5rem; |           bottom: 0; | ||||||
|           background: rgba(239, 68, 68, 0.1); |           left: 0; | ||||||
|           border: 1px solid rgba(239, 68, 68, 0.3); |           right: 0; | ||||||
|           border-radius: var(--radius-sm); |           padding: 0.5rem 0.75rem; | ||||||
|           color: #f87171; |           background: rgba(239, 68, 68, 0.9); | ||||||
|           font-size: 0.75rem; |           backdrop-filter: blur(4px); | ||||||
|  |           color: #fff; | ||||||
|  |           font-size: 0.7rem; | ||||||
|  |           font-weight: 500; | ||||||
|  |           display: flex; | ||||||
|  |           align-items: center; | ||||||
|  |           gap: 0.375rem; | ||||||
|  |           border-top: 1px solid rgba(239, 68, 68, 0.5); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .editor-error::before { | ||||||
|  |           content: '!'; | ||||||
|  |           display: inline-flex; | ||||||
|  |           width: 16px; | ||||||
|  |           height: 16px; | ||||||
|  |           align-items: center; | ||||||
|  |           justify-content: center; | ||||||
|  |           background: rgba(255, 255, 255, 0.2); | ||||||
|  |           border-radius: 50%; | ||||||
|  |           font-size: 0.65rem; | ||||||
|  |           font-weight: bold; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         .main-content { |         .main-content { | ||||||
| @@ -389,38 +532,72 @@ export class WccProperties extends DeesElement { | |||||||
|           height: 100px; |           height: 100px; | ||||||
|         } |         } | ||||||
|       </style> |       </style> | ||||||
|       ${this.showAdvancedEditor ? html` |       ${this.editingProperties.length > 0 ? html` | ||||||
|         <div class="advanced-editor"> |         <div class="advanced-editor-container"> | ||||||
|           <div class="editor-header"> |           <div class="editor-header-bar"> | ||||||
|             <div class="editor-title">Editing: ${this.editingProperty?.name}</div> |             <div class="editor-header-title">Property Editors</div> | ||||||
|             <div class="editor-actions"> |             <button class="editor-close-all" @click=${this.closeAllEditors}> | ||||||
|               <button class="editor-button" @click=${this.handleEditorCancel}>Cancel</button> |               Close All | ||||||
|               <button class="editor-button primary" @click=${this.handleEditorSave}>Save</button> |             </button> | ||||||
|             </div> |  | ||||||
|           </div> |           </div> | ||||||
|           <div class="editor-content"> |           <div class="editors-container"> | ||||||
|             <textarea  |             ${this.editingProperties.length === 0 ? html` | ||||||
|               class="editor-textarea" |               <div style=" | ||||||
|               .value=${this.editorValue} |                 flex: 1; | ||||||
|               @input=${(e: InputEvent) => { |                 display: flex; | ||||||
|                 this.editorValue = (e.target as HTMLTextAreaElement).value; |                 align-items: center; | ||||||
|                 this.editorError = ''; |                 justify-content: center; | ||||||
|               }} |                 color: #666; | ||||||
|               @keydown=${(e: KeyboardEvent) => { |                 font-size: 0.875rem; | ||||||
|                 if (e.key === 'Tab') { |                 text-align: center; | ||||||
|                   e.preventDefault(); |                 padding: 2rem; | ||||||
|                   const target = e.target as HTMLTextAreaElement; |               "> | ||||||
|                   const start = target.selectionStart; |                 <div> | ||||||
|                   const end = target.selectionEnd; |                   <div style="margin-bottom: 0.5rem; font-size: 1.5rem; opacity: 0.5;">{ }</div> | ||||||
|                   const value = target.value; |                   <div>No properties being edited</div> | ||||||
|                   target.value = value.substring(0, start) + '  ' + value.substring(end); |                   <div style="font-size: 0.75rem; margin-top: 0.25rem; opacity: 0.7;">Click "Edit Object/Array" buttons to start editing</div> | ||||||
|                   target.selectionStart = target.selectionEnd = start + 2; |                 </div> | ||||||
|                 } |               </div> | ||||||
|               }} |  | ||||||
|             ></textarea> |  | ||||||
|             ${this.editorError ? html` |  | ||||||
|               <div class="editor-error">${this.editorError}</div> |  | ||||||
|             ` : null} |             ` : null} | ||||||
|  |             ${this.editingProperties.map(prop => html` | ||||||
|  |               <div class="editor-instance"> | ||||||
|  |                 <div class="editor-header"> | ||||||
|  |                   <div class="editor-title">${prop.name}</div> | ||||||
|  |                   <div class="editor-actions"> | ||||||
|  |                     <button class="editor-button" @click=${() => this.handleEditorCancel(prop.id)}>✕</button> | ||||||
|  |                     <button class="editor-button primary" @click=${() => this.handleEditorSave(prop.id)}>✓</button> | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="editor-content"> | ||||||
|  |                   <textarea  | ||||||
|  |                     class="editor-textarea" | ||||||
|  |                     .value=${prop.editorValue} | ||||||
|  |                     @input=${(e: InputEvent) => { | ||||||
|  |                       const editor = this.editingProperties.find(p => p.id === prop.id); | ||||||
|  |                       if (editor) { | ||||||
|  |                         editor.editorValue = (e.target as HTMLTextAreaElement).value; | ||||||
|  |                         editor.editorError = ''; | ||||||
|  |                         this.requestUpdate(); | ||||||
|  |                       } | ||||||
|  |                     }} | ||||||
|  |                     @keydown=${(e: KeyboardEvent) => { | ||||||
|  |                       if (e.key === 'Tab') { | ||||||
|  |                         e.preventDefault(); | ||||||
|  |                         const target = e.target as HTMLTextAreaElement; | ||||||
|  |                         const start = target.selectionStart; | ||||||
|  |                         const end = target.selectionEnd; | ||||||
|  |                         const value = target.value; | ||||||
|  |                         target.value = value.substring(0, start) + '  ' + value.substring(end); | ||||||
|  |                         target.selectionStart = target.selectionEnd = start + 2; | ||||||
|  |                       } | ||||||
|  |                     }} | ||||||
|  |                   ></textarea> | ||||||
|  |                   ${prop.editorError ? html` | ||||||
|  |                     <div class="editor-error">${prop.editorError}</div> | ||||||
|  |                   ` : null} | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             `)} | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       ` : null} |       ` : null} | ||||||
| @@ -736,53 +913,84 @@ export class WccProperties extends DeesElement { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private openAdvancedEditor(propertyName: string, value: any, element: HTMLElement) { |   private openAdvancedEditor(propertyName: string, value: any, element: HTMLElement) { | ||||||
|     this.editingProperty = { |     // Check if this property is already being edited | ||||||
|  |     const existingEditor = this.editingProperties.find(p => p.name === propertyName && p.element === element); | ||||||
|  |     if (existingEditor) { | ||||||
|  |       return; // Property is already open for editing | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const newEditor = { | ||||||
|  |       id: `${propertyName}-${Date.now()}`, | ||||||
|       name: propertyName, |       name: propertyName, | ||||||
|       value: value, |       value: value, | ||||||
|       element: element |       element: element, | ||||||
|  |       editorValue: JSON.stringify(value, null, 2), | ||||||
|  |       editorError: '' | ||||||
|     }; |     }; | ||||||
|     this.editorValue = JSON.stringify(value, null, 2); |  | ||||||
|     this.editorError = ''; |     this.editingProperties = [...this.editingProperties, newEditor]; | ||||||
|     this.showAdvancedEditor = true; |  | ||||||
|      |      | ||||||
|     // Notify parent to resize frame |     // Notify parent to resize frame if this is the first editor | ||||||
|     this.dispatchEvent( |     if (this.editingProperties.length === 1) { | ||||||
|       new CustomEvent('editorStateChanged', { |       this.dispatchEvent( | ||||||
|         detail: { isOpen: true }, |         new CustomEvent('editorStateChanged', { | ||||||
|         bubbles: true |           detail: { isOpen: true }, | ||||||
|       }) |           bubbles: true | ||||||
|     ); |         }) | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private handleEditorSave() { |   private handleEditorSave(editorId: string) { | ||||||
|  |     const editor = this.editingProperties.find(p => p.id === editorId); | ||||||
|  |     if (!editor) return; | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|       const parsedValue = JSON.parse(this.editorValue); |       const parsedValue = JSON.parse(editor.editorValue); | ||||||
|       if (this.editingProperty) { |       editor.element[editor.name] = parsedValue; | ||||||
|         this.editingProperty.element[this.editingProperty.name] = parsedValue; |        | ||||||
|         this.showAdvancedEditor = false; |       // Remove this editor from the list | ||||||
|         this.editorError = ''; |       this.editingProperties = this.editingProperties.filter(p => p.id !== editorId); | ||||||
|          |        | ||||||
|         // Notify parent to resize frame back |       // If no more editors, notify parent to resize frame | ||||||
|  |       if (this.editingProperties.length === 0) { | ||||||
|         this.dispatchEvent( |         this.dispatchEvent( | ||||||
|           new CustomEvent('editorStateChanged', { |           new CustomEvent('editorStateChanged', { | ||||||
|             detail: { isOpen: false }, |             detail: { isOpen: false }, | ||||||
|             bubbles: true |             bubbles: true | ||||||
|           }) |           }) | ||||||
|         ); |         ); | ||||||
|          |  | ||||||
|         // Refresh properties display |  | ||||||
|         this.createProperties(); |  | ||||||
|       } |       } | ||||||
|  |        | ||||||
|  |       // Refresh properties display | ||||||
|  |       this.createProperties(); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       this.editorError = `Invalid JSON: ${error.message}`; |       // Update error for this specific editor | ||||||
|  |       const editorIndex = this.editingProperties.findIndex(p => p.id === editorId); | ||||||
|  |       if (editorIndex !== -1) { | ||||||
|  |         this.editingProperties[editorIndex].editorError = `Invalid JSON: ${error.message}`; | ||||||
|  |         this.requestUpdate(); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private handleEditorCancel() { |   private handleEditorCancel(editorId: string) { | ||||||
|     this.showAdvancedEditor = false; |     // Remove this editor from the list | ||||||
|     this.editingProperty = null; |     this.editingProperties = this.editingProperties.filter(p => p.id !== editorId); | ||||||
|     this.editorValue = ''; |      | ||||||
|     this.editorError = ''; |     // If no more editors, notify parent to resize frame | ||||||
|  |     if (this.editingProperties.length === 0) { | ||||||
|  |       this.dispatchEvent( | ||||||
|  |         new CustomEvent('editorStateChanged', { | ||||||
|  |           detail: { isOpen: false }, | ||||||
|  |           bubbles: true | ||||||
|  |         }) | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private closeAllEditors() { | ||||||
|  |     this.editingProperties = []; | ||||||
|      |      | ||||||
|     // Notify parent to resize frame back |     // Notify parent to resize frame back | ||||||
|     this.dispatchEvent( |     this.dispatchEvent( | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user