callix-dialer-widget 2.8.2 → 2.8.3

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/WIDGET-README.md CHANGED
@@ -154,6 +154,12 @@ guardado, a tela avisa que a conexão está voltando, e ele é enviado no recone
154
154
  tiver menos de 15 s; mais velho que isso é descartado, para não atingir outra chamada. Antes,
155
155
  um "encerrar" dado nesse momento deixava a chamada ativa no motor.
156
156
 
157
+ Espelho e F5 no meio da chamada (2.8.3): a tela de chamada mostra o número da chamada em
158
+ curso informado pelo SDK ou pelo motor quando ninguém digitou nada naquele teclado (antes
159
+ aparecia "(--) ----- ----" na aba espelho). Click-to-call com o agente em pausa (2.8.3): o
160
+ agente sai da pausa, espera o Callix liberá-lo (até 8 s) e disca; se não liberar, a tarefa
161
+ volta à fila. No modo motor, um `dial` recebido em pausa faz o mesmo dentro do motor.
162
+
157
163
  Sem `engineUrl` nada muda: o SDK continua rodando no navegador como sempre.
158
164
 
159
165
  ## 🔐 Login e usuário conhecido
@@ -58735,7 +58735,7 @@ function AuthenticatedMobileDialer({
58735
58735
  showClientInfoModal = false,
58736
58736
  density
58737
58737
  }) {
58738
- var _a2, _b, _c, _d, _e;
58738
+ var _a2, _b, _c, _d, _e, _f;
58739
58739
  const { skipManualQualification } = useDialerConfig();
58740
58740
  const [dialValue, setDialValue] = useState("");
58741
58741
  const [activeScreen, setActiveScreen] = useState("dialer");
@@ -58775,6 +58775,7 @@ function AuthenticatedMobileDialer({
58775
58775
  const currentCall = useCallOperatorCurrentCall();
58776
58776
  const { hangup, answer, reject } = useCallOperatorCurrentCallControls();
58777
58777
  const callInfo = useCallOperatorCurrentCallInfo();
58778
+ const activeCallNumber = ((_a2 = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _a2.destinationNumber) || (currentCall == null ? void 0 : currentCall.callerNumber) || "";
58778
58779
  const rawSuccessQualifications = useCallOperatorSuccessQualifications();
58779
58780
  const rawDiscardQualifications = useCallOperatorDiscardQualifications();
58780
58781
  const successQualifications = useMemo(() => rawSuccessQualifications ?? [], [rawSuccessQualifications]);
@@ -59349,6 +59350,8 @@ function AuthenticatedMobileDialer({
59349
59350
  phoneNumber = callInfo.info.campaignContact.phoneNumber;
59350
59351
  } else if (dialValue) {
59351
59352
  phoneNumber = dialValue;
59353
+ } else if (activeCallNumber) {
59354
+ phoneNumber = activeCallNumber;
59352
59355
  }
59353
59356
  const cleanNumber = phoneNumber.replace(/[^\d+]/g, "");
59354
59357
  let whatsappNumber = cleanNumber;
@@ -59364,7 +59367,7 @@ function AuthenticatedMobileDialer({
59364
59367
  const whatsappUrl = `https://wa.me/${whatsappNumber.replace("+", "")}?text=${encodedMessage}`;
59365
59368
  console.log("[MobileDialer] Abrindo WhatsApp com template:", whatsappUrl);
59366
59369
  window.open(whatsappUrl, "_blank");
59367
- }, [callInfo, dialValue, userData, username, contactData.finalData]);
59370
+ }, [callInfo, dialValue, userData, username, contactData.finalData, activeCallNumber]);
59368
59371
  const handleGoOnBreak = useCallback(
59369
59372
  async (breakId) => {
59370
59373
  if (!goOnBreak) return;
@@ -59432,8 +59435,9 @@ function AuthenticatedMobileDialer({
59432
59435
  if ((callInfo == null ? void 0 : callInfo.type) === "campaign" && ((_a3 = callInfo.info.campaignContact) == null ? void 0 : _a3.phoneNumber)) {
59433
59436
  return formatPhoneForDisplay(callInfo.info.campaignContact.phoneNumber);
59434
59437
  }
59435
- return formattedDial || "(--) ----- ----";
59436
- }, [callInfo, formattedDial]);
59438
+ if (formattedDial) return formattedDial;
59439
+ return activeCallNumber ? formatPhoneForDisplay(activeCallNumber) : "(--) ----- ----";
59440
+ }, [callInfo, formattedDial, activeCallNumber]);
59437
59441
  const callStatusLabel = useMemo(() => {
59438
59442
  if (isConnecting) return "Ligando...";
59439
59443
  if (isInCall) return "Em chamada";
@@ -59448,7 +59452,7 @@ function AuthenticatedMobileDialer({
59448
59452
  if (isOnBreak) return "paused";
59449
59453
  return "available";
59450
59454
  }, [isError, isOnBreak]);
59451
- const activeBreakName = (operatorState == null ? void 0 : operatorState.state) === "onBreak" ? (_a2 = operatorState.break) == null ? void 0 : _a2.name : void 0;
59455
+ const activeBreakName = (operatorState == null ? void 0 : operatorState.state) === "onBreak" ? (_b = operatorState.break) == null ? void 0 : _b.name : void 0;
59452
59456
  const statusBadgeText = useMemo(() => {
59453
59457
  if (isError) return (dialerNotice == null ? void 0 : dialerNotice.source) === "device" ? dialerNotice.title : "Erro";
59454
59458
  if (isOnBreak) return currentBreakName || activeBreakName || "Em pausa";
@@ -59591,15 +59595,15 @@ function AuthenticatedMobileDialer({
59591
59595
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-card-header", children: [
59592
59596
  /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-user-circle client-avatar" }),
59593
59597
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-main-info", children: [
59594
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-name", id: "clientName", children: findValue(contactData.finalData, ["DECISOR", "NOME", "CLIENTE", "PROSPECT"]) ?? ((_b = callInfo.info.campaignContact) == null ? void 0 : _b.label) ?? "--" }),
59595
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-company", id: "clientCompany", children: findValue(contactData.finalData, ["EMPRESA", "RAZAO SOCIAL", "RAZÃO SOCIAL", "RAZAO_SOCIAL"]) ?? ((_c = callInfo.info.campaign) == null ? void 0 : _c.name) ?? "--" })
59598
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-name", id: "clientName", children: findValue(contactData.finalData, ["DECISOR", "NOME", "CLIENTE", "PROSPECT"]) ?? ((_c = callInfo.info.campaignContact) == null ? void 0 : _c.label) ?? "--" }),
59599
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-company", id: "clientCompany", children: findValue(contactData.finalData, ["EMPRESA", "RAZAO SOCIAL", "RAZÃO SOCIAL", "RAZAO_SOCIAL"]) ?? ((_d = callInfo.info.campaign) == null ? void 0 : _d.name) ?? "--" })
59596
59600
  ] })
59597
59601
  ] }),
59598
59602
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "client-card-divider" }),
59599
59603
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-list", children: [
59600
59604
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-row", children: [
59601
59605
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-label", children: "Socio" }),
59602
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-value", children: findValue(contactData.finalData, ["SOCIO", "PROSPECT", "DECISOR", "NOME", "CLIENTE"]) ?? ((_d = callInfo.info.campaignContact) == null ? void 0 : _d.label) ?? "--" })
59606
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-value", children: findValue(contactData.finalData, ["SOCIO", "PROSPECT", "DECISOR", "NOME", "CLIENTE"]) ?? ((_e = callInfo.info.campaignContact) == null ? void 0 : _e.label) ?? "--" })
59603
59607
  ] }),
