Skip to content

Commit 8bdc71c

Browse files
committed
revert(settings): restore the Insights page as it was before the settings page lane
1 parent cf584f1 commit 8bdc71c

12 files changed

Lines changed: 232 additions & 254 deletions

File tree

‎apps/sim/app/(product)/o/[organizationId]/settings/_components/sections/usage/activity.tsx‎

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
'use client'
22

3-
import type { ReactNode } from 'react'
43
import { Avatar } from '@sim/emcn/avatar'
4+
import { Button } from '@sim/emcn/button'
55
import { BarChart, TrendChart } from '@sim/emcn/chart/charts'
66
import { DataTable, MetricGroup, TableLabel } from '@sim/emcn/data-display'
77
import { EmptyState } from '@sim/emcn/empty-state'
88
import { ChoiceMenu } from '@sim/emcn/menu/choice-menu'
99
import { OverflowText } from '@sim/emcn/overflow-text'
1010
import { Pagination } from '@sim/emcn/pagination'
1111
import { FailureNotice } from '@sim/emcn/status'
12-
import {
13-
DetailHeader,
14-
SectionToolbar,
15-
} from '@/app/(product)/_components/settings-parts/settings-parts'
16-
import { UsageBlock } from '@/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-block'
1712
import styles from '@/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-section.module.css'
1813
import {
1914
type OrganizationUsageWindowKey,
@@ -31,7 +26,8 @@ interface ActivityOverviewProps {
3126

3227
function SummaryView({ summary }: { summary: ReturnType<typeof useActivitySummary> }) {
3328
return (
34-
<UsageBlock title='Activity'>
29+
<section className={styles.block} aria-label='Activity'>
30+
<h2 data-type='T093'>Activity</h2>
3531
{summary.failed ? (
3632
<FailureNotice message='Couldn’t load activity.' onRetry={summary.retry} />
3733
) : summary.pending ? null : (
@@ -45,14 +41,14 @@ function SummaryView({ summary }: { summary: ReturnType<typeof useActivitySummar
4541
series={summary.outcomeSeries}
4642
/>
4743
<p className={styles.quiet} data-type='T060'>
48-
Other includes cancelled, paused, and unfinished runs
44+
Other includes cancelled, paused, and unfinished runs.
4945
</p>
5046
</div>
5147
<TrendChart title='Chat runs' points={summary.chatPoints} />
5248
</div>
5349
</>
5450
)}
55-
</UsageBlock>
51+
</section>
5652
)
5753
}
5854

@@ -91,13 +87,7 @@ const COLUMNS_BY_DIMENSION = {
9187
],
9288
} as const
9389

94-
interface ActivityPanelProps {
95-
organizationId: string
96-
/** The period menu a drilled-into workspace shows under its own header. */
97-
period?: ReactNode
98-
}
99-
100-
export function ActivityPanel({ organizationId, period }: ActivityPanelProps) {
90+
export function ActivityPanel({ organizationId }: { organizationId: string }) {
10191
const view = useUsageView()
10292
const { window, workspace, activityDimension, activitySort, activityPage, setState } = view
10393
const workspaceId = workspace ?? undefined
@@ -111,32 +101,30 @@ export function ActivityPanel({ organizationId, period }: ActivityPanelProps) {
111101
activityPage,
112102
workspaceId
113103
)
114-
const header = workspace && (
115-
<>
116-
<DetailHeader
117-
backLabel='Activity'
118-
title={summary.workspaceName ?? 'Workspace activity'}
119-
onBack={() =>
120-
void setState({ workspace: null, activityDimension: 'workspace', activityPage: 0 })
121-
}
122-
/>
123-
{period && <SectionToolbar>{period}</SectionToolbar>}
124-
</>
125-
)
104+
const toAllWorkspaces = () =>
105+
void setState({ workspace: null, activityDimension: 'workspace', activityPage: 0 })
126106
if (workspace && summary.unavailable)
127107
return (
128-
<>
129-
{header}
130-
<EmptyState title='Workspace unavailable' />
131-
</>
108+
<EmptyState
109+
title='Workspace unavailable.'
110+
action={<Button onClick={toAllWorkspaces}>All workspaces</Button>}
111+
/>
132112
)
133113
const member = activityDimension === 'member'
134114
return (
135115
<>
136-
{header}
116+
{workspace && (
117+
<div className={styles.toolbar}>
118+
<Button variant='quiet' icon='I093' onClick={toAllWorkspaces}>
119+
All workspaces
120+
</Button>
121+
<span data-type='T067'>{summary.workspaceName ?? 'Workspace activity'}</span>
122+
</div>
123+
)}
137124
<SummaryView summary={summary} />
138-
<UsageBlock title='Breakdown'>
139-
<SectionToolbar>
125+
<section className={styles.block} aria-label='Breakdown'>
126+
<h2 data-type='T093'>Breakdown</h2>
127+
<div className={styles.toolbar}>
140128
<ChoiceMenu
141129
label='Group activity by'
142130
options={ACTIVITY_DIMENSIONS}
@@ -158,11 +146,11 @@ export function ActivityPanel({ organizationId, period }: ActivityPanelProps) {
158146
}
159147
/>
160148
)}
161-
</SectionToolbar>
149+
</div>
162150
{breakdown.failed ? (
163151
<FailureNotice message='Couldn’t load the breakdown.' onRetry={breakdown.retry} />
164152
) : !breakdown.rows ? null : breakdown.rows.length === 0 ? (
165-
<EmptyState title='No activity in this period' />
153+
<EmptyState title='No activity in this period.' />
166154
) : (
167155
<DataTable
168156
title='Activity breakdown'
@@ -221,7 +209,7 @@ export function ActivityPanel({ organizationId, period }: ActivityPanelProps) {
221209
onPageChange={(page) => void setState({ activityPage: page - 1 })}
222210
/>
223211
)}
224-
</UsageBlock>
212+
</section>
225213
</>
226214
)
227215
}

‎apps/sim/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-block.tsx‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

‎apps/sim/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-credits.dom.test.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ afterEach(() => {
2727
container.remove()
2828
})
2929

30-
it('paints nothing while the credits are still loading', () => {
30+
it('paints only the heading while the credits are still loading', () => {
3131
const pending = {
3232
dimmed: false,
3333
failed: false,
3434
retry: () => undefined,
3535
chart: { loaded: false, used: 0, limit: null, bars: [], series: [], seriesTotals: [] },
3636
} as unknown as ReturnType<typeof useUsageOverview>
37-
act(() => root.render(<UsageCredits overview={pending} />))
38-
expect(container.textContent).toBe('')
37+
act(() => root.render(<UsageCredits label='This month' overview={pending} />))
38+
expect(container.textContent).toBe('This month')
3939
})

‎apps/sim/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-credits.tsx‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ import styles from '@/app/(product)/o/[organizationId]/settings/_components/sect
66
import type { useUsageOverview } from '@/platform/lib/data/usage'
77
import { LOCALE } from '@/platform/shared/time'
88

9-
/**
10-
* Headline, allowance and the source-stacked credit chart for the toolbar's period. The chart titles
11-
* the group: the period is already named by the menu above it.
12-
*/
13-
export function UsageCredits({ overview }: { overview: ReturnType<typeof useUsageOverview> }) {
9+
/** Headline, allowance and the source-stacked credit chart for one window. */
10+
export function UsageCredits({
11+
label,
12+
overview,
13+
}: {
14+
label: string
15+
overview: ReturnType<typeof useUsageOverview>
16+
}) {
1417
const { chart } = overview
1518
return (
16-
<div className={styles.block} data-dimmed={overview.dimmed || undefined}>
19+
<section className={styles.block} aria-label={label} data-dimmed={overview.dimmed || undefined}>
20+
<h2 data-type='T093'>{label}</h2>
1721
{chart.loaded && (
1822
<div className={styles.figure}>
1923
<span data-type='T102'>{chart.used.toLocaleString(LOCALE)}</span>
@@ -42,6 +46,6 @@ export function UsageCredits({ overview }: { overview: ReturnType<typeof useUsag
4246
hideEmptySeries
4347
/>
4448
)}
45-
</div>
49+
</section>
4650
)
4751
}
Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use client'
22

3-
import { PeriodPicker } from '@/app/(product)/o/[organizationId]/settings/_components/sections/usage/period-picker'
4-
import { UsageLedger } from '@/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-ledger'
5-
import { exportUsageCsv, useUsageEvents, useUsageView } from '@/platform/lib/data/usage'
3+
import { DataTable } from '@sim/emcn/data-display'
4+
import { EmptyState } from '@sim/emcn/empty-state'
5+
import { FailureNotice } from '@sim/emcn/status'
6+
import { DetailHeader } from '@/app/(product)/_components/settings-parts/settings-parts'
7+
import styles from '@/app/(product)/o/[organizationId]/settings/_components/sections/usage/usage-section.module.css'
8+
import { useUsageEvents, useUsageView } from '@/platform/lib/data/usage'
69

710
const COLUMNS = [
811
{ key: 'when', label: 'When', kind: 'text' },
@@ -11,46 +14,41 @@ const COLUMNS = [
1114
{ key: 'credits', label: 'Credits', kind: 'text' },
1215
] as const
1316

14-
/** The raw ledger: Insights says whether spend is healthy, this says what a charge was. */
17+
/** The raw ledger: the panel says whether spend is healthy, this says what a charge was. */
1518
export function UsageEvents({ organizationId }: { organizationId: string }) {
16-
const view = useUsageView()
17-
const events = useUsageEvents(organizationId, view.window)
19+
const { window, backHref } = useUsageView()
20+
const events = useUsageEvents(organizationId, window)
1821
return (
19-
<UsageLedger
20-
backLabel='Insights'
21-
backHref={view.backHref}
22-
title='Usage events'
23-
description='Every credit-consuming event across your organization’s workspaces'
24-
period={
25-
<PeriodPicker
26-
options={view.periodOptions}
27-
value={view.currentPeriod}
28-
customValue={view.customPeriod}
29-
range={
30-
view.startDate && view.endDate ? { start: view.startDate, end: view.endDate } : null
31-
}
32-
onPreset={view.selectPeriod}
33-
onRange={view.applyRange}
34-
/>
35-
}
36-
columns={COLUMNS}
37-
rows={events.rows.map((event) => ({
38-
id: event.id,
39-
values: {
40-
when: event.when,
41-
label: event.label,
42-
description: event.description,
43-
credits: event.credits,
44-
},
45-
}))}
46-
loadMore={events.loadMore}
47-
pending={events.pending}
48-
failed={events.failed}
49-
dimmed={events.dimmed}
50-
retry={events.retry}
51-
subject='usage events'
52-
emptyTitle='No usage in this period'
53-
onExport={() => exportUsageCsv(organizationId, view.window)}
54-
/>
22+
<>
23+
<DetailHeader
24+
backLabel='Insights'
25+
backHref={backHref}
26+
title='Usage events'
27+
description='Every credit-consuming event across your organization’s workspaces'
28+
/>
29+
{events.failed && events.rows.length === 0 ? (
30+
<FailureNotice message='Couldn’t load usage events.' onRetry={events.retry} />
31+
) : events.pending ? null : events.rows.length === 0 ? (
32+
<EmptyState title='No usage in this period.' />
33+
) : (
34+
<div className={styles.dimmable} data-dimmed={events.dimmed || undefined}>
35+
<DataTable
36+
title='Usage events'
37+
titleHidden
38+
columns={COLUMNS}
39+
loadMore={events.loadMore}
40+
rows={events.rows.map((event) => ({
41+
id: event.id,
42+
values: {
43+
when: event.when,
44+
label: event.label,
45+
description: event.description,
46+
credits: event.credits,
47+
},
48+
}))}
49+
/>
50+
</div>
51+
)}
52+
</>
5553
)
5654
}

0 commit comments

Comments
 (0)