From 69f9415e45c29c9ce543e5043a8fdd915d4d847f Mon Sep 17 00:00:00 2001 From: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com> Date: Mon, 17 Aug 2026 01:43:33 +0800 Subject: [PATCH] Add Projects panel to Usage & Spend pane --- CHANGELOG.md | 1 + .../PreferencesSpendDashboardPane.swift | 87 ++++++++++++++++++- .../Resources/ar.lproj/Localizable.strings | 2 + .../Resources/ca.lproj/Localizable.strings | 2 + .../Resources/de.lproj/Localizable.strings | 2 + .../Resources/en.lproj/Localizable.strings | 2 + .../Resources/es.lproj/Localizable.strings | 2 + .../Resources/fa.lproj/Localizable.strings | 2 + .../Resources/fr.lproj/Localizable.strings | 2 + .../Resources/gl.lproj/Localizable.strings | 2 + .../Resources/id.lproj/Localizable.strings | 2 + .../Resources/it.lproj/Localizable.strings | 2 + .../Resources/ja.lproj/Localizable.strings | 2 + .../Resources/ko.lproj/Localizable.strings | 2 + .../Resources/nl.lproj/Localizable.strings | 2 + .../Resources/pl.lproj/Localizable.strings | 2 + .../Resources/pt-BR.lproj/Localizable.strings | 2 + .../Resources/ru.lproj/Localizable.strings | 2 + .../Resources/sv.lproj/Localizable.strings | 2 + .../Resources/th.lproj/Localizable.strings | 2 + .../Resources/tr.lproj/Localizable.strings | 2 + .../Resources/uk.lproj/Localizable.strings | 2 + .../Resources/vi.lproj/Localizable.strings | 2 + .../zh-Hans.lproj/Localizable.strings | 2 + .../zh-Hant.lproj/Localizable.strings | 2 + 25 files changed, 133 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d76b2a98..b6f43dc1c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added - Usage & Spend: aggregate per-project spend into ranked, window-scoped rows and carry project/session breakdowns through the cached Codex prefill so the dashboard and the menu chart agree on project data. Thanks @Yuxin-Qiao! +- Usage & Spend: add a Projects panel to the settings pane and let the Models and Projects lists expand beyond the top eight rows. Thanks @Yuxin-Qiao! ## 0.50.1 — 2026-08-16 diff --git a/Sources/CodexBar/PreferencesSpendDashboardPane.swift b/Sources/CodexBar/PreferencesSpendDashboardPane.swift index d29681f4dd..5a5a546b7b 100644 --- a/Sources/CodexBar/PreferencesSpendDashboardPane.swift +++ b/Sources/CodexBar/PreferencesSpendDashboardPane.swift @@ -452,6 +452,9 @@ private struct SpendCurrencySection: View { SpendProviderPanel(group: self.group) SpendModelPanel(group: self.group) + if !self.group.projects.isEmpty { + SpendProjectPanel(group: self.group) + } SpendDailyChart(group: self.group) } } @@ -507,6 +510,9 @@ private struct SpendProviderPanel: View { private struct SpendModelPanel: View { let group: SpendDashboardModel.CurrencyGroup + @State private var showsAllRows = false + + private static let collapsedRowCount = 8 var body: some View { SpendDashboardPanel { @@ -529,7 +535,7 @@ private struct SpendModelPanel: View { .foregroundStyle(.secondary) .padding(.bottom, 6) } - ForEach(self.group.models.prefix(8)) { row in + ForEach(self.visibleRows) { row in if row.rank > 1 { Divider() } @@ -558,10 +564,89 @@ private struct SpendModelPanel: View { } .padding(.vertical, 9) } + SpendPanelExpandButton( + rowCount: self.group.models.count, + collapsedRowCount: Self.collapsedRowCount, + showsAllRows: self.$showsAllRows) } } } } + + private var visibleRows: ArraySlice { + self.group.models.prefix( + self.showsAllRows ? self.group.models.count : Self.collapsedRowCount) + } +} + +private struct SpendProjectPanel: View { + let group: SpendDashboardModel.CurrencyGroup + @State private var showsAllRows = false + + private static let collapsedRowCount = 8 + + var body: some View { + SpendDashboardPanel { + VStack(alignment: .leading, spacing: 0) { + Text(L("Projects")).font(.headline).padding(.bottom, 8) + ForEach(self.visibleRows) { row in + if row.rank > 1 { + Divider() + } + HStack(spacing: 10) { + Text(spendDashboardRankText(row.rank)) + .font(.caption.monospacedDigit()) + .foregroundStyle(.tertiary) + .frame(width: 26, alignment: .leading) + Image(systemName: "folder") + .font(.caption) + .foregroundStyle(.tertiary) + VStack(alignment: .leading, spacing: 2) { + Text(row.projectName).lineLimit(1) + Text(row.providerName).font(.caption).foregroundStyle(.secondary) + } + Spacer() + Text(row.totalCost.map { + UsageFormatter.currencyString($0, currencyCode: self.group.currencyCode) + } ?? "—") + .monospacedDigit() + } + .padding(.vertical, 9) + } + SpendPanelExpandButton( + rowCount: self.group.projects.count, + collapsedRowCount: Self.collapsedRowCount, + showsAllRows: self.$showsAllRows) + } + } + } + + private var visibleRows: ArraySlice { + self.group.projects.prefix( + self.showsAllRows ? self.group.projects.count : Self.collapsedRowCount) + } +} + +private struct SpendPanelExpandButton: View { + let rowCount: Int + let collapsedRowCount: Int + @Binding var showsAllRows: Bool + + var body: some View { + if self.rowCount > self.collapsedRowCount { + Button { + self.showsAllRows.toggle() + } label: { + Text( + self.showsAllRows + ? L("Show less") + : L("Show all (%d)", self.rowCount)) + .font(.caption) + } + .buttonStyle(.borderless) + .padding(.top, 6) + } + } } struct SpendDailyChartPresentation: Equatable { diff --git a/Sources/CodexBar/Resources/ar.lproj/Localizable.strings b/Sources/CodexBar/Resources/ar.lproj/Localizable.strings index a1add5270e..9687977e23 100644 --- a/Sources/CodexBar/Resources/ar.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/ar.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "إظهار الكل (%d)"; +"Show less" = "إظهار أقل"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/ca.lproj/Localizable.strings b/Sources/CodexBar/Resources/ca.lproj/Localizable.strings index f0ce9c6813..940b1deeec 100644 --- a/Sources/CodexBar/Resources/ca.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/ca.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Mostra-ho tot (%d)"; +"Show less" = "Mostra menys"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/de.lproj/Localizable.strings b/Sources/CodexBar/Resources/de.lproj/Localizable.strings index 0cda3a177a..3bab879f98 100644 --- a/Sources/CodexBar/Resources/de.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/de.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Alle anzeigen (%d)"; +"Show less" = "Weniger anzeigen"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/en.lproj/Localizable.strings b/Sources/CodexBar/Resources/en.lproj/Localizable.strings index d2ffdf0529..823283ab28 100644 --- a/Sources/CodexBar/Resources/en.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/en.lproj/Localizable.strings @@ -111,6 +111,8 @@ "Could not switch system account" = "Could not switch system account"; "Credits" = "Credits"; "Individual credits" = "Individual credits"; +"Show all (%d)" = "Show all (%d)"; +"Show less" = "Show less"; "Workspace" = "Workspace"; "Credits history" = "Credits history"; "Cursor login failed" = "Cursor login failed"; diff --git a/Sources/CodexBar/Resources/es.lproj/Localizable.strings b/Sources/CodexBar/Resources/es.lproj/Localizable.strings index a6726934f3..5a42b29b8b 100644 --- a/Sources/CodexBar/Resources/es.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/es.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Mostrar todo (%d)"; +"Show less" = "Mostrar menos"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/fa.lproj/Localizable.strings b/Sources/CodexBar/Resources/fa.lproj/Localizable.strings index 2989520621..8d71b6c9b7 100644 --- a/Sources/CodexBar/Resources/fa.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/fa.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "نمایش همه (%d)"; +"Show less" = "نمایش کمتر"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/fr.lproj/Localizable.strings b/Sources/CodexBar/Resources/fr.lproj/Localizable.strings index 2074575c7d..6bf47bc760 100644 --- a/Sources/CodexBar/Resources/fr.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/fr.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Tout afficher (%d)"; +"Show less" = "Afficher moins"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/gl.lproj/Localizable.strings b/Sources/CodexBar/Resources/gl.lproj/Localizable.strings index 29cef092ca..703a171a50 100644 --- a/Sources/CodexBar/Resources/gl.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/gl.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Mostrar todo (%d)"; +"Show less" = "Mostrar menos"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/id.lproj/Localizable.strings b/Sources/CodexBar/Resources/id.lproj/Localizable.strings index 2c023e04d5..de000246ff 100644 --- a/Sources/CodexBar/Resources/id.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/id.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Tampilkan semua (%d)"; +"Show less" = "Tampilkan lebih sedikit"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/it.lproj/Localizable.strings b/Sources/CodexBar/Resources/it.lproj/Localizable.strings index e5c84c1902..f8921508b7 100644 --- a/Sources/CodexBar/Resources/it.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/it.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "Sincronizzazione iCloud"; +"Show all (%d)" = "Mostra tutto (%d)"; +"Show less" = "Mostra meno"; "Sync settings and providers across your Macs via iCloud" = "Sincronizza impostazioni e provider sui tuoi Mac tramite iCloud"; "Include API keys, cookies, and tokens" = "Includi chiavi API, cookie e token"; "Sync usage snapshots" = "Sincronizza istantanee di utilizzo"; diff --git a/Sources/CodexBar/Resources/ja.lproj/Localizable.strings b/Sources/CodexBar/Resources/ja.lproj/Localizable.strings index 5450527094..62376e4b0f 100644 --- a/Sources/CodexBar/Resources/ja.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/ja.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "すべて表示(%d)"; +"Show less" = "表示を減らす"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/ko.lproj/Localizable.strings b/Sources/CodexBar/Resources/ko.lproj/Localizable.strings index c2c4694371..4f5f0df2c1 100644 --- a/Sources/CodexBar/Resources/ko.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/ko.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "모두 보기(%d)"; +"Show less" = "간략히 보기"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/nl.lproj/Localizable.strings b/Sources/CodexBar/Resources/nl.lproj/Localizable.strings index 8c6d008070..93257a3bee 100644 --- a/Sources/CodexBar/Resources/nl.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/nl.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Alles tonen (%d)"; +"Show less" = "Minder tonen"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/pl.lproj/Localizable.strings b/Sources/CodexBar/Resources/pl.lproj/Localizable.strings index 9ebff1f3be..fd1a6e366e 100644 --- a/Sources/CodexBar/Resources/pl.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/pl.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Pokaż wszystko (%d)"; +"Show less" = "Pokaż mniej"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings b/Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings index 5df8ca2590..72cf7b4e71 100644 --- a/Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/pt-BR.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Mostrar tudo (%d)"; +"Show less" = "Mostrar menos"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/ru.lproj/Localizable.strings b/Sources/CodexBar/Resources/ru.lproj/Localizable.strings index fe49292d0a..07d3881f05 100644 --- a/Sources/CodexBar/Resources/ru.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/ru.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Показать все (%d)"; +"Show less" = "Показать меньше"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/sv.lproj/Localizable.strings b/Sources/CodexBar/Resources/sv.lproj/Localizable.strings index 54788af8b7..66cf096242 100644 --- a/Sources/CodexBar/Resources/sv.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/sv.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Visa alla (%d)"; +"Show less" = "Visa färre"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/th.lproj/Localizable.strings b/Sources/CodexBar/Resources/th.lproj/Localizable.strings index 01d882f2a3..78a355d4c2 100644 --- a/Sources/CodexBar/Resources/th.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/th.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "แสดงทั้งหมด (%d)"; +"Show less" = "แสดงน้อยลง"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/tr.lproj/Localizable.strings b/Sources/CodexBar/Resources/tr.lproj/Localizable.strings index 78ca5c77eb..9f441b4f02 100644 --- a/Sources/CodexBar/Resources/tr.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/tr.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Tümünü göster (%d)"; +"Show less" = "Daha az göster"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/uk.lproj/Localizable.strings b/Sources/CodexBar/Resources/uk.lproj/Localizable.strings index 62a2b5a208..44b85d16d8 100644 --- a/Sources/CodexBar/Resources/uk.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/uk.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Показати всі (%d)"; +"Show less" = "Показати менше"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/vi.lproj/Localizable.strings b/Sources/CodexBar/Resources/vi.lproj/Localizable.strings index d9a4c504e9..2ced682842 100644 --- a/Sources/CodexBar/Resources/vi.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/vi.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "Hiện tất cả (%d)"; +"Show less" = "Thu gọn"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings b/Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings index 1c7705209c..ba4b18e1f4 100644 --- a/Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "显示全部(%d)"; +"Show less" = "收起"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots"; diff --git a/Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings b/Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings index 6c0e09d311..b4a85e905e 100644 --- a/Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings +++ b/Sources/CodexBar/Resources/zh-Hant.lproj/Localizable.strings @@ -2,6 +2,8 @@ /* iCloud Sync */ "iCloud Sync" = "iCloud Sync"; +"Show all (%d)" = "顯示全部(%d)"; +"Show less" = "收起"; "Sync settings and providers across your Macs via iCloud" = "Sync settings and providers across your Macs via iCloud"; "Include API keys, cookies, and tokens" = "Include API keys, cookies, and tokens"; "Sync usage snapshots" = "Sync usage snapshots";