getkirby / kirby

Kirby's core application folder
https://getkirby.com
Other
1.27k stars 167 forks source link

Dynamic options from api fetched on load #6043

Open nilshoerrmann opened 10 months ago

nilshoerrmann commented 10 months ago

Description

When loading options for a tags field from an API, all options are fetched on page load causing the panel to freeze if the received data is huge. My guess is the same applies to other fields with options (select, multiselect …).

Expected behavior
Dynamic options should only be loaded when the filter dialog is opened for the first time.

To reproduce

We are returning a list of icons from our assets folder via a custom route:

    [
        'pattern' => 'icons',
        'action' => function () {
            $path = kirby()->root('assets') . '/icons';
            $icons = Dir::index($path);

            $icons = array_map(function ($icon) use ($path) {
                $info = pathinfo($icon);
                return [
                    'name' => $info['filename'],
                    'icon' => trim(F::read($path . '/' . $icon))
                ];
            }, $icons);

            return Json::encode($icons);
        }
    ]

And are using this route as API endpoint for a tags field:

icons:
  label: Icons
  type: tags
  options:
    type: api
    url: '{{ site.url }}/icons'
    text: '{{ item.name }}'
    value: '{{ item.name }}'

Your setup

Kirby Version
Kirby 4

nilshoerrmann commented 10 months ago

Actually, I think if data is coming from an API, suggestions should the fetched just in time when the user searches. So in our case the filter dialog would best be until the user starts typing the first letters to reduce the amount of options that needs to be displayed.

nilshoerrmann commented 10 months ago

Maybe – for backwards compatibility reasons – this could be handled with a new type that dynamically provides the filter value:

icons:
  label: Icons
  type: tags
  options:
    type: live
    url: '{{ site.url }}/icons?query={{ filter.value }}'
    text: '{{ item.name }}'
    value: '{{ item.name }}'
distantnative commented 9 months ago

I am totally on board with the usefulness. But it's also not trivial as we would need to introduce two different architectures (preloaded, only loaded on the fly). Which is quite the overhead.

I think it's more realistic to refactor the fields in the midterm run to always only lazy-load their options.