zenit-sdk 0.1.9 → 0.2.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.
@@ -642,49 +642,146 @@ function useGeolocation(options) {
642
642
  import L2 from "leaflet";
643
643
 
644
644
  // src/config/modalWhitelist.ts
645
- var SECTOR_MODAL_WHITELIST = [
646
- { key: "Sector", label: "Sector" },
647
- { key: "Promotor", label: "Promotor" },
648
- { key: "Capital Total", label: "Capital Total" },
649
- { key: "Total Capital Mora", label: "Capital en Mora" },
650
- { key: "Tendencia Mora", label: "Tendencia de Mora", hint: "trend_icon" },
651
- { key: "Tendencia Capital", label: "Tendencia de Capital", hint: "trend_icon" },
652
- { key: "Tendencia Castigos", label: "Tendencia de Castigos", hint: "trend_icon" },
653
- { key: "Impacto Sector", label: "Impacto del Sector" },
654
- { key: "Total Clientes Sector", label: "Total de Clientes" },
655
- { key: "Total Clientes Sanos", label: "Clientes Sanos" },
656
- { key: "Total Clientes Morosos", label: "Clientes en Mora" },
657
- { key: "Total Clientes Castigados", label: "Clientes Castigados" },
658
- { key: "Total Clientes Nuevos", label: "Clientes Nuevos" },
659
- { key: "Total Clientes Salidos", label: "Clientes Salidos" },
660
- { key: "Insights", label: "An\xE1lisis IA", hint: "collapsible" },
661
- { key: "Recomendaciones", label: "Recomendaciones IA", hint: "collapsible" }
662
- ];
645
+ function normalizeKey(value) {
646
+ return value.normalize("NFD").replace(/\p{Diacritic}/gu, "").replace(/[_\s-]+/g, "").toLowerCase().trim();
647
+ }
663
648
  var CLIENTE_MODAL_WHITELIST = [
664
- { key: "nombre del cliente", label: "Nombre del Cliente" },
665
- { key: "dpi", label: "DPI" },
666
- { key: "kpi", label: "Estado", hint: "kpi_badge" },
667
- { key: "tel principal", label: "Tel\xE9fono", hint: "phone_link" },
668
- { key: "capital concedido", label: "Capital Concedido" },
669
- { key: "mora", label: "Monto en Mora", hint: "mora_alert" },
670
- { key: "etapa", label: "Etapa del Cr\xE9dito" },
671
- { key: "prestamo", label: "No. de Pr\xE9stamo" },
672
- { key: "sucursal", label: "Sucursal", aliases: ["nombre sucursal"] }
649
+ {
650
+ id: "nombre_cliente",
651
+ label: "Nombre del Cliente",
652
+ aliases: ["nombre_del_cliente", "nombre cliente", "nombre_del_cliente ", "NOMBRE_CLIENTE"]
653
+ },
654
+ {
655
+ id: "dpi",
656
+ label: "DPI",
657
+ aliases: ["dpi", "DPI"]
658
+ },
659
+ {
660
+ id: "kpi",
661
+ label: "Estado",
662
+ aliases: ["kpi", "KPI"],
663
+ hint: "kpi_badge"
664
+ },
665
+ {
666
+ id: "tel_principal",
667
+ label: "Tel\xE9fono",
668
+ aliases: ["tel_principal", "tel principal", "telefono", "telefono_principal", "TEL_PRINCIPAL"],
669
+ hint: "phone_link"
670
+ },
671
+ {
672
+ id: "capital_concedido",
673
+ label: "Capital Concedido",
674
+ aliases: ["capital_concedido", "capital concedido", "CAPITAL_CONCEDIDO"]
675
+ },
676
+ {
677
+ id: "mora",
678
+ label: "Monto en Mora",
679
+ aliases: ["mora", "MORA"],
680
+ hint: "mora_alert"
681
+ },
682
+ {
683
+ id: "etapa",
684
+ label: "Etapa del Cr\xE9dito",
685
+ aliases: ["etapa", "ETAPA"]
686
+ },
687
+ {
688
+ id: "prestamo",
689
+ label: "No. de Pr\xE9stamo",
690
+ aliases: ["prestamo", "prestamo_id", "no_prestamo", "numero_prestamo", "PRESTAMO"]
691
+ },
692
+ {
693
+ id: "sucursal",
694
+ label: "Sucursal",
695
+ aliases: ["sucursal", "nombre_sucursal", "nombre sucursal", "SUCURSAL"]
696
+ }
697
+ ];
698
+ var SECTOR_MODAL_WHITELIST = [
699
+ { id: "sector", label: "Sector", aliases: ["nom_sector", "NOM_SECTOR", "sector", "SECTOR"] },
700
+ { id: "promotor", label: "Promotor", aliases: ["promotor", "PROMOTOR"] },
701
+ { id: "capital_total", label: "Capital Total", aliases: ["capital_total", "capital total", "CAPITAL_TOTAL"] },
702
+ {
703
+ id: "total_capital_mora",
704
+ label: "Total Capital Mora",
705
+ aliases: ["total_capital_mora", "total capital mora", "TOTAL_CAPITAL_MORA"]
706
+ },
707
+ {
708
+ id: "tendencia_mora",
709
+ label: "Tendencia Mora",
710
+ aliases: ["tendencia_mora", "tendencia mora", "TENDENCIA_MORA"],
711
+ hint: "trend_icon"
712
+ },
713
+ {
714
+ id: "tendencia_capital",
715
+ label: "Tendencia Capital",
716
+ aliases: ["tendencia_capital", "tendencia capital", "TENDENCIA_CAPITAL"],
717
+ hint: "trend_icon"
718
+ },
719
+ {
720
+ id: "tendencia_castigos",
721
+ label: "Tendencia Castigos",
722
+ aliases: ["tendencia_castigos", "tendencia castigos", "TENDENCIA_CASTIGOS"],
723
+ hint: "trend_icon"
724
+ },
725
+ {
726
+ id: "impacto_sector",
727
+ label: "Impacto Sector",
728
+ aliases: ["impacto_sector", "impacto sector", "IMPACTO_SECTOR"]
729
+ },
730
+ {
731
+ id: "total_clientes_sector",
732
+ label: "Total Clientes Sector",
733
+ aliases: ["total_clientes_sector", "total clientes sector", "TOTAL_CLIENTES_SECTOR"]
734
+ },
735
+ {
736
+ id: "total_clientes_sanos",
737
+ label: "Total Clientes Sanos",
738
+ aliases: ["total_clientes_sanos", "total clientes sanos", "TOTAL_CLIENTES_SANOS"]
739
+ },
740
+ {
741
+ id: "total_clientes_morosos",
742
+ label: "Total Clientes Morosos",
743
+ aliases: ["total_clientes_morosos", "total clientes morosos", "TOTAL_CLIENTES_MOROSOS"]
744
+ },
745
+ {
746
+ id: "total_clientes_castigados",
747
+ label: "Total Clientes Castigados",
748
+ aliases: ["total_clientes_castigados", "total clientes castigados", "TOTAL_CLIENTES_CASTIGADOS"]
749
+ },
750
+ {
751
+ id: "total_clientes_nuevos",
752
+ label: "Total Clientes Nuevos",
753
+ aliases: ["total_clientes_nuevos", "total clientes nuevos", "TOTAL_CLIENTES_NUEVOS"]
754
+ },
755
+ {
756
+ id: "total_clientes_salidos",
757
+ label: "Total Clientes Salidos",
758
+ aliases: ["total_clientes_salidos", "total clientes salidos", "TOTAL_CLIENTES_SALIDOS"]
759
+ },
760
+ { id: "insights", label: "Insights", aliases: ["insights", "INSIGHTS"], hint: "collapsible" },
761
+ {
762
+ id: "recomendaciones",
763
+ label: "Recomendaciones",
764
+ aliases: ["recomendaciones", "RECOMENDACIONES"],
765
+ hint: "collapsible"
766
+ }
673
767
  ];
674
768
  function applyModalWhitelist(rawData, whitelist) {
675
- const keys = Object.keys(rawData ?? {});
676
- return whitelist.map(({ key, label, hint, aliases = [] }) => {
677
- const keysToTry = [key, ...aliases];
678
- let value = void 0;
679
- for (const k of keysToTry) {
680
- const match = keys.find((rawKey) => rawKey.toLowerCase() === k.toLowerCase());
681
- if (match !== void 0 && rawData[match] !== null && rawData[match] !== void 0) {
682
- value = rawData[match];
683
- break;
684
- }
769
+ const keyByNormalized = /* @__PURE__ */ new Map();
770
+ Object.keys(rawData ?? {}).forEach((rawKey) => {
771
+ const normalized = normalizeKey(rawKey);
772
+ if (!normalized || keyByNormalized.has(normalized)) return;
773
+ keyByNormalized.set(normalized, rawKey);
774
+ });
775
+ return whitelist.map(({ id, label, hint, aliases }) => {
776
+ const candidates = [...aliases, id];
777
+ for (const candidate of candidates) {
778
+ const matchedKey = keyByNormalized.get(normalizeKey(candidate));
779
+ if (!matchedKey) continue;
780
+ const value = rawData[matchedKey];
781
+ if (value === null || value === void 0) continue;
782
+ return { id, label, value, hint: hint ?? null, matchedKey };
685
783
  }
686
- if (value === void 0) return null;
687
- return { label, value, hint: hint ?? null };
784
+ return null;
688
785
  }).filter((entry) => Boolean(entry));
689
786
  }
690
787
 
@@ -925,10 +1022,6 @@ function shouldIncludePopupEntry(key, value) {
925
1022
  return true;
926
1023
  }
927
1024
  function createPopupContent(properties) {
928
- const whitelistedRows = buildWhitelistedRows(properties);
929
- if (whitelistedRows) {
930
- return whitelistedRows;
931
- }
932
1025
  const header = findHeaderProperties(properties);
933
1026
  const headerText = header.title?.value ?? extractPopupHeader(properties);
934
1027
  const usedKeys = new Set([header.title?.key, header.badge?.key, header.description?.key].filter(Boolean));
@@ -952,6 +1045,10 @@ function createPopupContent(properties) {
952
1045
  const descriptionHtml = header.description ? `<div style="margin-bottom:10px; padding:8px 10px; background:#f8fafc; border-left:3px solid #38bdf8; border-radius:6px; color:#334155; font-size:12px;">${escapeHtml(
953
1046
  header.description.value
954
1047
  )}</div>` : "";
1048
+ const whitelistedRows = buildWhitelistedRows(properties, { colorBar, headerHtml, descriptionHtml });
1049
+ if (whitelistedRows) {
1050
+ return whitelistedRows;
1051
+ }
955
1052
  const rowsHtml = entries.map(([key, value]) => {
956
1053
  const label = escapeHtml(formatLabel(key));
957
1054
  const normalizedKey = key.trim().toLowerCase();
@@ -968,13 +1065,37 @@ function createPopupContent(properties) {
968
1065
  }).join("");
969
1066
  return `<div>${colorBar}${headerHtml}${descriptionHtml}${rowsHtml}</div>`;
970
1067
  }
971
- function buildWhitelistedRows(properties) {
972
- const whitelist = selectModalWhitelist(properties);
973
- if (!whitelist) return null;
1068
+ function buildWhitelistedRows(properties, headerSections) {
1069
+ const selection = selectModalWhitelist(properties);
1070
+ if (!selection) {
1071
+ logModalWhitelistDebug({
1072
+ modalType: "generic",
1073
+ properties,
1074
+ entries: [],
1075
+ whitelist: null,
1076
+ fallbackToGeneric: true
1077
+ });
1078
+ return null;
1079
+ }
1080
+ const { whitelist, modalType } = selection;
974
1081
  const entries = applyModalWhitelist(properties, whitelist);
975
1082
  if (entries.length === 0) {
976
- return '<div style="padding:8px 0; color:#64748b; text-align:center;">Sin datos disponibles</div>';
1083
+ logModalWhitelistDebug({
1084
+ modalType,
1085
+ properties,
1086
+ entries,
1087
+ whitelist,
1088
+ fallbackToGeneric: true
1089
+ });
1090
+ return null;
977
1091
  }
1092
+ logModalWhitelistDebug({
1093
+ modalType,
1094
+ properties,
1095
+ entries,
1096
+ whitelist,
1097
+ fallbackToGeneric: false
1098
+ });
978
1099
  const rowsHtml = entries.map(({ label, value }) => {
979
1100
  const valueHtml = renderPopupValue(value);
980
1101
  return `
@@ -984,20 +1105,33 @@ function buildWhitelistedRows(properties) {
984
1105
  </div>
985
1106
  `;
986
1107
  }).join("");
987
- return `<div>${rowsHtml}</div>`;
1108
+ return `<div>${headerSections.colorBar}${headerSections.headerHtml}${headerSections.descriptionHtml}${rowsHtml}</div>`;
988
1109
  }
989
- function countWhitelistMatches(properties, whitelist) {
990
- const keys = Object.keys(properties).map((key) => key.toLowerCase());
991
- return whitelist.reduce((count, item) => {
992
- const candidates = [item.key, ...item.aliases ?? []].map((candidate) => candidate.toLowerCase());
993
- return candidates.some((candidate) => keys.includes(candidate)) ? count + 1 : count;
994
- }, 0);
1110
+ function hasAnyKey(properties, candidates) {
1111
+ const normalizedKeys = new Set(Object.keys(properties).map((key) => normalizeKey(key)));
1112
+ return candidates.some((candidate) => normalizedKeys.has(normalizeKey(candidate)));
995
1113
  }
996
1114
  function selectModalWhitelist(properties) {
997
- const sectorMatches = countWhitelistMatches(properties, SECTOR_MODAL_WHITELIST);
998
- const clienteMatches = countWhitelistMatches(properties, CLIENTE_MODAL_WHITELIST);
999
- if (sectorMatches === 0 && clienteMatches === 0) return null;
1000
- return sectorMatches >= clienteMatches ? SECTOR_MODAL_WHITELIST : CLIENTE_MODAL_WHITELIST;
1115
+ if (hasAnyKey(properties, ["nombre_del_cliente", "dpi", "capital_concedido", "kpi"])) {
1116
+ return { modalType: "cliente", whitelist: CLIENTE_MODAL_WHITELIST };
1117
+ }
1118
+ if (hasAnyKey(properties, ["nom_sector", "NOM_SECTOR", "total_clientes_sector", "capital_total", "impacto_sector"])) {
1119
+ return { modalType: "sector", whitelist: SECTOR_MODAL_WHITELIST };
1120
+ }
1121
+ return null;
1122
+ }
1123
+ function logModalWhitelistDebug(options) {
1124
+ if (process.env.NODE_ENV === "production") return;
1125
+ const { modalType, properties, entries, whitelist, fallbackToGeneric } = options;
1126
+ const matchedIds = new Set(entries.map((entry) => entry.id));
1127
+ const missingFields = (whitelist ?? []).filter((item) => !matchedIds.has(item.id)).map((item) => item.id);
1128
+ console.info("[modal-whitelist]", {
1129
+ modalType,
1130
+ keys: Object.keys(properties),
1131
+ matchedFields: entries.map((entry) => ({ id: entry.id, matchedKey: entry.matchedKey })),
1132
+ missingFields,
1133
+ fallbackToGeneric
1134
+ });
1001
1135
  }
1002
1136
  function isPolygonType(layerType, geometryType) {
1003
1137
  const candidate = (layerType ?? geometryType ?? "").toLowerCase();
@@ -5213,4 +5347,4 @@ export {
5213
5347
  useSendMessageStream,
5214
5348
  FloatingChatBox
5215
5349
  };
5216
- //# sourceMappingURL=chunk-3M57OBM6.mjs.map
5350
+ //# sourceMappingURL=chunk-TH7D3ECH.mjs.map