table content copy

This commit is contained in:
Nate Kelley 2025-09-25 10:59:24 -06:00
parent 34914026a5
commit bf1b08344c
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 28 additions and 22 deletions

View File

@ -7,7 +7,6 @@ export type * from './datasources';
export type * from './metric';
export type * from './permission';
export type * from './permission_groups';
export type * from './search';
export type * from './sql';
export type * from './teams';
export type * from './terms';

View File

@ -1,6 +1,6 @@
import type { SearchTextResponse } from '@buster/server-shared/search';
import type { ShareAssetType } from '@buster/server-shared/share';
import React, { useLayoutEffect, useMemo, useState } from 'react';
import type { BusterSearchResult } from '@/api/asset_interfaces/search';
import {
useAddAndRemoveAssetsFromCollection,
useGetCollection,
@ -33,8 +33,9 @@ export const AddToCollectionModal: React.FC<{
const { data: searchResults } = useSearch({
query: debouncedSearchTerm,
asset_types: ['metric_file', 'dashboard_file'],
num_results: 100,
assetTypes: ['metric_file', 'dashboard_file'],
page_size: 50,
page: 1,
});
const [selectedAssets, setSelectedAssets] = useState<SelectedAsset[]>([]);
@ -42,13 +43,13 @@ export const AddToCollectionModal: React.FC<{
return selectedAssets.map((asset) => asset.id);
}, [selectedAssets]);
const columns = useMemo<InputSelectModalProps<BusterSearchResult>['columns']>(
const columns = useMemo<InputSelectModalProps<SearchTextResponse['data'][number]>['columns']>(
() => [
{
title: 'Name',
dataIndex: 'name',
render: (name, data) => {
const Icon = assetTypeToIcon(data.type) || ASSET_ICONS.metrics;
dataIndex: 'title',
render: (name, record) => {
const Icon = assetTypeToIcon(record.assetType) || ASSET_ICONS.metrics;
return (
<div className="flex items-center gap-1.5">
<span className="text-icon-color">
@ -61,7 +62,7 @@ export const AddToCollectionModal: React.FC<{
},
{
title: 'Updated',
dataIndex: 'updated_at',
dataIndex: 'updatedAt',
width: 140,
render: (value: string) => {
return formatDate({
@ -74,10 +75,10 @@ export const AddToCollectionModal: React.FC<{
[]
);
const rows: BusterListRowItem<BusterSearchResult>[] = useMemo(() => {
const rows: BusterListRowItem<SearchTextResponse['data'][number]>[] = useMemo(() => {
return (
searchResults?.map((asset) => ({
id: asset.id,
searchResults?.data?.map((asset) => ({
id: asset.assetId,
data: asset,
})) || []
);
@ -86,7 +87,7 @@ export const AddToCollectionModal: React.FC<{
const createKeySearchResultMap = useMemoizedFn(() => {
const map = new Map<string, SelectedAsset>();
rows.forEach((asset) => {
if (asset.data?.type) map.set(asset.id, { type: asset.data?.type, id: asset.id });
if (asset.data?.assetType) map.set(asset.id, { type: asset.data?.assetType, id: asset.id });
});
return map;
});

View File

@ -11,7 +11,6 @@ import {
SquareChart,
Table,
} from '@/components/ui/icons';
import type { iconProps } from '@/components/ui/icons/NucleoIconOutlined/iconProps';
import SquareChartPlus from '@/components/ui/icons/NucleoIconOutlined/square-chart-plus';
export const ASSET_ICONS = {

View File

@ -16,7 +16,6 @@ export type MetricChartCardProps = {
metricId: string;
versionNumber: number | undefined;
readOnly?: boolean;
className?: string;
attributes?: DraggableAttributes;
listeners?: DraggableSyntheticListeners;
headerSecondaryContent?: React.ReactNode;
@ -25,7 +24,7 @@ export type MetricChartCardProps = {
renderChartContent?: boolean; // we do this to avoid expensive rendering if off screen
disableTooltip?: boolean;
cacheDataId?: string;
};
} & React.HTMLAttributes<HTMLDivElement>;
const stableMetricSelect = ({
chart_config,
@ -62,6 +61,7 @@ export const MetricChartCard = React.memo(
renderChartContent = true,
disableTooltip,
cacheDataId,
...rest
},
ref
) => {
@ -102,6 +102,7 @@ export const MetricChartCard = React.memo(
errorData={errorData}
isTable={isTable}
className={className}
{...rest}
>
<MetricViewChartHeader
name={name}
@ -144,13 +145,12 @@ type MetricViewChartCardContainerProps = {
hasData: boolean;
errorData: boolean;
isTable: boolean;
className?: string;
};
} & React.HTMLAttributes<HTMLDivElement>;
const MetricViewChartCardContainer = React.forwardRef<
HTMLDivElement,
MetricViewChartCardContainerProps
>(({ children, loadingData, hasData, errorData, isTable, className }, ref) => {
>(({ children, loadingData, hasData, errorData, isTable, className, ...divProps }, ref) => {
const cardClass = React.useMemo(() => {
if (loadingData || errorData || !hasData) return 'h-full max-h-[600px]';
if (isTable) return 'h-full';
@ -161,6 +161,7 @@ const MetricViewChartCardContainer = React.forwardRef<
<MetricViewChartProvider>
<div
ref={ref}
{...divProps}
className={cn(
'bg-background flex flex-col overflow-hidden rounded border shadow',
cardClass,

View File

@ -3,6 +3,7 @@ import { MetricChartCard } from '@/components/features/metrics/MetricChartCard';
import { ReportMetricThreeDotMenu } from '@/components/features/metrics/ReportMetricItem';
import { useGetReportParams } from '@/context/Reports/useGetReportParams';
import { useInViewport } from '@/hooks/useInViewport';
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
export const MetricContent = React.memo(
({
@ -30,6 +31,10 @@ export const MetricContent = React.memo(
}
const renderChart = inViewport || isExportMode || hasBeenInViewport.current;
const handleCopy = useMemoizedFn((e: React.ClipboardEvent<HTMLDivElement>) => {
e.stopPropagation();
});
return (
<MetricChartCard
ref={ref}
@ -50,6 +55,7 @@ export const MetricContent = React.memo(
/>
)
}
onCopy={handleCopy}
/>
);
}

View File

@ -56,5 +56,5 @@ th {
strong,
b {
@apply font-semibold
@apply font-semibold;
}

View File

@ -18,6 +18,6 @@ export const PaginatedResponseSchema = <T>(schema: z.ZodType<T>) =>
export type PaginatedResponse<T> = z.infer<ReturnType<typeof PaginatedResponseSchema<T>>>;
export const PaginatedRequestSchema = z.object({
page: z.coerce.number().min(1).optional().default(1).optional(),
page_size: z.coerce.number().min(1).max(5000).default(250).optional(),
page: z.coerce.number().min(1).optional().default(1),
page_size: z.coerce.number().min(1).max(5000).default(250),
});