@credithub/harlan-components 1.128.0 → 1.130.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/dist/components/chart/chartSystem.js +28 -12
- package/dist/components/chart/hooks/useChartData.d.ts +3 -1
- package/dist/components/chart/hooks/useChartData.js +30 -7
- package/dist/components/chart/utils/dataProcessing.js +0 -7
- package/dist/components/dossie/generativeAi/generativeAi.js +10 -4
- package/dist/components/liminar/liminar.js +27 -5
- package/dist/components/protestos/protestosSp.js +1 -3
- package/dist/components/requestContextTypes.d.ts +7 -0
- package/dist/components/scoreSerasa/scoreSerasa.js +15 -6
- package/dist/components/scoreSerasa/scoreSerasaProbUtils.d.ts +24 -0
- package/dist/components/scoreSerasa/scoreSerasaProbUtils.js +66 -0
- package/dist/components/section.d.ts +2 -0
- package/dist/components/section.js +42 -14
- package/dist/components/streamQuery.js +16 -6
- package/dist/components/webservice.d.ts +2 -1
- package/dist/components/webservice.js +55 -31
- package/dist/contexts/createDataContext.js +3 -3
- package/dist/dev/manualPushSectionPreview.d.ts +2 -0
- package/dist/dev/manualPushSectionPreview.js +42 -0
- package/dist/hooks/useSafeQuery.d.ts +1 -0
- package/dist/utils/classifyRequestError.d.ts +9 -0
- package/dist/utils/classifyRequestError.js +26 -0
- package/lib/cjs/index.js +311 -95
- package/lib/esm/index.js +312 -96
- package/package.json +5 -3
|
@@ -14,7 +14,8 @@ import { ConsultasComplementaresContext } from '../consultasComplementares';
|
|
|
14
14
|
import { ButtonsSummary, SummaryButton } from '../dossie/summary/styles';
|
|
15
15
|
import { getProductsPrices } from '../dossie/summary/utils';
|
|
16
16
|
import StatusMessage from '../interface/statusMessage';
|
|
17
|
-
import Section from '../section';
|
|
17
|
+
import Section, { pushExceptionDescription } from '../section';
|
|
18
|
+
import { isErrorWithPushFlag } from '../../utils/classifyRequestError';
|
|
18
19
|
import { RequestStatus } from '../webservice';
|
|
19
20
|
import ChartContent from './chartContent';
|
|
20
21
|
import useChartData from './hooks/useChartData';
|
|
@@ -90,7 +91,7 @@ var ChartSystem = function (_a) {
|
|
|
90
91
|
});
|
|
91
92
|
}); };
|
|
92
93
|
}, [loadingButtons, hasCredits, productsPrices, setConsultasComplementares]);
|
|
93
|
-
var _p = useChartData(consultaSerasa, consultaBoaVista), chartData = _p.data, isLoadingChart = _p.isLoading, errorChart = _p.error, refetchChart = _p.refetch, chartDataProgress = _p.loadingProgress;
|
|
94
|
+
var _p = useChartData(consultaSerasa, consultaBoaVista), chartData = _p.data, isLoadingChart = _p.isLoading, errorChart = _p.error, chartUpstreamFailed = _p.upstreamRequestFailed, refetchChart = _p.refetch, chartDataProgress = _p.loadingProgress;
|
|
94
95
|
var _q = useDividasPublicas(), quantidadeDividas = _q.quantidade, valorTotalDividas = _q.valorTotal, ultimaOcorrenciaDividas = _q.ultimaOcorrencia, dividasProgress = _q.loadingProgress;
|
|
95
96
|
var lastComplementary = useRef({
|
|
96
97
|
serasa: null,
|
|
@@ -99,7 +100,14 @@ var ChartSystem = function (_a) {
|
|
|
99
100
|
// Evita escrever documentHistory repetidamente com o mesmo conteúdo
|
|
100
101
|
var lastDocHistorySigRef = useRef('');
|
|
101
102
|
// (refetch de histórico por mudança complementar centralizado no hook useChartData)
|
|
102
|
-
var
|
|
103
|
+
var chartHasError = chartUpstreamFailed || errorChart != null;
|
|
104
|
+
var errorMessage = errorChart instanceof Error
|
|
105
|
+
? errorChart
|
|
106
|
+
: typeof errorChart === 'string'
|
|
107
|
+
? new Error(errorChart)
|
|
108
|
+
: chartUpstreamFailed
|
|
109
|
+
? new Error()
|
|
110
|
+
: null;
|
|
103
111
|
var isOpen = useToggle(true)[0];
|
|
104
112
|
// Usa valores já calculados de globalData.protestosData (calculados uma única vez em protestos.tsx)
|
|
105
113
|
var quantidadeProtestos = (_g = (_f = globalData === null || globalData === void 0 ? void 0 : globalData.protestosData) === null || _f === void 0 ? void 0 : _f.totalProtestos) !== null && _g !== void 0 ? _g : 0;
|
|
@@ -231,10 +239,10 @@ var ChartSystem = function (_a) {
|
|
|
231
239
|
response: undefined,
|
|
232
240
|
type: isLoadingChart
|
|
233
241
|
? RequestStatus.Loading
|
|
234
|
-
:
|
|
242
|
+
: chartHasError
|
|
235
243
|
? RequestStatus.Error
|
|
236
244
|
: RequestStatus.Success,
|
|
237
|
-
error: errorMessage
|
|
245
|
+
error: errorMessage,
|
|
238
246
|
refetch: refetchChart,
|
|
239
247
|
document: chartData,
|
|
240
248
|
progress: loadingProgress,
|
|
@@ -267,13 +275,21 @@ var ChartSystem = function (_a) {
|
|
|
267
275
|
: undefined, ultimaOcorrenciaPefinSerasa: Array.isArray(chartData === null || chartData === void 0 ? void 0 : chartData.serasa) && chartData.serasa.length > 0
|
|
268
276
|
? (ultimaOcorrenciaSerasa !== null && ultimaOcorrenciaSerasa !== void 0 ? ultimaOcorrenciaSerasa : undefined)
|
|
269
277
|
: undefined })));
|
|
270
|
-
}, isError: function (err) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
278
|
+
}, isError: function (err) {
|
|
279
|
+
return isErrorWithPushFlag(err)
|
|
280
|
+
? {
|
|
281
|
+
children: React.createElement(React.Fragment, null),
|
|
282
|
+
description: pushExceptionDescription(err),
|
|
283
|
+
variant: 'default'
|
|
284
|
+
}
|
|
285
|
+
: {
|
|
286
|
+
children: React.createElement(React.Fragment, null),
|
|
287
|
+
description: (React.createElement(StatusMessage, { type: "error" },
|
|
288
|
+
"Erro ao realizar a an\u00E1lise: ",
|
|
289
|
+
err.message)),
|
|
290
|
+
variant: 'error'
|
|
291
|
+
};
|
|
292
|
+
} }));
|
|
277
293
|
};
|
|
278
294
|
export default ChartSystem;
|
|
279
295
|
var templateObject_1;
|
|
@@ -2,7 +2,9 @@ import { DataInput } from '../../../components/chart/types/iChart';
|
|
|
2
2
|
declare const useChartData: (consultaSerasa: any, consultaBoaVista: any) => {
|
|
3
3
|
data: DataInput | null;
|
|
4
4
|
isLoading: boolean;
|
|
5
|
-
error:
|
|
5
|
+
error: Error | null;
|
|
6
|
+
/** True quando Histórico/Protestos/CCF estão em Error (mesmo sem mensagem no Error). */
|
|
7
|
+
upstreamRequestFailed: boolean;
|
|
6
8
|
refetch: () => void;
|
|
7
9
|
loadingProgress: number;
|
|
8
10
|
};
|
|
@@ -37,7 +37,11 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
37
37
|
var _g = useState(false), isProcessing = _g[0], setIsProcessing = _g[1];
|
|
38
38
|
var _h = useState(false), dataReady = _h[0], setDataReady = _h[1];
|
|
39
39
|
var lastProgress = useRef(0);
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Evita reprocessar em vão. Inclui totais do IEPTB (globalData) para atualizar o pie
|
|
42
|
+
* quando o JSON do DOCUMENTHISTORY for o mesmo; a série `protestos` do gráfico vem
|
|
43
|
+
* só do histórico em `processData` (sem override com IEPTB).
|
|
44
|
+
*/
|
|
41
45
|
var lastProcessSnapshotKey = useRef(null);
|
|
42
46
|
var processingTimeout = useRef(null);
|
|
43
47
|
var ctxHistory = useContext(Queries.GraficosAnaliticos);
|
|
@@ -155,6 +159,7 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
155
159
|
boaVista: null
|
|
156
160
|
});
|
|
157
161
|
useEffect(function () {
|
|
162
|
+
var _a;
|
|
158
163
|
var serasaChanged = consultaSerasa !== lastComplementary.current.serasa;
|
|
159
164
|
var boaVistaChanged = consultaBoaVista !== lastComplementary.current.boaVista;
|
|
160
165
|
if (serasaChanged || boaVistaChanged) {
|
|
@@ -162,7 +167,12 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
162
167
|
serasa: consultaSerasa,
|
|
163
168
|
boaVista: consultaBoaVista
|
|
164
169
|
};
|
|
165
|
-
ctxHistory.
|
|
170
|
+
if (ctxHistory.type !== RequestStatus.Error) {
|
|
171
|
+
ctxHistory.refetch();
|
|
172
|
+
}
|
|
173
|
+
else if ((_a = import.meta.env) === null || _a === void 0 ? void 0 : _a.DEV) {
|
|
174
|
+
console.debug('[useChartData] refetch de histórico ignorado: consulta anterior em erro');
|
|
175
|
+
}
|
|
166
176
|
}
|
|
167
177
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
168
178
|
}, [consultaSerasa, consultaBoaVista]);
|
|
@@ -172,8 +182,12 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
172
182
|
ctxProtestos.type === RequestStatus.Success &&
|
|
173
183
|
ctxCCF.type === RequestStatus.Success;
|
|
174
184
|
}, [ctxHistory.type, ctxProtestos.type, ctxCCF.type]);
|
|
185
|
+
var upstreamRequestFailed = useMemo(function () {
|
|
186
|
+
return ctxHistory.type === RequestStatus.Error ||
|
|
187
|
+
ctxProtestos.type === RequestStatus.Error ||
|
|
188
|
+
ctxCCF.type === RequestStatus.Error;
|
|
189
|
+
}, [ctxHistory.type, ctxProtestos.type, ctxCCF.type]);
|
|
175
190
|
useEffect(function () {
|
|
176
|
-
var _a;
|
|
177
191
|
// Limpa timeout anterior se existir
|
|
178
192
|
if (processingTimeout.current) {
|
|
179
193
|
clearTimeout(processingTimeout.current);
|
|
@@ -189,8 +203,13 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
189
203
|
setIsProcessing(false);
|
|
190
204
|
return;
|
|
191
205
|
}
|
|
192
|
-
if (
|
|
193
|
-
|
|
206
|
+
if (upstreamRequestFailed) {
|
|
207
|
+
var err = ctxHistory.type === RequestStatus.Error
|
|
208
|
+
? ctxHistory.error
|
|
209
|
+
: ctxProtestos.type === RequestStatus.Error
|
|
210
|
+
? ctxProtestos.error
|
|
211
|
+
: ctxCCF.error;
|
|
212
|
+
setErrorState(err !== null && err !== void 0 ? err : null);
|
|
194
213
|
setIsProcessing(false);
|
|
195
214
|
setDataReady(false);
|
|
196
215
|
lastProcessSnapshotKey.current = null;
|
|
@@ -232,7 +251,7 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
232
251
|
}
|
|
233
252
|
catch (error) {
|
|
234
253
|
console.error('[useChartData] Erro ao processar dados:', error);
|
|
235
|
-
setErrorState(
|
|
254
|
+
setErrorState(error instanceof Error ? error : new Error(String(error)));
|
|
236
255
|
setIsProcessing(false);
|
|
237
256
|
setDataReady(false);
|
|
238
257
|
lastProcessSnapshotKey.current = null;
|
|
@@ -264,11 +283,15 @@ var useChartData = function (consultaSerasa, consultaBoaVista) {
|
|
|
264
283
|
// Verifica se está carregando - aguarda TODOS os contextos necessários terminarem
|
|
265
284
|
// E aguarda o processamento E renderização dos dados estar completo
|
|
266
285
|
// Só sai de loading quando dataReady === true (todos os contextos prontos + dados processados)
|
|
267
|
-
var isLoading = !
|
|
286
|
+
var isLoading = !upstreamRequestFailed &&
|
|
287
|
+
errorState == null &&
|
|
288
|
+
(!dataReady || isProcessing || !allContextsReady);
|
|
268
289
|
return {
|
|
269
290
|
data: data,
|
|
270
291
|
isLoading: isLoading,
|
|
271
292
|
error: errorState,
|
|
293
|
+
/** True quando Histórico/Protestos/CCF estão em Error (mesmo sem mensagem no Error). */
|
|
294
|
+
upstreamRequestFailed: upstreamRequestFailed,
|
|
272
295
|
refetch: ctxHistory.refetch,
|
|
273
296
|
loadingProgress: loadingProgress
|
|
274
297
|
};
|
|
@@ -75,13 +75,6 @@ export var processData = function (data, quantidadeProcessosJuridicos, totalProt
|
|
|
75
75
|
.filter(removeSameAsNext)
|
|
76
76
|
.map(function (info) { return (__assign(__assign({}, info), { data: parseProtestStringToDate(info.data) })); })
|
|
77
77
|
.filter(function (info) { return !Number.isNaN(info.data.getTime()); }), function (info) { return info.data; });
|
|
78
|
-
/** Alinha o último ponto (data da consulta mais recente no histórico) com os totais ao vivo (mesma fonte que o pie). */
|
|
79
|
-
if (totalProtestos !== undefined && data.protestos.length > 0) {
|
|
80
|
-
var i = data.protestos.length - 1;
|
|
81
|
-
data.protestos[i] = __assign(__assign(__assign({}, data.protestos[i]), { quantidade: totalProtestos }), (valorTotalProtestos !== undefined
|
|
82
|
-
? { valorTotal: valorTotalProtestos }
|
|
83
|
-
: {}));
|
|
84
|
-
}
|
|
85
78
|
// ------------------------------------------------------------------
|
|
86
79
|
// CCFs
|
|
87
80
|
// ------------------------------------------------------------------
|
|
@@ -70,12 +70,16 @@ var GenerativeAI = function (_a) {
|
|
|
70
70
|
var _o = useStreamQuery("SELECT FROM 'LlamaApi'.'Consulta'", summaryQueryData, streamMode === 'summary' && !!summaryQueryData), summaryIterator = _o.responseIterator, summaryError = _o.error, summaryLoading = _o.isLoading, refetchSummary = _o.refetch, abortSummary = _o.abort;
|
|
71
71
|
// Configura a query chat
|
|
72
72
|
var _p = useStreamQuery("SELECT FROM 'LlamaApi'.'Consulta'", chatQueryData, streamMode === 'chat' && !!chatQueryData), chatIterator = _p.responseIterator, chatError = _p.error, chatLoading = _p.isLoading, refetchChat = _p.refetch, abortChat = _p.abort;
|
|
73
|
-
// Dispara o refetch
|
|
73
|
+
// Dispara o refetch quando summaryQueryData mudar, exceto após erro real (evita loop de crédito)
|
|
74
74
|
useEffect(function () {
|
|
75
|
-
|
|
75
|
+
var _a;
|
|
76
|
+
if (summaryQueryData && !summaryError) {
|
|
76
77
|
refetchSummary();
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
+
else if (summaryQueryData && summaryError && ((_a = import.meta.env) === null || _a === void 0 ? void 0 : _a.DEV)) {
|
|
80
|
+
console.debug('[GenerativeAI] refetch summary ignorado: erro na consulta anterior');
|
|
81
|
+
}
|
|
82
|
+
}, [summaryQueryData, refetchSummary, summaryError]);
|
|
79
83
|
// Detecta a transição de refreshQuery de false para true para reiniciar a consulta
|
|
80
84
|
var prevRefreshQueryRef = useRef(refreshQuery);
|
|
81
85
|
useEffect(function () {
|
|
@@ -90,9 +94,11 @@ var GenerativeAI = function (_a) {
|
|
|
90
94
|
}
|
|
91
95
|
// Incrementa o refreshKey para forçar a atualização da query
|
|
92
96
|
setRefreshKey(function (prev) { return prev + 1; });
|
|
97
|
+
// Retry explícito (refresh externo), mesmo se houve erro antes
|
|
98
|
+
refetchSummary();
|
|
93
99
|
}
|
|
94
100
|
prevRefreshQueryRef.current = refreshQuery;
|
|
95
|
-
}, [refreshQuery, abortSummary, streamMode]);
|
|
101
|
+
}, [refreshQuery, abortSummary, streamMode, refetchSummary]);
|
|
96
102
|
// Processa o stream da consulta summary (apenas uma vez)
|
|
97
103
|
var processedSummaryRef = useRef(false);
|
|
98
104
|
useEffect(function () {
|
|
@@ -246,21 +246,43 @@ var Liminar = function (_a) {
|
|
|
246
246
|
return;
|
|
247
247
|
var fetch = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
248
248
|
var dossie, processosJuridicos, depsLoaded, newIds, hash, sourceApi, sourceProcessos, _a, possuiIndiciosDeLiminarProtestosDoPassado, protestosIds, sourceProtestos, combined, finalStatus;
|
|
249
|
-
var _b;
|
|
250
|
-
return __generator(this, function (
|
|
251
|
-
switch (
|
|
249
|
+
var _b, _c, _d;
|
|
250
|
+
return __generator(this, function (_e) {
|
|
251
|
+
switch (_e.label) {
|
|
252
252
|
case 0:
|
|
253
253
|
dossie = globalData === null || globalData === void 0 ? void 0 : globalData.dossie;
|
|
254
254
|
processosJuridicos = globalData === null || globalData === void 0 ? void 0 : globalData.processosJuridicosData;
|
|
255
255
|
depsLoaded = !!(processosJuridicos === null || processosJuridicos === void 0 ? void 0 : processosJuridicos.isLoaded) && !!(dossie === null || dossie === void 0 ? void 0 : dossie.carousel);
|
|
256
256
|
if (!depsLoaded || ctx.type === RequestStatus.Loading)
|
|
257
257
|
return [2 /*return*/];
|
|
258
|
+
if (ctx.type === RequestStatus.Error ||
|
|
259
|
+
(processosJuridicos === null || processosJuridicos === void 0 ? void 0 : processosJuridicos.error) ||
|
|
260
|
+
((_b = globalData === null || globalData === void 0 ? void 0 : globalData.protestosData) === null || _b === void 0 ? void 0 : _b.error)) {
|
|
261
|
+
if ((_c = import.meta.env) === null || _c === void 0 ? void 0 : _c.DEV) {
|
|
262
|
+
console.debug('[Liminar] consulta complementar ignorada: upstream em erro');
|
|
263
|
+
}
|
|
264
|
+
if (!processedRef.current) {
|
|
265
|
+
setData(function (prev) { return (__assign(__assign({}, prev), { liminar: {
|
|
266
|
+
indiciosDeLiminar: false,
|
|
267
|
+
message: 'Não encontrado',
|
|
268
|
+
isLoaded: true,
|
|
269
|
+
processosComLiminarIds: [],
|
|
270
|
+
indiciosDeLiminarProtestosDoPassado: false,
|
|
271
|
+
protestosDoPassadoIds: '',
|
|
272
|
+
invertedProcessos: [],
|
|
273
|
+
origensLiminar: [],
|
|
274
|
+
descricaoLiminar: 'Não encontrado'
|
|
275
|
+
} })); });
|
|
276
|
+
processedRef.current = true;
|
|
277
|
+
}
|
|
278
|
+
return [2 /*return*/];
|
|
279
|
+
}
|
|
258
280
|
newIds = foundBusinessEntity
|
|
259
281
|
? processosComAssuntoValido.map(function (p) { return p.id; })
|
|
260
282
|
: [];
|
|
261
283
|
hash = JSON.stringify({
|
|
262
284
|
t: ctx.type,
|
|
263
|
-
indicios: (
|
|
285
|
+
indicios: (_d = ctx.document) === null || _d === void 0 ? void 0 : _d.indiciosDeLiminar,
|
|
264
286
|
carousel: dossie.carousel,
|
|
265
287
|
empresas: processosJuridicos.empresa
|
|
266
288
|
});
|
|
@@ -273,7 +295,7 @@ var Liminar = function (_a) {
|
|
|
273
295
|
setIsLoadingLiminarProtestosDoPassado(true);
|
|
274
296
|
return [4 /*yield*/, fetchLiminarProtestosDoPassado()];
|
|
275
297
|
case 1:
|
|
276
|
-
_a =
|
|
298
|
+
_a = _e.sent(), possuiIndiciosDeLiminarProtestosDoPassado = _a.possuiIndiciosDeLiminarProtestosDoPassado, protestosIds = _a.protestosDoPassadoIds;
|
|
277
299
|
setIsLoadingLiminarProtestosDoPassado(false);
|
|
278
300
|
sourceProtestos = detectLiminarFromProtestosDoPassado(possuiIndiciosDeLiminarProtestosDoPassado, protestosIds);
|
|
279
301
|
combined = combineLiminarSources([
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ProtestosIcon from '../../assets/icones/protestos';
|
|
2
|
-
import { useGlobalData } from '../../contexts/globalDataContext';
|
|
3
2
|
import { formatMoney } from '../../utils/number';
|
|
4
3
|
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
4
|
import AddItemField from '../common/addItem';
|
|
@@ -9,7 +8,6 @@ import Section from '../section';
|
|
|
9
8
|
import { Queries, RequestStatus } from '../webservice';
|
|
10
9
|
var ProtestosSP = function () {
|
|
11
10
|
var ctxLiminar = useContext(Queries.Liminar);
|
|
12
|
-
var setData = useGlobalData().setData;
|
|
13
11
|
var _a = useState(false), dataUpdated = _a[0], setDataUpdated = _a[1];
|
|
14
12
|
var _b = useState(false), hideSection = _b[0], setHideSection = _b[1];
|
|
15
13
|
var prevCtxTypeRef = useRef(null);
|
|
@@ -28,7 +26,7 @@ var ProtestosSP = function () {
|
|
|
28
26
|
setHideSection(true);
|
|
29
27
|
}
|
|
30
28
|
prevCtxTypeRef.current = ctxLiminar.type;
|
|
31
|
-
}, [ctxLiminar.type, ctxLiminar.document, dataUpdated
|
|
29
|
+
}, [ctxLiminar.type, ctxLiminar.document, dataUpdated]);
|
|
32
30
|
var possuiProtestosSp = useMemo(function () {
|
|
33
31
|
var _a;
|
|
34
32
|
if ((ctxLiminar === null || ctxLiminar === void 0 ? void 0 : ctxLiminar.type) === RequestStatus.Success)
|
|
@@ -11,6 +11,11 @@ export type ParsedResponse<T> = {
|
|
|
11
11
|
response: Response;
|
|
12
12
|
document: T;
|
|
13
13
|
};
|
|
14
|
+
/** Aviso de exceção esperada (`push=true` no XML); só exibe UI se houver `message` ou `code`. */
|
|
15
|
+
export type PushNotice = {
|
|
16
|
+
message?: string;
|
|
17
|
+
code?: number;
|
|
18
|
+
};
|
|
14
19
|
export type RequestContext<R> = {
|
|
15
20
|
data?: Client.Form;
|
|
16
21
|
urlData?: Client.Form;
|
|
@@ -24,6 +29,8 @@ export type RequestContext<R> = {
|
|
|
24
29
|
activeRequests?: number;
|
|
25
30
|
showLoadingBar?: boolean;
|
|
26
31
|
warningMessage?: string | null;
|
|
32
|
+
/** Presente quando o backend sinalizou `push=true` (situação esperada, fluxo segue). */
|
|
33
|
+
pushNotice?: PushNotice | null;
|
|
27
34
|
};
|
|
28
35
|
export type HeaderReplaceResponse = {
|
|
29
36
|
children: ReactNode;
|
|
@@ -5,14 +5,12 @@ import { useSafeQuery } from '../../hooks/useSafeQuery';
|
|
|
5
5
|
import { isDocumentoPF } from '../../utils/string';
|
|
6
6
|
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
import AddItemField from '../common/addItem';
|
|
8
|
+
import { formatInadPercentDisplay, inadCountPer100, resolveSerasaInadPercent } from './scoreSerasaProbUtils';
|
|
8
9
|
import { ConsultasComplementaresContext } from '../consultasComplementares';
|
|
9
10
|
import { Result, ResultContent } from '../interface/result';
|
|
10
11
|
import StatusMessage from '../interface/statusMessage';
|
|
11
12
|
import Section from '../section';
|
|
12
13
|
import { RequestStatus } from '../webservice';
|
|
13
|
-
var parseProb = function (raw) {
|
|
14
|
-
return typeof raw === 'number' ? raw : Number(String(raw).replace(',', '.')) || 0;
|
|
15
|
-
};
|
|
16
14
|
var ConsultaScoreSerasa = function (_a) {
|
|
17
15
|
var _b, _c, _d, _e, _f, _g;
|
|
18
16
|
var documento = _a.documento;
|
|
@@ -21,7 +19,14 @@ var ConsultaScoreSerasa = function (_a) {
|
|
|
21
19
|
var _h = useState(false), dataUpdated = _h[0], setDataUpdated = _h[1];
|
|
22
20
|
var _j = useSafeQuery("SELECT FROM 'ScoreSerasa'.'Consulta'", { documento: documento }, (_c = (_b = consultasComplementaresContext === null || consultasComplementaresContext === void 0 ? void 0 : consultasComplementaresContext.consultasComplementares) === null || _b === void 0 ? void 0 : _b.scoreSerasa) === null || _c === void 0 ? void 0 : _c.consultaRealizada), response = _j.response, isLoading = _j.isLoading, error = _j.error, loadingProgress = _j.loadingProgress;
|
|
23
21
|
var scoreData = (_e = (_d = response === null || response === void 0 ? void 0 : response.document) === null || _d === void 0 ? void 0 : _d.dados) === null || _e === void 0 ? void 0 : _e.score;
|
|
24
|
-
var
|
|
22
|
+
var inadResolvido = useMemo(function () {
|
|
23
|
+
return (scoreData === null || scoreData === void 0 ? void 0 : scoreData.score_calculado) === 'S'
|
|
24
|
+
? resolveSerasaInadPercent({
|
|
25
|
+
pontuacao: scoreData.pontuacao,
|
|
26
|
+
probabilidade_inadimplencia: scoreData.probabilidade_inadimplencia
|
|
27
|
+
})
|
|
28
|
+
: null;
|
|
29
|
+
}, [scoreData]);
|
|
25
30
|
var scoreRef = useRef(null);
|
|
26
31
|
var consultaRealizada = useMemo(function () {
|
|
27
32
|
var _a, _b;
|
|
@@ -61,8 +66,12 @@ var ConsultaScoreSerasa = function (_a) {
|
|
|
61
66
|
progress: loadingProgress
|
|
62
67
|
}, title: "Score Serasa", subtitle: "Consulta de Score", icon: ScoreBoaVistaIcon, description: !error && (React.createElement(StatusMessage, { type: scoreData ? 'success' : 'default' }, description)), onSuccess: function () { return (React.createElement(Result, null, scoreData && (React.createElement(ResultContent, { desktop: "repeat(4, 1fr)", tablet: "repeat(3, 1fr)", mobile: "1fr 1fr" },
|
|
63
68
|
React.createElement(AddItemField, { name: "Score", value: String(scoreData.pontuacao) }),
|
|
64
|
-
React.createElement(AddItemField, { name: "Probabilidade de Inadimpl\u00EAncia", value:
|
|
65
|
-
|
|
69
|
+
React.createElement(AddItemField, { name: "Probabilidade de Inadimpl\u00EAncia", value: inadResolvido
|
|
70
|
+
? formatInadPercentDisplay(inadResolvido.percent0to100)
|
|
71
|
+
: '—' }),
|
|
72
|
+
React.createElement(AddItemField, { name: "An\u00E1lise", value: inadResolvido
|
|
73
|
+
? "DE CADA 100 ".concat(isDocumentoPF(documento) ? 'PESSOAS' : 'EMPRESAS', " CLASSIFICADAS NESTA CLASSE DE SCORE, \u00C9 PROV\u00C1VEL QUE ").concat(inadCountPer100(inadResolvido.percent0to100), " APRESENTEM D\u00C9BITOS NO MERCADO NOS PR\u00D3XIMOS 6 MESES.")
|
|
74
|
+
: '—' }))))); }, isError: function (err) { return ({
|
|
66
75
|
children: React.createElement(React.Fragment, null),
|
|
67
76
|
description: (React.createElement(StatusMessage, { type: "error" },
|
|
68
77
|
"Erro ao realizar a consulta: ",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escala 0–1000 do Score Serasa; fora de faixa é ajustada (clamp).
|
|
3
|
+
*/
|
|
4
|
+
export declare function parsePonto1000(pontuacao: unknown): number;
|
|
5
|
+
/**
|
|
6
|
+
* A API preenche probabilidade (0–100) ou vem vazia.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isProbFromApiValid(raw: unknown): boolean;
|
|
9
|
+
export declare function inadFromFallbackPontuacao(p: number): number;
|
|
10
|
+
/**
|
|
11
|
+
* Número inteiro 0–100 na frase "de cada 100" (arredondamento do % resolvido).
|
|
12
|
+
*/
|
|
13
|
+
export declare function inadCountPer100(percent0to100: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* "99,80%" com duas decimais (formato local).
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatInadPercentDisplay(percent0to100: number): string;
|
|
18
|
+
export declare function resolveSerasaInadPercent(rules: {
|
|
19
|
+
pontuacao: unknown;
|
|
20
|
+
probabilidade_inadimplencia: unknown;
|
|
21
|
+
}): {
|
|
22
|
+
percent0to100: number;
|
|
23
|
+
fromApi: boolean;
|
|
24
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var SCORE_MAX = 1000;
|
|
2
|
+
var parseNumberFlexible = function (raw) {
|
|
3
|
+
if (raw === null || raw === undefined)
|
|
4
|
+
return null;
|
|
5
|
+
if (typeof raw === 'number') {
|
|
6
|
+
return Number.isFinite(raw) ? raw : null;
|
|
7
|
+
}
|
|
8
|
+
var s = String(raw).trim();
|
|
9
|
+
if (s === '')
|
|
10
|
+
return null;
|
|
11
|
+
var n = Number(s.replace(',', '.'));
|
|
12
|
+
return Number.isFinite(n) ? n : null;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Escala 0–1000 do Score Serasa; fora de faixa é ajustada (clamp).
|
|
16
|
+
*/
|
|
17
|
+
export function parsePonto1000(pontuacao) {
|
|
18
|
+
var n = parseNumberFlexible(pontuacao);
|
|
19
|
+
if (n === null)
|
|
20
|
+
return 0;
|
|
21
|
+
return Math.min(SCORE_MAX, Math.max(0, n));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A API preenche probabilidade (0–100) ou vem vazia.
|
|
25
|
+
*/
|
|
26
|
+
export function isProbFromApiValid(raw) {
|
|
27
|
+
if (raw === null || raw === undefined)
|
|
28
|
+
return false;
|
|
29
|
+
if (typeof raw === 'string' && raw.trim() === '')
|
|
30
|
+
return false;
|
|
31
|
+
var n = parseNumberFlexible(raw);
|
|
32
|
+
return n !== null;
|
|
33
|
+
}
|
|
34
|
+
var parseApiProbPercent = function (raw) {
|
|
35
|
+
var n = parseNumberFlexible(raw);
|
|
36
|
+
return n === null ? 0 : n;
|
|
37
|
+
};
|
|
38
|
+
export function inadFromFallbackPontuacao(p) {
|
|
39
|
+
return ((SCORE_MAX - p) / SCORE_MAX) * 100;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Número inteiro 0–100 na frase "de cada 100" (arredondamento do % resolvido).
|
|
43
|
+
*/
|
|
44
|
+
export function inadCountPer100(percent0to100) {
|
|
45
|
+
return Math.min(100, Math.max(0, Math.round(percent0to100)));
|
|
46
|
+
}
|
|
47
|
+
var percentFormatter = new Intl.NumberFormat('pt-BR', {
|
|
48
|
+
minimumFractionDigits: 2,
|
|
49
|
+
maximumFractionDigits: 2
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* "99,80%" com duas decimais (formato local).
|
|
53
|
+
*/
|
|
54
|
+
export function formatInadPercentDisplay(percent0to100) {
|
|
55
|
+
return "".concat(percentFormatter.format(percent0to100), "%");
|
|
56
|
+
}
|
|
57
|
+
export function resolveSerasaInadPercent(rules) {
|
|
58
|
+
var p = parsePonto1000(rules.pontuacao);
|
|
59
|
+
if (isProbFromApiValid(rules.probabilidade_inadimplencia)) {
|
|
60
|
+
return {
|
|
61
|
+
percent0to100: parseApiProbPercent(rules.probabilidade_inadimplencia),
|
|
62
|
+
fromApi: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return { percent0to100: inadFromFallbackPontuacao(p), fromApi: false };
|
|
66
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ISectionProps, RequestStatus } from './requestContextTypes';
|
|
3
|
+
/** Aviso no header para exceção esperada (`push=true`): só a mensagem do backend. */
|
|
4
|
+
export declare function pushExceptionDescription(err: Error): React.ReactNode;
|
|
3
5
|
declare const Section: React.ForwardRefExoticComponent<Omit<ISectionProps<unknown>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
4
6
|
export declare const headerStatus: Record<RequestStatus, string>;
|
|
5
7
|
export default Section;
|
|
@@ -14,6 +14,7 @@ import { PrintSectionWrapper } from './common/printSectionWrapper';
|
|
|
14
14
|
import Header from './interface/header';
|
|
15
15
|
import StatusMessage from './interface/statusMessage';
|
|
16
16
|
import { RequestStatus } from './requestContextTypes';
|
|
17
|
+
import { isErrorWithPushFlag } from '../utils/classifyRequestError';
|
|
17
18
|
var ButtonWrapper = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n justify-content: center;\n width: 100%;\n height: 40%;\n max-height: 52px;\n max-width: 300px;\n margin: 0 auto;\n"], ["\n justify-content: center;\n width: 100%;\n height: 40%;\n max-height: 52px;\n max-width: 300px;\n margin: 0 auto;\n"])));
|
|
18
19
|
var sectionIdCounter = 0;
|
|
19
20
|
var nextSectionId = function () {
|
|
@@ -49,12 +50,22 @@ var useSectionPrintBlocker = function (ctx, title, enabled, registerBlocker, res
|
|
|
49
50
|
}
|
|
50
51
|
}, [ctx, enabled, registerBlocker, resolveBlocker, title]);
|
|
51
52
|
};
|
|
53
|
+
/** Aviso no header para exceção esperada (`push=true`): só a mensagem do backend. */
|
|
54
|
+
export function pushExceptionDescription(err) {
|
|
55
|
+
var _a;
|
|
56
|
+
var message = (_a = err.message) === null || _a === void 0 ? void 0 : _a.trim();
|
|
57
|
+
if (!message)
|
|
58
|
+
return undefined;
|
|
59
|
+
return React.createElement(StatusMessage, { type: "warning" }, message);
|
|
60
|
+
}
|
|
52
61
|
var Section = forwardRef(function (_a, ref) {
|
|
53
62
|
var onSuccess = _a.onSuccess, _b = _a.isError, isError = _b === void 0 ? function (err, ctx) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
if (isErrorWithPushFlag(err)) {
|
|
64
|
+
return {
|
|
65
|
+
children: React.createElement(React.Fragment, null),
|
|
66
|
+
description: pushExceptionDescription(err),
|
|
67
|
+
variant: 'default'
|
|
68
|
+
};
|
|
58
69
|
}
|
|
59
70
|
var message = 'Problemas de comunicação, tente novamente.';
|
|
60
71
|
return {
|
|
@@ -72,10 +83,18 @@ var Section = forwardRef(function (_a, ref) {
|
|
|
72
83
|
useSectionPrintBlocker(ctx, headerProps === null || headerProps === void 0 ? void 0 : headerProps.title, readinessEnabled, printReadiness.registerBlocker, printReadiness.resolveBlocker);
|
|
73
84
|
if (!ctx)
|
|
74
85
|
return null;
|
|
75
|
-
var type = ctx.type, progress = ctx.progress, warningMessage = ctx.warningMessage;
|
|
86
|
+
var type = ctx.type, progress = ctx.progress, warningMessage = ctx.warningMessage, pushNotice = ctx.pushNotice;
|
|
76
87
|
var renderResponse = useCallback(function () {
|
|
77
88
|
switch (type) {
|
|
78
89
|
case RequestStatus.Success:
|
|
90
|
+
if (pushNotice &&
|
|
91
|
+
(ctx.document === undefined || ctx.document === null)) {
|
|
92
|
+
return {
|
|
93
|
+
children: React.createElement(React.Fragment, null),
|
|
94
|
+
description: undefined,
|
|
95
|
+
variant: 'default'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
79
98
|
return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(ctx.document, ctx);
|
|
80
99
|
case RequestStatus.Error: {
|
|
81
100
|
var errorResult = isError(ctx.error, ctx);
|
|
@@ -92,21 +111,30 @@ var Section = forwardRef(function (_a, ref) {
|
|
|
92
111
|
default:
|
|
93
112
|
return null;
|
|
94
113
|
}
|
|
95
|
-
}, [type, onSuccess, isError, onLoading, ctx, printMode]);
|
|
114
|
+
}, [type, onSuccess, isError, onLoading, ctx, printMode, pushNotice]);
|
|
96
115
|
var renderedResponse = renderResponse();
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
React.createElement(
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
var descriptionWithAlerts = useCallback(function (description) {
|
|
117
|
+
var _a;
|
|
118
|
+
var out = description;
|
|
119
|
+
if (warningMessage) {
|
|
120
|
+
out = (React.createElement(React.Fragment, null,
|
|
121
|
+
React.createElement(StatusMessage, { type: "warning" }, warningMessage),
|
|
122
|
+
out));
|
|
123
|
+
}
|
|
124
|
+
var pushMessage = (_a = pushNotice === null || pushNotice === void 0 ? void 0 : pushNotice.message) === null || _a === void 0 ? void 0 : _a.trim();
|
|
125
|
+
if (pushMessage) {
|
|
126
|
+
out = (React.createElement(React.Fragment, null,
|
|
127
|
+
React.createElement(StatusMessage, { type: "warning" }, pushMessage),
|
|
128
|
+
out));
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}, [warningMessage, pushNotice]);
|
|
104
132
|
var defaultHeaderActions = useMemo(function () {
|
|
105
133
|
return !printMode ? (React.createElement(BtnWrapper, { hidden: type === RequestStatus.Loading, onClick: toggleOpen }, isOpen ? React.createElement(ChevronUp, null) : React.createElement(ChevronDown, null))) : null;
|
|
106
134
|
}, [type, isOpen, toggleOpen, printMode]);
|
|
107
135
|
var renderHeader = function (props) {
|
|
108
136
|
var description = props.description, actions = props.actions, rest = __rest(props, ["description", "actions"]);
|
|
109
|
-
return (React.createElement(Header, __assign({ printBar: renderedResponse !== null && isOpen }, rest, { description:
|
|
137
|
+
return (React.createElement(Header, __assign({ printBar: renderedResponse !== null && isOpen }, rest, { description: descriptionWithAlerts(description), className: cn(className, type !== undefined && headerStatus[type]
|
|
110
138
|
? headerStatus[type]
|
|
111
139
|
: '', props.className), variant: type === RequestStatus.Loading ? 'loading' : props.variant, loadingProps: {
|
|
112
140
|
percentage: progress !== null && progress !== void 0 ? progress : 0,
|
|
@@ -214,16 +214,26 @@ export function useStreamQuery(query, data, enabled) {
|
|
|
214
214
|
!abortControllerRef.current.signal.aborted) {
|
|
215
215
|
abortControllerRef.current.abort();
|
|
216
216
|
abortControllerRef.current = null;
|
|
217
|
-
setIsLoading(false);
|
|
218
|
-
hasStreamStartedRef.current = false;
|
|
219
|
-
setResponseIterator(null);
|
|
220
217
|
}
|
|
218
|
+
setIsLoading(false);
|
|
219
|
+
hasStreamStartedRef.current = false;
|
|
220
|
+
setResponseIterator(null);
|
|
221
221
|
}, []);
|
|
222
|
+
/**
|
|
223
|
+
* Invariante anti-loop: após falha, mantemos `responseIterator` não-nulo até `abortStream`
|
|
224
|
+
* (o `useEffect` abaixo só dispara novo fetch quando `!responseIterator`). Limpar o iterator
|
|
225
|
+
* em todo erro sem esse contrato faria o efeito reabrir HTTP em ciclo.
|
|
226
|
+
*/
|
|
222
227
|
useEffect(function () {
|
|
223
|
-
if (enabled
|
|
224
|
-
|
|
228
|
+
if (!enabled) {
|
|
229
|
+
abortStream();
|
|
230
|
+
return;
|
|
225
231
|
}
|
|
226
|
-
|
|
232
|
+
if (responseIterator)
|
|
233
|
+
return;
|
|
234
|
+
fetchStream();
|
|
235
|
+
}, [enabled, responseIterator, fetchStream, abortStream]);
|
|
236
|
+
useEffect(function () { return function () { return abortStream(); }; }, [abortStream]);
|
|
227
237
|
return {
|
|
228
238
|
responseIterator: responseIterator,
|
|
229
239
|
error: error,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EditalResponse, LiminarResponse, PDFProtestoDiscoverResponse, ProcessosJuridicosState } from '../@types/domain';
|
|
2
2
|
import { Client } from '@credithub/webservice';
|
|
3
3
|
import React, { Context, FC, PropsWithChildren } from 'react';
|
|
4
|
-
import { type ParsedResponse, type RequestContext } from './requestContextTypes';
|
|
4
|
+
import { type ParsedResponse, type PushNotice, type RequestContext } from './requestContextTypes';
|
|
5
5
|
export * from './requestContextTypes';
|
|
6
6
|
export declare const WebService: React.Context<Client.WebService>;
|
|
7
7
|
type RequestDefaults = {
|
|
@@ -25,6 +25,7 @@ export declare function CustomProvider<T extends Client.Form = Client.Form, R =
|
|
|
25
25
|
export declare function useQuery<R = unknown, T extends Client.Form = Client.Form>(query: string, data?: T, enabled?: boolean): {
|
|
26
26
|
response: ParsedResponse<R> | null;
|
|
27
27
|
error: Error | null;
|
|
28
|
+
pushNotice: PushNotice | null;
|
|
28
29
|
isLoading: boolean;
|
|
29
30
|
loadingProgress: number;
|
|
30
31
|
refetch: () => void;
|