59604
59608
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "client-info-row", children: [
59605
59609
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "client-info-label", children: "Empresa" }),
@@ -59796,7 +59800,7 @@ function AuthenticatedMobileDialer({
59796
59800
  {
59797
59801
  isOpen: isClientInfoModalOpen,
59798
59802
  campaignCallInfo,
59799
- campaignContactPhoneId: ((_e = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _e.campaignContactPhoneId) ?? null,
59803
+ campaignContactPhoneId: ((_f = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _f.campaignContactPhoneId) ?? null,
59800
59804
  callDuration: callDurationSeconds,
59801
59805
  isCallActive: isInCall || isConnecting,
59802
59806
  onClose: () => setIsClientInfoModalOpen(false)
@@ -60563,6 +60567,7 @@ const BUSY_INTERVAL_FACTOR = 3;
60563
60567
  const DISPATCH_COOLDOWN_MS = 6e3;
60564
60568
  const CALL_START_TIMEOUT_MS = 4e3;
60565
60569
  const CALL_START_CHECK_MS = 100;
60570
+ const LEAVE_BREAK_TIMEOUT_MS = 8e3;
60566
60571
  const MAX_BACKOFF_MS = 6e4;
60567
60572
  const NOT_CONFIGURED_INTERVAL_MS = 5 * 6e4;
60568
60573
  const NOT_CONFIGURED_CODES = /* @__PURE__ */ new Set(["STORE_NOT_CONFIGURED", "SERVER_NOT_CONFIGURED"]);
@@ -60578,11 +60583,13 @@ function buildHeaders(sessionToken) {
60578
60583
  const delay = (ms2) => new Promise((resolve) => setTimeout(resolve, ms2));
60579
60584
  function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask }) {
60580
60585
  const operatorState = useCallOperatorState();
60581
- const { makeManualCall } = useCallOperatorControls();
60586
+ const { makeManualCall, becomeAvailable } = useCallOperatorControls();
60582
60587
  const stateRef = useRef(operatorState == null ? void 0 : operatorState.state);
60583
60588
  stateRef.current = operatorState == null ? void 0 : operatorState.state;
60584
60589
  const makeManualCallRef = useRef(makeManualCall);
60585
60590
  makeManualCallRef.current = makeManualCall;
60591
+ const becomeAvailableRef = useRef(becomeAvailable);
60592
+ becomeAvailableRef.current = becomeAvailable;
60586
60593
  const onTaskRef = useRef(onTask);
60587
60594
  onTaskRef.current = onTask;
60588
60595
  const tickerRef = useRef(null);
@@ -60644,6 +60651,16 @@ function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask
60644
60651
  console.error("[ClickToCall] não foi possível confirmar a tarefa", options.taskId, "; o servidor a marcará como não confirmada");
60645
60652
  return false;
60646
60653
  };
60654
+ const waitForOperatorState = (predicate, timeoutMs) => new Promise((resolve) => {
60655
+ const deadline = Date.now() + timeoutMs;
60656
+ const check = () => {
60657
+ if (disposed) return resolve(false);
60658
+ if (predicate(stateRef.current)) return resolve(true);
60659
+ if (Date.now() >= deadline) return resolve(false);
60660
+ setTimeout(check, CALL_START_CHECK_MS);
60661
+ };
60662
+ check();
60663
+ });
60647
60664
  const waitForCallStart = () => new Promise((resolve) => {
60648
60665
  const deadline = Date.now() + CALL_START_TIMEOUT_MS;
60649
60666
  const check = () => {
@@ -60677,6 +60694,23 @@ function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask
60677
60694
  } catch (error2) {
60678
60695
  console.warn("[ClickToCall] onTask lançou erro:", error2);
60679
60696
  }
60697
+ if (presenceFromOperatorState(stateRef.current) === "on_break") {
60698
+ console.log("[ClickToCall] operador em pausa: saindo da pausa para ligar");
60699
+ try {
60700
+ becomeAvailableRef.current();
60701
+ } catch (error2) {
60702
+ const message = error2 instanceof Error ? error2.message : String(error2);
60703
+ console.error("[ClickToCall] becomeAvailable falhou:", message);
60704
+ await ack({ taskId: task.id, status: "failed", error: `Não deu para sair da pausa: ${message}`, retry: true });
60705
+ return;
60706
+ }
60707
+ const available = await waitForOperatorState((state2) => state2 === "idle", LEAVE_BREAK_TIMEOUT_MS);
60708
+ if (!available) {
60709
+ console.warn("[ClickToCall] o operador não saiu da pausa a tempo (estado", stateRef.current, "): devolvendo à fila");
60710
+ await ack({ taskId: task.id, status: "failed", error: `Operador não saiu da pausa (${stateRef.current ?? "desconhecido"})`, retry: true });
60711
+ return;
60712
+ }
60713
+ }
60680
60714
  try {
60681
60715
  makeManualCallRef.current(task.phone);
60682
60716
  } catch (error2) {
@@ -60780,7 +60814,7 @@ function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask
60780
60814
  }, [enabled, pollIntervalMs, sessionToken]);
60781
60815
  return null;
60782
60816
  }
60783
- const WIDGET_VERSION = "2.8.2";
60817
+ const WIDGET_VERSION = "2.8.3";
60784
60818
  let currentSipWebSocket = null;
60785
60819
  function sendSipUnregisterIfPossible(ws) {
60786
60820
  if (ws.readyState !== WebSocket.OPEN) return;