types.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. import type {Duration} from 'moment';
  2. // Keep this in sync with the backend blueprint
  3. // "ReplayRecord" is distinct from the common: "replay = new ReplayReader()"
  4. export type ReplayRecord = {
  5. /**
  6. * Number that represents how much user activity happened in a replay.
  7. */
  8. activity: number;
  9. browser: {
  10. name: null | string;
  11. version: null | string;
  12. };
  13. /**
  14. * The number of errors associated with the replay.
  15. */
  16. count_errors: number;
  17. /**
  18. * The number of segments that make up the replay.
  19. */
  20. count_segments: number;
  21. /**
  22. * The number of urls visited in the replay.
  23. */
  24. count_urls: number;
  25. device: {
  26. brand: null | string;
  27. family: null | string;
  28. model_id: null | string;
  29. name: null | string;
  30. };
  31. dist: null | string;
  32. /**
  33. * Difference of `finished_at` and `started_at` in seconds.
  34. */
  35. duration: Duration;
  36. environment: null | string;
  37. error_ids: string[];
  38. /**
  39. * The **latest** timestamp received as determined by the SDK.
  40. */
  41. finished_at: Date;
  42. /**
  43. * Whether the currently authenticated user has seen this replay or not.
  44. */
  45. has_viewed: boolean;
  46. /**
  47. * The ID of the Replay instance
  48. */
  49. id: string;
  50. /**
  51. * Whether the replay was deleted.
  52. * When deleted the rrweb data & attachments are removed from blob storage,
  53. * but the record of the replay is not removed.
  54. */
  55. is_archived: boolean;
  56. os: {
  57. name: null | string;
  58. version: null | string;
  59. };
  60. platform: string;
  61. project_id: string;
  62. releases: null | string[];
  63. sdk: {
  64. name: null | string;
  65. version: null | string;
  66. };
  67. /**
  68. * The **earliest** timestamp received as determined by the SDK.
  69. */
  70. started_at: Date;
  71. tags: Record<string, string[]>;
  72. trace_ids: string[];
  73. urls: string[];
  74. user: {
  75. display_name: null | string;
  76. email: null | string;
  77. id: null | string;
  78. ip: null | string;
  79. username: null | string;
  80. };
  81. /**
  82. * The number of dead clicks associated with the replay.
  83. */
  84. count_dead_clicks?: number;
  85. /**
  86. * The number of rage clicks associated with the replay.
  87. */
  88. count_rage_clicks?: number;
  89. };
  90. // The ReplayRecord fields, but with nested fields represented as `foo.bar`.
  91. export type ReplayRecordNestedFieldName =
  92. | keyof ReplayRecord
  93. | `browser.${keyof ReplayRecord['browser']}`
  94. | `device.${keyof ReplayRecord['device']}`
  95. | `os.${keyof ReplayRecord['os']}`
  96. | `user.${keyof ReplayRecord['user']}`;
  97. export type ReplayListLocationQuery = {
  98. cursor?: string;
  99. end?: string;
  100. environment?: string[];
  101. field?: string[];
  102. limit?: string;
  103. offset?: string;
  104. project?: string[];
  105. query?: string;
  106. sort?: string;
  107. start?: string;
  108. statsPeriod?: string;
  109. utc?: 'true' | 'false';
  110. };
  111. export type ReplayListQueryReferrer =
  112. | 'replayList'
  113. | 'issueReplays'
  114. | 'transactionReplays';
  115. // Sync with ReplayListRecord below
  116. export const REPLAY_LIST_FIELDS = [
  117. 'activity',
  118. 'browser.name',
  119. 'browser.version',
  120. 'count_dead_clicks',
  121. 'count_errors',
  122. 'count_rage_clicks',
  123. 'duration',
  124. 'finished_at',
  125. 'has_viewed',
  126. 'id',
  127. 'is_archived',
  128. 'os.name',
  129. 'os.version',
  130. 'project_id',
  131. 'started_at',
  132. 'user',
  133. ];
  134. // Sync with REPLAY_LIST_FIELDS above
  135. export type ReplayListRecord = Pick<
  136. ReplayRecord,
  137. | 'activity'
  138. | 'browser'
  139. | 'count_dead_clicks'
  140. | 'count_errors'
  141. | 'count_rage_clicks'
  142. | 'duration'
  143. | 'finished_at'
  144. | 'has_viewed'
  145. | 'id'
  146. | 'is_archived'
  147. | 'os'
  148. | 'project_id'
  149. | 'started_at'
  150. | 'user'
  151. >;
  152. export type ReplaySegment = {
  153. dateAdded: string;
  154. projectId: string;
  155. replayId: string;
  156. segmentId: number;
  157. };
  158. /**
  159. * This is a result of a custom discover query
  160. */
  161. export interface ReplayError {
  162. ['error.type']: string[];
  163. ['error.value']: string[]; // deprecated, use title instead. See organization_replay_events_meta.py
  164. id: string;
  165. issue: string;
  166. ['issue.id']: number;
  167. ['project.name']: string;
  168. timestamp: string;
  169. title: string;
  170. }
  171. export type DeadRageSelectorItem = {
  172. aria_label: string;
  173. dom_element: {
  174. fullSelector: string;
  175. projectId: number;
  176. selector: string;
  177. };
  178. element: string;
  179. project_id: number;
  180. count_dead_clicks?: number;
  181. count_rage_clicks?: number;
  182. };
  183. export type DeadRageSelectorListResponse = {
  184. data: {
  185. count_dead_clicks: number;
  186. count_rage_clicks: number;
  187. dom_element: string;
  188. element: ReplayClickElement;
  189. project_id: number;
  190. }[];
  191. };
  192. export type ReplayClickElement = {
  193. alt: string;
  194. aria_label: string;
  195. class: string[];
  196. component_name: string;
  197. id: string;
  198. role: string;
  199. tag: string;
  200. testid: string;
  201. title: string;
  202. };
  203. export interface DeadRageSelectorQueryParams {
  204. isWidgetData: boolean;
  205. cursor?: string | string[] | undefined | null;
  206. per_page?: number;
  207. prefix?: string;
  208. sort?:
  209. | 'count_dead_clicks'
  210. | '-count_dead_clicks'
  211. | 'count_rage_clicks'
  212. | '-count_rage_clicks';
  213. }