@campfire-interactive/shell-header 0.8.15 → 0.11.0
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.
- package/dist/index.d.ts +81 -2
- package/dist/index.js +543 -27
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -126,6 +126,71 @@ interface AboutInfo {
|
|
|
126
126
|
/** API build + deploy metadata (rendered as a second section when present). */
|
|
127
127
|
api?: VersionInfo;
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Host-supplied context stamped onto every bug report (Ctrl+Alt+B modal).
|
|
131
|
+
* Hosts typically derive appVersion/apiVersion from the same data they pass
|
|
132
|
+
* as `about`.
|
|
133
|
+
*/
|
|
134
|
+
interface BugReportContext {
|
|
135
|
+
/** Reporting app slug, e.g. "omsf". */
|
|
136
|
+
appId: string;
|
|
137
|
+
/** Environment label, e.g. "dev". Hosts should omit the whole `bugReport`
|
|
138
|
+
* prop in prod until the prod-visibility story exists. */
|
|
139
|
+
environment: string;
|
|
140
|
+
/** Defaults to window.location.href at submit time. */
|
|
141
|
+
url?: string;
|
|
142
|
+
appVersion?: string;
|
|
143
|
+
apiVersion?: string;
|
|
144
|
+
/**
|
|
145
|
+
* URL of the suite issues list (dms webapp `/issues`). When set, the
|
|
146
|
+
* dialog links to it ("View known issues") so reporters can check whether
|
|
147
|
+
* their bug is already filed. Opens in a new tab.
|
|
148
|
+
*/
|
|
149
|
+
issuesUrl?: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* What the modal hands to `onSubmit`. Field names (minus `screenshot`)
|
|
153
|
+
* mirror dms-client's CreateBugReportInput, so a host can:
|
|
154
|
+
*
|
|
155
|
+
* const { screenshot, ...input } = payload;
|
|
156
|
+
* const report = await dms.bugReports.create(input);
|
|
157
|
+
* if (screenshot) {
|
|
158
|
+
* await dms.attachments.upload(screenshot, {
|
|
159
|
+
* entityType: 'bug_report', entityId: report.id,
|
|
160
|
+
* name: 'screenshot.png', app: 'bug-reports',
|
|
161
|
+
* });
|
|
162
|
+
* }
|
|
163
|
+
*/
|
|
164
|
+
interface BugReportPayload {
|
|
165
|
+
appId: string;
|
|
166
|
+
environment: string;
|
|
167
|
+
url: string;
|
|
168
|
+
title: string;
|
|
169
|
+
description: string;
|
|
170
|
+
appVersion?: string;
|
|
171
|
+
apiVersion?: string;
|
|
172
|
+
userAgent: string;
|
|
173
|
+
/** e.g. "1920x1080" (window inner size). */
|
|
174
|
+
viewport: string;
|
|
175
|
+
/** Console-error ring-buffer snapshot (installBugReportCapture). */
|
|
176
|
+
console: unknown[];
|
|
177
|
+
/** Failed-request ring-buffer snapshot. */
|
|
178
|
+
network: unknown[];
|
|
179
|
+
/** Edited PNG, or null when the reporter skipped/removed the capture. */
|
|
180
|
+
screenshot: Blob | null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Enables the hidden Ctrl+Alt+B bug-report modal. Like `about`, the package
|
|
184
|
+
* stays presentational: context comes in via props, and the host owns
|
|
185
|
+
* submission via onSubmit (typically dms-client — see BugReportPayload).
|
|
186
|
+
* The host should also call installBugReportCapture() at app boot so the
|
|
187
|
+
* console/network ring buffers have content by the time a bug is filed.
|
|
188
|
+
*/
|
|
189
|
+
interface BugReportConfig {
|
|
190
|
+
context: BugReportContext;
|
|
191
|
+
/** Rejection keeps the modal open and shows the error message. */
|
|
192
|
+
onSubmit: (report: BugReportPayload) => Promise<void>;
|
|
193
|
+
}
|
|
129
194
|
/**
|
|
130
195
|
* Subset of the platform-notifications `Notification` shape that the bell UI
|
|
131
196
|
* actually renders. Hosts typically map their fetched items (e.g., from
|
|
@@ -242,6 +307,13 @@ interface ShellHeaderProps {
|
|
|
242
307
|
* prop disables the shortcut and renders nothing extra.
|
|
243
308
|
*/
|
|
244
309
|
about?: AboutInfo;
|
|
310
|
+
/**
|
|
311
|
+
* Optional bug-report wiring. When provided, enables a hidden Ctrl+Alt+B
|
|
312
|
+
* (Cmd+Opt+B on Mac) shortcut that opens a bug-report modal with optional
|
|
313
|
+
* screenshot capture. Omitting this prop disables the shortcut and renders
|
|
314
|
+
* nothing extra. See BugReportConfig for the host contract.
|
|
315
|
+
*/
|
|
316
|
+
bugReport?: BugReportConfig;
|
|
245
317
|
/**
|
|
246
318
|
* When true, the header's top-left shows the campfire suite wordmark
|
|
247
319
|
* instead of the current app's badge + title. Used by the /home launcher,
|
|
@@ -255,7 +327,7 @@ interface ShellHeaderProps {
|
|
|
255
327
|
children?: React.ReactNode;
|
|
256
328
|
}
|
|
257
329
|
|
|
258
|
-
declare function ShellHeader({ appId, user, authorizedApps, currentTenantRole, notificationCount, onNotificationClick, notifications, onMarkRead, onMarkAllRead, onNotificationItemClick, onLogout, locale, supportedLocales, onLocaleChange, currency, supportedCurrencies, onCurrencyChange, tenant, tenants, onTenantSwitch, userMenuItems, about, showSuiteLogo, brandWidth, children, }: ShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
330
|
+
declare function ShellHeader({ appId, user, authorizedApps, currentTenantRole, notificationCount, onNotificationClick, notifications, onMarkRead, onMarkAllRead, onNotificationItemClick, onLogout, locale, supportedLocales, onLocaleChange, currency, supportedCurrencies, onCurrencyChange, tenant, tenants, onTenantSwitch, userMenuItems, about, bugReport, showSuiteLogo, brandWidth, children, }: ShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
259
331
|
|
|
260
332
|
interface LocaleSwitcherProps {
|
|
261
333
|
currentLocale: string;
|
|
@@ -264,6 +336,13 @@ interface LocaleSwitcherProps {
|
|
|
264
336
|
}
|
|
265
337
|
declare function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }: LocaleSwitcherProps): react_jsx_runtime.JSX.Element;
|
|
266
338
|
|
|
339
|
+
/**
|
|
340
|
+
* Install the capture hooks. Idempotent; safe to call in any environment
|
|
341
|
+
* (no-ops outside a browser). Call from the app entry point so the buffers
|
|
342
|
+
* exist before the bug does.
|
|
343
|
+
*/
|
|
344
|
+
declare function installBugReportCapture(): void;
|
|
345
|
+
|
|
267
346
|
declare const appCatalog: AppDefinition[];
|
|
268
347
|
/**
|
|
269
348
|
* Derive the app URL from the current hostname, optionally appending the
|
|
@@ -274,4 +353,4 @@ declare const appCatalog: AppDefinition[];
|
|
|
274
353
|
*/
|
|
275
354
|
declare function getAppUrl(app: AppDefinition): string;
|
|
276
355
|
|
|
277
|
-
export { type AboutInfo, type AppDefinition, type CurrencyOption, type LocaleOption, LocaleSwitcher, type NotificationItem, ShellHeader, type ShellHeaderProps, type ShellUser, type VersionInfo, appCatalog, getAppUrl };
|
|
356
|
+
export { type AboutInfo, type AppDefinition, type BugReportConfig, type BugReportContext, type BugReportPayload, type CurrencyOption, type LocaleOption, LocaleSwitcher, type NotificationItem, ShellHeader, type ShellHeaderProps, type ShellUser, type VersionInfo, appCatalog, getAppUrl, installBugReportCapture };
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// src/styles.css
|
|
27
|
-
styleInject(".cfi-sh-header {\n display: flex;\n align-items: center;\n height: var(--cfi-shell-header-height, 48px);\n padding: 0 var(--cfi-spacing-md, 1rem);\n background: white;\n color: var(--cfi-color-gray-900, #111827);\n font-family: var(--cfi-font-family, system-ui, sans-serif);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n position: relative;\n z-index: 1000;\n}\n.cfi-sh-left {\n display: flex;\n align-items: center;\n flex: 1;\n gap: var(--cfi-spacing-md, 1rem);\n overflow: hidden;\n}\n.cfi-sh-app-brand {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n flex-shrink: 0;\n}\n.cfi-sh-app-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n color: white;\n font-size: 14px;\n font-weight: 700;\n font-family: inherit;\n border-radius: var(--cfi-radius-md, 0.375rem);\n flex-shrink: 0;\n}\n.cfi-sh-app-title {\n font-weight: 600;\n font-size: var(--cfi-font-size-base, 1rem);\n color: var(--cfi-color-gray-900, #111827);\n white-space: nowrap;\n}\n.cfi-sh-suite-logo {\n height: 22px;\n width: auto;\n display: block;\n}\n.cfi-sh-right {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n flex-shrink: 0;\n}\n.cfi-sh-icon-btn {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: transparent;\n border: none;\n border-radius: 50%;\n color: var(--cfi-color-gray-600, #4b5563);\n cursor: pointer;\n transition: background 150ms;\n}\n.cfi-sh-icon-btn:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--cfi-color-error, #ef4444);\n color: white;\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-align: center;\n border-radius: 99px;\n}\n.cfi-sh-app-switcher {\n position: relative;\n}\n.cfi-sh-app-grid {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--cfi-spacing-xs, 0.25rem);\n padding: var(--cfi-spacing-sm, 0.5rem);\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n min-width: 280px;\n}\n.cfi-sh-app-grid-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-xs, 0.25rem);\n border-radius: var(--cfi-radius-md, 0.375rem);\n color: var(--cfi-color-gray-700, #374151);\n text-decoration: none;\n cursor: pointer;\n transition: background 100ms;\n font-family: inherit;\n}\n.cfi-sh-app-grid-item:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-app-grid-item-active {\n background: var(--cfi-color-primary-50, #fff7ed);\n color: var(--cfi-color-primary-700, #c2410c);\n}\n.cfi-sh-app-grid-item-active:hover {\n background: var(--cfi-color-primary-100, #ffedd5);\n}\n.cfi-sh-app-grid-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n}\n.cfi-sh-app-grid-label {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-align: center;\n line-height: 1.35;\n max-width: 80px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n white-space: normal;\n overflow: hidden;\n min-height: 2.7em;\n}\n.cfi-sh-user-menu {\n position: relative;\n}\n.cfi-sh-avatar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: var(--cfi-color-primary-600, #ea580c);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: opacity 150ms;\n}\n.cfi-sh-avatar-btn:hover {\n opacity: 0.85;\n}\n.cfi-sh-avatar-img {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n object-fit: cover;\n}\n.cfi-sh-avatar-initials {\n color: white;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n font-family: inherit;\n}\n.cfi-sh-user-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n min-width: 200px;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n}\n.cfi-sh-user-header {\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n display: flex;\n flex-direction: column;\n}\n.cfi-sh-user-name {\n font-weight: 500;\n color: var(--cfi-color-gray-900, #111827);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-user-email {\n color: var(--cfi-color-gray-500, #6b7280);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n}\n.cfi-sh-divider {\n height: 1px;\n background: var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-menu-item {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n width: 100%;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n background: none;\n border: none;\n color: var(--cfi-color-gray-700, #374151);\n cursor: pointer;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-menu-item:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-menu-item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.cfi-sh-locale-switcher {\n position: relative;\n}\n.cfi-sh-locale-btn {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n height: 32px;\n padding: 0 var(--cfi-spacing-sm, 0.5rem);\n background: transparent;\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n border-radius: var(--cfi-radius-md, 0.375rem);\n color: var(--cfi-color-gray-700, #374151);\n cursor: pointer;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-locale-btn:hover:not(:disabled) {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-locale-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.cfi-sh-locale-label {\n letter-spacing: 0.02em;\n}\n.cfi-sh-locale-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n min-width: 180px;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n padding: var(--cfi-spacing-xs, 0.25rem) 0;\n}\n.cfi-sh-locale-dropdown .cfi-sh-menu-item {\n justify-content: space-between;\n}\n.cfi-sh-locale-item-active {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-locale-item-label {\n flex: 1;\n text-align: left;\n}\n.cfi-sh-locale-item-code {\n color: var(--cfi-color-gray-400, #9ca3af);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n letter-spacing: 0.02em;\n}\n.cfi-sh-locale-row {\n justify-content: flex-start;\n}\n.cfi-sh-locale-row-label {\n flex: 1;\n text-align: left;\n}\n.cfi-sh-locale-row-current {\n color: var(--cfi-color-gray-500, #6b7280);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n margin-right: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-locale-chevron {\n transition: transform 150ms ease;\n flex-shrink: 0;\n}\n.cfi-sh-locale-chevron-open {\n transform: rotate(180deg);\n}\n.cfi-sh-locale-sublist {\n border-top: 1px solid var(--cfi-color-gray-100, #f3f4f6);\n background: var(--cfi-color-gray-50, #f9fafb);\n}\n.cfi-sh-locale-sub-item {\n padding-left: calc(var(--cfi-spacing-md, 1rem) + var(--cfi-spacing-md, 1rem));\n justify-content: space-between;\n}\n.cfi-sh-tenant-static {\n cursor: default;\n pointer-events: none;\n}\n.cfi-sh-tenant-check {\n color: var(--cfi-color-violet-600, #7c3aed);\n}\n.cfi-sh-notif {\n position: relative;\n}\n.cfi-sh-notif-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 360px;\n max-height: 480px;\n display: flex;\n flex-direction: column;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n overflow: hidden;\n}\n.cfi-sh-notif-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n flex-shrink: 0;\n}\n.cfi-sh-notif-title {\n font-weight: 600;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-notif-mark-all {\n background: none;\n border: none;\n color: var(--cfi-color-primary-600, #ea580c);\n cursor: pointer;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-family: inherit;\n padding: 0;\n}\n.cfi-sh-notif-mark-all:hover {\n text-decoration: underline;\n}\n.cfi-sh-notif-list {\n overflow-y: auto;\n flex: 1;\n}\n.cfi-sh-notif-empty {\n padding: var(--cfi-spacing-lg, 1.5rem) var(--cfi-spacing-md, 1rem);\n color: var(--cfi-color-gray-500, #6b7280);\n text-align: center;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-notif-item {\n display: flex;\n align-items: flex-start;\n gap: var(--cfi-spacing-sm, 0.5rem);\n width: 100%;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n background: none;\n border: none;\n border-bottom: 1px solid var(--cfi-color-gray-100, #f3f4f6);\n text-align: left;\n cursor: pointer;\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-notif-item:hover {\n background: var(--cfi-color-gray-50, #f9fafb);\n}\n.cfi-sh-notif-item:last-child {\n border-bottom: none;\n}\n.cfi-sh-notif-dot {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n margin-top: 6px;\n background: var(--cfi-color-primary-600, #ea580c);\n border-radius: 50%;\n}\n.cfi-sh-notif-dot-placeholder {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n margin-top: 6px;\n}\n.cfi-sh-notif-content {\n flex: 1;\n min-width: 0;\n}\n.cfi-sh-notif-item-title {\n font-weight: 500;\n color: var(--cfi-color-gray-900, #111827);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n margin-bottom: 2px;\n}\n.cfi-sh-notif-item-unread .cfi-sh-notif-item-title {\n font-weight: 600;\n}\n.cfi-sh-notif-item-body {\n color: var(--cfi-color-gray-600, #4b5563);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.cfi-sh-notif-item-time {\n color: var(--cfi-color-gray-400, #9ca3af);\n font-size: 11px;\n margin-top: 4px;\n}\n.cfi-sh-about-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1100;\n font-family: var(--cfi-font-family, system-ui, sans-serif);\n}\n.cfi-sh-about-card {\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n min-width: 360px;\n max-width: 500px;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-header {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n padding: var(--cfi-spacing-md, 1rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-about-title {\n font-weight: 600;\n font-size: var(--cfi-font-size-lg, 1.125rem);\n flex: 1;\n}\n.cfi-sh-about-env {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n background: var(--cfi-color-gray-100, #f3f4f6);\n color: var(--cfi-color-gray-700, #374151);\n padding: 2px 8px;\n border-radius: var(--cfi-radius-sm, 0.25rem);\n font-weight: 600;\n}\n.cfi-sh-about-close {\n background: none;\n border: none;\n font-size: 1.5rem;\n line-height: 1;\n cursor: pointer;\n color: var(--cfi-color-gray-500, #6b7280);\n padding: 0 4px;\n font-family: inherit;\n}\n.cfi-sh-about-close:hover {\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-body {\n padding: var(--cfi-spacing-md, 1rem);\n display: flex;\n flex-direction: column;\n gap: var(--cfi-spacing-md, 1rem);\n}\n.cfi-sh-about-section-title {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n color: var(--cfi-color-gray-500, #6b7280);\n margin-bottom: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-about-list {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: var(--cfi-spacing-xs, 0.25rem) var(--cfi-spacing-md, 1rem);\n margin: 0;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-about-list dt {\n color: var(--cfi-color-gray-600, #4b5563);\n font-weight: 500;\n}\n.cfi-sh-about-list dd {\n margin: 0;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-list code {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Consolas,\n monospace;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n background: var(--cfi-color-gray-100, #f3f4f6);\n padding: 1px 6px;\n border-radius: var(--cfi-radius-sm, 0.25rem);\n}\n.cfi-sh-about-date {\n color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-about-footer {\n display: flex;\n justify-content: flex-end;\n padding: var(--cfi-spacing-md, 1rem);\n border-top: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-about-copy {\n background: var(--cfi-color-gray-100, #f3f4f6);\n border: 1px solid var(--cfi-color-gray-300, #d1d5db);\n color: var(--cfi-color-gray-900, #111827);\n padding: 6px 12px;\n border-radius: var(--cfi-radius-md, 0.375rem);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: background 150ms;\n}\n.cfi-sh-about-copy:hover {\n background: var(--cfi-color-gray-200, #e5e7eb);\n}\n");
|
|
27
|
+
styleInject(".cfi-sh-header {\n display: flex;\n align-items: center;\n height: var(--cfi-shell-header-height, 48px);\n padding: 0 var(--cfi-spacing-md, 1rem);\n background: white;\n color: var(--cfi-color-gray-900, #111827);\n font-family: var(--cfi-font-family, system-ui, sans-serif);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n position: relative;\n z-index: 1000;\n}\n.cfi-sh-left {\n display: flex;\n align-items: center;\n flex: 1;\n gap: var(--cfi-spacing-md, 1rem);\n overflow: hidden;\n}\n.cfi-sh-app-brand {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n flex-shrink: 0;\n}\n.cfi-sh-app-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n color: white;\n font-size: 14px;\n font-weight: 700;\n font-family: inherit;\n border-radius: var(--cfi-radius-md, 0.375rem);\n flex-shrink: 0;\n}\n.cfi-sh-app-title {\n font-weight: 600;\n font-size: var(--cfi-font-size-base, 1rem);\n color: var(--cfi-color-gray-900, #111827);\n white-space: nowrap;\n}\n.cfi-sh-suite-logo {\n height: 22px;\n width: auto;\n display: block;\n}\n.cfi-sh-right {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n flex-shrink: 0;\n}\n.cfi-sh-icon-btn {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: transparent;\n border: none;\n border-radius: 50%;\n color: var(--cfi-color-gray-600, #4b5563);\n cursor: pointer;\n transition: background 150ms;\n}\n.cfi-sh-icon-btn:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--cfi-color-error, #ef4444);\n color: white;\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-align: center;\n border-radius: 99px;\n}\n.cfi-sh-app-switcher {\n position: relative;\n}\n.cfi-sh-app-grid {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--cfi-spacing-xs, 0.25rem);\n padding: var(--cfi-spacing-sm, 0.5rem);\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n min-width: 280px;\n}\n.cfi-sh-app-grid-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-xs, 0.25rem);\n border-radius: var(--cfi-radius-md, 0.375rem);\n color: var(--cfi-color-gray-700, #374151);\n text-decoration: none;\n cursor: pointer;\n transition: background 100ms;\n font-family: inherit;\n}\n.cfi-sh-app-grid-item:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-app-grid-item-active {\n background: var(--cfi-color-primary-50, #fff7ed);\n color: var(--cfi-color-primary-700, #c2410c);\n}\n.cfi-sh-app-grid-item-active:hover {\n background: var(--cfi-color-primary-100, #ffedd5);\n}\n.cfi-sh-app-grid-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n}\n.cfi-sh-app-grid-label {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-align: center;\n line-height: 1.35;\n max-width: 80px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n white-space: normal;\n overflow: hidden;\n min-height: 2.7em;\n}\n.cfi-sh-user-menu {\n position: relative;\n}\n.cfi-sh-avatar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n background: var(--cfi-color-primary-600, #ea580c);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n transition: opacity 150ms;\n}\n.cfi-sh-avatar-btn:hover {\n opacity: 0.85;\n}\n.cfi-sh-avatar-img {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n object-fit: cover;\n}\n.cfi-sh-avatar-initials {\n color: white;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n font-family: inherit;\n}\n.cfi-sh-user-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n min-width: 200px;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n}\n.cfi-sh-user-header {\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n display: flex;\n flex-direction: column;\n}\n.cfi-sh-user-name {\n font-weight: 500;\n color: var(--cfi-color-gray-900, #111827);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-user-email {\n color: var(--cfi-color-gray-500, #6b7280);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n}\n.cfi-sh-divider {\n height: 1px;\n background: var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-menu-item {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n width: 100%;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n background: none;\n border: none;\n color: var(--cfi-color-gray-700, #374151);\n cursor: pointer;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-menu-item:hover {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-menu-item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.cfi-sh-locale-switcher {\n position: relative;\n}\n.cfi-sh-locale-btn {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-xs, 0.25rem);\n height: 32px;\n padding: 0 var(--cfi-spacing-sm, 0.5rem);\n background: transparent;\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n border-radius: var(--cfi-radius-md, 0.375rem);\n color: var(--cfi-color-gray-700, #374151);\n cursor: pointer;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-locale-btn:hover:not(:disabled) {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-locale-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.cfi-sh-locale-label {\n letter-spacing: 0.02em;\n}\n.cfi-sh-locale-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n min-width: 180px;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n padding: var(--cfi-spacing-xs, 0.25rem) 0;\n}\n.cfi-sh-locale-dropdown .cfi-sh-menu-item {\n justify-content: space-between;\n}\n.cfi-sh-locale-item-active {\n background: var(--cfi-color-gray-100, #f3f4f6);\n}\n.cfi-sh-locale-item-label {\n flex: 1;\n text-align: left;\n}\n.cfi-sh-locale-item-code {\n color: var(--cfi-color-gray-400, #9ca3af);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-weight: 600;\n letter-spacing: 0.02em;\n}\n.cfi-sh-locale-row {\n justify-content: flex-start;\n}\n.cfi-sh-locale-row-label {\n flex: 1;\n text-align: left;\n}\n.cfi-sh-locale-row-current {\n color: var(--cfi-color-gray-500, #6b7280);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n margin-right: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-locale-chevron {\n transition: transform 150ms ease;\n flex-shrink: 0;\n}\n.cfi-sh-locale-chevron-open {\n transform: rotate(180deg);\n}\n.cfi-sh-locale-sublist {\n border-top: 1px solid var(--cfi-color-gray-100, #f3f4f6);\n background: var(--cfi-color-gray-50, #f9fafb);\n}\n.cfi-sh-locale-sub-item {\n padding-left: calc(var(--cfi-spacing-md, 1rem) + var(--cfi-spacing-md, 1rem));\n justify-content: space-between;\n}\n.cfi-sh-tenant-static {\n cursor: default;\n pointer-events: none;\n}\n.cfi-sh-tenant-check {\n color: var(--cfi-color-violet-600, #7c3aed);\n}\n.cfi-sh-notif {\n position: relative;\n}\n.cfi-sh-notif-dropdown {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 360px;\n max-height: 480px;\n display: flex;\n flex-direction: column;\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: var(--cfi-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n z-index: 1001;\n overflow: hidden;\n}\n.cfi-sh-notif-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n flex-shrink: 0;\n}\n.cfi-sh-notif-title {\n font-weight: 600;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-notif-mark-all {\n background: none;\n border: none;\n color: var(--cfi-color-primary-600, #ea580c);\n cursor: pointer;\n font-size: var(--cfi-font-size-xs, 0.75rem);\n font-family: inherit;\n padding: 0;\n}\n.cfi-sh-notif-mark-all:hover {\n text-decoration: underline;\n}\n.cfi-sh-notif-list {\n overflow-y: auto;\n flex: 1;\n}\n.cfi-sh-notif-empty {\n padding: var(--cfi-spacing-lg, 1.5rem) var(--cfi-spacing-md, 1rem);\n color: var(--cfi-color-gray-500, #6b7280);\n text-align: center;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-notif-item {\n display: flex;\n align-items: flex-start;\n gap: var(--cfi-spacing-sm, 0.5rem);\n width: 100%;\n padding: var(--cfi-spacing-sm, 0.5rem) var(--cfi-spacing-md, 1rem);\n background: none;\n border: none;\n border-bottom: 1px solid var(--cfi-color-gray-100, #f3f4f6);\n text-align: left;\n cursor: pointer;\n font-family: inherit;\n transition: background 100ms;\n}\n.cfi-sh-notif-item:hover {\n background: var(--cfi-color-gray-50, #f9fafb);\n}\n.cfi-sh-notif-item:last-child {\n border-bottom: none;\n}\n.cfi-sh-notif-dot {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n margin-top: 6px;\n background: var(--cfi-color-primary-600, #ea580c);\n border-radius: 50%;\n}\n.cfi-sh-notif-dot-placeholder {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n margin-top: 6px;\n}\n.cfi-sh-notif-content {\n flex: 1;\n min-width: 0;\n}\n.cfi-sh-notif-item-title {\n font-weight: 500;\n color: var(--cfi-color-gray-900, #111827);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n margin-bottom: 2px;\n}\n.cfi-sh-notif-item-unread .cfi-sh-notif-item-title {\n font-weight: 600;\n}\n.cfi-sh-notif-item-body {\n color: var(--cfi-color-gray-600, #4b5563);\n font-size: var(--cfi-font-size-xs, 0.75rem);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.cfi-sh-notif-item-time {\n color: var(--cfi-color-gray-400, #9ca3af);\n font-size: 11px;\n margin-top: 4px;\n}\n.cfi-sh-about-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1100;\n font-family: var(--cfi-font-family, system-ui, sans-serif);\n}\n.cfi-sh-about-card {\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n min-width: 360px;\n max-width: 500px;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-header {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n padding: var(--cfi-spacing-md, 1rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-about-title {\n font-weight: 600;\n font-size: var(--cfi-font-size-lg, 1.125rem);\n flex: 1;\n}\n.cfi-sh-about-env {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n background: var(--cfi-color-gray-100, #f3f4f6);\n color: var(--cfi-color-gray-700, #374151);\n padding: 2px 8px;\n border-radius: var(--cfi-radius-sm, 0.25rem);\n font-weight: 600;\n}\n.cfi-sh-about-close {\n background: none;\n border: none;\n font-size: 1.5rem;\n line-height: 1;\n cursor: pointer;\n color: var(--cfi-color-gray-500, #6b7280);\n padding: 0 4px;\n font-family: inherit;\n}\n.cfi-sh-about-close:hover {\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-body {\n padding: var(--cfi-spacing-md, 1rem);\n display: flex;\n flex-direction: column;\n gap: var(--cfi-spacing-md, 1rem);\n}\n.cfi-sh-about-section-title {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n color: var(--cfi-color-gray-500, #6b7280);\n margin-bottom: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-about-list {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: var(--cfi-spacing-xs, 0.25rem) var(--cfi-spacing-md, 1rem);\n margin: 0;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n}\n.cfi-sh-about-list dt {\n color: var(--cfi-color-gray-600, #4b5563);\n font-weight: 500;\n}\n.cfi-sh-about-list dd {\n margin: 0;\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-about-list code {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Consolas,\n monospace;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n background: var(--cfi-color-gray-100, #f3f4f6);\n padding: 1px 6px;\n border-radius: var(--cfi-radius-sm, 0.25rem);\n}\n.cfi-sh-about-date {\n color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-about-footer {\n display: flex;\n justify-content: flex-end;\n padding: var(--cfi-spacing-md, 1rem);\n border-top: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-about-copy {\n background: var(--cfi-color-gray-100, #f3f4f6);\n border: 1px solid var(--cfi-color-gray-300, #d1d5db);\n color: var(--cfi-color-gray-900, #111827);\n padding: 6px 12px;\n border-radius: var(--cfi-radius-md, 0.375rem);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: background 150ms;\n}\n.cfi-sh-about-copy:hover {\n background: var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-bug-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1100;\n font-family: var(--cfi-font-family, system-ui, sans-serif);\n}\n.cfi-sh-bug-card {\n background: white;\n border-radius: var(--cfi-radius-lg, 0.5rem);\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n width: 480px;\n max-width: calc(100vw - 32px);\n color: var(--cfi-color-gray-900, #111827);\n display: flex;\n flex-direction: column;\n}\n.cfi-sh-bug-card-wide {\n width: min(1100px, calc(100vw - 64px));\n}\n.cfi-sh-bug-header {\n display: flex;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n padding: var(--cfi-spacing-md, 1rem);\n border-bottom: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-bug-title {\n font-weight: 600;\n font-size: var(--cfi-font-size-lg, 1.125rem);\n flex: 1;\n}\n.cfi-sh-bug-env {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n background: var(--cfi-color-gray-100, #f3f4f6);\n color: var(--cfi-color-gray-700, #374151);\n padding: 2px 8px;\n border-radius: var(--cfi-radius-sm, 0.25rem);\n font-weight: 600;\n}\n.cfi-sh-bug-close {\n background: none;\n border: none;\n font-size: 1.5rem;\n line-height: 1;\n cursor: pointer;\n color: var(--cfi-color-gray-500, #6b7280);\n padding: 0 4px;\n font-family: inherit;\n}\n.cfi-sh-bug-close:hover {\n color: var(--cfi-color-gray-900, #111827);\n}\n.cfi-sh-bug-body {\n padding: var(--cfi-spacing-md, 1rem);\n display: flex;\n flex-direction: column;\n gap: var(--cfi-spacing-sm, 0.5rem);\n}\n.cfi-sh-bug-label {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-bug-input,\n.cfi-sh-bug-textarea {\n font-family: inherit;\n font-size: var(--cfi-font-size-sm, 0.875rem);\n color: var(--cfi-color-gray-900, #111827);\n border: 1px solid var(--cfi-color-gray-300, #d1d5db);\n border-radius: var(--cfi-radius-md, 0.375rem);\n padding: 8px 10px;\n outline: none;\n}\n.cfi-sh-bug-input:focus,\n.cfi-sh-bug-textarea:focus {\n border-color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-bug-textarea {\n resize: vertical;\n min-height: 72px;\n}\n.cfi-sh-bug-shot {\n display: flex;\n align-items: flex-start;\n gap: var(--cfi-spacing-sm, 0.5rem);\n flex-wrap: wrap;\n padding-top: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-bug-thumb {\n max-width: 200px;\n max-height: 120px;\n border: 1px solid var(--cfi-color-gray-300, #d1d5db);\n border-radius: var(--cfi-radius-sm, 0.25rem);\n display: block;\n}\n.cfi-sh-bug-shot-actions {\n display: flex;\n flex-direction: column;\n gap: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-bug-meta {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-bug-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--cfi-spacing-sm, 0.5rem);\n}\n.cfi-sh-bug-modes {\n display: flex;\n gap: var(--cfi-spacing-xs, 0.25rem);\n}\n.cfi-sh-bug-hint {\n font-size: var(--cfi-font-size-xs, 0.75rem);\n color: var(--cfi-color-gray-500, #6b7280);\n}\n.cfi-sh-bug-canvas-wrap {\n overflow: auto;\n max-height: 65vh;\n border: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n border-radius: var(--cfi-radius-sm, 0.25rem);\n background: var(--cfi-color-gray-100, #f3f4f6);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.cfi-sh-bug-canvas {\n max-width: 100%;\n max-height: 65vh;\n cursor: crosshair;\n touch-action: none;\n display: block;\n}\n.cfi-sh-bug-footer {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: var(--cfi-spacing-sm, 0.5rem);\n padding: var(--cfi-spacing-md, 1rem);\n border-top: 1px solid var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-bug-btn {\n background: var(--cfi-color-gray-100, #f3f4f6);\n border: 1px solid var(--cfi-color-gray-300, #d1d5db);\n color: var(--cfi-color-gray-900, #111827);\n padding: 6px 12px;\n border-radius: var(--cfi-radius-md, 0.375rem);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: background 150ms;\n}\n.cfi-sh-bug-btn:hover {\n background: var(--cfi-color-gray-200, #e5e7eb);\n}\n.cfi-sh-bug-btn:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.cfi-sh-bug-btn-primary {\n background: var(--cfi-color-gray-900, #111827);\n border-color: var(--cfi-color-gray-900, #111827);\n color: white;\n}\n.cfi-sh-bug-btn-primary:hover:not(:disabled) {\n background: var(--cfi-color-gray-700, #374151);\n}\n.cfi-sh-bug-btn-active {\n background: var(--cfi-color-gray-900, #111827);\n border-color: var(--cfi-color-gray-900, #111827);\n color: white;\n}\n.cfi-sh-bug-error {\n color: var(--cfi-color-red-600, #dc2626);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n margin-right: auto;\n}\n.cfi-sh-bug-success {\n color: var(--cfi-color-green-600, #16a34a);\n font-size: var(--cfi-font-size-sm, 0.875rem);\n font-weight: 500;\n}\n.cfi-sh-bug-issues-link {\n color: var(--cfi-color-gray-600, #4b5563);\n text-decoration: underline;\n}\n.cfi-sh-bug-issues-link:hover {\n color: var(--cfi-color-gray-900, #111827);\n}\n");
|
|
28
28
|
|
|
29
29
|
// src/appCatalog.ts
|
|
30
30
|
var appCatalog = [
|
|
@@ -740,11 +740,523 @@ function useAboutShortcut(enabled) {
|
|
|
740
740
|
return [isOpen, setIsOpen];
|
|
741
741
|
}
|
|
742
742
|
|
|
743
|
+
// src/BugReportModal.tsx
|
|
744
|
+
import { useCallback, useEffect as useEffect6, useRef as useRef4, useState as useState6 } from "react";
|
|
745
|
+
|
|
746
|
+
// src/captureScreenshot.ts
|
|
747
|
+
async function captureTabScreenshot() {
|
|
748
|
+
if (!navigator.mediaDevices?.getDisplayMedia) {
|
|
749
|
+
throw new Error("Screen capture is not supported in this browser");
|
|
750
|
+
}
|
|
751
|
+
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
752
|
+
video: true,
|
|
753
|
+
audio: false,
|
|
754
|
+
// Chromium hints, absent from lib.dom's DisplayMediaStreamOptions.
|
|
755
|
+
preferCurrentTab: true,
|
|
756
|
+
selfBrowserSurface: "include"
|
|
757
|
+
});
|
|
758
|
+
const video = document.createElement("video");
|
|
759
|
+
try {
|
|
760
|
+
video.srcObject = stream;
|
|
761
|
+
video.muted = true;
|
|
762
|
+
await video.play();
|
|
763
|
+
await new Promise(requestAnimationFrame);
|
|
764
|
+
await new Promise(requestAnimationFrame);
|
|
765
|
+
const canvas = document.createElement("canvas");
|
|
766
|
+
canvas.width = video.videoWidth;
|
|
767
|
+
canvas.height = video.videoHeight;
|
|
768
|
+
const ctx = canvas.getContext("2d");
|
|
769
|
+
if (!ctx || canvas.width === 0 || canvas.height === 0) {
|
|
770
|
+
throw new Error("Could not read a frame from the screen capture");
|
|
771
|
+
}
|
|
772
|
+
ctx.drawImage(video, 0, 0);
|
|
773
|
+
return await new Promise((resolve, reject) => {
|
|
774
|
+
canvas.toBlob(
|
|
775
|
+
(blob) => blob ? resolve(blob) : reject(new Error("Screenshot encoding failed")),
|
|
776
|
+
"image/png"
|
|
777
|
+
);
|
|
778
|
+
});
|
|
779
|
+
} finally {
|
|
780
|
+
video.srcObject = null;
|
|
781
|
+
stream.getTracks().forEach((t) => t.stop());
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// src/bugReportCapture.ts
|
|
786
|
+
var MAX_ENTRIES = 50;
|
|
787
|
+
var MAX_MESSAGE_CHARS = 500;
|
|
788
|
+
var consoleBuffer = [];
|
|
789
|
+
var networkBuffer = [];
|
|
790
|
+
var installed = false;
|
|
791
|
+
function push(buffer, entry) {
|
|
792
|
+
buffer.push(entry);
|
|
793
|
+
if (buffer.length > MAX_ENTRIES) buffer.shift();
|
|
794
|
+
}
|
|
795
|
+
function formatArg(arg) {
|
|
796
|
+
if (typeof arg === "string") return arg;
|
|
797
|
+
if (arg instanceof Error) return `${arg.name}: ${arg.message}`;
|
|
798
|
+
try {
|
|
799
|
+
return JSON.stringify(arg);
|
|
800
|
+
} catch {
|
|
801
|
+
return String(arg);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
function formatArgs(args) {
|
|
805
|
+
return args.map(formatArg).join(" ").slice(0, MAX_MESSAGE_CHARS);
|
|
806
|
+
}
|
|
807
|
+
function installBugReportCapture() {
|
|
808
|
+
if (installed || typeof window === "undefined") return;
|
|
809
|
+
installed = true;
|
|
810
|
+
for (const level of ["error", "warn"]) {
|
|
811
|
+
const original = console[level].bind(console);
|
|
812
|
+
console[level] = (...args) => {
|
|
813
|
+
push(consoleBuffer, { at: (/* @__PURE__ */ new Date()).toISOString(), level, message: formatArgs(args) });
|
|
814
|
+
original(...args);
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
window.addEventListener("error", (e) => {
|
|
818
|
+
push(consoleBuffer, {
|
|
819
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
820
|
+
level: "error",
|
|
821
|
+
message: `uncaught: ${e.message} (${e.filename ?? "?"}:${e.lineno ?? "?"})`.slice(0, MAX_MESSAGE_CHARS)
|
|
822
|
+
});
|
|
823
|
+
});
|
|
824
|
+
window.addEventListener("unhandledrejection", (e) => {
|
|
825
|
+
push(consoleBuffer, {
|
|
826
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
827
|
+
level: "error",
|
|
828
|
+
message: `unhandledrejection: ${formatArg(e.reason)}`.slice(0, MAX_MESSAGE_CHARS)
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
const originalFetch = window.fetch.bind(window);
|
|
832
|
+
window.fetch = async (input, init) => {
|
|
833
|
+
const started = performance.now();
|
|
834
|
+
const method = init?.method ?? (typeof Request !== "undefined" && input instanceof Request ? input.method : "GET");
|
|
835
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
836
|
+
try {
|
|
837
|
+
const res = await originalFetch(input, init);
|
|
838
|
+
if (!res.ok) {
|
|
839
|
+
push(networkBuffer, {
|
|
840
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
841
|
+
method: method.toUpperCase(),
|
|
842
|
+
url,
|
|
843
|
+
status: res.status,
|
|
844
|
+
durationMs: Math.round(performance.now() - started),
|
|
845
|
+
requestId: res.headers.get("x-request-id") ?? void 0
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
return res;
|
|
849
|
+
} catch (err) {
|
|
850
|
+
push(networkBuffer, {
|
|
851
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
852
|
+
method: method.toUpperCase(),
|
|
853
|
+
url,
|
|
854
|
+
status: 0,
|
|
855
|
+
durationMs: Math.round(performance.now() - started)
|
|
856
|
+
});
|
|
857
|
+
throw err;
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
function snapshotBugReportCapture() {
|
|
862
|
+
return { console: [...consoleBuffer], network: [...networkBuffer] };
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// src/BugReportModal.tsx
|
|
866
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
867
|
+
function normalizeRect(x0, y0, x1, y1) {
|
|
868
|
+
return {
|
|
869
|
+
x: Math.min(x0, x1),
|
|
870
|
+
y: Math.min(y0, y1),
|
|
871
|
+
w: Math.abs(x1 - x0),
|
|
872
|
+
h: Math.abs(y1 - y0)
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
function BugReportModal({ config, onClose }) {
|
|
876
|
+
const [view, setView] = useState6("form");
|
|
877
|
+
const [title, setTitle] = useState6("");
|
|
878
|
+
const [description, setDescription] = useState6("");
|
|
879
|
+
const [screenshot, setScreenshot] = useState6(null);
|
|
880
|
+
const [capturing, setCapturing] = useState6(false);
|
|
881
|
+
const [captureError, setCaptureError] = useState6(null);
|
|
882
|
+
const [submitState, setSubmitState] = useState6("idle");
|
|
883
|
+
const [submitError, setSubmitError] = useState6(null);
|
|
884
|
+
const workCanvasRef = useRef4(null);
|
|
885
|
+
const originalRef = useRef4(null);
|
|
886
|
+
const displayCanvasRef = useRef4(null);
|
|
887
|
+
const dragStartRef = useRef4(null);
|
|
888
|
+
const [mode, setMode] = useState6("crop");
|
|
889
|
+
const closeUnlessBusy = useCallback(() => {
|
|
890
|
+
if (submitState === "submitting" || capturing) return;
|
|
891
|
+
if (screenshot) URL.revokeObjectURL(screenshot.previewUrl);
|
|
892
|
+
onClose();
|
|
893
|
+
}, [submitState, capturing, screenshot, onClose]);
|
|
894
|
+
useEffect6(() => {
|
|
895
|
+
function handleEsc(e) {
|
|
896
|
+
if (e.key !== "Escape") return;
|
|
897
|
+
if (view === "editor") {
|
|
898
|
+
setView("form");
|
|
899
|
+
} else {
|
|
900
|
+
closeUnlessBusy();
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
document.addEventListener("keydown", handleEsc);
|
|
904
|
+
return () => document.removeEventListener("keydown", handleEsc);
|
|
905
|
+
}, [view, closeUnlessBusy]);
|
|
906
|
+
async function handleCapture() {
|
|
907
|
+
setCaptureError(null);
|
|
908
|
+
setCapturing(true);
|
|
909
|
+
try {
|
|
910
|
+
const blob = await captureTabScreenshot();
|
|
911
|
+
const image = await blobToCanvas(blob);
|
|
912
|
+
originalRef.current = cloneCanvas(image);
|
|
913
|
+
workCanvasRef.current = image;
|
|
914
|
+
setView("editor");
|
|
915
|
+
} catch (err) {
|
|
916
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
917
|
+
setCaptureError(/denied|dismissed|NotAllowed/i.test(message) ? null : message);
|
|
918
|
+
} finally {
|
|
919
|
+
setCapturing(false);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
useEffect6(() => {
|
|
923
|
+
if (view !== "editor") return;
|
|
924
|
+
syncDisplay();
|
|
925
|
+
});
|
|
926
|
+
function syncDisplay(preview) {
|
|
927
|
+
const work = workCanvasRef.current;
|
|
928
|
+
const display = displayCanvasRef.current;
|
|
929
|
+
if (!work || !display) return;
|
|
930
|
+
if (display.width !== work.width || display.height !== work.height) {
|
|
931
|
+
display.width = work.width;
|
|
932
|
+
display.height = work.height;
|
|
933
|
+
}
|
|
934
|
+
const ctx = display.getContext("2d");
|
|
935
|
+
if (!ctx) return;
|
|
936
|
+
ctx.clearRect(0, 0, display.width, display.height);
|
|
937
|
+
ctx.drawImage(work, 0, 0);
|
|
938
|
+
if (preview && preview.w > 0 && preview.h > 0) {
|
|
939
|
+
if (mode === "redact") {
|
|
940
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.85)";
|
|
941
|
+
ctx.fillRect(preview.x, preview.y, preview.w, preview.h);
|
|
942
|
+
} else {
|
|
943
|
+
ctx.save();
|
|
944
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.45)";
|
|
945
|
+
ctx.fillRect(0, 0, display.width, display.height);
|
|
946
|
+
ctx.clearRect(preview.x, preview.y, preview.w, preview.h);
|
|
947
|
+
ctx.drawImage(
|
|
948
|
+
work,
|
|
949
|
+
preview.x,
|
|
950
|
+
preview.y,
|
|
951
|
+
preview.w,
|
|
952
|
+
preview.h,
|
|
953
|
+
preview.x,
|
|
954
|
+
preview.y,
|
|
955
|
+
preview.w,
|
|
956
|
+
preview.h
|
|
957
|
+
);
|
|
958
|
+
ctx.strokeStyle = "#fff";
|
|
959
|
+
ctx.setLineDash([6, 4]);
|
|
960
|
+
ctx.lineWidth = 2;
|
|
961
|
+
ctx.strokeRect(preview.x, preview.y, preview.w, preview.h);
|
|
962
|
+
ctx.restore();
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
function canvasPoint(e) {
|
|
967
|
+
const display = displayCanvasRef.current;
|
|
968
|
+
const rect = display.getBoundingClientRect();
|
|
969
|
+
return {
|
|
970
|
+
x: Math.max(0, Math.min(display.width, (e.clientX - rect.left) * (display.width / rect.width))),
|
|
971
|
+
y: Math.max(0, Math.min(display.height, (e.clientY - rect.top) * (display.height / rect.height)))
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
function handlePointerDown(e) {
|
|
975
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
976
|
+
dragStartRef.current = canvasPoint(e);
|
|
977
|
+
}
|
|
978
|
+
function handlePointerMove(e) {
|
|
979
|
+
const start = dragStartRef.current;
|
|
980
|
+
if (!start) return;
|
|
981
|
+
const now = canvasPoint(e);
|
|
982
|
+
syncDisplay(normalizeRect(start.x, start.y, now.x, now.y));
|
|
983
|
+
}
|
|
984
|
+
function handlePointerUp(e) {
|
|
985
|
+
const start = dragStartRef.current;
|
|
986
|
+
dragStartRef.current = null;
|
|
987
|
+
if (!start) return;
|
|
988
|
+
const end = canvasPoint(e);
|
|
989
|
+
const rect = normalizeRect(start.x, start.y, end.x, end.y);
|
|
990
|
+
const work = workCanvasRef.current;
|
|
991
|
+
if (!work || rect.w < 4 || rect.h < 4) {
|
|
992
|
+
syncDisplay();
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
if (mode === "redact") {
|
|
996
|
+
const ctx = work.getContext("2d");
|
|
997
|
+
ctx.fillStyle = "#000";
|
|
998
|
+
ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
|
|
999
|
+
} else {
|
|
1000
|
+
const cropped = document.createElement("canvas");
|
|
1001
|
+
cropped.width = Math.round(rect.w);
|
|
1002
|
+
cropped.height = Math.round(rect.h);
|
|
1003
|
+
cropped.getContext("2d").drawImage(
|
|
1004
|
+
work,
|
|
1005
|
+
rect.x,
|
|
1006
|
+
rect.y,
|
|
1007
|
+
rect.w,
|
|
1008
|
+
rect.h,
|
|
1009
|
+
0,
|
|
1010
|
+
0,
|
|
1011
|
+
rect.w,
|
|
1012
|
+
rect.h
|
|
1013
|
+
);
|
|
1014
|
+
workCanvasRef.current = cropped;
|
|
1015
|
+
}
|
|
1016
|
+
syncDisplay();
|
|
1017
|
+
}
|
|
1018
|
+
function handleEditorReset() {
|
|
1019
|
+
const original = originalRef.current;
|
|
1020
|
+
if (!original) return;
|
|
1021
|
+
workCanvasRef.current = cloneCanvas(original);
|
|
1022
|
+
syncDisplay();
|
|
1023
|
+
}
|
|
1024
|
+
async function handleEditorDone() {
|
|
1025
|
+
const work = workCanvasRef.current;
|
|
1026
|
+
if (!work) return;
|
|
1027
|
+
const blob = await new Promise(
|
|
1028
|
+
(resolve, reject) => work.toBlob((b) => b ? resolve(b) : reject(new Error("Screenshot encoding failed")), "image/png")
|
|
1029
|
+
);
|
|
1030
|
+
if (screenshot) URL.revokeObjectURL(screenshot.previewUrl);
|
|
1031
|
+
setScreenshot({ blob, previewUrl: URL.createObjectURL(blob) });
|
|
1032
|
+
setView("form");
|
|
1033
|
+
}
|
|
1034
|
+
function handleRemoveScreenshot() {
|
|
1035
|
+
if (screenshot) URL.revokeObjectURL(screenshot.previewUrl);
|
|
1036
|
+
setScreenshot(null);
|
|
1037
|
+
}
|
|
1038
|
+
async function handleSubmit() {
|
|
1039
|
+
if (!title.trim() || submitState === "submitting") return;
|
|
1040
|
+
setSubmitState("submitting");
|
|
1041
|
+
setSubmitError(null);
|
|
1042
|
+
const { context } = config;
|
|
1043
|
+
const captured = snapshotBugReportCapture();
|
|
1044
|
+
const payload = {
|
|
1045
|
+
appId: context.appId,
|
|
1046
|
+
environment: context.environment,
|
|
1047
|
+
url: context.url ?? window.location.href,
|
|
1048
|
+
title: title.trim(),
|
|
1049
|
+
description: description.trim(),
|
|
1050
|
+
appVersion: context.appVersion,
|
|
1051
|
+
apiVersion: context.apiVersion,
|
|
1052
|
+
userAgent: navigator.userAgent,
|
|
1053
|
+
viewport: `${window.innerWidth}x${window.innerHeight}`,
|
|
1054
|
+
console: captured.console,
|
|
1055
|
+
network: captured.network,
|
|
1056
|
+
screenshot: screenshot?.blob ?? null
|
|
1057
|
+
};
|
|
1058
|
+
try {
|
|
1059
|
+
await config.onSubmit(payload);
|
|
1060
|
+
setSubmitState("success");
|
|
1061
|
+
window.setTimeout(() => {
|
|
1062
|
+
if (screenshot) URL.revokeObjectURL(screenshot.previewUrl);
|
|
1063
|
+
onClose();
|
|
1064
|
+
}, 1500);
|
|
1065
|
+
} catch (err) {
|
|
1066
|
+
setSubmitState("error");
|
|
1067
|
+
setSubmitError(err instanceof Error ? err.message : "Submitting the report failed");
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
if (capturing) return null;
|
|
1071
|
+
return /* @__PURE__ */ jsx6(
|
|
1072
|
+
"div",
|
|
1073
|
+
{
|
|
1074
|
+
className: "cfi-sh-bug-overlay",
|
|
1075
|
+
role: "dialog",
|
|
1076
|
+
"aria-modal": "true",
|
|
1077
|
+
"aria-label": "Report an issue",
|
|
1078
|
+
children: /* @__PURE__ */ jsxs6("div", { className: `cfi-sh-bug-card${view === "editor" ? " cfi-sh-bug-card-wide" : ""}`, children: [
|
|
1079
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-header", children: [
|
|
1080
|
+
/* @__PURE__ */ jsx6("span", { className: "cfi-sh-bug-title", children: "Report an issue" }),
|
|
1081
|
+
/* @__PURE__ */ jsx6("span", { className: "cfi-sh-bug-env", children: config.context.environment }),
|
|
1082
|
+
/* @__PURE__ */ jsx6("button", { className: "cfi-sh-bug-close", type: "button", onClick: closeUnlessBusy, "aria-label": "Close", children: "\xD7" })
|
|
1083
|
+
] }),
|
|
1084
|
+
view === "editor" ? /* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-body", children: [
|
|
1085
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-toolbar", children: [
|
|
1086
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-modes", children: [
|
|
1087
|
+
/* @__PURE__ */ jsx6(
|
|
1088
|
+
"button",
|
|
1089
|
+
{
|
|
1090
|
+
type: "button",
|
|
1091
|
+
className: `cfi-sh-bug-btn${mode === "crop" ? " cfi-sh-bug-btn-active" : ""}`,
|
|
1092
|
+
onClick: () => setMode("crop"),
|
|
1093
|
+
children: "Crop"
|
|
1094
|
+
}
|
|
1095
|
+
),
|
|
1096
|
+
/* @__PURE__ */ jsx6(
|
|
1097
|
+
"button",
|
|
1098
|
+
{
|
|
1099
|
+
type: "button",
|
|
1100
|
+
className: `cfi-sh-bug-btn${mode === "redact" ? " cfi-sh-bug-btn-active" : ""}`,
|
|
1101
|
+
onClick: () => setMode("redact"),
|
|
1102
|
+
children: "Redact"
|
|
1103
|
+
}
|
|
1104
|
+
)
|
|
1105
|
+
] }),
|
|
1106
|
+
/* @__PURE__ */ jsx6("span", { className: "cfi-sh-bug-hint", children: mode === "crop" ? "Drag to crop to a region" : "Drag to black out sensitive data" }),
|
|
1107
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-modes", children: [
|
|
1108
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn", onClick: handleEditorReset, children: "Reset" }),
|
|
1109
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn cfi-sh-bug-btn-primary", onClick: handleEditorDone, children: "Done" })
|
|
1110
|
+
] })
|
|
1111
|
+
] }),
|
|
1112
|
+
/* @__PURE__ */ jsx6("div", { className: "cfi-sh-bug-canvas-wrap", children: /* @__PURE__ */ jsx6(
|
|
1113
|
+
"canvas",
|
|
1114
|
+
{
|
|
1115
|
+
ref: displayCanvasRef,
|
|
1116
|
+
className: "cfi-sh-bug-canvas",
|
|
1117
|
+
onPointerDown: handlePointerDown,
|
|
1118
|
+
onPointerMove: handlePointerMove,
|
|
1119
|
+
onPointerUp: handlePointerUp
|
|
1120
|
+
}
|
|
1121
|
+
) })
|
|
1122
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-body", children: [
|
|
1123
|
+
/* @__PURE__ */ jsx6("label", { className: "cfi-sh-bug-label", htmlFor: "cfi-sh-bug-title-input", children: "Title" }),
|
|
1124
|
+
/* @__PURE__ */ jsx6(
|
|
1125
|
+
"input",
|
|
1126
|
+
{
|
|
1127
|
+
id: "cfi-sh-bug-title-input",
|
|
1128
|
+
className: "cfi-sh-bug-input",
|
|
1129
|
+
value: title,
|
|
1130
|
+
onChange: (e) => setTitle(e.target.value),
|
|
1131
|
+
placeholder: "What went wrong?",
|
|
1132
|
+
maxLength: 200,
|
|
1133
|
+
autoFocus: true
|
|
1134
|
+
}
|
|
1135
|
+
),
|
|
1136
|
+
/* @__PURE__ */ jsx6("label", { className: "cfi-sh-bug-label", htmlFor: "cfi-sh-bug-desc-input", children: "Details" }),
|
|
1137
|
+
/* @__PURE__ */ jsx6(
|
|
1138
|
+
"textarea",
|
|
1139
|
+
{
|
|
1140
|
+
id: "cfi-sh-bug-desc-input",
|
|
1141
|
+
className: "cfi-sh-bug-textarea",
|
|
1142
|
+
value: description,
|
|
1143
|
+
onChange: (e) => setDescription(e.target.value),
|
|
1144
|
+
placeholder: "What did you expect? What happened instead? Steps to reproduce\u2026",
|
|
1145
|
+
rows: 4,
|
|
1146
|
+
maxLength: 1e4
|
|
1147
|
+
}
|
|
1148
|
+
),
|
|
1149
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-shot", children: [
|
|
1150
|
+
screenshot ? /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1151
|
+
/* @__PURE__ */ jsx6("img", { className: "cfi-sh-bug-thumb", src: screenshot.previewUrl, alt: "Screenshot preview" }),
|
|
1152
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-shot-actions", children: [
|
|
1153
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn", onClick: handleCapture, children: "Retake" }),
|
|
1154
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn", onClick: handleRemoveScreenshot, children: "Remove" })
|
|
1155
|
+
] })
|
|
1156
|
+
] }) : /* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn", onClick: handleCapture, children: "Capture screenshot" }),
|
|
1157
|
+
captureError && /* @__PURE__ */ jsx6("div", { className: "cfi-sh-bug-error", children: captureError })
|
|
1158
|
+
] }),
|
|
1159
|
+
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-meta", children: [
|
|
1160
|
+
"Includes: URL, app version, recent console errors and failed requests.",
|
|
1161
|
+
config.context.issuesUrl && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1162
|
+
" ",
|
|
1163
|
+
/* @__PURE__ */ jsx6(
|
|
1164
|
+
"a",
|
|
1165
|
+
{
|
|
1166
|
+
className: "cfi-sh-bug-issues-link",
|
|
1167
|
+
href: config.context.issuesUrl,
|
|
1168
|
+
target: "_blank",
|
|
1169
|
+
rel: "noreferrer",
|
|
1170
|
+
children: "View known issues"
|
|
1171
|
+
}
|
|
1172
|
+
)
|
|
1173
|
+
] })
|
|
1174
|
+
] })
|
|
1175
|
+
] }),
|
|
1176
|
+
view === "form" && /* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-footer", children: [
|
|
1177
|
+
submitState === "error" && submitError && /* @__PURE__ */ jsx6("span", { className: "cfi-sh-bug-error", children: submitError }),
|
|
1178
|
+
submitState === "success" ? /* @__PURE__ */ jsxs6("span", { className: "cfi-sh-bug-success", children: [
|
|
1179
|
+
"Report submitted \u2014 thank you!",
|
|
1180
|
+
config.context.issuesUrl && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1181
|
+
" ",
|
|
1182
|
+
/* @__PURE__ */ jsx6(
|
|
1183
|
+
"a",
|
|
1184
|
+
{
|
|
1185
|
+
className: "cfi-sh-bug-issues-link",
|
|
1186
|
+
href: config.context.issuesUrl,
|
|
1187
|
+
target: "_blank",
|
|
1188
|
+
rel: "noreferrer",
|
|
1189
|
+
children: "View it on the issues page"
|
|
1190
|
+
}
|
|
1191
|
+
)
|
|
1192
|
+
] })
|
|
1193
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1194
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cfi-sh-bug-btn", onClick: closeUnlessBusy, children: "Cancel" }),
|
|
1195
|
+
/* @__PURE__ */ jsx6(
|
|
1196
|
+
"button",
|
|
1197
|
+
{
|
|
1198
|
+
type: "button",
|
|
1199
|
+
className: "cfi-sh-bug-btn cfi-sh-bug-btn-primary",
|
|
1200
|
+
onClick: handleSubmit,
|
|
1201
|
+
disabled: !title.trim() || submitState === "submitting",
|
|
1202
|
+
children: submitState === "submitting" ? "Submitting\u2026" : "Submit report"
|
|
1203
|
+
}
|
|
1204
|
+
)
|
|
1205
|
+
] })
|
|
1206
|
+
] })
|
|
1207
|
+
] })
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
async function blobToCanvas(blob) {
|
|
1212
|
+
const bitmap = await createImageBitmap(blob);
|
|
1213
|
+
try {
|
|
1214
|
+
const canvas = document.createElement("canvas");
|
|
1215
|
+
canvas.width = bitmap.width;
|
|
1216
|
+
canvas.height = bitmap.height;
|
|
1217
|
+
canvas.getContext("2d").drawImage(bitmap, 0, 0);
|
|
1218
|
+
return canvas;
|
|
1219
|
+
} finally {
|
|
1220
|
+
bitmap.close();
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
function cloneCanvas(source) {
|
|
1224
|
+
const copy = document.createElement("canvas");
|
|
1225
|
+
copy.width = source.width;
|
|
1226
|
+
copy.height = source.height;
|
|
1227
|
+
copy.getContext("2d").drawImage(source, 0, 0);
|
|
1228
|
+
return copy;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// src/useBugReportShortcut.ts
|
|
1232
|
+
import { useEffect as useEffect7, useState as useState7 } from "react";
|
|
1233
|
+
function useBugReportShortcut(enabled) {
|
|
1234
|
+
const [isOpen, setIsOpen] = useState7(false);
|
|
1235
|
+
useEffect7(() => {
|
|
1236
|
+
if (!enabled) return;
|
|
1237
|
+
function handleKeyDown(e) {
|
|
1238
|
+
const platformMod = e.ctrlKey || e.metaKey;
|
|
1239
|
+
if (!platformMod || !e.altKey || e.shiftKey) return;
|
|
1240
|
+
if (e.code !== "KeyB" && e.key.toLowerCase() !== "b") return;
|
|
1241
|
+
const target = e.target;
|
|
1242
|
+
if (target) {
|
|
1243
|
+
const tag = target.tagName;
|
|
1244
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable) return;
|
|
1245
|
+
}
|
|
1246
|
+
e.preventDefault();
|
|
1247
|
+
setIsOpen((open) => !open);
|
|
1248
|
+
}
|
|
1249
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1250
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1251
|
+
}, [enabled]);
|
|
1252
|
+
return [isOpen, setIsOpen];
|
|
1253
|
+
}
|
|
1254
|
+
|
|
743
1255
|
// src/assets/campfire-wordmark.png
|
|
744
1256
|
var campfire_wordmark_default = "data:image/png;base64,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";
|
|
745
1257
|
|
|
746
1258
|
// src/ShellHeader.tsx
|
|
747
|
-
import { Fragment as
|
|
1259
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
748
1260
|
function ShellHeader({
|
|
749
1261
|
appId,
|
|
750
1262
|
user,
|
|
@@ -768,24 +1280,26 @@ function ShellHeader({
|
|
|
768
1280
|
onTenantSwitch,
|
|
769
1281
|
userMenuItems,
|
|
770
1282
|
about,
|
|
1283
|
+
bugReport,
|
|
771
1284
|
showSuiteLogo,
|
|
772
1285
|
brandWidth,
|
|
773
1286
|
children
|
|
774
1287
|
}) {
|
|
775
1288
|
const currentApp = appCatalog.find((a) => a.id === appId);
|
|
776
1289
|
const [aboutOpen, setAboutOpen] = useAboutShortcut(about !== void 0);
|
|
1290
|
+
const [bugOpen, setBugOpen] = useBugReportShortcut(bugReport !== void 0);
|
|
777
1291
|
const brandStyle = brandWidth ? { width: `${brandWidth}px`, flexShrink: 0, boxSizing: "border-box" } : void 0;
|
|
778
|
-
return /* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
780
|
-
/* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
currentApp && /* @__PURE__ */
|
|
783
|
-
/* @__PURE__ */
|
|
1292
|
+
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1293
|
+
/* @__PURE__ */ jsxs7("header", { className: "cfi-sh-header", children: [
|
|
1294
|
+
/* @__PURE__ */ jsxs7("div", { className: "cfi-sh-left", children: [
|
|
1295
|
+
/* @__PURE__ */ jsx7("div", { className: "cfi-sh-app-brand", style: brandStyle, children: showSuiteLogo ? /* @__PURE__ */ jsx7("img", { className: "cfi-sh-suite-logo", src: campfire_wordmark_default, alt: "Campfire" }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1296
|
+
currentApp && /* @__PURE__ */ jsx7("span", { className: "cfi-sh-app-badge", style: { background: currentApp.color }, children: currentApp.letter }),
|
|
1297
|
+
/* @__PURE__ */ jsx7("span", { className: "cfi-sh-app-title", children: currentApp?.name || appId })
|
|
784
1298
|
] }) }),
|
|
785
1299
|
children
|
|
786
1300
|
] }),
|
|
787
|
-
/* @__PURE__ */
|
|
788
|
-
/* @__PURE__ */
|
|
1301
|
+
/* @__PURE__ */ jsxs7("div", { className: "cfi-sh-right", children: [
|
|
1302
|
+
/* @__PURE__ */ jsx7(
|
|
789
1303
|
NotificationBell,
|
|
790
1304
|
{
|
|
791
1305
|
count: notificationCount,
|
|
@@ -796,8 +1310,8 @@ function ShellHeader({
|
|
|
796
1310
|
onItemClick: onNotificationItemClick
|
|
797
1311
|
}
|
|
798
1312
|
),
|
|
799
|
-
/* @__PURE__ */
|
|
800
|
-
/* @__PURE__ */
|
|
1313
|
+
/* @__PURE__ */ jsx7(AppSwitcher, { currentAppId: appId, authorizedApps, currentTenantRole }),
|
|
1314
|
+
/* @__PURE__ */ jsx7(
|
|
801
1315
|
UserMenu,
|
|
802
1316
|
{
|
|
803
1317
|
user,
|
|
@@ -817,18 +1331,19 @@ function ShellHeader({
|
|
|
817
1331
|
)
|
|
818
1332
|
] })
|
|
819
1333
|
] }),
|
|
820
|
-
about && aboutOpen && /* @__PURE__ */
|
|
1334
|
+
about && aboutOpen && /* @__PURE__ */ jsx7(AboutModal, { about, onClose: () => setAboutOpen(false) }),
|
|
1335
|
+
bugReport && bugOpen && /* @__PURE__ */ jsx7(BugReportModal, { config: bugReport, onClose: () => setBugOpen(false) })
|
|
821
1336
|
] });
|
|
822
1337
|
}
|
|
823
1338
|
|
|
824
1339
|
// src/LocaleSwitcher.tsx
|
|
825
|
-
import { useState as
|
|
826
|
-
import { jsx as
|
|
1340
|
+
import { useState as useState8, useRef as useRef5, useEffect as useEffect8 } from "react";
|
|
1341
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
827
1342
|
function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }) {
|
|
828
|
-
const [open, setOpen] =
|
|
829
|
-
const [updating, setUpdating] =
|
|
830
|
-
const ref =
|
|
831
|
-
|
|
1343
|
+
const [open, setOpen] = useState8(false);
|
|
1344
|
+
const [updating, setUpdating] = useState8(false);
|
|
1345
|
+
const ref = useRef5(null);
|
|
1346
|
+
useEffect8(() => {
|
|
832
1347
|
function handleClickOutside(e) {
|
|
833
1348
|
if (ref.current && !ref.current.contains(e.target)) {
|
|
834
1349
|
setOpen(false);
|
|
@@ -852,8 +1367,8 @@ function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }) {
|
|
|
852
1367
|
setOpen(false);
|
|
853
1368
|
}
|
|
854
1369
|
}
|
|
855
|
-
return /* @__PURE__ */
|
|
856
|
-
/* @__PURE__ */
|
|
1370
|
+
return /* @__PURE__ */ jsxs8("div", { className: "cfi-sh-locale-switcher", ref, children: [
|
|
1371
|
+
/* @__PURE__ */ jsxs8(
|
|
857
1372
|
"button",
|
|
858
1373
|
{
|
|
859
1374
|
className: "cfi-sh-locale-btn",
|
|
@@ -864,20 +1379,20 @@ function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }) {
|
|
|
864
1379
|
disabled: updating,
|
|
865
1380
|
title: current?.label ?? currentLocale,
|
|
866
1381
|
children: [
|
|
867
|
-
/* @__PURE__ */
|
|
868
|
-
/* @__PURE__ */
|
|
1382
|
+
/* @__PURE__ */ jsx8(Globe, { size: 16 }),
|
|
1383
|
+
/* @__PURE__ */ jsx8("span", { className: "cfi-sh-locale-label", children: buttonLabel })
|
|
869
1384
|
]
|
|
870
1385
|
}
|
|
871
1386
|
),
|
|
872
|
-
open && /* @__PURE__ */
|
|
1387
|
+
open && /* @__PURE__ */ jsx8("div", { className: "cfi-sh-locale-dropdown", children: supportedLocales.map((loc) => /* @__PURE__ */ jsxs8(
|
|
873
1388
|
"button",
|
|
874
1389
|
{
|
|
875
1390
|
className: loc.code === currentLocale ? "cfi-sh-menu-item cfi-sh-locale-item-active" : "cfi-sh-menu-item",
|
|
876
1391
|
onClick: () => handleSelect(loc.code),
|
|
877
1392
|
disabled: updating,
|
|
878
1393
|
children: [
|
|
879
|
-
/* @__PURE__ */
|
|
880
|
-
/* @__PURE__ */
|
|
1394
|
+
/* @__PURE__ */ jsx8("span", { className: "cfi-sh-locale-item-label", children: loc.label }),
|
|
1395
|
+
/* @__PURE__ */ jsx8("span", { className: "cfi-sh-locale-item-code", children: loc.code.toUpperCase() })
|
|
881
1396
|
]
|
|
882
1397
|
},
|
|
883
1398
|
loc.code
|
|
@@ -888,5 +1403,6 @@ export {
|
|
|
888
1403
|
LocaleSwitcher,
|
|
889
1404
|
ShellHeader,
|
|
890
1405
|
appCatalog,
|
|
891
|
-
getAppUrl
|
|
1406
|
+
getAppUrl,
|
|
1407
|
+
installBugReportCapture
|
|
892
1408
|
};
|