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

View File

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

View File

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

View File

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

View File

@ -56,5 +56,5 @@ th {
strong, strong,
b { 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 type PaginatedResponse<T> = z.infer<ReturnType<typeof PaginatedResponseSchema<T>>>;
export const PaginatedRequestSchema = z.object({ export const PaginatedRequestSchema = z.object({
page: z.coerce.number().min(1).optional().default(1).optional(), page: z.coerce.number().min(1).optional().default(1),
page_size: z.coerce.number().min(1).max(5000).default(250).optional(), page_size: z.coerce.number().min(1).max(5000).default(250),
}); });