@david-xpn/llm-ui-feedback 0.1.3 → 0.1.5
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.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +95 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -59,8 +59,8 @@ interface CapturedContext {
|
|
|
59
59
|
interface FeedbackWidgetProps {
|
|
60
60
|
/** Tenant identifier — required. */
|
|
61
61
|
clientId: string;
|
|
62
|
-
/** Backend API URL
|
|
63
|
-
apiUrl
|
|
62
|
+
/** Backend API URL — required. */
|
|
63
|
+
apiUrl: string;
|
|
64
64
|
/** Corner position for the floating button. Default: 'bottom-right' */
|
|
65
65
|
position?: WidgetPosition;
|
|
66
66
|
/** Hex color for the FAB accent. Default: '#3b82f6' */
|
package/dist/index.d.ts
CHANGED
|
@@ -59,8 +59,8 @@ interface CapturedContext {
|
|
|
59
59
|
interface FeedbackWidgetProps {
|
|
60
60
|
/** Tenant identifier — required. */
|
|
61
61
|
clientId: string;
|
|
62
|
-
/** Backend API URL
|
|
63
|
-
apiUrl
|
|
62
|
+
/** Backend API URL — required. */
|
|
63
|
+
apiUrl: string;
|
|
64
64
|
/** Corner position for the floating button. Default: 'bottom-right' */
|
|
65
65
|
position?: WidgetPosition;
|
|
66
66
|
/** Hex color for the FAB accent. Default: '#3b82f6' */
|
package/dist/index.js
CHANGED
|
@@ -826,13 +826,23 @@ function DraftModal({ pendingContext, addingDraft, onAdd, onCancel }) {
|
|
|
826
826
|
// src/components/SubmitModal.tsx
|
|
827
827
|
var import_react5 = require("react");
|
|
828
828
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
829
|
-
function SubmitModal({ count, onSubmit, onCancel, submitting }) {
|
|
829
|
+
function SubmitModal({ count, onSubmit, onCancel, onDone, submitting, submittedUrl }) {
|
|
830
830
|
const [title, setTitle] = (0, import_react5.useState)("");
|
|
831
|
+
const [copied, setCopied] = (0, import_react5.useState)(false);
|
|
831
832
|
const handleSubmit = () => {
|
|
832
833
|
if (title.trim() && !submitting) {
|
|
833
834
|
onSubmit(title.trim());
|
|
834
835
|
}
|
|
835
836
|
};
|
|
837
|
+
const handleCopy = async () => {
|
|
838
|
+
if (!submittedUrl) return;
|
|
839
|
+
try {
|
|
840
|
+
await navigator.clipboard.writeText(submittedUrl);
|
|
841
|
+
setCopied(true);
|
|
842
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
843
|
+
} catch {
|
|
844
|
+
}
|
|
845
|
+
};
|
|
836
846
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
837
847
|
"div",
|
|
838
848
|
{
|
|
@@ -847,9 +857,12 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
|
|
|
847
857
|
fontFamily: "system-ui, sans-serif"
|
|
848
858
|
},
|
|
849
859
|
onClick: (e) => {
|
|
850
|
-
if (e.target === e.currentTarget
|
|
860
|
+
if (e.target === e.currentTarget) {
|
|
861
|
+
if (submittedUrl) onDone();
|
|
862
|
+
else if (!submitting) onCancel();
|
|
863
|
+
}
|
|
851
864
|
},
|
|
852
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
865
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
853
866
|
"div",
|
|
854
867
|
{
|
|
855
868
|
style: {
|
|
@@ -860,7 +873,64 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
|
|
|
860
873
|
maxWidth: "90vw",
|
|
861
874
|
boxShadow: "0 8px 32px rgba(0,0,0,0.2)"
|
|
862
875
|
},
|
|
863
|
-
children: [
|
|
876
|
+
children: submittedUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: { margin: "0 0 16px", fontSize: 16 }, children: "Feedback Submitted" }),
|
|
878
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#6b7280" }, children: "Share this link to view the feedback:" }),
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
|
|
880
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
881
|
+
"input",
|
|
882
|
+
{
|
|
883
|
+
type: "text",
|
|
884
|
+
value: submittedUrl,
|
|
885
|
+
readOnly: true,
|
|
886
|
+
onFocus: (e) => e.target.select(),
|
|
887
|
+
style: {
|
|
888
|
+
flex: 1,
|
|
889
|
+
padding: 10,
|
|
890
|
+
borderRadius: 8,
|
|
891
|
+
border: "1px solid #d1d5db",
|
|
892
|
+
fontSize: 13,
|
|
893
|
+
boxSizing: "border-box",
|
|
894
|
+
color: "#374151",
|
|
895
|
+
background: "#f9fafb"
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
),
|
|
899
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
900
|
+
"button",
|
|
901
|
+
{
|
|
902
|
+
onClick: handleCopy,
|
|
903
|
+
style: {
|
|
904
|
+
padding: "8px 14px",
|
|
905
|
+
borderRadius: 8,
|
|
906
|
+
border: "1px solid #d1d5db",
|
|
907
|
+
background: copied ? "#dcfce7" : "#f3f4f6",
|
|
908
|
+
color: copied ? "#166534" : "#374151",
|
|
909
|
+
fontSize: 13,
|
|
910
|
+
cursor: "pointer",
|
|
911
|
+
whiteSpace: "nowrap"
|
|
912
|
+
},
|
|
913
|
+
children: copied ? "Copied!" : "Copy"
|
|
914
|
+
}
|
|
915
|
+
)
|
|
916
|
+
] }),
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", justifyContent: "flex-end", marginTop: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
918
|
+
"button",
|
|
919
|
+
{
|
|
920
|
+
onClick: onDone,
|
|
921
|
+
style: {
|
|
922
|
+
padding: "8px 16px",
|
|
923
|
+
borderRadius: 6,
|
|
924
|
+
border: "none",
|
|
925
|
+
background: "#3b82f6",
|
|
926
|
+
color: "#fff",
|
|
927
|
+
fontSize: 13,
|
|
928
|
+
cursor: "pointer"
|
|
929
|
+
},
|
|
930
|
+
children: "Done"
|
|
931
|
+
}
|
|
932
|
+
) })
|
|
933
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
864
934
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: { margin: "0 0 16px", fontSize: 16 }, children: "Submit Feedback" }),
|
|
865
935
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: { margin: "0 0 12px", fontSize: 14, color: "#6b7280" }, children: [
|
|
866
936
|
count,
|
|
@@ -925,7 +995,7 @@ function SubmitModal({ count, onSubmit, onCancel, submitting }) {
|
|
|
925
995
|
}
|
|
926
996
|
)
|
|
927
997
|
] })
|
|
928
|
-
]
|
|
998
|
+
] })
|
|
929
999
|
}
|
|
930
1000
|
)
|
|
931
1001
|
}
|
|
@@ -1214,9 +1284,6 @@ function createApiClient(apiUrl, clientId) {
|
|
|
1214
1284
|
};
|
|
1215
1285
|
}
|
|
1216
1286
|
|
|
1217
|
-
// src/config.ts
|
|
1218
|
-
var DEFAULT_API_URL = "https://your-lambda-function-url.lambda-url.us-east-1.on.aws";
|
|
1219
|
-
|
|
1220
1287
|
// src/components/FeedbackWidget.tsx
|
|
1221
1288
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1222
1289
|
var CONTAINER_ID = "llm-ui-feedback-root";
|
|
@@ -1237,7 +1304,8 @@ var initialState = {
|
|
|
1237
1304
|
selectedDraftIds: /* @__PURE__ */ new Set(),
|
|
1238
1305
|
submitModalOpen: false,
|
|
1239
1306
|
addingDraft: false,
|
|
1240
|
-
submitting: false
|
|
1307
|
+
submitting: false,
|
|
1308
|
+
submittedShareUrl: null
|
|
1241
1309
|
};
|
|
1242
1310
|
function widgetReducer(state, action) {
|
|
1243
1311
|
switch (action.type) {
|
|
@@ -1282,12 +1350,15 @@ function widgetReducer(state, action) {
|
|
|
1282
1350
|
return { ...state, submitModalOpen: false };
|
|
1283
1351
|
case "SET_SUBMITTING":
|
|
1284
1352
|
return { ...state, submitting: action.submitting };
|
|
1353
|
+
case "SUBMIT_SUCCESS":
|
|
1354
|
+
return { ...state, submitting: false, submittedShareUrl: action.shareUrl };
|
|
1285
1355
|
case "SUBMIT_COMPLETE": {
|
|
1286
1356
|
const submitted = new Set(action.submittedIds);
|
|
1287
1357
|
return {
|
|
1288
1358
|
...state,
|
|
1289
1359
|
submitting: false,
|
|
1290
1360
|
submitModalOpen: false,
|
|
1361
|
+
submittedShareUrl: null,
|
|
1291
1362
|
drafts: state.drafts.filter((d) => !submitted.has(d.id)),
|
|
1292
1363
|
selectedDraftIds: /* @__PURE__ */ new Set()
|
|
1293
1364
|
};
|
|
@@ -1316,7 +1387,7 @@ function isEditableTarget(el) {
|
|
|
1316
1387
|
}
|
|
1317
1388
|
function FeedbackWidget({
|
|
1318
1389
|
clientId,
|
|
1319
|
-
apiUrl
|
|
1390
|
+
apiUrl,
|
|
1320
1391
|
position = "bottom-right",
|
|
1321
1392
|
buttonColor = "#3b82f6",
|
|
1322
1393
|
hotkey
|
|
@@ -1465,16 +1536,24 @@ function FeedbackWidget({
|
|
|
1465
1536
|
});
|
|
1466
1537
|
}
|
|
1467
1538
|
}, [api]);
|
|
1539
|
+
const submittedDraftIdsRef = (0, import_react7.useRef)([]);
|
|
1468
1540
|
const handleSubmit = (0, import_react7.useCallback)(async (title) => {
|
|
1469
1541
|
dispatch({ type: "SET_SUBMITTING", submitting: true });
|
|
1470
1542
|
const draftIds = Array.from(state.selectedDraftIds);
|
|
1543
|
+
submittedDraftIdsRef.current = draftIds;
|
|
1471
1544
|
try {
|
|
1472
|
-
await api.submitSession({ title, draftIds });
|
|
1473
|
-
|
|
1545
|
+
const result = await api.submitSession({ title, draftIds });
|
|
1546
|
+
const group = result.feedbackGroup;
|
|
1547
|
+
const shareUrl = group.shareToken ? `${apiUrl}/feedback-groups/${group.id}/markdown?token=${group.shareToken}` : "";
|
|
1548
|
+
dispatch({ type: "SUBMIT_SUCCESS", shareUrl });
|
|
1474
1549
|
} catch {
|
|
1475
1550
|
dispatch({ type: "SET_SUBMITTING", submitting: false });
|
|
1476
1551
|
}
|
|
1477
|
-
}, [state.selectedDraftIds, api]);
|
|
1552
|
+
}, [state.selectedDraftIds, api, apiUrl]);
|
|
1553
|
+
const handleSubmitDone = (0, import_react7.useCallback)(() => {
|
|
1554
|
+
dispatch({ type: "SUBMIT_COMPLETE", submittedIds: submittedDraftIdsRef.current });
|
|
1555
|
+
submittedDraftIdsRef.current = [];
|
|
1556
|
+
}, []);
|
|
1478
1557
|
if (session.status === "loading") return null;
|
|
1479
1558
|
return (0, import_react_dom.createPortal)(
|
|
1480
1559
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
@@ -1521,7 +1600,9 @@ function FeedbackWidget({
|
|
|
1521
1600
|
count: state.selectedDraftIds.size,
|
|
1522
1601
|
onSubmit: handleSubmit,
|
|
1523
1602
|
onCancel: () => dispatch({ type: "CLOSE_SUBMIT_MODAL" }),
|
|
1524
|
-
|
|
1603
|
+
onDone: handleSubmitDone,
|
|
1604
|
+
submitting: state.submitting,
|
|
1605
|
+
submittedUrl: state.submittedShareUrl
|
|
1525
1606
|
}
|
|
1526
1607
|
)
|
|
1527
1608
|
] }),
|