spaps-issue-reporting-react 0.1.2 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.3] - 2026-04-20
4
+
5
+ - Changed: publish the page-first report flow package metadata and align README metadata with the current package version.
6
+
7
+ ## [0.1.1] - 2026-04-05
8
+
9
+ - Docs: align package README metadata with published version.
10
+
3
11
  ## [0.1.0] - 2026-03-29
4
12
 
5
13
  - Added the first shared React issue-reporting package for SPAPS consumers.
package/README.md CHANGED
@@ -10,16 +10,16 @@ Examples in this README use placeholder IDs and app labels. Replace them with va
10
10
  npm install spaps-issue-reporting-react react react-dom @tanstack/react-query
11
11
  ```
12
12
 
13
- This package targets `Node.js >=18` and React 18+.
13
+ This package targets `Node.js >=18` and React 18+. Voice input uses the package's `@elevenlabs/react` dependency and a SPAPS-minted single-use token.
14
14
 
15
15
  ## When It Fits
16
16
 
17
17
  | Need | Package gives you |
18
18
  | --- | --- |
19
19
  | A visible issue-report entry point | Floating button with open/recent state |
20
- | A guided reporting flow | Report mode, highlighted sections, create/edit/reply modal |
20
+ | A guided reporting flow | Page-first create flow, optional section picking, create/edit/reply modal |
21
21
  | A lightweight integration contract | Any client that exposes `issueReporting.*` methods |
22
- | App-level control | Eligibility, reporter identity, scope, and copy stay in your app |
22
+ | App-level control | Eligibility, reporter identity, scope, page policy, and copy stay in your app |
23
23
 
24
24
  ## Quick Start
25
25
 
@@ -27,6 +27,7 @@ This package targets `Node.js >=18` and React 18+.
27
27
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
28
28
  import {
29
29
  FloatingIssueReportButton,
30
+ IssueReportingPageConfig,
30
31
  IssueReportingProvider,
31
32
  ReportableSection,
32
33
  } from "spaps-issue-reporting-react";
@@ -42,9 +43,12 @@ export function AppShell() {
42
43
  isEligible={true}
43
44
  principalId="user_123"
44
45
  reporterRoleHint="staff"
45
- allowTenantScope
46
46
  defaultScope="mine"
47
+ inputModes={["text", "voice"]}
48
+ defaultInputMode="text"
47
49
  >
50
+ <IssueReportingPageConfig createMode="surface_preferred" />
51
+
48
52
  <ReportableSection
49
53
  reportableName={{
50
54
  componentKey: "patient_chart",
@@ -66,24 +70,72 @@ export function AppShell() {
66
70
  ## What Your App Still Owns
67
71
 
68
72
  - A client with `issueReporting.getStatus`, `list`, `get`, `create`, `update`, and `reply`.
73
+ - A client with `issueReporting.createVoiceToken` when `inputModes` includes `voice`.
69
74
  - Any auth and token refresh behavior needed by that client.
70
75
  - Eligibility rules such as feature flags, account state, or role checks.
71
76
  - The current principal ID and optional role hint passed into the provider.
72
- - Whether users can switch between `mine` and `tenant` queue scope.
77
+ - Whether users can switch between `mine` and a custom tenant queue scope. The stock SPAPS API
78
+ supports `mine` only; use `allowTenantScope` only with a client that implements tenant reads.
79
+ - Whether a page defaults to `general_page`, `surface_required`, or `surface_preferred` reporting.
80
+ - Whether the app allows `["text"]`, `["voice"]`, or `["text", "voice"]` report input.
73
81
  - Styling integration if your build strips package utility classes.
74
82
  - Any app-specific copy overrides.
75
83
  - Origin registration on the owning SPAPS application if the browser calls SPAPS directly with a publishable key.
76
84
 
77
85
  For direct browser integrations, `allowed_origins` is stored on the SPAPS `applications` row that owns the publishable key. It is not configured on this package. If multiple hostnames share one SPAPS application, put all of them on that row. Updating `allowed_origins` does not require restarting SPAPS.
78
86
 
87
+ ## Voice Input
88
+
89
+ Voice mode is opt-in per app. Configure the owning SPAPS application with either:
90
+
91
+ ```json
92
+ {
93
+ "issue_reporting_input_modes": ["text", "voice"]
94
+ }
95
+ ```
96
+
97
+ or:
98
+
99
+ ```json
100
+ {
101
+ "issue_reporting": {
102
+ "input_modes": ["voice"]
103
+ }
104
+ }
105
+ ```
106
+
107
+ The SPAPS server also needs `ELEVENLABS_API_KEY`. The browser calls your normal SPAPS client, which mints a short-lived Scribe token through `issueReporting.createVoiceToken()`. The committed transcript is submitted as the issue `note`; raw audio is not stored by this package.
108
+
109
+ ```tsx
110
+ <IssueReportingProvider
111
+ client={spaps}
112
+ isEligible={true}
113
+ inputModes={["voice"]}
114
+ defaultInputMode="voice"
115
+ voice={{
116
+ modelId: "scribe_v2_realtime",
117
+ microphone: {
118
+ echoCancellation: true,
119
+ noiseSuppression: true,
120
+ autoGainControl: true,
121
+ },
122
+ }}
123
+ >
124
+ <FloatingIssueReportButton />
125
+ </IssueReportingProvider>
126
+ ```
127
+
128
+ When text and voice are both enabled, the modal keeps the textarea available and lets the user append a committed transcript into the editable note.
129
+
79
130
  ## Exported Surface
80
131
 
81
132
  | Export | Purpose |
82
133
  | --- | --- |
83
134
  | `IssueReportingProvider` | Owns queries, modal state, copy, scope, and report-mode behavior |
135
+ | `IssueReportingPageConfig` | Per-page override for `general_page`, `surface_required`, or `surface_preferred` create policy |
84
136
  | `FloatingIssueReportButton` | Renders the floating entry point, popover, and modal |
85
137
  | `ReportableSection` | Marks a region as selectable when report mode is active |
86
- | `useIssueReporting` | Full provider state, including `enterReportMode()` |
138
+ | `useIssueReporting` | Full provider state, including `startNewIssue()`, `openPageIssueModal()`, and `enterReportMode()` |
87
139
  | `useIssueReportingStatus` | Query helper for summary state |
88
140
  | `useIssueReportingHistory` | Query helper for filtered history lists |
89
141
  | `useIssueReportingMutations` | Mutation helpers for create, update, and reply flows |
@@ -111,18 +163,35 @@ npm test
111
163
 
112
164
  Make sure `FloatingIssueReportButton` is rendered inside `IssueReportingProvider` and that `isEligible` is `true`.
113
165
 
166
+ ### I want page-level reporting without wrapping every widget
167
+
168
+ That is the default. `Report This Page` opens immediately and captures the current route plus the inventory of visible registered reportable sections on the active page.
169
+
114
170
  ### Report mode turns on, but sections do not respond
115
171
 
116
172
  Wrap the target UI in `ReportableSection`, or call `useIssueReporting().selectPanel(...)` from a custom control.
117
173
 
174
+ ### This page should force a specific surface selection
175
+
176
+ Render `IssueReportingPageConfig` with `createMode="surface_required"` inside that page's visible provider subtree. Hidden mounted routes, tabs, or panels do not affect the active page's policy.
177
+
118
178
  ### Tenant scope never appears
119
179
 
120
- Set `allowTenantScope={true}`. The provider defaults to `mine`.
180
+ The stock SPAPS API supports `mine` only. Set `allowTenantScope={true}` only when your client
181
+ implements tenant-scoped `getStatus` and `list` calls.
121
182
 
122
183
  ### Styles look unformatted
123
184
 
124
185
  Include the package in your Tailwind or CSS-content scan, or override the rendered classes in your host app.
125
186
 
187
+ ### Voice controls do not appear
188
+
189
+ Pass `inputModes={["voice"]}` or `inputModes={["text", "voice"]}` to the provider, and enable `voice` in the owning SPAPS application's issue-reporting settings.
190
+
191
+ ### Voice starts with a token error
192
+
193
+ Confirm that the SPAPS server has `ELEVENLABS_API_KEY` set and that the current user is authenticated and eligible for issue reporting.
194
+
126
195
  ## Limitations
127
196
 
128
197
  - This package assumes React Query is already part of the host app.
@@ -139,6 +208,10 @@ No. You only need a client object that implements the `issueReporting` methods e
139
208
 
140
209
  Yes. Use `useIssueReporting().enterReportMode()` inside the provider tree.
141
210
 
211
+ ### Can I open a page-level report from my own button?
212
+
213
+ Yes. Use `useIssueReporting().openPageIssueModal()` or `useIssueReporting().startNewIssue()`.
214
+
142
215
  ### Can I report plain strings instead of structured descriptors?
143
216
 
144
217
  Yes. `reportableName` accepts either a string or a `{ componentKey, componentLabel, ... }` object.
@@ -155,6 +228,13 @@ No. It only renders scope choices that your app explicitly allows.
155
228
 
156
229
  No. This package is UI only. If your browser app calls SPAPS directly with a publishable key, the relevant SPAPS application row must include that browser origin in `allowed_origins`.
157
230
 
231
+ ## Metadata
232
+
233
+ - `package_name`: `spaps-issue-reporting-react`
234
+ - `latest_version`: `0.1.3`
235
+ - `minimum_runtime`: `Node.js >=18.0.0`
236
+ - `api_base_url`: `https://api.sweetpotato.dev`
237
+
158
238
  ## About Contributions
