embeddable dashboard

This commit is contained in:
Nate Kelley 2025-03-18 14:19:56 -06:00
parent 178cc86a7e
commit 96731d86d0
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
8 changed files with 34 additions and 24 deletions

View File

@ -1,4 +1,3 @@
import { BusterRoutes } from '@/routes/busterRoutes/busterRoutes';
import axios, { AxiosError } from 'axios';
import { rustErrorHandler } from './buster_rest/errors';
import { AxiosRequestHeaders } from 'axios';

View File

@ -1,11 +1,16 @@
import { DashboardController } from '@/controllers/DashboardController';
'use client';
export default async function EmbedDashboardsPage(props: {
params: Promise<{ dashboardId: string }>;
}) {
const params = await props.params;
import { useGetDashboard } from '@/api/buster_rest/dashboards';
import { CircleSpinnerLoaderContainer } from '@/components/ui/loaders';
import { DashboardViewDashboardController } from '@/controllers/DashboardController/DashboardViewDashboardController';
const { dashboardId } = params;
export default function EmbedDashboardsPage(props: { params: { dashboardId: string } }) {
const { dashboardId } = props.params;
const { isFetched: isFetchedDashboard } = useGetDashboard(dashboardId);
return <DashboardController dashboardId={dashboardId} />;
if (!isFetchedDashboard) {
return <CircleSpinnerLoaderContainer className="min-h-screen" />;
}
return <DashboardViewDashboardController dashboardId={dashboardId} readOnly={true} />;
}

View File

@ -6,7 +6,7 @@ import { MetricViewChart } from '@/controllers/MetricController/MetricViewChart/
export default function EmbedMetricsPage({ params }: { params: { metricId: string } }) {
const { metricId } = params;
const { data, isFetched, error } = useGetMetric(metricId);
const { isFetched } = useGetMetric(metricId);
if (!isFetched) {
return <CircleSpinnerLoaderContainer className="min-h-screen" />;

View File

@ -9,6 +9,7 @@ import { BusterDragColumnMarkers } from './_BusterDragColumnMarkers';
import { calculateColumnSpan, columnSpansToPercent } from './config';
import SplitPane, { Pane } from '../layouts/AppSplitter/SplitPane';
import { cn } from '@/lib/classMerge';
import '../layouts/AppSplitter/splitterStyles.css';
type ContainerProps = {
rowId: string;

View File

@ -8,7 +8,10 @@ import { AddTypeModal } from '@/components/features/modal/AddTypeModal';
import { useMemoizedFn } from '@/hooks';
import { useGetDashboard } from '@/api/buster_rest/dashboards';
export const DashboardController: React.FC<{ dashboardId: string }> = ({ dashboardId }) => {
export const DashboardController: React.FC<{ dashboardId: string; readOnly?: boolean }> = ({
dashboardId,
readOnly = false
}) => {
const { data: dashboardResponse, isFetched: isFetchedDashboard } = useGetDashboard(dashboardId);
const selectedFileView = useChatLayoutContextSelector((x) => x.selectedFileView) || 'dashboard';
const [openAddTypeModal, setOpenAddTypeModal] = useState(false);

View File

@ -10,20 +10,16 @@ export const DashboardEditTitles: React.FC<{
title: string;
onUpdateDashboard: ReturnType<typeof useUpdateDashboard>['mutateAsync'];
description: string;
allowEdit?: boolean;
readOnly?: boolean;
dashboardId: string;
}> = React.memo(({ onUpdateDashboard, allowEdit, title, description, dashboardId }) => {
}> = React.memo(({ onUpdateDashboard, readOnly, title, description, dashboardId }) => {
const onChangeTitle = useMemoizedFn((name: string) => {
onUpdateDashboard({ name, id: dashboardId });
});
const onChangeDescription = useMemoizedFn((description: string) => {
onUpdateDashboard({ description, id: dashboardId });
if (!readOnly) onUpdateDashboard({ name, id: dashboardId });
});
const onChangeDashboardDescription = useMemoizedFn(
(value: React.ChangeEvent<HTMLInputElement>) => {
onChangeDescription(value.target.value);
if (!readOnly) onUpdateDashboard({ description: value.target.value, id: dashboardId });
}
);
@ -31,7 +27,7 @@ export const DashboardEditTitles: React.FC<{
<div className="flex flex-col space-y-0">
<EditableTitle
className="w-full truncate"
disabled={!allowEdit}
readOnly={readOnly}
onChange={onChangeTitle}
id={DASHBOARD_TITLE_INPUT_ID}
placeholder="New Dashboard"
@ -39,11 +35,11 @@ export const DashboardEditTitles: React.FC<{
{title}
</EditableTitle>
{(description || allowEdit) && (
{(description || !readOnly) && (
<Input
variant="ghost"
className={'pl-0!'}
disabled={!allowEdit}
readOnly={readOnly}
onChange={onChangeDashboardDescription}
defaultValue={description}
placeholder="Add description..."

View File

@ -13,14 +13,18 @@ import {
useUpdateDashboardConfig
} from '@/api/buster_rest/dashboards';
export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({ dashboardId }) => {
export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({
dashboardId,
readOnly = false
}) => {
const isAnonymousUser = useUserConfigContextSelector((state) => state.isAnonymousUser);
const { data: dashboardResponse } = useGetDashboard(dashboardId);
const { mutateAsync: onUpdateDashboard } = useUpdateDashboard();
const { mutateAsync: onUpdateDashboardConfig } = useUpdateDashboardConfig();
const [openAddContentModal, setOpenAddContentModal] = useState(false);
const allowEdit = dashboardResponse?.permission !== ShareRole.VIEWER && !isAnonymousUser;
const allowEdit =
!readOnly && dashboardResponse?.permission !== ShareRole.VIEWER && !isAnonymousUser;
const metrics = dashboardResponse?.metrics;
const dashboard = dashboardResponse?.dashboard;
@ -33,7 +37,7 @@ export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({
<DashboardEditTitles
onUpdateDashboard={onUpdateDashboard}
dashboardId={dashboardId}
allowEdit={allowEdit}
readOnly={readOnly}
title={dashboardResponse?.dashboard?.name || ''}
description={dashboardResponse?.dashboard?.description || ''}
/>
@ -43,6 +47,7 @@ export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({
dashboard={dashboard}
onUpdateDashboardConfig={onUpdateDashboardConfig}
onOpenAddContentModal={onOpenAddContentModal}
readOnly={readOnly}
/>
</div>
);

View File

@ -5,6 +5,7 @@ import React from 'react';
export interface DashboardViewProps {
dashboardId: string;
readOnly?: boolean;
}
export const DashboardViewComponents: Record<DashboardFileView, React.FC<DashboardViewProps>> = {