fix(web): resolve dashboard widget errors and deployment config #530
12
.env.example
12
.env.example
@@ -79,7 +79,7 @@ OIDC_CLIENT_ID=your-client-id-here
|
|||||||
OIDC_CLIENT_SECRET=your-client-secret-here
|
OIDC_CLIENT_SECRET=your-client-secret-here
|
||||||
# Redirect URI must match what's configured in Authentik
|
# Redirect URI must match what's configured in Authentik
|
||||||
# Development: http://localhost:3001/auth/oauth2/callback/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
|
OIDC_REDIRECT_URI=http://localhost:3001/auth/oauth2/callback/authentik
|
||||||
|
|
||||||
# Authentik PostgreSQL Database
|
# Authentik PostgreSQL Database
|
||||||
@@ -361,17 +361,17 @@ RATE_LIMIT_STORAGE=redis
|
|||||||
# a single workspace.
|
# a single workspace.
|
||||||
MATRIX_HOMESERVER_URL=http://synapse:8008
|
MATRIX_HOMESERVER_URL=http://synapse:8008
|
||||||
MATRIX_ACCESS_TOKEN=
|
MATRIX_ACCESS_TOKEN=
|
||||||
MATRIX_BOT_USER_ID=@mosaic-bot:matrix.example.com
|
MATRIX_BOT_USER_ID=@mosaic-bot:matrix.woltje.com
|
||||||
MATRIX_SERVER_NAME=matrix.example.com
|
MATRIX_SERVER_NAME=matrix.woltje.com
|
||||||
# MATRIX_CONTROL_ROOM_ID=!roomid:matrix.example.com
|
# MATRIX_CONTROL_ROOM_ID=!roomid:matrix.woltje.com
|
||||||
# MATRIX_WORKSPACE_ID=your-workspace-uuid
|
# MATRIX_WORKSPACE_ID=your-workspace-uuid
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Matrix / Synapse Deployment
|
# Matrix / Synapse Deployment
|
||||||
# ======================
|
# ======================
|
||||||
# Domains for Traefik routing to Matrix services
|
# Domains for Traefik routing to Matrix services
|
||||||
MATRIX_DOMAIN=matrix.example.com
|
MATRIX_DOMAIN=matrix.woltje.com
|
||||||
ELEMENT_DOMAIN=chat.example.com
|
ELEMENT_DOMAIN=chat.woltje.com
|
||||||
|
|
||||||
# Synapse database (created automatically by synapse-db-init in the swarm compose)
|
# Synapse database (created automatically by synapse-db-init in the swarm compose)
|
||||||
SYNAPSE_POSTGRES_DB=synapse
|
SYNAPSE_POSTGRES_DB=synapse
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ function LoginPageContent(): ReactElement {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-6 flex justify-center">
|
<div className="mt-6 flex justify-center">
|
||||||
<AuthStatusPill label="Mosaic v0.1" tone="neutral" />
|
<AuthStatusPill label="Mosaic v0.0.20" tone="neutral" />
|
||||||
</div>
|
</div>
|
||||||
</AuthCard>
|
</AuthCard>
|
||||||
</AuthShell>
|
</AuthShell>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useState, useEffect } from "react";
|
|||||||
import { FolderOpen, Bot, Activity, Clock, AlertCircle, CheckCircle2 } from "lucide-react";
|
import { FolderOpen, Bot, Activity, Clock, AlertCircle, CheckCircle2 } from "lucide-react";
|
||||||
import type { WidgetProps } from "@mosaic/shared";
|
import type { WidgetProps } from "@mosaic/shared";
|
||||||
import { apiPost } from "@/lib/api/client";
|
import { apiPost } from "@/lib/api/client";
|
||||||
|
import { useWorkspaceId } from "@/lib/hooks";
|
||||||
|
|
||||||
interface ActiveProject {
|
interface ActiveProject {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -34,6 +35,7 @@ interface AgentSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps): React.JSX.Element {
|
export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps): React.JSX.Element {
|
||||||
|
const workspaceId = useWorkspaceId();
|
||||||
const [projects, setProjects] = useState<ActiveProject[]>([]);
|
const [projects, setProjects] = useState<ActiveProject[]>([]);
|
||||||
const [agentSessions, setAgentSessions] = useState<AgentSession[]>([]);
|
const [agentSessions, setAgentSessions] = useState<AgentSession[]>([]);
|
||||||
const [isLoadingProjects, setIsLoadingProjects] = useState(true);
|
const [isLoadingProjects, setIsLoadingProjects] = useState(true);
|
||||||
@@ -48,7 +50,11 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
|||||||
try {
|
try {
|
||||||
setProjectsError(null);
|
setProjectsError(null);
|
||||||
// Use API client to ensure CSRF token is included
|
// 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);
|
setProjects(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch active projects:", error);
|
console.error("Failed to fetch active projects:", error);
|
||||||
@@ -67,7 +73,7 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
|||||||
return (): void => {
|
return (): void => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [workspaceId]);
|
||||||
|
|
||||||
// Fetch agent chains
|
// Fetch agent chains
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -75,7 +81,11 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
|||||||
try {
|
try {
|
||||||
setAgentsError(null);
|
setAgentsError(null);
|
||||||
// Use API client to ensure CSRF token is included
|
// 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);
|
setAgentSessions(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch agent sessions:", error);
|
console.error("Failed to fetch agent sessions:", error);
|
||||||
@@ -94,7 +104,7 @@ export function ActiveProjectsWidget({ id: _id, config: _config }: WidgetProps):
|
|||||||
return (): void => {
|
return (): void => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [workspaceId]);
|
||||||
|
|
||||||
const getStatusIcon = (status: string): React.JSX.Element => {
|
const getStatusIcon = (status: string): React.JSX.Element => {
|
||||||
const statusUpper = status.toUpperCase();
|
const statusUpper = status.toUpperCase();
|
||||||
|
|||||||
@@ -176,6 +176,9 @@ services:
|
|||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
PORT: ${WEB_PORT:-3000}
|
PORT: ${WEB_PORT:-3000}
|
||||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
|
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:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
@@ -187,6 +190,7 @@ services:
|
|||||||
retries: 3
|
retries: 3
|
||||||
start_period: 40s
|
start_period: 40s
|
||||||
networks:
|
networks:
|
||||||
|
- internal
|
||||||
- traefik-public
|
- traefik-public
|
||||||
deploy:
|
deploy:
|
||||||
restart_policy:
|
restart_policy:
|
||||||
|
|||||||
Reference in New Issue
Block a user