feat: add team selector to dashboard page header
- Dropdown to assign/unassign dashboard to a team - Updates immediately via PATCH - createDashboard and updateDashboard API now accept team_id Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -16,11 +16,14 @@ import {
|
||||
deleteWidget,
|
||||
getWidgetData,
|
||||
getViews,
|
||||
getTeams,
|
||||
updateDashboard,
|
||||
} from "@/lib/api";
|
||||
import type {
|
||||
Dashboard,
|
||||
DashboardWidget,
|
||||
SavedView,
|
||||
Team,
|
||||
WidgetData,
|
||||
} from "@/lib/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -55,6 +58,7 @@ export default function DashboardPage({ params }: { params: Promise<{ id: string
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [autoRefresh, setAutoRefresh] = useState(false);
|
||||
const [teams, setTeams] = useState<Team[]>([]);
|
||||
|
||||
// Add widget dialog
|
||||
const [addOpen, setAddOpen] = useState(false);
|
||||
@@ -90,9 +94,8 @@ export default function DashboardPage({ params }: { params: Promise<{ id: string
|
||||
|
||||
useEffect(() => {
|
||||
fetchDashboard();
|
||||
getViews().then(({ data }) => {
|
||||
if (data) setViews(data);
|
||||
});
|
||||
getViews().then(({ data }) => { if (data) setViews(data); });
|
||||
getTeams().then(({ data }) => { if (data) setTeams(data); });
|
||||
}, [fetchDashboard]);
|
||||
|
||||
// Auto-refresh: only refresh widget data, not structure
|
||||
@@ -207,9 +210,25 @@ export default function DashboardPage({ params }: { params: Promise<{ id: string
|
||||
Dashboard
|
||||
</div>
|
||||
<h1 className="mt-1 text-xl font-semibold text-foreground">{dashboard.name}</h1>
|
||||
{dashboard.description && (
|
||||
<p className="mt-0.5 text-sm text-muted-foreground">{dashboard.description}</p>
|
||||
)}
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<select
|
||||
value={dashboard.team_id ?? ""}
|
||||
onChange={async (e) => {
|
||||
const teamId = e.target.value || null;
|
||||
await updateDashboard(dashboard.id, { team_id: teamId });
|
||||
setDashboard((prev) => prev ? { ...prev, team_id: teamId } : prev);
|
||||
}}
|
||||
className="h-7 rounded border border-border bg-card px-2 text-xs text-muted-foreground outline-none"
|
||||
>
|
||||
<option value="">No team</option>
|
||||
{teams.map((t) => (
|
||||
<option key={t.id} value={t.id}>{t.name}</option>
|
||||
))}
|
||||
</select>
|
||||
{dashboard.description && (
|
||||
<p className="text-sm text-muted-foreground">{dashboard.description}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
|
||||
@@ -297,6 +297,7 @@ export async function getDashboard(id: string): Promise<{ data: Dashboard | null
|
||||
export async function createDashboard(data: {
|
||||
name: string;
|
||||
description?: string;
|
||||
team_id?: string | null;
|
||||
is_default?: boolean;
|
||||
}): Promise<{ data: Dashboard | null; error: string | null }> {
|
||||
return request<Dashboard>("/dashboards", { method: "POST", body: JSON.stringify(data) });
|
||||
@@ -305,6 +306,7 @@ export async function createDashboard(data: {
|
||||
export async function updateDashboard(id: string, data: {
|
||||
name?: string;
|
||||
description?: string | null;
|
||||
team_id?: string | null;
|
||||
is_default?: boolean;
|
||||
layout?: unknown[];
|
||||
}): Promise<{ data: Dashboard | null; error: string | null }> {
|
||||
|
||||
Reference in New Issue
Block a user