@uxbertlabs/reportly 1.0.26 → 1.0.28
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/components/IssueModal.d.ts.map +1 -1
- package/dist/components/ReportlyProvider.d.ts +6 -6
- package/dist/components/ReportlyProvider.d.ts.map +1 -1
- package/dist/index.cjs.js +113 -62
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +113 -62
- package/dist/index.esm.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -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,
|
|
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,4BA8W7D;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React, { ReactNode } from
|
|
2
|
-
import type { ReportlyConfig, IssueData, CompleteIssue, AnnotationTool } from
|
|
3
|
-
import type { N8nResponse } from
|
|
4
|
-
import AnnotationManager from
|
|
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:
|
|
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?:
|
|
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,
|
|
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"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -9632,13 +9632,13 @@ const initialState = {
|
|
|
9632
9632
|
isAnnotating: false,
|
|
9633
9633
|
isCapturing: false,
|
|
9634
9634
|
screenshot: null,
|
|
9635
|
-
captureMode:
|
|
9636
|
-
currentTool:
|
|
9637
|
-
currentColor:
|
|
9635
|
+
captureMode: "viewport",
|
|
9636
|
+
currentTool: "pen",
|
|
9637
|
+
currentColor: "#ff0000",
|
|
9638
9638
|
config: {
|
|
9639
9639
|
ui: {
|
|
9640
|
-
position:
|
|
9641
|
-
theme:
|
|
9640
|
+
position: "bottom-right",
|
|
9641
|
+
theme: "light"
|
|
9642
9642
|
},
|
|
9643
9643
|
features: {
|
|
9644
9644
|
annotation: true,
|
|
@@ -9648,67 +9648,67 @@ const initialState = {
|
|
|
9648
9648
|
};
|
|
9649
9649
|
function reportlyReducer(state, action) {
|
|
9650
9650
|
switch (action.type) {
|
|
9651
|
-
case
|
|
9651
|
+
case "OPEN_MODAL":
|
|
9652
9652
|
return {
|
|
9653
9653
|
...state,
|
|
9654
9654
|
isOpen: true
|
|
9655
9655
|
};
|
|
9656
|
-
case
|
|
9656
|
+
case "CLOSE_MODAL":
|
|
9657
9657
|
return {
|
|
9658
9658
|
...state,
|
|
9659
9659
|
isOpen: false,
|
|
9660
9660
|
isAnnotating: false
|
|
9661
9661
|
};
|
|
9662
|
-
case
|
|
9662
|
+
case "START_ANNOTATION":
|
|
9663
9663
|
return {
|
|
9664
9664
|
...state,
|
|
9665
9665
|
isAnnotating: true,
|
|
9666
9666
|
isOpen: false
|
|
9667
9667
|
};
|
|
9668
|
-
case
|
|
9668
|
+
case "END_ANNOTATION":
|
|
9669
9669
|
return {
|
|
9670
9670
|
...state,
|
|
9671
9671
|
isAnnotating: false,
|
|
9672
9672
|
isOpen: true
|
|
9673
9673
|
};
|
|
9674
|
-
case
|
|
9674
|
+
case "START_CAPTURE":
|
|
9675
9675
|
return {
|
|
9676
9676
|
...state,
|
|
9677
9677
|
isCapturing: true
|
|
9678
9678
|
};
|
|
9679
|
-
case
|
|
9679
|
+
case "END_CAPTURE":
|
|
9680
9680
|
return {
|
|
9681
9681
|
...state,
|
|
9682
9682
|
isCapturing: false
|
|
9683
9683
|
};
|
|
9684
|
-
case
|
|
9684
|
+
case "SET_SCREENSHOT":
|
|
9685
9685
|
return {
|
|
9686
9686
|
...state,
|
|
9687
9687
|
screenshot: action.payload
|
|
9688
9688
|
};
|
|
9689
|
-
case
|
|
9689
|
+
case "SET_CAPTURE_MODE":
|
|
9690
9690
|
return {
|
|
9691
9691
|
...state,
|
|
9692
9692
|
captureMode: action.payload
|
|
9693
9693
|
};
|
|
9694
|
-
case
|
|
9694
|
+
case "SET_TOOL":
|
|
9695
9695
|
return {
|
|
9696
9696
|
...state,
|
|
9697
9697
|
currentTool: action.payload
|
|
9698
9698
|
};
|
|
9699
|
-
case
|
|
9699
|
+
case "SET_COLOR":
|
|
9700
9700
|
return {
|
|
9701
9701
|
...state,
|
|
9702
9702
|
currentColor: action.payload
|
|
9703
9703
|
};
|
|
9704
|
-
case
|
|
9704
|
+
case "RESET":
|
|
9705
9705
|
return {
|
|
9706
9706
|
...state,
|
|
9707
9707
|
isOpen: false,
|
|
9708
9708
|
isAnnotating: false,
|
|
9709
9709
|
screenshot: null
|
|
9710
9710
|
};
|
|
9711
|
-
case
|
|
9711
|
+
case "UPDATE_CONFIG":
|
|
9712
9712
|
return {
|
|
9713
9713
|
...state,
|
|
9714
9714
|
config: {
|
|
@@ -9740,58 +9740,58 @@ function ReportlyProvider({
|
|
|
9740
9740
|
const screenshot = React.useMemo(() => new Screenshot(), []);
|
|
9741
9741
|
const openModal = React.useCallback(() => {
|
|
9742
9742
|
dispatch({
|
|
9743
|
-
type:
|
|
9743
|
+
type: "OPEN_MODAL"
|
|
9744
9744
|
});
|
|
9745
9745
|
}, []);
|
|
9746
9746
|
const closeModal = React.useCallback(() => {
|
|
9747
9747
|
dispatch({
|
|
9748
|
-
type:
|
|
9748
|
+
type: "CLOSE_MODAL"
|
|
9749
9749
|
});
|
|
9750
9750
|
}, []);
|
|
9751
9751
|
const startAnnotation = React.useCallback(() => {
|
|
9752
9752
|
dispatch({
|
|
9753
|
-
type:
|
|
9753
|
+
type: "START_ANNOTATION"
|
|
9754
9754
|
});
|
|
9755
9755
|
}, []);
|
|
9756
9756
|
const endAnnotation = React.useCallback(() => {
|
|
9757
9757
|
dispatch({
|
|
9758
|
-
type:
|
|
9758
|
+
type: "END_ANNOTATION"
|
|
9759
9759
|
});
|
|
9760
9760
|
}, []);
|
|
9761
|
-
const captureScreenshot = React.useCallback(async (mode =
|
|
9761
|
+
const captureScreenshot = React.useCallback(async (mode = "viewport") => {
|
|
9762
9762
|
try {
|
|
9763
9763
|
dispatch({
|
|
9764
|
-
type:
|
|
9764
|
+
type: "START_CAPTURE"
|
|
9765
9765
|
});
|
|
9766
9766
|
dispatch({
|
|
9767
|
-
type:
|
|
9767
|
+
type: "SET_CAPTURE_MODE",
|
|
9768
9768
|
payload: mode
|
|
9769
9769
|
});
|
|
9770
9770
|
// Close modal before capturing
|
|
9771
9771
|
dispatch({
|
|
9772
|
-
type:
|
|
9772
|
+
type: "CLOSE_MODAL"
|
|
9773
9773
|
});
|
|
9774
9774
|
// Wait a bit for the modal to close (for animation)
|
|
9775
9775
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
9776
9776
|
const screenshotData = await screenshot.capture(mode);
|
|
9777
9777
|
dispatch({
|
|
9778
|
-
type:
|
|
9778
|
+
type: "SET_SCREENSHOT",
|
|
9779
9779
|
payload: screenshotData
|
|
9780
9780
|
});
|
|
9781
9781
|
// Reopen modal after capture
|
|
9782
9782
|
dispatch({
|
|
9783
|
-
type:
|
|
9783
|
+
type: "OPEN_MODAL"
|
|
9784
9784
|
});
|
|
9785
9785
|
dispatch({
|
|
9786
|
-
type:
|
|
9786
|
+
type: "END_CAPTURE"
|
|
9787
9787
|
});
|
|
9788
9788
|
} catch (error) {
|
|
9789
|
-
console.error(
|
|
9789
|
+
console.error("Failed to capture screenshot:", error);
|
|
9790
9790
|
dispatch({
|
|
9791
|
-
type:
|
|
9791
|
+
type: "OPEN_MODAL"
|
|
9792
9792
|
});
|
|
9793
9793
|
dispatch({
|
|
9794
|
-
type:
|
|
9794
|
+
type: "END_CAPTURE"
|
|
9795
9795
|
});
|
|
9796
9796
|
throw error;
|
|
9797
9797
|
}
|
|
@@ -9803,13 +9803,13 @@ function ReportlyProvider({
|
|
|
9803
9803
|
}
|
|
9804
9804
|
await captureScreenshot(state.captureMode);
|
|
9805
9805
|
} catch (error) {
|
|
9806
|
-
console.error(
|
|
9806
|
+
console.error("Failed to retake screenshot:", error);
|
|
9807
9807
|
throw error;
|
|
9808
9808
|
}
|
|
9809
9809
|
}, [annotationManager, captureScreenshot, state.captureMode]);
|
|
9810
9810
|
const setTool = React.useCallback(tool => {
|
|
9811
9811
|
dispatch({
|
|
9812
|
-
type:
|
|
9812
|
+
type: "SET_TOOL",
|
|
9813
9813
|
payload: tool
|
|
9814
9814
|
});
|
|
9815
9815
|
if (annotationManager) {
|
|
@@ -9818,7 +9818,7 @@ function ReportlyProvider({
|
|
|
9818
9818
|
}, [annotationManager]);
|
|
9819
9819
|
const setColor = React.useCallback(color => {
|
|
9820
9820
|
dispatch({
|
|
9821
|
-
type:
|
|
9821
|
+
type: "SET_COLOR",
|
|
9822
9822
|
payload: color
|
|
9823
9823
|
});
|
|
9824
9824
|
if (annotationManager) {
|
|
@@ -9829,19 +9829,19 @@ function ReportlyProvider({
|
|
|
9829
9829
|
try {
|
|
9830
9830
|
const completeIssue = {
|
|
9831
9831
|
...issueData,
|
|
9832
|
-
screenshot: state.screenshot ||
|
|
9832
|
+
screenshot: state.screenshot || "",
|
|
9833
9833
|
deviceInfo: deviceInfo.get(),
|
|
9834
9834
|
createdAt: new Date().toISOString()
|
|
9835
9835
|
};
|
|
9836
9836
|
exportService.exportToJSON(completeIssue);
|
|
9837
9837
|
dispatch({
|
|
9838
|
-
type:
|
|
9838
|
+
type: "RESET"
|
|
9839
9839
|
});
|
|
9840
9840
|
if (annotationManager) {
|
|
9841
9841
|
annotationManager.clear();
|
|
9842
9842
|
}
|
|
9843
9843
|
} catch (error) {
|
|
9844
|
-
console.error(
|
|
9844
|
+
console.error("Failed to submit issue:", error);
|
|
9845
9845
|
throw error;
|
|
9846
9846
|
}
|
|
9847
9847
|
}, [state.screenshot, deviceInfo, exportService, annotationManager]);
|
|
@@ -9849,14 +9849,14 @@ function ReportlyProvider({
|
|
|
9849
9849
|
try {
|
|
9850
9850
|
const completeIssue = {
|
|
9851
9851
|
...issueData,
|
|
9852
|
-
screenshot: state.screenshot ||
|
|
9852
|
+
screenshot: state.screenshot || "",
|
|
9853
9853
|
deviceInfo: deviceInfo.get(),
|
|
9854
9854
|
createdAt: new Date().toISOString()
|
|
9855
9855
|
};
|
|
9856
9856
|
const response = await exportService.sendToN8n(completeIssue);
|
|
9857
9857
|
if (response?.success) {
|
|
9858
9858
|
dispatch({
|
|
9859
|
-
type:
|
|
9859
|
+
type: "RESET"
|
|
9860
9860
|
});
|
|
9861
9861
|
if (annotationManager) {
|
|
9862
9862
|
annotationManager.clear();
|
|
@@ -9864,7 +9864,7 @@ function ReportlyProvider({
|
|
|
9864
9864
|
}
|
|
9865
9865
|
return response;
|
|
9866
9866
|
} catch (error) {
|
|
9867
|
-
console.error(
|
|
9867
|
+
console.error("Failed to create jira ticket:", error);
|
|
9868
9868
|
throw error;
|
|
9869
9869
|
}
|
|
9870
9870
|
}, [state.screenshot, deviceInfo, exportService, annotationManager]);
|
|
@@ -9873,19 +9873,19 @@ function ReportlyProvider({
|
|
|
9873
9873
|
}, [exportService]);
|
|
9874
9874
|
const updateConfig = React.useCallback(newConfig => {
|
|
9875
9875
|
dispatch({
|
|
9876
|
-
type:
|
|
9876
|
+
type: "UPDATE_CONFIG",
|
|
9877
9877
|
payload: newConfig
|
|
9878
9878
|
});
|
|
9879
9879
|
}, []);
|
|
9880
9880
|
const updateScreenshot = React.useCallback(screenshot => {
|
|
9881
9881
|
dispatch({
|
|
9882
|
-
type:
|
|
9882
|
+
type: "SET_SCREENSHOT",
|
|
9883
9883
|
payload: screenshot
|
|
9884
9884
|
});
|
|
9885
9885
|
}, []);
|
|
9886
9886
|
const reset = React.useCallback(() => {
|
|
9887
9887
|
dispatch({
|
|
9888
|
-
type:
|
|
9888
|
+
type: "RESET"
|
|
9889
9889
|
});
|
|
9890
9890
|
if (annotationManager) {
|
|
9891
9891
|
annotationManager.clear();
|
|
@@ -9917,7 +9917,7 @@ function ReportlyProvider({
|
|
|
9917
9917
|
function useReportly() {
|
|
9918
9918
|
const context = React.useContext(ReportlyContext);
|
|
9919
9919
|
if (!context) {
|
|
9920
|
-
throw new Error(
|
|
9920
|
+
throw new Error("useReportly must be used within a ReportlyProvider");
|
|
9921
9921
|
}
|
|
9922
9922
|
return context;
|
|
9923
9923
|
}
|
|
@@ -10352,12 +10352,20 @@ function IssueModal({
|
|
|
10352
10352
|
const [captureMode, setCaptureMode] = React.useState("viewport");
|
|
10353
10353
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
10354
10354
|
const [isSubmittingN8n, setIsSubmittingN8n] = React.useState(false);
|
|
10355
|
+
const [errors, setErrors] = React.useState({});
|
|
10355
10356
|
const handleInputChange = React.useCallback((field, value) => {
|
|
10356
10357
|
setFormData(prev => ({
|
|
10357
10358
|
...prev,
|
|
10358
10359
|
[field]: value
|
|
10359
10360
|
}));
|
|
10360
|
-
|
|
10361
|
+
// Clear error for the field when user starts typing
|
|
10362
|
+
if (field === "title" && errors.title) {
|
|
10363
|
+
setErrors(prev => ({
|
|
10364
|
+
...prev,
|
|
10365
|
+
title: undefined
|
|
10366
|
+
}));
|
|
10367
|
+
}
|
|
10368
|
+
}, [errors.title]);
|
|
10361
10369
|
const handleClose = React.useCallback(() => {
|
|
10362
10370
|
const hasData = state.screenshot !== null || formData.title.trim() !== "" || formData.description.trim() !== "";
|
|
10363
10371
|
if (hasData) {
|
|
@@ -10378,28 +10386,40 @@ function IssueModal({
|
|
|
10378
10386
|
}, [state.screenshot, formData.title, formData.description, reset, closeModal]);
|
|
10379
10387
|
const handleCapture = React.useCallback(async () => {
|
|
10380
10388
|
try {
|
|
10389
|
+
setErrors({});
|
|
10381
10390
|
await captureScreenshot(captureMode);
|
|
10382
10391
|
} catch (error) {
|
|
10383
10392
|
console.error("Failed to capture screenshot:", error);
|
|
10384
|
-
|
|
10393
|
+
setErrors({
|
|
10394
|
+
general: "Failed to capture screenshot. Please try again."
|
|
10395
|
+
});
|
|
10385
10396
|
}
|
|
10386
10397
|
}, [captureScreenshot, captureMode]);
|
|
10387
10398
|
const handleRetake = React.useCallback(async () => {
|
|
10388
10399
|
try {
|
|
10400
|
+
setErrors({});
|
|
10389
10401
|
await retakeScreenshot();
|
|
10390
10402
|
} catch (error) {
|
|
10391
10403
|
console.error("Failed to retake screenshot:", error);
|
|
10392
|
-
|
|
10404
|
+
setErrors({
|
|
10405
|
+
general: "Failed to retake screenshot. Please try again."
|
|
10406
|
+
});
|
|
10393
10407
|
}
|
|
10394
10408
|
}, [retakeScreenshot]);
|
|
10395
10409
|
const handleSubmit = React.useCallback(async e => {
|
|
10396
10410
|
e.preventDefault();
|
|
10411
|
+
// Clear previous errors
|
|
10412
|
+
setErrors({});
|
|
10413
|
+
// Validation
|
|
10414
|
+
const newErrors = {};
|
|
10397
10415
|
if (!formData.title.trim()) {
|
|
10398
|
-
|
|
10399
|
-
return;
|
|
10416
|
+
newErrors.title = "Please enter an issue title";
|
|
10400
10417
|
}
|
|
10401
10418
|
if (!state.screenshot) {
|
|
10402
|
-
|
|
10419
|
+
newErrors.screenshot = "Please capture a screenshot first";
|
|
10420
|
+
}
|
|
10421
|
+
if (Object.keys(newErrors).length > 0) {
|
|
10422
|
+
setErrors(newErrors);
|
|
10403
10423
|
return;
|
|
10404
10424
|
}
|
|
10405
10425
|
try {
|
|
@@ -10413,18 +10433,26 @@ function IssueModal({
|
|
|
10413
10433
|
});
|
|
10414
10434
|
} catch (error) {
|
|
10415
10435
|
console.error("Failed to submit issue:", error);
|
|
10416
|
-
|
|
10436
|
+
setErrors({
|
|
10437
|
+
general: "Failed to submit issue. Please try again."
|
|
10438
|
+
});
|
|
10417
10439
|
} finally {
|
|
10418
10440
|
setIsSubmitting(false);
|
|
10419
10441
|
}
|
|
10420
10442
|
}, [formData, state.screenshot, submitIssue]);
|
|
10421
10443
|
const handleN8nSubmit = React.useCallback(async () => {
|
|
10444
|
+
// Clear previous errors
|
|
10445
|
+
setErrors({});
|
|
10446
|
+
// Validation
|
|
10447
|
+
const newErrors = {};
|
|
10422
10448
|
if (!formData.title.trim()) {
|
|
10423
|
-
|
|
10424
|
-
return;
|
|
10449
|
+
newErrors.title = "Please enter an issue title";
|
|
10425
10450
|
}
|
|
10426
10451
|
if (!state.screenshot) {
|
|
10427
|
-
|
|
10452
|
+
newErrors.screenshot = "Please capture a screenshot first";
|
|
10453
|
+
}
|
|
10454
|
+
if (Object.keys(newErrors).length > 0) {
|
|
10455
|
+
setErrors(newErrors);
|
|
10428
10456
|
return;
|
|
10429
10457
|
}
|
|
10430
10458
|
try {
|
|
@@ -10437,13 +10465,19 @@ function IssueModal({
|
|
|
10437
10465
|
priority: "Medium",
|
|
10438
10466
|
deviceType: "desktop"
|
|
10439
10467
|
});
|
|
10440
|
-
|
|
10468
|
+
setErrors({
|
|
10469
|
+
general: "Issue sent to n8n successfully!"
|
|
10470
|
+
});
|
|
10441
10471
|
} else {
|
|
10442
|
-
|
|
10472
|
+
setErrors({
|
|
10473
|
+
general: `Failed to send to n8n: ${response.message}`
|
|
10474
|
+
});
|
|
10443
10475
|
}
|
|
10444
10476
|
} catch (error) {
|
|
10445
10477
|
console.error("Failed to send to n8n:", error);
|
|
10446
|
-
|
|
10478
|
+
setErrors({
|
|
10479
|
+
general: "Failed to send to n8n. Please try again."
|
|
10480
|
+
});
|
|
10447
10481
|
} finally {
|
|
10448
10482
|
setIsSubmittingN8n(false);
|
|
10449
10483
|
}
|
|
@@ -10495,7 +10529,12 @@ function IssueModal({
|
|
|
10495
10529
|
className: "uxbert-capture-title"
|
|
10496
10530
|
}, "Capture Screenshot"), /*#__PURE__*/React.createElement("p", {
|
|
10497
10531
|
className: "uxbert-capture-description"
|
|
10498
|
-
}, "Choose what to capture before reporting your issue"), /*#__PURE__*/React.createElement("div", {
|
|
10532
|
+
}, "Choose what to capture before reporting your issue"), errors.general && (/*#__PURE__*/React.createElement("div", {
|
|
10533
|
+
className: "uxbert-error-message",
|
|
10534
|
+
style: {
|
|
10535
|
+
marginBottom: "1rem"
|
|
10536
|
+
}
|
|
10537
|
+
}, errors.general)), /*#__PURE__*/React.createElement("div", {
|
|
10499
10538
|
className: "uxbert-capture-modes"
|
|
10500
10539
|
}, /*#__PURE__*/React.createElement("label", {
|
|
10501
10540
|
className: cn("uxbert-capture-mode-option", captureMode === "viewport" && "active")
|
|
@@ -10548,7 +10587,17 @@ function IssueModal({
|
|
|
10548
10587
|
src: state.screenshot,
|
|
10549
10588
|
alt: "Screenshot preview",
|
|
10550
10589
|
className: "uxbert-screenshot-image"
|
|
10551
|
-
})), /*#__PURE__*/React.createElement("div", {
|
|
10590
|
+
})), errors.screenshot && (/*#__PURE__*/React.createElement("div", {
|
|
10591
|
+
className: "uxbert-error-message",
|
|
10592
|
+
style: {
|
|
10593
|
+
marginTop: "0.5rem"
|
|
10594
|
+
}
|
|
10595
|
+
}, errors.screenshot)), errors.general && (/*#__PURE__*/React.createElement("div", {
|
|
10596
|
+
className: "uxbert-error-message",
|
|
10597
|
+
style: {
|
|
10598
|
+
marginTop: "0.5rem"
|
|
10599
|
+
}
|
|
10600
|
+
}, errors.general)), /*#__PURE__*/React.createElement("div", {
|
|
10552
10601
|
className: "uxbert-screenshot-actions"
|
|
10553
10602
|
}, /*#__PURE__*/React.createElement("button", {
|
|
10554
10603
|
onClick: handleRetake,
|
|
@@ -10583,8 +10632,10 @@ function IssueModal({
|
|
|
10583
10632
|
onChange: e => handleInputChange("title", e.target.value),
|
|
10584
10633
|
placeholder: "Brief description of the issue",
|
|
10585
10634
|
required: true,
|
|
10586
|
-
className: "uxbert-form-input"
|
|
10587
|
-
})
|
|
10635
|
+
className: cn("uxbert-form-input", errors.title && "uxbert-form-input-error")
|
|
10636
|
+
}), errors.title && /*#__PURE__*/React.createElement("div", {
|
|
10637
|
+
className: "uxbert-error-message"
|
|
10638
|
+
}, errors.title)), /*#__PURE__*/React.createElement("div", {
|
|
10588
10639
|
className: "uxbert-form-group"
|
|
10589
10640
|
}, /*#__PURE__*/React.createElement("label", {
|
|
10590
10641
|
htmlFor: "issue-description",
|
|
@@ -10661,7 +10712,7 @@ function IssueModal({
|
|
|
10661
10712
|
style: {
|
|
10662
10713
|
color: "currentColor"
|
|
10663
10714
|
}
|
|
10664
|
-
}), "
|
|
10715
|
+
}), "Create Ticket")))))))))));
|
|
10665
10716
|
}
|
|
10666
10717
|
|
|
10667
10718
|
function AnnotationToolbar({
|