mirror of https://github.com/buster-so/buster.git
make loaders for all pages
This commit is contained in:
parent
8732e895c7
commit
a3333b2c94
|
@ -0,0 +1,5 @@
|
||||||
|
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <FileIndeterminateLoader />;
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <></>;
|
return <>TODO: Collection Page</>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <FileIndeterminateLoader />;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <FileIndeterminateLoader />;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <FileIndeterminateLoader />;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FileIndeterminateLoader } from '@/components/features/FileIndeterminateLoader';
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <FileIndeterminateLoader />;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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..."
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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 }) => {
|
||||||
|
|
Loading…
Reference in New Issue