diff --git a/apps/web-tss/src/components/features/metrics/MetricThreeDotMenu.tsx b/apps/web-tss/src/components/features/metrics/MetricThreeDotMenu.tsx index 58a74d726..5a8546de8 100644 --- a/apps/web-tss/src/components/features/metrics/MetricThreeDotMenu.tsx +++ b/apps/web-tss/src/components/features/metrics/MetricThreeDotMenu.tsx @@ -37,7 +37,7 @@ import { Trash, } from '@/components/ui/icons'; import { useBusterNotifications } from '@/context/BusterNotifications'; -import { useIsChatMode } from '@/context/Chats/useIsChatMode'; +import { useIsChatMode } from '@/context/Chats/useMode'; import { useDownloadMetricDataCSV } from '@/context/Metrics/useDownloadMetricDataCSV'; import { useDownloadPNGSelectMenu } from '@/context/Metrics/useDownloadMetricDataPNG'; import { useRenameMetricOnPage } from '@/context/Metrics/useRenameMetricOnPage'; diff --git a/apps/web-tss/src/components/ui/list/BusterList/create-link-items.ts b/apps/web-tss/src/components/ui/list/BusterList/create-link-items.ts new file mode 100644 index 000000000..ce1020528 --- /dev/null +++ b/apps/web-tss/src/components/ui/list/BusterList/create-link-items.ts @@ -0,0 +1,53 @@ +import type { RegisteredRouter } from '@tanstack/react-router'; +import { create } from 'lodash'; +import type { BusterListRowItem } from './interfaces'; + +export function createLinkItems< + T, + TRouter extends RegisteredRouter, + TOptions, + TFrom extends string = string, +>( + items: BusterListRowItem[] +): BusterListRowItem[] { + return items; +} + +export function createLinkItem< + T, + TRouter extends RegisteredRouter = RegisteredRouter, + TOptions = Record, + TFrom extends string = string, +>( + item: BusterListRowItem +): BusterListRowItem { + return item; +} + +const test = createLinkItem({ + id: '1', + data: { + name: 'Test', + }, + link: { + to: '/app/metrics/$metricId', + params: { + metricId: '1', + }, + }, +}); + +const test2 = createLinkItem<{ + swag: boolean; +}>({ + id: '1', + data: { + swag: true, + }, + link: { + to: '/app/metrics/$metricId', + params: { + metricId: '1', + }, + }, +}); diff --git a/apps/web-tss/src/components/ui/list/BusterList/index.ts b/apps/web-tss/src/components/ui/list/BusterList/index.ts index a52d93ba1..a29735231 100644 --- a/apps/web-tss/src/components/ui/list/BusterList/index.ts +++ b/apps/web-tss/src/components/ui/list/BusterList/index.ts @@ -1,3 +1,4 @@ +export * from './create-link-items'; export * from './interfaces'; export * from './ListSelectedOptionPopup'; diff --git a/apps/web-tss/src/components/ui/list/BusterList/interfaces.ts b/apps/web-tss/src/components/ui/list/BusterList/interfaces.ts index ed480d75b..b7ab815cf 100644 --- a/apps/web-tss/src/components/ui/list/BusterList/interfaces.ts +++ b/apps/web-tss/src/components/ui/list/BusterList/interfaces.ts @@ -1,6 +1,6 @@ -import type { LinkProps } from '@tanstack/react-router'; +import type { LinkProps, RegisteredRouter } from '@tanstack/react-router'; import type React from 'react'; -import type { OptionsTo } from '@/types/routes'; +import type { ILinkProps } from '@/types/routes'; import type { ContextMenuProps } from '../../context-menu/ContextMenu'; export interface BusterListProps { @@ -31,8 +31,12 @@ export type BusterListColumn = { }; }[keyof T]; -type BusterListRowLink = { - link: OptionsTo; +type BusterListRowLink< + TRouter extends RegisteredRouter = RegisteredRouter, + TOptions = Record, + TFrom extends string = string, +> = { + link: ILinkProps; preloadDelay?: LinkProps['preloadDelay']; preload?: LinkProps['preload']; }; @@ -41,7 +45,12 @@ type BusterListRowNotLink = { link?: never; }; -export type BusterListRowItem = { +export type BusterListRowItem< + T = unknown, + TRouter extends RegisteredRouter = RegisteredRouter, + TOptions = Record, + TFrom extends string = string, +> = { id: string; data: T | null; onClick?: () => void; @@ -49,7 +58,7 @@ export type BusterListRowItem = { rowSection?: BusterListSectionRow; hidden?: boolean; dataTestId?: string; -} & (BusterListRowLink | BusterListRowNotLink); +} & (BusterListRowLink | BusterListRowNotLink); export interface BusterListSectionRow { title: string; diff --git a/apps/web-tss/src/context/Chats/useIsChatMode.ts b/apps/web-tss/src/context/Chats/useMode.ts similarity index 64% rename from apps/web-tss/src/context/Chats/useIsChatMode.ts rename to apps/web-tss/src/context/Chats/useMode.ts index 06fe5b5ae..8b619fcb4 100644 --- a/apps/web-tss/src/context/Chats/useIsChatMode.ts +++ b/apps/web-tss/src/context/Chats/useMode.ts @@ -8,3 +8,11 @@ export const useIsChatMode = () => { }); return chatId !== undefined; }; + +export const useIsFileMode = () => { + const chatId = useParams({ + select: stableSelect, + strict: false, + }); + return chatId === undefined; +}; diff --git a/apps/web-tss/src/controllers/MetricListContainer/MetricItemsContainer.tsx b/apps/web-tss/src/controllers/MetricListContainer/MetricItemsContainer.tsx index e1a2d1278..eb372bcad 100644 --- a/apps/web-tss/src/controllers/MetricListContainer/MetricItemsContainer.tsx +++ b/apps/web-tss/src/controllers/MetricListContainer/MetricItemsContainer.tsx @@ -8,13 +8,12 @@ import { } from '@/components/features/metrics/StatusBadgeIndicator'; import { Avatar } from '@/components/ui/avatar'; import type { BusterListColumn, BusterListRowItem } from '@/components/ui/list'; -import { BusterList, ListEmptyStateWithButton } from '@/components/ui/list'; +import { BusterList, createLinkItem, ListEmptyStateWithButton } from '@/components/ui/list'; import { useCreateListByDate } from '@/components/ui/list/useCreateListByDate'; import { Text } from '@/components/ui/typography'; import { useMemoizedFn } from '@/hooks/useMemoizedFn'; import { formatDate } from '@/lib/date'; import { makeHumanReadble } from '@/lib/text'; -import type { OptionsTo } from '@/types/routes'; import { MetricSelectedOptionPopup } from './MetricItemsSelectedPopup'; export const MetricItemsContainer: React.FC<{ @@ -36,16 +35,18 @@ export const MetricItemsContainer: React.FC<{ const metricsByDate: BusterListRowItem[] = useMemo(() => { return Object.entries(logsRecord).flatMap>( ([key, metrics]) => { - const records = metrics.map((metric) => ({ - id: metric.id, - data: metric, - link: { - to: '/app/metrics/$metricId', - params: { - metricId: metric.id, + const records = metrics.map((metric) => + createLinkItem({ + id: metric.id, + data: metric, + link: { + to: '/app/metrics/$metricId', + params: { + metricId: metric.id, + }, }, - } satisfies OptionsTo, - })); + }) + ); const hasRecords = records.length > 0; if (!hasRecords) { return []; diff --git a/apps/web-tss/src/layouts/AssetContainer/MetricAssetContainer/MetricHeaderButtons.tsx b/apps/web-tss/src/layouts/AssetContainer/MetricAssetContainer/MetricHeaderButtons.tsx index a6f965c6d..725ab052f 100644 --- a/apps/web-tss/src/layouts/AssetContainer/MetricAssetContainer/MetricHeaderButtons.tsx +++ b/apps/web-tss/src/layouts/AssetContainer/MetricAssetContainer/MetricHeaderButtons.tsx @@ -1,5 +1,5 @@ import { Link } from '@tanstack/react-router'; -import React, { useMemo } from 'react'; +import React from 'react'; import { useGetMetric } from '@/api/buster_rest/metrics'; import { CreateChatButton } from '@/components/features/AssetLayout/CreateChatButton'; import { SaveMetricToCollectionButton } from '@/components/features/buttons/SaveMetricToCollectionButton'; @@ -7,8 +7,8 @@ import { SaveMetricToDashboardButton } from '@/components/features/buttons/SaveM import { ShareMetricButton } from '@/components/features/buttons/ShareMetricButton'; import { ThreeDotMenuButton } from '@/components/features/metrics/MetricThreeDotMenu'; import { SquareChartPen } from '@/components/ui/icons'; +import { useIsFileMode } from '@/context/Chats/useMode'; import { useIsMetricReadOnly } from '@/context/Metrics/useIsMetricReadOnly'; -import { useMemoizedFn } from '@/hooks/useMemoizedFn'; import { canEdit, getIsEffectiveOwner } from '@/lib/share'; import { FileButtonContainer } from '../FileButtonContainer'; import { HideButtonContainer } from '../HideButtonContainer'; @@ -18,6 +18,7 @@ export const MetricContainerHeaderButtons: React.FC<{ metricId: string; metricVersionNumber: number; }> = React.memo(({ metricId, metricVersionNumber }) => { + const isFileMode = useIsFileMode(); const { isViewingOldVersion } = useIsMetricReadOnly({ metricId: metricId || '', }); @@ -43,7 +44,7 @@ export const MetricContainerHeaderButtons: React.FC<{ isViewingOldVersion={isViewingOldVersion} versionNumber={metricVersionNumber} /> - + @@ -53,62 +54,49 @@ export const MetricContainerHeaderButtons: React.FC<{ MetricContainerHeaderButtons.displayName = 'MetricContainerHeaderButtons'; const EditChartButton = React.memo(({ metricId }: { metricId: string }) => { - const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage); - const selectedFileViewSecondary = useChatLayoutContextSelector( - (x) => x.selectedFileViewSecondary - ); - const chatId = useChatIndividualContextSelector((x) => x.chatId); - const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber); - const editableSecondaryView: MetricFileViewSecondary = 'chart-edit'; - const isSelectedView = selectedFileViewSecondary === editableSecondaryView; + const isEditorOpen = true; + // const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber); + // const editableSecondaryView: MetricFileViewSecondary = 'chart-edit'; + // const isSelectedView = selectedFileViewSecondary === editableSecondaryView; - const href = useMemo(() => { - if (isSelectedView) { - return assetParamsToRoute({ - chatId, - assetId: metricId, - type: 'metric', - secondaryView: undefined, - versionNumber: metricVersionNumber, - page: 'chart', - }); - } + // const href = useMemo(() => { + // if (isSelectedView) { + // return assetParamsToRoute({ + // chatId, + // assetId: metricId, + // type: 'metric', + // secondaryView: undefined, + // versionNumber: metricVersionNumber, + // page: 'chart', + // }); + // } - return assetParamsToRoute({ - chatId, - assetId: metricId, - type: 'metric', - secondaryView: 'chart-edit', - versionNumber: metricVersionNumber, - page: 'chart', - }); - }, [chatId, metricId, isSelectedView, metricVersionNumber]); - - //I HAVE NO IDEA WHY... but onClickButton is called twice if wrapped in a link - const onClickButton = useMemoizedFn(() => { - onChangePage(href, { shallow: true }); - }); + // return assetParamsToRoute({ + // chatId, + // assetId: metricId, + // type: 'metric', + // secondaryView: 'chart-edit', + // versionNumber: metricVersionNumber, + // page: 'chart', + // }); + // }, [chatId, metricId, isSelectedView, metricVersionNumber]); return ( { e.preventDefault(); e.stopPropagation(); }} - onMouseDown={(e) => { - e.preventDefault(); - e.stopPropagation(); - onClickButton(); - }} > } - selected={isSelectedView} + selected={isEditorOpen} /> ); diff --git a/apps/web-tss/src/lib/assets/assetParamsToRoute.ts b/apps/web-tss/src/lib/assets/assetParamsToRoute.ts index 9699cd652..37e5031b8 100644 --- a/apps/web-tss/src/lib/assets/assetParamsToRoute.ts +++ b/apps/web-tss/src/lib/assets/assetParamsToRoute.ts @@ -1,5 +1,5 @@ import type { FileRouteTypes } from '@/routeTree.gen'; -import type { OptionsTo } from '@/types/routes'; +import type { ILinkProps } from '@/types/routes'; type RouteFilePaths = FileRouteTypes['to']; @@ -269,7 +269,7 @@ class RouteBuilder> { /** * Build navigation options with route and params */ - buildNavigationOptions(): OptionsTo { + buildNavigationOptions(): ILinkProps { const route = this.build(); const params = this.getParams(); const search = this.getSearchParams(); @@ -289,7 +289,7 @@ class RouteBuilder> { } // Type assertion through unknown for complex generic type - return navOptions as OptionsTo; + return navOptions as unknown as ILinkProps; } /** @@ -425,7 +425,7 @@ class RouteBuilder> { * }); * // Result: { to: '/app/dashboards/dashboard-456', params: { dashboardId: 'dashboard-456', metricId: 'metric-789' }, search: { dashboard_version_number: 3, metric_version_number: 2 } } */ -export const assetParamsToRoute = (params: AssetParamsToRoute): OptionsTo => { +export const assetParamsToRoute = (params: AssetParamsToRoute): ILinkProps => { const builder = new RouteBuilder(); // Build route based on asset type and additional params diff --git a/apps/web-tss/src/types/routes.ts b/apps/web-tss/src/types/routes.ts index 999d1997c..9b4b7f6d1 100644 --- a/apps/web-tss/src/types/routes.ts +++ b/apps/web-tss/src/types/routes.ts @@ -14,7 +14,7 @@ export type ILinkOptions = Partial< >; export type ILinkProps< - TRouter extends RegisteredRouter, - TOptions, + TRouter extends RegisteredRouter = RegisteredRouter, + TOptions = Record, TFrom extends string = string, > = ValidateLinkOptions & ILinkOptions;