dsh-subscriptions 0.2.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +220 -180
  2. package/lib/auth/claude-code-creds.js +31 -9
  3. package/lib/auth/device-flow.js +16 -9
  4. package/lib/auth/oauth-flow.js +13 -10
  5. package/lib/auth/rpc.d.ts +8 -4
  6. package/lib/auth/rpc.js +89 -25
  7. package/lib/auth/store.js +80 -31
  8. package/lib/client/CursorCard.d.ts +1 -1
  9. package/lib/client/CursorCard.js +50 -16
  10. package/lib/client/ExternalUsageCards.d.ts +1 -1
  11. package/lib/client/ExternalUsageCards.js +37 -16
  12. package/lib/client/ImageGallery.d.ts +2 -2
  13. package/lib/client/ImageGallery.js +92 -33
  14. package/lib/client/ImageGenerateToolview.js +50 -14
  15. package/lib/client/OllamaCard.d.ts +1 -1
  16. package/lib/client/OllamaCard.js +26 -8
  17. package/lib/client/OllamaSettingsManager.js +113 -30
  18. package/lib/client/ProviderAccountManager.d.ts +1 -1
  19. package/lib/client/ProviderAccountManager.js +164 -49
  20. package/lib/client/ProviderModelEditor.js +137 -34
  21. package/lib/client/SpeedSelect.d.ts +62 -14
  22. package/lib/client/SpeedSelect.js +261 -49
  23. package/lib/client/SubscriptionUsageBadge.d.ts +4 -10
  24. package/lib/client/SubscriptionUsageBadge.js +300 -112
  25. package/lib/client/SubscriptionsSection.d.ts +2 -0
  26. package/lib/client/SubscriptionsSection.js +265 -85
  27. package/lib/client/UsageBadgeDisplaySetting.js +35 -12
  28. package/lib/client/UsageMeter.d.ts +1 -1
  29. package/lib/client/UsageMeter.js +62 -24
  30. package/lib/client/VideoGenerateToolview.js +69 -17
  31. package/lib/client/account-preferences.d.ts +8 -0
  32. package/lib/client/account-preferences.js +20 -5
  33. package/lib/client/host-contract.d.ts +11 -2
  34. package/lib/client/host-contract.js +20 -3
  35. package/lib/client/index.d.ts +5 -5
  36. package/lib/client/index.js +34 -12
  37. package/lib/client/locales.d.ts +22 -0
  38. package/lib/client/locales.js +73 -51
  39. package/lib/client/model-filter.d.ts +37 -0
  40. package/lib/client/model-filter.js +45 -0
  41. package/lib/client/ollama-draft.js +21 -12
  42. package/lib/client/reset-action.js +6 -4
  43. package/lib/client/reset-credits-view.d.ts +1 -1
  44. package/lib/client/reset-credits-view.js +66 -17
  45. package/lib/client/subscription-card-styles.js +94 -24
  46. package/lib/client/usage-color-preferences.js +4 -2
  47. package/lib/client/usage-pace.js +30 -12
  48. package/lib/client/usage-window-filter.d.ts +7 -0
  49. package/lib/client/usage-window-filter.js +12 -0
  50. package/lib/client.js +480 -136
  51. package/lib/client.js.map +1 -1
  52. package/lib/http.js +1 -1
  53. package/lib/index.d.ts +3 -3
  54. package/lib/index.js +167 -76
  55. package/lib/model-defaults.js +4 -2
  56. package/lib/provider-settings.d.ts +17 -0
  57. package/lib/provider-settings.js +79 -16
  58. package/lib/providers/account-preferences.js +51 -22
  59. package/lib/providers/accounts.js +15 -9
  60. package/lib/providers/antigravity-oauth-client.js +2 -2
  61. package/lib/providers/antigravity.js +141 -68
  62. package/lib/providers/catalog-store.js +120 -41
  63. package/lib/providers/claude-cli-version.js +3 -3
  64. package/lib/providers/claude.d.ts +9 -2
  65. package/lib/providers/claude.js +153 -90
  66. package/lib/providers/codex-client-version.js +3 -3
  67. package/lib/providers/codex-search.js +40 -13
  68. package/lib/providers/codex.js +196 -112
  69. package/lib/providers/common.js +71 -39
  70. package/lib/providers/copilot.js +143 -82
  71. package/lib/providers/cursor-adapter.js +42 -18
  72. package/lib/providers/cursor-auth.d.ts +1 -1
  73. package/lib/providers/cursor-auth.js +69 -24
  74. package/lib/providers/cursor-model-settings.js +14 -5
  75. package/lib/providers/cursor-usage.js +27 -13
  76. package/lib/providers/external-usage-controller.js +14 -5
  77. package/lib/providers/external-usage.js +59 -23
  78. package/lib/providers/grok.js +152 -89
  79. package/lib/providers/image-pool.js +29 -11
  80. package/lib/providers/minimax-usage.js +31 -11
  81. package/lib/providers/npm-cli-version.js +10 -3
  82. package/lib/providers/ollama-settings.js +24 -8
  83. package/lib/providers/ollama-web.js +29 -11
  84. package/lib/providers/ollama.js +129 -66
  85. package/lib/providers/pool-family.js +11 -3
  86. package/lib/providers/pool-health.js +28 -8
  87. package/lib/providers/pool-usage.js +16 -9
  88. package/lib/providers/pool.d.ts +8 -0
  89. package/lib/providers/pool.js +81 -42
  90. package/lib/providers/rate-limit.js +8 -2
  91. package/lib/providers/replay.js +40 -17
  92. package/lib/providers/reset-redemption.js +18 -6
  93. package/lib/tools/image-generate.js +123 -65
  94. package/lib/tools/registration.js +5 -2
  95. package/lib/tools/video-generate.js +51 -31
  96. package/lib/tools/x-search.js +50 -22
  97. package/lib/translate/anthropic.js +85 -37
  98. package/lib/translate/antigravity-schema.js +71 -28
  99. package/lib/translate/antigravity-thinking.js +22 -9
  100. package/lib/translate/antigravity.js +151 -52
  101. package/lib/translate/chat-completions.js +67 -23
  102. package/lib/translate/resolved.js +55 -21
  103. package/lib/translate/responses.js +69 -29
  104. package/lib/translate/sse.js +4 -1
  105. package/package.json +27 -4
