callix-dialer-widget 2.2.0 → 2.4.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.
- package/WIDGET-README.md +72 -3
- package/dist-widget/callix-dialer.css +1 -1
- package/dist-widget/callix-dialer.es.js +1537 -750
- package/dist-widget/callix-dialer.es.js.map +1 -1
- package/dist-widget/callix-dialer.umd.js +4 -4
- package/dist-widget/callix-dialer.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
6
6
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
7
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
8
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
-
import React, {
|
|
9
|
+
import React, { useState, useMemo, useRef, useEffect, useCallback, forwardRef, useLayoutEffect, useId, createContext, useImperativeHandle, StrictMode, useContext } from "react";
|
|
10
10
|
import require$$0$2, { createPortal } from "react-dom";
|
|
11
11
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
12
12
|
function getAugmentedNamespace(n) {
|
|
@@ -101,9 +101,9 @@ function requireAxios() {
|
|
|
101
101
|
const { toString } = Object.prototype;
|
|
102
102
|
const { getPrototypeOf } = Object;
|
|
103
103
|
const { iterator, toStringTag } = Symbol;
|
|
104
|
-
const kindOf = /* @__PURE__ */ ((
|
|
104
|
+
const kindOf = /* @__PURE__ */ ((cache2) => (thing) => {
|
|
105
105
|
const str = toString.call(thing);
|
|
106
|
-
return
|
|
106
|
+
return cache2[str] || (cache2[str] = str.slice(8, -1).toLowerCase());
|
|
107
107
|
})(/* @__PURE__ */ Object.create(null));
|
|
108
108
|
const kindOfTest = (type) => {
|
|
109
109
|
type = type.toLowerCase();
|
|
@@ -307,10 +307,10 @@ function requireAxios() {
|
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
309
|
const matchAll = (regExp, str) => {
|
|
310
|
-
let
|
|
310
|
+
let matches2;
|
|
311
311
|
const arr = [];
|
|
312
|
-
while ((
|
|
313
|
-
arr.push(
|
|
312
|
+
while ((matches2 = regExp.exec(str)) !== null) {
|
|
313
|
+
arr.push(matches2);
|
|
314
314
|
}
|
|
315
315
|
return arr;
|
|
316
316
|
};
|
|
@@ -5774,11 +5774,11 @@ var StateNode = (
|
|
|
5774
5774
|
if (!afterConfig) {
|
|
5775
5775
|
return [];
|
|
5776
5776
|
}
|
|
5777
|
-
var mutateEntryExit = function(
|
|
5778
|
-
var delayRef = isFunction(
|
|
5777
|
+
var mutateEntryExit = function(delay2, i2) {
|
|
5778
|
+
var delayRef = isFunction(delay2) ? "".concat(_this.id, ":delay[").concat(i2, "]") : delay2;
|
|
5779
5779
|
var eventType = after(delayRef, _this.id);
|
|
5780
5780
|
_this.onEntry.push(send$1(eventType, {
|
|
5781
|
-
delay
|
|
5781
|
+
delay: delay2
|
|
5782
5782
|
}));
|
|
5783
5783
|
_this.onExit.push(cancel$1(eventType));
|
|
5784
5784
|
return eventType;
|
|
@@ -5788,12 +5788,12 @@ var StateNode = (
|
|
|
5788
5788
|
return __assign(__assign({}, transition), {
|
|
5789
5789
|
event: eventType
|
|
5790
5790
|
});
|
|
5791
|
-
}) : flatten(Object.keys(afterConfig).map(function(
|
|
5792
|
-
var configTransition = afterConfig[
|
|
5791
|
+
}) : flatten(Object.keys(afterConfig).map(function(delay2, i2) {
|
|
5792
|
+
var configTransition = afterConfig[delay2];
|
|
5793
5793
|
var resolvedTransition = isString(configTransition) ? {
|
|
5794
5794
|
target: configTransition
|
|
5795
5795
|
} : configTransition;
|
|
5796
|
-
var resolvedDelay = !isNaN(+
|
|
5796
|
+
var resolvedDelay = !isNaN(+delay2) ? +delay2 : delay2;
|
|
5797
5797
|
var eventType = mutateEntryExit(resolvedDelay, i2);
|
|
5798
5798
|
return toArray(resolvedTransition).map(function(transition) {
|
|
5799
5799
|
return __assign(__assign({}, transition), {
|
|
@@ -5803,9 +5803,9 @@ var StateNode = (
|
|
|
5803
5803
|
});
|
|
5804
5804
|
}));
|
|
5805
5805
|
return delayedTransitions.map(function(delayedTransition) {
|
|
5806
|
-
var
|
|
5806
|
+
var delay2 = delayedTransition.delay;
|
|
5807
5807
|
return __assign(__assign({}, _this.formatTransition(delayedTransition)), {
|
|
5808
|
-
delay
|
|
5808
|
+
delay: delay2
|
|
5809
5809
|
});
|
|
5810
5810
|
});
|
|
5811
5811
|
};
|
|
@@ -7785,13 +7785,13 @@ function requireExtractExtension() {
|
|
|
7785
7785
|
return {};
|
|
7786
7786
|
}
|
|
7787
7787
|
var numberWithoutExtension = number.slice(0, start2);
|
|
7788
|
-
var
|
|
7788
|
+
var matches2 = number.match(EXTN_PATTERN2);
|
|
7789
7789
|
var i2 = 1;
|
|
7790
|
-
while (i2 <
|
|
7791
|
-
if (
|
|
7790
|
+
while (i2 < matches2.length) {
|
|
7791
|
+
if (matches2[i2]) {
|
|
7792
7792
|
return {
|
|
7793
7793
|
number: numberWithoutExtension,
|
|
7794
|
-
ext:
|
|
7794
|
+
ext: matches2[i2]
|
|
7795
7795
|
};
|
|
7796
7796
|
}
|
|
7797
7797
|
i2++;
|
|
@@ -10797,10 +10797,10 @@ function requirePhoneNumberMatcher() {
|
|
|
10797
10797
|
return _createClass2(PhoneNumberMatcher2, [{
|
|
10798
10798
|
key: "find",
|
|
10799
10799
|
value: function find() {
|
|
10800
|
-
var
|
|
10801
|
-
while (this.maxTries > 0 && (
|
|
10802
|
-
var candidate =
|
|
10803
|
-
var offset =
|
|
10800
|
+
var matches2;
|
|
10801
|
+
while (this.maxTries > 0 && (matches2 = this.PATTERN.exec(this.text)) !== null) {
|
|
10802
|
+
var candidate = matches2[0];
|
|
10803
|
+
var offset = matches2.index;
|
|
10804
10804
|
candidate = (0, _parsePreCandidate["default"])(candidate);
|
|
10805
10805
|
if ((0, _isValidPreCandidate["default"])(candidate, offset, this.text)) {
|
|
10806
10806
|
var match2 = (
|
|
@@ -14024,12 +14024,12 @@ function requireMemoize() {
|
|
|
14024
14024
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
14025
14025
|
}
|
|
14026
14026
|
var memoized = function() {
|
|
14027
|
-
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0],
|
|
14028
|
-
if (
|
|
14029
|
-
return
|
|
14027
|
+
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache2 = memoized.cache;
|
|
14028
|
+
if (cache2.has(key)) {
|
|
14029
|
+
return cache2.get(key);
|
|
14030
14030
|
}
|
|
14031
14031
|
var result2 = func.apply(this, args);
|
|
14032
|
-
memoized.cache =
|
|
14032
|
+
memoized.cache = cache2.set(key, result2) || cache2;
|
|
14033
14033
|
return result2;
|
|
14034
14034
|
};
|
|
14035
14035
|
memoized.cache = new (memoize.Cache || MapCache)();
|
|
@@ -14503,14 +14503,14 @@ function requirePhoneNumberSearch() {
|
|
|
14503
14503
|
return _createClass2(PhoneNumberSearch2, [{
|
|
14504
14504
|
key: "find",
|
|
14505
14505
|
value: function find() {
|
|
14506
|
-
var
|
|
14507
|
-
if (!
|
|
14506
|
+
var matches2 = this.regexp.exec(this.text);
|
|
14507
|
+
if (!matches2) {
|
|
14508
14508
|
return;
|
|
14509
14509
|
}
|
|
14510
|
-
var number =
|
|
14511
|
-
var startsAt =
|
|
14510
|
+
var number = matches2[0];
|
|
14511
|
+
var startsAt = matches2.index;
|
|
14512
14512
|
number = number.replace(WHITESPACE_IN_THE_BEGINNING_PATTERN, "");
|
|
14513
|
-
startsAt +=
|
|
14513
|
+
startsAt += matches2[0].length - number.length;
|
|
14514
14514
|
number = number.replace(PUNCTUATION_IN_THE_END_PATTERN, "");
|
|
14515
14515
|
number = (0, _parsePreCandidate["default"])(number);
|
|
14516
14516
|
var result2 = this.parseCandidate(number, startsAt);
|
|
@@ -42753,73 +42753,73 @@ function requireChunk52ALM2Y4() {
|
|
|
42753
42753
|
function isInjector(value) {
|
|
42754
42754
|
return __isInternalType(value, Injector);
|
|
42755
42755
|
}
|
|
42756
|
-
var getWeakCacheItem = (
|
|
42756
|
+
var getWeakCacheItem = (cache2, deps) => {
|
|
42757
42757
|
while (true) {
|
|
42758
42758
|
const [dep, ...rest] = deps;
|
|
42759
|
-
const entry =
|
|
42759
|
+
const entry = cache2.get(dep);
|
|
42760
42760
|
if (!entry) {
|
|
42761
42761
|
return;
|
|
42762
42762
|
}
|
|
42763
42763
|
if (!rest.length) {
|
|
42764
42764
|
return entry[1];
|
|
42765
42765
|
}
|
|
42766
|
-
|
|
42766
|
+
cache2 = entry[0];
|
|
42767
42767
|
deps = rest;
|
|
42768
42768
|
}
|
|
42769
42769
|
};
|
|
42770
|
-
var setWeakCacheItem = (
|
|
42770
|
+
var setWeakCacheItem = (cache2, deps, item) => {
|
|
42771
42771
|
while (true) {
|
|
42772
42772
|
const [dep, ...rest] = deps;
|
|
42773
|
-
let entry =
|
|
42773
|
+
let entry = cache2.get(dep);
|
|
42774
42774
|
if (!entry) {
|
|
42775
42775
|
entry = [/* @__PURE__ */ new WeakMap()];
|
|
42776
|
-
|
|
42776
|
+
cache2.set(dep, entry);
|
|
42777
42777
|
}
|
|
42778
42778
|
if (!rest.length) {
|
|
42779
42779
|
entry[1] = item;
|
|
42780
42780
|
return;
|
|
42781
42781
|
}
|
|
42782
|
-
|
|
42782
|
+
cache2 = entry[0];
|
|
42783
42783
|
deps = rest;
|
|
42784
42784
|
}
|
|
42785
42785
|
};
|
|
42786
42786
|
var createDeepCache = () => {
|
|
42787
|
-
let
|
|
42787
|
+
let cache2 = /* @__PURE__ */ new WeakMap();
|
|
42788
42788
|
const deepCache = (createFn, foundFn, deps) => {
|
|
42789
42789
|
if (!deps.length)
|
|
42790
42790
|
throw new Error("Dependencies need to exist.");
|
|
42791
|
-
const cachedValue = getWeakCacheItem(
|
|
42791
|
+
const cachedValue = getWeakCacheItem(cache2, deps);
|
|
42792
42792
|
if (cachedValue) {
|
|
42793
42793
|
foundFn(cachedValue);
|
|
42794
42794
|
return cachedValue;
|
|
42795
42795
|
}
|
|
42796
42796
|
const newObject = createFn();
|
|
42797
|
-
setWeakCacheItem(
|
|
42797
|
+
setWeakCacheItem(cache2, deps, newObject);
|
|
42798
42798
|
return newObject;
|
|
42799
42799
|
};
|
|
42800
42800
|
const upsert = (createFn, deps) => {
|
|
42801
42801
|
if (!deps.length)
|
|
42802
42802
|
throw new Error("Dependencies need to exist.");
|
|
42803
|
-
const cachedValue = getWeakCacheItem(
|
|
42803
|
+
const cachedValue = getWeakCacheItem(cache2, deps);
|
|
42804
42804
|
const newObject = createFn(cachedValue);
|
|
42805
|
-
setWeakCacheItem(
|
|
42805
|
+
setWeakCacheItem(cache2, deps, newObject);
|
|
42806
42806
|
};
|
|
42807
42807
|
const remove = (...deps) => {
|
|
42808
|
-
removeWeakCacheItem(
|
|
42808
|
+
removeWeakCacheItem(cache2, deps);
|
|
42809
42809
|
};
|
|
42810
|
-
const get = (deps) => getWeakCacheItem(
|
|
42810
|
+
const get = (deps) => getWeakCacheItem(cache2, deps);
|
|
42811
42811
|
return {
|
|
42812
42812
|
get,
|
|
42813
|
-
cache,
|
|
42813
|
+
cache: cache2,
|
|
42814
42814
|
deepCache,
|
|
42815
42815
|
upsert,
|
|
42816
42816
|
remove
|
|
42817
42817
|
};
|
|
42818
42818
|
};
|
|
42819
|
-
var removeWeakCacheItem = (
|
|
42819
|
+
var removeWeakCacheItem = (cache2, deps) => {
|
|
42820
42820
|
while (true) {
|
|
42821
42821
|
const [dep, ...rest] = deps;
|
|
42822
|
-
let entry =
|
|
42822
|
+
let entry = cache2.get(dep);
|
|
42823
42823
|
if (!entry) {
|
|
42824
42824
|
return;
|
|
42825
42825
|
}
|
|
@@ -42828,7 +42828,7 @@ function requireChunk52ALM2Y4() {
|
|
|
42828
42828
|
entry[1] = void 0;
|
|
42829
42829
|
return;
|
|
42830
42830
|
} else {
|
|
42831
|
-
|
|
42831
|
+
cache2 = entry[0];
|
|
42832
42832
|
deps = rest;
|
|
42833
42833
|
}
|
|
42834
42834
|
}
|
|
@@ -44185,11 +44185,11 @@ var directive = (factory, data) => {
|
|
|
44185
44185
|
const key = stringify(data);
|
|
44186
44186
|
let directive2;
|
|
44187
44187
|
if (key) {
|
|
44188
|
-
var
|
|
44189
|
-
if (!
|
|
44190
|
-
cacheByFactory.set(factory,
|
|
44188
|
+
var cache2 = cacheByFactory.get(factory);
|
|
44189
|
+
if (!cache2) {
|
|
44190
|
+
cacheByFactory.set(factory, cache2 = /* @__PURE__ */ new Map());
|
|
44191
44191
|
}
|
|
44192
|
-
directive2 =
|
|
44192
|
+
directive2 = cache2.get(key);
|
|
44193
44193
|
}
|
|
44194
44194
|
if (!directive2) {
|
|
44195
44195
|
directive2 = Object.defineProperty((params, context) => {
|
|
@@ -44198,9 +44198,9 @@ var directive = (factory, data) => {
|
|
|
44198
44198
|
}, "toJSON", {
|
|
44199
44199
|
value: () => key || data
|
|
44200
44200
|
});
|
|
44201
|
-
if (
|
|
44202
|
-
|
|
44203
|
-
ensureMaxSize(
|
|
44201
|
+
if (cache2) {
|
|
44202
|
+
cache2.set(key, directive2);
|
|
44203
|
+
ensureMaxSize(cache2, 1e4);
|
|
44204
44204
|
}
|
|
44205
44205
|
}
|
|
44206
44206
|
return directive2;
|
|
@@ -45472,7 +45472,7 @@ var resolveContext = {
|
|
|
45472
45472
|
};
|
|
45473
45473
|
var handleArbitraryValues = (section, key) => (key = key[0] == "[" && key.slice(-1) == "]" && key.slice(1, -1)) && includes(section, "olor") == /^(#|(hsl|rgb)a?\(|[a-z]+$)/.test(key) && (includes(key, "calc(") ? key.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, "$1 $2 ") : key);
|
|
45474
45474
|
var makeThemeResolver = (config) => {
|
|
45475
|
-
const
|
|
45475
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
45476
45476
|
const theme2 = { ...defaultTheme, ...config };
|
|
45477
45477
|
const deref = (theme3, section) => {
|
|
45478
45478
|
const base = theme3 && theme3[section];
|
|
@@ -45486,9 +45486,9 @@ var makeThemeResolver = (config) => {
|
|
|
45486
45486
|
defaultValue = key;
|
|
45487
45487
|
key = join$1(tail(keypath), ".");
|
|
45488
45488
|
}
|
|
45489
|
-
let base =
|
|
45489
|
+
let base = cache2.get(section);
|
|
45490
45490
|
if (!base) {
|
|
45491
|
-
|
|
45491
|
+
cache2.set(section, base = { ...deref(theme2, section) });
|
|
45492
45492
|
Object.assign(base, deref(theme2.extend, section));
|
|
45493
45493
|
}
|
|
45494
45494
|
if (key != null) {
|
|
@@ -48472,96 +48472,146 @@ function getAuthHeaders() {
|
|
|
48472
48472
|
}
|
|
48473
48473
|
return headers;
|
|
48474
48474
|
}
|
|
48475
|
-
|
|
48476
|
-
|
|
48477
|
-
|
|
48478
|
-
|
|
48479
|
-
|
|
48480
|
-
|
|
48481
|
-
}
|
|
48482
|
-
|
|
48483
|
-
|
|
48484
|
-
|
|
48485
|
-
|
|
48486
|
-
|
|
48487
|
-
|
|
48488
|
-
}
|
|
48489
|
-
async function getCodeToNameMapping(campaignModelId) {
|
|
48490
|
-
const url = `${API_BASE_URL}/api/campaign-fields/${campaignModelId}`;
|
|
48491
|
-
const response = await fetch(url, {
|
|
48492
|
-
method: "GET",
|
|
48493
|
-
headers: getAuthHeaders(),
|
|
48494
|
-
credentials: "omit"
|
|
48495
|
-
});
|
|
48496
|
-
if (!response.ok) {
|
|
48497
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
48498
|
-
throw new Error(error2.error || `Falha ao buscar mapeamento: ${response.status}`);
|
|
48499
|
-
}
|
|
48500
|
-
const json = await response.json();
|
|
48501
|
-
return json;
|
|
48502
|
-
}
|
|
48503
|
-
async function getCustomerCodeToNameMapping(formId) {
|
|
48504
|
-
const url = `${API_BASE_URL}/api/campaign-contact/0?source=customer&formId=${encodeURIComponent(String(formId))}`;
|
|
48505
|
-
const response = await fetch(url, {
|
|
48506
|
-
method: "GET",
|
|
48507
|
-
headers: getAuthHeaders(),
|
|
48508
|
-
credentials: "omit"
|
|
48509
|
-
});
|
|
48510
|
-
if (!response.ok) {
|
|
48511
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
48512
|
-
throw new Error(error2.error || `Falha ao buscar campos (cliente): ${response.status}`);
|
|
48475
|
+
const CAMPAIGN_FORM_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
48476
|
+
const DEFAULT_RETRIES = 2;
|
|
48477
|
+
const RETRY_DELAY_MS = 800;
|
|
48478
|
+
const REQUEST_TIMEOUT_MS$1 = 15e3;
|
|
48479
|
+
const cache = /* @__PURE__ */ new Map();
|
|
48480
|
+
function campaignFormCacheKey(request) {
|
|
48481
|
+
return `${request.source}:${request.id}`;
|
|
48482
|
+
}
|
|
48483
|
+
function campaignFormRequestFromCallInfo(info, phoneId) {
|
|
48484
|
+
var _a2, _b;
|
|
48485
|
+
const contact = info == null ? void 0 : info.campaignContact;
|
|
48486
|
+
if (!(contact == null ? void 0 : contact.id)) {
|
|
48487
|
+
return null;
|
|
48513
48488
|
}
|
|
48514
|
-
const
|
|
48515
|
-
|
|
48516
|
-
|
|
48517
|
-
|
|
48518
|
-
|
|
48519
|
-
|
|
48520
|
-
|
|
48521
|
-
|
|
48489
|
+
const customer = contact.customer;
|
|
48490
|
+
if ((customer == null ? void 0 : customer.id) && (customer == null ? void 0 : customer.formId)) {
|
|
48491
|
+
return { source: "customer", id: customer.id, formId: customer.formId, campaignId: ((_a2 = info == null ? void 0 : info.campaign) == null ? void 0 : _a2.id) ?? null, phoneId: phoneId ?? null };
|
|
48492
|
+
}
|
|
48493
|
+
return { source: "campaign", id: contact.id, campaignId: ((_b = info == null ? void 0 : info.campaign) == null ? void 0 : _b.id) ?? null, phoneId: phoneId ?? null };
|
|
48494
|
+
}
|
|
48495
|
+
function buildCampaignFormUrl(apiBaseUrl, request) {
|
|
48496
|
+
const params = new URLSearchParams();
|
|
48497
|
+
if (request.source === "customer") params.set("source", "customer");
|
|
48498
|
+
if (request.campaignId) params.set("campaignId", String(request.campaignId));
|
|
48499
|
+
if (request.formId) params.set("formId", String(request.formId));
|
|
48500
|
+
if (request.phoneId) params.set("phoneId", String(request.phoneId));
|
|
48501
|
+
if (request.signature && request.expiresAt) {
|
|
48502
|
+
params.set("sig", request.signature);
|
|
48503
|
+
params.set("exp", String(request.expiresAt));
|
|
48504
|
+
}
|
|
48505
|
+
const query = params.toString();
|
|
48506
|
+
return `${apiBaseUrl}/api/campaign-form/${encodeURIComponent(String(request.id))}${query ? `?${query}` : ""}`;
|
|
48507
|
+
}
|
|
48508
|
+
function isFormResponse(value) {
|
|
48509
|
+
if (!value || typeof value !== "object") return false;
|
|
48510
|
+
const form = value;
|
|
48511
|
+
return typeof form.id === "number" && !!form.values && typeof form.values === "object" && Array.isArray(form.fields);
|
|
48512
|
+
}
|
|
48513
|
+
const NETWORK_ERROR_MESSAGE = "Não foi possível conectar ao servidor do discador. Verifique a conexão ou se o back-end está atualizado.";
|
|
48514
|
+
const ROUTE_MISSING_MESSAGE = "Rota do formulário não encontrada no servidor do discador. Atualize o back-end (deploy) para esta versão do widget.";
|
|
48515
|
+
function describeHttpError(status, body) {
|
|
48516
|
+
if (status === 401) return "Sessão expirada. Entre novamente no discador.";
|
|
48517
|
+
const fromBody = body.message || body.error;
|
|
48518
|
+
if (fromBody) return fromBody;
|
|
48519
|
+
if (status === 404) return ROUTE_MISSING_MESSAGE;
|
|
48520
|
+
return `Erro ${status}`;
|
|
48521
|
+
}
|
|
48522
|
+
async function requestOnce(url, headers) {
|
|
48523
|
+
const controller = new AbortController();
|
|
48524
|
+
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS$1);
|
|
48525
|
+
try {
|
|
48526
|
+
const response = await fetch(url, { method: "GET", headers, credentials: "omit", signal: controller.signal });
|
|
48527
|
+
if (!response.ok) {
|
|
48528
|
+
const body = await response.json().catch(() => ({}));
|
|
48529
|
+
const error2 = new Error(describeHttpError(response.status, body));
|
|
48530
|
+
error2.status = response.status;
|
|
48531
|
+
throw error2;
|
|
48532
|
+
}
|
|
48533
|
+
const data = await response.json();
|
|
48534
|
+
if (!isFormResponse(data)) {
|
|
48535
|
+
throw new Error("Resposta inesperada do servidor");
|
|
48536
|
+
}
|
|
48537
|
+
return data;
|
|
48538
|
+
} catch (error2) {
|
|
48539
|
+
if (error2 instanceof Error && error2.name === "AbortError") {
|
|
48540
|
+
throw new Error("Tempo esgotado ao buscar o formulário");
|
|
48541
|
+
}
|
|
48542
|
+
if (error2 instanceof TypeError) {
|
|
48543
|
+
const wrapped = new Error(NETWORK_ERROR_MESSAGE);
|
|
48544
|
+
wrapped.cause = error2;
|
|
48545
|
+
throw wrapped;
|
|
48546
|
+
}
|
|
48547
|
+
throw error2;
|
|
48548
|
+
} finally {
|
|
48549
|
+
clearTimeout(timer);
|
|
48550
|
+
}
|
|
48551
|
+
}
|
|
48552
|
+
function shouldRetry(error2) {
|
|
48553
|
+
const status = error2 == null ? void 0 : error2.status;
|
|
48554
|
+
if (status === void 0) return true;
|
|
48555
|
+
return status >= 500 || status === 408 || status === 429;
|
|
48556
|
+
}
|
|
48557
|
+
function fetchCampaignForm(request, options = {}) {
|
|
48558
|
+
const key = campaignFormCacheKey(request);
|
|
48559
|
+
const now = Date.now();
|
|
48560
|
+
const cached = cache.get(key);
|
|
48561
|
+
if (cached && cached.until > now && !options.force) {
|
|
48562
|
+
return cached.promise;
|
|
48563
|
+
}
|
|
48564
|
+
const url = buildCampaignFormUrl(options.apiBaseUrl ?? API_BASE_URL, request);
|
|
48565
|
+
const headers = options.headers ?? getAuthHeaders();
|
|
48566
|
+
const retries = Math.max(0, options.retries ?? DEFAULT_RETRIES);
|
|
48567
|
+
const promise = (async () => {
|
|
48568
|
+
let lastError;
|
|
48569
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
48570
|
+
try {
|
|
48571
|
+
return await requestOnce(url, headers);
|
|
48572
|
+
} catch (error2) {
|
|
48573
|
+
lastError = error2;
|
|
48574
|
+
if (attempt === retries || !shouldRetry(error2)) break;
|
|
48575
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS * 2 ** attempt));
|
|
48522
48576
|
}
|
|
48523
48577
|
}
|
|
48524
|
-
|
|
48525
|
-
|
|
48526
|
-
}
|
|
48527
|
-
|
|
48528
|
-
|
|
48529
|
-
|
|
48530
|
-
|
|
48531
|
-
|
|
48532
|
-
|
|
48533
|
-
});
|
|
48534
|
-
if (!response.ok) {
|
|
48535
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
48536
|
-
throw new Error(error2.error || `Falha ao buscar valores: ${response.status}`);
|
|
48537
|
-
}
|
|
48538
|
-
const json = await response.json();
|
|
48539
|
-
return json;
|
|
48540
|
-
}
|
|
48541
|
-
async function getCustomerContactValues$1(customerId) {
|
|
48542
|
-
const url = `${API_BASE_URL}/api/campaign-fields/0?source=customer&customerId=${encodeURIComponent(String(customerId))}`;
|
|
48543
|
-
const response = await fetch(url, {
|
|
48544
|
-
method: "GET",
|
|
48545
|
-
headers: getAuthHeaders(),
|
|
48546
|
-
credentials: "omit"
|
|
48578
|
+
throw lastError instanceof Error ? lastError : new Error("Erro ao buscar o formulário");
|
|
48579
|
+
})();
|
|
48580
|
+
cache.set(key, { promise, until: now + CAMPAIGN_FORM_CACHE_TTL_MS });
|
|
48581
|
+
promise.then((form) => {
|
|
48582
|
+
var _a2;
|
|
48583
|
+
if (form.partial && ((_a2 = cache.get(key)) == null ? void 0 : _a2.promise) === promise) cache.delete(key);
|
|
48584
|
+
}).catch(() => {
|
|
48585
|
+
var _a2;
|
|
48586
|
+
if (((_a2 = cache.get(key)) == null ? void 0 : _a2.promise) === promise) cache.delete(key);
|
|
48547
48587
|
});
|
|
48548
|
-
|
|
48549
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
48550
|
-
throw new Error(error2.error || `Falha ao buscar valores (cliente): ${response.status}`);
|
|
48551
|
-
}
|
|
48552
|
-
const json = await response.json();
|
|
48553
|
-
return json;
|
|
48588
|
+
return promise;
|
|
48554
48589
|
}
|
|
48555
|
-
function
|
|
48556
|
-
|
|
48557
|
-
|
|
48558
|
-
|
|
48559
|
-
|
|
48590
|
+
function normalizeFormKey(value) {
|
|
48591
|
+
return String(value ?? "").normalize("NFC").trim().toLowerCase().replace(/\s+/g, " ");
|
|
48592
|
+
}
|
|
48593
|
+
function findFormValue(form, candidates) {
|
|
48594
|
+
if (!(form == null ? void 0 : form.values)) {
|
|
48595
|
+
return void 0;
|
|
48596
|
+
}
|
|
48597
|
+
const byNormalizedKey = /* @__PURE__ */ new Map();
|
|
48598
|
+
for (const [key, value] of Object.entries(form.values)) {
|
|
48599
|
+
const normalized = stripAccents(normalizeFormKey(key));
|
|
48600
|
+
if (!byNormalizedKey.has(normalized) && value !== void 0 && value !== null && String(value).trim() !== "") {
|
|
48601
|
+
byNormalizedKey.set(normalized, String(value));
|
|
48602
|
+
}
|
|
48603
|
+
}
|
|
48604
|
+
for (const candidate of candidates) {
|
|
48605
|
+
const value = byNormalizedKey.get(stripAccents(normalizeFormKey(candidate)));
|
|
48606
|
+
if (value !== void 0) {
|
|
48560
48607
|
return value;
|
|
48561
48608
|
}
|
|
48562
48609
|
}
|
|
48563
48610
|
return void 0;
|
|
48564
48611
|
}
|
|
48612
|
+
function stripAccents(value) {
|
|
48613
|
+
return value.normalize("NFD").replace(/[̀-ͯ]/g, "");
|
|
48614
|
+
}
|
|
48565
48615
|
function formatPhoneValue(raw) {
|
|
48566
48616
|
if (!raw) return "-";
|
|
48567
48617
|
const digits = raw.replace(/\D/g, "");
|
|
@@ -48575,18 +48625,12 @@ function formatPhoneValue(raw) {
|
|
|
48575
48625
|
return raw.trim();
|
|
48576
48626
|
}
|
|
48577
48627
|
function CallInfoDisplay() {
|
|
48628
|
+
var _a2;
|
|
48578
48629
|
const callInfo = clientSdkReactExports.useCallOperatorCurrentCallInfo();
|
|
48579
|
-
|
|
48580
|
-
|
|
48581
|
-
callInfo,
|
|
48582
|
-
type: callInfo == null ? void 0 : callInfo.type,
|
|
48583
|
-
hasCampaignInfo: (callInfo == null ? void 0 : callInfo.type) === "campaign",
|
|
48584
|
-
info: (callInfo == null ? void 0 : callInfo.type) === "campaign" ? callInfo.info : null,
|
|
48585
|
-
campaignContact: (callInfo == null ? void 0 : callInfo.type) === "campaign" ? callInfo.info.campaignContact : null
|
|
48586
|
-
});
|
|
48587
|
-
}, [callInfo]);
|
|
48630
|
+
const currentCall = clientSdkReactExports.useCallOperatorCurrentCall();
|
|
48631
|
+
const campaignContactPhoneId = ((_a2 = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _a2.campaignContactPhoneId) ?? null;
|
|
48588
48632
|
if ((callInfo == null ? void 0 : callInfo.type) === "campaign") {
|
|
48589
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(CampaignCallInfoDisplay, { campaignCallInfo: callInfo.info });
|
|
48633
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(CampaignCallInfoDisplay, { campaignCallInfo: callInfo.info, campaignContactPhoneId });
|
|
48590
48634
|
}
|
|
48591
48635
|
if (callInfo) {
|
|
48592
48636
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-amber-700", children: "Chamada manual (sem informações de campanha)" }) });
|
|
@@ -48596,83 +48640,63 @@ function CallInfoDisplay() {
|
|
|
48596
48640
|
function CampaignCallInfoDisplay(props) {
|
|
48597
48641
|
const { campaign, campaignContact } = props.campaignCallInfo;
|
|
48598
48642
|
const [contactData, setContactData] = useState({
|
|
48599
|
-
|
|
48643
|
+
form: null,
|
|
48600
48644
|
isLoading: false,
|
|
48601
48645
|
error: null
|
|
48602
48646
|
});
|
|
48603
|
-
const [
|
|
48647
|
+
const [retry, setRetry] = useState({ key: null, n: 0 });
|
|
48648
|
+
const request = useMemo(
|
|
48649
|
+
() => campaignFormRequestFromCallInfo(props.campaignCallInfo, props.campaignContactPhoneId),
|
|
48650
|
+
[props.campaignCallInfo, props.campaignContactPhoneId]
|
|
48651
|
+
);
|
|
48652
|
+
const requestKey = request ? campaignFormCacheKey(request) : null;
|
|
48653
|
+
const requestRef = useRef(request);
|
|
48654
|
+
requestRef.current = request;
|
|
48655
|
+
const partialRefreshKeyRef = useRef(null);
|
|
48604
48656
|
useEffect(() => {
|
|
48605
|
-
|
|
48606
|
-
|
|
48607
|
-
|
|
48608
|
-
if (fetchedContactId === campaignContact.id) {
|
|
48657
|
+
const current = requestRef.current;
|
|
48658
|
+
if (!current || !requestKey) {
|
|
48659
|
+
setContactData({ form: null, isLoading: false, error: null });
|
|
48609
48660
|
return;
|
|
48610
48661
|
}
|
|
48611
48662
|
let cancelled = false;
|
|
48612
|
-
|
|
48613
|
-
|
|
48614
|
-
|
|
48615
|
-
|
|
48616
|
-
|
|
48617
|
-
|
|
48618
|
-
|
|
48619
|
-
|
|
48620
|
-
getCustomerCodeToNameMapping(customer.formId),
|
|
48621
|
-
getCustomerContactValues$1(customer.id)
|
|
48622
|
-
]);
|
|
48623
|
-
} else {
|
|
48624
|
-
const config = await getCampaignConfig$2(campaignContact.id);
|
|
48625
|
-
if (!config.campaignModelId) {
|
|
48626
|
-
throw new Error("campaignModelId não encontrado");
|
|
48627
|
-
}
|
|
48628
|
-
[codeToNameMap, contactValues] = await Promise.all([
|
|
48629
|
-
getCodeToNameMapping(config.campaignModelId),
|
|
48630
|
-
getContactValues$2(campaignContact.id)
|
|
48631
|
-
]);
|
|
48663
|
+
let refreshTimer = null;
|
|
48664
|
+
setContactData({ form: null, isLoading: true, error: null });
|
|
48665
|
+
fetchCampaignForm(current, { force: retry.key === requestKey && retry.n > 0 }).then((form) => {
|
|
48666
|
+
if (!cancelled) {
|
|
48667
|
+
setContactData({ form, isLoading: false, error: null });
|
|
48668
|
+
if (form.partial && partialRefreshKeyRef.current !== requestKey) {
|
|
48669
|
+
partialRefreshKeyRef.current = requestKey;
|
|
48670
|
+
refreshTimer = setTimeout(() => setRetry((prev) => ({ key: requestKey, n: prev.n + 1 })), 3e3);
|
|
48632
48671
|
}
|
|
48633
|
-
|
|
48634
|
-
|
|
48635
|
-
|
|
48636
|
-
|
|
48637
|
-
|
|
48672
|
+
}
|
|
48673
|
+
}).catch((error2) => {
|
|
48674
|
+
if (!cancelled) {
|
|
48675
|
+
console.error("[CampaignCallInfoDisplay] Erro ao buscar dados:", error2);
|
|
48676
|
+
setContactData({
|
|
48677
|
+
form: null,
|
|
48678
|
+
isLoading: false,
|
|
48679
|
+
error: error2 instanceof Error ? error2.message : "Erro ao buscar dados do contato"
|
|
48638
48680
|
});
|
|
48639
|
-
if (!cancelled) {
|
|
48640
|
-
setContactData({
|
|
48641
|
-
finalData,
|
|
48642
|
-
isLoading: false,
|
|
48643
|
-
error: null
|
|
48644
|
-
});
|
|
48645
|
-
setFetchedContactId(campaignContact.id);
|
|
48646
|
-
}
|
|
48647
|
-
} catch (error2) {
|
|
48648
|
-
if (!cancelled) {
|
|
48649
|
-
console.error("[CampaignCallInfoDisplay] Erro ao buscar dados:", error2);
|
|
48650
|
-
const errorMessage = error2 instanceof Error ? error2.message : "Erro ao buscar dados do contato";
|
|
48651
|
-
setContactData({
|
|
48652
|
-
finalData: {},
|
|
48653
|
-
isLoading: false,
|
|
48654
|
-
error: errorMessage
|
|
48655
|
-
});
|
|
48656
|
-
}
|
|
48657
48681
|
}
|
|
48658
|
-
};
|
|
48659
|
-
void fetchContactData();
|
|
48682
|
+
});
|
|
48660
48683
|
return () => {
|
|
48661
48684
|
cancelled = true;
|
|
48685
|
+
if (refreshTimer) clearTimeout(refreshTimer);
|
|
48662
48686
|
};
|
|
48663
|
-
}, [
|
|
48687
|
+
}, [requestKey, retry]);
|
|
48664
48688
|
const prioritizedFields = useMemo(
|
|
48665
48689
|
() => [
|
|
48666
|
-
{ label: "Decisor", keys: ["DECISOR"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { className: "text-sm" }) },
|
|
48667
|
-
{ label: "Empresa", keys: ["EMPRESA", "RAZAO SOCIAL"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiBriefcase, { className: "text-sm" }) },
|
|
48668
|
-
{ label: "Dívida ativa", keys: ["DIVIDA ATIVA", "DÍVIDA ATIVA"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiHash, { className: "text-sm" }) },
|
|
48690
|
+
{ label: "Decisor", keys: ["DECISOR", "CONTATO", "NOME"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { className: "text-sm" }) },
|
|
48691
|
+
{ label: "Empresa", keys: ["EMPRESA", "RAZAO SOCIAL", "RAZÃO SOCIAL", "CLIENTE"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiBriefcase, { className: "text-sm" }) },
|
|
48692
|
+
{ label: "Dívida ativa", keys: ["DIVIDA ATIVA", "DÍVIDA ATIVA", "VALOR TOTAL DEVIDO"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiHash, { className: "text-sm" }) },
|
|
48669
48693
|
{ label: "Telefone", keys: ["TELEFONE", "CELULAR", "WHATSAPP"], icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FiSmartphone, { className: "text-sm" }) }
|
|
48670
48694
|
],
|
|
48671
48695
|
[]
|
|
48672
48696
|
);
|
|
48673
48697
|
const highlightData = useMemo(() => {
|
|
48674
48698
|
return prioritizedFields.map((field) => {
|
|
48675
|
-
const rawValue = (field.label === "Telefone" ?
|
|
48699
|
+
const rawValue = (field.label === "Telefone" ? findFormValue(contactData.form, field.keys) ?? (campaignContact == null ? void 0 : campaignContact.phoneNumber) : findFormValue(contactData.form, field.keys)) || "";
|
|
48676
48700
|
const display2 = field.label === "Telefone" ? formatPhoneValue(rawValue) : (rawValue || "-").toString().trim() || "-";
|
|
48677
48701
|
return {
|
|
48678
48702
|
...field,
|
|
@@ -48680,7 +48704,7 @@ function CampaignCallInfoDisplay(props) {
|
|
|
48680
48704
|
isEmpty: !rawValue
|
|
48681
48705
|
};
|
|
48682
48706
|
});
|
|
48683
|
-
}, [campaignContact == null ? void 0 : campaignContact.phoneNumber, contactData.
|
|
48707
|
+
}, [campaignContact == null ? void 0 : campaignContact.phoneNumber, contactData.form, prioritizedFields]);
|
|
48684
48708
|
const hasData = highlightData.some((item) => !item.isEmpty);
|
|
48685
48709
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 rounded-2xl border border-slate-200 bg-white/90 p-3 shadow-sm", children: [
|
|
48686
48710
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 flex items-center justify-between gap-2", children: [
|
|
@@ -48696,7 +48720,7 @@ function CampaignCallInfoDisplay(props) {
|
|
|
48696
48720
|
"Em chamada"
|
|
48697
48721
|
] })
|
|
48698
48722
|
] }),
|
|
48699
|
-
contactData.isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-slate-200 bg-slate-50 p-4 text-center", children: [
|
|
48723
|
+
contactData.isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-slate-200 bg-slate-50 p-4 text-center", role: "status", children: [
|
|
48700
48724
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto mb-2 inline-block h-7 w-7 animate-spin rounded-full border-2 border-emerald-500 border-t-transparent" }),
|
|
48701
48725
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-medium text-slate-600", children: "Carregando dados do contato..." })
|
|
48702
48726
|
] }),
|
|
@@ -48706,10 +48730,11 @@ function CampaignCallInfoDisplay(props) {
|
|
|
48706
48730
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-rose-700", children: "Erro ao carregar dados" })
|
|
48707
48731
|
] }),
|
|
48708
48732
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ml-6 text-[11px] text-rose-600", children: contactData.error }),
|
|
48709
|
-
|
|
48733
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
48710
48734
|
"button",
|
|
48711
48735
|
{
|
|
48712
|
-
|
|
48736
|
+
type: "button",
|
|
48737
|
+
onClick: () => setRetry((prev) => ({ key: requestKey, n: prev.n + 1 })),
|
|
48713
48738
|
className: "mt-2 ml-6 text-[11px] font-semibold text-rose-700 underline hover:text-rose-800",
|
|
48714
48739
|
children: "Tentar novamente"
|
|
48715
48740
|
}
|
|
@@ -50237,13 +50262,13 @@ function extractExtension(number) {
|
|
|
50237
50262
|
return {};
|
|
50238
50263
|
}
|
|
50239
50264
|
var numberWithoutExtension = number.slice(0, start2);
|
|
50240
|
-
var
|
|
50265
|
+
var matches2 = number.match(EXTN_PATTERN);
|
|
50241
50266
|
var i2 = 1;
|
|
50242
|
-
while (i2 <
|
|
50243
|
-
if (
|
|
50267
|
+
while (i2 < matches2.length) {
|
|
50268
|
+
if (matches2[i2]) {
|
|
50244
50269
|
return {
|
|
50245
50270
|
number: numberWithoutExtension,
|
|
50246
|
-
ext:
|
|
50271
|
+
ext: matches2[i2]
|
|
50247
50272
|
};
|
|
50248
50273
|
}
|
|
50249
50274
|
i2++;
|
|
@@ -51141,6 +51166,266 @@ function buildDialPlan(rawValue, defaultPrefix = DEFAULT_COUNTRY_PREFIX) {
|
|
|
51141
51166
|
const differs = Boolean(e164) && onlyDigits(e164 ?? "") !== typedDigits;
|
|
51142
51167
|
return { raw, display: display2, e164, dialDisplay, isValid: isValid2, differs };
|
|
51143
51168
|
}
|
|
51169
|
+
const QUERIES = {
|
|
51170
|
+
fine: "(pointer: fine)",
|
|
51171
|
+
coarse: "(pointer: coarse)",
|
|
51172
|
+
hover: "(hover: hover)"
|
|
51173
|
+
};
|
|
51174
|
+
function matches(query) {
|
|
51175
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
51176
|
+
return null;
|
|
51177
|
+
}
|
|
51178
|
+
try {
|
|
51179
|
+
return window.matchMedia(query).matches;
|
|
51180
|
+
} catch {
|
|
51181
|
+
return null;
|
|
51182
|
+
}
|
|
51183
|
+
}
|
|
51184
|
+
function getInputProfile() {
|
|
51185
|
+
const fine = matches(QUERIES.fine);
|
|
51186
|
+
const coarse = matches(QUERIES.coarse);
|
|
51187
|
+
const hover = matches(QUERIES.hover);
|
|
51188
|
+
const pointer = coarse ? "coarse" : fine ? "fine" : "unknown";
|
|
51189
|
+
const touchLike = pointer === "coarse" || pointer !== "fine" && hover === false;
|
|
51190
|
+
return { pointer, hover: hover === true, touchLike };
|
|
51191
|
+
}
|
|
51192
|
+
function resolveDensity(density, profile) {
|
|
51193
|
+
if (density === "compact" || density === "comfortable") {
|
|
51194
|
+
return density;
|
|
51195
|
+
}
|
|
51196
|
+
return profile.touchLike ? "comfortable" : "compact";
|
|
51197
|
+
}
|
|
51198
|
+
function parseDensity(value) {
|
|
51199
|
+
const normalized = (value ?? "").trim().toLowerCase();
|
|
51200
|
+
if (normalized === "compact" || normalized === "compacta" || normalized === "compacto") return "compact";
|
|
51201
|
+
if (normalized === "comfortable" || normalized === "confortavel" || normalized === "confortável" || normalized === "touch") return "comfortable";
|
|
51202
|
+
if (normalized === "auto") return "auto";
|
|
51203
|
+
return void 0;
|
|
51204
|
+
}
|
|
51205
|
+
function useInputProfile() {
|
|
51206
|
+
const [profile, setProfile] = useState(() => getInputProfile());
|
|
51207
|
+
useEffect(() => {
|
|
51208
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
51209
|
+
return;
|
|
51210
|
+
}
|
|
51211
|
+
const update2 = () => setProfile(getInputProfile());
|
|
51212
|
+
const lists = [];
|
|
51213
|
+
for (const query of Object.values(QUERIES)) {
|
|
51214
|
+
try {
|
|
51215
|
+
const list = window.matchMedia(query);
|
|
51216
|
+
if (typeof list.addEventListener === "function") {
|
|
51217
|
+
list.addEventListener("change", update2);
|
|
51218
|
+
} else if (typeof list.addListener === "function") {
|
|
51219
|
+
list.addListener(update2);
|
|
51220
|
+
}
|
|
51221
|
+
lists.push(list);
|
|
51222
|
+
} catch {
|
|
51223
|
+
}
|
|
51224
|
+
}
|
|
51225
|
+
update2();
|
|
51226
|
+
return () => {
|
|
51227
|
+
for (const list of lists) {
|
|
51228
|
+
if (typeof list.removeEventListener === "function") {
|
|
51229
|
+
list.removeEventListener("change", update2);
|
|
51230
|
+
} else if (typeof list.removeListener === "function") {
|
|
51231
|
+
list.removeListener(update2);
|
|
51232
|
+
}
|
|
51233
|
+
}
|
|
51234
|
+
};
|
|
51235
|
+
}, []);
|
|
51236
|
+
return profile;
|
|
51237
|
+
}
|
|
51238
|
+
const CLICK_TO_CALL_EVENT = "callix:click-to-call";
|
|
51239
|
+
function presenceFromOperatorState(state) {
|
|
51240
|
+
if (!state) {
|
|
51241
|
+
return "unknown";
|
|
51242
|
+
}
|
|
51243
|
+
switch (state) {
|
|
51244
|
+
case "idle":
|
|
51245
|
+
return "available";
|
|
51246
|
+
case "onBreak":
|
|
51247
|
+
return "on_break";
|
|
51248
|
+
case "afterCall":
|
|
51249
|
+
case "manualCallFailed":
|
|
51250
|
+
return "after_call";
|
|
51251
|
+
case "offline":
|
|
51252
|
+
case "stopped":
|
|
51253
|
+
case "startupError":
|
|
51254
|
+
case "startup.error":
|
|
51255
|
+
case "networkDown":
|
|
51256
|
+
return "offline";
|
|
51257
|
+
case "starting":
|
|
51258
|
+
return "unknown";
|
|
51259
|
+
case "callRinging":
|
|
51260
|
+
case "manualCallSetup":
|
|
51261
|
+
case "manualCallRinging":
|
|
51262
|
+
case "callInProgress":
|
|
51263
|
+
return "in_call";
|
|
51264
|
+
default:
|
|
51265
|
+
return /call|ringing|dial/i.test(state) ? "in_call" : "unknown";
|
|
51266
|
+
}
|
|
51267
|
+
}
|
|
51268
|
+
function canDispatchTo(presence) {
|
|
51269
|
+
return presence === "available" || presence === "on_break";
|
|
51270
|
+
}
|
|
51271
|
+
const REQUEST_TIMEOUT_MS = 1e4;
|
|
51272
|
+
const DEFAULT_PRESENCE_TTL_SECONDS = 45;
|
|
51273
|
+
function withTimeout(signal) {
|
|
51274
|
+
const controller = new AbortController();
|
|
51275
|
+
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
51276
|
+
if (signal) {
|
|
51277
|
+
if (signal.aborted) {
|
|
51278
|
+
controller.abort();
|
|
51279
|
+
} else {
|
|
51280
|
+
signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
51281
|
+
}
|
|
51282
|
+
}
|
|
51283
|
+
return { signal: controller.signal, clear: () => clearTimeout(timer) };
|
|
51284
|
+
}
|
|
51285
|
+
async function pollClickToCall(options) {
|
|
51286
|
+
const { signal, clear } = withTimeout(options.signal);
|
|
51287
|
+
try {
|
|
51288
|
+
const response = await fetch(`${options.apiBaseUrl}/api/click-to-call/poll`, {
|
|
51289
|
+
method: "POST",
|
|
51290
|
+
headers: options.headers,
|
|
51291
|
+
body: JSON.stringify({ state: options.state ?? null, claim: options.claim }),
|
|
51292
|
+
credentials: "omit",
|
|
51293
|
+
signal
|
|
51294
|
+
});
|
|
51295
|
+
if (!response.ok) {
|
|
51296
|
+
let code = null;
|
|
51297
|
+
try {
|
|
51298
|
+
const data2 = await response.json();
|
|
51299
|
+
code = typeof (data2 == null ? void 0 : data2.error) === "string" ? data2.error : null;
|
|
51300
|
+
} catch {
|
|
51301
|
+
}
|
|
51302
|
+
return { ok: false, status: response.status, code };
|
|
51303
|
+
}
|
|
51304
|
+
const data = await response.json();
|
|
51305
|
+
return {
|
|
51306
|
+
ok: true,
|
|
51307
|
+
presence: data.presence ?? "unknown",
|
|
51308
|
+
task: data.task && typeof data.task === "object" && typeof data.task.phone === "string" ? data.task : null,
|
|
51309
|
+
pollIntervalMs: typeof data.pollIntervalMs === "number" ? data.pollIntervalMs : 0,
|
|
51310
|
+
presenceTtlSeconds: typeof data.presenceTtlSeconds === "number" && data.presenceTtlSeconds > 0 ? data.presenceTtlSeconds : DEFAULT_PRESENCE_TTL_SECONDS
|
|
51311
|
+
};
|
|
51312
|
+
} finally {
|
|
51313
|
+
clear();
|
|
51314
|
+
}
|
|
51315
|
+
}
|
|
51316
|
+
async function ackClickToCall(options) {
|
|
51317
|
+
const { signal, clear } = withTimeout();
|
|
51318
|
+
try {
|
|
51319
|
+
const response = await fetch(`${options.apiBaseUrl}/api/click-to-call/${encodeURIComponent(options.taskId)}`, {
|
|
51320
|
+
method: "PATCH",
|
|
51321
|
+
headers: options.headers,
|
|
51322
|
+
body: JSON.stringify({ status: options.status, error: options.error, retry: options.retry === true }),
|
|
51323
|
+
credentials: "omit",
|
|
51324
|
+
keepalive: true,
|
|
51325
|
+
signal
|
|
51326
|
+
});
|
|
51327
|
+
if (!response.ok) {
|
|
51328
|
+
let code = null;
|
|
51329
|
+
try {
|
|
51330
|
+
const data2 = await response.json();
|
|
51331
|
+
code = typeof (data2 == null ? void 0 : data2.error) === "string" ? data2.error : null;
|
|
51332
|
+
} catch {
|
|
51333
|
+
}
|
|
51334
|
+
return { ok: false, status: response.status, code };
|
|
51335
|
+
}
|
|
51336
|
+
const data = await response.json();
|
|
51337
|
+
return { ok: true, task: data.task ?? null };
|
|
51338
|
+
} finally {
|
|
51339
|
+
clear();
|
|
51340
|
+
}
|
|
51341
|
+
}
|
|
51342
|
+
function reportClickToCallOffline(config) {
|
|
51343
|
+
try {
|
|
51344
|
+
void fetch(`${config.apiBaseUrl}/api/click-to-call/poll`, {
|
|
51345
|
+
method: "POST",
|
|
51346
|
+
headers: config.headers,
|
|
51347
|
+
body: JSON.stringify({ state: "offline", claim: false }),
|
|
51348
|
+
credentials: "omit",
|
|
51349
|
+
keepalive: true
|
|
51350
|
+
}).catch(() => void 0);
|
|
51351
|
+
} catch {
|
|
51352
|
+
}
|
|
51353
|
+
}
|
|
51354
|
+
const WORKER_SOURCE = `
|
|
51355
|
+
let timer = null;
|
|
51356
|
+
self.onmessage = (event) => {
|
|
51357
|
+
const interval = Number(event && event.data && event.data.interval) || 0;
|
|
51358
|
+
if (timer) { clearInterval(timer); timer = null; }
|
|
51359
|
+
if (interval > 0) { timer = setInterval(() => self.postMessage('tick'), interval); }
|
|
51360
|
+
};
|
|
51361
|
+
`;
|
|
51362
|
+
function createBackgroundTicker(callback, intervalMs) {
|
|
51363
|
+
let current = Math.max(250, Math.round(intervalMs));
|
|
51364
|
+
let fallbackTimer = null;
|
|
51365
|
+
let worker = null;
|
|
51366
|
+
let objectUrl = null;
|
|
51367
|
+
let stopped = false;
|
|
51368
|
+
const startFallback = () => {
|
|
51369
|
+
if (stopped) return;
|
|
51370
|
+
if (fallbackTimer) clearInterval(fallbackTimer);
|
|
51371
|
+
fallbackTimer = setInterval(callback, current);
|
|
51372
|
+
};
|
|
51373
|
+
try {
|
|
51374
|
+
if (typeof Worker !== "undefined" && typeof Blob !== "undefined" && typeof URL !== "undefined" && URL.createObjectURL) {
|
|
51375
|
+
objectUrl = URL.createObjectURL(new Blob([WORKER_SOURCE], { type: "application/javascript" }));
|
|
51376
|
+
worker = new Worker(objectUrl);
|
|
51377
|
+
worker.onmessage = () => {
|
|
51378
|
+
if (!stopped) callback();
|
|
51379
|
+
};
|
|
51380
|
+
worker.onerror = () => {
|
|
51381
|
+
worker == null ? void 0 : worker.terminate();
|
|
51382
|
+
worker = null;
|
|
51383
|
+
startFallback();
|
|
51384
|
+
};
|
|
51385
|
+
worker.postMessage({ interval: current });
|
|
51386
|
+
} else {
|
|
51387
|
+
startFallback();
|
|
51388
|
+
}
|
|
51389
|
+
} catch {
|
|
51390
|
+
worker = null;
|
|
51391
|
+
startFallback();
|
|
51392
|
+
}
|
|
51393
|
+
return {
|
|
51394
|
+
setInterval(ms2) {
|
|
51395
|
+
if (stopped) return;
|
|
51396
|
+
const next = Math.max(250, Math.round(ms2));
|
|
51397
|
+
if (next === current) return;
|
|
51398
|
+
current = next;
|
|
51399
|
+
if (worker) {
|
|
51400
|
+
worker.postMessage({ interval: current });
|
|
51401
|
+
} else {
|
|
51402
|
+
startFallback();
|
|
51403
|
+
}
|
|
51404
|
+
},
|
|
51405
|
+
stop() {
|
|
51406
|
+
stopped = true;
|
|
51407
|
+
if (worker) {
|
|
51408
|
+
worker.terminate();
|
|
51409
|
+
worker = null;
|
|
51410
|
+
}
|
|
51411
|
+
if (objectUrl) {
|
|
51412
|
+
URL.revokeObjectURL(objectUrl);
|
|
51413
|
+
objectUrl = null;
|
|
51414
|
+
}
|
|
51415
|
+
if (fallbackTimer) {
|
|
51416
|
+
clearInterval(fallbackTimer);
|
|
51417
|
+
fallbackTimer = null;
|
|
51418
|
+
}
|
|
51419
|
+
}
|
|
51420
|
+
};
|
|
51421
|
+
}
|
|
51422
|
+
function nationalDigitsFromE164(e164) {
|
|
51423
|
+
const digits = (e164 ?? "").replace(/\D/g, "");
|
|
51424
|
+
if (digits.startsWith("55") && (digits.length === 12 || digits.length === 13)) {
|
|
51425
|
+
return digits.slice(2);
|
|
51426
|
+
}
|
|
51427
|
+
return e164.startsWith("+") ? `+${digits}` : digits;
|
|
51428
|
+
}
|
|
51144
51429
|
const DEFAULT_DIALER_DIMENSIONS = { width: 448, height: 640 };
|
|
51145
51430
|
const MIN_DIALER_WIDTH = 280;
|
|
51146
51431
|
const MIN_DIALER_HEIGHT = 420;
|
|
@@ -51344,6 +51629,17 @@ function FloatingDialer({
|
|
|
51344
51629
|
}
|
|
51345
51630
|
prevAuthRef.current = isAuthenticated;
|
|
51346
51631
|
}, [isAuthenticated]);
|
|
51632
|
+
useEffect(() => {
|
|
51633
|
+
const onClickToCall = (event) => {
|
|
51634
|
+
const task = event.detail;
|
|
51635
|
+
setIsOpen(true);
|
|
51636
|
+
if (task == null ? void 0 : task.phone) {
|
|
51637
|
+
updateDialValue(nationalDigitsFromE164(task.phone).slice(0, MAX_DIAL_LENGTH));
|
|
51638
|
+
}
|
|
51639
|
+
};
|
|
51640
|
+
window.addEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
51641
|
+
return () => window.removeEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
51642
|
+
}, [updateDialValue]);
|
|
51347
51643
|
const prevLoginSignalRef = useRef(false);
|
|
51348
51644
|
useEffect(() => {
|
|
51349
51645
|
const hasLoginSignal = !isAuthenticated && Boolean(loginConfirmation || sessionError);
|
|
@@ -51845,7 +52141,8 @@ function AuthenticatedDialer({
|
|
|
51845
52141
|
typeof window !== "undefined" ? window.innerWidth <= 640 : false
|
|
51846
52142
|
);
|
|
51847
52143
|
const isMobileVariant = variant === "mobile";
|
|
51848
|
-
const
|
|
52144
|
+
const inputProfile = useInputProfile();
|
|
52145
|
+
const isMobileLayout = isMobileVariant || isMobileViewport && inputProfile.touchLike;
|
|
51849
52146
|
const breaks = useSignal(operator == null ? void 0 : operator.breaks) || [];
|
|
51850
52147
|
const { goOnBreak, goOffBreak } = useOperatorBreak();
|
|
51851
52148
|
const sanitizedDialValue = useMemo(() => dialValue.slice(0, MAX_DIAL_LENGTH), [dialValue]);
|
|
@@ -51879,11 +52176,16 @@ function AuthenticatedDialer({
|
|
|
51879
52176
|
[becomeAvailable]
|
|
51880
52177
|
);
|
|
51881
52178
|
useEffect(() => {
|
|
51882
|
-
if (
|
|
51883
|
-
|
|
51884
|
-
void requestAvailability("Nao foi possivel ficar disponivel automaticamente.");
|
|
52179
|
+
if (hasRequestedAvailabilityRef.current) {
|
|
52180
|
+
return;
|
|
51885
52181
|
}
|
|
51886
|
-
|
|
52182
|
+
hasRequestedAvailabilityRef.current = true;
|
|
52183
|
+
const busyStates = ["onBreak", "manualCallSetup", "manualCallRinging", "manualCallFailed", "callRinging", "callInProgress", "afterCall"];
|
|
52184
|
+
if (callState && busyStates.includes(callState)) {
|
|
52185
|
+
return;
|
|
52186
|
+
}
|
|
52187
|
+
void requestAvailability("Nao foi possivel ficar disponivel automaticamente.");
|
|
52188
|
+
}, [requestAvailability, callState]);
|
|
51887
52189
|
useEffect(() => {
|
|
51888
52190
|
if (callState === "idle") {
|
|
51889
52191
|
setAvailabilityError(null);
|
|
@@ -51968,8 +52270,14 @@ function AuthenticatedDialer({
|
|
|
51968
52270
|
}, 8e3);
|
|
51969
52271
|
return () => window.clearTimeout(timer);
|
|
51970
52272
|
}, [callState]);
|
|
52273
|
+
const normalizedNumberRef = useRef(normalizedNumber);
|
|
52274
|
+
normalizedNumberRef.current = normalizedNumber;
|
|
51971
52275
|
useEffect(() => {
|
|
51972
52276
|
if (callState === "manualCallRinging" || callState === "callInProgress") {
|
|
52277
|
+
const dialed = normalizedNumberRef.current;
|
|
52278
|
+
if (dialed) {
|
|
52279
|
+
setLastDialedNumber((previous) => previous ?? dialed);
|
|
52280
|
+
}
|
|
51973
52281
|
setDialValue("");
|
|
51974
52282
|
}
|
|
51975
52283
|
if (callState === "idle") {
|
|
@@ -52368,6 +52676,16 @@ function AuthenticatedDialer({
|
|
|
52368
52676
|
return newValue;
|
|
52369
52677
|
});
|
|
52370
52678
|
}, [setDialValue, cursorPosition]);
|
|
52679
|
+
useEffect(() => {
|
|
52680
|
+
const onClickToCall = (event) => {
|
|
52681
|
+
const task = event.detail;
|
|
52682
|
+
if (!(task == null ? void 0 : task.phone)) return;
|
|
52683
|
+
setCallError(null);
|
|
52684
|
+
setLastDialedNumber(task.phone);
|
|
52685
|
+
};
|
|
52686
|
+
window.addEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
52687
|
+
return () => window.removeEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
52688
|
+
}, []);
|
|
52371
52689
|
const handleCall = useCallback(async () => {
|
|
52372
52690
|
if (!isIdle && !isOnBreak) {
|
|
52373
52691
|
return;
|
|
@@ -54056,30 +54374,65 @@ function historyPhoneDigits(item) {
|
|
|
54056
54374
|
}
|
|
54057
54375
|
return digits;
|
|
54058
54376
|
}
|
|
54377
|
+
function normalizeSearchText(value) {
|
|
54378
|
+
return (value ?? "").toString().normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
54379
|
+
}
|
|
54380
|
+
function classifyHistoryQuery(query) {
|
|
54381
|
+
const raw = (query ?? "").trim();
|
|
54382
|
+
if (!raw) {
|
|
54383
|
+
return { kind: "empty", digits: "", text: "" };
|
|
54384
|
+
}
|
|
54385
|
+
const digits = onlyDigits(raw);
|
|
54386
|
+
const nonPhoneChars = raw.replace(/[\d\s()+\-.]/g, "");
|
|
54387
|
+
if (digits.length >= 3 && nonPhoneChars.length === 0) {
|
|
54388
|
+
return { kind: "phone", digits, text: normalizeSearchText(raw) };
|
|
54389
|
+
}
|
|
54390
|
+
return { kind: "text", digits, text: normalizeSearchText(raw) };
|
|
54391
|
+
}
|
|
54392
|
+
function historySearchHaystack(item) {
|
|
54393
|
+
const parts = [
|
|
54394
|
+
item.formattedPhone,
|
|
54395
|
+
historyPhoneDigits(item),
|
|
54396
|
+
item.callTypeLabel,
|
|
54397
|
+
item.campaignName,
|
|
54398
|
+
item.contactLabel,
|
|
54399
|
+
item.qualificationName,
|
|
54400
|
+
item.failureCauseLabel,
|
|
54401
|
+
item.hangupCauseLabel,
|
|
54402
|
+
item.formattedDate,
|
|
54403
|
+
item.note,
|
|
54404
|
+
item.protocol !== void 0 ? String(item.protocol) : void 0
|
|
54405
|
+
];
|
|
54406
|
+
if (item.fields) {
|
|
54407
|
+
for (const value of Object.values(item.fields)) {
|
|
54408
|
+
if (value !== void 0 && value !== null) {
|
|
54409
|
+
parts.push(String(value));
|
|
54410
|
+
}
|
|
54411
|
+
}
|
|
54412
|
+
}
|
|
54413
|
+
return normalizeSearchText(parts.filter(Boolean).join(" | "));
|
|
54414
|
+
}
|
|
54415
|
+
function itemMatchesHistoryQuery(item, query) {
|
|
54416
|
+
if (query.kind === "empty") {
|
|
54417
|
+
return true;
|
|
54418
|
+
}
|
|
54419
|
+
if (query.kind === "phone") {
|
|
54420
|
+
return historyPhoneDigits(item).includes(query.digits) || onlyDigits(item.phoneNumber).includes(query.digits) || item.protocol !== void 0 && String(item.protocol).includes(query.digits);
|
|
54421
|
+
}
|
|
54422
|
+
const haystack = historySearchHaystack(item);
|
|
54423
|
+
const terms = query.text.split(" ").filter(Boolean);
|
|
54424
|
+
return terms.every((term) => haystack.includes(term));
|
|
54425
|
+
}
|
|
54426
|
+
function filterHistoryItems(items, query) {
|
|
54427
|
+
const parsed = typeof query === "string" ? classifyHistoryQuery(query) : query;
|
|
54428
|
+
if (parsed.kind === "empty") {
|
|
54429
|
+
return items;
|
|
54430
|
+
}
|
|
54431
|
+
return items.filter((item) => itemMatchesHistoryQuery(item, parsed));
|
|
54432
|
+
}
|
|
54059
54433
|
const DEFAULT_QUALIFICATION = "chamada sem qualificação";
|
|
54434
|
+
const SEARCH_DEBOUNCE_MS = 350;
|
|
54060
54435
|
const DETAILS_TITLE = "Ver detalhes da chamada";
|
|
54061
|
-
async function fetchJson(url, headers) {
|
|
54062
|
-
const response = await fetch(url, { method: "GET", headers, credentials: "omit" });
|
|
54063
|
-
if (!response.ok) {
|
|
54064
|
-
const body = await response.json().catch(() => ({}));
|
|
54065
|
-
throw new Error(body.error || `Erro ${response.status}`);
|
|
54066
|
-
}
|
|
54067
|
-
return await response.json();
|
|
54068
|
-
}
|
|
54069
|
-
async function fetchCampaignForm(apiBaseUrl, contactId, headers) {
|
|
54070
|
-
const config = await fetchJson(`${apiBaseUrl}/api/campaign-config/${contactId}`, headers);
|
|
54071
|
-
if (!(config == null ? void 0 : config.campaignModelId)) {
|
|
54072
|
-
throw new Error("Formulário da campanha não encontrado");
|
|
54073
|
-
}
|
|
54074
|
-
const [fields, values] = await Promise.all([
|
|
54075
|
-
fetchJson(`${apiBaseUrl}/api/campaign-fields/${config.campaignModelId}`, headers),
|
|
54076
|
-
fetchJson(`${apiBaseUrl}/api/campaign-contact/${contactId}`, headers)
|
|
54077
|
-
]);
|
|
54078
|
-
return {
|
|
54079
|
-
rows: Array.isArray(fields == null ? void 0 : fields.rows) ? fields.rows.filter((row) => Array.isArray(row) && row.length > 0) : [],
|
|
54080
|
-
values: values && typeof values === "object" ? values : {}
|
|
54081
|
-
};
|
|
54082
|
-
}
|
|
54083
54436
|
function useRecordings(apiBaseUrl, getAuthHeaders2) {
|
|
54084
54437
|
const [states, setStates] = useState({});
|
|
54085
54438
|
const statesRef = useRef(states);
|
|
@@ -54335,7 +54688,7 @@ function CallDetailsSheet({
|
|
|
54335
54688
|
onCall,
|
|
54336
54689
|
onWhatsApp
|
|
54337
54690
|
}) {
|
|
54338
|
-
const [form, setForm] = useState({ status: "idle",
|
|
54691
|
+
const [form, setForm] = useState({ status: "idle", form: null });
|
|
54339
54692
|
const closeButtonRef = useRef(null);
|
|
54340
54693
|
const isCampaign = item.callType === "campaign";
|
|
54341
54694
|
useEffect(() => {
|
|
@@ -54361,65 +54714,79 @@ function CallDetailsSheet({
|
|
|
54361
54714
|
}, [onClose]);
|
|
54362
54715
|
useEffect(() => {
|
|
54363
54716
|
if (!isCampaign || !item.campaignContactId) {
|
|
54364
|
-
setForm({ status: "idle",
|
|
54717
|
+
setForm({ status: "idle", form: null });
|
|
54365
54718
|
return;
|
|
54366
54719
|
}
|
|
54367
54720
|
let cancelled = false;
|
|
54368
|
-
setForm({ status: "loading",
|
|
54369
|
-
fetchCampaignForm(
|
|
54721
|
+
setForm({ status: "loading", form: null });
|
|
54722
|
+
fetchCampaignForm(
|
|
54723
|
+
{
|
|
54724
|
+
source: "campaign",
|
|
54725
|
+
id: item.campaignContactId,
|
|
54726
|
+
campaignId: item.campaignId ?? null,
|
|
54727
|
+
signature: item.formSignature ?? null,
|
|
54728
|
+
expiresAt: item.formExpiresAt ?? null
|
|
54729
|
+
},
|
|
54730
|
+
{ apiBaseUrl, headers: getAuthHeaders2(), retries: 0 }
|
|
54731
|
+
).then((result2) => {
|
|
54370
54732
|
if (!cancelled) {
|
|
54371
|
-
setForm({ status: "ready",
|
|
54733
|
+
setForm({ status: "ready", form: result2 });
|
|
54372
54734
|
}
|
|
54373
54735
|
}).catch((error2) => {
|
|
54374
54736
|
if (!cancelled) {
|
|
54375
54737
|
console.warn("[CallHistoryList] Formulário da campanha indisponível, usando campos do histórico:", error2);
|
|
54376
|
-
setForm({
|
|
54377
|
-
status: "error",
|
|
54378
|
-
rows: [],
|
|
54379
|
-
values: {},
|
|
54380
|
-
error: error2 instanceof Error ? error2.message : "Erro ao carregar formulário"
|
|
54381
|
-
});
|
|
54738
|
+
setForm({ status: "error", form: null, error: error2 instanceof Error ? error2.message : "Erro ao carregar formulário" });
|
|
54382
54739
|
}
|
|
54383
54740
|
});
|
|
54384
54741
|
return () => {
|
|
54385
54742
|
cancelled = true;
|
|
54386
54743
|
};
|
|
54387
|
-
}, [apiBaseUrl, getAuthHeaders2, isCampaign, item.campaignContactId, item.id]);
|
|
54744
|
+
}, [apiBaseUrl, getAuthHeaders2, isCampaign, item.campaignContactId, item.campaignId, item.id]);
|
|
54388
54745
|
const fallbackFields = useMemo(
|
|
54389
54746
|
() => Object.entries(item.fields ?? {}).filter(
|
|
54390
54747
|
([key, value]) => value !== void 0 && value !== null && String(value).trim() !== "" && !isInternalFieldKey(key)
|
|
54391
54748
|
),
|
|
54392
54749
|
[item.fields]
|
|
54393
54750
|
);
|
|
54751
|
+
const fallbackByKey = useMemo(() => {
|
|
54752
|
+
const map = /* @__PURE__ */ new Map();
|
|
54753
|
+
for (const [key, value] of Object.entries(item.fields ?? {})) {
|
|
54754
|
+
if (value === void 0 || value === null || String(value).trim() === "") continue;
|
|
54755
|
+
map.set(stripAccents(normalizeFormKey(key)), String(value));
|
|
54756
|
+
}
|
|
54757
|
+
return map;
|
|
54758
|
+
}, [item.fields]);
|
|
54394
54759
|
const resolveFieldValue = (field) => {
|
|
54395
|
-
|
|
54396
|
-
|
|
54397
|
-
if (byCode !== void 0 && byCode !== null && String(byCode).trim() !== "") {
|
|
54398
|
-
return String(byCode);
|
|
54399
|
-
}
|
|
54400
|
-
const byName = (_a2 = item.fields) == null ? void 0 : _a2[field.name];
|
|
54401
|
-
if (byName !== void 0 && byName !== null && String(byName).trim() !== "") {
|
|
54402
|
-
return String(byName);
|
|
54760
|
+
if (field.value && field.value.trim() !== "") {
|
|
54761
|
+
return field.value;
|
|
54403
54762
|
}
|
|
54404
|
-
|
|
54763
|
+
const byName = fallbackByKey.get(stripAccents(normalizeFormKey(field.label))) ?? fallbackByKey.get(stripAccents(normalizeFormKey(field.key)));
|
|
54764
|
+
return byName ?? "-";
|
|
54405
54765
|
};
|
|
54406
|
-
const
|
|
54766
|
+
const formRows = form.status === "ready" && form.form ? form.form.rows && form.form.rows.length > 0 ? form.form.rows : form.form.fields.length > 0 ? [form.form.fields] : [] : [];
|
|
54767
|
+
const hasFormRows = formRows.length > 0;
|
|
54407
54768
|
let formContent;
|
|
54408
|
-
if (form.status === "loading") {
|
|
54769
|
+
if (form.status === "loading" && fallbackFields.length === 0) {
|
|
54409
54770
|
formContent = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "details-loading", role: "status", children: [
|
|
54410
54771
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-spinner fa-spin", "aria-hidden": "true" }),
|
|
54411
54772
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Carregando formulário..." })
|
|
54412
54773
|
] });
|
|
54413
54774
|
} else if (hasFormRows) {
|
|
54414
|
-
formContent =
|
|
54415
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-field-label", title: field.
|
|
54775
|
+
formContent = formRows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-form-row", children: row.map((field, fieldIndex) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "details-field", children: [
|
|
54776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-field-label", title: field.label, children: field.label }),
|
|
54416
54777
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-field-value", children: resolveFieldValue(field) })
|
|
54417
|
-
] }, `${rowIndex}-${fieldIndex}-${field.
|
|
54778
|
+
] }, `${rowIndex}-${fieldIndex}-${field.key}`)) }, rowIndex));
|
|
54418
54779
|
} else if (fallbackFields.length > 0) {
|
|
54419
|
-
formContent = /* @__PURE__ */ jsxRuntimeExports.
|
|
54420
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
54421
|
-
|
|
54422
|
-
|
|
54780
|
+
formContent = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
54781
|
+
form.status === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "details-loading details-loading-inline", role: "status", children: [
|
|
54782
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-spinner fa-spin", "aria-hidden": "true" }),
|
|
54783
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Atualizando formulário..." })
|
|
54784
|
+
] }),
|
|
54785
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-form-row", children: fallbackFields.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "details-field", children: [
|
|
54786
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-field-label", title: key, children: key }),
|
|
54787
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "details-field-value", children: value })
|
|
54788
|
+
] }, key)) })
|
|
54789
|
+
] });
|
|
54423
54790
|
} else {
|
|
54424
54791
|
formContent = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "details-empty", children: [
|
|
54425
54792
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-user", "aria-hidden": "true" }),
|
|
@@ -54528,12 +54895,52 @@ function CallHistoryList({
|
|
|
54528
54895
|
onCall,
|
|
54529
54896
|
onWhatsApp,
|
|
54530
54897
|
apiBaseUrl,
|
|
54531
|
-
getAuthHeaders: getAuthHeaders2
|
|
54898
|
+
getAuthHeaders: getAuthHeaders2,
|
|
54899
|
+
query,
|
|
54900
|
+
onQueryChange,
|
|
54901
|
+
isSearching = false,
|
|
54902
|
+
searchHint = null
|
|
54532
54903
|
}) {
|
|
54533
54904
|
const [openPlayerId, setOpenPlayerId] = useState(null);
|
|
54534
54905
|
const [selectedId, setSelectedId] = useState(null);
|
|
54535
54906
|
const recordings = useRecordings(apiBaseUrl, getAuthHeaders2);
|
|
54536
54907
|
const { retain } = recordings;
|
|
54908
|
+
const [draft, setDraft] = useState(query ?? "");
|
|
54909
|
+
const lastEmittedRef = useRef(query ?? "");
|
|
54910
|
+
const debounceRef = useRef(null);
|
|
54911
|
+
useEffect(() => {
|
|
54912
|
+
const external = query ?? "";
|
|
54913
|
+
if (external !== lastEmittedRef.current) {
|
|
54914
|
+
lastEmittedRef.current = external;
|
|
54915
|
+
setDraft(external);
|
|
54916
|
+
}
|
|
54917
|
+
}, [query]);
|
|
54918
|
+
useEffect(() => {
|
|
54919
|
+
return () => {
|
|
54920
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
54921
|
+
};
|
|
54922
|
+
}, []);
|
|
54923
|
+
const handleDraftChange = useCallback(
|
|
54924
|
+
(value) => {
|
|
54925
|
+
setDraft(value);
|
|
54926
|
+
if (!onQueryChange) return;
|
|
54927
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
54928
|
+
debounceRef.current = setTimeout(() => {
|
|
54929
|
+
lastEmittedRef.current = value;
|
|
54930
|
+
onQueryChange(value);
|
|
54931
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
54932
|
+
},
|
|
54933
|
+
[onQueryChange]
|
|
54934
|
+
);
|
|
54935
|
+
const clearSearch = useCallback(() => {
|
|
54936
|
+
setDraft("");
|
|
54937
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
54938
|
+
lastEmittedRef.current = "";
|
|
54939
|
+
onQueryChange == null ? void 0 : onQueryChange("");
|
|
54940
|
+
}, [onQueryChange]);
|
|
54941
|
+
const parsedQuery = useMemo(() => classifyHistoryQuery(draft), [draft]);
|
|
54942
|
+
const visibleItems = useMemo(() => filterHistoryItems(items, parsedQuery), [items, parsedQuery]);
|
|
54943
|
+
const hasQuery = parsedQuery.kind !== "empty";
|
|
54537
54944
|
const dayLabels = useMemo(() => {
|
|
54538
54945
|
const now = /* @__PURE__ */ new Date();
|
|
54539
54946
|
const labels = {};
|
|
@@ -54583,6 +54990,28 @@ function CallHistoryList({
|
|
|
54583
54990
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "header-title", children: "Recentes" }),
|
|
54584
54991
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "history-refresh-btn", onClick: onRefresh, disabled: isLoading, "aria-label": "Atualizar histórico", children: /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: `fas fa-arrows-rotate ${isLoading ? "fa-spin" : ""}`, "aria-hidden": "true" }) })
|
|
54585
54992
|
] }),
|
|
54993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "history-search-bar", children: [
|
|
54994
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "history-search", children: [
|
|
54995
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-magnifying-glass history-search-icon", "aria-hidden": "true" }),
|
|
54996
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
54997
|
+
"input",
|
|
54998
|
+
{
|
|
54999
|
+
type: "search",
|
|
55000
|
+
className: "history-search-input",
|
|
55001
|
+
placeholder: "Buscar número, campanha, cliente...",
|
|
55002
|
+
"aria-label": "Buscar no histórico",
|
|
55003
|
+
autoComplete: "off",
|
|
55004
|
+
autoCapitalize: "none",
|
|
55005
|
+
autoCorrect: "off",
|
|
55006
|
+
spellCheck: false,
|
|
55007
|
+
value: draft,
|
|
55008
|
+
onChange: (event) => handleDraftChange(event.target.value)
|
|
55009
|
+
}
|
|
55010
|
+
),
|
|
55011
|
+
isSearching ? /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-spinner fa-spin history-search-spinner", "aria-hidden": "true", title: "Buscando..." }) : draft ? /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "history-search-clear", onClick: clearSearch, "aria-label": "Limpar busca", children: /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-xmark", "aria-hidden": "true" }) }) : null
|
|
55012
|
+
] }),
|
|
55013
|
+
hasQuery && searchHint && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "history-search-hint", children: searchHint })
|
|
55014
|
+
] }),
|
|
54586
55015
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "call-history-list", id: "callHistoryList", children: isLoading && items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "history-loading", role: "status", children: [
|
|
54587
55016
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-spinner fa-spin", "aria-hidden": "true" }),
|
|
54588
55017
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Carregando..." })
|
|
@@ -54593,7 +55022,18 @@ function CallHistoryList({
|
|
|
54593
55022
|
] }) : items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "history-empty", children: [
|
|
54594
55023
|
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-phone-slash", "aria-hidden": "true" }),
|
|
54595
55024
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Nenhuma ligação recente" })
|
|
54596
|
-
] }) :
|
|
55025
|
+
] }) : visibleItems.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "history-empty history-empty-search", children: [
|
|
55026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: "fas fa-magnifying-glass", "aria-hidden": "true" }),
|
|
55027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
55028
|
+
"Nenhuma chamada encontrada para ",
|
|
55029
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
55030
|
+
"“",
|
|
55031
|
+
draft.trim(),
|
|
55032
|
+
"”"
|
|
55033
|
+
] })
|
|
55034
|
+
] }),
|
|
55035
|
+
isSearching && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "history-search-status", children: "Buscando no servidor..." })
|
|
55036
|
+
] }) : visibleItems.map((item) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
54597
55037
|
HistoryRow,
|
|
54598
55038
|
{
|
|
54599
55039
|
item,
|
|
@@ -56061,9 +56501,55 @@ function DebugPanel({ onClose }) {
|
|
|
56061
56501
|
] });
|
|
56062
56502
|
}
|
|
56063
56503
|
const VIEWPORT_MARGIN$1 = 16;
|
|
56504
|
+
const BASE_WIDTH = 520;
|
|
56505
|
+
const FALLBACK_HEIGHT = 600;
|
|
56506
|
+
const FORM_SCALE_STORAGE_KEY = "callix_dialer_form_scale";
|
|
56507
|
+
const FORM_SCALE_MIN = 70;
|
|
56508
|
+
const FORM_SCALE_MAX = 180;
|
|
56509
|
+
const FORM_SCALE_STEP = 10;
|
|
56510
|
+
const FORM_SCALE_DEFAULT = 100;
|
|
56511
|
+
const CONTROL_MIN_PX = 28;
|
|
56512
|
+
const CONTROL_BUTTON_CLASS = "flex flex-shrink-0 items-center justify-center rounded-md transition hover:bg-black hover:bg-opacity-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white";
|
|
56513
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
56064
56514
|
function clamp$1(value, min2, max2) {
|
|
56065
56515
|
return Math.min(Math.max(value, min2), max2);
|
|
56066
56516
|
}
|
|
56517
|
+
function clampFormScale(percent) {
|
|
56518
|
+
if (!Number.isFinite(percent)) return FORM_SCALE_DEFAULT;
|
|
56519
|
+
const rounded = Math.round(percent / FORM_SCALE_STEP) * FORM_SCALE_STEP;
|
|
56520
|
+
return clamp$1(rounded, FORM_SCALE_MIN, FORM_SCALE_MAX);
|
|
56521
|
+
}
|
|
56522
|
+
function readStoredFormScale() {
|
|
56523
|
+
if (typeof window === "undefined") return FORM_SCALE_DEFAULT;
|
|
56524
|
+
try {
|
|
56525
|
+
const raw = window.localStorage.getItem(FORM_SCALE_STORAGE_KEY);
|
|
56526
|
+
if (raw === null || raw.trim() === "") return FORM_SCALE_DEFAULT;
|
|
56527
|
+
return clampFormScale(Number(raw));
|
|
56528
|
+
} catch {
|
|
56529
|
+
return FORM_SCALE_DEFAULT;
|
|
56530
|
+
}
|
|
56531
|
+
}
|
|
56532
|
+
function storeFormScale(percent) {
|
|
56533
|
+
try {
|
|
56534
|
+
window.localStorage.setItem(FORM_SCALE_STORAGE_KEY, String(percent));
|
|
56535
|
+
} catch {
|
|
56536
|
+
}
|
|
56537
|
+
}
|
|
56538
|
+
function detectZoomSupport() {
|
|
56539
|
+
if (typeof CSS === "undefined" || typeof CSS.supports !== "function") return true;
|
|
56540
|
+
try {
|
|
56541
|
+
if (!CSS.supports("zoom", "1.5")) return false;
|
|
56542
|
+
} catch {
|
|
56543
|
+
return true;
|
|
56544
|
+
}
|
|
56545
|
+
const firefox = typeof navigator !== "undefined" ? /\bFirefox\/(\d+)/.exec(navigator.userAgent) : null;
|
|
56546
|
+
if (firefox && Number(firefox[1]) < 131) return false;
|
|
56547
|
+
return true;
|
|
56548
|
+
}
|
|
56549
|
+
function readViewport() {
|
|
56550
|
+
if (typeof window === "undefined") return { width: 1024, height: 768 };
|
|
56551
|
+
return { width: window.innerWidth, height: window.innerHeight };
|
|
56552
|
+
}
|
|
56067
56553
|
function formatDuration(seconds) {
|
|
56068
56554
|
const hrs = Math.floor(seconds / 3600);
|
|
56069
56555
|
const mins = Math.floor(seconds % 3600 / 60);
|
|
@@ -56073,147 +56559,91 @@ function formatDuration(seconds) {
|
|
|
56073
56559
|
}
|
|
56074
56560
|
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
56075
56561
|
}
|
|
56076
|
-
|
|
56077
|
-
|
|
56078
|
-
|
|
56079
|
-
|
|
56080
|
-
|
|
56081
|
-
|
|
56082
|
-
const response = await fetch(url, options);
|
|
56083
|
-
const duration = Date.now() - startTime;
|
|
56084
|
-
console.log(`[DraggableClientInfoModal] ⏱️ Resposta em ${duration}ms - Status: ${response.status}`);
|
|
56085
|
-
if (!response.ok) {
|
|
56086
|
-
if (response.status >= 400 && response.status < 500) {
|
|
56087
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
56088
|
-
console.error(`[DraggableClientInfoModal] ❌ Erro do cliente (${response.status}):`, error2);
|
|
56089
|
-
throw new Error(error2.error || `Falha: ${response.status}`);
|
|
56090
|
-
}
|
|
56091
|
-
console.warn(`[DraggableClientInfoModal] ⚠️ Erro do servidor (${response.status}), tentando novamente...`);
|
|
56092
|
-
throw new Error(`HTTP ${response.status}`);
|
|
56093
|
-
}
|
|
56094
|
-
const json = await response.json();
|
|
56095
|
-
console.log(`[DraggableClientInfoModal] ✅ Dados recebidos com sucesso`);
|
|
56096
|
-
return json;
|
|
56097
|
-
} catch (error2) {
|
|
56098
|
-
const isLastAttempt = i2 === retries - 1;
|
|
56099
|
-
if (isLastAttempt) {
|
|
56100
|
-
console.error(`[DraggableClientInfoModal] 💥 Falha final após ${retries} tentativas:`, error2);
|
|
56101
|
-
throw error2;
|
|
56102
|
-
}
|
|
56103
|
-
const delay = backoff * Math.pow(2, i2);
|
|
56104
|
-
console.warn(`[DraggableClientInfoModal] ⏳ Aguardando ${delay}ms antes da próxima tentativa...`);
|
|
56105
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
56106
|
-
}
|
|
56107
|
-
}
|
|
56108
|
-
throw new Error("Todas as tentativas falharam");
|
|
56109
|
-
}
|
|
56110
|
-
async function getCampaignConfig$1(contactId) {
|
|
56111
|
-
const url = `${API_BASE_URL}/api/campaign-config/${contactId}`;
|
|
56112
|
-
return fetchWithRetry(url, {
|
|
56113
|
-
method: "GET",
|
|
56114
|
-
headers: getAuthHeaders(),
|
|
56115
|
-
credentials: "omit"
|
|
56116
|
-
});
|
|
56117
|
-
}
|
|
56118
|
-
async function getCampaignFields(campaignModelId) {
|
|
56119
|
-
const url = `${API_BASE_URL}/api/campaign-fields/${campaignModelId}`;
|
|
56120
|
-
const json = await fetchWithRetry(url, {
|
|
56121
|
-
method: "GET",
|
|
56122
|
-
headers: getAuthHeaders(),
|
|
56123
|
-
credentials: "omit"
|
|
56124
|
-
});
|
|
56125
|
-
console.log("[DraggableClientInfoModal] Estrutura de campos recebida:", json);
|
|
56126
|
-
if (!json.rows || !Array.isArray(json.rows)) {
|
|
56127
|
-
console.warn("[DraggableClientInfoModal] Estrutura de campos inválida, usando fallback");
|
|
56128
|
-
return {
|
|
56129
|
-
rows: [],
|
|
56130
|
-
labelField: null,
|
|
56131
|
-
phoneFields: []
|
|
56132
|
-
};
|
|
56133
|
-
}
|
|
56134
|
-
return json;
|
|
56135
|
-
}
|
|
56136
|
-
async function getCustomerFields(formId) {
|
|
56137
|
-
const url = `${API_BASE_URL}/api/campaign-contact/0?source=customer&formId=${encodeURIComponent(String(formId))}`;
|
|
56138
|
-
const json = await fetchWithRetry(url, {
|
|
56139
|
-
method: "GET",
|
|
56140
|
-
headers: getAuthHeaders(),
|
|
56141
|
-
credentials: "omit"
|
|
56142
|
-
});
|
|
56143
|
-
console.log("[DraggableClientInfoModal] (cliente) Estrutura de campos recebida:", json);
|
|
56144
|
-
if (!json.rows || !Array.isArray(json.rows)) {
|
|
56145
|
-
console.warn("[DraggableClientInfoModal] (cliente) Estrutura de campos inválida, usando fallback");
|
|
56146
|
-
return { rows: [], labelField: null, phoneFields: [] };
|
|
56147
|
-
}
|
|
56148
|
-
return json;
|
|
56149
|
-
}
|
|
56150
|
-
async function getContactValues$1(contactId) {
|
|
56151
|
-
const url = `${API_BASE_URL}/api/campaign-contact/${contactId}`;
|
|
56152
|
-
return fetchWithRetry(url, {
|
|
56153
|
-
method: "GET",
|
|
56154
|
-
headers: getAuthHeaders(),
|
|
56155
|
-
credentials: "omit"
|
|
56156
|
-
});
|
|
56157
|
-
}
|
|
56158
|
-
async function getCustomerContactValues(customerId) {
|
|
56159
|
-
const url = `${API_BASE_URL}/api/campaign-fields/0?source=customer&customerId=${encodeURIComponent(String(customerId))}`;
|
|
56160
|
-
return fetchWithRetry(url, {
|
|
56161
|
-
method: "GET",
|
|
56162
|
-
headers: getAuthHeaders(),
|
|
56163
|
-
credentials: "omit"
|
|
56164
|
-
});
|
|
56562
|
+
function gridColsFor(count) {
|
|
56563
|
+
if (count === 2) return "grid-cols-2";
|
|
56564
|
+
if (count === 3) return "grid-cols-3";
|
|
56565
|
+
if (count === 4) return "grid-cols-4";
|
|
56566
|
+
if (count >= 5) return "grid-cols-5";
|
|
56567
|
+
return "grid-cols-1";
|
|
56165
56568
|
}
|
|
56166
56569
|
function DraggableClientInfoModal({
|
|
56167
56570
|
isOpen,
|
|
56168
56571
|
campaignCallInfo,
|
|
56572
|
+
campaignContactPhoneId,
|
|
56169
56573
|
callDuration,
|
|
56170
56574
|
isCallActive,
|
|
56171
|
-
onClose
|
|
56575
|
+
onClose,
|
|
56576
|
+
portalTarget
|
|
56172
56577
|
}) {
|
|
56173
56578
|
const containerRef = useRef(null);
|
|
56174
56579
|
const pointerRef = useRef({ pointerId: null, offsetX: 0, offsetY: 0 });
|
|
56175
56580
|
const dragMovedRef = useRef(false);
|
|
56581
|
+
const focusWithinRef = useRef(false);
|
|
56582
|
+
const previouslyFocusedRef = useRef(null);
|
|
56583
|
+
const titleId = useId();
|
|
56176
56584
|
const [position2, setPosition] = useState({ x: 100, y: 100 });
|
|
56177
56585
|
const [isDragging, setIsDragging] = useState(false);
|
|
56178
|
-
const [
|
|
56179
|
-
const
|
|
56586
|
+
const [viewport, setViewport] = useState(readViewport);
|
|
56587
|
+
const zoomSupported = useMemo(detectZoomSupport, []);
|
|
56588
|
+
const [scalePercent, setScalePercent] = useState(readStoredFormScale);
|
|
56589
|
+
const [announcement, setAnnouncement] = useState("");
|
|
56590
|
+
const scale = zoomSupported ? scalePercent / 100 : 1;
|
|
56591
|
+
const scaleRef = useRef(scale);
|
|
56592
|
+
scaleRef.current = scale;
|
|
56593
|
+
const [form, setForm] = useState(null);
|
|
56180
56594
|
const [isLoading, setIsLoading] = useState(false);
|
|
56181
56595
|
const [error2, setError] = useState(null);
|
|
56182
|
-
const [
|
|
56596
|
+
const [retry, setRetry] = useState({ key: null, n: 0 });
|
|
56183
56597
|
const campaignContact = campaignCallInfo == null ? void 0 : campaignCallInfo.campaignContact;
|
|
56184
|
-
const
|
|
56185
|
-
|
|
56186
|
-
|
|
56187
|
-
|
|
56188
|
-
|
|
56189
|
-
|
|
56190
|
-
|
|
56191
|
-
|
|
56192
|
-
|
|
56193
|
-
|
|
56194
|
-
const
|
|
56195
|
-
const
|
|
56196
|
-
const maxY = Math.max(minY, viewportHeight - height - VIEWPORT_MARGIN$1);
|
|
56598
|
+
const request = useMemo(
|
|
56599
|
+
() => campaignFormRequestFromCallInfo(campaignCallInfo, campaignContactPhoneId),
|
|
56600
|
+
[campaignCallInfo, campaignContactPhoneId]
|
|
56601
|
+
);
|
|
56602
|
+
const requestKey = request ? campaignFormCacheKey(request) : null;
|
|
56603
|
+
const requestRef = useRef(request);
|
|
56604
|
+
requestRef.current = request;
|
|
56605
|
+
const partialRefreshKeyRef = useRef(null);
|
|
56606
|
+
const measure = useCallback(() => {
|
|
56607
|
+
var _a2;
|
|
56608
|
+
const rect = (_a2 = containerRef.current) == null ? void 0 : _a2.getBoundingClientRect();
|
|
56609
|
+
const currentScale = scaleRef.current;
|
|
56197
56610
|
return {
|
|
56198
|
-
|
|
56199
|
-
|
|
56611
|
+
width: rect && rect.width > 0 ? rect.width : BASE_WIDTH * currentScale,
|
|
56612
|
+
height: rect && rect.height > 0 ? rect.height : FALLBACK_HEIGHT * currentScale
|
|
56200
56613
|
};
|
|
56201
56614
|
}, []);
|
|
56202
|
-
|
|
56615
|
+
const clampPositionToViewport = useCallback(
|
|
56616
|
+
(proposed) => {
|
|
56617
|
+
if (typeof window === "undefined") {
|
|
56618
|
+
return proposed;
|
|
56619
|
+
}
|
|
56620
|
+
const { width, height } = measure();
|
|
56621
|
+
const minX = VIEWPORT_MARGIN$1;
|
|
56622
|
+
const minY = VIEWPORT_MARGIN$1;
|
|
56623
|
+
const maxX = Math.max(minX, window.innerWidth - width - VIEWPORT_MARGIN$1);
|
|
56624
|
+
const maxY = Math.max(minY, window.innerHeight - height - VIEWPORT_MARGIN$1);
|
|
56625
|
+
return {
|
|
56626
|
+
x: clamp$1(proposed.x, minX, maxX),
|
|
56627
|
+
y: clamp$1(proposed.y, minY, maxY)
|
|
56628
|
+
};
|
|
56629
|
+
},
|
|
56630
|
+
[measure]
|
|
56631
|
+
);
|
|
56632
|
+
useIsomorphicLayoutEffect(() => {
|
|
56203
56633
|
if (isOpen && typeof window !== "undefined") {
|
|
56204
|
-
|
|
56205
|
-
const width = (
|
|
56206
|
-
const height = (element == null ? void 0 : element.offsetHeight) ?? 600;
|
|
56634
|
+
setViewport(readViewport());
|
|
56635
|
+
const { width, height } = measure();
|
|
56207
56636
|
const centerX = (window.innerWidth - width) / 2;
|
|
56208
56637
|
const centerY = (window.innerHeight - height) / 2;
|
|
56209
56638
|
setPosition(clampPositionToViewport({ x: centerX, y: centerY }));
|
|
56210
56639
|
}
|
|
56211
|
-
}, [isOpen, clampPositionToViewport]);
|
|
56640
|
+
}, [isOpen, measure, clampPositionToViewport]);
|
|
56212
56641
|
useEffect(() => {
|
|
56213
56642
|
if (!isOpen || typeof window === "undefined") {
|
|
56214
56643
|
return;
|
|
56215
56644
|
}
|
|
56216
56645
|
const handleViewportChange = () => {
|
|
56646
|
+
setViewport(readViewport());
|
|
56217
56647
|
setPosition((prev) => clampPositionToViewport(prev));
|
|
56218
56648
|
};
|
|
56219
56649
|
window.addEventListener("resize", handleViewportChange);
|
|
@@ -56223,75 +56653,72 @@ function DraggableClientInfoModal({
|
|
|
56223
56653
|
window.removeEventListener("orientationchange", handleViewportChange);
|
|
56224
56654
|
};
|
|
56225
56655
|
}, [isOpen, clampPositionToViewport]);
|
|
56656
|
+
const keepInsideViewport = useCallback(() => {
|
|
56657
|
+
setPosition((prev) => {
|
|
56658
|
+
const next = clampPositionToViewport(prev);
|
|
56659
|
+
return next.x === prev.x && next.y === prev.y ? prev : next;
|
|
56660
|
+
});
|
|
56661
|
+
}, [clampPositionToViewport]);
|
|
56226
56662
|
useEffect(() => {
|
|
56227
|
-
if (!
|
|
56663
|
+
if (!isOpen) {
|
|
56228
56664
|
return;
|
|
56229
56665
|
}
|
|
56230
|
-
|
|
56666
|
+
keepInsideViewport();
|
|
56667
|
+
}, [isOpen, scalePercent, keepInsideViewport]);
|
|
56668
|
+
useEffect(() => {
|
|
56669
|
+
const element = containerRef.current;
|
|
56670
|
+
if (!isOpen || !element || typeof ResizeObserver === "undefined") {
|
|
56231
56671
|
return;
|
|
56232
56672
|
}
|
|
56233
|
-
|
|
56234
|
-
|
|
56235
|
-
|
|
56673
|
+
const observer = new ResizeObserver(() => keepInsideViewport());
|
|
56674
|
+
observer.observe(element);
|
|
56675
|
+
return () => observer.disconnect();
|
|
56676
|
+
}, [isOpen, keepInsideViewport]);
|
|
56677
|
+
useEffect(() => {
|
|
56678
|
+
const current = requestRef.current;
|
|
56679
|
+
if (!current || !requestKey) {
|
|
56680
|
+
setForm(null);
|
|
56236
56681
|
setError(null);
|
|
56237
|
-
|
|
56238
|
-
|
|
56239
|
-
|
|
56240
|
-
|
|
56241
|
-
|
|
56242
|
-
|
|
56243
|
-
|
|
56244
|
-
|
|
56245
|
-
|
|
56246
|
-
|
|
56247
|
-
|
|
56248
|
-
|
|
56249
|
-
|
|
56250
|
-
|
|
56251
|
-
|
|
56252
|
-
if (!config.campaignModelId) {
|
|
56253
|
-
throw new Error("campaignModelId não encontrado");
|
|
56254
|
-
}
|
|
56255
|
-
[campaignFields, contactValues] = await Promise.all([
|
|
56256
|
-
getCampaignFields(config.campaignModelId),
|
|
56257
|
-
getContactValues$1(campaignContact.id)
|
|
56258
|
-
]);
|
|
56259
|
-
}
|
|
56260
|
-
console.log("[DraggableClientInfoModal] Campos recebidos:", campaignFields);
|
|
56261
|
-
console.log("[DraggableClientInfoModal] Valores recebidos:", contactValues);
|
|
56262
|
-
if (!cancelled) {
|
|
56263
|
-
console.log("[DraggableClientInfoModal] ✅ Dados carregados com sucesso");
|
|
56264
|
-
setContactData(contactValues);
|
|
56265
|
-
setFieldRows(campaignFields.rows || []);
|
|
56266
|
-
setFetchedContactId(campaignContact.id);
|
|
56267
|
-
setIsLoading(false);
|
|
56268
|
-
}
|
|
56269
|
-
} catch (err) {
|
|
56270
|
-
if (!cancelled) {
|
|
56271
|
-
console.error("[DraggableClientInfoModal] ❌ Erro ao buscar dados:", err);
|
|
56272
|
-
const errorMessage = err instanceof Error ? err.message : "Erro ao buscar dados do contato";
|
|
56273
|
-
setError(errorMessage);
|
|
56274
|
-
setIsLoading(false);
|
|
56682
|
+
setIsLoading(false);
|
|
56683
|
+
return;
|
|
56684
|
+
}
|
|
56685
|
+
let cancelled = false;
|
|
56686
|
+
let refreshTimer = null;
|
|
56687
|
+
setIsLoading(true);
|
|
56688
|
+
setError(null);
|
|
56689
|
+
fetchCampaignForm(current, { force: retry.key === requestKey && retry.n > 0 }).then((result2) => {
|
|
56690
|
+
if (!cancelled) {
|
|
56691
|
+
console.log("[DraggableClientInfoModal] ✅ Formulário carregado:", result2.valuesSource, result2.layoutSource, result2.fields.length, "campos", result2.partial ? "(parcial)" : "");
|
|
56692
|
+
setForm(result2);
|
|
56693
|
+
setIsLoading(false);
|
|
56694
|
+
if (result2.partial && partialRefreshKeyRef.current !== requestKey) {
|
|
56695
|
+
partialRefreshKeyRef.current = requestKey;
|
|
56696
|
+
refreshTimer = setTimeout(() => setRetry((prev) => ({ key: requestKey, n: prev.n + 1 })), 3e3);
|
|
56275
56697
|
}
|
|
56276
56698
|
}
|
|
56277
|
-
}
|
|
56278
|
-
|
|
56699
|
+
}).catch((err) => {
|
|
56700
|
+
if (!cancelled) {
|
|
56701
|
+
console.error("[DraggableClientInfoModal] ❌ Erro ao buscar o formulário:", err);
|
|
56702
|
+
setForm(null);
|
|
56703
|
+
setError(err instanceof Error ? err.message : "Erro ao buscar dados do contato");
|
|
56704
|
+
setIsLoading(false);
|
|
56705
|
+
}
|
|
56706
|
+
});
|
|
56279
56707
|
return () => {
|
|
56280
56708
|
cancelled = true;
|
|
56709
|
+
if (refreshTimer) clearTimeout(refreshTimer);
|
|
56281
56710
|
};
|
|
56282
|
-
}, [
|
|
56711
|
+
}, [requestKey, retry]);
|
|
56283
56712
|
useEffect(() => {
|
|
56284
56713
|
if (!isDragging) {
|
|
56285
56714
|
return;
|
|
56286
56715
|
}
|
|
56287
56716
|
const handlePointerMove = (event) => {
|
|
56288
|
-
var _a2, _b;
|
|
56289
56717
|
if (pointerRef.current.pointerId !== event.pointerId) {
|
|
56290
56718
|
return;
|
|
56291
56719
|
}
|
|
56292
56720
|
dragMovedRef.current = true;
|
|
56293
|
-
const
|
|
56294
|
-
const modalHeight = ((_b = containerRef.current) == null ? void 0 : _b.offsetHeight) ?? 0;
|
|
56721
|
+
const { width: modalWidth, height: modalHeight } = measure();
|
|
56295
56722
|
const nextX = event.clientX - pointerRef.current.offsetX;
|
|
56296
56723
|
const nextY = event.clientY - pointerRef.current.offsetY;
|
|
56297
56724
|
const viewportWidth = typeof window !== "undefined" ? window.innerWidth : 0;
|
|
@@ -56314,19 +56741,32 @@ function DraggableClientInfoModal({
|
|
|
56314
56741
|
};
|
|
56315
56742
|
window.addEventListener("pointermove", handlePointerMove);
|
|
56316
56743
|
window.addEventListener("pointerup", handlePointerUp);
|
|
56744
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
56317
56745
|
return () => {
|
|
56318
56746
|
window.removeEventListener("pointermove", handlePointerMove);
|
|
56319
56747
|
window.removeEventListener("pointerup", handlePointerUp);
|
|
56748
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
56320
56749
|
};
|
|
56321
|
-
}, [isDragging]);
|
|
56750
|
+
}, [isDragging, measure]);
|
|
56322
56751
|
const beginDrag = useCallback((event) => {
|
|
56323
56752
|
if (event.button !== 0 && event.pointerType !== "touch") {
|
|
56324
56753
|
return;
|
|
56325
56754
|
}
|
|
56755
|
+
if (event.target instanceof Element && event.target.closest("button")) {
|
|
56756
|
+
return;
|
|
56757
|
+
}
|
|
56326
56758
|
const element = containerRef.current;
|
|
56327
56759
|
if (!element) {
|
|
56328
56760
|
return;
|
|
56329
56761
|
}
|
|
56762
|
+
event.preventDefault();
|
|
56763
|
+
const handle = event.currentTarget;
|
|
56764
|
+
if (typeof handle.setPointerCapture === "function") {
|
|
56765
|
+
try {
|
|
56766
|
+
handle.setPointerCapture(event.pointerId);
|
|
56767
|
+
} catch {
|
|
56768
|
+
}
|
|
56769
|
+
}
|
|
56330
56770
|
const rect = element.getBoundingClientRect();
|
|
56331
56771
|
pointerRef.current = {
|
|
56332
56772
|
pointerId: event.pointerId,
|
|
@@ -56341,119 +56781,243 @@ function DraggableClientInfoModal({
|
|
|
56341
56781
|
onClose();
|
|
56342
56782
|
}
|
|
56343
56783
|
}, [isCallActive, onClose]);
|
|
56784
|
+
const handleRetry = useCallback(() => {
|
|
56785
|
+
setRetry((prev) => ({ key: requestKey, n: prev.n + 1 }));
|
|
56786
|
+
}, [requestKey]);
|
|
56787
|
+
const applyScale = useCallback((next) => {
|
|
56788
|
+
const value = clampFormScale(next);
|
|
56789
|
+
setScalePercent(value);
|
|
56790
|
+
storeFormScale(value);
|
|
56791
|
+
return value;
|
|
56792
|
+
}, []);
|
|
56793
|
+
const canDecrease = scalePercent > FORM_SCALE_MIN;
|
|
56794
|
+
const canIncrease = scalePercent < FORM_SCALE_MAX;
|
|
56795
|
+
const handleDecrease = useCallback(() => {
|
|
56796
|
+
if (canDecrease) setAnnouncement(`Tamanho do formulário: ${applyScale(scalePercent - FORM_SCALE_STEP)}%`);
|
|
56797
|
+
}, [applyScale, canDecrease, scalePercent]);
|
|
56798
|
+
const handleIncrease = useCallback(() => {
|
|
56799
|
+
if (canIncrease) setAnnouncement(`Tamanho do formulário: ${applyScale(scalePercent + FORM_SCALE_STEP)}%`);
|
|
56800
|
+
}, [applyScale, canIncrease, scalePercent]);
|
|
56801
|
+
const handleResetScale = useCallback(() => {
|
|
56802
|
+
applyScale(FORM_SCALE_DEFAULT);
|
|
56803
|
+
setAnnouncement("");
|
|
56804
|
+
}, [applyScale]);
|
|
56805
|
+
useEffect(() => {
|
|
56806
|
+
if (!isOpen || typeof document === "undefined") {
|
|
56807
|
+
return;
|
|
56808
|
+
}
|
|
56809
|
+
const container = containerRef.current;
|
|
56810
|
+
const active = document.activeElement;
|
|
56811
|
+
previouslyFocusedRef.current = active && active !== document.body ? active : null;
|
|
56812
|
+
if (container && (!active || active === document.body)) {
|
|
56813
|
+
container.focus({ preventScroll: true });
|
|
56814
|
+
}
|
|
56815
|
+
return () => {
|
|
56816
|
+
const previous = previouslyFocusedRef.current;
|
|
56817
|
+
if (focusWithinRef.current && previous && previous.isConnected) {
|
|
56818
|
+
previous.focus({ preventScroll: true });
|
|
56819
|
+
}
|
|
56820
|
+
focusWithinRef.current = false;
|
|
56821
|
+
};
|
|
56822
|
+
}, [isOpen]);
|
|
56823
|
+
const handleFocusWithin = useCallback(() => {
|
|
56824
|
+
focusWithinRef.current = true;
|
|
56825
|
+
}, []);
|
|
56826
|
+
const handleBlurWithin = useCallback((event) => {
|
|
56827
|
+
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
56828
|
+
focusWithinRef.current = false;
|
|
56829
|
+
}
|
|
56830
|
+
}, []);
|
|
56831
|
+
const handleKeyDown = useCallback(
|
|
56832
|
+
(event) => {
|
|
56833
|
+
if (event.key === "Escape" && !isCallActive) {
|
|
56834
|
+
event.stopPropagation();
|
|
56835
|
+
handleCloseClick();
|
|
56836
|
+
}
|
|
56837
|
+
},
|
|
56838
|
+
[handleCloseClick, isCallActive]
|
|
56839
|
+
);
|
|
56344
56840
|
if (!isOpen) {
|
|
56345
56841
|
return null;
|
|
56346
56842
|
}
|
|
56347
|
-
const
|
|
56348
|
-
const
|
|
56349
|
-
const
|
|
56350
|
-
|
|
56843
|
+
const rows = (form == null ? void 0 : form.rows) && form.rows.length > 0 ? form.rows : [];
|
|
56844
|
+
const hasRows = rows.length > 0;
|
|
56845
|
+
const hasFields = Boolean(form && form.fields.length > 0);
|
|
56846
|
+
const hasData = hasRows || hasFields;
|
|
56847
|
+
const scaledStyle = {
|
|
56848
|
+
zoom: scale,
|
|
56849
|
+
width: `${BASE_WIDTH}px`,
|
|
56850
|
+
maxWidth: `${Math.max(160, Math.floor((viewport.width - 2 * VIEWPORT_MARGIN$1) / scale))}px`,
|
|
56851
|
+
maxHeight: `${Math.max(120, Math.floor((viewport.height - 2 * VIEWPORT_MARGIN$1) / scale))}px`
|
|
56351
56852
|
};
|
|
56352
|
-
const
|
|
56853
|
+
const controlPx = scale < 1 ? Math.ceil(CONTROL_MIN_PX / scale) : CONTROL_MIN_PX;
|
|
56854
|
+
const controlStyle = { width: `${controlPx}px`, height: `${controlPx}px` };
|
|
56855
|
+
const percentStyle = { height: `${controlPx}px`, minWidth: `${Math.ceil(48 / Math.min(scale, 1))}px` };
|
|
56856
|
+
const modalContent = /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56353
56857
|
"div",
|
|
56354
56858
|
{
|
|
56355
56859
|
ref: containerRef,
|
|
56356
|
-
|
|
56860
|
+
role: "dialog",
|
|
56861
|
+
"aria-labelledby": titleId,
|
|
56862
|
+
tabIndex: -1,
|
|
56863
|
+
onKeyDown: handleKeyDown,
|
|
56864
|
+
onFocus: handleFocusWithin,
|
|
56865
|
+
onBlur: handleBlurWithin,
|
|
56866
|
+
className: tw`fixed z-[9999] overflow-hidden rounded-xl border border-gray-300 bg-white text-gray-900 shadow-2xl focus:outline-none`,
|
|
56357
56867
|
style: {
|
|
56358
56868
|
left: `${position2.x}px`,
|
|
56359
56869
|
top: `${position2.y}px`,
|
|
56360
|
-
|
|
56361
|
-
|
|
56362
|
-
maxHeight: "calc(100vh - 32px)"
|
|
56870
|
+
maxWidth: `calc(100vw - ${2 * VIEWPORT_MARGIN$1}px)`,
|
|
56871
|
+
maxHeight: `calc(100vh - ${2 * VIEWPORT_MARGIN$1}px)`
|
|
56363
56872
|
},
|
|
56364
|
-
children:
|
|
56365
|
-
|
|
56366
|
-
|
|
56367
|
-
|
|
56368
|
-
|
|
56369
|
-
|
|
56370
|
-
|
|
56371
|
-
|
|
56372
|
-
|
|
56373
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: tw`text-sm font-bold`, children: "Informações da Campanha" })
|
|
56374
|
-
] }),
|
|
56375
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56376
|
-
"button",
|
|
56377
|
-
{
|
|
56378
|
-
type: "button",
|
|
56379
|
-
onClick: handleCloseClick,
|
|
56380
|
-
disabled: isCallActive,
|
|
56381
|
-
className: tw`rounded-full p-1 transition hover:bg-white/20 disabled:cursor-not-allowed disabled:opacity-40`,
|
|
56382
|
-
title: isCallActive ? "Aguarde o fim da chamada para fechar" : "Fechar",
|
|
56383
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FiX, { className: tw`h-5 w-5` })
|
|
56384
|
-
}
|
|
56385
|
-
)
|
|
56386
|
-
]
|
|
56387
|
-
}
|
|
56388
|
-
),
|
|
56389
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex-1 space-y-3 overflow-y-auto p-4`, children: [
|
|
56390
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`grid grid-cols-2 gap-3`, children: [
|
|
56391
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2 rounded-lg border border-slate-200 bg-slate-50 px-3 py-2`, children: [
|
|
56392
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(FiClock, { className: tw`h-4 w-4 text-slate-500` }),
|
|
56393
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
56394
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-slate-500 uppercase tracking-wide font-medium`, children: "Duração" }),
|
|
56395
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-sm font-bold text-slate-800`, children: formatDuration(callDuration) })
|
|
56396
|
-
] })
|
|
56397
|
-
] }),
|
|
56398
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2 rounded-lg border border-slate-200 bg-slate-50 px-3 py-2`, children: [
|
|
56399
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { className: tw`h-4 w-4 text-slate-500` }),
|
|
56400
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`min-w-0 flex-1`, children: [
|
|
56401
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-slate-500 uppercase tracking-wide font-medium`, children: "Cliente" }),
|
|
56402
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`truncate text-sm font-bold text-slate-800`, children: (campaignContact == null ? void 0 : campaignContact.label) || "N/A" })
|
|
56403
|
-
] })
|
|
56404
|
-
] })
|
|
56405
|
-
] }),
|
|
56406
|
-
isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`rounded-lg border border-blue-200 bg-blue-50 p-6 text-center`, children: [
|
|
56407
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`mx-auto mb-2 inline-block h-6 w-6 animate-spin rounded-full border-2 border-blue-500 border-t-transparent` }),
|
|
56408
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-xs font-medium text-blue-700`, children: "Carregando dados do contato..." })
|
|
56409
|
-
] }),
|
|
56410
|
-
error2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`rounded-lg border border-red-200 bg-red-50 p-3`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2`, children: [
|
|
56411
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(FiAlertCircle, { className: tw`h-4 w-4 flex-shrink-0 text-red-600` }),
|
|
56412
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
56413
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-xs font-semibold text-red-700`, children: "Erro ao carregar dados" }),
|
|
56414
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-red-600`, children: error2 })
|
|
56415
|
-
] })
|
|
56416
|
-
] }) }),
|
|
56417
|
-
!isLoading && !error2 && hasData && hasFieldStructure && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`space-y-2`, children: fieldRows.map((row, rowIndex) => {
|
|
56418
|
-
const numFields = row.length;
|
|
56419
|
-
let gridCols = "grid-cols-1";
|
|
56420
|
-
if (numFields === 2) {
|
|
56421
|
-
gridCols = "grid-cols-2";
|
|
56422
|
-
} else if (numFields === 3) {
|
|
56423
|
-
gridCols = "grid-cols-3";
|
|
56424
|
-
} else if (numFields === 4) {
|
|
56425
|
-
gridCols = "grid-cols-4";
|
|
56426
|
-
} else if (numFields === 5) {
|
|
56427
|
-
gridCols = "grid-cols-5";
|
|
56428
|
-
}
|
|
56429
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56873
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
56874
|
+
"div",
|
|
56875
|
+
{
|
|
56876
|
+
"data-testid": "campaign-form-scaled",
|
|
56877
|
+
"data-scale": zoomSupported ? scalePercent : FORM_SCALE_DEFAULT,
|
|
56878
|
+
className: tw`flex flex-col`,
|
|
56879
|
+
style: scaledStyle,
|
|
56880
|
+
children: [
|
|
56881
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
56430
56882
|
"div",
|
|
56431
56883
|
{
|
|
56432
|
-
|
|
56433
|
-
|
|
56434
|
-
|
|
56435
|
-
|
|
56436
|
-
|
|
56437
|
-
|
|
56438
|
-
|
|
56439
|
-
},
|
|
56440
|
-
|
|
56441
|
-
|
|
56442
|
-
|
|
56443
|
-
|
|
56444
|
-
|
|
56445
|
-
|
|
56446
|
-
|
|
56447
|
-
|
|
56448
|
-
|
|
56449
|
-
|
|
56450
|
-
|
|
56451
|
-
|
|
56452
|
-
|
|
56884
|
+
onPointerDown: beginDrag,
|
|
56885
|
+
className: tw`flex flex-wrap cursor-move select-none items-center gap-2 border-b border-gray-200 bg-gradient-to-r from-blue-600 to-blue-700 px-3 py-2.5 text-white`,
|
|
56886
|
+
style: { touchAction: "none" },
|
|
56887
|
+
children: [
|
|
56888
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex min-w-[7rem] flex-1 items-center gap-2`, children: [
|
|
56889
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { "aria-hidden": true, className: tw`h-5 w-5 flex-shrink-0` }),
|
|
56890
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { id: titleId, className: tw`truncate text-sm font-bold`, children: "Informações da Campanha" })
|
|
56891
|
+
] }),
|
|
56892
|
+
zoomSupported && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { role: "group", "aria-label": "Tamanho do formulário", className: tw`ml-auto flex flex-shrink-0 items-center gap-0.5`, children: [
|
|
56893
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56894
|
+
"button",
|
|
56895
|
+
{
|
|
56896
|
+
type: "button",
|
|
56897
|
+
onClick: handleDecrease,
|
|
56898
|
+
"aria-disabled": !canDecrease,
|
|
56899
|
+
"aria-label": "Diminuir o tamanho do formulário",
|
|
56900
|
+
title: "Diminuir o formulário e o texto",
|
|
56901
|
+
className: tw`${CONTROL_BUTTON_CLASS} ${canDecrease ? "" : "cursor-not-allowed"}`,
|
|
56902
|
+
style: controlStyle,
|
|
56903
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FiMinus, { "aria-hidden": true, className: tw`h-4 w-4 ${canDecrease ? "" : "opacity-40"}` })
|
|
56904
|
+
}
|
|
56905
|
+
),
|
|
56906
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
56907
|
+
"button",
|
|
56908
|
+
{
|
|
56909
|
+
type: "button",
|
|
56910
|
+
onClick: handleResetScale,
|
|
56911
|
+
"aria-label": `Tamanho atual ${scalePercent}%. Restaurar o tamanho padrão`,
|
|
56912
|
+
title: "Restaurar o tamanho padrão (100%)",
|
|
56913
|
+
className: tw`flex-shrink-0 rounded-md px-1 text-center text-xs font-semibold tabular-nums transition hover:bg-black hover:bg-opacity-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white`,
|
|
56914
|
+
style: percentStyle,
|
|
56915
|
+
children: [
|
|
56916
|
+
scalePercent,
|
|
56917
|
+
"%"
|
|
56918
|
+
]
|
|
56919
|
+
}
|
|
56920
|
+
),
|
|
56921
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56922
|
+
"button",
|
|
56923
|
+
{
|
|
56924
|
+
type: "button",
|
|
56925
|
+
onClick: handleIncrease,
|
|
56926
|
+
"aria-disabled": !canIncrease,
|
|
56927
|
+
"aria-label": "Aumentar o tamanho do formulário",
|
|
56928
|
+
title: "Aumentar o formulário e o texto",
|
|
56929
|
+
className: tw`${CONTROL_BUTTON_CLASS} ${canIncrease ? "" : "cursor-not-allowed"}`,
|
|
56930
|
+
style: controlStyle,
|
|
56931
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FiPlus, { "aria-hidden": true, className: tw`h-4 w-4 ${canIncrease ? "" : "opacity-40"}` })
|
|
56932
|
+
}
|
|
56933
|
+
),
|
|
56934
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { role: "status", className: tw`sr-only`, children: announcement })
|
|
56935
|
+
] }),
|
|
56936
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56937
|
+
"button",
|
|
56938
|
+
{
|
|
56939
|
+
type: "button",
|
|
56940
|
+
onClick: handleCloseClick,
|
|
56941
|
+
disabled: isCallActive,
|
|
56942
|
+
"aria-label": isCallActive ? "Aguarde o fim da chamada para fechar" : "Fechar",
|
|
56943
|
+
className: tw`${CONTROL_BUTTON_CLASS} rounded-full disabled:cursor-not-allowed disabled:opacity-40`,
|
|
56944
|
+
style: controlStyle,
|
|
56945
|
+
title: isCallActive ? "Aguarde o fim da chamada para fechar" : "Fechar",
|
|
56946
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FiX, { "aria-hidden": true, className: tw`h-5 w-5` })
|
|
56947
|
+
}
|
|
56948
|
+
)
|
|
56949
|
+
]
|
|
56950
|
+
}
|
|
56951
|
+
),
|
|
56952
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
56953
|
+
"div",
|
|
56954
|
+
{
|
|
56955
|
+
tabIndex: 0,
|
|
56956
|
+
role: "region",
|
|
56957
|
+
"aria-label": "Dados do contato",
|
|
56958
|
+
className: tw`min-h-0 flex-1 space-y-3 overflow-y-auto p-4 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500`,
|
|
56959
|
+
children: [
|
|
56960
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`grid grid-cols-2 gap-3`, children: [
|
|
56961
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2`, children: [
|
|
56962
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FiClock, { "aria-hidden": true, className: tw`h-4 w-4 text-gray-500` }),
|
|
56963
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
56964
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-gray-500 uppercase tracking-wide font-medium`, children: "Duração" }),
|
|
56965
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-sm font-bold text-gray-800`, children: formatDuration(callDuration) })
|
|
56966
|
+
] })
|
|
56967
|
+
] }),
|
|
56968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2`, children: [
|
|
56969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { "aria-hidden": true, className: tw`h-4 w-4 text-gray-500` }),
|
|
56970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`min-w-0 flex-1`, children: [
|
|
56971
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-gray-500 uppercase tracking-wide font-medium`, children: "Cliente" }),
|
|
56972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`truncate text-sm font-bold text-gray-800`, children: (campaignContact == null ? void 0 : campaignContact.label) || "N/A" })
|
|
56973
|
+
] })
|
|
56974
|
+
] })
|
|
56975
|
+
] }),
|
|
56976
|
+
isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`rounded-lg border border-blue-200 bg-blue-50 p-6 text-center`, role: "status", children: [
|
|
56977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`mx-auto mb-2 inline-block h-6 w-6 animate-spin rounded-full border-2 border-blue-500 border-t-transparent` }),
|
|
56978
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-xs font-medium text-blue-700`, children: "Carregando dados do contato..." })
|
|
56979
|
+
] }),
|
|
56980
|
+
error2 && !isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`rounded-lg border border-red-200 bg-red-50 p-3`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex items-center gap-2`, children: [
|
|
56981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FiAlertCircle, { "aria-hidden": true, className: tw`h-4 w-4 flex-shrink-0 text-red-600` }),
|
|
56982
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`min-w-0 flex-1`, children: [
|
|
56983
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-xs font-semibold text-red-700`, children: "Erro ao carregar dados" }),
|
|
56984
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-[10px] text-red-600`, children: error2 })
|
|
56985
|
+
] }),
|
|
56986
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56987
|
+
"button",
|
|
56988
|
+
{
|
|
56989
|
+
type: "button",
|
|
56990
|
+
onClick: handleRetry,
|
|
56991
|
+
className: tw`rounded-md border border-red-300 bg-white px-2 py-1 text-[11px] font-semibold text-red-700 transition hover:bg-red-100`,
|
|
56992
|
+
children: "Tentar novamente"
|
|
56993
|
+
}
|
|
56994
|
+
)
|
|
56995
|
+
] }) }),
|
|
56996
|
+
!isLoading && !error2 && hasRows && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`space-y-2`, children: rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`grid gap-2 ${gridColsFor(row.length)}`, children: row.map((field, fieldIndex) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
56997
|
+
Field,
|
|
56998
|
+
{
|
|
56999
|
+
label: field.label,
|
|
57000
|
+
value: field.value || "-",
|
|
57001
|
+
fullWidth: field.width === "100%"
|
|
57002
|
+
},
|
|
57003
|
+
`${rowIndex}-${fieldIndex}-${field.key}`
|
|
57004
|
+
)) }, rowIndex)) }),
|
|
57005
|
+
!isLoading && !error2 && !hasRows && hasFields && form && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`grid grid-cols-2 gap-2`, children: form.fields.map((field) => /* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: field.label, value: field.value || "-" }, field.key)) }),
|
|
57006
|
+
!isLoading && !error2 && !hasData && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`flex flex-col items-center justify-center rounded-lg border border-gray-200 bg-gray-50 px-4 py-8 text-center`, children: [
|
|
57007
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FiUser, { "aria-hidden": true, className: tw`mb-2 h-8 w-8 text-gray-400` }),
|
|
57008
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-sm text-gray-500`, children: "Nenhum dado disponível" })
|
|
57009
|
+
] })
|
|
57010
|
+
]
|
|
57011
|
+
}
|
|
57012
|
+
),
|
|
57013
|
+
isCallActive && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: tw`border-t border-gray-200 bg-gray-50 px-4 py-2`, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`text-center text-xs text-gray-500`, children: "Aguarde o fim da chamada para fechar" }) })
|
|
57014
|
+
]
|
|
57015
|
+
}
|
|
57016
|
+
)
|
|
56453
57017
|
}
|
|
56454
57018
|
);
|
|
56455
57019
|
if (typeof document !== "undefined") {
|
|
56456
|
-
return createPortal(modalContent, document.body);
|
|
57020
|
+
return createPortal(modalContent, portalTarget ?? document.body);
|
|
56457
57021
|
}
|
|
56458
57022
|
return null;
|
|
56459
57023
|
}
|
|
@@ -56463,9 +57027,16 @@ function Field({
|
|
|
56463
57027
|
fullWidth
|
|
56464
57028
|
}) {
|
|
56465
57029
|
const widthClass = fullWidth ? "col-span-full" : "";
|
|
56466
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`rounded-lg border border-
|
|
56467
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`mb-0.5 truncate text-[9px] font-semibold uppercase tracking-wide text-
|
|
56468
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
57030
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: tw`rounded-lg border border-gray-200 bg-white p-2 ${widthClass}`, children: [
|
|
57031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: tw`mb-0.5 truncate text-[9px] font-semibold uppercase tracking-wide text-gray-500`, children: label }),
|
|
57032
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
57033
|
+
"p",
|
|
57034
|
+
{
|
|
57035
|
+
className: tw`overflow-hidden break-words text-xs font-semibold text-gray-800`,
|
|
57036
|
+
style: { display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical" },
|
|
57037
|
+
children: value
|
|
57038
|
+
}
|
|
57039
|
+
)
|
|
56469
57040
|
] });
|
|
56470
57041
|
}
|
|
56471
57042
|
if (typeof window !== "undefined" && !window.__fetchIntercepted__) {
|
|
@@ -56563,104 +57134,8 @@ if (typeof window !== "undefined" && !window.__fetchIntercepted__) {
|
|
|
56563
57134
|
};
|
|
56564
57135
|
console.log("%c[FETCH INTERCEPTOR] ✅ Ativo - todas as requisições serão logadas", "color: #2196F3; font-weight: bold; font-size: 12px");
|
|
56565
57136
|
}
|
|
56566
|
-
async function getCampaignConfig(contactId) {
|
|
56567
|
-
const url = `${API_BASE_URL}/api/campaign-config/${contactId}`;
|
|
56568
|
-
const headers = getAuthHeaders();
|
|
56569
|
-
console.log("[getCampaignConfig] URL:", url);
|
|
56570
|
-
console.log("[getCampaignConfig] Headers:", JSON.stringify(headers));
|
|
56571
|
-
const response = await fetch(url, { method: "GET", headers, credentials: "omit" });
|
|
56572
|
-
if (!response.ok) {
|
|
56573
|
-
const errorBody = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
56574
|
-
console.error("[getCampaignConfig] Erro:", response.status, errorBody);
|
|
56575
|
-
if (response.status === 401) {
|
|
56576
|
-
const token = getSessionToken();
|
|
56577
|
-
console.error("[getCampaignConfig] 401 - Token atual:", token ? `${token.substring(0, 20)}...` : "NULL");
|
|
56578
|
-
console.error("[getCampaignConfig] 401 - Resposta completa:", JSON.stringify(errorBody));
|
|
56579
|
-
}
|
|
56580
|
-
throw new Error(errorBody.error || `Falha ao buscar config: ${response.status}`);
|
|
56581
|
-
}
|
|
56582
|
-
return response.json();
|
|
56583
|
-
}
|
|
56584
|
-
function processRowsToMapping(apiResponse) {
|
|
56585
|
-
const mapping = {};
|
|
56586
|
-
console.log("[processRowsToMapping] Processando estrutura:", typeof apiResponse);
|
|
56587
|
-
if (!apiResponse || typeof apiResponse !== "object") {
|
|
56588
|
-
console.warn("[processRowsToMapping] Resposta inválida:", apiResponse);
|
|
56589
|
-
return mapping;
|
|
56590
|
-
}
|
|
56591
|
-
const data = apiResponse;
|
|
56592
|
-
if (!data.rows || !Array.isArray(data.rows)) {
|
|
56593
|
-
console.warn("[processRowsToMapping] rows não encontrado ou não é array:", data);
|
|
56594
|
-
return mapping;
|
|
56595
|
-
}
|
|
56596
|
-
console.log("[processRowsToMapping] Total de linhas (rows):", data.rows.length);
|
|
56597
|
-
for (let rowIndex = 0; rowIndex < data.rows.length; rowIndex++) {
|
|
56598
|
-
const row = data.rows[rowIndex];
|
|
56599
|
-
if (!Array.isArray(row)) {
|
|
56600
|
-
console.warn(`[processRowsToMapping] Row ${rowIndex} não é array:`, row);
|
|
56601
|
-
continue;
|
|
56602
|
-
}
|
|
56603
|
-
for (const field of row) {
|
|
56604
|
-
if (field && typeof field === "object" && "code" in field && "name" in field) {
|
|
56605
|
-
const fieldObj = field;
|
|
56606
|
-
if (fieldObj.code && fieldObj.name) {
|
|
56607
|
-
console.log(`[processRowsToMapping] ✓ Mapeando: "${fieldObj.code}" -> "${fieldObj.name}"`);
|
|
56608
|
-
mapping[fieldObj.code] = fieldObj.name;
|
|
56609
|
-
}
|
|
56610
|
-
}
|
|
56611
|
-
}
|
|
56612
|
-
}
|
|
56613
|
-
console.log("[processRowsToMapping] Mapeamento final:", mapping);
|
|
56614
|
-
console.log("[processRowsToMapping] Total de campos mapeados:", Object.keys(mapping).length);
|
|
56615
|
-
return mapping;
|
|
56616
|
-
}
|
|
56617
|
-
function applyMappingToValues(mapping, values) {
|
|
56618
|
-
const finalData = {};
|
|
56619
|
-
console.log("[applyMappingToValues] Aplicando mapeamento...");
|
|
56620
|
-
console.log("[applyMappingToValues] Mapping keys:", Object.keys(mapping));
|
|
56621
|
-
console.log("[applyMappingToValues] Values keys:", Object.keys(values));
|
|
56622
|
-
for (const [code, value] of Object.entries(values)) {
|
|
56623
|
-
const name = mapping[code];
|
|
56624
|
-
if (name) {
|
|
56625
|
-
console.log(`[applyMappingToValues] ✓ "${code}" -> "${name}" = "${value}"`);
|
|
56626
|
-
finalData[name] = value;
|
|
56627
|
-
} else {
|
|
56628
|
-
console.log(`[applyMappingToValues] ✗ "${code}" não tem mapeamento (valor: "${value}")`);
|
|
56629
|
-
}
|
|
56630
|
-
}
|
|
56631
|
-
console.log("[applyMappingToValues] Final data:", finalData);
|
|
56632
|
-
return finalData;
|
|
56633
|
-
}
|
|
56634
|
-
async function fetchCampaignFieldsRaw(campaignModelId) {
|
|
56635
|
-
const url = `${API_BASE_URL}/api/campaign-fields/${campaignModelId}`;
|
|
56636
|
-
console.log("[fetchCampaignFieldsRaw] URL:", url);
|
|
56637
|
-
const response = await fetch(url, { method: "GET", headers: getAuthHeaders(), credentials: "omit" });
|
|
56638
|
-
if (!response.ok) {
|
|
56639
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
56640
|
-
throw new Error(error2.error || `Falha ao buscar campos: ${response.status}`);
|
|
56641
|
-
}
|
|
56642
|
-
const json = await response.json();
|
|
56643
|
-
console.log("[fetchCampaignFieldsRaw] Resposta recebida:", JSON.stringify(json, null, 2).substring(0, 500));
|
|
56644
|
-
return json;
|
|
56645
|
-
}
|
|
56646
|
-
async function getContactValues(contactId) {
|
|
56647
|
-
const url = `${API_BASE_URL}/api/campaign-contact/${contactId}`;
|
|
56648
|
-
const response = await fetch(url, { method: "GET", headers: getAuthHeaders(), credentials: "omit" });
|
|
56649
|
-
if (!response.ok) {
|
|
56650
|
-
const error2 = await response.json().catch(() => ({ error: "Erro desconhecido" }));
|
|
56651
|
-
throw new Error(error2.error || `Falha ao buscar valores: ${response.status}`);
|
|
56652
|
-
}
|
|
56653
|
-
return response.json();
|
|
56654
|
-
}
|
|
56655
57137
|
function findValue(finalData, candidates) {
|
|
56656
|
-
|
|
56657
|
-
const lowerCandidates = candidates.map((item) => item.toLowerCase());
|
|
56658
|
-
for (const [key, value] of entries) {
|
|
56659
|
-
if (lowerCandidates.includes(key.toLowerCase())) {
|
|
56660
|
-
return value;
|
|
56661
|
-
}
|
|
56662
|
-
}
|
|
56663
|
-
return void 0;
|
|
57138
|
+
return findFormValue({ values: finalData }, candidates);
|
|
56664
57139
|
}
|
|
56665
57140
|
function MobileDialer(props) {
|
|
56666
57141
|
useEffect(() => {
|
|
@@ -56673,10 +57148,12 @@ function MobileDialer(props) {
|
|
|
56673
57148
|
document.head.appendChild(link);
|
|
56674
57149
|
}
|
|
56675
57150
|
}, []);
|
|
57151
|
+
const inputProfile = useInputProfile();
|
|
57152
|
+
const density = resolveDensity(props.density, inputProfile);
|
|
56676
57153
|
if (!props.isAuthenticated) {
|
|
56677
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(MobileDialerLogin, { ...props });
|
|
57154
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MobileDialerLogin, { ...props, density });
|
|
56678
57155
|
}
|
|
56679
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(AuthenticatedMobileDialer, { ...props });
|
|
57156
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(AuthenticatedMobileDialer, { ...props, density });
|
|
56680
57157
|
}
|
|
56681
57158
|
function MobileDialerLogin({
|
|
56682
57159
|
username,
|
|
@@ -56685,7 +57162,8 @@ function MobileDialerLogin({
|
|
|
56685
57162
|
sessionError,
|
|
56686
57163
|
sessionStatus,
|
|
56687
57164
|
loginConfirmation,
|
|
56688
|
-
onCancelLoginConfirmation
|
|
57165
|
+
onCancelLoginConfirmation,
|
|
57166
|
+
density
|
|
56689
57167
|
}) {
|
|
56690
57168
|
const [loginInput, setLoginInput] = useState(username ?? "");
|
|
56691
57169
|
const [loginError, setLoginError] = useState(null);
|
|
@@ -56712,7 +57190,7 @@ function MobileDialerLogin({
|
|
|
56712
57190
|
const handleLogin = useCallback(() => submitLogin(loginInput), [submitLogin, loginInput]);
|
|
56713
57191
|
const showConfirmation = Boolean(loginConfirmation) && !isLoadingSession;
|
|
56714
57192
|
const loadingUser = ((loginConfirmation == null ? void 0 : loginConfirmation.username) || loginInput || username || "").trim();
|
|
56715
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "phone-container", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "screen dialer-screen login-screen active", id: "dialerScreen", children: [
|
|
57193
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "phone-container", "data-density": density === "compact" ? "compact" : "comfortable", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "screen dialer-screen login-screen active", id: "dialerScreen", children: [
|
|
56716
57194
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "dialer-header", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "status-container", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: `status-badge ${isLoadingSession ? "connecting" : "available"}`, children: [
|
|
56717
57195
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "status-dot" }),
|
|
56718
57196
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "status-text", children: isLoadingSession ? "Conectando" : "Login" })
|
|
@@ -56826,9 +57304,10 @@ Gostaríamos de fazer um *diagnóstico gratuito* para te apresentar os valores r
|
|
|
56826
57304
|
}
|
|
56827
57305
|
function AuthenticatedMobileDialer({
|
|
56828
57306
|
username,
|
|
56829
|
-
showClientInfoModal = false
|
|
57307
|
+
showClientInfoModal = false,
|
|
57308
|
+
density
|
|
56830
57309
|
}) {
|
|
56831
|
-
var _a2, _b, _c;
|
|
57310
|
+
var _a2, _b, _c, _d;
|
|
56832
57311
|
const { skipManualQualification } = useDialerConfig();
|
|
56833
57312
|
const [dialValue, setDialValue] = useState("");
|
|
56834
57313
|
const [activeScreen, setActiveScreen] = useState("dialer");
|
|
@@ -56850,10 +57329,14 @@ function AuthenticatedMobileDialer({
|
|
|
56850
57329
|
isLoading: false,
|
|
56851
57330
|
error: null
|
|
56852
57331
|
});
|
|
56853
|
-
const [fetchedContactId, setFetchedContactId] = useState(null);
|
|
56854
57332
|
const [callHistory, setCallHistory] = useState([]);
|
|
56855
57333
|
const [isLoadingHistory, setIsLoadingHistory] = useState(false);
|
|
56856
57334
|
const [historyError, setHistoryError] = useState(null);
|
|
57335
|
+
const [historyQuery, setHistoryQuery] = useState("");
|
|
57336
|
+
const [historySearchResults, setHistorySearchResults] = useState(null);
|
|
57337
|
+
const [isSearchingHistory, setIsSearchingHistory] = useState(false);
|
|
57338
|
+
const historyTextPoolRef = useRef(null);
|
|
57339
|
+
const historySearchSeqRef = useRef(0);
|
|
56857
57340
|
const [isSpeakerOn, setIsSpeakerOn] = useState(false);
|
|
56858
57341
|
const [audioOutputDevices, setAudioOutputDevices] = useState([]);
|
|
56859
57342
|
const [speakerDeviceId, setSpeakerDeviceId] = useState(null);
|
|
@@ -57030,90 +57513,54 @@ function AuthenticatedMobileDialer({
|
|
|
57030
57513
|
});
|
|
57031
57514
|
}
|
|
57032
57515
|
}, [callInfo]);
|
|
57033
|
-
const
|
|
57034
|
-
|
|
57516
|
+
const campaignFormRequest = useMemo(
|
|
57517
|
+
() => {
|
|
57518
|
+
var _a3;
|
|
57519
|
+
return (callInfo == null ? void 0 : callInfo.type) === "campaign" ? campaignFormRequestFromCallInfo(callInfo.info, ((_a3 = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _a3.campaignContactPhoneId) ?? null) : null;
|
|
57520
|
+
},
|
|
57521
|
+
[callInfo, currentCall]
|
|
57522
|
+
);
|
|
57523
|
+
const campaignFormKey = campaignFormRequest ? campaignFormCacheKey(campaignFormRequest) : null;
|
|
57524
|
+
const campaignFormRequestRef = useRef(campaignFormRequest);
|
|
57525
|
+
campaignFormRequestRef.current = campaignFormRequest;
|
|
57035
57526
|
useEffect(() => {
|
|
57036
|
-
|
|
57527
|
+
const request = campaignFormRequestRef.current;
|
|
57528
|
+
if (!request || !campaignFormKey) {
|
|
57037
57529
|
setContactData({ finalData: {}, isLoading: false, error: null });
|
|
57038
|
-
setFetchedContactId(null);
|
|
57039
|
-
return;
|
|
57040
|
-
}
|
|
57041
|
-
if (fetchedContactId === campaignContactId) {
|
|
57042
57530
|
return;
|
|
57043
57531
|
}
|
|
57044
57532
|
let cancelled = false;
|
|
57045
|
-
|
|
57046
|
-
|
|
57047
|
-
|
|
57048
|
-
|
|
57049
|
-
|
|
57050
|
-
|
|
57051
|
-
|
|
57052
|
-
|
|
57053
|
-
hasToken: !!tokenAtFetch,
|
|
57054
|
-
localStorageLength: typeof window !== "undefined" ? localStorage.length : 0
|
|
57533
|
+
let refreshTimer = null;
|
|
57534
|
+
setContactData({ finalData: {}, isLoading: true, error: null });
|
|
57535
|
+
addLog("debug", "FetchContact", "Buscando formulário do contato", { contactId: request.id, source: request.source });
|
|
57536
|
+
const apply2 = (form) => {
|
|
57537
|
+
setContactData({ finalData: form.values, isLoading: false, error: null });
|
|
57538
|
+
addLog("info", "FetchContact", `✅ Formulário: ${form.fields.length} campos (${form.valuesSource}, layout ${form.layoutSource})`, {
|
|
57539
|
+
contactId: request.id,
|
|
57540
|
+
partial: form.partial === true
|
|
57055
57541
|
});
|
|
57056
|
-
console.log("[MobileDialer] ========================================");
|
|
57057
|
-
setContactData({ finalData: {}, isLoading: true, error: null });
|
|
57058
|
-
try {
|
|
57059
|
-
const customer = campaignContact == null ? void 0 : campaignContact.customer;
|
|
57060
|
-
let fieldsRawData;
|
|
57061
|
-
let contactValues = {};
|
|
57062
|
-
if ((customer == null ? void 0 : customer.id) && (customer == null ? void 0 : customer.formId)) {
|
|
57063
|
-
console.log("[MobileDialer] 📋 Modo CLIENTE detectado:", customer);
|
|
57064
|
-
const customerFieldsUrl = `${API_BASE_URL}/api/campaign-contact/0?source=customer&formId=${encodeURIComponent(String(customer.formId))}`;
|
|
57065
|
-
const customerValuesUrl = `${API_BASE_URL}/api/campaign-fields/0?source=customer&customerId=${encodeURIComponent(String(customer.id))}`;
|
|
57066
|
-
const [fieldsResponse, valuesResponse] = await Promise.all([
|
|
57067
|
-
fetch(customerFieldsUrl, { method: "GET", headers: getAuthHeaders(), credentials: "omit" }),
|
|
57068
|
-
fetch(customerValuesUrl, { method: "GET", headers: getAuthHeaders(), credentials: "omit" })
|
|
57069
|
-
]);
|
|
57070
|
-
if (!fieldsResponse.ok) throw new Error(`Erro ao buscar campos cliente: ${fieldsResponse.status}`);
|
|
57071
|
-
if (!valuesResponse.ok) throw new Error(`Erro ao buscar valores cliente: ${valuesResponse.status}`);
|
|
57072
|
-
fieldsRawData = await fieldsResponse.json();
|
|
57073
|
-
contactValues = await valuesResponse.json();
|
|
57074
|
-
} else {
|
|
57075
|
-
console.log("[MobileDialer] 📋 Modo CAMPANHA detectado");
|
|
57076
|
-
const config = await getCampaignConfig(campaignContactId);
|
|
57077
|
-
console.log("[MobileDialer] Config recebida:", config);
|
|
57078
|
-
if (!config.campaignModelId) {
|
|
57079
|
-
throw new Error("campaignModelId não encontrado");
|
|
57080
|
-
}
|
|
57081
|
-
const [rawFields, rawValues] = await Promise.all([
|
|
57082
|
-
fetchCampaignFieldsRaw(config.campaignModelId),
|
|
57083
|
-
getContactValues(campaignContactId)
|
|
57084
|
-
]);
|
|
57085
|
-
fieldsRawData = rawFields;
|
|
57086
|
-
contactValues = rawValues;
|
|
57087
|
-
}
|
|
57088
|
-
console.log("[MobileDialer] ======= DADOS BRUTOS =======");
|
|
57089
|
-
console.log("[MobileDialer] fieldsRawData:", JSON.stringify(fieldsRawData, null, 2).substring(0, 1e3));
|
|
57090
|
-
console.log("[MobileDialer] contactValues:", JSON.stringify(contactValues, null, 2));
|
|
57091
|
-
const codeToNameMap = processRowsToMapping(fieldsRawData);
|
|
57092
|
-
console.log("[MobileDialer] ======= MAPEAMENTO PROCESSADO =======");
|
|
57093
|
-
console.log("[MobileDialer] codeToNameMap:", JSON.stringify(codeToNameMap, null, 2));
|
|
57094
|
-
const finalData = applyMappingToValues(codeToNameMap, contactValues);
|
|
57095
|
-
console.log("[MobileDialer] ======= RESULTADO FINAL =======");
|
|
57096
|
-
console.log("[MobileDialer] finalData:", JSON.stringify(finalData, null, 2));
|
|
57097
|
-
console.log("[MobileDialer] finalData keys:", Object.keys(finalData));
|
|
57098
|
-
console.log("[MobileDialer] ================================");
|
|
57099
|
-
if (!cancelled) {
|
|
57100
|
-
setContactData({ finalData, isLoading: false, error: null });
|
|
57101
|
-
setFetchedContactId(campaignContactId);
|
|
57102
|
-
}
|
|
57103
|
-
} catch (error2) {
|
|
57104
|
-
if (!cancelled) {
|
|
57105
|
-
console.error("[MobileDialer] Erro ao buscar dados:", error2);
|
|
57106
|
-
const errorMessage = error2 instanceof Error ? error2.message : "Erro ao buscar dados";
|
|
57107
|
-
setContactData({ finalData: {}, isLoading: false, error: errorMessage });
|
|
57108
|
-
setFetchedContactId(campaignContactId);
|
|
57109
|
-
}
|
|
57110
|
-
}
|
|
57111
57542
|
};
|
|
57112
|
-
|
|
57543
|
+
fetchCampaignForm(request).then((form) => {
|
|
57544
|
+
if (cancelled) return;
|
|
57545
|
+
apply2(form);
|
|
57546
|
+
if (form.partial) {
|
|
57547
|
+
refreshTimer = setTimeout(() => {
|
|
57548
|
+
if (cancelled) return;
|
|
57549
|
+
fetchCampaignForm(request, { force: true }).then((refreshed) => {
|
|
57550
|
+
if (!cancelled) apply2(refreshed);
|
|
57551
|
+
}).catch(() => void 0);
|
|
57552
|
+
}, 3e3);
|
|
57553
|
+
}
|
|
57554
|
+
}).catch((error2) => {
|
|
57555
|
+
if (cancelled) return;
|
|
57556
|
+
console.error("[MobileDialer] Erro ao buscar o formulário:", error2);
|
|
57557
|
+
setContactData({ finalData: {}, isLoading: false, error: error2 instanceof Error ? error2.message : "Erro ao buscar dados" });
|
|
57558
|
+
});
|
|
57113
57559
|
return () => {
|
|
57114
57560
|
cancelled = true;
|
|
57561
|
+
if (refreshTimer) clearTimeout(refreshTimer);
|
|
57115
57562
|
};
|
|
57116
|
-
}, [
|
|
57563
|
+
}, [campaignFormKey]);
|
|
57117
57564
|
const callStateStr = callState;
|
|
57118
57565
|
const isError = callStateStr === "startup.error" || callStateStr === "offline";
|
|
57119
57566
|
const isIdle = !callStateStr || callStateStr === "starting" || callStateStr === "idle" || callStateStr === "manualCallSetup" || callStateStr === "onBreak";
|
|
@@ -57165,6 +57612,18 @@ function AuthenticatedMobileDialer({
|
|
|
57165
57612
|
setPauseDurationSeconds(0);
|
|
57166
57613
|
}
|
|
57167
57614
|
}, [isOnBreak, currentBreakName]);
|
|
57615
|
+
useEffect(() => {
|
|
57616
|
+
const onClickToCall = (event) => {
|
|
57617
|
+
const task = event.detail;
|
|
57618
|
+
if (!(task == null ? void 0 : task.phone)) return;
|
|
57619
|
+
setCallError(null);
|
|
57620
|
+
setDialValue(nationalDigitsFromE164(task.phone).slice(0, 32));
|
|
57621
|
+
setActiveScreen("dialer");
|
|
57622
|
+
addLog("event", "Call", `🖱️ Click-to-call recebido: ${task.phoneDisplay}`, { taskId: task.id, source: task.source });
|
|
57623
|
+
};
|
|
57624
|
+
window.addEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
57625
|
+
return () => window.removeEventListener(CLICK_TO_CALL_EVENT, onClickToCall);
|
|
57626
|
+
}, []);
|
|
57168
57627
|
useEffect(() => {
|
|
57169
57628
|
console.log("[MobileDialer] Screen control effect - callState:", callState, "isInCall:", isInCall, "isConnecting:", isConnecting, "isAfterCall:", isAfterCall);
|
|
57170
57629
|
if (isInCall || isConnecting) {
|
|
@@ -57356,16 +57815,17 @@ function AuthenticatedMobileDialer({
|
|
|
57356
57815
|
haptic.notificationError();
|
|
57357
57816
|
}
|
|
57358
57817
|
}, [haptic, speakerSupported, speakerDeviceId, defaultDeviceId, isSpeakerOn, operator]);
|
|
57359
|
-
const
|
|
57360
|
-
|
|
57361
|
-
|
|
57362
|
-
|
|
57363
|
-
|
|
57364
|
-
|
|
57365
|
-
|
|
57366
|
-
|
|
57367
|
-
|
|
57368
|
-
|
|
57818
|
+
const requestHistory = useCallback(
|
|
57819
|
+
async ({ phone, limit }) => {
|
|
57820
|
+
const agentId = userData == null ? void 0 : userData.id;
|
|
57821
|
+
if (!agentId) {
|
|
57822
|
+
throw new Error("Aguardando ID do usuário");
|
|
57823
|
+
}
|
|
57824
|
+
const params = new URLSearchParams({ agent_id: String(agentId), limit: String(limit) });
|
|
57825
|
+
if (phone) {
|
|
57826
|
+
params.set("phone", phone);
|
|
57827
|
+
}
|
|
57828
|
+
const response = await fetch(`${API_BASE_URL}/api/call-history?${params.toString()}`, {
|
|
57369
57829
|
method: "GET",
|
|
57370
57830
|
headers: getAuthHeaders(),
|
|
57371
57831
|
credentials: "omit"
|
|
@@ -57376,8 +57836,22 @@ function AuthenticatedMobileDialer({
|
|
|
57376
57836
|
);
|
|
57377
57837
|
}
|
|
57378
57838
|
const data = await response.json();
|
|
57379
|
-
|
|
57380
|
-
|
|
57839
|
+
return data.items || [];
|
|
57840
|
+
},
|
|
57841
|
+
[userData == null ? void 0 : userData.id]
|
|
57842
|
+
);
|
|
57843
|
+
const fetchCallHistory = useCallback(async () => {
|
|
57844
|
+
if (!(userData == null ? void 0 : userData.id)) {
|
|
57845
|
+
console.log("[MobileDialer] Aguardando ID do usuário para buscar histórico");
|
|
57846
|
+
return;
|
|
57847
|
+
}
|
|
57848
|
+
setIsLoadingHistory(true);
|
|
57849
|
+
setHistoryError(null);
|
|
57850
|
+
historyTextPoolRef.current = null;
|
|
57851
|
+
try {
|
|
57852
|
+
const items = await requestHistory({ limit: 50 });
|
|
57853
|
+
console.log("[MobileDialer] Histórico recebido:", items.length, "registros");
|
|
57854
|
+
setCallHistory(items);
|
|
57381
57855
|
} catch (error2) {
|
|
57382
57856
|
console.error("[MobileDialer] Erro ao buscar histórico:", error2);
|
|
57383
57857
|
setHistoryError(error2 instanceof Error && error2.message.startsWith("Sessão") ? error2.message : "Erro ao carregar histórico");
|
|
@@ -57385,7 +57859,54 @@ function AuthenticatedMobileDialer({
|
|
|
57385
57859
|
} finally {
|
|
57386
57860
|
setIsLoadingHistory(false);
|
|
57387
57861
|
}
|
|
57388
|
-
}, [userData == null ? void 0 : userData.id]);
|
|
57862
|
+
}, [requestHistory, userData == null ? void 0 : userData.id]);
|
|
57863
|
+
const handleHistoryQueryChange = useCallback(
|
|
57864
|
+
async (query) => {
|
|
57865
|
+
setHistoryQuery(query);
|
|
57866
|
+
const parsed = classifyHistoryQuery(query);
|
|
57867
|
+
const seq = ++historySearchSeqRef.current;
|
|
57868
|
+
if (parsed.kind === "empty") {
|
|
57869
|
+
setHistorySearchResults(null);
|
|
57870
|
+
setIsSearchingHistory(false);
|
|
57871
|
+
return;
|
|
57872
|
+
}
|
|
57873
|
+
setIsSearchingHistory(true);
|
|
57874
|
+
try {
|
|
57875
|
+
let results;
|
|
57876
|
+
if (parsed.kind === "phone") {
|
|
57877
|
+
results = await requestHistory({ phone: parsed.digits, limit: 100 });
|
|
57878
|
+
} else {
|
|
57879
|
+
if (!historyTextPoolRef.current) {
|
|
57880
|
+
historyTextPoolRef.current = await requestHistory({ limit: 200 });
|
|
57881
|
+
}
|
|
57882
|
+
results = historyTextPoolRef.current;
|
|
57883
|
+
}
|
|
57884
|
+
if (seq === historySearchSeqRef.current) {
|
|
57885
|
+
setHistorySearchResults(results);
|
|
57886
|
+
}
|
|
57887
|
+
} catch (error2) {
|
|
57888
|
+
console.error("[MobileDialer] Erro na busca do histórico:", error2);
|
|
57889
|
+
if (seq === historySearchSeqRef.current) {
|
|
57890
|
+
setHistorySearchResults(null);
|
|
57891
|
+
}
|
|
57892
|
+
} finally {
|
|
57893
|
+
if (seq === historySearchSeqRef.current) {
|
|
57894
|
+
setIsSearchingHistory(false);
|
|
57895
|
+
}
|
|
57896
|
+
}
|
|
57897
|
+
},
|
|
57898
|
+
[requestHistory]
|
|
57899
|
+
);
|
|
57900
|
+
const historySearchHint = useMemo(() => {
|
|
57901
|
+
const parsed = classifyHistoryQuery(historyQuery);
|
|
57902
|
+
if (parsed.kind === "phone") {
|
|
57903
|
+
return "Busca por número em todo o histórico";
|
|
57904
|
+
}
|
|
57905
|
+
if (parsed.kind === "text") {
|
|
57906
|
+
return historySearchResults ? "Busca por texto nas últimas 200 chamadas" : "Busca por texto nas chamadas carregadas";
|
|
57907
|
+
}
|
|
57908
|
+
return null;
|
|
57909
|
+
}, [historyQuery, historySearchResults]);
|
|
57389
57910
|
useEffect(() => {
|
|
57390
57911
|
if (activeScreen === "history") {
|
|
57391
57912
|
void fetchCallHistory();
|
|
@@ -57536,7 +58057,7 @@ function AuthenticatedMobileDialer({
|
|
|
57536
58057
|
addLog("info", "Debug", "🔒 Painel de debug fechado");
|
|
57537
58058
|
} });
|
|
57538
58059
|
}
|
|
57539
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "phone-container", children: [
|
|
58060
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "phone-container", "data-density": density === "compact" ? "compact" : "comfortable", children: [
|
|
57540
58061
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `screen dialer-screen ${activeScreen === "dialer" ? "active" : ""}`, id: "dialerScreen", children: [
|
|
57541
58062
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "dialer-header", children: [
|
|
57542
58063
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "status-container", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: `status-badge ${statusBadgeClass}`, id: "statusBadge", children: [
|
|
@@ -57699,10 +58220,14 @@ function AuthenticatedMobileDialer({
|
|
|
57699
58220
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `screen call-history-screen ${activeScreen === "history" ? "active" : ""}`, id: "callHistoryScreen", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
57700
58221
|
CallHistoryList,
|
|
57701
58222
|
{
|
|
57702
|
-
items: callHistory,
|
|
58223
|
+
items: historySearchResults ?? callHistory,
|
|
57703
58224
|
isLoading: isLoadingHistory,
|
|
57704
58225
|
error: historyError,
|
|
57705
58226
|
onRefresh: fetchCallHistory,
|
|
58227
|
+
query: historyQuery,
|
|
58228
|
+
onQueryChange: handleHistoryQueryChange,
|
|
58229
|
+
isSearching: isSearchingHistory,
|
|
58230
|
+
searchHint: historySearchHint,
|
|
57706
58231
|
onCall: (call) => {
|
|
57707
58232
|
haptic.impactLight();
|
|
57708
58233
|
setDialValue(historyPhoneDigits(call));
|
|
@@ -57820,6 +58345,7 @@ function AuthenticatedMobileDialer({
|
|
|
57820
58345
|
{
|
|
57821
58346
|
isOpen: isClientInfoModalOpen,
|
|
57822
58347
|
campaignCallInfo,
|
|
58348
|
+
campaignContactPhoneId: ((_d = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _d.campaignContactPhoneId) ?? null,
|
|
57823
58349
|
callDuration: callDurationSeconds,
|
|
57824
58350
|
isCallActive: isInCall || isConnecting,
|
|
57825
58351
|
onClose: () => setIsClientInfoModalOpen(false)
|
|
@@ -58087,18 +58613,21 @@ function InlineDialer({ variant = "default", portalTarget, isAuthenticated, mode
|
|
|
58087
58613
|
if (!isAuthenticated || !isMiniMode) {
|
|
58088
58614
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(FloatingDialer, { variant, portalTarget, isAuthenticated, ...props });
|
|
58089
58615
|
}
|
|
58090
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(AuthenticatedMiniDialer, { ...props });
|
|
58616
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(AuthenticatedMiniDialer, { portalTarget, ...props });
|
|
58091
58617
|
}
|
|
58092
58618
|
function AuthenticatedMiniDialer({
|
|
58093
58619
|
username,
|
|
58094
58620
|
onLogin,
|
|
58095
58621
|
onLogout,
|
|
58096
58622
|
isLoadingSession,
|
|
58097
|
-
sessionError
|
|
58623
|
+
sessionError,
|
|
58624
|
+
portalTarget
|
|
58098
58625
|
}) {
|
|
58626
|
+
var _a2;
|
|
58099
58627
|
const { skipManualQualification } = useDialerConfig();
|
|
58100
58628
|
const operatorState = clientSdkReactExports.useCallOperatorState();
|
|
58101
58629
|
const currentCallInfo = clientSdkReactExports.useCallOperatorCurrentCallInfo();
|
|
58630
|
+
const currentCall = clientSdkReactExports.useCallOperatorCurrentCall();
|
|
58102
58631
|
const rawSuccessQualifications = clientSdkReactExports.useCallOperatorSuccessQualifications();
|
|
58103
58632
|
const rawDiscardQualifications = clientSdkReactExports.useCallOperatorDiscardQualifications();
|
|
58104
58633
|
const successQualifications = useMemo(() => rawSuccessQualifications ?? [], [rawSuccessQualifications]);
|
|
@@ -58354,9 +58883,11 @@ function AuthenticatedMiniDialer({
|
|
|
58354
58883
|
{
|
|
58355
58884
|
isOpen: isClientInfoModalOpen,
|
|
58356
58885
|
campaignCallInfo,
|
|
58886
|
+
campaignContactPhoneId: ((_a2 = currentCall == null ? void 0 : currentCall.data) == null ? void 0 : _a2.campaignContactPhoneId) ?? null,
|
|
58357
58887
|
callDuration: callDurationSeconds,
|
|
58358
58888
|
isCallActive: isInCall || isConnecting,
|
|
58359
|
-
onClose: () => setIsClientInfoModalOpen(false)
|
|
58889
|
+
onClose: () => setIsClientInfoModalOpen(false),
|
|
58890
|
+
portalTarget
|
|
58360
58891
|
}
|
|
58361
58892
|
),
|
|
58362
58893
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -58376,7 +58907,229 @@ function AuthenticatedMiniDialer({
|
|
|
58376
58907
|
)
|
|
58377
58908
|
] });
|
|
58378
58909
|
}
|
|
58379
|
-
const
|
|
58910
|
+
const DEFAULT_CLICK_TO_CALL_INTERVAL_MS = 4e3;
|
|
58911
|
+
const BUSY_INTERVAL_FACTOR = 3;
|
|
58912
|
+
const DISPATCH_COOLDOWN_MS = 6e3;
|
|
58913
|
+
const CALL_START_TIMEOUT_MS = 4e3;
|
|
58914
|
+
const CALL_START_CHECK_MS = 100;
|
|
58915
|
+
const MAX_BACKOFF_MS = 6e4;
|
|
58916
|
+
const NOT_CONFIGURED_INTERVAL_MS = 5 * 6e4;
|
|
58917
|
+
const NOT_CONFIGURED_CODES = /* @__PURE__ */ new Set(["STORE_NOT_CONFIGURED", "SERVER_NOT_CONFIGURED"]);
|
|
58918
|
+
const ACK_ATTEMPTS = 3;
|
|
58919
|
+
const ACK_RETRY_DELAY_MS = 1500;
|
|
58920
|
+
const CALL_STARTED_STATES = /* @__PURE__ */ new Set(["manualCallSetup", "manualCallRinging", "callInProgress", "afterCall"]);
|
|
58921
|
+
function buildHeaders(sessionToken) {
|
|
58922
|
+
if (sessionToken) {
|
|
58923
|
+
return { "Content-Type": "application/json", "x-session-token": sessionToken, Authorization: `Bearer ${sessionToken}` };
|
|
58924
|
+
}
|
|
58925
|
+
return getAuthHeaders();
|
|
58926
|
+
}
|
|
58927
|
+
const delay = (ms2) => new Promise((resolve) => setTimeout(resolve, ms2));
|
|
58928
|
+
function ClickToCallAgent({ enabled = true, pollIntervalMs, sessionToken, onTask }) {
|
|
58929
|
+
const operatorState = clientSdkReactExports.useCallOperatorState();
|
|
58930
|
+
const { makeManualCall } = clientSdkReactExports.useCallOperatorControls();
|
|
58931
|
+
const stateRef = useRef(operatorState == null ? void 0 : operatorState.state);
|
|
58932
|
+
stateRef.current = operatorState == null ? void 0 : operatorState.state;
|
|
58933
|
+
const makeManualCallRef = useRef(makeManualCall);
|
|
58934
|
+
makeManualCallRef.current = makeManualCall;
|
|
58935
|
+
const onTaskRef = useRef(onTask);
|
|
58936
|
+
onTaskRef.current = onTask;
|
|
58937
|
+
const tickerRef = useRef(null);
|
|
58938
|
+
const applyIntervalRef = useRef(null);
|
|
58939
|
+
useEffect(() => {
|
|
58940
|
+
var _a2;
|
|
58941
|
+
(_a2 = applyIntervalRef.current) == null ? void 0 : _a2.call(applyIntervalRef);
|
|
58942
|
+
}, [operatorState == null ? void 0 : operatorState.state]);
|
|
58943
|
+
useEffect(() => {
|
|
58944
|
+
if (!enabled) {
|
|
58945
|
+
return void 0;
|
|
58946
|
+
}
|
|
58947
|
+
let disposed = false;
|
|
58948
|
+
let inFlight = false;
|
|
58949
|
+
let cooldownUntil = 0;
|
|
58950
|
+
let failureStreak = 0;
|
|
58951
|
+
let mode2 = "normal";
|
|
58952
|
+
let notConfiguredWarned = false;
|
|
58953
|
+
let presenceTtlMs = 45e3;
|
|
58954
|
+
let baseInterval = Math.max(1e3, pollIntervalMs ?? DEFAULT_CLICK_TO_CALL_INTERVAL_MS);
|
|
58955
|
+
const config = { apiBaseUrl: API_BASE_URL, headers: buildHeaders(sessionToken) };
|
|
58956
|
+
const computeInterval = () => {
|
|
58957
|
+
if (mode2 === "notConfigured") {
|
|
58958
|
+
return NOT_CONFIGURED_INTERVAL_MS;
|
|
58959
|
+
}
|
|
58960
|
+
const ceiling = Math.max(1e3, Math.floor(presenceTtlMs / 2));
|
|
58961
|
+
const base = Math.min(baseInterval, ceiling);
|
|
58962
|
+
if (mode2 === "backoff") {
|
|
58963
|
+
return Math.min(base * 2 ** failureStreak, MAX_BACKOFF_MS);
|
|
58964
|
+
}
|
|
58965
|
+
const busy = Math.min(base * BUSY_INTERVAL_FACTOR, ceiling);
|
|
58966
|
+
return canDispatchTo(presenceFromOperatorState(stateRef.current)) ? base : busy;
|
|
58967
|
+
};
|
|
58968
|
+
const applyInterval = () => {
|
|
58969
|
+
var _a2;
|
|
58970
|
+
return (_a2 = tickerRef.current) == null ? void 0 : _a2.setInterval(computeInterval());
|
|
58971
|
+
};
|
|
58972
|
+
applyIntervalRef.current = applyInterval;
|
|
58973
|
+
const ack = async (options) => {
|
|
58974
|
+
for (let attempt = 0; attempt < ACK_ATTEMPTS; attempt++) {
|
|
58975
|
+
try {
|
|
58976
|
+
const result2 = await ackClickToCall({ ...config, ...options });
|
|
58977
|
+
if (result2.ok) {
|
|
58978
|
+
return true;
|
|
58979
|
+
}
|
|
58980
|
+
const retryable = result2.status >= 500 || result2.status === 408 || result2.status === 429;
|
|
58981
|
+
if (!retryable) {
|
|
58982
|
+
console.warn("[ClickToCall] confirmação recusada pelo servidor:", result2.status, result2.code ?? "", "(tarefa", options.taskId, ")");
|
|
58983
|
+
return false;
|
|
58984
|
+
}
|
|
58985
|
+
} catch (error2) {
|
|
58986
|
+
console.warn("[ClickToCall] confirmação falhou (tentativa", attempt + 1, "):", error2 instanceof Error ? error2.message : error2);
|
|
58987
|
+
}
|
|
58988
|
+
if (disposed || attempt === ACK_ATTEMPTS - 1) {
|
|
58989
|
+
break;
|
|
58990
|
+
}
|
|
58991
|
+
await delay(ACK_RETRY_DELAY_MS * (attempt + 1));
|
|
58992
|
+
}
|
|
58993
|
+
console.error("[ClickToCall] não foi possível confirmar a tarefa", options.taskId, "; o servidor a marcará como não confirmada");
|
|
58994
|
+
return false;
|
|
58995
|
+
};
|
|
58996
|
+
const waitForCallStart = () => new Promise((resolve) => {
|
|
58997
|
+
const deadline = Date.now() + CALL_START_TIMEOUT_MS;
|
|
58998
|
+
const check = () => {
|
|
58999
|
+
if (disposed) return resolve("disposed");
|
|
59000
|
+
const state = stateRef.current;
|
|
59001
|
+
if (state && CALL_STARTED_STATES.has(state)) return resolve("started");
|
|
59002
|
+
if (state === "manualCallFailed") return resolve("manual_failed");
|
|
59003
|
+
if (state === "callRinging" || presenceFromOperatorState(state) === "offline") return resolve("interrupted");
|
|
59004
|
+
if (Date.now() >= deadline) return resolve("not_started");
|
|
59005
|
+
setTimeout(check, CALL_START_CHECK_MS);
|
|
59006
|
+
};
|
|
59007
|
+
check();
|
|
59008
|
+
});
|
|
59009
|
+
const dispatch = async (task) => {
|
|
59010
|
+
var _a2;
|
|
59011
|
+
const state = stateRef.current;
|
|
59012
|
+
cooldownUntil = Date.now() + DISPATCH_COOLDOWN_MS;
|
|
59013
|
+
if (!canDispatchTo(presenceFromOperatorState(state))) {
|
|
59014
|
+
console.warn("[ClickToCall] tarefa", task.id, "recebida com operador ocupado (", state, "): devolvendo à fila");
|
|
59015
|
+
await ack({ taskId: task.id, status: "failed", error: `Operador indisponível (${state ?? "desconhecido"})`, retry: true });
|
|
59016
|
+
return;
|
|
59017
|
+
}
|
|
59018
|
+
console.log("[ClickToCall] 🖱️ ligação pedida pela API:", task.phoneDisplay, "(tarefa", task.id, ")");
|
|
59019
|
+
try {
|
|
59020
|
+
window.dispatchEvent(new CustomEvent(CLICK_TO_CALL_EVENT, { detail: task }));
|
|
59021
|
+
} catch (error2) {
|
|
59022
|
+
console.warn("[ClickToCall] falha ao notificar o discador:", error2);
|
|
59023
|
+
}
|
|
59024
|
+
try {
|
|
59025
|
+
(_a2 = onTaskRef.current) == null ? void 0 : _a2.call(onTaskRef, task);
|
|
59026
|
+
} catch (error2) {
|
|
59027
|
+
console.warn("[ClickToCall] onTask lançou erro:", error2);
|
|
59028
|
+
}
|
|
59029
|
+
try {
|
|
59030
|
+
makeManualCallRef.current(task.phone);
|
|
59031
|
+
} catch (error2) {
|
|
59032
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
59033
|
+
console.error("[ClickToCall] makeManualCall falhou:", message);
|
|
59034
|
+
await ack({ taskId: task.id, status: "failed", error: message, retry: false });
|
|
59035
|
+
return;
|
|
59036
|
+
}
|
|
59037
|
+
const outcome = await waitForCallStart();
|
|
59038
|
+
switch (outcome) {
|
|
59039
|
+
case "started":
|
|
59040
|
+
await ack({ taskId: task.id, status: "calling" });
|
|
59041
|
+
return;
|
|
59042
|
+
case "manual_failed":
|
|
59043
|
+
console.error("[ClickToCall] o SDK não conseguiu completar a chamada manual");
|
|
59044
|
+
await ack({ taskId: task.id, status: "failed", error: "Chamada manual falhou no SDK", retry: false });
|
|
59045
|
+
return;
|
|
59046
|
+
case "interrupted":
|
|
59047
|
+
console.warn("[ClickToCall] chamada manual não aconteceu (estado", stateRef.current, "): devolvendo à fila");
|
|
59048
|
+
await ack({ taskId: task.id, status: "failed", error: `Discador interrompido (${stateRef.current ?? "desconhecido"})`, retry: true });
|
|
59049
|
+
return;
|
|
59050
|
+
case "disposed":
|
|
59051
|
+
await ack({ taskId: task.id, status: "failed", error: "Discador encerrado durante a discagem", retry: true });
|
|
59052
|
+
return;
|
|
59053
|
+
default: {
|
|
59054
|
+
const message = `SDK não iniciou a chamada (estado continua ${stateRef.current ?? "desconhecido"})`;
|
|
59055
|
+
console.error("[ClickToCall]", message);
|
|
59056
|
+
await ack({ taskId: task.id, status: "failed", error: message, retry: false });
|
|
59057
|
+
}
|
|
59058
|
+
}
|
|
59059
|
+
};
|
|
59060
|
+
const tick = async () => {
|
|
59061
|
+
if (disposed || inFlight) {
|
|
59062
|
+
return;
|
|
59063
|
+
}
|
|
59064
|
+
inFlight = true;
|
|
59065
|
+
try {
|
|
59066
|
+
const state = stateRef.current;
|
|
59067
|
+
const claim = canDispatchTo(presenceFromOperatorState(state)) && Date.now() >= cooldownUntil;
|
|
59068
|
+
let result2;
|
|
59069
|
+
try {
|
|
59070
|
+
result2 = await pollClickToCall({ ...config, state, claim });
|
|
59071
|
+
} catch (error2) {
|
|
59072
|
+
result2 = { ok: false, status: 0, code: error2 instanceof Error && error2.name === "AbortError" ? "TIMEOUT" : "NETWORK" };
|
|
59073
|
+
}
|
|
59074
|
+
if (disposed) {
|
|
59075
|
+
if (result2.ok && result2.task) {
|
|
59076
|
+
await ack({ taskId: result2.task.id, status: "failed", error: "Discador encerrado antes de discar", retry: true });
|
|
59077
|
+
}
|
|
59078
|
+
return;
|
|
59079
|
+
}
|
|
59080
|
+
if (!result2.ok) {
|
|
59081
|
+
failureStreak += 1;
|
|
59082
|
+
const notConfigured = result2.code !== null && NOT_CONFIGURED_CODES.has(result2.code);
|
|
59083
|
+
mode2 = notConfigured ? "notConfigured" : "backoff";
|
|
59084
|
+
if (notConfigured) {
|
|
59085
|
+
if (!notConfiguredWarned) {
|
|
59086
|
+
notConfiguredWarned = true;
|
|
59087
|
+
console.warn("[ClickToCall] backend sem click-to-call configurado (", result2.code, "); nova tentativa em 5 min");
|
|
59088
|
+
}
|
|
59089
|
+
} else if (failureStreak === 1) {
|
|
59090
|
+
console.warn("[ClickToCall] polling falhou (HTTP", result2.status, result2.code ?? "", "); aplicando backoff");
|
|
59091
|
+
}
|
|
59092
|
+
applyInterval();
|
|
59093
|
+
return;
|
|
59094
|
+
}
|
|
59095
|
+
if (mode2 !== "normal") {
|
|
59096
|
+
mode2 = "normal";
|
|
59097
|
+
failureStreak = 0;
|
|
59098
|
+
}
|
|
59099
|
+
presenceTtlMs = result2.presenceTtlSeconds * 1e3;
|
|
59100
|
+
if (pollIntervalMs === void 0 && result2.pollIntervalMs > 0) {
|
|
59101
|
+
baseInterval = Math.max(1e3, result2.pollIntervalMs);
|
|
59102
|
+
}
|
|
59103
|
+
applyInterval();
|
|
59104
|
+
if (result2.task) {
|
|
59105
|
+
try {
|
|
59106
|
+
await dispatch(result2.task);
|
|
59107
|
+
} catch (error2) {
|
|
59108
|
+
console.error("[ClickToCall] erro ao tratar a tarefa", result2.task.id, ":", error2 instanceof Error ? error2.message : error2);
|
|
59109
|
+
}
|
|
59110
|
+
}
|
|
59111
|
+
} finally {
|
|
59112
|
+
inFlight = false;
|
|
59113
|
+
}
|
|
59114
|
+
};
|
|
59115
|
+
const ticker = createBackgroundTicker(() => void tick(), computeInterval());
|
|
59116
|
+
tickerRef.current = ticker;
|
|
59117
|
+
void tick();
|
|
59118
|
+
return () => {
|
|
59119
|
+
disposed = true;
|
|
59120
|
+
ticker.stop();
|
|
59121
|
+
if (tickerRef.current === ticker) {
|
|
59122
|
+
tickerRef.current = null;
|
|
59123
|
+
}
|
|
59124
|
+
if (applyIntervalRef.current === applyInterval) {
|
|
59125
|
+
applyIntervalRef.current = null;
|
|
59126
|
+
}
|
|
59127
|
+
reportClickToCallOffline(config);
|
|
59128
|
+
};
|
|
59129
|
+
}, [enabled, pollIntervalMs, sessionToken]);
|
|
59130
|
+
return null;
|
|
59131
|
+
}
|
|
59132
|
+
const WIDGET_VERSION = "2.4.0";
|
|
58380
59133
|
let currentSipWebSocket = null;
|
|
58381
59134
|
function sendSipUnregisterIfPossible(ws) {
|
|
58382
59135
|
if (ws.readyState !== WebSocket.OPEN) return;
|
|
@@ -58576,8 +59329,25 @@ function deriveOptionsFromElement(element) {
|
|
|
58576
59329
|
if (datasetAutoLogin !== void 0 && datasetAutoLogin !== null) {
|
|
58577
59330
|
result2.autoLogin = ["true", "1", "yes", ""].includes(datasetAutoLogin.trim().toLowerCase());
|
|
58578
59331
|
}
|
|
59332
|
+
const datasetDensity = parseDensity(element.getAttribute("data-callix-density") ?? element.dataset.callixDensity);
|
|
59333
|
+
if (datasetDensity) {
|
|
59334
|
+
result2.density = datasetDensity;
|
|
59335
|
+
}
|
|
59336
|
+
const datasetClickToCall = element.getAttribute("data-callix-click-to-call") ?? element.dataset.callixClickToCall;
|
|
59337
|
+
if (datasetClickToCall !== void 0 && datasetClickToCall !== null) {
|
|
59338
|
+
result2.clickToCall = !["false", "0", "no", "off"].includes(datasetClickToCall.trim().toLowerCase());
|
|
59339
|
+
}
|
|
58579
59340
|
return result2;
|
|
58580
59341
|
}
|
|
59342
|
+
function normalizeClickToCallOptions(value) {
|
|
59343
|
+
if (value === false) {
|
|
59344
|
+
return { enabled: false };
|
|
59345
|
+
}
|
|
59346
|
+
if (value === true || value === void 0 || value === null) {
|
|
59347
|
+
return { enabled: true };
|
|
59348
|
+
}
|
|
59349
|
+
return { ...value, enabled: value.enabled !== false };
|
|
59350
|
+
}
|
|
58581
59351
|
class CallixDialerWidget {
|
|
58582
59352
|
constructor(options) {
|
|
58583
59353
|
this.root = null;
|
|
@@ -58608,9 +59378,11 @@ class CallixDialerWidget {
|
|
|
58608
59378
|
if (this.options.autoLogin === void 0 && derived.autoLogin !== void 0) {
|
|
58609
59379
|
this.options.autoLogin = derived.autoLogin;
|
|
58610
59380
|
}
|
|
58611
|
-
if (this.options.
|
|
58612
|
-
this.
|
|
58613
|
-
|
|
59381
|
+
if (this.options.density === void 0 && derived.density !== void 0) {
|
|
59382
|
+
this.options.density = derived.density;
|
|
59383
|
+
}
|
|
59384
|
+
if (this.options.clickToCall === void 0 && derived.clickToCall !== void 0) {
|
|
59385
|
+
this.options.clickToCall = derived.clickToCall;
|
|
58614
59386
|
}
|
|
58615
59387
|
this.root = clientExports.createRoot(this.container);
|
|
58616
59388
|
this.root.render(
|
|
@@ -58954,6 +59726,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
58954
59726
|
}, []);
|
|
58955
59727
|
const DialerComponent = options.mode === "inline" || uiVariant === "mobile" ? InlineDialer : FloatingDialer;
|
|
58956
59728
|
const dialerMode = options.mode;
|
|
59729
|
+
const clickToCall = normalizeClickToCallOptions(options.clickToCall);
|
|
58957
59730
|
if (isDisconnecting) {
|
|
58958
59731
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(DialerConfigContext.Provider, { value: { skipManualQualification }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
58959
59732
|
DialerComponent,
|
|
@@ -58967,6 +59740,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
58967
59740
|
sessionStatus: "Encerrando sessão anterior...",
|
|
58968
59741
|
variant: uiVariant,
|
|
58969
59742
|
portalTarget,
|
|
59743
|
+
density: options.density,
|
|
58970
59744
|
mode: dialerMode
|
|
58971
59745
|
}
|
|
58972
59746
|
) });
|
|
@@ -58986,6 +59760,7 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
58986
59760
|
onCancelLoginConfirmation: handleCancelLoginConfirmation,
|
|
58987
59761
|
variant: uiVariant,
|
|
58988
59762
|
portalTarget,
|
|
59763
|
+
density: options.density,
|
|
58989
59764
|
mode: dialerMode
|
|
58990
59765
|
}
|
|
58991
59766
|
) });
|
|
@@ -58995,21 +59770,33 @@ function DialerWrapper({ options, containerEl }) {
|
|
|
58995
59770
|
{
|
|
58996
59771
|
domain: callixDomain,
|
|
58997
59772
|
userSessionToken: sessionToken,
|
|
58998
|
-
children: /* @__PURE__ */ jsxRuntimeExports.
|
|
58999
|
-
|
|
59000
|
-
|
|
59001
|
-
|
|
59002
|
-
|
|
59003
|
-
|
|
59004
|
-
|
|
59005
|
-
|
|
59006
|
-
|
|
59007
|
-
|
|
59008
|
-
|
|
59009
|
-
|
|
59010
|
-
|
|
59011
|
-
|
|
59012
|
-
|
|
59773
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(SdkCleanupManager, { ref: cleanupRef, children: [
|
|
59774
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
59775
|
+
DialerComponent,
|
|
59776
|
+
{
|
|
59777
|
+
isAuthenticated,
|
|
59778
|
+
username,
|
|
59779
|
+
onLogin: handleLogin,
|
|
59780
|
+
onLogout: handleLogout,
|
|
59781
|
+
isLoadingSession: isLoading,
|
|
59782
|
+
sessionError: error2,
|
|
59783
|
+
sessionStatus: loginStatus,
|
|
59784
|
+
variant: uiVariant,
|
|
59785
|
+
portalTarget,
|
|
59786
|
+
density: options.density,
|
|
59787
|
+
mode: dialerMode
|
|
59788
|
+
}
|
|
59789
|
+
),
|
|
59790
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
59791
|
+
ClickToCallAgent,
|
|
59792
|
+
{
|
|
59793
|
+
enabled: clickToCall.enabled,
|
|
59794
|
+
pollIntervalMs: clickToCall.pollIntervalMs,
|
|
59795
|
+
sessionToken,
|
|
59796
|
+
onTask: clickToCall.onTask
|
|
59797
|
+
}
|
|
59798
|
+
)
|
|
59799
|
+
] })
|
|
59013
59800
|
},
|
|
59014
59801
|
providerKey
|
|
59015
59802
|
) });
|