From 515d18ac77473d658bdce6b3625ad6b1b674c02f Mon Sep 17 00:00:00 2001 From: isabellaenriquez Date: Tue, 4 Nov 2025 11:07:43 -0500 Subject: [PATCH 1/3] feat(sub v3): Update usage log component --- static/app/components/timeline/index.tsx | 24 ++-- .../gsApp/views/subscriptionPage/usageLog.tsx | 135 ++++++++---------- 2 files changed, 75 insertions(+), 84 deletions(-) diff --git a/static/app/components/timeline/index.tsx b/static/app/components/timeline/index.tsx index 5f303b01ad67d3..6c0c363a5cc563 100644 --- a/static/app/components/timeline/index.tsx +++ b/static/app/components/timeline/index.tsx @@ -7,7 +7,6 @@ import type {Color} from 'sentry/utils/theme'; import {isChonkTheme} from 'sentry/utils/theme/withChonk'; export interface TimelineItemProps { - icon: React.ReactNode; title: React.ReactNode; children?: React.ReactNode; className?: string; @@ -16,6 +15,7 @@ export interface TimelineItemProps { iconBorder: string | Color; title: string | Color; }; + icon?: React.ReactNode; isActive?: boolean; onClick?: React.MouseEventHandler; onMouseEnter?: React.MouseEventHandler; @@ -45,15 +45,19 @@ function Item({ return ( - - {icon} - + {icon ? ( + + {icon} + + ) : ( + + )} {title} {timestamp ??
} diff --git a/static/gsApp/views/subscriptionPage/usageLog.tsx b/static/gsApp/views/subscriptionPage/usageLog.tsx index 513c7cf8517a7e..8f7528b398f4f6 100644 --- a/static/gsApp/views/subscriptionPage/usageLog.tsx +++ b/static/gsApp/views/subscriptionPage/usageLog.tsx @@ -1,18 +1,22 @@ import {Fragment} from 'react'; +import {useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import type {Location} from 'history'; import upperFirst from 'lodash/upperFirst'; -import {ActivityAvatar} from 'sentry/components/activity/item/avatar'; -import {UserAvatar} from 'sentry/components/core/avatar/userAvatar'; +import {Flex} from '@sentry/scraps/layout'; + +// import {ActivityAvatar} from 'sentry/components/activity/item/avatar'; +// import {UserAvatar} from 'sentry/components/core/avatar/userAvatar'; import {Tag} from 'sentry/components/core/badge/tag'; import {CompactSelect} from 'sentry/components/core/compactSelect'; import {DateTime} from 'sentry/components/dateTime'; import LoadingError from 'sentry/components/loadingError'; import type {CursorHandler} from 'sentry/components/pagination'; import Pagination from 'sentry/components/pagination'; -import {PanelTable} from 'sentry/components/panels/panelTable'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; +import {Timeline} from 'sentry/components/timeline'; +import {IconCircleFill} from 'sentry/icons'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {AuditLog} from 'sentry/types/organization'; @@ -33,26 +37,26 @@ import SubscriptionPageContainer from 'getsentry/views/subscriptionPage/componen import SubscriptionHeader from './subscriptionHeader'; -const avatarStyle = { - width: 36, - height: 36, - marginRight: space(1), -}; +// const avatarStyle = { +// width: 36, +// height: 36, +// marginRight: space(1), +// }; -function LogAvatar({logEntryUser}: {logEntryUser: User | undefined}) { - // Display Sentry's avatar for system or superuser-initiated events - if ( - logEntryUser?.isSuperuser || - (logEntryUser?.name === 'Sentry' && logEntryUser?.email === undefined) - ) { - return ; - } - // Display user's avatar for non-superusers-initiated events - if (logEntryUser !== undefined) { - return ; - } - return null; -} +// function LogAvatar({logEntryUser}: {logEntryUser: User | undefined}) { +// // Display Sentry's avatar for system or superuser-initiated events +// if ( +// logEntryUser?.isSuperuser || +// (logEntryUser?.name === 'Sentry' && logEntryUser?.email === undefined) +// ) { +// return ; +// } +// // Display user's avatar for non-superusers-initiated events +// if (logEntryUser !== undefined) { +// return ; +// } +// return null; +// } function LogUsername({logEntryUser}: {logEntryUser: User | undefined}) { if (logEntryUser?.isSuperuser) { @@ -98,9 +102,10 @@ type Props = { function UsageLog({location, subscription}: Props) { const organization = useOrganization(); const navigate = useNavigate(); + const theme = useTheme(); const { data: auditLogs, - isPending, + // isPending, isError, getResponseHeader, refetch, @@ -179,36 +184,37 @@ function UsageLog({location, subscription}: Props) { {isError ? ( ) : ( - - {auditLogs?.rows.map(entry => ( - - -
- -
- + + {auditLogs?.rows.map((entry, index) => ( + } + title={ + + {formatEntryTitle(entry.event)}{' '} - {formatEntryTitle(entry.event)} - {formatEntryMessage(entry.note)} - -
- - - - - -
+ + } + timestamp={ + + + + + } + > + {formatEntryMessage(entry.note)} + ))} -
+ )} @@ -236,13 +242,14 @@ function UsageLog({location, subscription}: Props) { export default withSubscription(UsageLog); export {UsageLog}; -const SentryAvatar = styled(ActivityAvatar)` - margin-right: ${space(1)}; -`; +// const SentryAvatar = styled(ActivityAvatar)` +// margin-right: ${space(1)}; +// `; const Note = styled('div')` font-size: ${p => p.theme.fontSize.md}; word-break: break-word; + font-weight: normal; `; const StaffNote = styled(Note)` @@ -257,26 +264,6 @@ const UsageLogContainer = styled('div')` gap: ${space(3)}; `; -const UsageTable = styled(PanelTable)` - box-shadow: inset 0px -1px 0px ${p => p.theme.gray200}; -`; - -const UserInfo = styled('div')` - font-size: ${p => p.theme.fontSize.sm}; - min-width: 250px; - display: flex; -`; - -const NoteContainer = styled('div')` - display: flex; - flex-direction: column; - justify-content: center; -`; - -const Title = styled('div')` - font-size: ${p => p.theme.fontSize.lg}; -`; - const TimestampInfo = styled('div')` display: grid; grid-template-columns: max-content auto; From ad1acfaee2e3c216858dcddbd7278709ffeb4613 Mon Sep 17 00:00:00 2001 From: isabellaenriquez Date: Tue, 4 Nov 2025 15:00:35 -0500 Subject: [PATCH 2/3] fixes --- static/app/components/timeline/index.tsx | 9 +- .../gsApp/views/subscriptionPage/usageLog.tsx | 167 ++++++++---------- 2 files changed, 81 insertions(+), 95 deletions(-) diff --git a/static/app/components/timeline/index.tsx b/static/app/components/timeline/index.tsx index 6c0c363a5cc563..770e4e370f82a0 100644 --- a/static/app/components/timeline/index.tsx +++ b/static/app/components/timeline/index.tsx @@ -2,6 +2,8 @@ import type {CSSProperties} from 'react'; import {useTheme, type Theme} from '@emotion/react'; import styled from '@emotion/styled'; +import {Flex} from '@sentry/scraps/layout'; + import {space} from 'sentry/styles/space'; import type {Color} from 'sentry/utils/theme'; import {isChonkTheme} from 'sentry/utils/theme/withChonk'; @@ -24,6 +26,7 @@ export interface TimelineItemProps { showLastLine?: boolean; style?: CSSProperties; timestamp?: React.ReactNode; + titleTrailingItems?: React.ReactNode; } function Item({ @@ -33,6 +36,7 @@ function Item({ colorConfig, timestamp, isActive = false, + titleTrailingItems, ref, ...props }: TimelineItemProps) { @@ -58,7 +62,10 @@ function Item({ ) : ( )} - {title} + + {title} + {titleTrailingItems} + {timestamp ??
} {children} diff --git a/static/gsApp/views/subscriptionPage/usageLog.tsx b/static/gsApp/views/subscriptionPage/usageLog.tsx index 8f7528b398f4f6..9ed80f5fcc896c 100644 --- a/static/gsApp/views/subscriptionPage/usageLog.tsx +++ b/static/gsApp/views/subscriptionPage/usageLog.tsx @@ -1,27 +1,25 @@ import {Fragment} from 'react'; import {useTheme} from '@emotion/react'; -import styled from '@emotion/styled'; import type {Location} from 'history'; import upperFirst from 'lodash/upperFirst'; -import {Flex} from '@sentry/scraps/layout'; +import {Container, Flex, Grid} from '@sentry/scraps/layout'; +import {Text} from '@sentry/scraps/text'; -// import {ActivityAvatar} from 'sentry/components/activity/item/avatar'; -// import {UserAvatar} from 'sentry/components/core/avatar/userAvatar'; import {Tag} from 'sentry/components/core/badge/tag'; import {CompactSelect} from 'sentry/components/core/compactSelect'; import {DateTime} from 'sentry/components/dateTime'; import LoadingError from 'sentry/components/loadingError'; import type {CursorHandler} from 'sentry/components/pagination'; import Pagination from 'sentry/components/pagination'; +import Placeholder from 'sentry/components/placeholder'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {Timeline} from 'sentry/components/timeline'; import {IconCircleFill} from 'sentry/icons'; import {t} from 'sentry/locale'; -import {space} from 'sentry/styles/space'; import type {AuditLog} from 'sentry/types/organization'; import type {User} from 'sentry/types/user'; -import {shouldUse24Hours} from 'sentry/utils/dates'; +import {getTimeFormat} from 'sentry/utils/dates'; import {useApiQuery} from 'sentry/utils/queryClient'; import {decodeScalar} from 'sentry/utils/queryString'; import {useMemoWithPrevious} from 'sentry/utils/useMemoWithPrevious'; @@ -37,38 +35,24 @@ import SubscriptionPageContainer from 'getsentry/views/subscriptionPage/componen import SubscriptionHeader from './subscriptionHeader'; -// const avatarStyle = { -// width: 36, -// height: 36, -// marginRight: space(1), -// }; - -// function LogAvatar({logEntryUser}: {logEntryUser: User | undefined}) { -// // Display Sentry's avatar for system or superuser-initiated events -// if ( -// logEntryUser?.isSuperuser || -// (logEntryUser?.name === 'Sentry' && logEntryUser?.email === undefined) -// ) { -// return ; -// } -// // Display user's avatar for non-superusers-initiated events -// if (logEntryUser !== undefined) { -// return ; -// } -// return null; -// } - function LogUsername({logEntryUser}: {logEntryUser: User | undefined}) { if (logEntryUser?.isSuperuser) { return ( - - {logEntryUser.name} + + + {logEntryUser.name} + {t('Sentry Staff')} - + ); } + if (logEntryUser?.name !== 'Sentry' && logEntryUser !== undefined) { - return {logEntryUser.name}; + return ( + + {logEntryUser.name} + + ); } return null; } @@ -99,13 +83,24 @@ type Props = { subscription: Subscription; }; +function SkeletonEntry() { + return ( + } + icon={} + > + + + ); +} + function UsageLog({location, subscription}: Props) { const organization = useOrganization(); const navigate = useNavigate(); const theme = useTheme(); const { data: auditLogs, - // isPending, + isPending, isError, getResponseHeader, refetch, @@ -122,7 +117,6 @@ function UsageLog({location, subscription}: Props) { {staleTime: 0} ); - // const eventNames = useMemoWithPrevious( previous => auditLogs?.eventNames ?? previous, [auditLogs?.eventNames] @@ -165,7 +159,7 @@ function UsageLog({location, subscription}: Props) { const usageLogContent = ( - + {isError ? ( + ) : auditLogs?.rows?.length === 0 ? ( + {t('No entries available.')} ) : ( - {auditLogs?.rows.map((entry, index) => ( - } - title={ - - {formatEntryTitle(entry.event)}{' '} - - - } - timestamp={ - - - - - } - > - {formatEntryMessage(entry.note)} - - ))} + {isPending + ? Array.from({length: 50}).map((_, index) => ) + : auditLogs?.rows.map((entry, index) => ( + } + title={formatEntryTitle(entry.event)} + titleTrailingItems={ + + + {' ・ '} + + + + + {entry.actor && entry.actor.name !== 'Sentry' && ( + + + {' ・ '} + + + + )} + + } + > + + + {formatEntryMessage(entry.note)} + + + + ))} )} - + ); @@ -241,33 +250,3 @@ function UsageLog({location, subscription}: Props) { export default withSubscription(UsageLog); export {UsageLog}; - -// const SentryAvatar = styled(ActivityAvatar)` -// margin-right: ${space(1)}; -// `; - -const Note = styled('div')` - font-size: ${p => p.theme.fontSize.md}; - word-break: break-word; - font-weight: normal; -`; - -const StaffNote = styled(Note)` - display: flex; - gap: ${space(1)}; - line-height: 1.5; -`; - -const UsageLogContainer = styled('div')` - display: grid; - grid-auto-flow: row; - gap: ${space(3)}; -`; - -const TimestampInfo = styled('div')` - display: grid; - grid-template-columns: max-content auto; - gap: ${space(1)}; - font-size: ${p => p.theme.fontSize.md}; - align-content: center; -`; From 2355f746e327246365c75fa1628c636aae75466a Mon Sep 17 00:00:00 2001 From: isabellaenriquez Date: Wed, 5 Nov 2025 09:04:31 -0500 Subject: [PATCH 3/3] incr max width --- static/gsApp/views/subscriptionPage/usageLog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/gsApp/views/subscriptionPage/usageLog.tsx b/static/gsApp/views/subscriptionPage/usageLog.tsx index 9ed80f5fcc896c..e39c5b135eae5d 100644 --- a/static/gsApp/views/subscriptionPage/usageLog.tsx +++ b/static/gsApp/views/subscriptionPage/usageLog.tsx @@ -216,7 +216,7 @@ function UsageLog({location, subscription}: Props) { } > - + {formatEntryMessage(entry.note)}