add more 3 dot menu items

This commit is contained in:
Nate Kelley 2025-03-17 11:29:33 -06:00
parent 5f6ce012e2
commit 3999262ce8
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
9 changed files with 48 additions and 23 deletions

View File

@ -15,7 +15,7 @@ export const DataContainer: React.FC<{
return ( return (
<div <div
className={cn( className={cn(
'bg-background rounded border', 'bg-background rounded border shadow',
'relative h-full w-full overflow-hidden', 'relative h-full w-full overflow-hidden',
className className
)}> )}>

View File

@ -81,8 +81,6 @@ export const useFavoriteStar = ({
return userFavorites?.some((favorite) => favorite.id === id || favorite.collection_id === id); return userFavorites?.some((favorite) => favorite.id === id || favorite.collection_id === id);
}, [userFavorites, id]); }, [userFavorites, id]);
console.log('userFavorites', isFavorited, userFavorites);
const onFavoriteClick = useMemoizedFn(async (e?: React.MouseEvent<HTMLButtonElement>) => { const onFavoriteClick = useMemoizedFn(async (e?: React.MouseEvent<HTMLButtonElement>) => {
e?.stopPropagation(); e?.stopPropagation();
e?.preventDefault(); e?.preventDefault();

View File

@ -28,7 +28,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
<DropdownMenuPrimitive.SubTrigger <DropdownMenuPrimitive.SubTrigger
ref={ref} ref={ref}
className={cn( className={cn(
'focus:bg-item-hover data-[state=open]:bg-item-hover flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none [&_svg]:pointer-events-none [&_svg]:shrink-0', 'focus:bg-item-hover data-[state=open]:bg-item-hover flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none select-none [&_svg]:pointer-events-none [&_svg]:shrink-0',
'dropdown-item mx-1 [&.dropdown-item:first-child]:mt-1! [&.dropdown-item:has(+.dropdown-separator)]:mb-1 [&.dropdown-item:has(~.dropdown-separator)]:mt-1 [&.dropdown-item:last-child]:mb-1!', 'dropdown-item mx-1 [&.dropdown-item:first-child]:mt-1! [&.dropdown-item:has(+.dropdown-separator)]:mb-1 [&.dropdown-item:has(~.dropdown-separator)]:mt-1 [&.dropdown-item:last-child]:mb-1!',
inset && 'pl-8', inset && 'pl-8',
className className
@ -204,7 +204,7 @@ const DropdownMenuLabel = React.forwardRef<
>(({ className, inset, ...props }, ref) => ( >(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Label <DropdownMenuPrimitive.Label
ref={ref} ref={ref}
className={cn('text-gray-dark px-2 py-1.5 text-sm', inset && 'pl-8', className)} className={cn('text-gray-dark px-2 py-1.5 text-base', inset && 'pl-8', className)}
{...props} {...props}
/> />
)); ));

View File

@ -10,7 +10,7 @@
position: absolute; position: absolute;
white-space: normal; white-space: normal;
width: 100%; width: 100%;
overflow: hidden; overflow: visible;
} }
.react-split__sash { .react-split__sash {

View File

@ -35,10 +35,12 @@ export const EditableTitle = React.memo(
placeholder?: string; placeholder?: string;
style?: React.CSSProperties; style?: React.CSSProperties;
inputClassName?: string; inputClassName?: string;
id?: string;
} & VariantProps<typeof editableTitleVariants> } & VariantProps<typeof editableTitleVariants>
>( >(
( (
{ {
id,
style, style,
disabled, disabled,
className = '', className = '',
@ -76,10 +78,11 @@ export const EditableTitle = React.memo(
<Input <Input
placeholder={placeholder} placeholder={placeholder}
ref={inputRef} ref={inputRef}
id={id}
disabled={disabled} disabled={disabled}
variant="ghost" variant="ghost"
className={cn( className={cn(
'w-full cursor-text! px-0! py-0! leading-1', 'w-full cursor-text! rounded-none! px-0! py-0! leading-1',
editableTitleVariants({ level }), editableTitleVariants({ level }),
inputClassName inputClassName
)} )}

View File

@ -3,6 +3,8 @@ import { Text } from '@/components/ui/typography';
import { EditableTitle } from '@/components/ui/typography/EditableTitle'; import { EditableTitle } from '@/components/ui/typography/EditableTitle';
import { cn } from '@/lib/classMerge'; import { cn } from '@/lib/classMerge';
export const METRIC_CHART_TITLE_INPUT_ID = 'metric-chart-title-input';
export const MetricViewChartHeader: React.FC<{ export const MetricViewChartHeader: React.FC<{
className?: string; className?: string;
title: string | undefined; title: string | undefined;
@ -20,7 +22,12 @@ export const MetricViewChartHeader: React.FC<{
)}> )}>
{hasTitleOrDescription ? ( {hasTitleOrDescription ? (
<> <>
<EditableTitle level={4} className="" inputClassName="h-auto!" onChange={onSetTitle}> <EditableTitle
id={METRIC_CHART_TITLE_INPUT_ID}
level={4}
className=""
inputClassName="h-auto!"
onChange={onSetTitle}>
{title} {title}
</EditableTitle> </EditableTitle>
<div className="flex items-center space-x-1 whitespace-nowrap"> <div className="flex items-center space-x-1 whitespace-nowrap">

View File

@ -83,7 +83,6 @@ export const MetricViewResults: React.FC<MetricViewProps> = React.memo(({ metric
return ( return (
<div ref={containerRef} className="h-full w-full p-5"> <div ref={containerRef} className="h-full w-full p-5">
<AppVerticalCodeSplitter <AppVerticalCodeSplitter
className="shadow"
ref={appSplitterRef} ref={appSplitterRef}
autoSaveId={autoSaveId} autoSaveId={autoSaveId}
sql={sql} sql={sql}

View File

@ -15,7 +15,7 @@ import { useMemoizedFn } from './useMemoizedFn';
* @example * @example
* ```tsx * ```tsx
* const { start, stop, isActive } = useSetInterval(() => { * const { start, stop, isActive } = useSetInterval(() => {
* console.log('This runs every second'); * //
* }, 1000); * }, 1000);
* ``` * ```
*/ */

View File

@ -17,7 +17,6 @@ import {
Download4, Download4,
History, History,
SquareCode, SquareCode,
Table,
SquareChartPen, SquareChartPen,
Star, Star,
ShareRight ShareRight
@ -43,6 +42,8 @@ import { StatusBadgeIndicator } from '@/components/features/metrics/StatusBadgeI
import { useFavoriteStar } from '@/components/features/list/FavoriteStar'; import { useFavoriteStar } from '@/components/features/list/FavoriteStar';
import { downloadElementToImage, exportElementToImage, exportJSONToCSV } from '@/lib/exportUtils'; import { downloadElementToImage, exportElementToImage, exportJSONToCSV } from '@/lib/exportUtils';
import { METRIC_CHART_CONTAINER_ID } from '@/controllers/MetricController/MetricViewChart/config'; import { METRIC_CHART_CONTAINER_ID } from '@/controllers/MetricController/MetricViewChart/config';
import { timeout } from '@/lib';
import { METRIC_CHART_TITLE_INPUT_ID } from '@/controllers/MetricController/MetricViewChart/MetricViewChartHeader';
export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => { export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => {
const { mutateAsync: deleteMetric, isPending: isDeletingMetric } = useDeleteMetric(); const { mutateAsync: deleteMetric, isPending: isDeletingMetric } = useDeleteMetric();
@ -61,15 +62,11 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }
const downloadPNGMenu = useDownloadPNGSelectMenu({ metricId }); const downloadPNGMenu = useDownloadPNGSelectMenu({ metricId });
const deleteMetricMenu = useDeleteMetricSelectMenu({ metricId }); const deleteMetricMenu = useDeleteMetricSelectMenu({ metricId });
const renameMetricMenu = useRenameMetricSelectMenu({ metricId }); const renameMetricMenu = useRenameMetricSelectMenu({ metricId });
const shareMenu = useShareMenuSelectMenu({ metricId });
const items: DropdownItems = useMemo( const items: DropdownItems = useMemo(
() => [ () => [
{ shareMenu,
label: 'Share',
value: 'share',
icon: <ShareRight />,
items: []
},
statusSelectMenu, statusSelectMenu,
{ type: 'divider' }, { type: 'divider' },
dashboardSelectMenu, dashboardSelectMenu,
@ -87,6 +84,7 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }
deleteMetricMenu deleteMetricMenu
], ],
[ [
renameMetricMenu,
dashboardSelectMenu, dashboardSelectMenu,
deleteMetricMenu, deleteMetricMenu,
downloadCSVMenu, downloadCSVMenu,
@ -101,7 +99,8 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }
collectionSelectMenu, collectionSelectMenu,
editChartMenu, editChartMenu,
resultsViewMenu, resultsViewMenu,
sqlEditorMenu sqlEditorMenu,
shareMenu
] ]
); );
@ -312,7 +311,7 @@ const useResultsViewSelectMenu = () => {
return useMemo( return useMemo(
() => ({ () => ({
label: 'Results view', label: 'Results view',
value: 'edit-chart', value: 'results-view',
onClick: onClickButton, onClick: onClickButton,
icon: <SquareChartPen /> icon: <SquareChartPen />
}), }),
@ -354,7 +353,7 @@ const useDownloadCSVSelectMenu = ({ metricId }: { metricId: string }) => {
const data = metricData?.data; const data = metricData?.data;
if (data && title) { if (data && title) {
setIsDownloading(true); setIsDownloading(true);
await exportJSONToCSV(data, `${title}.csv`); await exportJSONToCSV(data, title);
setIsDownloading(false); setIsDownloading(false);
} }
} }
@ -414,6 +413,7 @@ const useDeleteMetricSelectMenu = ({ metricId }: { metricId: string }) => {
const useRenameMetricSelectMenu = ({ metricId }: { metricId: string }) => { const useRenameMetricSelectMenu = ({ metricId }: { metricId: string }) => {
const { mutateAsync: updateMetric } = useUpdateMetric(); const { mutateAsync: updateMetric } = useUpdateMetric();
const onSetFileView = useChatLayoutContextSelector((x) => x.onSetFileView);
return useMemo( return useMemo(
() => ({ () => ({
@ -421,11 +421,29 @@ const useRenameMetricSelectMenu = ({ metricId }: { metricId: string }) => {
value: 'rename-metric', value: 'rename-metric',
icon: <Pencil />, icon: <Pencil />,
onClick: async () => { onClick: async () => {
console.log('rename'); onSetFileView({ fileView: 'chart' });
alert('TODO: Implement rename metric'); await timeout(125);
// await updateMetric({ id: metricId, title: 'New title' }); const input = document.getElementById(METRIC_CHART_TITLE_INPUT_ID) as HTMLInputElement;
if (input) {
input.focus();
input.select();
}
} }
}), }),
[metricId] [metricId]
); );
}; };
export const useShareMenuSelectMenu = ({ metricId }: { metricId: string }) => {
const { mutateAsync: updateMetric } = useUpdateMetric();
return useMemo(
() => ({
label: 'Share metric',
value: 'share-metric',
icon: <ShareRight />,
items: [<div className="bg-red-200 p-2">SWAG</div>]
}),
[]
);
};