Dashboard mit Link auf ein anderes Dashboard

so nun aber

nano ~/local/lib/check_mk/gui/plugins/dashboard/link_dashlet.py
Code Dashlet

`

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Check_MK 2.4 Compatible Link Dashlet

Creates clickable links/buttons to other dashboards, external URLs, or views.

Install to: local/lib/check_mk/gui/plugins/dashboard/link_dashlet.py
(Note the different path for CMK 2.4!)
"""

from cmk.gui.i18n import _
from cmk.gui.type_defs import HTTPVariables
from cmk.gui.htmllib.html import html
from cmk.gui.utils.html import HTML
from cmk.gui.valuespec import (
    CascadingDropdown,
    Dictionary,
    DropdownChoice,
    TextInput,
    TextAreaUnicode,
)

# Menu entry from helper library
import cmk.gui.dashboard.page_show_dashboard
from cmk.plugins.dashlets.other_dashlet_entries import my_dashboard_add_other_dashlet_entries
cmk.gui.dashboard.page_show_dashboard._dashboard_add_other_dashlet_entries = my_dashboard_add_other_dashlet_entries

try:
    # Check_MK 2.4 API
    from cmk.gui.dashboard.dashlet import Dashlet, dashlet_registry
    from cmk.gui.dashboard.type_defs import DashletConfig, DashletId
except ImportError:
    # Fallback for older versions
    from cmk.gui.plugins.dashboard.utils import Dashlet, dashlet_registry


@dashlet_registry.register
class LinkDashlet(Dashlet):
    """Dashlet that displays a clickable link/button"""

    @classmethod
    def type_name(cls):
        return "link_dashlet"

    @classmethod
    def title(cls):
        return _("Link / Button")

    @classmethod
    def description(cls):
        return _("Clickable link or button to dashboard, view, or URL")

    @classmethod
    def sort_index(cls):
        return 10

    @classmethod
    def initial_size(cls):
        return (20, 10)

    @classmethod
    def is_resizable(cls):
        return True

    @classmethod
    def initial_refresh_interval(cls):
        return False  # No refresh needed

    @classmethod
    def vs_parameters(cls):
        return Dictionary(
            title=_("Properties"),
            render="form",
            optional_keys=["description", "icon"],
            elements=[
                (
                    "link_type",
                    CascadingDropdown(
                        title=_("Link Type"),
                        choices=[
                            (
                                "dashboard",
                                _("Check_MK Dashboard"),
                                TextInput(
                                    title=_("Dashboard Name"),
                                    help=_("Name of the dashboard (from URL: dashboard.py?name=XXX)"),
                                    size=40,
                                ),
                            ),
                            (
                                "view",
                                _("Check_MK View"),
                                TextInput(
                                    title=_("View Name"),
                                    help=_("Name of the view (e.g., allhosts, allservices)"),
                                    size=40,
                                ),
                            ),
                            (
                                "url",
                                _("External URL"),
                                Dictionary(
                                    elements=[
                                        (
                                            "url",
                                            TextInput(
                                                title=_("URL"),
                                                help=_("Full URL (must start with http:// or https://)"),
                                                size=60,
                                            ),
                                        ),
                                        (
                                            "open_new",
                                            DropdownChoice(
                                                title=_("Open in"),
                                                choices=[
                                                    (False, _("Same window")),
                                                    (True, _("New window/tab")),
                                                ],
                                                default_value=True,
                                            ),
                                        ),
                                    ],
                                    optional_keys=[],
                                ),
                            ),
                            (
                                "iframe",
                                _("Embedded (iframe)"),
                                TextInput(
                                    title=_("URL to embed"),
                                    help=_("URL to embed in iframe. Note: Not all sites allow embedding."),
                                    size=60,
                                ),
                            ),
                        ],
                        default_value=("dashboard", "main"),
                    ),
                ),
                (
                    "link_title",
                    TextInput(
                        title=_("Link Title"),
                        help=_("Text displayed on the button"),
                        size=40,
                        allow_empty=False,
                        default_value="Link",
                    ),
                ),
                (
                    "link_description",
                    TextAreaUnicode(
                        title=_("Description (optional)"),
                        help=_("Additional text shown below title"),
                        rows=2,
                        cols=40,
                    ),
                ),
                (
                    "link_style",
                    DropdownChoice(
                        title=_("Display Style"),
                        choices=[
                            ("button", _("Large Button")),
                            ("card", _("Card")),
                            ("minimal", _("Minimal")),
                        ],
                        default_value="button",
                    ),
                ),
                (
                    "link_icon",
                    DropdownChoice(
                        title=_("Icon"),
                        choices=[
                            ("", _("No icon")),
                            ("📊", "📊 Dashboard"),
                            ("🖥️", "🖥️ Server"),
                            ("📈", "📈 Graph"),
                            ("🔍", "🔍 Search"),
                            ("⚙️", "⚙️ Settings"),
                            ("🌐", "🌐 Network"),
                            ("📡", "📡 Wireless"),
                            ("🚀", "🚀 Launch"),
                            ("⚡", "⚡ Fast"),
                            ("📋", "📋 List"),
                        ],
                        default_value="📊",
                    ),
                ),
                (
                    "link_color",
                    DropdownChoice(
                        title=_("Color Theme"),
                        choices=[
                            ("blue", _("Blue")),
                            ("green", _("Green")),
                            ("purple", _("Purple")),
                            ("orange", _("Orange")),
                            ("red", _("Red")),
                        ],
                        default_value="blue",
                    ),
                ),
            ],
        )

    def _get_link_data(self):
        """Get URL and target based on configuration"""
        link_config = self._dashlet_spec.get("link_type", ("dashboard", "main"))
        link_type = link_config[0]
        link_value = link_config[1]
        
        if link_type == "dashboard":
            url = f"dashboard.py?name={link_value}"
            target = "_self"
            is_iframe = False
        elif link_type == "view":
            url = f"view.py?view_name={link_value}"
            target = "_self"
            is_iframe = False
        elif link_type == "url":
            url = link_value.get("url", "#")
            target = "_blank" if link_value.get("open_new", True) else "_self"
            is_iframe = False
        elif link_type == "iframe":
            url = link_value
            target = None
            is_iframe = True
        else:
            url = "#"
            target = "_self"
            is_iframe = False
        
        return url, target, is_iframe

    def show(self):
        """Render the dashlet"""
        title = self._dashlet_spec.get("link_title", "Link")
        description = self._dashlet_spec.get("link_description", "")
        style = self._dashlet_spec.get("link_style", "button")
        icon = self._dashlet_spec.get("link_icon", "")
        color = self._dashlet_spec.get("link_color", "blue")
        
        url, target, is_iframe = self._get_link_data()
        
        # Color mappings
        color_map = {
            "blue": ("667eea", "764ba2"),
            "green": ("11998e", "38ef7d"),
            "purple": ("a8edea", "fed6e3"),
            "orange": ("f093fb", "f5576c"),
            "red": ("fa709a", "fee140"),
        }
        
        c1, c2 = color_map.get(color, ("667eea", "764ba2"))
        
# Styles
        html.open_div(style="height: 100%; padding: 0; margin: 0;")

        html.write_html(f"""
        <style>
            .link-dashlet-{self.dashlet_id} {{
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 20px;
                box-sizing: border-box;
                font-family: inherit;
            }}

            /* Gemeinsame Basis für den Link */
            .link-dashlet-{self.dashlet_id} a {{
                text-decoration: none;
                color: white;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                width: 100%;
                height: 100%;
                border-radius: 12px;
                background: linear-gradient(135deg, #{c1} 0%, #{c2} 100%);
                transition: all 0.3s ease;
                box-sizing: border-box;
                text-align: center;
            }}

            .link-dashlet-{self.dashlet_id} a:hover {{
                transform: translateY(-6px);
                box-shadow: 0 12px 25px rgba(0,0,0,0.25);
            }}

            /* Icon und Textgrößen */
            .link-dashlet-{self.dashlet_id} .icon {{
                font-size: 48px;
                margin-bottom: 12px;
            }}
            .link-dashlet-{self.dashlet_id} .title {{
                font-weight: bold;
                margin-bottom: 6px;
            }}
            .link-dashlet-{self.dashlet_id} .desc {{
                font-size: 13px;
                opacity: 0.9;
                line-height: 1.3;
            }}

            /* STYLE: Large Button */
            .style-button a {{
                padding: 30px;
                font-size: 22px;
                box-shadow: 0 8px 20px rgba(0,0,0,0.2);
            }}
            .style-button .title {{
                font-size: 24px;
            }}
            .style-button .icon {{
                font-size: 60px;
            }}

            /* STYLE: Card */
            .style-card a {{
                padding: 20px;
                box-shadow: 0 6px 15px rgba(0,0,0,0.15);
                border: 1px solid rgba(255,255,255,0.2);
            }}
            .style-card .title {{
                font-size: 20px;
            }}
            .style-card .icon {{
                font-size: 50px;
            }}

            /* STYLE: Minimal */
            .style-minimal a {{
                background: none !important;
                color: #333 !important;
                padding: 10px;
                border-radius: 8px;
            }}
            .style-minimal a:hover {{
                background: rgba(0,0,0,0.05) !important;
                transform: none;
                box-shadow: none;
            }}
            .style-minimal .icon {{
                font-size: 32px;
                margin-bottom: 8px;
            }}
            .style-minimal .title {{
                font-size: 16px;
                color: #333;
            }}
            .style-minimal .desc {{
                font-size: 12px;
                color: #666;
            }}

            /* iFrame immer vollflächig, unabhängig vom Style */
            .link-dashlet-{self.dashlet_id} iframe {{
                width: 100%;
                height: 100%;
                border: none;
                border-radius: 8px;
            }}
        </style>
        """)

        if is_iframe:
            # iFrame immer gleich darstellen
            html.write_html(HTML(f"""
            <div class="link-dashlet-{self.dashlet_id}" style="padding: 0;">
                <iframe src="{html.attrencode(url)}" allowfullscreen></iframe>
            </div>
            """))
        else:
            # Link/Button/Card/Minimal
            style_class = f"style-{style}"

            html.open_div(class_=f"link-dashlet-{self.dashlet_id} {style_class}")
            html.open_a(href=url, target=target if target else None)

            if icon:
                html.div(icon, class_="icon")
            html.div(title, class_="title")
            if description:
                html.div(description, class_="desc")

            html.close_a()
            html.close_div()

        html.close_div()

`

zusätzlich falls der Menüpunkt nicht im Add Menü von Dashboard auftaucht:

nano ~/local/lib/check_mk/plugins/dashlets/other_dashlet_entries.py
Code
#!/usr/bin/env python3

from cmk.gui.dashboard.page_show_dashboard import _dashboard_add_non_view_dashlet_link
from cmk.gui.page_menu import PageMenuEntry, PageMenu
from cmk.gui.dashboard.type_defs import DashboardName
from collections.abc import Iterable

def my_dashboard_add_other_dashlet_entries(name: DashboardName) -> Iterable[PageMenuEntry]:
    yield PageMenuEntry(
        title="Custom URL",
        icon_name="dashlet_url",
        item=_dashboard_add_non_view_dashlet_link(name, "url"),
    )

    yield PageMenuEntry(
        title="Static text",
        icon_name="dashlet_nodata",
        item=_dashboard_add_non_view_dashlet_link(name, "nodata"),
    )

    yield PageMenuEntry(
        title="LinkDashlet",
        icon_name="view_copy",
        item=_dashboard_add_non_view_dashlet_link(name, "link_dashlet"),
    )

Danke auch an @StefanM und @ChristianM