@@ -13,6 +13,8 @@ export interface AccountStatus {
13
13
  }
14
14
  /** One provider's login state as answered by the `status` endpoint. */
15
15
  export interface ProviderStatus {
16
+ /** Picker selection; absent follows discovery, [] hides all model quotas. */
17
+ visibleModels?: string[];
16
18
  busy: boolean;
17
19
  accounts: AccountStatus[];
18
20
  detail?: string;
@@ -15,18 +15,19 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
15
15
  import { useCallback, useEffect, useRef, useState } from 'react';
16
16
  import { en } from './locales.js';
17
17
  import { resetActionBlock } from './reset-action.js';
18
+ import { visibleUsageWindows } from './usage-window-filter.js';
18
19
  import { ProviderAccountManager } from './ProviderAccountManager.js';
19
20
  import { providerSettingsCss } from './provider-settings-styles.js';
20
21
  import { ExternalUsageCards } from './ExternalUsageCards.js';
21
22
  import { CursorCard } from './CursorCard.js';
22
23
  import { OllamaCard } from './OllamaCard.js';
23
24
  import { UsageMeter } from './UsageMeter.js';
24
- import { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits } from './reset-credits-view.js';
25
+ import { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits, } from './reset-credits-view.js';
25
26
  import { displayUsedPercent } from './usage-pace.js';
26
27
  import { UsageBadgeDisplaySetting } from './UsageBadgeDisplaySetting.js';
27
28
  import { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js';
28
29
  import { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js';
29
- import { callSubscriptionsAuth, SubscriptionsAuthError } from './subscriptions-rpc.js';
30
+ import { callSubscriptionsAuth, SubscriptionsAuthError, } from './subscriptions-rpc.js';
30
31
  export { callSubscriptionsAuth } from './subscriptions-rpc.js';
31
32
  /** Poll cadence while a provider login attempt is busy. */
32
33
  const POLL_INTERVAL_MS = 2000;
@@ -50,7 +51,7 @@ function messageOf(error) {
50
51
  }
51
52
  /** Copy a keyed map without the entries whose key is not in `live`. */
52
53
  function dropStale(map, live) {
53
- const stale = Object.keys(map).filter(key => !live.has(key));
54
+ const stale = Object.keys(map).filter((key) => !live.has(key));
54
55
  if (stale.length === 0)
55
56
  return map;
56
57
  const next = { ...map };
@@ -74,61 +75,128 @@ function fallbackTranslate(key, params) {
74
75
  }
75
76
  const styles = {
76
77
  section: {
77
- display: 'flex', flexDirection: 'column', gap: 12, maxWidth: 560,
78
+ display: 'flex',
79
+ flexDirection: 'column',
80
+ gap: 12,
81
+ maxWidth: 560,
78
82
  color: 'var(--dsw-alias-label-primary)',
79
83
  },
80
- intro: { margin: 0, color: 'var(--dsw-alias-label-tertiary)', fontSize: 14, lineHeight: '22px' },
81
- card: { ...cardStyles.card,
84
+ intro: {
85
+ margin: 0,
86
+ color: 'var(--dsw-alias-label-tertiary)',
87
+ fontSize: 14,
88
+ lineHeight: '22px',
89
+ },
90
+ card: {
91
+ ...cardStyles.card,
82
92
  border: '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',
83
- borderRadius: 'var(--dsw-radius-xl, 20px)', background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',
93
+ borderRadius: 'var(--dsw-radius-xl, 20px)',
94
+ background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',
84
95
  },
85
96
  cardHeader: cardStyles.header,
86
97
  dot: cardStyles.dot,
87
98
  name: cardStyles.name,
88
99
  statusLine: cardStyles.status,
89
- clientVersion: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)', fontVariantNumeric: 'tabular-nums' },
100
+ clientVersion: {
101
+ fontSize: 12,
102
+ lineHeight: '18px',
103
+ color: 'var(--dsw-alias-label-tertiary)',
104
+ fontVariantNumeric: 'tabular-nums',
105
+ },
90
106
  errorLine: cardStyles.error,
91
107
  actions: cardStyles.actions,
92
- usage: { ...cardStyles.usage, borderTop: '0.5px solid var(--dsw-alias-border-l2)' },
108
+ usage: {
109
+ ...cardStyles.usage,
110
+ borderTop: '0.5px solid var(--dsw-alias-border-l2)',
111
+ },
93
112
  usageHeader: cardStyles.usageHeader,
94
113
  usageTitle: cardStyles.usageTitle,
95
114
  usagePlan: cardStyles.usagePlan,
96
- usageRefresh: { minHeight: 22, height: 22, padding: '0 8px', marginLeft: 'auto' },
115
+ usageRefresh: {
116
+ minHeight: 22,
117
+ height: 22,
118
+ padding: '0 8px',
119
+ marginLeft: 'auto',
120
+ },
97
121
  usageRow: cardStyles.usageRow,
98
122
  usageMeta: cardStyles.usageMeta,
99
- accountRow: { ...cardStyles.account, border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)' },
123
+ accountRow: {
124
+ ...cardStyles.account,
125
+ border: '0.5px solid var(--dsw-alias-border-l2)',
126
+ borderRadius: 'var(--dsw-radius-lg, 16px)',
127
+ },
100
128
  accountHeader: cardStyles.accountHeader,
101
129
  accountName: cardStyles.accountName,
102
130
  starButton: {
103
- border: 'none', padding: 0, width: 28,
104
- font: 'inherit', fontSize: 14, lineHeight: '20px', cursor: 'pointer',
131
+ border: 'none',
132
+ padding: 0,
133
+ width: 28,
134
+ font: 'inherit',
135
+ fontSize: 14,
136
+ lineHeight: '20px',
137
+ cursor: 'pointer',
105
138
  color: 'var(--dsw-alias-state-warn-label)',
106
139
  },
107
140
  deviceCode: {
108
- marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6,
109
- border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)',
110
- padding: '10px 12px', background: 'var(--dsw-alias-bg-layer-1)',
141
+ marginTop: 4,
142
+ display: 'flex',
143
+ flexDirection: 'column',
144
+ gap: 6,
145
+ border: '0.5px solid var(--dsw-alias-border-l2)',
146
+ borderRadius: 'var(--dsw-radius-lg, 16px)',
147
+ padding: '10px 12px',
148
+ background: 'var(--dsw-alias-bg-layer-1)',
111
149
  },
112
150
  deviceCodeText: {
113
- fontFamily: 'monospace', fontSize: 18, lineHeight: '24px', letterSpacing: 2,
114
- color: 'var(--dsw-alias-label-primary)', userSelect: 'all',
151
+ fontFamily: 'monospace',
152
+ fontSize: 18,
153
+ lineHeight: '24px',
154
+ letterSpacing: 2,
155
+ color: 'var(--dsw-alias-label-primary)',
156
+ userSelect: 'all',
115
157
  },
116
158
  manual: { fontSize: 13, lineHeight: '20px' },
117
- manualRow: { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginTop: 8 },
159
+ manualRow: {
160
+ display: 'flex',
161
+ flexWrap: 'wrap',
162
+ gap: 8,
163
+ alignItems: 'center',
164
+ marginTop: 8,
165
+ },
118
166
  manualInput: { flex: '1 1 200px', minWidth: 0 },
119
167
  modalOverlay: {
120
- position: 'fixed', inset: 0, zIndex: 1000,
121
- display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16,
122
- background: 'var(--dsw-alias-bg-mask-1, #0006)', backdropFilter: 'var(--dsw-mask-blur, none)',
168
+ position: 'fixed',
169
+ inset: 0,
170
+ zIndex: 1000,
171
+ display: 'flex',
172
+ alignItems: 'center',
173
+ justifyContent: 'center',
174
+ padding: 16,
175
+ background: 'var(--dsw-alias-bg-mask-1, #0006)',
176
+ backdropFilter: 'var(--dsw-mask-blur, none)',
123
177
  },
124
178
  modal: {
125
- width: 460, maxWidth: '100%', maxHeight: '90vh', overflowY: 'auto',
126
- boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 12,
127
- padding: '16px 18px', borderRadius: 'var(--dsw-radius-panel, 28px)',
128
- background: 'var(--dsw-alias-bg-layer-2)', border: 0, boxShadow: 'var(--dsw-elevation-prominent)',
179
+ width: 460,
180
+ maxWidth: '100%',
181
+ maxHeight: '90vh',
182
+ overflowY: 'auto',
183
+ boxSizing: 'border-box',
184
+ display: 'flex',
185
+ flexDirection: 'column',
186
+ gap: 12,
187
+ padding: '16px 18px',
188
+ borderRadius: 'var(--dsw-radius-panel, 28px)',
189
+ background: 'var(--dsw-alias-bg-layer-2)',
190
+ border: 0,
191
+ boxShadow: 'var(--dsw-elevation-prominent)',
129
192
  },
130
193
  modalHeader: { display: 'flex', alignItems: 'center', gap: 8 },
131
- modalTitle: { fontWeight: 500, fontSize: 16, lineHeight: '24px', color: 'var(--dsw-alias-label-primary)' },
194
+ modalTitle: {
195
+ fontWeight: 500,
196
+ fontSize: 16,
197
+ lineHeight: '24px',
198
+ color: 'var(--dsw-alias-label-primary)',
199
+ },
132
200
  };
133
201
  /** Status dot color for one provider state. */
134
202
  function dotColor(status) {
@@ -138,16 +206,6 @@ function dotColor(status) {
138
206
  return 'var(--dsw-alias-state-success-primary)';
139
207
  return 'var(--dsw-alias-label-dimmed)';
140
208
  }
141
- /**
142
- * Whether a provider has at least one connected account. Multi-account made
143
- * "logged in" a property of the account list rather than a flag, so every
144
- * logged-in test goes through this one predicate.
145
- * @param status - the provider's last reported state, possibly absent.
146
- * @returns true when the provider serves at least one account.
147
- */
148
- function hasAccount(status) {
149
- return (status?.accounts.length ?? 0) > 0;
150
- }
151
209
  /**
152
210
  * One-line status text for one provider state.
153
211
  * @param t - section translate.
@@ -172,7 +230,10 @@ function statusText(t, status) {
172
230
  export function clientVersionText(t, clientVersion) {
173
231
  if (clientVersion === undefined)
174
232
  return '';
175
- return t('clientVersion', { version: clientVersion.version, source: t(CLIENT_VERSION_SOURCES[clientVersion.source]) });
233
+ return t('clientVersion', {
234
+ version: clientVersion.version,
235
+ source: t(CLIENT_VERSION_SOURCES[clientVersion.source]),
236
+ });
176
237
  }
177
238
  /**
178
239
  * Localized label of one usage window (kind, plus the model scope when named).
@@ -183,8 +244,12 @@ export function clientVersionText(t, clientVersion) {
183
244
  function usageWindowLabel(t, window) {
184
245
  const base = window.kind === 'session'
185
246
  ? t('usageSession')
186
- : window.kind === 'weekly' ? t('usageWeekly') : t('usageWindow');
187
- return window.scope !== undefined && window.scope !== '' ? `${base} · ${window.scope}` : base;
247
+ : window.kind === 'weekly'
248
+ ? t('usageWeekly')
249
+ : t('usageWindow');
250
+ return window.scope !== undefined && window.scope !== ''
251
+ ? `${base} · ${window.scope}`
252
+ : base;
188
253
  }
189
254
  /** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */
190
255
  export { usageBarColor } from './usage-pace.js';
@@ -199,7 +264,11 @@ export function SubscriptionsSection(props) {
199
264
  const [statuses, setStatuses] = useState({});
200
265
  const [errors, setErrors] = useState({});
201
266
  const [manualDrafts, setManualDrafts] = useState({
202
- codex: '', claude: '', grok: '', copilot: '', antigravity: '',
267
+ codex: '',
268
+ claude: '',
269
+ grok: '',
270
+ copilot: '',
271
+ antigravity: '',
203
272
  });
204
273
  /** Pending device-flow codes (copilot), shown while the attempt polls. */
205
274
  const [deviceCodes, setDeviceCodes] = useState({});
@@ -269,7 +338,8 @@ export function SubscriptionsSection(props) {
269
338
  return;
270
339
  setStatuses(response.providers);
271
340
  const signature = PROVIDERS.map(({ id }) => `${id}:${response.providers[id].accounts
272
- .map(account => `${account.key}:${account.isDefault}`).join(',')}`).join(';');
341
+ .map((account) => `${account.key}:${account.isDefault}`)
342
+ .join(',')}`).join(';');
273
343
  if (signature !== usageRosterSignatureRef.current) {
274
344
  usageRosterSignatureRef.current = signature;
275
345
  window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
@@ -295,7 +365,9 @@ export function SubscriptionsSection(props) {
295
365
  const startPolling = useCallback((provider) => {
296
366
  if (pollersRef.current.has(provider))
297
367
  return;
298
- pollersRef.current.set(provider, setInterval(() => { void refresh(); }, POLL_INTERVAL_MS));
368
+ pollersRef.current.set(provider, setInterval(() => {
369
+ void refresh();
370
+ }, POLL_INTERVAL_MS));
299
371
  }, [refresh]);
300
372
  // Initial load; every busy provider (e.g. an attempt started before a page
301
373
  // reload) resumes polling. Teardown clears pollers and the mounted guard.
@@ -314,6 +386,9 @@ export function SubscriptionsSection(props) {
314
386
  });
315
387
  return () => {
316
388
  mountedRef.current = false;
389
+ // The ref holds pollers started after this effect began. Copying .current
390
+ // at setup would clear an empty set and leave those intervals running.
391
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- read the live set at unmount
317
392
  for (const poller of pollersRef.current.values())
318
393
  clearInterval(poller);
319
394
  pollersRef.current.clear();
@@ -337,13 +412,16 @@ export function SubscriptionsSection(props) {
337
412
  if (rpc === undefined || usageInflightRef.current.has(key))
338
413
  return;
339
414
  const read = (async () => {
340
- setUsageLoading(prev => ({ ...prev, [key]: true }));
415
+ setUsageLoading((prev) => ({ ...prev, [key]: true }));
341
416
  try {
342
- const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account, ...force ? { force: true } : {} });
417
+ const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account, ...(force ? { force: true } : {}) });
343
418
  if (!mountedRef.current)
344
419
  return;
345
- setUsages(prev => ({ ...prev, [key]: usage }));
346
- setObservedAt(prev => ({ ...prev, [key]: usage.observedAt ?? Date.now() }));
420
+ setUsages((prev) => ({ ...prev, [key]: usage }));
421
+ setObservedAt((prev) => ({
422
+ ...prev,
423
+ [key]: usage.observedAt ?? Date.now(),
424
+ }));
347
425
  window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
348
426
  setUsageErrors((prev) => {
349
427
  const next = { ...prev };
@@ -353,12 +431,12 @@ export function SubscriptionsSection(props) {
353
431
  }
354
432
  catch (error) {
355
433
  if (mountedRef.current)
356
- setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }));
434
+ setUsageErrors((prev) => ({ ...prev, [key]: messageOf(error) }));
357
435
  }
358
436
  finally {
359
437
  usageInflightRef.current.delete(key);
360
438
  if (mountedRef.current)
361
- setUsageLoading(prev => ({ ...prev, [key]: false }));
439
+ setUsageLoading((prev) => ({ ...prev, [key]: false }));
362
440
  }
363
441
  })();
364
442
  usageInflightRef.current.set(key, read);
@@ -386,7 +464,10 @@ export function SubscriptionsSection(props) {
386
464
  }
387
465
  }
388
466
  async function consumeReset() {
389
- if (!rpc || !resetConfirmation || !resetAcknowledged || resetInflight.current)
467
+ if (!rpc ||
468
+ !resetConfirmation ||
469
+ !resetAcknowledged ||
470
+ resetInflight.current)
390
471
  return;
391
472
  const { account, ticket } = resetConfirmation;
392
473
  resetInflight.current = true;
@@ -418,8 +499,8 @@ export function SubscriptionsSection(props) {
418
499
  void loadUsage(id, account.key);
419
500
  }
420
501
  }
421
- setUsages(prev => dropStale(prev, live));
422
- setUsageErrors(prev => dropStale(prev, live));
502
+ setUsages((prev) => dropStale(prev, live));
503
+ setUsageErrors((prev) => dropStale(prev, live));
423
504
  }, [statuses, usages, usageErrors, loadUsage]);
424
505
  const login = useCallback(async (provider, method) => {
425
506
  if (rpc === undefined)
@@ -428,9 +509,10 @@ export function SubscriptionsSection(props) {
428
509
  try {
429
510
  const response = await callSubscriptionsAuth(rpc, 'login', {
430
511
  provider,
431
- ...method === undefined ? {} : { method },
512
+ ...(method === undefined ? {} : { method }),
432
513
  });
433
- if (typeof response.authorizeUrl === 'string' && response.authorizeUrl === '') {
514
+ if (typeof response.authorizeUrl === 'string' &&
515
+ response.authorizeUrl === '') {
434
516
  // Instant login (e.g. imported from Claude Code credentials)
435
517
  await refresh();
436
518
  return;
@@ -441,14 +523,25 @@ export function SubscriptionsSection(props) {
441
523
  if (!mountedRef.current)
442
524
  return;
443
525
  // Optimistic busy so Cancel and the manual fallback appear before the first poll tick.
444
- setStatuses(prev => ({
526
+ setStatuses((prev) => ({
445
527
  ...prev,
446
- [provider]: { accounts: prev[provider]?.accounts ?? [], ...prev[provider], busy: true },
528
+ [provider]: {
529
+ accounts: prev[provider]?.accounts ?? [],
530
+ ...prev[provider],
531
+ busy: true,
532
+ },
447
533
  }));
448
- if (typeof response.userCode === 'string' && response.userCode.length > 0) {
534
+ if (typeof response.userCode === 'string' &&
535
+ response.userCode.length > 0) {
449
536
  // Device flow: show the code card instead of opening the page blind —
450
537
  // the user copies the code first, then opens the verification page.
451
- setDeviceCodes(prev => ({ ...prev, [provider]: { userCode: response.userCode, verificationUrl: response.authorizeUrl } }));
538
+ setDeviceCodes((prev) => ({
539
+ ...prev,
540
+ [provider]: {
541
+ userCode: response.userCode,
542
+ verificationUrl: response.authorizeUrl,
543
+ },
544
+ }));
452
545
  }
453
546
  else {
454
547
  window.open(response.authorizeUrl, '_blank', 'noopener');
@@ -458,7 +551,7 @@ export function SubscriptionsSection(props) {
458
551
  catch (error) {
459
552
  setProviderError(provider, messageOf(error));
460
553
  }
461
- }, [rpc, t, setProviderError, startPolling]);
554
+ }, [rpc, t, setProviderError, startPolling, refresh]);
462
555
  const cancel = useCallback(async (provider) => {
463
556
  if (rpc === undefined)
464
557
  return;
@@ -479,9 +572,12 @@ export function SubscriptionsSection(props) {
479
572
  return;
480
573
  setProviderError(provider, undefined);
481
574
  try {
482
- await callSubscriptionsAuth(rpc, 'manual', { provider, input });
575
+ await callSubscriptionsAuth(rpc, 'manual', {
576
+ provider,
577
+ input,
578
+ });
483
579
  if (mountedRef.current)
484
- setManualDrafts(prev => ({ ...prev, [provider]: '' }));
580
+ setManualDrafts((prev) => ({ ...prev, [provider]: '' }));
485
581
  }
486
582
  catch (error) {
487
583
  setProviderError(provider, messageOf(error));
@@ -495,7 +591,10 @@ export function SubscriptionsSection(props) {
495
591
  return;
496
592
  setProviderError(provider, undefined);
497
593
  try {
498
- await callSubscriptionsAuth(rpc, 'logout', { provider, account });
594
+ await callSubscriptionsAuth(rpc, 'logout', {
595
+ provider,
596
+ account,
597
+ });
499
598
  }
500
599
  catch (error) {
501
600
  setProviderError(provider, messageOf(error));
@@ -507,7 +606,10 @@ export function SubscriptionsSection(props) {
507
606
  return;
508
607
  setProviderError(provider, undefined);
509
608
  try {
510
- await callSubscriptionsAuth(rpc, 'setDefault', { provider, account });
609
+ await callSubscriptionsAuth(rpc, 'setDefault', {
610
+ provider,
611
+ account,
612
+ });
511
613
  }
512
614
  catch (error) {
513
615
  setProviderError(provider, messageOf(error));
@@ -515,16 +617,19 @@ export function SubscriptionsSection(props) {
515
617
  await refresh();
516
618
  }, [rpc, setProviderError, refresh]);
517
619
  const copyDeviceCode = useCallback((provider, userCode) => {
518
- void navigator.clipboard?.writeText(userCode).then(() => {
620
+ void navigator.clipboard
621
+ ?.writeText(userCode)
622
+ .then(() => {
519
623
  if (!mountedRef.current)
520
624
  return;
521
625
  setCopiedCode(provider);
522
626
  setTimeout(() => {
523
627
  if (mountedRef.current) {
524
- setCopiedCode(current => current === provider ? undefined : current);
628
+ setCopiedCode((current) => current === provider ? undefined : current);
525
629
  }
526
630
  }, 1500);
527
- }).catch(() => undefined);
631
+ })
632
+ .catch(() => undefined);
528
633
  }, []);
529
634
  if (rpc === undefined) {
530
635
  return _jsx("p", { style: styles.intro, children: t('unavailable') });
@@ -534,34 +639,109 @@ export function SubscriptionsSection(props) {
534
639
  const busy = status?.busy === true;
535
640
  const deviceCode = deviceCodes[id];
536
641
  const accounts = status?.accounts ?? [];
537
- return (_jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("span", { style: { ...styles.dot, background: dotColor(status) } }), _jsx("span", { style: styles.name, children: name }), status?.clientVersion !== undefined && (_jsx("span", { style: styles.clientVersion, title: t('clientVersionHint'), children: clientVersionText(t, status.clientVersion) }))] }), _jsx("p", { style: styles.statusLine, children: statusText(t, status) }), status?.detail !== undefined && status.detail !== '' && (_jsx("p", { style: styles.statusLine, children: status.detail })), errors[id] !== undefined && _jsx("p", { style: styles.errorLine, children: errors[id] }), accounts.map((account) => {
642
+ return (_jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("span", { style: { ...styles.dot, background: dotColor(status) } }), _jsx("span", { style: styles.name, children: name }), status?.clientVersion !== undefined && (_jsx("span", { style: styles.clientVersion, title: t('clientVersionHint'), children: clientVersionText(t, status.clientVersion) }))] }), _jsx("p", { style: styles.statusLine, children: statusText(t, status) }), status?.detail !== undefined && status.detail !== '' && (_jsx("p", { style: styles.statusLine, children: status.detail })), errors[id] !== undefined && (_jsx("p", { style: styles.errorLine, children: errors[id] })), accounts.map((account) => {
538
643
  const usageKey = `${id}:${account.key}`;
539
644
  const usage = usages[usageKey];
645
+ const shownWindows = visibleUsageWindows(id, usage?.windows, status?.visibleModels);
540
646
  const usageError = usageErrors[usageKey];
541
647
  const display = account.account ?? account.key;
542
648
  const sortedCredits = [...(usage?.resetCredits ?? [])].sort((a, b) => (a.expiresAt ?? Infinity) - (b.expiresAt ?? Infinity));
543
- const nextReset = sortedCredits.find(c => c.expiresAt === undefined || c.expiresAt > Date.now());
544
- const resetBlock = usage ? resetActionBlock(usage) : 'resetUseRefresh';
649
+ const nextReset = sortedCredits.find((c) => c.expiresAt === undefined || c.expiresAt > Date.now());
650
+ const resetBlock = usage
651
+ ? resetActionBlock(usage)
652
+ : 'resetUseRefresh';
545
653
  const resetDisabled = resetBusy || resetBlock !== undefined;
546
654
  // Providers without a usage endpoint answer supported:false — no block.
547
- const showUsage = usage?.supported !== false
548
- && (usage !== undefined || usageError !== undefined || usageLoading[usageKey] === true);
655
+ const showUsage = usage?.supported !== false &&
656
+ (usage !== undefined ||
657
+ usageError !== undefined ||
658
+ usageLoading[usageKey] === true);
549
659
  return (_jsxs("div", { style: styles.accountRow, children: [_jsxs("div", { style: styles.accountHeader, children: [_jsx("button", { type: "button", style: styles.starButton, title: account.isDefault ? t('defaultBadge') : t('setDefault'), onClick: () => {
550
660
  if (!account.isDefault)
551
661
  void setDefault(id, account.key);
552
- }, children: account.isDefault ? '★' : '☆' }), _jsx("span", { style: styles.accountName, children: display }), account.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: account.plan })), account.expiresAt !== undefined && (_jsx("span", { style: styles.statusLine, children: t('accountExpires', { date: new Date(account.expiresAt).toLocaleString() }) })), _jsx("button", { type: "button", style: { marginLeft: 'auto', flexShrink: 0 }, onClick: () => { void logout(id, account.key, display, name); }, children: t('logout') })] }), showUsage && (_jsxs("div", { style: styles.usage, children: [_jsxs("div", { style: styles.usageHeader, children: [_jsx("span", { style: styles.usageTitle, children: t('usageTitle') }), usage?.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: t('usagePlan', { plan: usage.plan }) })), _jsx("button", { type: "button", style: styles.usageRefresh, disabled: usageLoading[usageKey] === true, onClick: () => { void loadUsage(id, account.key, true); }, children: t('usageRefresh') })] }), usage === undefined && usageError === undefined && (_jsx("p", { style: styles.statusLine, children: t('usageLoading') })), usageError !== undefined && (_jsx("p", { style: styles.errorLine, children: t('usageError', { message: usageError }) })), usage?.windows !== undefined && usage.windows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageEmpty') })), (usage?.windows ?? []).map((window, index) => {
662
+ }, children: account.isDefault ? '★' : '☆' }), _jsx("span", { style: styles.accountName, children: display }), account.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: account.plan })), account.expiresAt !== undefined && (_jsx("span", { style: styles.statusLine, children: t('accountExpires', {
663
+ date: new Date(account.expiresAt).toLocaleString(),
664
+ }) })), _jsx("button", { type: "button", style: { marginLeft: 'auto', flexShrink: 0 }, onClick: () => {
665
+ void logout(id, account.key, display, name);
666
+ }, children: t('logout') })] }), showUsage && (_jsxs("div", { style: styles.usage, children: [_jsxs("div", { style: styles.usageHeader, children: [_jsx("span", { style: styles.usageTitle, children: t('usageTitle') }), usage?.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: t('usagePlan', { plan: usage.plan }) })), _jsx("button", { type: "button", style: styles.usageRefresh, disabled: usageLoading[usageKey] === true, onClick: () => {
667
+ void loadUsage(id, account.key, true);
668
+ }, children: t('usageRefresh') })] }), usage === undefined && usageError === undefined && (_jsx("p", { style: styles.statusLine, children: t('usageLoading') })), usageError !== undefined && (_jsx("p", { style: styles.errorLine, children: t('usageError', { message: usageError }) })), usage?.windows !== undefined &&
669
+ usage.windows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageEmpty') })), usage?.windows !== undefined &&
670
+ usage.windows.length > 0 &&
671
+ shownWindows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageNoVisibleModels') })), shownWindows.map((window, index) => {
553
672
  const percent = displayUsedPercent(window.usedPercent);
554
- return (_jsxs("div", { style: styles.usageRow, children: [_jsxs("div", { style: styles.usageMeta, children: [_jsx("span", { children: usageWindowLabel(t, window) }), _jsxs("span", { children: [percent === undefined ? t('usageMeterInvalid') : `${percent}%`, window.resetsAt !== undefined
555
- && ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`] })] }), _jsx(UsageMeter, { window: window, t: t, observedAt: observedAt[usageKey], stale: usageError !== undefined || usage.stale === true })] }, index));
556
- }), (id === 'codex' || id === 'claude') && usage?.resetCreditsError !== undefined && (_jsx(ResetCreditsErrorLine, { provider: id, message: usage.resetCreditsError, t: t })), (id === 'codex' || id === 'claude') && showsResetCredits(id, usage?.resetCredits) && (_jsx(ResetCreditsDisclosure, { mode: id === 'claude' ? 'grants' : 'credits', credits: sortedCredits, t: t, ...nextReset !== undefined ? { nextCredit: nextReset } : {}, ...id === 'codex' ? { useAction: {
557
- accountKey: account.key,
558
- busy: resetBusy && resetAccount === account.key,
559
- disabled: resetDisabled,
560
- title: t(resetBusy ? 'resetUseChecking' : resetBlock ?? 'resetUseReady'),
561
- label: t('resetUseButton'),
562
- onUse: () => { if (!resetDisabled)
563
- void prepareReset(account.key); },
564
- } } : {}, ...resetAccount === account.key && resetMessage !== '' ? { statusMessage: resetMessage } : {} }))] }))] }, account.key));
565
- }), _jsxs("div", { style: styles.actions, children: [!busy && accounts.length === 0 && (_jsx("button", { type: "button", onClick: () => { void login(id); }, children: t('login') })), !busy && accounts.length > 0 && id === 'claude' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => { void login(id, 'oauth'); }, children: t('addAccountOAuth') }), _jsx("button", { type: "button", onClick: () => { void login(id, 'keychain'); }, children: t('addAccountKeychain') })] })), !busy && accounts.length > 0 && id !== 'claude' && (_jsx("button", { type: "button", onClick: () => { void login(id); }, children: t('addAccount') })), _jsx("button", { type: "button", "aria-haspopup": "dialog", onClick: () => setManagedProvider({ id, name }), children: t('accountsManage') }), busy && (_jsx("button", { type: "button", onClick: () => { void cancel(id); }, children: t('cancel') }))] }), !busy && accounts.length > 0 && (_jsx("p", { style: styles.statusLine, children: t('addAccountHint') })), busy && deviceCode !== undefined && (_jsxs("div", { style: styles.deviceCode, children: [_jsx("span", { style: styles.statusLine, children: t('deviceCodePrompt') }), _jsx("span", { style: styles.deviceCodeText, children: deviceCode.userCode }), _jsxs("div", { style: styles.actions, children: [_jsx("button", { type: "button", onClick: () => { copyDeviceCode(id, deviceCode.userCode); }, children: copiedCode === id ? t('deviceCodeCopied') : t('deviceCodeCopy') }), _jsx("button", { type: "button", onClick: () => { window.open(deviceCode.verificationUrl, '_blank', 'noopener'); }, children: t('deviceCodeOpenPage') })] })] })), busy && deviceCode === undefined && (_jsxs("details", { style: styles.manual, children: [_jsx("summary", { children: t('manualSummary') }), _jsxs("div", { style: styles.manualRow, children: [_jsx("input", { style: styles.manualInput, value: manualDrafts[id], placeholder: t('manualPlaceholder'), onChange: event => setManualDrafts(prev => ({ ...prev, [id]: event.target.value })) }), _jsx("button", { type: "button", onClick: () => { void submitManual(id); }, children: t('submit') })] })] }))] }, id));
566
- }), _jsx(CursorCard, { rpc: rpc, t: t }), _jsx(OllamaCard, { rpc: rpc, t: t }), _jsx(ExternalUsageCards, { rpc: rpc, t: t }), managedProvider && _jsx(ProviderAccountManager, { provider: managedProvider.id, name: managedProvider.name, rpc: rpc, t: t, onClose: () => setManagedProvider(undefined) }), _jsx("style", { children: '.subscriptions-reset-dialog::backdrop { background: var(--dsw-alias-bg-mask-1, #0006); backdrop-filter: var(--dsw-mask-blur, none); }' }), _jsx("dialog", { ref: resetDialogRef, className: "subscriptions-reset-dialog", "aria-labelledby": "subscriptions-reset-title", onCancel: () => setResetConfirmation(undefined), onClose: () => setResetConfirmation(undefined), style: { ...styles.modal, display: resetConfirmation ? 'flex' : 'none', margin: 'auto', color: 'var(--dsw-alias-label-primary)' }, children: resetConfirmation && _jsxs(_Fragment, { children: [_jsx("h3", { id: "subscriptions-reset-title", style: { ...styles.modalTitle, margin: 0 }, children: t('resetUseConfirmTitle') }), _jsx("p", { style: { ...styles.statusLine, overflowWrap: 'anywhere' }, children: statuses.codex?.accounts.find(a => a.key === resetConfirmation.account)?.account ?? resetConfirmation.account }), _jsxs("div", { style: { ...styles.usageMeta, gap: 12 }, children: [_jsx("span", { children: t('usageWeekly') }), _jsxs("strong", { children: [Math.round(resetConfirmation.weeklyUsedPercent), "%"] })] }), _jsx("div", { style: styles.usageMeta, children: _jsx("span", { children: resetConfirmation.creditExpiresAt === undefined ? t('resetCreditExpiryUnknown') : t('resetCreditExpires', { date: new Date(resetConfirmation.creditExpiresAt).toLocaleString() }) }) }), _jsx("p", { style: { ...styles.statusLine, margin: '4px 0' }, children: t('resetUseWarning') }), _jsxs("label", { style: { display: 'flex', gap: 8, alignItems: 'flex-start', fontSize: 12 }, children: [_jsx("input", { type: "checkbox", checked: resetAcknowledged, onChange: e => setResetAcknowledged(e.target.checked) }), t('resetUseAcknowledge')] }), _jsxs("div", { className: "dsh-subscription-dialog-actions", style: { ...styles.actions, justifyContent: 'flex-end', marginTop: 8 }, children: [_jsx("button", { type: "button", autoFocus: true, onClick: () => setResetConfirmation(undefined), children: t('cancel') }), _jsx("button", { type: "button", className: "dsh-subscription-primary", disabled: !resetAcknowledged || resetBusy, onClick: () => { void consumeReset(); }, children: t('resetUseConfirm') })] })] }) })] }));
673
+ return (_jsxs("div", { style: styles.usageRow, children: [_jsxs("div", { style: styles.usageMeta, children: [_jsx("span", { children: usageWindowLabel(t, window) }), _jsxs("span", { children: [percent === undefined
674
+ ? t('usageMeterInvalid')
675
+ : `${percent}%`, window.resetsAt !== undefined &&
676
+ ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`] })] }), _jsx(UsageMeter, { window: window, t: t, observedAt: observedAt[usageKey], stale: usageError !== undefined || usage.stale === true })] }, index));
677
+ }), (id === 'codex' || id === 'claude') &&
678
+ usage?.resetCreditsError !== undefined && (_jsx(ResetCreditsErrorLine, { provider: id, message: usage.resetCreditsError, t: t })), (id === 'codex' || id === 'claude') &&
679
+ showsResetCredits(id, usage?.resetCredits) && (_jsx(ResetCreditsDisclosure, { mode: id === 'claude' ? 'grants' : 'credits', credits: sortedCredits, t: t, ...(nextReset !== undefined
680
+ ? { nextCredit: nextReset }
681
+ : {}), ...(id === 'codex'
682
+ ? {
683
+ useAction: {
684
+ accountKey: account.key,
685
+ busy: resetBusy && resetAccount === account.key,
686
+ disabled: resetDisabled,
687
+ title: t(resetBusy
688
+ ? 'resetUseChecking'
689
+ : (resetBlock ?? 'resetUseReady')),
690
+ label: t('resetUseButton'),
691
+ onUse: () => {
692
+ if (!resetDisabled)
693
+ void prepareReset(account.key);
694
+ },
695
+ },
696
+ }
697
+ : {}), ...(resetAccount === account.key &&
698
+ resetMessage !== ''
699
+ ? { statusMessage: resetMessage }
700
+ : {}) }))] }))] }, account.key));
701
+ }), _jsxs("div", { style: styles.actions, children: [!busy && accounts.length === 0 && (_jsx("button", { type: "button", onClick: () => {
702
+ void login(id);
703
+ }, children: t('login') })), !busy && accounts.length > 0 && id === 'claude' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => {
704
+ void login(id, 'oauth');
705
+ }, children: t('addAccountOAuth') }), _jsx("button", { type: "button", onClick: () => {
706
+ void login(id, 'keychain');
707
+ }, children: t('addAccountKeychain') })] })), !busy && accounts.length > 0 && id !== 'claude' && (_jsx("button", { type: "button", onClick: () => {
708
+ void login(id);
709
+ }, children: t('addAccount') })), !busy && (_jsx("button", { type: "button", "aria-haspopup": "dialog", onClick: () => setManagedProvider({ id, name }), children: t('accountsManage') })), busy && (_jsx("button", { type: "button", onClick: () => {
710
+ void cancel(id);
711
+ }, children: t('cancel') }))] }), !busy && accounts.length > 0 && (_jsx("p", { style: styles.statusLine, children: t('addAccountHint') })), busy && deviceCode !== undefined && (_jsxs("div", { style: styles.deviceCode, children: [_jsx("span", { style: styles.statusLine, children: t('deviceCodePrompt') }), _jsx("span", { style: styles.deviceCodeText, children: deviceCode.userCode }), _jsxs("div", { style: styles.actions, children: [_jsx("button", { type: "button", onClick: () => {
712
+ copyDeviceCode(id, deviceCode.userCode);
713
+ }, children: copiedCode === id
714
+ ? t('deviceCodeCopied')
715
+ : t('deviceCodeCopy') }), _jsx("button", { type: "button", onClick: () => {
716
+ window.open(deviceCode.verificationUrl, '_blank', 'noopener');
717
+ }, children: t('deviceCodeOpenPage') })] })] })), busy && deviceCode === undefined && (_jsxs("details", { style: styles.manual, children: [_jsx("summary", { children: t('manualSummary') }), _jsxs("div", { style: styles.manualRow, children: [_jsx("input", { style: styles.manualInput, value: manualDrafts[id], placeholder: t('manualPlaceholder'), onChange: (event) => setManualDrafts((prev) => ({
718
+ ...prev,
719
+ [id]: event.target.value,
720
+ })) }), _jsx("button", { type: "button", onClick: () => {
721
+ void submitManual(id);
722
+ }, children: t('submit') })] })] }))] }, id));
723
+ }), _jsx(CursorCard, { rpc: rpc, t: t }), _jsx(OllamaCard, { rpc: rpc, t: t }), _jsx(ExternalUsageCards, { rpc: rpc, t: t }), managedProvider && (_jsx(ProviderAccountManager, { provider: managedProvider.id, name: managedProvider.name, rpc: rpc, t: t, onClose: () => {
724
+ setManagedProvider(undefined);
725
+ void refresh();
726
+ } })), _jsx("style", { children: '.subscriptions-reset-dialog::backdrop { background: var(--dsw-alias-bg-mask-1, #0006); backdrop-filter: var(--dsw-mask-blur, none); }' }), _jsx("dialog", { ref: resetDialogRef, className: "subscriptions-reset-dialog", "aria-labelledby": "subscriptions-reset-title", onCancel: () => setResetConfirmation(undefined), onClose: () => setResetConfirmation(undefined), style: {
727
+ ...styles.modal,
728
+ display: resetConfirmation ? 'flex' : 'none',
729
+ margin: 'auto',
730
+ color: 'var(--dsw-alias-label-primary)',
731
+ }, children: resetConfirmation && (_jsxs(_Fragment, { children: [_jsx("h3", { id: "subscriptions-reset-title", style: { ...styles.modalTitle, margin: 0 }, children: t('resetUseConfirmTitle') }), _jsx("p", { style: { ...styles.statusLine, overflowWrap: 'anywhere' }, children: statuses.codex?.accounts.find((a) => a.key === resetConfirmation.account)?.account ?? resetConfirmation.account }), _jsxs("div", { style: { ...styles.usageMeta, gap: 12 }, children: [_jsx("span", { children: t('usageWeekly') }), _jsxs("strong", { children: [Math.round(resetConfirmation.weeklyUsedPercent), "%"] })] }), _jsx("div", { style: styles.usageMeta, children: _jsx("span", { children: resetConfirmation.creditExpiresAt === undefined
732
+ ? t('resetCreditExpiryUnknown')
733
+ : t('resetCreditExpires', {
734
+ date: new Date(resetConfirmation.creditExpiresAt).toLocaleString(),
735
+ }) }) }), _jsx("p", { style: { ...styles.statusLine, margin: '4px 0' }, children: t('resetUseWarning') }), _jsxs("label", { style: {
736
+ display: 'flex',
737
+ gap: 8,
738
+ alignItems: 'flex-start',
739
+ fontSize: 12,
740
+ }, children: [_jsx("input", { type: "checkbox", checked: resetAcknowledged, onChange: (e) => setResetAcknowledged(e.target.checked) }), t('resetUseAcknowledge')] }), _jsxs("div", { className: "dsh-subscription-dialog-actions", style: {
741
+ ...styles.actions,
742
+ justifyContent: 'flex-end',
743
+ marginTop: 8,
744
+ }, children: [_jsx("button", { type: "button", autoFocus: true, onClick: () => setResetConfirmation(undefined), children: t('cancel') }), _jsx("button", { type: "button", className: "dsh-subscription-primary", disabled: !resetAcknowledged || resetBusy, onClick: () => {
745
+ void consumeReset();
746
+ }, children: t('resetUseConfirm') })] })] })) })] }));
567
747
  }