From ed19faecc7d594b3d6dcd9a5945c62ec4b2dacaa Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Thu, 25 Sep 2025 15:23:09 -0600 Subject: [PATCH] add workspace sharing to chat dropdown --- .../api/buster_rest/chats/queryRequests.ts | 5 ++ .../features/ShareMenu/ShareMenuInvite.tsx | 6 ++- .../features/chat/threeDotMenuHooks.tsx | 2 - .../hooks/useSeriesOptions/createTickDate.ts | 1 - apps/web/src/lib/routes/index.test.ts | 51 +++++++++++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 apps/web/src/lib/routes/index.test.ts diff --git a/apps/web/src/api/buster_rest/chats/queryRequests.ts b/apps/web/src/api/buster_rest/chats/queryRequests.ts index 1d2663abe..d792b4689 100644 --- a/apps/web/src/api/buster_rest/chats/queryRequests.ts +++ b/apps/web/src/api/buster_rest/chats/queryRequests.ts @@ -410,6 +410,7 @@ export const useUpdateChatShare = () => { const queryKey = chatQueryKeys.chatsGetChat(variables.id).queryKey; queryClient.setQueryData(queryKey, (previousData: IBusterChat | undefined) => { if (!previousData) return previousData; + return create(previousData, (draft: IBusterChat) => { draft.individual_permissions = ( draft.individual_permissions?.map((t) => { @@ -428,6 +429,10 @@ export const useUpdateChatShare = () => { if (variables.params.public_expiry_date !== undefined) { draft.public_expiry_date = variables.params.public_expiry_date; } + if (variables.params.workspace_sharing !== undefined) { + draft.workspace_sharing = variables.params.workspace_sharing; + s; + } }); }); }, diff --git a/apps/web/src/components/features/ShareMenu/ShareMenuInvite.tsx b/apps/web/src/components/features/ShareMenu/ShareMenuInvite.tsx index 38a4a78c8..9a8f72b02 100644 --- a/apps/web/src/components/features/ShareMenu/ShareMenuInvite.tsx +++ b/apps/web/src/components/features/ShareMenu/ShareMenuInvite.tsx @@ -49,7 +49,11 @@ export const ShareMenuInvite: React.FC = React.memo( const disableSubmit = !inputHasText(inputValue) || !isValidEmail(inputValue); const isInviting = - isInvitingMetric || isInvitingDashboard || isInvitingCollection || isInvitingChat; + isInvitingMetric || + isInvitingDashboard || + isInvitingCollection || + isInvitingChat || + isInvitingReport; const options: SelectItem[] = useMemo(() => { return ( diff --git a/apps/web/src/components/features/chat/threeDotMenuHooks.tsx b/apps/web/src/components/features/chat/threeDotMenuHooks.tsx index 6be4551d5..e507d0081 100644 --- a/apps/web/src/components/features/chat/threeDotMenuHooks.tsx +++ b/apps/web/src/components/features/chat/threeDotMenuHooks.tsx @@ -12,8 +12,6 @@ import { timeout } from '@/lib/timeout'; import { getShareAssetConfig, ShareMenuContent } from '../ShareMenu'; import { CHAT_HEADER_TITLE_ID } from './ChatHeaderTitle'; -const stablePermissionSelector = (chat: IBusterChat) => chat.permission; - export const useShareMenuSelectMenu = ({ chatId = '' }: { chatId: string | undefined }) => { const { data: shareAssetConfig } = useGetChat({ id: chatId }, { select: getShareAssetConfig }); const isEffectiveOwner = getIsEffectiveOwner(shareAssetConfig?.permission); diff --git a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/createTickDate.ts b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/createTickDate.ts index d9312a57d..7e6ec09c4 100644 --- a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/createTickDate.ts +++ b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/createTickDate.ts @@ -12,7 +12,6 @@ export const createTickDates = ( xAxisKeys: string[], columnLabelFormats: Record ): (Date | string)[] | null => { - console.clear(); const xColumnLabelFormats = xAxisKeys.map( (key) => columnLabelFormats[key] || DEFAULT_COLUMN_LABEL_FORMAT ); diff --git a/apps/web/src/lib/routes/index.test.ts b/apps/web/src/lib/routes/index.test.ts new file mode 100644 index 000000000..5e384c1d5 --- /dev/null +++ b/apps/web/src/lib/routes/index.test.ts @@ -0,0 +1,51 @@ +import type { ParsedLocation } from '@tanstack/react-router'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { createFullURL } from './index'; + +// Mock window.location.origin +Object.defineProperty(window, 'location', { + value: { + origin: 'https://example.com', + }, + writable: true, +}); + +describe('createFullURL', () => { + beforeEach(() => { + // Reset window.location.origin before each test + Object.defineProperty(window, 'location', { + value: { + origin: 'https://example.com', + }, + writable: true, + }); + }); + + it('should create full URL from string input', () => { + // Test case: String input should be appended to window.location.origin + // Expected: Should return the origin combined with the path string + const path = '/dashboard/metrics'; + const result = createFullURL(path); + + expect(result).toBe('https://example.com/dashboard/metrics'); + }); + + it('should create full URL from ParsedLocation input', () => { + // Test case: ParsedLocation input should use the href property + // Expected: Should return the origin combined with the ParsedLocation.href + const mockLocation: ParsedLocation = { + href: '/reports/123?tab=overview', + pathname: '/reports/123', + search: { tab: 'overview' }, + searchStr: '?tab=overview', + state: {}, + hash: '', + key: 'test-key', + maskedLocation: undefined, + } as ParsedLocation; + + const result = createFullURL(mockLocation); + + expect(result).toBe('https://example.com/reports/123?tab=overview'); + }); +});