callix-dialer-widget 1.4.9 → 1.5.1

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.
@@ -52892,6 +52892,30 @@ async function getCodeToNameMapping(campaignModelId) {
52892
52892
  const json = await response.json();
52893
52893
  return json;
52894
52894
  }
52895
+ async function getCustomerCodeToNameMapping(formId) {
52896
+ const url = `${API_BASE_URL$1}/api/campaign-contact/0?source=customer&formId=${encodeURIComponent(String(formId))}`;
52897
+ const response = await fetch(url, {
52898
+ method: "GET",
52899
+ headers: getAuthHeaders$1(),
52900
+ credentials: "omit"
52901
+ });
52902
+ if (!response.ok) {
52903
+ const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
52904
+ throw new Error(error2.error || `Falha ao buscar campos (cliente): ${response.status}`);
52905
+ }
52906
+ const json = await response.json();
52907
+ const mapping = {};
52908
+ if (json && Array.isArray(json.rows)) {
52909
+ for (const row of json.rows) {
52910
+ for (const field of row) {
52911
+ if (field && field.code && field.name) {
52912
+ mapping[field.code] = field.name;
52913
+ }
52914
+ }
52915
+ }
52916
+ }
52917
+ return mapping;
52918
+ }
52895
52919
  async function getContactValues$1(contactId) {
52896
52920
  const url = `${API_BASE_URL$1}/api/campaign-contact/${contactId}`;
52897
52921
  const response = await fetch(url, {
@@ -52906,6 +52930,20 @@ async function getContactValues$1(contactId) {
52906
52930
  const json = await response.json();
52907
52931
  return json;
52908
52932
  }
52933
+ async function getCustomerContactValues(customerId) {
52934
+ const url = `${API_BASE_URL$1}/api/campaign-fields/0?source=customer&customerId=${encodeURIComponent(String(customerId))}`;
52935
+ const response = await fetch(url, {
52936
+ method: "GET",
52937
+ headers: getAuthHeaders$1(),
52938
+ credentials: "omit"
52939
+ });
52940
+ if (!response.ok) {
52941
+ const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
52942
+ throw new Error(error2.error || `Falha ao buscar valores (cliente): ${response.status}`);
52943
+ }
52944
+ const json = await response.json();
52945
+ return json;
52946
+ }
52909
52947
  function CallInfoDisplay() {
52910
52948
  const callInfo = clientSdkReactExports.useCallOperatorCurrentCallInfo();
52911
52949
  useEffect(() => {
@@ -52944,17 +52982,29 @@ function CampaignCallInfoDisplay(props) {
52944
52982
  const fetchContactData = async () => {
52945
52983
  setContactData({ finalData: {}, isLoading: true, error: null });
52946
52984
  try {
52947
- console.log("[CampaignCallInfoDisplay] 1. Buscando config para contato:", campaignContact.id);
52948
- const config = await getCampaignConfig$1(campaignContact.id);
52949
- console.log("[CampaignCallInfoDisplay] 2. Config recebida:", config);
52950
- if (!config.campaignModelId) {
52951
- throw new Error("campaignModelId não encontrado");
52985
+ const customer = campaignContact.customer;
52986
+ console.log("[CampaignCallInfoDisplay] 1. Verificando customer no campaignContact:", customer);
52987
+ let codeToNameMap = {};
52988
+ let contactValues = {};
52989
+ if ((customer == null ? void 0 : customer.id) && (customer == null ? void 0 : customer.formId)) {
52990
+ console.log("[CampaignCallInfoDisplay] 2a. Modo CUSTOMER: buscando rows (formId) e dados (customerId)...");
52991
+ [codeToNameMap, contactValues] = await Promise.all([
52992
+ getCustomerCodeToNameMapping(customer.formId),
52993
+ getCustomerContactValues(customer.id)
52994
+ ]);
52995
+ } else {
52996
+ console.log("[CampaignCallInfoDisplay] 2b. Modo CAMPANHA: buscando config, rows e dados...");
52997
+ const config = await getCampaignConfig$1(campaignContact.id);
52998
+ console.log("[CampaignCallInfoDisplay] 2b. Config recebida:", config);
52999
+ if (!config.campaignModelId) {
53000
+ throw new Error("campaignModelId não encontrado");
53001
+ }
53002
+ console.log("[CampaignCallInfoDisplay] 3. Buscando mapeamento e valores em paralelo...");
53003
+ [codeToNameMap, contactValues] = await Promise.all([
53004
+ getCodeToNameMapping(config.campaignModelId),
53005
+ getContactValues$1(campaignContact.id)
53006
+ ]);
52952
53007
  }
52953
- console.log("[CampaignCallInfoDisplay] 3. Buscando mapeamento e valores em paralelo...");
52954
- const [codeToNameMap, contactValues] = await Promise.all([
52955
- getCodeToNameMapping(config.campaignModelId),
52956
- getContactValues$1(campaignContact.id)
52957
- ]);
52958
53008
  console.log("[CampaignCallInfoDisplay] 4. Mapeamento recebido:", codeToNameMap);
52959
53009
  console.log("[CampaignCallInfoDisplay] 5. Valores recebidos:", contactValues);
52960
53010
  const finalData = {};
@@ -53110,6 +53160,9 @@ function normalizePhoneNumberPaste(pastedText) {
53110
53160
  if (numero[0] === "9") {
53111
53161
  return cleaned;
53112
53162
  }
53163
+ if (["2", "3", "4"].includes(numero[0])) {
53164
+ return cleaned;
53165
+ }
53113
53166
  return ddd + "9" + numero;
53114
53167
  }
53115
53168
  if (len === 12) {
@@ -53753,6 +53806,7 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
53753
53806
  const dialerCardRef = useRef(null);
53754
53807
  const dialDisplayRef = useRef(null);
53755
53808
  const hiddenInputRef = useRef(null);
53809
+ const visibleInputRef = useRef(null);
53756
53810
  const [callError, setCallError] = useState(null);
53757
53811
  const [availabilityError, setAvailabilityError] = useState(null);
53758
53812
  const [afterCallError, setAfterCallError] = useState(null);
@@ -53760,6 +53814,7 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
53760
53814
  const [afterCallResult, setAfterCallResult] = useState("success");
53761
53815
  const [selectedQualificationId, setSelectedQualificationId] = useState(null);
53762
53816
  const [callDurationSeconds, setCallDurationSeconds] = useState(0);
53817
+ const [cursorPosition, setCursorPosition] = useState(0);
53763
53818
  const [networkMetric, setNetworkMetric] = useState(INITIAL_NETWORK_METRIC);
53764
53819
  const [audioMetric, setAudioMetric] = useState(INITIAL_AUDIO_METRIC);
53765
53820
  const toneContextRef = useRef(null);
@@ -54226,39 +54281,90 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
54226
54281
  return;
54227
54282
  }
54228
54283
  setCallError(null);
54229
- setDialValue((prev) => (prev + digit).slice(0, MAX_DIAL_LENGTH));
54284
+ if (!/^[0-9*#]$/.test(digit)) {
54285
+ console.warn("[handleDial] Dígito inválido ignorado:", digit);
54286
+ return;
54287
+ }
54288
+ const capturedPos = cursorPosition;
54289
+ setDialValue((prevValue) => {
54290
+ const currentValue = prevValue;
54291
+ const newValue = currentValue.slice(0, capturedPos) + digit + currentValue.slice(capturedPos);
54292
+ const trimmedValue = newValue.slice(0, MAX_DIAL_LENGTH);
54293
+ const newCursorPos = Math.min(capturedPos + 1, trimmedValue.length);
54294
+ setCursorPosition(newCursorPos);
54295
+ setTimeout(() => {
54296
+ if (visibleInputRef.current) {
54297
+ visibleInputRef.current.focus();
54298
+ visibleInputRef.current.setSelectionRange(newCursorPos, newCursorPos);
54299
+ }
54300
+ }, 0);
54301
+ return trimmedValue;
54302
+ });
54230
54303
  },
54231
- [playTone, currentCall, isInCall, isRinging, canEditNumber, setDialValue]
54304
+ [playTone, currentCall, isInCall, isRinging, canEditNumber, cursorPosition, setDialValue]
54232
54305
  );
54233
54306
  const handleClear = useCallback(() => {
54234
54307
  setCallError(null);
54235
54308
  setDialValue("");
54309
+ setCursorPosition(0);
54310
+ setTimeout(() => {
54311
+ if (visibleInputRef.current) {
54312
+ visibleInputRef.current.focus();
54313
+ }
54314
+ }, 0);
54236
54315
  }, [setDialValue]);
54237
54316
  const handleBackspace = useCallback(() => {
54238
54317
  setCallError(null);
54239
- setDialValue((prev) => prev.slice(0, -1));
54240
- }, [setDialValue]);
54318
+ const capturedPos = cursorPosition;
54319
+ if (capturedPos === 0) {
54320
+ return;
54321
+ }
54322
+ setDialValue((prevValue) => {
54323
+ const newValue = prevValue.slice(0, capturedPos - 1) + prevValue.slice(capturedPos);
54324
+ const newCursorPos = capturedPos - 1;
54325
+ setCursorPosition(newCursorPos);
54326
+ setTimeout(() => {
54327
+ if (visibleInputRef.current) {
54328
+ visibleInputRef.current.focus();
54329
+ visibleInputRef.current.setSelectionRange(newCursorPos, newCursorPos);
54330
+ }
54331
+ }, 0);
54332
+ return newValue;
54333
+ });
54334
+ }, [setDialValue, cursorPosition]);
54241
54335
  const handleCall = useCallback(async () => {
54242
54336
  if (!isIdle && !isOnBreak) {
54243
54337
  return;
54244
54338
  }
54245
- if (!normalizedNumber) {
54339
+ if (!sanitizedDialValue) {
54340
+ setCallError("Informe um numero para ligar.");
54341
+ return;
54342
+ }
54343
+ const normalizedLocal = normalizePhoneNumberPaste(sanitizedDialValue);
54344
+ console.log("[handleCall] sanitizedDialValue:", sanitizedDialValue);
54345
+ console.log("[handleCall] normalizedLocal após normalizePhoneNumberPaste:", normalizedLocal);
54346
+ const e164Number = normalizeToE164(normalizedLocal, DEFAULT_COUNTRY_PREFIX);
54347
+ console.log("[handleCall] e164Number após normalizeToE164:", e164Number);
54348
+ if (!e164Number) {
54246
54349
  setCallError("Informe um numero para ligar.");
54247
54350
  return;
54248
54351
  }
54249
- if (!isNumberValid) {
54250
- setCallError("Numero invalido. Digite apenas o numero local, sem o +55.");
54352
+ const isValid2 = isValidPhoneNumberSafe(e164Number);
54353
+ console.log("[handleCall] isValidPhoneNumberSafe:", isValid2);
54354
+ if (!isValid2) {
54355
+ setCallError("Numero invalido. Digite um numero de celular valido com DDD.");
54251
54356
  return;
54252
54357
  }
54358
+ console.log("[handleCall] 🚀 Ligando para:", e164Number);
54253
54359
  try {
54254
54360
  setCallError(null);
54255
- setLastDialedNumber(normalizedNumber);
54256
- await makeManualCall(normalizedNumber);
54361
+ setLastDialedNumber(e164Number);
54362
+ void makeManualCall(e164Number);
54257
54363
  } catch (error2) {
54258
54364
  console.error("Erro ao iniciar chamada", error2);
54259
54365
  setCallError("Nao foi possivel iniciar a ligacao.");
54260
54366
  }
54261
- }, [isIdle, isOnBreak, normalizedNumber, isNumberValid, makeManualCall]);
54367
+ }, [isIdle, isOnBreak, sanitizedDialValue, makeManualCall]);
54262
54368
  const handleGoOnBreak = useCallback(async (breakId) => {
54263
54369
  try {
54264
54370
  setBreakError(null);
@@ -54280,7 +54386,17 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
54280
54386
  }
54281
54387
  }, [goOffBreak]);
54282
54388
  useEffect(() => {
54283
- if (!isMiniMode && !isDialerFocused) {
54389
+ if (visibleInputRef.current && sanitizedDialValue.length < cursorPosition) {
54390
+ const newPos = sanitizedDialValue.length;
54391
+ setCursorPosition(newPos);
54392
+ visibleInputRef.current.setSelectionRange(newPos, newPos);
54393
+ }
54394
+ }, [sanitizedDialValue, cursorPosition]);
54395
+ useEffect(() => {
54396
+ if (isMiniMode) {
54397
+ return;
54398
+ }
54399
+ if (!isDialerFocused) {
54284
54400
  return;
54285
54401
  }
54286
54402
  const handleKeyDown = (event2) => {
@@ -54406,6 +54522,13 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
54406
54522
  }
54407
54523
  const normalized = normalizePhoneNumberPaste(pastedText);
54408
54524
  setDialValue(normalized);
54525
+ setCursorPosition(normalized.length);
54526
+ setTimeout(() => {
54527
+ if (visibleInputRef.current) {
54528
+ visibleInputRef.current.focus();
54529
+ visibleInputRef.current.setSelectionRange(normalized.length, normalized.length);
54530
+ }
54531
+ }, 0);
54409
54532
  }, [setDialValue]);
54410
54533
  const handleSelectInputDevice = useCallback((event2) => {
54411
54534
  const value = event2.target.value;
@@ -54671,15 +54794,86 @@ function AuthenticatedDialer({ username, dialValue, setDialValue, onLogout, vari
54671
54794
  ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
54672
54795
  "div",
54673
54796
  {
54674
- className: tw`space-y-1 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 cursor-text`,
54675
- onClick: () => {
54676
- var _a3;
54677
- return (_a3 = hiddenInputRef.current) == null ? void 0 : _a3.focus();
54678
- },
54797
+ className: tw`space-y-1 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2`,
54679
54798
  children: [
54680
54799
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tw`text-[10px] font-semibold uppercase tracking-wide text-slate-500`, children: "Numero" }),
54681
54800
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2`, children: [
54682
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tw`flex-1 truncate text-sm font-semibold text-slate-800`, children: dialDisplayText || /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tw`text-slate-400 text-xs font-normal`, children: "Digite ou cole um numero" }) }),
54801
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
54802
+ "input",
54803
+ {
54804
+ ref: visibleInputRef,
54805
+ type: "text",
54806
+ inputMode: "tel",
54807
+ value: sanitizedDialValue,
54808
+ onChange: (e) => {
54809
+ const input = e.target;
54810
+ setCursorPosition(input.selectionStart || 0);
54811
+ },
54812
+ onClick: (e) => {
54813
+ setCursorPosition(e.target.selectionStart || 0);
54814
+ },
54815
+ onKeyUp: (e) => {
54816
+ setCursorPosition(e.target.selectionStart || 0);
54817
+ },
54818
+ onSelect: (e) => {
54819
+ setCursorPosition(e.target.selectionStart || 0);
54820
+ },
54821
+ onKeyDown: (e) => {
54822
+ if (!miniCanUseKeypad) {
54823
+ e.preventDefault();
54824
+ return;
54825
+ }
54826
+ const key = e.key;
54827
+ const input = e.target;
54828
+ const currentPos = input.selectionStart || 0;
54829
+ setCursorPosition(currentPos);
54830
+ if (key === "Backspace") {
54831
+ e.preventDefault();
54832
+ handleBackspace();
54833
+ return;
54834
+ }
54835
+ if (key === "Delete") {
54836
+ e.preventDefault();
54837
+ const capturedPos = currentPos;
54838
+ setDialValue((prevValue) => {
54839
+ if (capturedPos < prevValue.length) {
54840
+ const newValue = prevValue.slice(0, capturedPos) + prevValue.slice(capturedPos + 1);
54841
+ setTimeout(() => {
54842
+ if (visibleInputRef.current) {
54843
+ visibleInputRef.current.setSelectionRange(capturedPos, capturedPos);
54844
+ setCursorPosition(capturedPos);
54845
+ }
54846
+ }, 0);
54847
+ return newValue;
54848
+ }
54849
+ return prevValue;
54850
+ });
54851
+ return;
54852
+ }
54853
+ if (key === "Enter") {
54854
+ e.preventDefault();
54855
+ void handleCall();
54856
+ return;
54857
+ }
54858
+ if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(key)) {
54859
+ return;
54860
+ }
54861
+ if ((e.ctrlKey || e.metaKey) && ["a", "c", "v", "x"].includes(key.toLowerCase())) {
54862
+ return;
54863
+ }
54864
+ if (/^[0-9*#]$/.test(key)) {
54865
+ e.preventDefault();
54866
+ handleDial(key);
54867
+ return;
54868
+ }
54869
+ e.preventDefault();
54870
+ },
54871
+ onPaste: handlePaste,
54872
+ disabled: !miniCanUseKeypad,
54873
+ placeholder: "Digite ou cole um numero",
54874
+ className: tw`flex-1 bg-transparent text-sm font-semibold text-slate-800 outline-none placeholder:text-slate-400 placeholder:text-xs placeholder:font-normal disabled:opacity-60 disabled:cursor-not-allowed`
54875
+ }
54876
+ ),
54683
54877
  /* @__PURE__ */ jsxRuntimeExports.jsx(
54684
54878
  "button",
54685
54879
  {
@@ -55172,7 +55366,15 @@ function normalizeToE164(rawValue, defaultPrefix) {
55172
55366
  if (!prefixDigits) {
55173
55367
  return `+${digits}`;
55174
55368
  }
55175
- return `+${prefixDigits}${digits}`;
55369
+ let phoneNumber = digits;
55370
+ if (prefixDigits === "55" && digits.length >= 10) {
55371
+ const ddd = digits.substring(0, 2);
55372
+ const number = digits.substring(2);
55373
+ if (number.length === 8 && !["2", "3", "4"].includes(number[0])) {
55374
+ phoneNumber = `${ddd}9${number}`;
55375
+ }
55376
+ }
55377
+ return `+${prefixDigits}${phoneNumber}`;
55176
55378
  }
55177
55379
  function isValidPhoneNumberSafe(value) {
55178
55380
  try {