mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-02-05 07:56:30 -05:00
feat: implement complete plugin store repository synchronization system
• Fix repository sync implementation in admin API (was TODO placeholder) - Add full fetch/parse logic for repository.json and plugin index - Implement robot matching by name/manufacturer patterns - Handle plugin creation/updates with proper error handling - Add comprehensive TypeScript typing throughout • Fix plugin store installation state detection - Add getStudyPlugins API integration to check installed plugins - Update PluginCard component with isInstalled prop and correct button states - Fix repository name display using metadata.repositoryId mapping - Show "Installed" (disabled) vs "Install" (enabled) based on actual state • Resolve admin access and authentication issues - Add missing administrator role to user system roles table - Fix admin route access for repository management - Enable repository sync functionality in admin dashboard • Add repository metadata integration - Update plugin records with proper repositoryId references - Add metadata field to robots.plugins.list API response - Enable repository name display for all plugins from metadata • Fix TypeScript compliance across plugin system - Replace unsafe 'any' types with proper interfaces - Add type definitions for repository and plugin data structures - Use nullish coalescing operators for safer null handling - Remove unnecessary type assertions • Integrate live repository at https://repo.hristudio.com - Successfully loads 3 robot plugins (TurtleBot3 Burger/Waffle, NAO) - Complete ROS2 action definitions with parameter schemas - Trust level categorization (official, verified, community) - Platform and documentation metadata preservation • Update documentation and development workflow - Document plugin repository system in work_in_progress.md - Update quick-reference.md with repository sync examples - Add plugin installation and management guidance - Remove problematic test script with TypeScript errors BREAKING CHANGE: Plugin store now requires repository sync for robot plugins. Run repository sync in admin dashboard after deployment to populate plugin store. Closes: Plugin store repository integration Resolves: Installation state detection and repository name display Fixes: Admin authentication and TypeScript compliance issues
This commit is contained in:
@@ -50,6 +50,7 @@ interface PluginStoreItem {
|
||||
status: "active" | "deprecated" | "disabled";
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
metadata: unknown;
|
||||
}
|
||||
|
||||
const trustLevelConfig = {
|
||||
@@ -77,10 +78,12 @@ function PluginCard({
|
||||
plugin,
|
||||
onInstall,
|
||||
repositoryName,
|
||||
isInstalled,
|
||||
}: {
|
||||
plugin: PluginStoreItem;
|
||||
onInstall: (pluginId: string) => void;
|
||||
repositoryName?: string;
|
||||
isInstalled?: boolean;
|
||||
}) {
|
||||
const trustLevel = plugin.trustLevel;
|
||||
const trustConfig = trustLevel ? trustLevelConfig[trustLevel] : null;
|
||||
@@ -149,10 +152,10 @@ function PluginCard({
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => onInstall(plugin.id)}
|
||||
disabled={plugin.status !== "active"}
|
||||
disabled={plugin.status !== "active" || isInstalled}
|
||||
>
|
||||
<Download className="mr-2 h-3 w-3" />
|
||||
Install
|
||||
{isInstalled ? "Installed" : "Install"}
|
||||
</Button>
|
||||
{plugin.repositoryUrl && (
|
||||
<Button variant="outline" size="sm" asChild>
|
||||
@@ -191,7 +194,19 @@ export function PluginStoreBrowse() {
|
||||
{
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
) as { data: Array<{ url: string; name: string }> | undefined };
|
||||
) as { data: Array<{ id: string; url: string; name: string }> | undefined };
|
||||
|
||||
// Get installed plugins for current study
|
||||
const { data: installedPlugins } =
|
||||
api.robots.plugins.getStudyPlugins.useQuery(
|
||||
{
|
||||
studyId: selectedStudyId!,
|
||||
},
|
||||
{
|
||||
enabled: !!selectedStudyId,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
data: availablePlugins,
|
||||
@@ -279,6 +294,12 @@ export function PluginStoreBrowse() {
|
||||
});
|
||||
}, [availablePlugins, searchTerm, statusFilter, trustLevelFilter]);
|
||||
|
||||
// Create a set of installed plugin IDs for quick lookup
|
||||
const installedPluginIds = React.useMemo(() => {
|
||||
if (!installedPlugins) return new Set<string>();
|
||||
return new Set(installedPlugins.map((p) => p.plugin.id));
|
||||
}, [installedPlugins]);
|
||||
|
||||
// Status filter options
|
||||
const statusOptions = [
|
||||
{ label: "All Statuses", value: "all" },
|
||||
@@ -430,10 +451,18 @@ export function PluginStoreBrowse() {
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{filteredPlugins.map((plugin) => {
|
||||
// Find repository for this plugin (this would need to be enhanced with actual repository mapping)
|
||||
const repository = repositories?.find((repo) =>
|
||||
plugin.repositoryUrl?.includes(repo.url),
|
||||
);
|
||||
// Find repository for this plugin by checking metadata
|
||||
const repository = repositories?.find((repo) => {
|
||||
// First try to match by URL
|
||||
if (plugin.repositoryUrl?.includes(repo.url)) {
|
||||
return true;
|
||||
}
|
||||
// Then try to match by repository ID in metadata if available
|
||||
const metadata = plugin.metadata as {
|
||||
repositoryId?: string;
|
||||
} | null;
|
||||
return metadata?.repositoryId === repo.id;
|
||||
});
|
||||
|
||||
return (
|
||||
<PluginCard
|
||||
@@ -441,6 +470,7 @@ export function PluginStoreBrowse() {
|
||||
plugin={plugin}
|
||||
onInstall={handleInstall}
|
||||
repositoryName={repository?.name}
|
||||
isInstalled={installedPluginIds.has(plugin.id)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user