diff --git a/apps/desktop/renderer-architecture.json b/apps/desktop/renderer-architecture.json index 57999f4148..9cb3f55f8c 100644 --- a/apps/desktop/renderer-architecture.json +++ b/apps/desktop/renderer-architecture.json @@ -4257,7 +4257,7 @@ "unresolvedDependencies": 0, "actionFactories": [], "dependencyPaths": { - "../../shared/runtime-host-identity.js": 1, + "../features/usage-activity": 1, "../locales/settings-usage-copy": 1, "./settings-error-copy": 1, "./settings-metric-card": 1, diff --git a/apps/desktop/src/renderer/features/usage-activity/index.ts b/apps/desktop/src/renderer/features/usage-activity/index.ts new file mode 100644 index 0000000000..68c9428844 --- /dev/null +++ b/apps/desktop/src/renderer/features/usage-activity/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { + shortUsageActivitySessionId, + UsageActivityPagination, + type UsageActivityPage, +} from './ui/usage-activity-pagination.js'; diff --git a/apps/desktop/src/renderer/features/usage-activity/ui/usage-activity-pagination.tsx b/apps/desktop/src/renderer/features/usage-activity/ui/usage-activity-pagination.tsx new file mode 100644 index 0000000000..5cbd00b1a4 --- /dev/null +++ b/apps/desktop/src/renderer/features/usage-activity/ui/usage-activity-pagination.tsx @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Pagination, paginateData } from '@astryxdesign/core'; +import { HStack } from '@maka/ui'; +import { useState, type ReactNode } from 'react'; +import { parseDesktopSessionKey } from '../../../../shared/runtime-host-identity.js'; + +export interface UsageActivityPage { + items: Item[]; + rowIndexStart: number; + rowCount: number; + reset(): void; +} + +export function UsageActivityPagination(props: { + items: Item[]; + pageSize: number; + children(page: UsageActivityPage): ReactNode; +}) { + const [page, setPage] = useState(1); + const pageCount = Math.max(1, Math.ceil(props.items.length / props.pageSize)); + const currentPage = Math.min(page, pageCount); + + return ( + <> + {props.children({ + items: paginateData(props.items, currentPage, props.pageSize), + rowIndexStart: (currentPage - 1) * props.pageSize + 1, + rowCount: props.items.length, + reset: () => setPage(1), + })} + {pageCount > 1 ? ( + + + + ) : null} + + ); +} + +export function shortUsageActivitySessionId(sessionKey: string) { + try { + return shortenSessionId(parseDesktopSessionKey(sessionKey).sessionId); + } catch { + return shortenSessionId(sessionKey); + } +} + +function shortenSessionId(sessionId: string) { + return sessionId.length > 8 ? sessionId.slice(0, 8) : sessionId; +} diff --git a/apps/desktop/src/renderer/settings/usage-settings-page.tsx b/apps/desktop/src/renderer/settings/usage-settings-page.tsx index 87c9860f2f..52c40ae298 100644 --- a/apps/desktop/src/renderer/settings/usage-settings-page.tsx +++ b/apps/desktop/src/renderer/settings/usage-settings-page.tsx @@ -33,7 +33,6 @@ import { proportional, } from '@astryxdesign/core'; import { uiLocaleToIntlLocale } from '@maka/core/ui-locale'; -import { parseDesktopSessionKey } from '../../shared/runtime-host-identity.js'; import { type AppSettings, type UpdateAppSettingsResult, @@ -51,6 +50,11 @@ import { Banner, } from '@maka/ui'; import { ICON_SIZE, Activity, BarChart3, Cpu, Database, RefreshCcw, Search } from '@maka/ui/icons'; +import { + shortUsageActivitySessionId, + UsageActivityPagination, + type UsageActivityPage, +} from '../features/usage-activity'; import { getUsageSettingsCopy, type UsageSettingsCopy, @@ -63,6 +67,8 @@ import { useOptimisticSettingsDraft } from './use-optimistic-settings-draft'; type UsageActiveTab = AppSettings['usage']['activeTab']; +const USAGE_REQUESTS_PAGE_SIZE = 50; + export function UsageSettingsPage(props: { settings: AppSettings; stats: UsageStats | null; @@ -303,13 +309,25 @@ function UsageRequestsPanel(props: { endContent={