159
239
 
160
240
  > *About Contributions:* Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via `gh` and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.
package/dist/index.d.mts CHANGED
@@ -2,11 +2,24 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { ReactNode } from 'react';
4
4
  import * as spaps_types from 'spaps-types';
5
- import { IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, UpdateIssueReportRequest, ReplyIssueReportRequest } from 'spaps-types';
5
+ import { IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, UpdateIssueReportRequest, ReplyIssueReportRequest, IssueReportingVoiceTokenResult, IssueReportingInputMode, IssueReportingVoiceProvider } from 'spaps-types';
6
6
  export { CreateIssueReportRequest, IssueReport, IssueReportListResult, IssueReportScope, IssueReportStatus, IssueReportStatusResult, ReplyIssueReportRequest, UpdateIssueReportRequest } from 'spaps-types';
7
7
  import * as _tanstack_query_core from '@tanstack/query-core';
8
8
  import * as _tanstack_react_query from '@tanstack/react-query';
9
9
 
10
+ interface IssueReportingVoiceMicrophoneConfig {
11
+ deviceId?: string;
12
+ echoCancellation?: boolean;
13
+ noiseSuppression?: boolean;
14
+ autoGainControl?: boolean;
15
+ channelCount?: number;
16
+ }
17
+ interface IssueReportingVoiceConfig {
18
+ provider?: IssueReportingVoiceProvider;
19
+ modelId?: string;
20
+ requireMicrophonePermission?: boolean;
21
+ microphone?: IssueReportingVoiceMicrophoneConfig;
22
+ }
10
23
  interface IssueReportingClient {
11
24
  issueReporting: {
12
25
  getStatus: (params?: {
@@ -22,6 +35,7 @@ interface IssueReportingClient {
22
35
  create: (payload: CreateIssueReportRequest) => Promise<IssueReport>;
23
36
  update: (issueReportId: string, payload: UpdateIssueReportRequest) => Promise<IssueReport>;
24
37
  reply: (issueReportId: string, payload: ReplyIssueReportRequest) => Promise<IssueReport>;
38
+ createVoiceToken?: () => Promise<IssueReportingVoiceTokenResult>;
25
39
  };
26
40
  }
27
41
  interface ReportableTargetDescriptor {
@@ -31,11 +45,14 @@ interface ReportableTargetDescriptor {
31
45
  metadata?: Record<string, unknown>;
32
46
  }
33
47
  type ReportableInput = string | ReportableTargetDescriptor;
48
+ type IssueReportingCreateMode = "general_page" | "surface_required" | "surface_preferred";
34
49
  type IssueHistoryFilter = "all" | "unresolved" | "resolved";
35
50
  interface IssueReportingCopy {
36
51
  entryAriaLabel: string;
37
52
  popoverTitle: string;
38
53
  reportNewAction: string;
54
+ reportPageAction: string;
55
+ reportSpecificAction: string;
39
56
  filtersAll: string;
40
57
  filtersUnresolved: string;
41
58
  filtersResolved: string;
@@ -52,6 +69,9 @@ interface IssueReportingCopy {
52
69
  reportModeTitle: string;
53
70
  reportModeDescription: string;
54
71
  reportModeCancelAction: string;
72
+ generalPageTargetLabel: string;
73
+ surfaceRequiredDescription: string;
74
+ specificSectionUnavailableDescription: string;
55
75
  createTitlePrefix: string;
56
76
  editTitlePrefix: string;
57
77
  replyTitlePrefix: string;
@@ -82,6 +102,10 @@ interface IssueReportingProviderProps {
82
102
  getPageUrl?: () => string;
83
103
  defaultScope?: IssueReportScope;
84
104
  allowTenantScope?: boolean;
105
+ defaultCreateMode?: IssueReportingCreateMode;
106
+ inputModes?: IssueReportingInputMode[];
107
+ defaultInputMode?: IssueReportingInputMode;
108
+ voice?: IssueReportingVoiceConfig;
85
109
  copy?: Partial<IssueReportingCopy>;
86
110
  children: ReactNode;
87
111
  }
@@ -89,6 +113,9 @@ interface FloatingIssueReportButtonProps {
89
113
  className?: string;
90
114
  positionClassName?: string;
91
115
  }
116
+ interface IssueReportingPageConfigProps {
117
+ createMode: IssueReportingCreateMode;
118
+ }
92
119
 
93
120
  declare function FloatingIssueReportButton({ className, positionClassName, }: FloatingIssueReportButtonProps): react_jsx_runtime.JSX.Element | null;
94
121
  declare function ReportableSection({ reportableName, children, className, as: Component, }: {
@@ -96,7 +123,7 @@ declare function ReportableSection({ reportableName, children, className, as: Co
96
123
  children: React__default.ReactNode;
97
124
  className?: string;
98
125
  as?: keyof JSX.IntrinsicElements;
99
- }): react_jsx_runtime.JSX.Element;
126
+ }): React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
100
127
 
101
128
  type ModalMode = "create" | "edit" | "reply";
102
129
  type ResolvedTarget = {
@@ -122,9 +149,12 @@ type IssueReportingContextValue = {
122
149
  principalId: string | null;
123
150
  copy: IssueReportingCopy;
124
151
  isReportMode: boolean;
152
+ hasRegisteredTargets: boolean;
125
153
  enterReportMode: () => void;
126
154
  cancelReportMode: () => void;
127
155
  selectPanel: (target: ReportableInput) => void;
156
+ openPageIssueModal: () => void;
157
+ startNewIssue: () => void;
128
158
  isPopoverOpen: boolean;
129
159
  openPopover: () => void;
130
160
  closePopover: () => void;
@@ -135,6 +165,12 @@ type IssueReportingContextValue = {
135
165
  scope: IssueReportScope;
136
166
  setScope: (scope: IssueReportScope) => void;
137
167
  allowTenantScope: boolean;
168
+ createMode: IssueReportingCreateMode;
169
+ inputModes: IssueReportingInputMode[];
170
+ defaultInputMode: IssueReportingInputMode;
171
+ voice: Required<Pick<IssueReportingVoiceConfig, "provider" | "modelId" | "requireMicrophonePermission">> & {
172
+ microphone?: IssueReportingVoiceConfig["microphone"];
173
+ };
138
174
  };
139
175
  declare const defaultIssueReportingCopy: IssueReportingCopy;
140
176
  declare const issueReportingKeys: {
@@ -155,6 +191,7 @@ declare function getEntryPointState(status?: {
155
191
  declare function getEntryPointClassName(state: "open" | "recent_resolved" | "neutral"): string;
156
192
  declare function getIssueNoteLengthMessage(note: string, copy: IssueReportingCopy): string;
157
193
  declare function useIssueReporting(): IssueReportingContextValue;
194
+ declare function IssueReportingPageConfig({ createMode, }: IssueReportingPageConfigProps): react_jsx_runtime.JSX.Element;
158
195
  declare function useIssueReportingStatus(): _tanstack_react_query.UseQueryResult<spaps_types.IssueReportStatusResult, Error>;
159
196
  declare function useIssueReportingHistory(filter?: IssueHistoryFilter): {
160
197
  items: IssueReport[];
@@ -347,14 +384,17 @@ declare function useIssueReportingMutations(): {
347
384
  reporterRoleHint?: string;
348
385
  }, unknown>;
349
386
  };
350
- declare function IssueReportingProvider({ client, isEligible, reporterRoleHint, principalId, getPageUrl, defaultScope, allowTenantScope, copy, children, }: IssueReportingProviderProps): react_jsx_runtime.JSX.Element;
387
+ declare function IssueReportingProvider({ client, isEligible, reporterRoleHint, principalId, getPageUrl, defaultScope, allowTenantScope, defaultCreateMode, inputModes, defaultInputMode, voice, copy, children, }: IssueReportingProviderProps): react_jsx_runtime.JSX.Element;
351
388
 
352
389
  interface ReportModeContextValue {
353
390
  isReportMode: boolean;
354
391
  selectPanel: (target: ReportableInput) => void;
355
392
  cancelReportMode: () => void;
393
+ hasRegisteredTargets: boolean;
394
+ registerTarget: (id: symbol, target: ReportableInput, getElement: () => Element | null) => void;
395
+ unregisterTarget: (id: symbol) => void;
356
396
  }
357
397
  declare const ReportModeContext: React.Context<ReportModeContextValue | null>;
358
398
  declare function useReportMode(): ReportModeContextValue | null;
359
399
 
360
- export { FloatingIssueReportButton, type FloatingIssueReportButtonProps, type IssueHistoryFilter, type IssueReportingClient, type IssueReportingCopy, IssueReportingProvider, type IssueReportingProviderProps, ReportModeContext, type ReportModeContextValue, type ReportableInput, ReportableSection, type ReportableTargetDescriptor, defaultIssueReportingCopy, filterIssueReports, getEntryPointClassName, getEntryPointState, getIssueNoteLengthMessage, getIssueStatusBadgeLabel, getIssueStatusClassName, isClosedIssueStatus, isOpenIssueStatus, issueReportingKeys, useIssueReporting, useIssueReportingHistory, useIssueReportingMutations, useIssueReportingStatus, useReportMode };
400
+ export { FloatingIssueReportButton, type FloatingIssueReportButtonProps, type IssueHistoryFilter, type IssueReportingClient, type IssueReportingCopy, type IssueReportingCreateMode, IssueReportingPageConfig, type IssueReportingPageConfigProps, IssueReportingProvider, type IssueReportingProviderProps, ReportModeContext, type ReportModeContextValue, type ReportableInput, ReportableSection, type ReportableTargetDescriptor, defaultIssueReportingCopy, filterIssueReports, getEntryPointClassName, getEntryPointState, getIssueNoteLengthMessage, getIssueStatusBadgeLabel, getIssueStatusClassName, isClosedIssueStatus, isOpenIssueStatus, issueReportingKeys, useIssueReporting, useIssueReportingHistory, useIssueReportingMutations, useIssueReportingStatus, useReportMode };
package/dist/index.d.ts CHANGED
@@ -2,11 +2,24 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { ReactNode } from 'react';
4
4
  import * as spaps_types from 'spaps-types';
5
- import { IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, UpdateIssueReportRequest, ReplyIssueReportRequest } from 'spaps-types';
5
+ import { IssueReportScope, IssueReportStatusResult, IssueReportStatus, IssueReportListResult, IssueReport, CreateIssueReportRequest, UpdateIssueReportRequest, ReplyIssueReportRequest, IssueReportingVoiceTokenResult, IssueReportingInputMode, IssueReportingVoiceProvider } from 'spaps-types';
6
6
  export { CreateIssueReportRequest, IssueReport, IssueReportListResult, IssueReportScope, IssueReportStatus, IssueReportStatusResult, ReplyIssueReportRequest, UpdateIssueReportRequest } from 'spaps-types';
7
7
  import * as _tanstack_query_core from '@tanstack/query-core';
8
8
  import * as _tanstack_react_query from '@tanstack/react-query';
9
9
 
10
+ interface IssueReportingVoiceMicrophoneConfig {
11
+ deviceId?: string;
12
+ echoCancellation?: boolean;
13
+ noiseSuppression?: boolean;
14
+ autoGainControl?: boolean;
15
+ channelCount?: number;
16
+ }
17
+ interface IssueReportingVoiceConfig {
18
+ provider?: IssueReportingVoiceProvider;
19
+ modelId?: string;
20
+ requireMicrophonePermission?: boolean;
21
+ microphone?: IssueReportingVoiceMicrophoneConfig;
22
+ }
10
23
  interface IssueReportingClient {
11
24
  issueReporting: {
12
25
  getStatus: (params?: {
@@ -22,6 +35,7 @@ interface IssueReportingClient {
22
35
  create: (payload: CreateIssueReportRequest) => Promise<IssueReport>;
23
36
  update: (issueReportId: string, payload: UpdateIssueReportRequest) => Promise<IssueReport>;
24
37
  reply: (issueReportId: string, payload: ReplyIssueReportRequest) => Promise<IssueReport>;
38
+ createVoiceToken?: () => Promise<IssueReportingVoiceTokenResult>;
25
39
  };
26
40
  }
27
41
  interface ReportableTargetDescriptor {
@@ -31,11 +45,14 @@ interface ReportableTargetDescriptor {
31
45
  metadata?: Record<string, unknown>;
32
46
  }
33
47
  type ReportableInput = string | ReportableTargetDescriptor;
48
+ type IssueReportingCreateMode = "general_page" | "surface_required" | "surface_preferred";
34
49
  type IssueHistoryFilter = "all" | "unresolved" | "resolved";
35
50
  interface IssueReportingCopy {
36
51
  entryAriaLabel: string;
37
52
  popoverTitle: string;
38
53
  reportNewAction: string;
54
+ reportPageAction: string;
55
+ reportSpecificAction: string;
39
56
  filtersAll: string;
40
57
  filtersUnresolved: string;
41
58
  filtersResolved: string;
@@ -52,6 +69,9 @@ interface IssueReportingCopy {
52
69
  reportModeTitle: string;
53
70
  reportModeDescription: string;
54
71
  reportModeCancelAction: string;
72
+ generalPageTargetLabel: string;
73
+ surfaceRequiredDescription: string;
74
+ specificSectionUnavailableDescription: string;
55
75
  createTitlePrefix: string;
56
76
  editTitlePrefix: string;
57
77
  replyTitlePrefix: string;
@@ -82,6 +102,10 @@ interface IssueReportingProviderProps {
82
102
  getPageUrl?: () => string;
83
103
  defaultScope?: IssueReportScope;
84
104
  allowTenantScope?: boolean;
105
+ defaultCreateMode?: IssueReportingCreateMode;
106
+ inputModes?: IssueReportingInputMode[];
107
+ defaultInputMode?: IssueReportingInputMode;
108
+ voice?: IssueReportingVoiceConfig;
85
109
  copy?: Partial<IssueReportingCopy>;
86
110
  children: ReactNode;
87
111
  }
@@ -89,6 +113,9 @@ interface FloatingIssueReportButtonProps {
89
113
  className?: string;
90
114
  positionClassName?: string;
91
115
  }
116
+ interface IssueReportingPageConfigProps {
117
+ createMode: IssueReportingCreateMode;
118
+ }
92
119
 
93
120
  declare function FloatingIssueReportButton({ className, positionClassName, }: FloatingIssueReportButtonProps): react_jsx_runtime.JSX.Element | null;
94
121
  declare function ReportableSection({ reportableName, children, className, as: Component, }: {
@@ -96,7 +123,7 @@ declare function ReportableSection({ reportableName, children, className, as: Co
96
123
  children: React__default.ReactNode;
97
124
  className?: string;
98
125
  as?: keyof JSX.IntrinsicElements;
99
- }): react_jsx_runtime.JSX.Element;
126
+ }): React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
100
127
 
101
128
  type ModalMode = "create" | "edit" | "reply";
102
129
  type ResolvedTarget = {
@@ -122,9 +149,12 @@ type IssueReportingContextValue = {
122
149
  principalId: string | null;
123
150
  copy: IssueReportingCopy;
124
151
  isReportMode: boolean;
152
+ hasRegisteredTargets: boolean;
125
153
  enterReportMode: () => void;
126
154
  cancelReportMode: () => void;
127
155
  selectPanel: (target: ReportableInput) => void;
156
+ openPageIssueModal: () => void;
157
+ startNewIssue: () => void;
128
158
  isPopoverOpen: boolean;
129
159
  openPopover: () => void;
130
160
  closePopover: () => void;
@@ -135,6 +165,12 @@ type IssueReportingContextValue = {
135
165
  scope: IssueReportScope;
136
166
  setScope: (scope: IssueReportScope) => void;
137
167
  allowTenantScope: boolean;
168
+ createMode: IssueReportingCreateMode;
169
+ inputModes: IssueReportingInputMode[];
170
+ defaultInputMode: IssueReportingInputMode;
171
+ voice: Required<Pick<IssueReportingVoiceConfig, "provider" | "modelId" | "requireMicrophonePermission">> & {
172
+ microphone?: IssueReportingVoiceConfig["microphone"];
173
+ };
138
174
  };
139
175
  declare const defaultIssueReportingCopy: IssueReportingCopy;
140
176
  declare const issueReportingKeys: {
@@ -155,6 +191,7 @@ declare function getEntryPointState(status?: {
155
191
  declare function getEntryPointClassName(state: "open" | "recent_resolved" | "neutral"): string;
156
192
  declare function getIssueNoteLengthMessage(note: string, copy: IssueReportingCopy): string;
157
193
  declare function useIssueReporting(): IssueReportingContextValue;
194
+ declare function IssueReportingPageConfig({ createMode, }: IssueReportingPageConfigProps): react_jsx_runtime.JSX.Element;
158
195
  declare function useIssueReportingStatus(): _tanstack_react_query.UseQueryResult<spaps_types.IssueReportStatusResult, Error>;
159
196
  declare function useIssueReportingHistory(filter?: IssueHistoryFilter): {
160
197
  items: IssueReport[];
@@ -347,14 +384,17 @@ declare function useIssueReportingMutations(): {
347
384
  reporterRoleHint?: string;
348
385
  }, unknown>;
349
386
  };
350
- declare function IssueReportingProvider({ client, isEligible, reporterRoleHint, principalId, getPageUrl, defaultScope, allowTenantScope, copy, children, }: IssueReportingProviderProps): react_jsx_runtime.JSX.Element;
387
+ declare function IssueReportingProvider({ client, isEligible, reporterRoleHint, principalId, getPageUrl, defaultScope, allowTenantScope, defaultCreateMode, inputModes, defaultInputMode, voice, copy, children, }: IssueReportingProviderProps): react_jsx_runtime.JSX.Element;
351
388
 
352
389
  interface ReportModeContextValue {
353
390
  isReportMode: boolean;
354
391
  selectPanel: (target: ReportableInput) => void;
355
392
  cancelReportMode: () => void;
393
+ hasRegisteredTargets: boolean;
394
+ registerTarget: (id: symbol, target: ReportableInput, getElement: () => Element | null) => void;
395
+ unregisterTarget: (id: symbol) => void;
356
396
  }
357
397
  declare const ReportModeContext: React.Context<ReportModeContextValue | null>;
358
398
  declare function useReportMode(): ReportModeContextValue | null;
359
399
 
360
- export { FloatingIssueReportButton, type FloatingIssueReportButtonProps, type IssueHistoryFilter, type IssueReportingClient, type IssueReportingCopy, IssueReportingProvider, type IssueReportingProviderProps, ReportModeContext, type ReportModeContextValue, type ReportableInput, ReportableSection, type ReportableTargetDescriptor, defaultIssueReportingCopy, filterIssueReports, getEntryPointClassName, getEntryPointState, getIssueNoteLengthMessage, getIssueStatusBadgeLabel, getIssueStatusClassName, isClosedIssueStatus, isOpenIssueStatus, issueReportingKeys, useIssueReporting, useIssueReportingHistory, useIssueReportingMutations, useIssueReportingStatus, useReportMode };
400
+ export { FloatingIssueReportButton, type FloatingIssueReportButtonProps, type IssueHistoryFilter, type IssueReportingClient, type IssueReportingCopy, type IssueReportingCreateMode, IssueReportingPageConfig, type IssueReportingPageConfigProps, IssueReportingProvider, type IssueReportingProviderProps, ReportModeContext, type ReportModeContextValue, type ReportableInput, ReportableSection, type ReportableTargetDescriptor, defaultIssueReportingCopy, filterIssueReports, getEntryPointClassName, getEntryPointState, getIssueNoteLengthMessage, getIssueStatusBadgeLabel, getIssueStatusClassName, isClosedIssueStatus, isOpenIssueStatus, issueReportingKeys, useIssueReporting, useIssueReportingHistory, useIssueReportingMutations, useIssueReportingStatus, useReportMode };