filament-tree icon indicating copy to clipboard operation
filament-tree copied to clipboard

Allow sort model data customisation

Open assertchris opened this issue 1 year ago • 0 comments

Howdy!

Firstly, thank you for making this plugin; it's super cool.

We're using it in a project, at work, and one of the things we wanna do is set stuff in the tree view without opening the model. Quick things, like which platforms the API should return this tree item for...

Screenshot 2024-02-26 at 07 20 47

(Please forgive the horrible MVP UI 😅)

I started by trying to have Alpine bind data-* attributes to the values of those inputs, and nestable dutifully passed those to Livewire. Then I noticed that after the first serialize() call, the values weren't updating. Turns out jQuery's data() function caches in an internal store so the data-* attributes are never updated after the first serialize().

I introduced the attrs() function, which fetches them from attributes instead of data().

The next issue was getting Livewire to write the new db fields. To this end, I added a bit of a hook into the InteractsWithTree concern:

public function beforeUpdateTree(array $data): void
{
    $this->online_at = data_get($data, 'onlineAt');
    $this->offline_at = data_get($data, 'offlineAt');
    $this->show_on_desktop = data_get($data, 'showOnDesktop', false);
    $this->show_on_mobile = data_get($data, 'showOnMobile', false);
    $this->show_on_app = data_get($data, 'showOnApp', false);
}

This is from app/Models/MenuItem.php

If this method exists on the model, during the call to updateTree(), it will be called before the model is saved. This allows someone to set fields based on the array data coming from the modified serialize() call.

My tree item template has the following snippets:

<li
    class="filament-tree-row dd-item"
    x-data="{
        id: '{{ $recordKey }}',
        online_at: {{ $record->online_at ? "'" . $record->online_at->format('Y-m-d\TH:i') . "'" : 'null' }},
        offline_at: {{ $record->offline_at ? "'" . $record->offline_at->format('Y-m-d\TH:i') . "'" : 'null' }},
        show_on_desktop: {{ $record->show_on_desktop ? 'true' : 'false' }},
        show_on_mobile: {{ $record->show_on_mobile ? 'true' : 'false' }},
        show_on_app: {{ $record->show_on_app ? 'true' : 'false' }},
    }"
    x-bind:data-id="id"
    x-bind:data-online-at="online_at"
    x-bind:data-offline-at="offline_at"
    x-bind:data-show-on-desktop="show_on_desktop"
    x-bind:data-show-on-mobile="show_on_mobile"
    x-bind:data-show-on-app="show_on_app"
>

This is from resources/views/vendor/filament-tree/components/tree/item.blade.php

<x-publish-configuration
    online-model="online_at"
    offline-model="offline_at"
/>
<x-platform-configuration
    desktop-model="show_on_desktop"
    mobile-model="show_on_mobile"
    app-model="show_on_app"
/>

This is from resources/views/vendor/filament-tree/components/tree/item.blade.php

Other than the changes to the vendor view file, and the additions to the nestable plugin script + InteractsWithTree concern; these were the only changes I needed to make to achieve saving and loading of custom data straight from the tree view.

Hope you like the change.

assertchris avatar Feb 26 '24 05:02 assertchris