Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

www/caddy: partials bootgrid example implementation #4388

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Monviech
Copy link
Member

@Monviech Monviech commented Dec 6, 2024

This PR is not for merging but rather for discussion of the code.

It aims to generalize the bootgrid table setup.

If this approach seems valuable, I would like to add it to core in some way.

Current status: "Works for me"

@Monviech Monviech self-assigned this Dec 6, 2024
Comment on lines +42 to +58
$formDialogReverseProxy = $this->getForm("dialogReverseProxy");
$this->view->formDialogReverseProxy = $this->preprocessFields($formDialogReverseProxy, 'reverse.');

$formDialogSubdomain = $this->getForm("dialogSubdomain");
$this->view->formDialogSubdomain = $this->preprocessFields($formDialogSubdomain, 'subdomain.');

$formDialogHandle = $this->getForm("dialogHandle");
$this->view->formDialogHandle = $this->preprocessFields($formDialogHandle, 'handle.');

$formDialogAccessList = $this->getForm("dialogAccessList");
$this->view->formDialogAccessList = $this->preprocessFields($formDialogAccessList, 'accesslist.');

$formDialogBasicAuth = $this->getForm("dialogBasicAuth");
$this->view->formDialogBasicAuth = $this->preprocessFields($formDialogBasicAuth, 'basicauth.');

$formDialogHeader = $this->getForm("dialogHeader");
$this->view->formDialogHeader = $this->preprocessFields($formDialogHeader, 'header.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit too much boilerplate for my taste, but I'm sure this can be improved. Can't the form hold the additional argument too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main issue here was this:

<th data-column-id="enabled" data-width="6em" data-type="boolean" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>

data-column-id="enabled"

<id>reverse.enabled</id>

I need to split the id. I could not process that in the template due to restrictions.

Maybe this boilerplate can be centralized at a different spot so I can always receive a data-column-id that has been generated from the id.

Copy link
Member

@fichtner fichtner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symbolic approval here, I think the approach is very nice 👍

a few design decisions regarding form xml need to be made but that's just optics

}

// Sort fields by 'sequence', defaulting to 0 if not set
usort($fields, function ($a, $b) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This here has the side effect to also change the order in the form dialogue. If there should be a /different/ sequence for the columns and the form this solution has to be changed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I tried to do it like this in the .volt template it always crashed. So there are very different possibilities between volt and jinja 2 it seems and I can not sort the same way in the template as e.g.: here:

{% set unsorted_layer4_configs = helpers.toList('Pischem.caddy.reverseproxy.layer4') %}
{# Ensure that 'Sequence' is present and converted to an integer in each item #}
{% for item in unsorted_layer4_configs %}
{% set _ = item.update({'Sequence': item.get('Sequence', '0') | int}) %}
{% endfor %}
{# Sort the configurations based on 'Sequence' #}
{% set layer4_configs = unsorted_layer4_configs | sort(attribute='Sequence') %}

@AdSchellevis
Copy link
Member

I was doubting a bit to offer feedback in the code, but it's probably easier to document my comments and concerns here.

Although I don't mind combining grid fields in forms, we do need to seek a way to explain the fields properly and prevent cluttering functionality.

Consider the following field (which my the way could also be positioned in a [sub]tab)

    <field>
        <id>subnet4.description</id>
        <label>Description</label>
        <type>text</type>
        <help>You may enter a description here for your reference (not parsed).</help>
    </field>

If we add a sequence field here, what does it mean?

So how about positioning the grid properties inside a container, e.g.

    <field>
        <id>subnet4.description</id>
        <label>Description</label>
        <type>text</type>
        <help>You may enter a description here for your reference (not parsed).</help>
        <grid_view>
            <sequence>1</sequence>
        </grid_view>
    </field>

My next issue is more or less a past sin, as getForm() returns a plain list, its difficult to add information for multiple targets (roles). We can use getForm() to extract, but then still need to interpret the results. Which pleads for a separate function to extract the grid[s] from the form definition.

Maybe if we add a getFormGrids() it would be easier to understand the code. My assumption would be that the id identifies the path, we should be able to recursively extract a structure like the following from the definition above:

{
    'subnet4': {
          '0000001.0001': {
               'id': 'description',
                'description': 'Description',
                .....
           }
    }
}

The 0000001.0001 we would generate based on the row number of the record (second part) and the offered sequence for the field.
We can then easily sort all found containers by key.

Obviously we need to feed the output of getFormGrids() to the view in the same way as we would for the form (which means we pass two containers).

I can take a look at building the getFormGrids() method, but not today I'm afraid, maybe it's better to start with a ticket in core if we wish to pursue this further. The idea is practical, I think the bootgrid_tables partial is more or less ok (just needs to be named bootgrid_table as it generates one). There are just details to be filled in at some point (for example how to map types and suppress fields when not relevant at all)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants