@uxbertlabs/reportly 1.0.27 → 1.0.29

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.
@@ -1 +1 @@
1
- {"version":3,"file":"IssueModal.d.ts","sourceRoot":"","sources":["../../src/components/IssueModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAOrD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,SAAc,EAAE,EAAE,eAAe,4BA+V7D;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"IssueModal.d.ts","sourceRoot":"","sources":["../../src/components/IssueModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAOrD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,SAAc,EAAE,EAAE,eAAe,4BAkX7D;AAED,eAAe,UAAU,CAAC"}
@@ -1,13 +1,13 @@
1
- import React, { ReactNode } from 'react';
2
- import type { ReportlyConfig, IssueData, CompleteIssue, AnnotationTool } from '../types';
3
- import type { N8nResponse } from '../features/n8n-integration';
4
- import AnnotationManager from '../features/annotation';
1
+ import React, { ReactNode } from "react";
2
+ import type { ReportlyConfig, IssueData, CompleteIssue, AnnotationTool } from "../types";
3
+ import type { N8nResponse } from "../features/n8n-integration";
4
+ import AnnotationManager from "../features/annotation";
5
5
  export interface ReportlyState {
6
6
  isOpen: boolean;
7
7
  isAnnotating: boolean;
8
8
  isCapturing: boolean;
9
9
  screenshot: string | null;
10
- captureMode: 'viewport' | 'fullpage';
10
+ captureMode: "viewport" | "fullpage";
11
11
  currentTool: string;
12
12
  currentColor: string;
13
13
  config: ReportlyConfig;
@@ -20,7 +20,7 @@ interface ReportlyContextType {
20
20
  closeModal: () => void;
21
21
  startAnnotation: () => void;
22
22
  endAnnotation: () => void;
23
- captureScreenshot: (mode?: 'viewport' | 'fullpage') => Promise<void>;
23
+ captureScreenshot: (mode?: "viewport" | "fullpage") => Promise<void>;
24
24
  retakeScreenshot: () => Promise<void>;
25
25
  setTool: (tool: AnnotationTool) => void;
26
26
  setColor: (color: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"ReportlyProvider.d.ts","sourceRoot":"","sources":["../../src/components/ReportlyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAyC,SAAS,EAAwB,MAAM,OAAO,CAAC;AACtG,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAI/D,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB;AAmED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,oBAAoB,EAAE,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC;IAClE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,iBAAiB,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACxD,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAW,EAAE,EAAE,qBAAqB,qBA0KhF;AAED,wBAAgB,WAAW,IAAI,mBAAmB,CAMjD"}
1
+ {"version":3,"file":"ReportlyProvider.d.ts","sourceRoot":"","sources":["../../src/components/ReportlyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAyC,SAAS,EAAwB,MAAM,OAAO,CAAC;AACtG,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAI/D,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,UAAU,GAAG,UAAU,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB;AAmED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,oBAAoB,EAAE,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,KAAK,IAAI,CAAC;IAClE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,iBAAiB,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACxD,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAW,EAAE,EAAE,qBAAqB,qBAwLhF;AAED,wBAAgB,WAAW,IAAI,mBAAmB,CAMjD"}
@@ -1 +1 @@
1
- {"version":3,"file":"n8n-integration.d.ts","sourceRoot":"","sources":["../../src/features/n8n-integration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,SAAS;IAI9B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIlC;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IA0F/D;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;;OAGG;YACW,eAAe;IAkC7B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAiC5C;;OAEG;IACH,SAAS,IAAI,SAAS,GAAG,IAAI;IAI7B;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAWhC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;CAKnC;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"n8n-integration.d.ts","sourceRoot":"","sources":["../../src/features/n8n-integration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,SAAS;IAI9B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIlC;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IA0F/D;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;;OAGG;YACW,eAAe;IAmC7B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAiC5C;;OAEG;IACH,SAAS,IAAI,SAAS,GAAG,IAAI;IAI7B;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAWhC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;CAKnC;AAED,eAAe,cAAc,CAAC"}
package/dist/index.cjs.js CHANGED
@@ -214,6 +214,7 @@ class N8nIntegration {
214
214
  formData.append("title", issueData.title);
215
215
  formData.append("description", issueData.description);
216
216
  formData.append("priority", issueData.priority);
217
+ formData.append("deviceType", issueData.deviceType);
217
218
  formData.append("createdAt", issueData.createdAt);
218
219
  // Convert base64 screenshot to binary Blob and add as file
219
220
  const screenshotBlob = this.base64ToBlob(issueData.screenshot);
@@ -9632,13 +9633,13 @@ const initialState = {
9632
9633
  isAnnotating: false,
9633
9634
  isCapturing: false,
9634
9635
  screenshot: null,
9635
- captureMode: 'viewport',
9636
- currentTool: 'pen',
9637
- currentColor: '#ff0000',
9636
+ captureMode: "viewport",
9637
+ currentTool: "pen",
9638
+ currentColor: "#ff0000",
9638
9639
  config: {
9639
9640
  ui: {
9640
- position: 'bottom-right',
9641
- theme: 'light'
9641
+ position: "bottom-right",
9642
+ theme: "light"
9642
9643
  },
9643
9644
  features: {
9644
9645
  annotation: true,
@@ -9648,67 +9649,67 @@ const initialState = {
9648
9649
  };
9649
9650
  function reportlyReducer(state, action) {
9650
9651
  switch (action.type) {
9651
- case 'OPEN_MODAL':
9652
+ case "OPEN_MODAL":
9652
9653
  return {
9653
9654
  ...state,
9654
9655
  isOpen: true
9655
9656
  };
9656
- case 'CLOSE_MODAL':
9657
+ case "CLOSE_MODAL":
9657
9658
  return {
9658
9659
  ...state,
9659
9660
  isOpen: false,
9660
9661
  isAnnotating: false
9661
9662
  };
9662
- case 'START_ANNOTATION':
9663
+ case "START_ANNOTATION":
9663
9664
  return {
9664
9665
  ...state,
9665
9666
  isAnnotating: true,
9666
9667
  isOpen: false
9667
9668
  };
9668
- case 'END_ANNOTATION':
9669
+ case "END_ANNOTATION":
9669
9670
  return {
9670
9671
  ...state,
9671
9672
  isAnnotating: false,
9672
9673
  isOpen: true
9673
9674
  };
9674
- case 'START_CAPTURE':
9675
+ case "START_CAPTURE":
9675
9676
  return {
9676
9677
  ...state,
9677
9678
  isCapturing: true
9678
9679
  };
9679
- case 'END_CAPTURE':
9680
+ case "END_CAPTURE":
9680
9681
  return {
9681
9682
  ...state,
9682
9683
  isCapturing: false
9683
9684
  };
9684
- case 'SET_SCREENSHOT':
9685
+ case "SET_SCREENSHOT":
9685
9686
  return {
9686
9687
  ...state,
9687
9688
  screenshot: action.payload
9688
9689
  };
9689
- case 'SET_CAPTURE_MODE':
9690
+ case "SET_CAPTURE_MODE":
9690
9691
  return {
9691
9692
  ...state,
9692
9693
  captureMode: action.payload
9693
9694
  };
9694
- case 'SET_TOOL':
9695
+ case "SET_TOOL":
9695
9696
  return {
9696
9697
  ...state,
9697
9698
  currentTool: action.payload
9698
9699
  };
9699
- case 'SET_COLOR':
9700
+ case "SET_COLOR":
9700
9701
  return {
9701
9702
  ...state,
9702
9703
  currentColor: action.payload
9703
9704
  };
9704
- case 'RESET':
9705
+ case "RESET":
9705
9706
  return {
9706
9707
  ...state,
9707
9708
  isOpen: false,
9708
9709
  isAnnotating: false,
9709
9710
  screenshot: null
9710
9711
  };
9711
- case 'UPDATE_CONFIG':
9712
+ case "UPDATE_CONFIG":
9712
9713
  return {
9713
9714
  ...state,
9714
9715
  config: {
@@ -9740,58 +9741,58 @@ function ReportlyProvider({
9740
9741
  const screenshot = React.useMemo(() => new Screenshot(), []);
9741
9742
  const openModal = React.useCallback(() => {
9742
9743
  dispatch({
9743
- type: 'OPEN_MODAL'
9744
+ type: "OPEN_MODAL"
9744
9745
  });
9745
9746
  }, []);
9746
9747
  const closeModal = React.useCallback(() => {
9747
9748
  dispatch({
9748
- type: 'CLOSE_MODAL'
9749
+ type: "CLOSE_MODAL"
9749
9750
  });
9750
9751
  }, []);
9751
9752
  const startAnnotation = React.useCallback(() => {
9752
9753
  dispatch({
9753
- type: 'START_ANNOTATION'
9754
+ type: "START_ANNOTATION"
9754
9755
  });
9755
9756
  }, []);
9756
9757
  const endAnnotation = React.useCallback(() => {
9757
9758
  dispatch({
9758
- type: 'END_ANNOTATION'
9759
+ type: "END_ANNOTATION"
9759
9760
  });
9760
9761
  }, []);
9761
- const captureScreenshot = React.useCallback(async (mode = 'viewport') => {
9762
+ const captureScreenshot = React.useCallback(async (mode = "viewport") => {
9762
9763
  try {
9763
9764
  dispatch({
9764
- type: 'START_CAPTURE'
9765
+ type: "START_CAPTURE"
9765
9766
  });
9766
9767
  dispatch({
9767
- type: 'SET_CAPTURE_MODE',
9768
+ type: "SET_CAPTURE_MODE",
9768
9769
  payload: mode
9769
9770
  });
9770
9771
  // Close modal before capturing
9771
9772
  dispatch({
9772
- type: 'CLOSE_MODAL'
9773
+ type: "CLOSE_MODAL"
9773
9774
  });
9774
9775
  // Wait a bit for the modal to close (for animation)
9775
9776
  await new Promise(resolve => setTimeout(resolve, 100));
9776
9777
  const screenshotData = await screenshot.capture(mode);
9777
9778
  dispatch({
9778
- type: 'SET_SCREENSHOT',
9779
+ type: "SET_SCREENSHOT",
9779
9780
  payload: screenshotData
9780
9781
  });
9781
9782
  // Reopen modal after capture
9782
9783
  dispatch({
9783
- type: 'OPEN_MODAL'
9784
+ type: "OPEN_MODAL"
9784
9785
  });
9785
9786
  dispatch({
9786
- type: 'END_CAPTURE'
9787
+ type: "END_CAPTURE"
9787
9788
  });
9788
9789
  } catch (error) {
9789
- console.error('Failed to capture screenshot:', error);
9790
+ console.error("Failed to capture screenshot:", error);
9790
9791
  dispatch({
9791
- type: 'OPEN_MODAL'
9792
+ type: "OPEN_MODAL"
9792
9793
  });
9793
9794
  dispatch({
9794
- type: 'END_CAPTURE'
9795
+ type: "END_CAPTURE"
9795
9796
  });
9796
9797
  throw error;
9797
9798
  }
@@ -9803,13 +9804,13 @@ function ReportlyProvider({
9803
9804
  }
9804
9805
  await captureScreenshot(state.captureMode);
9805
9806
  } catch (error) {
9806
- console.error('Failed to retake screenshot:', error);
9807
+ console.error("Failed to retake screenshot:", error);
9807
9808
  throw error;
9808
9809
  }
9809
9810
  }, [annotationManager, captureScreenshot, state.captureMode]);
9810
9811
  const setTool = React.useCallback(tool => {
9811
9812
  dispatch({
9812
- type: 'SET_TOOL',
9813
+ type: "SET_TOOL",
9813
9814
  payload: tool
9814
9815
  });
9815
9816
  if (annotationManager) {
@@ -9818,7 +9819,7 @@ function ReportlyProvider({
9818
9819
  }, [annotationManager]);
9819
9820
  const setColor = React.useCallback(color => {
9820
9821
  dispatch({
9821
- type: 'SET_COLOR',
9822
+ type: "SET_COLOR",
9822
9823
  payload: color
9823
9824
  });
9824
9825
  if (annotationManager) {
@@ -9829,19 +9830,19 @@ function ReportlyProvider({
9829
9830
  try {
9830
9831
  const completeIssue = {
9831
9832
  ...issueData,
9832
- screenshot: state.screenshot || '',
9833
+ screenshot: state.screenshot || "",
9833
9834
  deviceInfo: deviceInfo.get(),
9834
9835
  createdAt: new Date().toISOString()
9835
9836
  };
9836
9837
  exportService.exportToJSON(completeIssue);
9837
9838
  dispatch({
9838
- type: 'RESET'
9839
+ type: "RESET"
9839
9840
  });
9840
9841
  if (annotationManager) {
9841
9842
  annotationManager.clear();
9842
9843
  }
9843
9844
  } catch (error) {
9844
- console.error('Failed to submit issue:', error);
9845
+ console.error("Failed to submit issue:", error);
9845
9846
  throw error;
9846
9847
  }
9847
9848
  }, [state.screenshot, deviceInfo, exportService, annotationManager]);
@@ -9849,14 +9850,14 @@ function ReportlyProvider({
9849
9850
  try {
9850
9851
  const completeIssue = {
9851
9852
  ...issueData,
9852
- screenshot: state.screenshot || '',
9853
+ screenshot: state.screenshot || "",
9853
9854
  deviceInfo: deviceInfo.get(),
9854
9855
  createdAt: new Date().toISOString()
9855
9856
  };
9856
9857
  const response = await exportService.sendToN8n(completeIssue);
9857
9858
  if (response?.success) {
9858
9859
  dispatch({
9859
- type: 'RESET'
9860
+ type: "RESET"
9860
9861
  });
9861
9862
  if (annotationManager) {
9862
9863
  annotationManager.clear();
@@ -9864,7 +9865,7 @@ function ReportlyProvider({
9864
9865
  }
9865
9866
  return response;
9866
9867
  } catch (error) {
9867
- console.error('Failed to send to n8n:', error);
9868
+ console.error("Failed to create jira ticket:", error);
9868
9869
  throw error;
9869
9870
  }
9870
9871
  }, [state.screenshot, deviceInfo, exportService, annotationManager]);
@@ -9873,19 +9874,19 @@ function ReportlyProvider({
9873
9874
  }, [exportService]);
9874
9875
  const updateConfig = React.useCallback(newConfig => {
9875
9876
  dispatch({
9876
- type: 'UPDATE_CONFIG',
9877
+ type: "UPDATE_CONFIG",
9877
9878
  payload: newConfig
9878
9879
  });
9879
9880
  }, []);
9880
9881
  const updateScreenshot = React.useCallback(screenshot => {
9881
9882
  dispatch({
9882
- type: 'SET_SCREENSHOT',
9883
+ type: "SET_SCREENSHOT",
9883
9884
  payload: screenshot
9884
9885
  });
9885
9886
  }, []);
9886
9887
  const reset = React.useCallback(() => {
9887
9888
  dispatch({
9888
- type: 'RESET'
9889
+ type: "RESET"
9889
9890
  });
9890
9891
  if (annotationManager) {
9891
9892
  annotationManager.clear();
@@ -9917,7 +9918,7 @@ function ReportlyProvider({
9917
9918
  function useReportly() {
9918
9919
  const context = React.useContext(ReportlyContext);
9919
9920
  if (!context) {
9920
- throw new Error('useReportly must be used within a ReportlyProvider');
9921
+ throw new Error("useReportly must be used within a ReportlyProvider");
9921
9922
  }
9922
9923
  return context;
9923
9924
  }
@@ -10352,12 +10353,20 @@ function IssueModal({
10352
10353
  const [captureMode, setCaptureMode] = React.useState("viewport");
10353
10354
  const [isSubmitting, setIsSubmitting] = React.useState(false);
10354
10355
  const [isSubmittingN8n, setIsSubmittingN8n] = React.useState(false);
10356
+ const [errors, setErrors] = React.useState({});
10355
10357
  const handleInputChange = React.useCallback((field, value) => {
10356
10358
  setFormData(prev => ({
10357
10359
  ...prev,
10358
10360
  [field]: value
10359
10361
  }));
10360
- }, []);
10362
+ // Clear error for the field when user starts typing
10363
+ if (field === "title" && errors.title) {
10364
+ setErrors(prev => ({
10365
+ ...prev,
10366
+ title: undefined
10367
+ }));
10368
+ }
10369
+ }, [errors.title]);
10361
10370
  const handleClose = React.useCallback(() => {
10362
10371
  const hasData = state.screenshot !== null || formData.title.trim() !== "" || formData.description.trim() !== "";
10363
10372
  if (hasData) {
@@ -10378,28 +10387,40 @@ function IssueModal({
10378
10387
  }, [state.screenshot, formData.title, formData.description, reset, closeModal]);
10379
10388
  const handleCapture = React.useCallback(async () => {
10380
10389
  try {
10390
+ setErrors({});
10381
10391
  await captureScreenshot(captureMode);
10382
10392
  } catch (error) {
10383
10393
  console.error("Failed to capture screenshot:", error);
10384
- alert("Failed to capture screenshot. Please try again.");
10394
+ setErrors({
10395
+ general: "Failed to capture screenshot. Please try again."
10396
+ });
10385
10397
  }
10386
10398
  }, [captureScreenshot, captureMode]);
10387
10399
  const handleRetake = React.useCallback(async () => {
10388
10400
  try {
10401
+ setErrors({});
10389
10402
  await retakeScreenshot();
10390
10403
  } catch (error) {
10391
10404
  console.error("Failed to retake screenshot:", error);
10392
- alert("Failed to retake screenshot. Please try again.");
10405
+ setErrors({
10406
+ general: "Failed to retake screenshot. Please try again."
10407
+ });
10393
10408
  }
10394
10409
  }, [retakeScreenshot]);
10395
10410
  const handleSubmit = React.useCallback(async e => {
10396
10411
  e.preventDefault();
10412
+ // Clear previous errors
10413
+ setErrors({});
10414
+ // Validation
10415
+ const newErrors = {};
10397
10416
  if (!formData.title.trim()) {
10398
- alert("Please enter an issue title");
10399
- return;
10417
+ newErrors.title = "Please enter an issue title";
10400
10418
  }
10401
10419
  if (!state.screenshot) {
10402
- alert("Please capture a screenshot first");
10420
+ newErrors.screenshot = "Please capture a screenshot first";
10421
+ }
10422
+ if (Object.keys(newErrors).length > 0) {
10423
+ setErrors(newErrors);
10403
10424
  return;
10404
10425
  }
10405
10426
  try {
@@ -10413,18 +10434,26 @@ function IssueModal({
10413
10434
  });
10414
10435
  } catch (error) {
10415
10436
  console.error("Failed to submit issue:", error);
10416
- alert("Failed to submit issue. Please try again.");
10437
+ setErrors({
10438
+ general: "Failed to submit issue. Please try again."
10439
+ });
10417
10440
  } finally {
10418
10441
  setIsSubmitting(false);
10419
10442
  }
10420
10443
  }, [formData, state.screenshot, submitIssue]);
10421
10444
  const handleN8nSubmit = React.useCallback(async () => {
10445
+ // Clear previous errors
10446
+ setErrors({});
10447
+ // Validation
10448
+ const newErrors = {};
10422
10449
  if (!formData.title.trim()) {
10423
- alert("Please enter an issue title");
10424
- return;
10450
+ newErrors.title = "Please enter an issue title";
10425
10451
  }
10426
10452
  if (!state.screenshot) {
10427
- alert("Please capture a screenshot first");
10453
+ newErrors.screenshot = "Please capture a screenshot first";
10454
+ }
10455
+ if (Object.keys(newErrors).length > 0) {
10456
+ setErrors(newErrors);
10428
10457
  return;
10429
10458
  }
10430
10459
  try {
@@ -10437,13 +10466,19 @@ function IssueModal({
10437
10466
  priority: "Medium",
10438
10467
  deviceType: "desktop"
10439
10468
  });
10440
- alert("Issue sent to n8n successfully!");
10469
+ setErrors({
10470
+ general: "Issue sent to n8n successfully!"
10471
+ });
10441
10472
  } else {
10442
- alert(`Failed to send to n8n: ${response.message}`);
10473
+ setErrors({
10474
+ general: `Failed to send to n8n: ${response.message}`
10475
+ });
10443
10476
  }
10444
10477
  } catch (error) {
10445
10478
  console.error("Failed to send to n8n:", error);
10446
- alert("Failed to send to n8n. Please try again.");
10479
+ setErrors({
10480
+ general: "Failed to send to n8n. Please try again."
10481
+ });
10447
10482
  } finally {
10448
10483
  setIsSubmittingN8n(false);
10449
10484
  }
@@ -10495,7 +10530,12 @@ function IssueModal({
10495
10530
  className: "uxbert-capture-title"
10496
10531
  }, "Capture Screenshot"), /*#__PURE__*/React.createElement("p", {
10497
10532
  className: "uxbert-capture-description"
10498
- }, "Choose what to capture before reporting your issue"), /*#__PURE__*/React.createElement("div", {
10533
+ }, "Choose what to capture before reporting your issue"), errors.general && (/*#__PURE__*/React.createElement("div", {
10534
+ className: "uxbert-error-message",
10535
+ style: {
10536
+ marginBottom: "1rem"
10537
+ }
10538
+ }, errors.general)), /*#__PURE__*/React.createElement("div", {
10499
10539
  className: "uxbert-capture-modes"
10500
10540
  }, /*#__PURE__*/React.createElement("label", {
10501
10541
  className: cn("uxbert-capture-mode-option", captureMode === "viewport" && "active")
@@ -10548,7 +10588,17 @@ function IssueModal({
10548
10588
  src: state.screenshot,
10549
10589
  alt: "Screenshot preview",
10550
10590
  className: "uxbert-screenshot-image"
10551
- })), /*#__PURE__*/React.createElement("div", {
10591
+ })), errors.screenshot && (/*#__PURE__*/React.createElement("div", {
10592
+ className: "uxbert-error-message",
10593
+ style: {
10594
+ marginTop: "0.5rem"
10595
+ }
10596
+ }, errors.screenshot)), errors.general && (/*#__PURE__*/React.createElement("div", {
10597
+ className: "uxbert-error-message",
10598
+ style: {
10599
+ marginTop: "0.5rem"
10600
+ }
10601
+ }, errors.general)), /*#__PURE__*/React.createElement("div", {
10552
10602
  className: "uxbert-screenshot-actions"
10553
10603
  }, /*#__PURE__*/React.createElement("button", {
10554
10604
  onClick: handleRetake,
@@ -10583,8 +10633,10 @@ function IssueModal({
10583
10633
  onChange: e => handleInputChange("title", e.target.value),
10584
10634
  placeholder: "Brief description of the issue",
10585
10635
  required: true,
10586
- className: "uxbert-form-input"
10587
- })), /*#__PURE__*/React.createElement("div", {
10636
+ className: cn("uxbert-form-input", errors.title && "uxbert-form-input-error")
10637
+ }), errors.title && /*#__PURE__*/React.createElement("div", {
10638
+ className: "uxbert-error-message"
10639
+ }, errors.title)), /*#__PURE__*/React.createElement("div", {
10588
10640
  className: "uxbert-form-group"
10589
10641
  }, /*#__PURE__*/React.createElement("label", {
10590
10642
  htmlFor: "issue-description",
@@ -10609,14 +10661,16 @@ function IssueModal({
10609
10661
  onChange: e => handleInputChange("priority", e.target.value),
10610
10662
  className: "uxbert-form-select"
10611
10663
  }, /*#__PURE__*/React.createElement("option", {
10612
- value: "Low"
10664
+ value: "5"
10665
+ }, "Lowest"), /*#__PURE__*/React.createElement("option", {
10666
+ value: "4"
10613
10667
  }, "Low"), /*#__PURE__*/React.createElement("option", {
10614
- value: "Medium"
10668
+ value: "3"
10615
10669
  }, "Medium"), /*#__PURE__*/React.createElement("option", {
10616
- value: "High"
10670
+ value: "2"
10617
10671
  }, "High"), /*#__PURE__*/React.createElement("option", {
10618
- value: "Critical"
10619
- }, "Critical"))), /*#__PURE__*/React.createElement("div", {
10672
+ value: "1"
10673
+ }, "Highest"))), /*#__PURE__*/React.createElement("div", {
10620
10674
  className: "uxbert-form-group"
10621
10675
  }, /*#__PURE__*/React.createElement("label", {
10622
10676
  htmlFor: "device-type",
@@ -10661,7 +10715,7 @@ function IssueModal({
10661
10715
  style: {
10662
10716
  color: "currentColor"
10663
10717
  }
10664
- }), "Send to n8n")))))))))));
10718
+ }), "Create Ticket")))))))))));
10665
10719
  }
10666
10720
 
10667
10721
  function AnnotationToolbar({