Skip to content

Apps Grid

components.apps_grid

App launcher grid component.

AppsGrid

Bases: Component

A grid component for displaying available apps with search functionality.

Parameters:

Name Type Description Default
key str

Key to get the apps dict from kwargs

'apps'
Source code in components/apps_grid.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@UIRegistry.register("lariv.AppsGrid")
class AppsGrid(Component):
    """
    A grid component for displaying available apps with search functionality.

    Parameters:
        key: Key to get the apps dict from kwargs
    """

    def __init__(self, key: str = "apps", **kwargs):
        super().__init__(key=key, **kwargs)
        self.key = key

    def render_html(self, **kwargs) -> str:
        apps = kwargs.get(self.key, {})

        if not apps:
            return """
            <div id="app-layout" class="container max-w-5xl mx-auto p-6">
                <div class="alert alert-warning">
                    <span>No apps available</span>
                </div>
            </div>
            """

        app_cards = ""

        for app_name, app in apps.items():
            if app.get("p_type") not in ["app", "core"]:
                continue

            icon = app.get("icon", "cube")
            verbose_name = app.get("verbose_name", app_name)
            url = app.get("url", "#")

            app_cards += f"""
            <a hx-get="{url}" href="{url}" class="btn btn-md h-auto flex-col space-y-1 py-4"
                hx-target="#app-layout" hx-swap="outerHTML"
                x-show="'{verbose_name}'.toLowerCase().includes(search.toLowerCase())" x-cloak>
                {{% heroicon_outline "{icon}" class="w-8 h-8" %}}
                <div class="text-sm truncate min-w-0 w-full">{verbose_name}</div>
            </a>
            """

        return f"""
        <div class="container max-w-5xl mx-auto p-6 @container {self.classes}" x-data="{{ search: '' }}">
            <div class="mb-4">
                <input type="text" x-model="search" placeholder="Search apps..." class="input input-bordered w-full" />
            </div>
            <div class="grid grid-cols-2 @md:grid-cols-4 @2xl:grid-cols-6 gap-2" hx-boost>
                {app_cards}
            </div>
        </div>
        """