mirror of
https://github.com/baz-scm/awesome-reviewers.git
synced 2025-08-20 18:58:52 +03:00
104 lines
24 KiB
JSON
104 lines
24 KiB
JSON
[
|
|
{
|
|
"discussion_id": "2216640917",
|
|
"pr_number": 35030,
|
|
"pr_file": "frontend/src/scenes/insights/filters/ActionFilter/ActionFilterRow/ActionFilterRow.tsx",
|
|
"created_at": "2025-07-18T18:16:52+00:00",
|
|
"commented_code": "</>\n ),\n },\n+ {\n+ label: () => (\n+ <>\n+ {index > 0 && (\n+ <>\n+ <div className=\"px-2 py-1\">\n+ <LemonCheckbox\n+ checked={!!filter.optionalInFunnel}\n+ onChange={(checked) => {\n+ updateFilterOptional({\n+ ...filter,\n+ optionalInFunnel: checked,\n+ index,\n+ })\n+ }}\n+ label=\"Optional step\"",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"discussion_comments": [
|
|
{
|
|
"comment_id": "2216640917",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 35030,
|
|
"pr_file": "frontend/src/scenes/insights/filters/ActionFilter/ActionFilterRow/ActionFilterRow.tsx",
|
|
"discussion_id": "2216640917",
|
|
"commented_code": "@@ -580,6 +588,30 @@ export function ActionFilterRow({\n </>\n ),\n },\n+ {\n+ label: () => (\n+ <>\n+ {index > 0 && (\n+ <>\n+ <div className=\"px-2 py-1\">\n+ <LemonCheckbox\n+ checked={!!filter.optionalInFunnel}\n+ onChange={(checked) => {\n+ updateFilterOptional({\n+ ...filter,\n+ optionalInFunnel: checked,\n+ index,\n+ })\n+ }}\n+ label=\"Optional step\"",
|
|
"comment_created_at": "2025-07-18T18:16:52+00:00",
|
|
"comment_author": "zlwaterfield",
|
|
"comment_body": "I think it's worth adding a tooltip here / link to docs because it's not intuitive to me what happens around drop off calcs when this is checked. ",
|
|
"pr_file_module": null
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"discussion_id": "2272902970",
|
|
"pr_number": 36116,
|
|
"pr_file": "products/error_tracking/frontend/components/ExceptionCard/Tabs/SessionTab/SessionTimeline/SessionTimeline.tsx",
|
|
"created_at": "2025-08-13T10:37:26+00:00",
|
|
"commented_code": "+import { TabsPrimitiveContent, TabsPrimitiveContentProps } from 'lib/ui/TabsPrimitive/TabsPrimitive'\n+import { sessionTabLogic } from '../sessionTabLogic'\n+import { useActions, useValues } from 'kea'\n+import { IconVerticalAlignCenter } from 'lib/lemon-ui/icons'\n+import { ButtonPrimitive, ButtonPrimitiveProps } from 'lib/ui/Button/ButtonPrimitives'\n+import { errorPropertiesLogic } from 'lib/components/Errors/errorPropertiesLogic'\n+import { forwardRef, useCallback, useEffect, useMemo, useRef } from 'react'\n+import { cva } from 'cva'\n+import { dayjs } from 'lib/dayjs'\n+import { Link, Spinner } from '@posthog/lemon-ui'\n+import { exceptionCardLogic } from '../../../exceptionCardLogic'\n+import { useScrollObserver } from '../../../../../hooks/use-scroll-observer'\n+import { useAsyncCallback } from 'products/error_tracking/frontend/hooks/use-async-callback'\n+import { ItemCollector, ItemRenderer, RendererProps, TimelineItem } from './timeline'\n+import { cn } from 'lib/utils/css-classes'\n+\n+const LOADING_DEBOUNCE_OPTIONS = { leading: true, delay: 500 }\n+\n+export function SessionTimeline({ ...props }: TabsPrimitiveContentProps): JSX.Element {\n+ const { items, timestamp, sessionId, currentCategories } = useValues(sessionTabLogic)\n+ const { setItems, toggleCategory } = useActions(sessionTabLogic)\n+ const { uuid } = useValues(errorPropertiesLogic)\n+ const { currentSessionTab } = useValues(exceptionCardLogic)\n+\n+ const collector = useMemo(() => {\n+ // Add jitter to catch event at exact timestamp\n+ return new ItemCollector(sessionId, dayjs(timestamp).add(1, 'millisecond'))\n+ }, [sessionId, timestamp])\n+ const containerRef = useRef<HTMLDivElement | null>(null)\n+\n+ const scrollToItem = useCallback((uuid: string) => {\n+ const item = containerRef.current?.querySelector(`[data-item-id=\"${uuid}\"]`)\n+ if (item) {\n+ item.scrollIntoView({ behavior: 'instant', block: 'center' })\n+ }\n+ }, [])\n+\n+ const [loadBefore, beforeLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadBefore(currentCategories, 25).then(() => {\n+ const items = collector.collectItems()\n+ const containerEl = containerRef.current\n+ const scrollTop = containerEl?.scrollTop || 0\n+ const scrollHeight = containerEl?.scrollHeight || 0\n+ setItems(items)\n+ // Restore scroll position\n+ requestAnimationFrame(() => {\n+ const newScrollHeight = containerEl?.scrollHeight || 0\n+ if (containerEl) {\n+ containerEl.scrollTop = scrollTop + (newScrollHeight - scrollHeight)\n+ }\n+ })\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ const [loadAfter, afterLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadAfter(currentCategories, 25).then(() => {\n+ setItems(collector.collectItems())\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ useEffect(() => {\n+ collector.clear()\n+ Promise.all([loadBefore(), loadAfter()]).then(() => {\n+ const items = collector.collectItems()\n+ setItems(items)\n+ scrollToItem(uuid)\n+ })\n+ }, [collector, loadBefore, loadAfter, setItems, scrollToItem, uuid])\n+\n+ const scrollRefCb = useScrollObserver({\n+ onScrollTop: () => {\n+ if (collector.hasBefore(currentCategories)) {\n+ return loadBefore()\n+ }\n+ },\n+ onScrollBottom: () => {\n+ if (collector.hasAfter(currentCategories)) {\n+ return loadAfter()\n+ }\n+ },\n+ })\n+\n+ useEffect(() => {\n+ requestAnimationFrame(() => {\n+ // Scroll to item on tab change\n+ scrollToItem(uuid)\n+ })\n+ }, [uuid, scrollToItem, currentSessionTab])\n+\n+ return (\n+ <TabsPrimitiveContent {...props}>\n+ <div className=\"flex\">\n+ <div className=\"flex flex-col justify-between items-center p-1 border-r border-gray-3\">\n+ <div className=\"flex flex-col items-center gap-2\">\n+ {collector.getCategories().map((cat) => (\n+ <SessionGroupToggle\n+ active={currentCategories.includes(cat)}\n+ key={cat}\n+ onClick={() => toggleCategory(cat)}\n+ >\n+ {collector.getRenderer(cat)?.categoryIcon}\n+ </SessionGroupToggle>\n+ ))}\n+ </div>\n+ {items.find((item) => item.id === uuid) && (\n+ <ButtonPrimitive iconOnly onClick={() => scrollToItem(uuid)}>\n+ <IconVerticalAlignCenter />\n+ </ButtonPrimitive>",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"discussion_comments": [
|
|
{
|
|
"comment_id": "2272902970",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 36116,
|
|
"pr_file": "products/error_tracking/frontend/components/ExceptionCard/Tabs/SessionTab/SessionTimeline/SessionTimeline.tsx",
|
|
"discussion_id": "2272902970",
|
|
"commented_code": "@@ -0,0 +1,215 @@\n+import { TabsPrimitiveContent, TabsPrimitiveContentProps } from 'lib/ui/TabsPrimitive/TabsPrimitive'\n+import { sessionTabLogic } from '../sessionTabLogic'\n+import { useActions, useValues } from 'kea'\n+import { IconVerticalAlignCenter } from 'lib/lemon-ui/icons'\n+import { ButtonPrimitive, ButtonPrimitiveProps } from 'lib/ui/Button/ButtonPrimitives'\n+import { errorPropertiesLogic } from 'lib/components/Errors/errorPropertiesLogic'\n+import { forwardRef, useCallback, useEffect, useMemo, useRef } from 'react'\n+import { cva } from 'cva'\n+import { dayjs } from 'lib/dayjs'\n+import { Link, Spinner } from '@posthog/lemon-ui'\n+import { exceptionCardLogic } from '../../../exceptionCardLogic'\n+import { useScrollObserver } from '../../../../../hooks/use-scroll-observer'\n+import { useAsyncCallback } from 'products/error_tracking/frontend/hooks/use-async-callback'\n+import { ItemCollector, ItemRenderer, RendererProps, TimelineItem } from './timeline'\n+import { cn } from 'lib/utils/css-classes'\n+\n+const LOADING_DEBOUNCE_OPTIONS = { leading: true, delay: 500 }\n+\n+export function SessionTimeline({ ...props }: TabsPrimitiveContentProps): JSX.Element {\n+ const { items, timestamp, sessionId, currentCategories } = useValues(sessionTabLogic)\n+ const { setItems, toggleCategory } = useActions(sessionTabLogic)\n+ const { uuid } = useValues(errorPropertiesLogic)\n+ const { currentSessionTab } = useValues(exceptionCardLogic)\n+\n+ const collector = useMemo(() => {\n+ // Add jitter to catch event at exact timestamp\n+ return new ItemCollector(sessionId, dayjs(timestamp).add(1, 'millisecond'))\n+ }, [sessionId, timestamp])\n+ const containerRef = useRef<HTMLDivElement | null>(null)\n+\n+ const scrollToItem = useCallback((uuid: string) => {\n+ const item = containerRef.current?.querySelector(`[data-item-id=\"${uuid}\"]`)\n+ if (item) {\n+ item.scrollIntoView({ behavior: 'instant', block: 'center' })\n+ }\n+ }, [])\n+\n+ const [loadBefore, beforeLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadBefore(currentCategories, 25).then(() => {\n+ const items = collector.collectItems()\n+ const containerEl = containerRef.current\n+ const scrollTop = containerEl?.scrollTop || 0\n+ const scrollHeight = containerEl?.scrollHeight || 0\n+ setItems(items)\n+ // Restore scroll position\n+ requestAnimationFrame(() => {\n+ const newScrollHeight = containerEl?.scrollHeight || 0\n+ if (containerEl) {\n+ containerEl.scrollTop = scrollTop + (newScrollHeight - scrollHeight)\n+ }\n+ })\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ const [loadAfter, afterLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadAfter(currentCategories, 25).then(() => {\n+ setItems(collector.collectItems())\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ useEffect(() => {\n+ collector.clear()\n+ Promise.all([loadBefore(), loadAfter()]).then(() => {\n+ const items = collector.collectItems()\n+ setItems(items)\n+ scrollToItem(uuid)\n+ })\n+ }, [collector, loadBefore, loadAfter, setItems, scrollToItem, uuid])\n+\n+ const scrollRefCb = useScrollObserver({\n+ onScrollTop: () => {\n+ if (collector.hasBefore(currentCategories)) {\n+ return loadBefore()\n+ }\n+ },\n+ onScrollBottom: () => {\n+ if (collector.hasAfter(currentCategories)) {\n+ return loadAfter()\n+ }\n+ },\n+ })\n+\n+ useEffect(() => {\n+ requestAnimationFrame(() => {\n+ // Scroll to item on tab change\n+ scrollToItem(uuid)\n+ })\n+ }, [uuid, scrollToItem, currentSessionTab])\n+\n+ return (\n+ <TabsPrimitiveContent {...props}>\n+ <div className=\"flex\">\n+ <div className=\"flex flex-col justify-between items-center p-1 border-r border-gray-3\">\n+ <div className=\"flex flex-col items-center gap-2\">\n+ {collector.getCategories().map((cat) => (\n+ <SessionGroupToggle\n+ active={currentCategories.includes(cat)}\n+ key={cat}\n+ onClick={() => toggleCategory(cat)}\n+ >\n+ {collector.getRenderer(cat)?.categoryIcon}\n+ </SessionGroupToggle>\n+ ))}\n+ </div>\n+ {items.find((item) => item.id === uuid) && (\n+ <ButtonPrimitive iconOnly onClick={() => scrollToItem(uuid)}>\n+ <IconVerticalAlignCenter />\n+ </ButtonPrimitive>",
|
|
"comment_created_at": "2025-08-13T10:37:26+00:00",
|
|
"comment_author": "daibhin",
|
|
"comment_body": "Felt like all of these icons could have done with some form of tooltip. I wasn't entirely sure what they were doing as I clicked them",
|
|
"pr_file_module": null
|
|
},
|
|
{
|
|
"comment_id": "2273024888",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 36116,
|
|
"pr_file": "products/error_tracking/frontend/components/ExceptionCard/Tabs/SessionTab/SessionTimeline/SessionTimeline.tsx",
|
|
"discussion_id": "2272902970",
|
|
"commented_code": "@@ -0,0 +1,215 @@\n+import { TabsPrimitiveContent, TabsPrimitiveContentProps } from 'lib/ui/TabsPrimitive/TabsPrimitive'\n+import { sessionTabLogic } from '../sessionTabLogic'\n+import { useActions, useValues } from 'kea'\n+import { IconVerticalAlignCenter } from 'lib/lemon-ui/icons'\n+import { ButtonPrimitive, ButtonPrimitiveProps } from 'lib/ui/Button/ButtonPrimitives'\n+import { errorPropertiesLogic } from 'lib/components/Errors/errorPropertiesLogic'\n+import { forwardRef, useCallback, useEffect, useMemo, useRef } from 'react'\n+import { cva } from 'cva'\n+import { dayjs } from 'lib/dayjs'\n+import { Link, Spinner } from '@posthog/lemon-ui'\n+import { exceptionCardLogic } from '../../../exceptionCardLogic'\n+import { useScrollObserver } from '../../../../../hooks/use-scroll-observer'\n+import { useAsyncCallback } from 'products/error_tracking/frontend/hooks/use-async-callback'\n+import { ItemCollector, ItemRenderer, RendererProps, TimelineItem } from './timeline'\n+import { cn } from 'lib/utils/css-classes'\n+\n+const LOADING_DEBOUNCE_OPTIONS = { leading: true, delay: 500 }\n+\n+export function SessionTimeline({ ...props }: TabsPrimitiveContentProps): JSX.Element {\n+ const { items, timestamp, sessionId, currentCategories } = useValues(sessionTabLogic)\n+ const { setItems, toggleCategory } = useActions(sessionTabLogic)\n+ const { uuid } = useValues(errorPropertiesLogic)\n+ const { currentSessionTab } = useValues(exceptionCardLogic)\n+\n+ const collector = useMemo(() => {\n+ // Add jitter to catch event at exact timestamp\n+ return new ItemCollector(sessionId, dayjs(timestamp).add(1, 'millisecond'))\n+ }, [sessionId, timestamp])\n+ const containerRef = useRef<HTMLDivElement | null>(null)\n+\n+ const scrollToItem = useCallback((uuid: string) => {\n+ const item = containerRef.current?.querySelector(`[data-item-id=\"${uuid}\"]`)\n+ if (item) {\n+ item.scrollIntoView({ behavior: 'instant', block: 'center' })\n+ }\n+ }, [])\n+\n+ const [loadBefore, beforeLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadBefore(currentCategories, 25).then(() => {\n+ const items = collector.collectItems()\n+ const containerEl = containerRef.current\n+ const scrollTop = containerEl?.scrollTop || 0\n+ const scrollHeight = containerEl?.scrollHeight || 0\n+ setItems(items)\n+ // Restore scroll position\n+ requestAnimationFrame(() => {\n+ const newScrollHeight = containerEl?.scrollHeight || 0\n+ if (containerEl) {\n+ containerEl.scrollTop = scrollTop + (newScrollHeight - scrollHeight)\n+ }\n+ })\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ const [loadAfter, afterLoading] = useAsyncCallback(\n+ () =>\n+ collector.loadAfter(currentCategories, 25).then(() => {\n+ setItems(collector.collectItems())\n+ }),\n+ [collector, currentCategories],\n+ LOADING_DEBOUNCE_OPTIONS\n+ )\n+\n+ useEffect(() => {\n+ collector.clear()\n+ Promise.all([loadBefore(), loadAfter()]).then(() => {\n+ const items = collector.collectItems()\n+ setItems(items)\n+ scrollToItem(uuid)\n+ })\n+ }, [collector, loadBefore, loadAfter, setItems, scrollToItem, uuid])\n+\n+ const scrollRefCb = useScrollObserver({\n+ onScrollTop: () => {\n+ if (collector.hasBefore(currentCategories)) {\n+ return loadBefore()\n+ }\n+ },\n+ onScrollBottom: () => {\n+ if (collector.hasAfter(currentCategories)) {\n+ return loadAfter()\n+ }\n+ },\n+ })\n+\n+ useEffect(() => {\n+ requestAnimationFrame(() => {\n+ // Scroll to item on tab change\n+ scrollToItem(uuid)\n+ })\n+ }, [uuid, scrollToItem, currentSessionTab])\n+\n+ return (\n+ <TabsPrimitiveContent {...props}>\n+ <div className=\"flex\">\n+ <div className=\"flex flex-col justify-between items-center p-1 border-r border-gray-3\">\n+ <div className=\"flex flex-col items-center gap-2\">\n+ {collector.getCategories().map((cat) => (\n+ <SessionGroupToggle\n+ active={currentCategories.includes(cat)}\n+ key={cat}\n+ onClick={() => toggleCategory(cat)}\n+ >\n+ {collector.getRenderer(cat)?.categoryIcon}\n+ </SessionGroupToggle>\n+ ))}\n+ </div>\n+ {items.find((item) => item.id === uuid) && (\n+ <ButtonPrimitive iconOnly onClick={() => scrollToItem(uuid)}>\n+ <IconVerticalAlignCenter />\n+ </ButtonPrimitive>",
|
|
"comment_created_at": "2025-08-13T11:13:09+00:00",
|
|
"comment_author": "hpouillot",
|
|
"comment_body": "I agree I'll create a follow-up PR with those tooltips",
|
|
"pr_file_module": null
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"discussion_id": "2250699652",
|
|
"pr_number": 36080,
|
|
"pr_file": "frontend/src/scenes/surveys/CopySurveyLink.tsx",
|
|
"created_at": "2025-08-04T07:52:21+00:00",
|
|
"commented_code": "url.pathname = `/external_surveys/${surveyId}`\n copyToClipboard(url.toString(), 'survey link')\n }}\n+ className={className}\n+ size=\"small\"\n+ tooltip=\"Responses are anonymous. Add the distinct_id query parameter to identify the response.\"",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"discussion_comments": [
|
|
{
|
|
"comment_id": "2250699652",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 36080,
|
|
"pr_file": "frontend/src/scenes/surveys/CopySurveyLink.tsx",
|
|
"discussion_id": "2250699652",
|
|
"commented_code": "@@ -11,8 +11,11 @@ export function CopySurveyLink({ surveyId }: { surveyId: string }): JSX.Element\n url.pathname = `/external_surveys/${surveyId}`\n copyToClipboard(url.toString(), 'survey link')\n }}\n+ className={className}\n+ size=\"small\"\n+ tooltip=\"Responses are anonymous. Add the distinct_id query parameter to identify the response.\"",
|
|
"comment_created_at": "2025-08-04T07:52:21+00:00",
|
|
"comment_author": "marandaneto",
|
|
"comment_body": "```suggestion\r\n tooltip=\"Responses are anonymous by default. Add the distinct_id query parameter to identify the user.\"\r\n```",
|
|
"pr_file_module": null
|
|
},
|
|
{
|
|
"comment_id": "2250700109",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 36080,
|
|
"pr_file": "frontend/src/scenes/surveys/CopySurveyLink.tsx",
|
|
"discussion_id": "2250699652",
|
|
"commented_code": "@@ -11,8 +11,11 @@ export function CopySurveyLink({ surveyId }: { surveyId: string }): JSX.Element\n url.pathname = `/external_surveys/${surveyId}`\n copyToClipboard(url.toString(), 'survey link')\n }}\n+ className={className}\n+ size=\"small\"\n+ tooltip=\"Responses are anonymous. Add the distinct_id query parameter to identify the response.\"",
|
|
"comment_created_at": "2025-08-04T07:52:34+00:00",
|
|
"comment_author": "marandaneto",
|
|
"comment_body": "i link we should link to the docs here as wlel if possible",
|
|
"pr_file_module": null
|
|
},
|
|
{
|
|
"comment_id": "2252318860",
|
|
"repo_full_name": "PostHog/posthog",
|
|
"pr_number": 36080,
|
|
"pr_file": "frontend/src/scenes/surveys/CopySurveyLink.tsx",
|
|
"discussion_id": "2250699652",
|
|
"commented_code": "@@ -11,8 +11,11 @@ export function CopySurveyLink({ surveyId }: { surveyId: string }): JSX.Element\n url.pathname = `/external_surveys/${surveyId}`\n copyToClipboard(url.toString(), 'survey link')\n }}\n+ className={className}\n+ size=\"small\"\n+ tooltip=\"Responses are anonymous. Add the distinct_id query parameter to identify the response.\"",
|
|
"comment_created_at": "2025-08-04T18:47:26+00:00",
|
|
"comment_author": "lucasheriques",
|
|
"comment_body": "on the tooltip I don't think we can, supports only strings. but I have added it on the survey overview:\r\n\r\n",
|
|
"pr_file_module": null
|
|
}
|
|
]
|
|
}
|
|
] |