@mhosaic/feedback 0.18.0 → 0.19.0

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.
@@ -169,6 +169,24 @@ function createApiClient(options) {
169
169
  }
170
170
  return response.json();
171
171
  }
172
+ async function reopenUnresolved(reportId, externalId) {
173
+ const response = await fetcher(
174
+ `${endpoint}/api/feedback/v1/reports/widget/${reportId}/`,
175
+ {
176
+ method: "PATCH",
177
+ headers: {
178
+ ...widgetHeaders(externalId),
179
+ "Content-Type": "application/json"
180
+ },
181
+ body: JSON.stringify({ status: "in_progress" })
182
+ }
183
+ );
184
+ if (!response.ok) {
185
+ const text = await response.text().catch(() => "");
186
+ throw new Error(`reopenUnresolved failed: ${response.status} ${text}`);
187
+ }
188
+ return response.json();
189
+ }
172
190
  function boardQueryString(filters) {
173
191
  if (!filters) return "";
174
192
  const params = new URLSearchParams();
@@ -209,7 +227,7 @@ function createApiClient(options) {
209
227
  }
210
228
  return response.json();
211
229
  }
212
- async function checkVisibility(externalId) {
230
+ async function checkVisibility(externalId, email) {
213
231
  const response = await fetcher(
214
232
  `${endpoint}/api/feedback/v1/widget/visibility/`,
215
233
  {
@@ -218,7 +236,10 @@ function createApiClient(options) {
218
236
  ...widgetHeaders(externalId),
219
237
  "Content-Type": "application/json"
220
238
  },
221
- body: JSON.stringify({ external_id: externalId })
239
+ body: JSON.stringify({
240
+ external_id: externalId,
241
+ ...email ? { email } : {}
242
+ })
222
243
  }
223
244
  );
224
245
  if (!response.ok) {
@@ -235,6 +256,7 @@ function createApiClient(options) {
235
256
  getReport,
236
257
  addComment,
237
258
  closeAsResolved,
259
+ reopenUnresolved,
238
260
  listBoard,
239
261
  fetchBoardKpis
240
262
  };
@@ -626,12 +648,15 @@ var DEFAULT_STRINGS = {
626
648
  "detail.compose_sending": "Sending\u2026",
627
649
  "detail.close_cta": "Mark as resolved",
628
650
  "detail.close_busy": "Marking\u2026",
651
+ "detail.reopen_cta": "Still not fixed",
652
+ "detail.reopen_busy": "Reopening\u2026",
629
653
  "detail.teammate_notice": "Viewing a teammate\u2019s report \u2014 replies are private to the submitter.",
630
654
  "detail.load_failed.title": "Report not available",
631
655
  "detail.load_failed.body": "It may have been deleted, or you no longer have access to it.",
632
656
  "detail.load_failed.cta": "Back",
633
657
  "detail.send_failed": "Couldn\u2019t send your reply. Try again.",
634
658
  "detail.close_failed": "Couldn\u2019t mark as resolved. Try again.",
659
+ "detail.reopen_failed": "Couldn\u2019t reopen the report. Try again.",
635
660
  "detail.history": "Status history",
636
661
  "detail.context.submitted_at": "Submitted",
637
662
  "detail.context.page": "Page",
@@ -765,12 +790,15 @@ var FRENCH_STRINGS = {
765
790
  "detail.compose_sending": "Envoi\u2026",
766
791
  "detail.close_cta": "Marquer comme r\xE9solu",
767
792
  "detail.close_busy": "Validation\u2026",
793
+ "detail.reopen_cta": "Toujours pas r\xE9gl\xE9",
794
+ "detail.reopen_busy": "R\xE9ouverture\u2026",
768
795
  "detail.teammate_notice": "Vous consultez le rapport d\u2019un co\xE9quipier \u2014 les r\xE9ponses sont priv\xE9es au soumetteur.",
769
796
  "detail.load_failed.title": "Rapport indisponible",
770
797
  "detail.load_failed.body": "Il a peut-\xEAtre \xE9t\xE9 supprim\xE9, ou vous n\u2019y avez plus acc\xE8s.",
771
798
  "detail.load_failed.cta": "Retour",
772
799
  "detail.send_failed": "Impossible d\u2019envoyer votre r\xE9ponse. R\xE9essayez.",
773
800
  "detail.close_failed": "Impossible de marquer comme r\xE9solu. R\xE9essayez.",
801
+ "detail.reopen_failed": "Impossible de rouvrir le rapport. R\xE9essayez.",
774
802
  "detail.history": "Historique du statut",
775
803
  "detail.context.submitted_at": "Envoy\xE9",
776
804
  "detail.context.page": "Page",
@@ -910,6 +938,7 @@ function ReportDetailView({
910
938
  const [composeBody, setComposeBody] = useState("");
911
939
  const [sending, setSending] = useState(false);
912
940
  const [closing, setClosing] = useState(false);
941
+ const [reopening, setReopening] = useState(false);
913
942
  const mountedRef = useRef(true);
914
943
  const fetchDetail = async () => {
915
944
  try {
@@ -955,7 +984,7 @@ function ReportDetailView({
955
984
  }
956
985
  };
957
986
  const handleClose = async () => {
958
- if (closing) return;
987
+ if (closing || reopening) return;
959
988
  setClosing(true);
960
989
  try {
961
990
  const next = await api.closeAsResolved(reportId, externalId);
@@ -970,6 +999,22 @@ function ReportDetailView({
970
999
  if (mountedRef.current) setClosing(false);
971
1000
  }
972
1001
  };
1002
+ const handleReopen = async () => {
1003
+ if (closing || reopening) return;
1004
+ setReopening(true);
1005
+ try {
1006
+ const next = await api.reopenUnresolved(reportId, externalId);
1007
+ if (!mountedRef.current) return;
1008
+ setDetail(next);
1009
+ } catch (err) {
1010
+ if (typeof console !== "undefined")
1011
+ console.warn("[mhosaic] reopenUnresolved:", err);
1012
+ if (!mountedRef.current) return;
1013
+ setError(strings["detail.reopen_failed"]);
1014
+ } finally {
1015
+ if (mountedRef.current) setReopening(false);
1016
+ }
1017
+ };
973
1018
  if (!detail && !error) {
974
1019
  return /* @__PURE__ */ jsx2("div", { class: "mine-loading", children: strings["mine.loading"] });
975
1020
  }
@@ -1047,10 +1092,20 @@ function ReportDetailView({
1047
1092
  type: "button",
1048
1093
  class: "btn",
1049
1094
  onClick: handleClose,
1050
- disabled: closing,
1095
+ disabled: closing || reopening,
1051
1096
  children: closing ? strings["detail.close_busy"] : strings["detail.close_cta"]
1052
1097
  }
1053
1098
  ),
1099
+ showCloseCta && /* @__PURE__ */ jsx2(
1100
+ "button",
1101
+ {
1102
+ type: "button",
1103
+ class: "btn btn--ghost",
1104
+ onClick: handleReopen,
1105
+ disabled: closing || reopening,
1106
+ children: reopening ? strings["detail.reopen_busy"] : strings["detail.reopen_cta"]
1107
+ }
1108
+ ),
1054
1109
  /* @__PURE__ */ jsx2(
1055
1110
  "button",
1056
1111
  {
@@ -4756,8 +4811,8 @@ function createFeedback(config) {
4756
4811
  capture_method: captureMethod,
4757
4812
  technical_context
4758
4813
  };
4759
- if ("0.18.0") {
4760
- payload.widget_version = "0.18.0";
4814
+ if ("0.19.0") {
4815
+ payload.widget_version = "0.19.0";
4761
4816
  }
4762
4817
  if (manualScreenshot) payload.screenshot = manualScreenshot;
4763
4818
  if (values.synthetic) payload.synthetic = true;
@@ -4798,7 +4853,10 @@ function createFeedback(config) {
4798
4853
  // Phase 4: the manifest tells the loader whether this project gates the
4799
4854
  // widget per end-user; the loader forwards it as `requiresVisibilityCheck`.
4800
4855
  requiresVisibilityCheck: config.requiresVisibilityCheck ?? false,
4801
- checkVisibility: (externalId) => api.checkVisibility(externalId)
4856
+ // Send the identified email alongside the id so an email-based allowlist
4857
+ // can match (the backend matches external_id OR email). Read from `user`
4858
+ // live so identity set after createFeedback() is reflected.
4859
+ checkVisibility: (externalId) => api.checkVisibility(externalId, user?.email)
4802
4860
  });
4803
4861
  const instance = {
4804
4862
  show() {
@@ -4847,4 +4905,4 @@ function createFeedback(config) {
4847
4905
  export {
4848
4906
  createFeedback
4849
4907
  };
4850
- //# sourceMappingURL=chunk-4QQI5ZYD.mjs.map
4908
+ //# sourceMappingURL=chunk-LCH5O3GT.mjs.map