dpgaspar / Flask-AppBuilder

Simple and rapid application development framework, built on top of Flask. includes detailed security, auto CRUD generation for your models, google charts and much more. Demo (login with guest/welcome) - http://flaskappbuilder.pythonanywhere.com/
BSD 3-Clause "New" or "Revised" License
4.63k stars 1.35k forks source link

Order of Lists in Multiview #2170

Closed gbrault closed 8 months ago

gbrault commented 9 months ago

The Multiview is displaying views in the order of coding dispite they are declared as a list.

    def list(self):
        pages = get_page_args()
        page_sizes = get_page_size_args()
        orders = get_order_args()
        views_widgets = list()
        for view in self._views:
            if orders.get(view.__class__.__name__):
                order_column, order_direction = orders.get(view.__class__.__name__)
            else:
                order_column, order_direction = "", ""
            page = pages.get(view.__class__.__name__)
            page_size = page_sizes.get(view.__class__.__name__)
            views_widgets.append(
                view._get_view_widget(
                    filters=view._base_filters,
                    order_column=order_column,
                    order_direction=order_direction,
                    page=page,
                    page_size=page_size,
                )
            )
        self.update_redirect()
        return self.render_template(
            self.list_template, views=self._views, views_widgets=views_widgets
        )

it's there

Just change this function with

    def list(self):
        pages = get_page_args()
        page_sizes = get_page_size_args()
        orders = get_order_args()
        views_widgets = list()
        for view in self._views:
            if orders.get(view.__class__.__name__):
                order_column, order_direction = orders.get(view.__class__.__name__)
            else:
                order_column, order_direction = "", ""
            page = pages.get(view.__class__.__name__)
            page_size = page_sizes.get(view.__class__.__name__)
            views_widgets.append(
                view._get_view_widget(
                    filters=view._base_filters,
                    order_column=order_column,
                    order_direction=order_direction,
                    page=page,
                    page_size=page_size,
                )
            )
        # reorder views_widgets (instance) in the same order as self.views (class)
        views_order = [v.__name__ for v in self.views]
        views_widgets = sorted(views_widgets, key=lambda x: views_order.index(x.template_args['modelview_name']))
        # reorder self._views (instance) in the same order as self.views (class)
        _views = sorted(self._views, key=lambda x: views_order.index(x.__class__.__name__))
        return self.render_template(
            self.list_template, views=_views, views_widgets=views_widgets, title=self.title
        )

It will be ordered according to Mutiview declaration

For example

class LesReleves(MultipleView):
    title = "Les Relevés"
    list_template = 'releve/multiple_views.html'
    views = [
        Vue_releve_A_Valider_vsql,
        Vue_releve_A_Confirmer_vsql,
        Vue_releve_OT_ilex_vsql,
        Vue_releve_avant_vente_chiffre_vsql
    ]

Will show the lists according to the views order in this last piece of code

@dpgaspar could you confirm passing _views instead of self._views is ok? Many THANKS.

Yoyasp commented 8 months ago

I had some trouble running your code, but after removing the title=self.title in the render_template function it worked.

return self.render_template(
            self.list_template, views=_views, views_widgets=views_widgets, title=self.title
        )

I see no problem doing it this way, since it doesnt override the self._views

Maybe create a pull request so it has this behaviour by default (but without the title)

gbrault commented 8 months ago

@Yoyasp thanks for your trial. Yes, I maybe added the title which is not part of the original code!

gbrault commented 8 months ago

I can close the request now!