Add links to plugins

This commit is contained in:
Gregory Schier
2025-06-23 09:46:54 -07:00
parent 1948fb78bd
commit a1b1eafd39
6 changed files with 29 additions and 9 deletions

View File

@@ -2,4 +2,4 @@
export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, }; export type PluginMetadata = { version: string, name: string, displayName: string, description: string | null, homepageUrl: string | null, repositoryUrl: string | null, };
export type PluginVersion = { id: string, version: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, }; export type PluginVersion = { id: string, version: string, url: string, description: string | null, name: string, displayName: string, homepageUrl: string | null, repositoryUrl: string | null, checksum: string, readme: string | null, yanked: boolean, };

View File

@@ -1,3 +1,4 @@
use crate::error::Error::ApiErr;
use crate::error::Result; use crate::error::Result;
use crate::plugin_meta::get_plugin_meta; use crate::plugin_meta::get_plugin_meta;
use log::{info, warn}; use log::{info, warn};
@@ -9,7 +10,6 @@ use tauri::{AppHandle, Runtime, is_dev};
use ts_rs::TS; use ts_rs::TS;
use yaak_common::api_client::yaak_api_client; use yaak_common::api_client::yaak_api_client;
use yaak_models::query_manager::QueryManagerExt; use yaak_models::query_manager::QueryManagerExt;
use crate::error::Error::ApiErr;
pub async fn get_plugin<R: Runtime>( pub async fn get_plugin<R: Runtime>(
app_handle: &AppHandle<R>, app_handle: &AppHandle<R>,
@@ -108,6 +108,7 @@ fn base_url(path: &str) -> Url {
pub struct PluginVersion { pub struct PluginVersion {
pub id: String, pub id: String,
pub version: String, pub version: String,
pub url: String,
pub description: Option<String>, pub description: Option<String>,
pub name: String, pub name: String,
pub display_name: String, pub display_name: String,

View File

@@ -52,7 +52,7 @@ pub async fn download_and_install<R: Runtime>(
checked_at: Some(Utc::now().naive_utc()), checked_at: Some(Utc::now().naive_utc()),
directory: plugin_dir_str.clone(), directory: plugin_dir_str.clone(),
enabled: true, enabled: true,
url: None, url: Some(plugin_version.url.clone()),
..Default::default() ..Default::default()
}, },
&UpdateSource::Background, &UpdateSource::Background,

View File

@@ -18,6 +18,7 @@ import { useUninstallPlugin } from '../../hooks/useUninstallPlugin';
import { Button } from '../core/Button'; import { Button } from '../core/Button';
import { IconButton } from '../core/IconButton'; import { IconButton } from '../core/IconButton';
import { InlineCode } from '../core/InlineCode'; import { InlineCode } from '../core/InlineCode';
import { Link } from '../core/Link';
import { LoadingIcon } from '../core/LoadingIcon'; import { LoadingIcon } from '../core/LoadingIcon';
import { PlainInput } from '../core/PlainInput'; import { PlainInput } from '../core/PlainInput';
import { HStack } from '../core/Stacks'; import { HStack } from '../core/Stacks';
@@ -115,7 +116,15 @@ function PluginTableRow({
return ( return (
<TableRow> <TableRow>
<TableCell className="font-semibold">{pluginInfo.data.displayName}</TableCell> <TableCell className="font-semibold">
{plugin.url ? (
<Link noUnderline href={plugin.url}>
{pluginInfo.data.displayName}
</Link>
) : (
pluginInfo.data.displayName
)}
</TableCell>
<TableCell> <TableCell>
<InlineCode>{pluginInfo.data?.version}</InlineCode> <InlineCode>{pluginInfo.data?.version}</InlineCode>
</TableCell> </TableCell>
@@ -187,7 +196,11 @@ function PluginSearch() {
<TableBody> <TableBody>
{results.data.plugins.map((plugin) => ( {results.data.plugins.map((plugin) => (
<TableRow key={plugin.id}> <TableRow key={plugin.id}>
<TableCell className="font-semibold">{plugin.displayName}</TableCell> <TableCell className="font-semibold">
<Link noUnderline href={plugin.url}>
{plugin.displayName}
</Link>
</TableCell>
<TableCell> <TableCell>
<InlineCode>{plugin.version}</InlineCode> <InlineCode>{plugin.version}</InlineCode>
</TableCell> </TableCell>

View File

@@ -6,12 +6,13 @@ import { Icon } from './Icon';
interface Props extends HTMLAttributes<HTMLAnchorElement> { interface Props extends HTMLAttributes<HTMLAnchorElement> {
href: string; href: string;
noUnderline?: boolean;
} }
export function Link({ href, children, className, ...other }: Props) { export function Link({ href, children, noUnderline, className, ...other }: Props) {
const isExternal = href.match(/^https?:\/\//); const isExternal = href.match(/^https?:\/\//);
className = classNames(className, 'relative underline hover:text-violet-600'); className = classNames(className, 'relative');
if (isExternal) { if (isExternal) {
let finalHref = href; let finalHref = href;
@@ -25,13 +26,17 @@ export function Link({ href, children, className, ...other }: Props) {
href={finalHref} href={finalHref}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className={classNames(className, 'pr-4 inline-flex items-center')} className={classNames(
className,
'pr-4 inline-flex items-center hover:underline',
!noUnderline && 'underline',
)}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
}} }}
{...other} {...other}
> >
<span className="underline">{children}</span> <span>{children}</span>
<Icon className="inline absolute right-0.5 top-[0.3em]" size="xs" icon="external_link" /> <Icon className="inline absolute right-0.5 top-[0.3em]" size="xs" icon="external_link" />
</a> </a>
); );

View File

@@ -11,6 +11,7 @@ export function useUninstallPlugin() {
const confirmed = await showConfirmDelete({ const confirmed = await showConfirmDelete({
id: 'uninstall-plugin-' + name, id: 'uninstall-plugin-' + name,
title: 'Uninstall Plugin', title: 'Uninstall Plugin',
confirmText: 'Uninstall',
description: ( description: (
<> <>
Permanently uninstall <InlineCode>{name}</InlineCode>? Permanently uninstall <InlineCode>{name}</InlineCode>?