From 0e24aa3d52853d7c2b38059d9ec955d8ac34ba2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 15 Aug 2026 00:02:09 +0000 Subject: [PATCH] a way into the plugin from its detail panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit installing something and then having to guess its url is a small thing that makes the whole flow feel unfinished. the detail panel now links to the plugin's screen. shown only while installed AND enabled, and only when the plugin has a frontend at all. a link to an unmounted route lands on the home page, because the shell redirects an unknown path — which reads as a broken link rather than a plugin that is switched off. a backend-only plugin has no screen to open and gets no link rather than a dead one. Co-Authored-By: Claude Opus 5 --- .../src/apps/Plugins/PluginDetail.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/workspaces/officerdev/src/apps/Plugins/PluginDetail.tsx b/src/workspaces/officerdev/src/apps/Plugins/PluginDetail.tsx index b3eeeaba..d7097f67 100644 --- a/src/workspaces/officerdev/src/apps/Plugins/PluginDetail.tsx +++ b/src/workspaces/officerdev/src/apps/Plugins/PluginDetail.tsx @@ -1,4 +1,4 @@ -import { useSearchParams } from 'react-router'; +import { Link, useSearchParams } from 'react-router'; import { usePlugins, type PluginItem } from './usePlugins'; // The right panel: one plugin, and the four verbs. @@ -105,6 +105,21 @@ export const PluginDetail = () => { + {/* The way in, when there is one. + Only while installed AND enabled: a link to a route that is not mounted is a link to the home + page, since the shell redirects an unknown path — which reads as the link being broken rather + than the plugin being off. `has.web` because a plugin can be entirely backend and have no screen + to open at all. */} + {plugin.installed && plugin.enabled && plugin.has.web ? ( + + Open {plugin.label} + + + ) : null} +
{!plugin.installed ? (