Skip to content

Commit ef9c6e3

Browse files
committed
Fix bug with missing menu item fields
Add actions to menu item in tree.
1 parent 400f27a commit ef9c6e3

File tree

4 files changed

+85
-26
lines changed

4 files changed

+85
-26
lines changed

database/migrations/create_filament_flexible_content_block_menu_items_table.php.stub

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ return new class extends Migration
1717
// Translatable label
1818
$table->json('label');
1919

20+
// Link type (url, route, or model alias)
21+
$table->string('link_type');
22+
2023
// Link options
2124
$table->string('url')->nullable();
25+
$table->string('route')->nullable();
2226
$table->string('linkable_type')->nullable();
2327
$table->unsignedBigInteger('linkable_id')->nullable();
2428

resources/views/filament/resources/menu-resource/pages/manage-menu-items.blade.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ function menuItemsManager(config) {
6161
6262
init() {
6363
this.initSortable();
64+
this.setupEventListeners();
65+
},
66+
67+
setupEventListeners() {
68+
// Listen for Livewire events to refresh menu items
69+
this.$wire.on('menu-items-updated', () => {
70+
this.refreshMenuItems();
71+
});
72+
},
73+
74+
refreshMenuItems() {
75+
this.loading = true;
76+
this.$wire.call('getMenuItems').then((items) => {
77+
this.items = items;
78+
this.loading = false;
79+
// Re-initialize sortable after items are updated
80+
this.$nextTick(() => {
81+
this.initSortable();
82+
});
83+
});
6484
},
6585
6686
initSortable() {
@@ -114,16 +134,16 @@ function menuItemsManager(config) {
114134
<!-- Actions -->
115135
<div class="flex items-center space-x-2 opacity-0 group-hover:opacity-100 transition-opacity">
116136
${canHaveChildren ? `
117-
<button onclick="$wire.addMenuItem(${item.id})"
137+
<button onclick="$wire.mountAction('addMenuItem', { parent_id: ${item.id} })"
118138
class="inline-flex items-center px-2 py-1 border border-gray-300 rounded text-xs font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
119139
{{ flexiblePagesTrans('menu_items.tree.add_child') }}
120140
</button>
121141
` : ''}
122-
<button onclick="$wire.editMenuItem(${item.id})"
142+
<button onclick="$wire.mountAction('editMenuItem', { itemId: ${item.id} })"
123143
class="inline-flex items-center px-2 py-1 border border-primary-300 rounded text-xs font-medium text-primary-700 bg-primary-50 hover:bg-primary-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
124144
{{ flexiblePagesTrans('menu_items.tree.edit') }}
125145
</button>
126-
<button onclick="$wire.deleteMenuItem(${item.id})"
146+
<button onclick="$wire.mountAction('deleteMenuItem', { itemId: ${item.id} })"
127147
class="inline-flex items-center px-2 py-1 border border-red-300 rounded text-xs font-medium text-red-700 bg-red-50 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
128148
{{ flexiblePagesTrans('menu_items.tree.delete') }}
129149
</button>

src/Filament/Form/Forms/MenuItemForm.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ protected static function getLabelField(): TextInput
8585
{
8686
return TextInput::make(static::FIELD_LABEL)
8787
->label(flexiblePagesTrans('menu_items.form.label_lbl'))
88-
->required()
88+
->required(fn (Get $get): bool => !$get(static::FIELD_USE_MODEL_TITLE))
89+
->visible(fn (Get $get): bool => !$get(static::FIELD_USE_MODEL_TITLE))
8990
->maxLength(255)
9091
->helperText(flexiblePagesTrans('menu_items.form.label_help'));
9192
}

src/Resources/MenuResource/Pages/ManageMenuItems.php

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,43 +85,58 @@ protected function getHeaderActions(): array
8585
->icon('heroicon-o-plus')
8686
->color('primary')
8787
->form($this->getMenuItemFormSchema())
88-
->action(function (array $data): void {
88+
->fillForm(function (array $arguments): array {
89+
$parentId = $arguments['parent_id'] ?? null;
90+
return [
91+
'parent_id' => $parentId,
92+
'is_visible' => true,
93+
'target' => '_self'
94+
];
95+
})
96+
->action(function (array $data, array $arguments): void {
97+
// Merge parent_id from arguments into data
98+
$parentId = $arguments['parent_id'] ?? null;
99+
if ($parentId) {
100+
$data['parent_id'] = $parentId;
101+
}
89102
$this->createMenuItem($data);
90103
})
91-
->modalHeading(flexiblePagesTrans('menu_items.tree.add_item'))
104+
->modalHeading(function (array $arguments): string {
105+
$parentId = $arguments['parent_id'] ?? null;
106+
return $parentId
107+
? flexiblePagesTrans('menu_items.tree.add_child')
108+
: flexiblePagesTrans('menu_items.tree.add_item');
109+
})
92110
->modalSubmitActionLabel(__('Create'))
93111
->modalWidth('2xl')
94112
->slideOver(),
95113
];
96114
}
97115

98-
public function addMenuItem(?int $parentId = null): void
116+
protected function getActions(): array
99117
{
100-
$this->mountAction('addMenuItem', ['parent_id' => $parentId]);
118+
return [
119+
$this->editMenuItemAction(),
120+
$this->deleteMenuItemAction(),
121+
];
101122
}
102123

103-
public function editMenuItem(int $itemId): void
104-
{
105-
$item = $this->getMenuItemSecurely($itemId);
106-
107-
if (! $item) {
108-
Notification::make()
109-
->title(flexiblePagesTrans('menu_items.errors.item_not_found'))
110-
->danger()
111-
->send();
112-
113-
return;
114-
}
115124

116-
$this->mountAction('editMenuItem', ['item' => $item]);
117-
}
118125

119126
public function editMenuItemAction(): Action
120127
{
121128
return Action::make('editMenuItem')
122129
->form($this->getMenuItemFormSchema())
123130
->fillForm(function (array $arguments): array {
124-
$item = $arguments['item'];
131+
$itemId = $arguments['itemId'] ?? null;
132+
if (!$itemId) {
133+
return [];
134+
}
135+
136+
$item = $this->getMenuItemSecurely($itemId);
137+
if (!$item) {
138+
return [];
139+
}
125140

126141
return [
127142
'link_type' => $item->link_type,
@@ -136,15 +151,33 @@ public function editMenuItemAction(): Action
136151
];
137152
})
138153
->action(function (array $data, array $arguments): void {
139-
$item = $arguments['item'];
140-
$this->updateMenuItem($item->id, $data);
154+
$itemId = $arguments['itemId'] ?? null;
155+
if ($itemId) {
156+
$this->updateMenuItem($itemId, $data);
157+
}
141158
})
142159
->modalHeading(flexiblePagesTrans('menu_items.tree.edit'))
143160
->modalSubmitActionLabel(__('Update'))
144161
->modalWidth('2xl')
145162
->slideOver();
146163
}
147164

165+
public function deleteMenuItemAction(): Action
166+
{
167+
return Action::make('deleteMenuItem')
168+
->requiresConfirmation()
169+
->modalHeading(flexiblePagesTrans('menu_items.tree.delete_confirm_title'))
170+
->modalDescription(flexiblePagesTrans('menu_items.tree.delete_confirm_text'))
171+
->modalSubmitActionLabel(flexiblePagesTrans('menu_items.tree.delete'))
172+
->color('danger')
173+
->action(function (array $arguments): void {
174+
$itemId = $arguments['itemId'] ?? null;
175+
if ($itemId) {
176+
$this->deleteMenuItem($itemId);
177+
}
178+
});
179+
}
180+
148181
protected function getMenuItemFormSchema(): array
149182
{
150183
return MenuItemForm::getSchema();
@@ -718,7 +751,8 @@ public function updateMenuItem(int $itemId, array $data): void
718751

719752
protected function validateMenuItemData(array $data): void
720753
{
721-
if (empty($data['label'])) {
754+
// Label is only required if use_model_title is false
755+
if (empty($data['label']) && !($data['use_model_title'] ?? false)) {
722756
throw new Exception(flexiblePagesTrans('menu_items.form.label_lbl').' is required');
723757
}
724758

0 commit comments

Comments
 (0)