make loaders for all pages

This commit is contained in:
Nate Kelley 2025-03-28 13:16:39 -06:00
parent 8732e895c7
commit a3333b2c94
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
13 changed files with 60 additions and 25 deletions

View File

@ -0,0 +1,5 @@
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
export default function Loading() {
return <FileIndeterminateLoader />;
}

View File

@ -1,3 +1,3 @@
export default function Page() { export default function Page() {
return <></>; return <>TODO: Collection Page</>;
} }

View File

@ -0,0 +1,5 @@
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
export default function Loading() {
return <FileIndeterminateLoader />;
}

View File

@ -0,0 +1,5 @@
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
export default function Loading() {
return <FileIndeterminateLoader />;
}

View File

@ -0,0 +1,5 @@
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
export default function Loading() {
return <FileIndeterminateLoader />;
}

View File

@ -0,0 +1,5 @@
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
export default function Loading() {
return <FileIndeterminateLoader />;
}

View File

@ -4,15 +4,9 @@ import { ShareMenu } from '../ShareMenu';
import { ShareAssetType } from '@/api/asset_interfaces'; import { ShareAssetType } from '@/api/asset_interfaces';
import { useGetDashboard } from '@/api/buster_rest/dashboards'; import { useGetDashboard } from '@/api/buster_rest/dashboards';
import { getShareAssetConfig } from '../ShareMenu/helpers'; import { getShareAssetConfig } from '../ShareMenu/helpers';
import { getIsEffectiveOwner } from '@/lib/share';
export const ShareDashboardButton = React.memo(({ dashboardId }: { dashboardId: string }) => { export const ShareDashboardButton = React.memo(({ dashboardId }: { dashboardId: string }) => {
const { data: dashboardResponse } = useGetDashboard({ id: dashboardId }, getShareAssetConfig); const { data: dashboardResponse } = useGetDashboard({ id: dashboardId }, getShareAssetConfig);
const isEffectiveOwner = getIsEffectiveOwner(dashboardResponse?.permission);
if (!isEffectiveOwner) {
return null;
}
return ( return (
<ShareMenu <ShareMenu

View File

@ -65,6 +65,7 @@ export const InputTextAreaButton = forwardRef<HTMLTextAreaElement, InputTextArea
variant="ghost" variant="ghost"
className={cn( className={cn(
'leading-1.3 w-full px-5! py-4! pr-10 align-middle transition-all duration-500', 'leading-1.3 w-full px-5! py-4! pr-10 align-middle transition-all duration-500',
'hover:shadow-md focus:shadow-lg',
loading && 'cursor-not-allowed! opacity-70' loading && 'cursor-not-allowed! opacity-70'
)} )}
autoResize={autoResize} autoResize={autoResize}

View File

@ -34,7 +34,7 @@ export const ChatInput: React.FC<{}> = React.memo(({}) => {
<div <div
className={cn( className={cn(
'flex flex-col space-y-1.5', 'flex flex-col space-y-1.5',
'z-10 mx-3 mt-0.5 mb-2 flex min-h-fit flex-col items-center overflow-hidden' 'z-10 mx-3 mt-0.5 mb-2 flex min-h-fit flex-col items-center overflow-visible'
)}> )}>
<InputTextAreaButton <InputTextAreaButton
placeholder="Ask Buster a question..." placeholder="Ask Buster a question..."

View File

@ -12,19 +12,30 @@ import { Plus } from '@/components/ui/icons';
import { DashboardThreeDotMenu } from './DashboardThreeDotMenu'; import { DashboardThreeDotMenu } from './DashboardThreeDotMenu';
import { AppTooltip } from '@/components/ui/tooltip'; import { AppTooltip } from '@/components/ui/tooltip';
import { useGetDashboard } from '@/api/buster_rest/dashboards'; import { useGetDashboard } from '@/api/buster_rest/dashboards';
import { canEdit } from '@/lib/share'; import { canEdit, getIsEffectiveOwner } from '@/lib/share';
import { useDashboardContentStore } from '@/context/Dashboards'; import { useDashboardContentStore } from '@/context/Dashboards';
export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo( export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(
() => { () => {
const selectedFileView = useChatLayoutContextSelector((x) => x.selectedFileView); const selectedFileView = useChatLayoutContextSelector((x) => x.selectedFileView);
const selectedFileId = useChatIndividualContextSelector((x) => x.selectedFileId)!; const selectedFileId = useChatIndividualContextSelector((x) => x.selectedFileId)!;
const dashboardId = selectedFileId;
const { data: permission, error: dashboardError } = useGetDashboard(
{ id: dashboardId },
(x) => x.permission
);
if (dashboardError) return null;
const isEditor = canEdit(permission);
const isEffectiveOwner = getIsEffectiveOwner(permission);
return ( return (
<FileButtonContainer> <FileButtonContainer>
<SaveToCollectionButton /> <SaveToCollectionButton />
<ShareDashboardButton dashboardId={selectedFileId} /> {isEffectiveOwner && <ShareDashboardButton dashboardId={selectedFileId} />}
<AddContentToDashboardButton dashboardId={selectedFileId} /> {isEditor && <AddContentToDashboardButton />}
<DashboardThreeDotMenu dashboardId={selectedFileId} /> <DashboardThreeDotMenu dashboardId={selectedFileId} />
<HideButtonContainer show={selectedFileView === 'file'}> <HideButtonContainer show={selectedFileView === 'file'}>
<CreateChatButton /> <CreateChatButton />
@ -42,15 +53,9 @@ const SaveToCollectionButton = React.memo(() => {
}); });
SaveToCollectionButton.displayName = 'SaveToCollectionButton'; SaveToCollectionButton.displayName = 'SaveToCollectionButton';
const AddContentToDashboardButton = React.memo(({ dashboardId }: { dashboardId: string }) => { const AddContentToDashboardButton = React.memo(() => {
const { data: permission } = useGetDashboard({ id: dashboardId }, (x) => x.permission);
const isEditor = canEdit(permission);
const onOpenAddContentModal = useDashboardContentStore((x) => x.onOpenAddContentModal); const onOpenAddContentModal = useDashboardContentStore((x) => x.onOpenAddContentModal);
if (!isEditor) {
return null;
}
return ( return (
<AppTooltip title="Add content"> <AppTooltip title="Add content">
<Button variant="ghost" prefix={<Plus />} onClick={onOpenAddContentModal} /> <Button variant="ghost" prefix={<Plus />} onClick={onOpenAddContentModal} />

View File

@ -38,13 +38,16 @@ export const FileContainerHeader: React.FC = React.memo(() => {
[selectedFileType] [selectedFileType]
); );
const { data: hasAccess } = useAssetCheck( const { data: hasAccessQuery } = useAssetCheck(
{ assetId: selectedFileId, fileType: selectedFileType }, { assetId: selectedFileId, fileType: selectedFileType },
(x) => x.has_access (x) => x.has_access
); );
const hasAccess = hasAccessQuery ?? true; // we assume access until it is revoked
if (isVersionHistoryMode) return <FileContainerHeaderVersionHistory />; if (isVersionHistoryMode) return <FileContainerHeaderVersionHistory />;
console.log(hasAccess, selectedFileView);
return ( return (
<> <>
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">

View File

@ -13,22 +13,30 @@ import { ShareMetricButton } from '../../../../../components/features/buttons/Sh
import { SquareChartPen, SquareCode } from '@/components/ui/icons'; import { SquareChartPen, SquareCode } from '@/components/ui/icons';
import { useGetMetric } from '@/api/buster_rest/metrics'; import { useGetMetric } from '@/api/buster_rest/metrics';
import { ThreeDotMenuButton } from './MetricThreeDotMenu'; import { ThreeDotMenuButton } from './MetricThreeDotMenu';
import { canEdit, getIsEffectiveOwner } from '@/lib/share';
export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(() => { export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(() => {
const selectedLayout = useChatLayoutContextSelector((x) => x.selectedLayout); const selectedLayout = useChatLayoutContextSelector((x) => x.selectedLayout);
const selectedFileId = useChatIndividualContextSelector((x) => x.selectedFileId)!; const selectedFileId = useChatIndividualContextSelector((x) => x.selectedFileId)!;
const metricId = selectedFileId; const metricId = selectedFileId;
const { isFetched: isMetricFetched, error: metricError } = useGetMetric({ id: metricId }); const { error: metricError, data: permission } = useGetMetric(
{ id: metricId },
(x) => x.permission
);
if (!isMetricFetched || metricError) return null; //we assume it is fetched until it is not
if (metricError) return null;
const isEditor = canEdit(permission);
const isEffectiveOwner = getIsEffectiveOwner(permission);
return ( return (
<FileButtonContainer> <FileButtonContainer>
<EditChartButton /> {isEditor && <EditChartButton />}
<EditSQLButton /> {isEffectiveOwner && <EditSQLButton />}
<SaveToCollectionButton metricId={metricId} /> <SaveToCollectionButton metricId={metricId} />
<SaveToDashboardButton metricId={metricId} /> <SaveToDashboardButton metricId={metricId} />
<ShareMetricButton metricId={metricId} /> {isEffectiveOwner && <ShareMetricButton metricId={metricId} />}
<ThreeDotMenuButton metricId={metricId} /> <ThreeDotMenuButton metricId={metricId} />
<HideButtonContainer show={selectedLayout === 'file'}> <HideButtonContainer show={selectedLayout === 'file'}>
<CreateChatButton /> <CreateChatButton />

View File

@ -49,7 +49,6 @@ import { METRIC_CHART_TITLE_INPUT_ID } from '@/controllers/MetricController/Metr
import { ShareMenuContent } from '@/components/features/ShareMenu/ShareMenuContent'; import { ShareMenuContent } from '@/components/features/ShareMenu/ShareMenuContent';
import { canEdit, getIsEffectiveOwner, getIsOwner } from '@/lib/share'; import { canEdit, getIsEffectiveOwner, getIsOwner } from '@/lib/share';
import { getShareAssetConfig } from '@/components/features/ShareMenu/helpers'; import { getShareAssetConfig } from '@/components/features/ShareMenu/helpers';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => { export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => {