fix(web): resolve dashboard widget errors and deployment config
All checks were successful
ci/woodpecker/push/web Pipeline was successful
All checks were successful
ci/woodpecker/push/web Pipeline was successful
- Add workspace ID to ActiveProjectsWidget API calls (fixes 401/403) - Add ORCHESTRATOR_URL and ORCHESTRATOR_API_KEY to web service in swarm compose (fixes 503 on orchestrator proxy routes) - Add internal network to web service for orchestrator connectivity - Update .env.example domain examples to single-level subdomains - Fix version display on login page from v0.1 to v0.0.20 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
.env.example
12
.env.example
@@ -79,7 +79,7 @@ OIDC_CLIENT_ID=your-client-id-here
|
||||
OIDC_CLIENT_SECRET=your-client-secret-here
|
||||
# Redirect URI must match what's configured in Authentik
|
||||
# Development: http://localhost:3001/auth/oauth2/callback/authentik
|
||||
# Production: https://api.mosaicstack.dev/auth/oauth2/callback/authentik
|
||||
# Production: https://mosaic-api.woltje.com/auth/oauth2/callback/authentik
|
||||
OIDC_REDIRECT_URI=http://localhost:3001/auth/oauth2/callback/authentik
|
||||
|
||||
# Authentik PostgreSQL Database
|
||||
@@ -361,17 +361,17 @@ RATE_LIMIT_STORAGE=redis
|
||||
# a single workspace.
|
||||
MATRIX_HOMESERVER_URL=http://synapse:8008
|
||||
MATRIX_ACCESS_TOKEN=
|
||||
MATRIX_BOT_USER_ID=@mosaic-bot:matrix.example.com
|
||||
MATRIX_SERVER_NAME=matrix.example.com
|
||||
# MATRIX_CONTROL_ROOM_ID=!roomid:matrix.example.com
|
||||
MATRIX_BOT_USER_ID=@mosaic-bot:matrix.woltje.com
|
||||
MATRIX_SERVER_NAME=matrix.woltje.com
|
||||
# MATRIX_CONTROL_ROOM_ID=!roomid:matrix.woltje.com
|
||||
# MATRIX_WORKSPACE_ID=your-workspace-uuid
|
||||
|
||||
# ======================
|
||||
# Matrix / Synapse Deployment
|
||||
# ======================
|
||||
# Domains for Traefik routing to Matrix services
|
||||
MATRIX_DOMAIN=matrix.example.com
|
||||
ELEMENT_DOMAIN=chat.example.com
|
||||
MATRIX_DOMAIN=matrix.woltje.com
|
||||
ELEMENT_DOMAIN=chat.woltje.com
|
||||
|
||||
# Synapse database (created automatically by synapse-db-init in the swarm compose)
|
||||
SYNAPSE_POSTGRES_DB=synapse
|
||||
|
||||
@@ -326,7 +326,7 @@ function LoginPageContent(): ReactElement {
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-center">
|
||||
<AuthStatusPill label="Mosaic v0.1" tone="neutral" />
|
||||
<AuthStatusPill label="Mosaic v0.0.20" tone="neutral" />
|
||||
</div>
|
||||
</AuthCard>
|
||||
</AuthShell>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useState, useEffect } from "react";
|
||||
import { FolderOpen, Bot, Activity, Clock, AlertCircle, CheckCircle2 } from "lucide-react";
|
||||
import type { WidgetProps } from "@mosaic/shared";
|
||||
import { apiPost } from "@/lib/api/client";
|
||||
import { useWorkspaceId } from "@/lib/hooks";
|
||||
|
||||
interface ActiveProject {
|
||||
id: string;
|
||||
@@ -34,6 +35,7 @@ interface AgentSession {
|
||||
}
|
||||
|
||||
export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps): React.JSX.Element {
|
||||
const workspaceId = useWorkspaceId();
|
||||
const [projects, setProjects] = useState<ActiveProject[]>([]);
|
||||
const [agentSessions, setAgentSessions] = useState<AgentSession[]>([]);
|
||||
const [isLoadingProjects, setIsLoadingProjects] = useState(true);
|
||||
@@ -48,7 +50,11 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
||||
try {
|
||||
setProjectsError(null);
|
||||
// Use API client to ensure CSRF token is included
|
||||
const data = await apiPost<ActiveProject[]>("/api/widgets/data/active-projects");
|
||||
const data = await apiPost<ActiveProject[]>(
|
||||
"/api/widgets/data/active-projects",
|
||||
undefined,
|
||||
workspaceId ?? undefined
|
||||
);
|
||||
setProjects(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch active projects:", error);
|
||||
@@ -67,7 +73,7 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
||||
return (): void => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
}, [workspaceId]);
|
||||
|
||||
// Fetch agent chains
|
||||
useEffect(() => {
|
||||
@@ -75,7 +81,11 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
||||
try {
|
||||
setAgentsError(null);
|
||||
// Use API client to ensure CSRF token is included
|
||||
const data = await apiPost<AgentSession[]>("/api/widgets/data/agent-chains");
|
||||
const data = await apiPost<AgentSession[]>(
|
||||
"/api/widgets/data/agent-chains",
|
||||
undefined,
|
||||
workspaceId ?? undefined
|
||||
);
|
||||
setAgentSessions(data);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch agent sessions:", error);
|
||||
@@ -94,7 +104,7 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
||||
return (): void => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
}, [workspaceId]);
|
||||
|
||||
const getStatusIcon = (status: string): React.JSX.Element => {
|
||||
const statusUpper = status.toUpperCase();
|
||||
|
||||
@@ -176,6 +176,9 @@ services:
|
||||
NODE_ENV: production
|
||||
PORT: ${WEB_PORT:-3000}
|
||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
|
||||
# Server-side orchestrator proxy (API routes forward to orchestrator service)
|
||||
ORCHESTRATOR_URL: http://orchestrator:3001
|
||||
ORCHESTRATOR_API_KEY: ${ORCHESTRATOR_API_KEY}
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
@@ -187,6 +190,7 @@ services:
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
networks:
|
||||
- internal
|
||||
- traefik-public
|
||||
deploy:
|
||||
restart_policy:
|
||||
|
||||
Reference in New Issue
Block a user