diff --git a/app/Filament/Admin/Resources/FooterTemplates/Pages/EditFooterTemplate.php b/app/Filament/Admin/Resources/FooterTemplates/Pages/EditFooterTemplate.php
index 9194f15..bdc8049 100644
--- a/app/Filament/Admin/Resources/FooterTemplates/Pages/EditFooterTemplate.php
+++ b/app/Filament/Admin/Resources/FooterTemplates/Pages/EditFooterTemplate.php
@@ -52,4 +52,11 @@ class EditFooterTemplate extends EditRecord
return $data;
}
+
+ protected function afterSave(): void
+ {
+ // Kaydetme sonrası preview'ı güncelle
+ // Livewire event dispatch et
+ $this->dispatch('template-saved');
+ }
}
diff --git a/app/Filament/Admin/Resources/FooterTemplates/Schemas/FooterTemplateForm.php b/app/Filament/Admin/Resources/FooterTemplates/Schemas/FooterTemplateForm.php
index fe9a753..87e61bf 100644
--- a/app/Filament/Admin/Resources/FooterTemplates/Schemas/FooterTemplateForm.php
+++ b/app/Filament/Admin/Resources/FooterTemplates/Schemas/FooterTemplateForm.php
@@ -50,13 +50,11 @@ class FooterTemplateForm
// Preview Component - placed after editor
View::make('components.template-preview')
- ->viewData(function ($record) {
- return [
- 'type' => 'footer',
- 'fieldName' => 'html_content',
- 'recordId' => $record?->id,
- ];
- })
+ ->viewData([
+ 'type' => 'footer',
+ 'fieldName' => 'html_content',
+ 'recordId' => null, // Will be extracted from URL by JavaScript
+ ])
->columnSpanFull(),
Toggle::make('is_active')
diff --git a/app/Filament/Admin/Resources/HeaderTemplates/Pages/EditHeaderTemplate.php b/app/Filament/Admin/Resources/HeaderTemplates/Pages/EditHeaderTemplate.php
index a345243..fa6b6d5 100644
--- a/app/Filament/Admin/Resources/HeaderTemplates/Pages/EditHeaderTemplate.php
+++ b/app/Filament/Admin/Resources/HeaderTemplates/Pages/EditHeaderTemplate.php
@@ -52,4 +52,11 @@ class EditHeaderTemplate extends EditRecord
return $data;
}
+
+ protected function afterSave(): void
+ {
+ // Kaydetme sonrası preview'ı güncelle
+ // Livewire event dispatch et (JavaScript tarafında Livewire.on() ile dinlenecek)
+ $this->dispatch('template-saved');
+ }
}
diff --git a/app/Filament/Admin/Resources/HeaderTemplates/Schemas/HeaderTemplateForm.php b/app/Filament/Admin/Resources/HeaderTemplates/Schemas/HeaderTemplateForm.php
index 2519047..c697942 100644
--- a/app/Filament/Admin/Resources/HeaderTemplates/Schemas/HeaderTemplateForm.php
+++ b/app/Filament/Admin/Resources/HeaderTemplates/Schemas/HeaderTemplateForm.php
@@ -49,13 +49,11 @@ class HeaderTemplateForm
// Preview Component - placed after editor
View::make('components.template-preview')
- ->viewData(function ($record) {
- return [
- 'type' => 'header',
- 'fieldName' => 'html_content',
- 'recordId' => $record?->id,
- ];
- })
+ ->viewData([
+ 'type' => 'header',
+ 'fieldName' => 'html_content',
+ 'recordId' => null, // Will be extracted from URL by JavaScript
+ ])
->columnSpanFull(),
Toggle::make('is_active')
diff --git a/app/Filament/Admin/Resources/MenuTemplates/Pages/EditMenuTemplate.php b/app/Filament/Admin/Resources/MenuTemplates/Pages/EditMenuTemplate.php
index ad843a3..554bce9 100644
--- a/app/Filament/Admin/Resources/MenuTemplates/Pages/EditMenuTemplate.php
+++ b/app/Filament/Admin/Resources/MenuTemplates/Pages/EditMenuTemplate.php
@@ -28,4 +28,11 @@ class EditMenuTemplate extends EditRecord
RestoreAction::make(),
];
}
+
+ protected function afterSave(): void
+ {
+ // Kaydetme sonrası preview'ı güncelle
+ // Livewire event dispatch et
+ $this->dispatch('template-saved');
+ }
}
diff --git a/app/Filament/Admin/Resources/MenuTemplates/Schemas/MenuTemplateForm.php b/app/Filament/Admin/Resources/MenuTemplates/Schemas/MenuTemplateForm.php
index a7bca8b..c9c6424 100644
--- a/app/Filament/Admin/Resources/MenuTemplates/Schemas/MenuTemplateForm.php
+++ b/app/Filament/Admin/Resources/MenuTemplates/Schemas/MenuTemplateForm.php
@@ -46,13 +46,11 @@ class MenuTemplateForm
// Preview Component
View::make('components.menu-template-preview')
- ->viewData(function ($record) {
- return [
- 'type' => 'menu',
- 'fieldName' => 'html_content',
- 'recordId' => $record?->id,
- ];
- })
+ ->viewData([
+ 'type' => 'menu',
+ 'fieldName' => 'html_content',
+ 'recordId' => null, // Will be extracted from URL by JavaScript
+ ])
->columnSpanFull(),
Toggle::make('is_active')
diff --git a/app/Filament/Admin/Resources/SectionTemplates/Pages/EditSectionTemplate.php b/app/Filament/Admin/Resources/SectionTemplates/Pages/EditSectionTemplate.php
index 5cd61e4..d48b122 100644
--- a/app/Filament/Admin/Resources/SectionTemplates/Pages/EditSectionTemplate.php
+++ b/app/Filament/Admin/Resources/SectionTemplates/Pages/EditSectionTemplate.php
@@ -52,4 +52,11 @@ class EditSectionTemplate extends EditRecord
return $data;
}
+
+ protected function afterSave(): void
+ {
+ // Kaydetme sonrası preview'ı güncelle
+ // Livewire event dispatch et
+ $this->dispatch('template-saved');
+ }
}
diff --git a/app/Filament/Admin/Resources/SectionTemplates/Schemas/SectionTemplateForm.php b/app/Filament/Admin/Resources/SectionTemplates/Schemas/SectionTemplateForm.php
index e2f0d2f..1d98fce 100644
--- a/app/Filament/Admin/Resources/SectionTemplates/Schemas/SectionTemplateForm.php
+++ b/app/Filament/Admin/Resources/SectionTemplates/Schemas/SectionTemplateForm.php
@@ -49,13 +49,11 @@ class SectionTemplateForm
// Preview Component - placed after editor
View::make('components.template-preview')
- ->viewData(function ($record) {
- return [
- 'type' => 'section',
- 'fieldName' => 'html_content',
- 'recordId' => $record?->id,
- ];
- })
+ ->viewData([
+ 'type' => 'section',
+ 'fieldName' => 'html_content',
+ 'recordId' => null, // Will be extracted from URL by JavaScript
+ ])
->columnSpanFull(),
Toggle::make('is_active')
diff --git a/resources/views/components/menu-template-preview.blade.php b/resources/views/components/menu-template-preview.blade.php
index 98774ae..694e3a5 100644
--- a/resources/views/components/menu-template-preview.blade.php
+++ b/resources/views/components/menu-template-preview.blade.php
@@ -116,6 +116,27 @@ function templatePreview(previewUrl, type, fieldName, recordIdFromView = null) {
} catch (e) {
console.log('[Preview] Could not get ID from Livewire');
}
+
+ // Livewire event listener ekle (Livewire 3.x için)
+ if (window.Livewire) {
+ document.addEventListener('livewire:init', () => {
+ Livewire.on('template-saved', () => {
+ this.updatePreview();
+ });
+ });
+
+ // Eğer Livewire zaten yüklendiyse direkt dinle
+ if (window.Livewire.hook) {
+ Livewire.on('template-saved', () => {
+ this.updatePreview();
+ });
+ }
+ }
+
+ // Window event listener ekle (alternatif - Livewire event'lerini de yakalar)
+ window.addEventListener('template-saved', () => {
+ this.updatePreview();
+ });
},
async updatePreview() {
diff --git a/resources/views/components/placeholder-picker.blade.php b/resources/views/components/placeholder-picker.blade.php
index 02230ba..f25b84a 100644
--- a/resources/views/components/placeholder-picker.blade.php
+++ b/resources/views/components/placeholder-picker.blade.php
@@ -85,7 +85,7 @@
size="sm"
color="gray"
outlined
- @click="insertPlaceholder('{{ $fieldName }}', type + '.' + example)"
+ x-on:click="window.insertPlaceholder('{{ $fieldName }}', type + '.' + example)"
x-bind:tooltip="'{{ __('placeholder-picker.click_to_insert') }}'"
>
@@ -105,7 +105,7 @@
size="sm"
color="primary"
outlined
- @click="insertPlaceholder('{{ $fieldName }}', 'menu')"
+ x-on:click="window.insertPlaceholder('{{ $fieldName }}', 'menu')"
>
{menu}
@@ -113,7 +113,7 @@
size="sm"
color="primary"
outlined
- @click="insertPlaceholder('{{ $fieldName }}', 'staticMenu')"
+ x-on:click="window.insertPlaceholder('{{ $fieldName }}', 'staticMenu')"
>
{staticMenu}
@@ -179,25 +179,37 @@
// Monaco Editor instance'ını bul
const editorContainer = document.querySelector('[data-field-name=\'' + fieldName + '\']');
let monacoEditorInstance = null;
- let currentValue = '';
- let cursorPosition = null;
- // Monaco Editor'dan cursor pozisyonunu al
- if (editorContainer && window.monaco) {
+ // Monaco Editor instance'ını bul
+ if (editorContainer && window.monaco && window.monaco.editor) {
+ // Tüm Monaco Editor instance'larını kontrol et
const editorInstances = window.monaco.editor.getEditors();
for (let editor of editorInstances) {
- const container = editor.getContainerDomNode();
- if (container && container.closest && container.closest('[data-field-name=\'' + fieldName + '\']')) {
- monacoEditorInstance = editor;
- const model = editor.getModel();
- currentValue = model.getValue();
- const selection = editor.getSelection();
- if (selection) {
- cursorPosition = model.getOffsetAt(selection.getStartPosition());
- } else {
- cursorPosition = currentValue.length;
+ try {
+ const container = editor.getContainerDomNode();
+ if (container) {
+ // Container'ın parent'larını kontrol et
+ let parent = container;
+ while (parent && parent !== document.body) {
+ if (parent.hasAttribute && parent.hasAttribute('data-field-name') &&
+ parent.getAttribute('data-field-name') === fieldName) {
+ monacoEditorInstance = editor;
+ break;
+ }
+ parent = parent.parentElement;
+ }
+
+ // Veya closest metodunu kullan
+ if (!monacoEditorInstance && container.closest) {
+ const closest = container.closest('[data-field-name=\'' + fieldName + '\']');
+ if (closest) {
+ monacoEditorInstance = editor;
+ break;
+ }
+ }
}
- break;
+ } catch (e) {
+ console.debug('Monaco Editor container check failed:', e);
}
}
}
@@ -205,93 +217,90 @@
// Monaco Editor varsa, doğrudan onu kullan
if (monacoEditorInstance) {
const model = monacoEditorInstance.getModel();
- const newValue = currentValue.slice(0, cursorPosition) + placeholderText + currentValue.slice(cursorPosition);
+ const currentValue = model.getValue();
- // Monaco Editor'da değeri güncelle
- monacoEditorInstance.executeEdits('placeholder-insert', [{
- range: new window.monaco.Range(
- model.getPositionAt(cursorPosition).lineNumber,
- model.getPositionAt(cursorPosition).column,
- model.getPositionAt(cursorPosition).lineNumber,
- model.getPositionAt(cursorPosition).column
- ),
- text: placeholderText
- }]);
-
- // Cursor pozisyonunu güncelle
- const newPosition = model.getPositionAt(cursorPosition + placeholderText.length);
- monacoEditorInstance.setPosition(newPosition);
+ // Monaco Editor'ı focus et (önce focus et ki cursor pozisyonu doğru alınsın)
monacoEditorInstance.focus();
- // Filament form state'ini güncellemek için Monaco Editor'ın change event'ini tetikle
- // Filament CodeEditor otomatik olarak değişiklikleri algılar
+ // Kısa bir delay ile cursor pozisyonunu al (focus işleminin tamamlanması için)
setTimeout(() => {
- // Monaco Editor model değişikliğini tetikle
- // Bu, Filament'in CodeEditor component'inin otomatik olarak algılamasını sağlar
- if (monacoEditorInstance) {
- // Model'in değerini tekrar set et (zaten set ettik ama event'i tetiklemek için)
- const model = monacoEditorInstance.getModel();
-
- // Monaco Editor'ın onDidChangeContent event'ini manuel tetikle
- // Filament CodeEditor bu event'i dinliyor ve form state'ini güncelliyor
- model.onDidChangeContent(() => {
- // Bu event zaten tetiklenmiş olacak, sadece emin olmak için
- });
-
+ // Cursor pozisyonunu al (selection varsa onu kullan, yoksa cursor pozisyonunu)
+ let selection = monacoEditorInstance.getSelection();
+ let cursorPosition;
+
+ if (selection && !selection.isEmpty()) {
+ // Seçili metin varsa, başlangıç pozisyonunu kullan
+ cursorPosition = model.getOffsetAt(selection.getStartPosition());
+ } else {
+ // Seçim yoksa cursor pozisyonunu kullan
+ const position = monacoEditorInstance.getPosition();
+ if (position) {
+ cursorPosition = model.getOffsetAt(position);
+ } else {
+ // Cursor pozisyonu alınamazsa sona ekle
+ cursorPosition = currentValue.length;
+ }
+ }
+
+ // Placeholder'ı cursor pozisyonuna ekle
+ const position = model.getPositionAt(cursorPosition);
+ const range = new window.monaco.Range(
+ position.lineNumber,
+ position.column,
+ position.lineNumber,
+ position.column
+ );
+
+ // Edit işlemini yap
+ monacoEditorInstance.executeEdits('placeholder-insert', [{
+ range: range,
+ text: placeholderText
+ }]);
+
+ // Cursor pozisyonunu güncelle (placeholder'ın sonuna)
+ const newCursorPosition = model.getPositionAt(cursorPosition + placeholderText.length);
+ monacoEditorInstance.setPosition(newCursorPosition);
+
+ // Focus'u koru
+ monacoEditorInstance.focus();
+
+ // Filament form state'ini güncellemek için güncel değeri al
+ const updatedValue = model.getValue();
+
+ // Filament form state'ini güncelle
+ setTimeout(() => {
// Hidden input'u bul ve güncelle (eğer varsa)
const hiddenInput = editorContainer.querySelector('input[type=\'hidden\']');
if (hiddenInput) {
- hiddenInput.value = newValue;
+ hiddenInput.value = updatedValue;
hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));
hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
}
// Filament form'unu bul ve güncelle
- // Form component'ini bulmak için editor container'ın parent'larını kontrol et
- let formComponent = null;
const formWireElement = editorContainer.closest('form [wire\\:id], [wire\\:id][wire\\:key*="form"]');
if (formWireElement && window.Livewire) {
const wireId = formWireElement.getAttribute('wire:id');
const component = window.Livewire.find(wireId);
- // Component'in form component'i olup olmadığını kontrol et
- // Sadece field path'lerini kontrol et, 'data' property'sine direkt erişme
if (component && component.get) {
const fieldPath = 'data.' + fieldName;
try {
- // Field path'i kontrol et
if (component.get(fieldPath) !== undefined) {
- formComponent = component;
+ component.set(fieldPath, updatedValue);
} else if (component.get('data.html_content') !== undefined) {
- formComponent = component;
+ component.set('data.html_content', updatedValue);
} else if (component.get('html_content') !== undefined) {
- formComponent = component;
+ component.set('html_content', updatedValue);
}
} catch (e) {
- // Property kontrolü sırasında hata alırsak, component'i kullanma
+ console.debug('Livewire form state update skipped:', e.message);
}
}
}
-
- // Sadece form component'i bulunduysa güncelle
- if (formComponent) {
- try {
- const fieldPath = 'data.' + fieldName;
- if (formComponent.get(fieldPath) !== undefined) {
- formComponent.set(fieldPath, newValue);
- } else if (formComponent.get('data.html_content') !== undefined) {
- formComponent.set('data.html_content', newValue);
- } else if (formComponent.get('html_content') !== undefined) {
- formComponent.set('html_content', newValue);
- }
- } catch (e) {
- // Hata durumunda sadece console'a yaz, Monaco Editor zaten güncellenmiş
- console.debug('Livewire form state update skipped:', e.message);
- }
- }
- }
- }, 150);
+ }, 100);
+ }, 50);
return;
}
diff --git a/resources/views/components/template-preview.blade.php b/resources/views/components/template-preview.blade.php
index 98774ae..694e3a5 100644
--- a/resources/views/components/template-preview.blade.php
+++ b/resources/views/components/template-preview.blade.php
@@ -116,6 +116,27 @@ function templatePreview(previewUrl, type, fieldName, recordIdFromView = null) {
} catch (e) {
console.log('[Preview] Could not get ID from Livewire');
}
+
+ // Livewire event listener ekle (Livewire 3.x için)
+ if (window.Livewire) {
+ document.addEventListener('livewire:init', () => {
+ Livewire.on('template-saved', () => {
+ this.updatePreview();
+ });
+ });
+
+ // Eğer Livewire zaten yüklendiyse direkt dinle
+ if (window.Livewire.hook) {
+ Livewire.on('template-saved', () => {
+ this.updatePreview();
+ });
+ }
+ }
+
+ // Window event listener ekle (alternatif - Livewire event'lerini de yakalar)
+ window.addEventListener('template-saved', () => {
+ this.updatePreview();
+ });
},
async updatePreview() {