Improve Directory pages.
This commit is contained in:
@@ -428,8 +428,8 @@ func (api *API) AppsGetAvailableReadme(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
readmePath := filepath.Join(api.appsDir, appName, "README.md")
|
||||
content, err := os.ReadFile(readmePath)
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
content, err := appsMgr.GetCatalogReadme(appName)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("README not found for app '%s'", appName))
|
||||
|
||||
@@ -1501,6 +1501,20 @@ func (m *Manager) GetEnhancedStatus(instanceName, appName string) (*RuntimeStatu
|
||||
return m.getRuntimeStatus(kubeconfigPath, namespace)
|
||||
}
|
||||
|
||||
// GetCatalogReadme returns the README.md content for an available app from the catalog directory.
|
||||
func (m *Manager) GetCatalogReadme(appName string) ([]byte, error) {
|
||||
if m.appsDir == "" {
|
||||
return nil, fmt.Errorf("apps directory not configured")
|
||||
}
|
||||
|
||||
appDir, _, err := m.resolveAppDir(appName, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return os.ReadFile(filepath.Join(appDir, "README.md"))
|
||||
}
|
||||
|
||||
// GetAppManifest reads and parses the manifest.yaml for an app from the apps directory
|
||||
func (m *Manager) GetAppManifest(appName string) (*AppManifest, error) {
|
||||
if m.appsDir == "" {
|
||||
|
||||
@@ -201,10 +201,6 @@ export function AppsComponent({ infrastructureOnly = false }: AppsComponentProps
|
||||
|
||||
const hasInfraApps = installedApps.some(app => app.category === 'infrastructure');
|
||||
|
||||
// Running count scoped to this view's filtered apps
|
||||
const runningApps = baseApps
|
||||
.filter(app => app.deploymentStatus === 'deployed' && liveStatuses[app.name] === 'running').length;
|
||||
|
||||
if (!currentInstance) {
|
||||
return (
|
||||
<Card className="p-8 text-center">
|
||||
@@ -247,7 +243,7 @@ export function AppsComponent({ infrastructureOnly = false }: AppsComponentProps
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{!infrastructureOnly && (
|
||||
<Button variant="outline" asChild>
|
||||
<Button asChild>
|
||||
<Link to={`/instances/${currentInstance}/app-directory`}>
|
||||
<LayoutGrid className="h-4 w-4 mr-2" />
|
||||
Browse Directory
|
||||
@@ -299,16 +295,6 @@ export function AppsComponent({ infrastructureOnly = false }: AppsComponentProps
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{isLoading ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
Loading...
|
||||
</span>
|
||||
) : (
|
||||
`${runningApps} running · ${baseApps.length} installed`
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{isLoading ? (
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
Settings,
|
||||
} from 'lucide-react';
|
||||
import { useInstanceContext } from '../../hooks/useInstanceContext';
|
||||
import { useAvailableApps, useDeployedApps, useAppStatuses } from '../../hooks/useApps';
|
||||
import { useAvailableApps, useDeployedApps } from '../../hooks/useApps';
|
||||
import { useSetupStatus } from '../../services/api';
|
||||
import { usePageHelp } from '../../hooks/usePageHelp';
|
||||
import { ErrorBoundary } from '../../components';
|
||||
@@ -135,12 +135,6 @@ function AppDirectoryContent() {
|
||||
appCategories.sort();
|
||||
const categories = infraOnly ? ['infrastructure'] : ['all', ...appCategories];
|
||||
|
||||
// Stats
|
||||
const installedApps = applications.filter(a => a.deploymentStatus);
|
||||
const deployedAppNames = installedApps.filter(a => a.deploymentStatus === 'deployed').map(a => a.name);
|
||||
const liveStatuses = useAppStatuses(currentInstance, deployedAppNames);
|
||||
const runningApps = deployedAppNames.filter(name => liveStatuses[name] === 'running').length;
|
||||
|
||||
// Filter
|
||||
const sortedApps = [...applications].sort((a, b) => a.name.localeCompare(b.name));
|
||||
const filteredApps = sortedApps.filter(app => {
|
||||
@@ -218,17 +212,7 @@ function AppDirectoryContent() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{isLoading ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
Loading apps...
|
||||
</span>
|
||||
) : (
|
||||
`${runningApps} running · ${installedApps.length} installed · ${applications.length} in directory`
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-end">
|
||||
<Button
|
||||
variant={hideInstalled ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
|
||||
Reference in New Issue
Block a user