@inkindcards/semantic-layer 2.0.0 → 2.1.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.cjs +546 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +53 -2
- package/dist/components.d.ts +53 -2
- package/dist/components.js +545 -3
- package/dist/components.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/{types-DJpYLOyy.d.cts → types-c5qj4BKB.d.cts} +1 -1
- package/dist/{types-DJpYLOyy.d.ts → types-c5qj4BKB.d.ts} +1 -1
- package/package.json +1 -1
package/dist/components.cjs
CHANGED
|
@@ -805,10 +805,556 @@ function AdminDashboard({ className }) {
|
|
|
805
805
|
tab === "users" && /* @__PURE__ */ jsxRuntime.jsx(UsersTab, {})
|
|
806
806
|
] });
|
|
807
807
|
}
|
|
808
|
+
var InspectableRegistryContext = react.createContext(null);
|
|
809
|
+
function InspectableRegistry({ children }) {
|
|
810
|
+
const [entries, setEntries] = react.useState(/* @__PURE__ */ new Map());
|
|
811
|
+
const [inspectActive, setInspectActive] = react.useState(false);
|
|
812
|
+
const [selectedId, setSelectedId] = react.useState(null);
|
|
813
|
+
const register = react.useCallback((entry) => {
|
|
814
|
+
setEntries((prev) => {
|
|
815
|
+
const next = new Map(prev);
|
|
816
|
+
next.set(entry.id, entry);
|
|
817
|
+
return next;
|
|
818
|
+
});
|
|
819
|
+
}, []);
|
|
820
|
+
const unregister = react.useCallback((id) => {
|
|
821
|
+
setEntries((prev) => {
|
|
822
|
+
const next = new Map(prev);
|
|
823
|
+
next.delete(id);
|
|
824
|
+
return next;
|
|
825
|
+
});
|
|
826
|
+
setSelectedId((prev) => prev === id ? null : prev);
|
|
827
|
+
}, []);
|
|
828
|
+
const value = {
|
|
829
|
+
entries,
|
|
830
|
+
register,
|
|
831
|
+
unregister,
|
|
832
|
+
inspectActive,
|
|
833
|
+
setInspectActive,
|
|
834
|
+
selectedId,
|
|
835
|
+
setSelectedId
|
|
836
|
+
};
|
|
837
|
+
return /* @__PURE__ */ jsxRuntime.jsx(InspectableRegistryContext.Provider, { value, children });
|
|
838
|
+
}
|
|
839
|
+
function Inspectable({
|
|
840
|
+
label,
|
|
841
|
+
currentSource = "unknown",
|
|
842
|
+
data,
|
|
843
|
+
columns,
|
|
844
|
+
children
|
|
845
|
+
}) {
|
|
846
|
+
const registry = react.useContext(InspectableRegistryContext);
|
|
847
|
+
const id = react.useId();
|
|
848
|
+
const ref = react.useRef(null);
|
|
849
|
+
const inferredColumns = columns ?? (data?.[0] ? Object.keys(data[0]) : []);
|
|
850
|
+
const sampleValues = data?.slice(0, 3) ?? [];
|
|
851
|
+
react.useEffect(() => {
|
|
852
|
+
if (!registry) return;
|
|
853
|
+
registry.register({
|
|
854
|
+
id,
|
|
855
|
+
label,
|
|
856
|
+
currentSource,
|
|
857
|
+
columns: inferredColumns,
|
|
858
|
+
sampleValues,
|
|
859
|
+
element: ref.current
|
|
860
|
+
});
|
|
861
|
+
return () => registry.unregister(id);
|
|
862
|
+
}, [id, label, currentSource, inferredColumns.join(","), registry]);
|
|
863
|
+
if (!registry) {
|
|
864
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
865
|
+
}
|
|
866
|
+
const isSelected = registry.selectedId === id;
|
|
867
|
+
const showOutline = registry.inspectActive;
|
|
868
|
+
const handleClick = (e) => {
|
|
869
|
+
if (!registry.inspectActive) return;
|
|
870
|
+
e.stopPropagation();
|
|
871
|
+
registry.setSelectedId(isSelected ? null : id);
|
|
872
|
+
};
|
|
873
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
874
|
+
"div",
|
|
875
|
+
{
|
|
876
|
+
ref,
|
|
877
|
+
onClick: handleClick,
|
|
878
|
+
style: {
|
|
879
|
+
position: "relative",
|
|
880
|
+
outline: showOutline ? isSelected ? "2px solid #3b82f6" : "2px dashed #93c5fd" : "none",
|
|
881
|
+
outlineOffset: 2,
|
|
882
|
+
borderRadius: 4,
|
|
883
|
+
cursor: showOutline ? "pointer" : "inherit",
|
|
884
|
+
transition: "outline 0.15s ease"
|
|
885
|
+
},
|
|
886
|
+
children: [
|
|
887
|
+
showOutline && /* @__PURE__ */ jsxRuntime.jsx(
|
|
888
|
+
"div",
|
|
889
|
+
{
|
|
890
|
+
style: {
|
|
891
|
+
position: "absolute",
|
|
892
|
+
top: -10,
|
|
893
|
+
left: 4,
|
|
894
|
+
fontSize: 10,
|
|
895
|
+
fontWeight: 600,
|
|
896
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
897
|
+
color: "#fff",
|
|
898
|
+
backgroundColor: isSelected ? "#3b82f6" : "#93c5fd",
|
|
899
|
+
padding: "1px 6px",
|
|
900
|
+
borderRadius: 3,
|
|
901
|
+
zIndex: 1e4,
|
|
902
|
+
pointerEvents: "none",
|
|
903
|
+
whiteSpace: "nowrap"
|
|
904
|
+
},
|
|
905
|
+
children: label
|
|
906
|
+
}
|
|
907
|
+
),
|
|
908
|
+
children
|
|
909
|
+
]
|
|
910
|
+
}
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/components/field-matcher.ts
|
|
915
|
+
var AGG_PREFIXES = ["total_", "sum_", "avg_", "count_", "min_", "max_", "num_"];
|
|
916
|
+
var NOISE_SUFFIXES = ["_name", "_id", "_value", "_val", "_amt", "_amount"];
|
|
917
|
+
function camelToSnake(s) {
|
|
918
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
|
|
919
|
+
}
|
|
920
|
+
function normalize(s) {
|
|
921
|
+
let result = camelToSnake(s).toLowerCase().trim();
|
|
922
|
+
for (const prefix of AGG_PREFIXES) {
|
|
923
|
+
if (result.startsWith(prefix) && result.length > prefix.length) {
|
|
924
|
+
result = result.slice(prefix.length);
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
for (const suffix of NOISE_SUFFIXES) {
|
|
929
|
+
if (result.endsWith(suffix) && result.length > suffix.length) {
|
|
930
|
+
result = result.slice(0, -suffix.length);
|
|
931
|
+
break;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return result;
|
|
935
|
+
}
|
|
936
|
+
function matchExact(column, catalog) {
|
|
937
|
+
const lower = column.toLowerCase();
|
|
938
|
+
return catalog.find((f) => f.name.toLowerCase() === lower) ?? null;
|
|
939
|
+
}
|
|
940
|
+
function matchNormalized(column, catalog) {
|
|
941
|
+
const norm = normalize(column);
|
|
942
|
+
return catalog.find((f) => normalize(f.name) === norm) ?? null;
|
|
943
|
+
}
|
|
944
|
+
function matchDisplayName(column, catalog) {
|
|
945
|
+
const lower = normalize(column).replace(/_/g, " ");
|
|
946
|
+
if (lower.length < 3) return null;
|
|
947
|
+
return catalog.find((f) => f.displayName.toLowerCase().includes(lower)) ?? catalog.find((f) => f.description.toLowerCase().includes(lower)) ?? null;
|
|
948
|
+
}
|
|
949
|
+
function matchFields(columns, catalog) {
|
|
950
|
+
return columns.map((column) => {
|
|
951
|
+
const exact = matchExact(column, catalog);
|
|
952
|
+
if (exact) return { column, suggestedField: exact, confidence: "exact" };
|
|
953
|
+
const normalized = matchNormalized(column, catalog);
|
|
954
|
+
if (normalized) return { column, suggestedField: normalized, confidence: "fuzzy" };
|
|
955
|
+
const display = matchDisplayName(column, catalog);
|
|
956
|
+
if (display) return { column, suggestedField: display, confidence: "fuzzy" };
|
|
957
|
+
return { column, suggestedField: null, confidence: "manual" };
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// src/components/prompt-generator.ts
|
|
962
|
+
function generateMigrationPrompt(componentLabel, mappings) {
|
|
963
|
+
const resolved = mappings.filter((m) => m.field !== null);
|
|
964
|
+
if (resolved.length === 0) {
|
|
965
|
+
return `Replace the sample/hardcoded data in the "${componentLabel}" component with live data from the semantic layer using useSemanticQuery. Use the DataCatalog to find the right field names.`;
|
|
966
|
+
}
|
|
967
|
+
const metrics = resolved.filter((m) => m.field.type === "metric").map((m) => m.field.name);
|
|
968
|
+
const timeDims = resolved.filter((m) => m.field.type === "time_dimension").map((m) => m.field.name);
|
|
969
|
+
const dims = resolved.filter((m) => m.field.type === "dimension").map((m) => m.field.name);
|
|
970
|
+
const groupBy = [...timeDims, ...dims];
|
|
971
|
+
const parts = [
|
|
972
|
+
`Replace the sample/hardcoded data in the "${componentLabel}" component with a useSemanticQuery call using:`
|
|
973
|
+
];
|
|
974
|
+
if (metrics.length > 0) {
|
|
975
|
+
parts.push(` metrics: [${metrics.map((n) => `'${n}'`).join(", ")}]`);
|
|
976
|
+
}
|
|
977
|
+
if (groupBy.length > 0) {
|
|
978
|
+
parts.push(` groupBy: [${groupBy.map((n) => `'${n}'`).join(", ")}]`);
|
|
979
|
+
}
|
|
980
|
+
if (timeDims.length > 0) {
|
|
981
|
+
parts.push(` grain: 'month'`);
|
|
982
|
+
}
|
|
983
|
+
parts.push("");
|
|
984
|
+
parts.push("Map the query result columns to the component's props:");
|
|
985
|
+
for (const m of resolved) {
|
|
986
|
+
parts.push(` "${m.column}" \u2192 data column "${m.field.name}"`);
|
|
987
|
+
}
|
|
988
|
+
parts.push("");
|
|
989
|
+
parts.push(
|
|
990
|
+
"Remove the old hardcoded/sample data and any fetch logic it used. Use the data, isLoading, and error values from useSemanticQuery to render the component."
|
|
991
|
+
);
|
|
992
|
+
return parts.join("\n");
|
|
993
|
+
}
|
|
994
|
+
function DataInspector({ children }) {
|
|
995
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(InspectableRegistry, { children: [
|
|
996
|
+
/* @__PURE__ */ jsxRuntime.jsx(InspectorOverlay, {}),
|
|
997
|
+
children
|
|
998
|
+
] });
|
|
999
|
+
}
|
|
1000
|
+
function InspectorOverlay() {
|
|
1001
|
+
const registry = react.useContext(InspectableRegistryContext);
|
|
1002
|
+
if (!registry) return null;
|
|
1003
|
+
const { inspectActive, setInspectActive, selectedId, setSelectedId, entries } = registry;
|
|
1004
|
+
react.useEffect(() => {
|
|
1005
|
+
function handleKeyDown(e) {
|
|
1006
|
+
if (e.ctrlKey && e.shiftKey && e.key === "I") {
|
|
1007
|
+
e.preventDefault();
|
|
1008
|
+
setInspectActive(!inspectActive);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1012
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1013
|
+
}, [inspectActive, setInspectActive]);
|
|
1014
|
+
const selectedEntry = selectedId ? entries.get(selectedId) ?? null : null;
|
|
1015
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1016
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1017
|
+
ToggleButton,
|
|
1018
|
+
{
|
|
1019
|
+
active: inspectActive,
|
|
1020
|
+
count: entries.size,
|
|
1021
|
+
onToggle: () => {
|
|
1022
|
+
setInspectActive(!inspectActive);
|
|
1023
|
+
if (inspectActive) setSelectedId(null);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
selectedEntry && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1028
|
+
InspectorModal,
|
|
1029
|
+
{
|
|
1030
|
+
entry: selectedEntry,
|
|
1031
|
+
onClose: () => setSelectedId(null)
|
|
1032
|
+
}
|
|
1033
|
+
)
|
|
1034
|
+
] });
|
|
1035
|
+
}
|
|
1036
|
+
function ToggleButton({
|
|
1037
|
+
active,
|
|
1038
|
+
count,
|
|
1039
|
+
onToggle
|
|
1040
|
+
}) {
|
|
1041
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1042
|
+
"button",
|
|
1043
|
+
{
|
|
1044
|
+
onClick: onToggle,
|
|
1045
|
+
title: active ? "Exit inspect mode (Ctrl+Shift+I)" : "Enter inspect mode (Ctrl+Shift+I)",
|
|
1046
|
+
style: {
|
|
1047
|
+
position: "fixed",
|
|
1048
|
+
bottom: 20,
|
|
1049
|
+
right: 20,
|
|
1050
|
+
zIndex: 99999,
|
|
1051
|
+
display: "flex",
|
|
1052
|
+
alignItems: "center",
|
|
1053
|
+
gap: 6,
|
|
1054
|
+
padding: "8px 16px",
|
|
1055
|
+
fontSize: 13,
|
|
1056
|
+
fontWeight: 600,
|
|
1057
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1058
|
+
color: active ? "#fff" : "#374151",
|
|
1059
|
+
backgroundColor: active ? "#3b82f6" : "#fff",
|
|
1060
|
+
border: `1px solid ${active ? "#2563eb" : "#d1d5db"}`,
|
|
1061
|
+
borderRadius: 999,
|
|
1062
|
+
cursor: "pointer",
|
|
1063
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.12)",
|
|
1064
|
+
transition: "all 0.15s ease"
|
|
1065
|
+
},
|
|
1066
|
+
children: [
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1068
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
1069
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
|
|
1070
|
+
] }),
|
|
1071
|
+
active ? "Inspecting" : "Inspect Data",
|
|
1072
|
+
count > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1073
|
+
"span",
|
|
1074
|
+
{
|
|
1075
|
+
style: {
|
|
1076
|
+
display: "inline-flex",
|
|
1077
|
+
alignItems: "center",
|
|
1078
|
+
justifyContent: "center",
|
|
1079
|
+
minWidth: 18,
|
|
1080
|
+
height: 18,
|
|
1081
|
+
fontSize: 11,
|
|
1082
|
+
fontWeight: 700,
|
|
1083
|
+
borderRadius: 999,
|
|
1084
|
+
backgroundColor: active ? "rgba(255,255,255,0.25)" : "#e5e7eb",
|
|
1085
|
+
color: active ? "#fff" : "#6b7280",
|
|
1086
|
+
padding: "0 5px"
|
|
1087
|
+
},
|
|
1088
|
+
children: count
|
|
1089
|
+
}
|
|
1090
|
+
)
|
|
1091
|
+
]
|
|
1092
|
+
}
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
function InspectorModal({
|
|
1096
|
+
entry,
|
|
1097
|
+
onClose
|
|
1098
|
+
}) {
|
|
1099
|
+
const { fields: catalog } = chunkT2C43AAL_cjs.useMetrics();
|
|
1100
|
+
const initialMatches = react.useMemo(
|
|
1101
|
+
() => matchFields(entry.columns, catalog),
|
|
1102
|
+
[entry.columns, catalog]
|
|
1103
|
+
);
|
|
1104
|
+
const [mappings, setMappings] = react.useState(
|
|
1105
|
+
() => new Map(initialMatches.map((m) => [m.column, m.suggestedField]))
|
|
1106
|
+
);
|
|
1107
|
+
react.useEffect(() => {
|
|
1108
|
+
setMappings(new Map(initialMatches.map((m) => [m.column, m.suggestedField])));
|
|
1109
|
+
}, [initialMatches]);
|
|
1110
|
+
const [copied, setCopied] = react.useState(false);
|
|
1111
|
+
const handleFieldChange = react.useCallback((column, field) => {
|
|
1112
|
+
setMappings((prev) => {
|
|
1113
|
+
const next = new Map(prev);
|
|
1114
|
+
next.set(column, field);
|
|
1115
|
+
return next;
|
|
1116
|
+
});
|
|
1117
|
+
}, []);
|
|
1118
|
+
const handleGenerate = react.useCallback(async () => {
|
|
1119
|
+
const fieldMappings = entry.columns.map((col) => ({
|
|
1120
|
+
column: col,
|
|
1121
|
+
field: mappings.get(col) ?? null
|
|
1122
|
+
}));
|
|
1123
|
+
const prompt = generateMigrationPrompt(entry.label, fieldMappings);
|
|
1124
|
+
try {
|
|
1125
|
+
await navigator.clipboard.writeText(prompt);
|
|
1126
|
+
setCopied(true);
|
|
1127
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1128
|
+
} catch {
|
|
1129
|
+
const ta = document.createElement("textarea");
|
|
1130
|
+
ta.value = prompt;
|
|
1131
|
+
document.body.appendChild(ta);
|
|
1132
|
+
ta.select();
|
|
1133
|
+
document.execCommand("copy");
|
|
1134
|
+
document.body.removeChild(ta);
|
|
1135
|
+
setCopied(true);
|
|
1136
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1137
|
+
}
|
|
1138
|
+
}, [entry, mappings]);
|
|
1139
|
+
const confidenceMap = react.useMemo(() => {
|
|
1140
|
+
const map = /* @__PURE__ */ new Map();
|
|
1141
|
+
for (const m of initialMatches) map.set(m.column, m.confidence);
|
|
1142
|
+
return map;
|
|
1143
|
+
}, [initialMatches]);
|
|
1144
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1145
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { onClick: onClose, style: backdropStyle }),
|
|
1146
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalStyle, children: [
|
|
1147
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalHeaderStyle, children: [
|
|
1148
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1149
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 700, color: "#111827" }, children: entry.label }),
|
|
1150
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: "#6b7280", marginTop: 2 }, children: [
|
|
1151
|
+
"Source: ",
|
|
1152
|
+
entry.currentSource
|
|
1153
|
+
] })
|
|
1154
|
+
] }),
|
|
1155
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onClose, style: closeBtnStyle, children: "\xD7" })
|
|
1156
|
+
] }),
|
|
1157
|
+
entry.sampleValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: sectionStyle, children: [
|
|
1158
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: sectionTitleStyle, children: "Current Data Preview" }),
|
|
1159
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflow: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: previewTableStyle, children: [
|
|
1160
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: entry.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("th", { style: previewThStyle, children: col }, col)) }) }),
|
|
1161
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: entry.sampleValues.map((row, i) => /* @__PURE__ */ jsxRuntime.jsx("tr", { children: entry.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("td", { style: previewTdStyle, children: row[col] === null || row[col] === void 0 ? "\u2014" : String(row[col]) }, col)) }, i)) })
|
|
1162
|
+
] }) })
|
|
1163
|
+
] }),
|
|
1164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: sectionStyle, children: [
|
|
1165
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: sectionTitleStyle, children: "Field Mapping" }),
|
|
1166
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 13 }, children: [
|
|
1167
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: mappingThStyle, children: "Current Column" }),
|
|
1169
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: mappingThStyle, children: "Confidence" }),
|
|
1170
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: mappingThStyle, children: "Semantic Layer Field" })
|
|
1171
|
+
] }) }),
|
|
1172
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: entry.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1173
|
+
MappingRow,
|
|
1174
|
+
{
|
|
1175
|
+
column: col,
|
|
1176
|
+
confidence: confidenceMap.get(col) ?? "manual",
|
|
1177
|
+
selectedField: mappings.get(col) ?? null,
|
|
1178
|
+
catalog,
|
|
1179
|
+
onChange: (field) => handleFieldChange(col, field)
|
|
1180
|
+
},
|
|
1181
|
+
col
|
|
1182
|
+
)) })
|
|
1183
|
+
] }),
|
|
1184
|
+
catalog.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: "#9ca3af", marginTop: 8, textAlign: "center" }, children: "No semantic layer catalog available. Connect to the gateway to enable smart matching." })
|
|
1185
|
+
] }),
|
|
1186
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "12px 20px", borderTop: "1px solid #e5e7eb" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleGenerate, style: generateBtnStyle, children: copied ? "Copied to clipboard!" : "Generate Migration Prompt" }) })
|
|
1187
|
+
] })
|
|
1188
|
+
] });
|
|
1189
|
+
}
|
|
1190
|
+
function MappingRow({
|
|
1191
|
+
column,
|
|
1192
|
+
confidence,
|
|
1193
|
+
selectedField,
|
|
1194
|
+
catalog,
|
|
1195
|
+
onChange
|
|
1196
|
+
}) {
|
|
1197
|
+
const badgeColors = {
|
|
1198
|
+
exact: { bg: "#dcfce7", color: "#15803d" },
|
|
1199
|
+
fuzzy: { bg: "#fef9c3", color: "#a16207" },
|
|
1200
|
+
manual: { bg: "#fee2e2", color: "#dc2626" }
|
|
1201
|
+
};
|
|
1202
|
+
const badge = badgeColors[confidence] ?? badgeColors.manual;
|
|
1203
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1204
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: mappingTdStyle, children: /* @__PURE__ */ jsxRuntime.jsx("code", { style: { fontSize: 12, color: "#6366f1", fontFamily: "monospace" }, children: column }) }),
|
|
1205
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { ...mappingTdStyle, textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1206
|
+
"span",
|
|
1207
|
+
{
|
|
1208
|
+
style: {
|
|
1209
|
+
display: "inline-block",
|
|
1210
|
+
padding: "1px 6px",
|
|
1211
|
+
fontSize: 10,
|
|
1212
|
+
fontWeight: 600,
|
|
1213
|
+
borderRadius: 4,
|
|
1214
|
+
backgroundColor: badge.bg,
|
|
1215
|
+
color: badge.color
|
|
1216
|
+
},
|
|
1217
|
+
children: confidence
|
|
1218
|
+
}
|
|
1219
|
+
) }),
|
|
1220
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: mappingTdStyle, children: catalog.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1221
|
+
"select",
|
|
1222
|
+
{
|
|
1223
|
+
value: selectedField?.name ?? "",
|
|
1224
|
+
onChange: (e) => {
|
|
1225
|
+
const field = catalog.find((f) => f.name === e.target.value) ?? null;
|
|
1226
|
+
onChange(field);
|
|
1227
|
+
},
|
|
1228
|
+
style: selectStyle2,
|
|
1229
|
+
children: [
|
|
1230
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "-- none --" }),
|
|
1231
|
+
catalog.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: f.name, children: [
|
|
1232
|
+
f.displayName,
|
|
1233
|
+
" (",
|
|
1234
|
+
f.type,
|
|
1235
|
+
") \u2014 ",
|
|
1236
|
+
f.name
|
|
1237
|
+
] }, f.name))
|
|
1238
|
+
]
|
|
1239
|
+
}
|
|
1240
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#9ca3af" }, children: selectedField ? selectedField.name : "No catalog" }) })
|
|
1241
|
+
] });
|
|
1242
|
+
}
|
|
1243
|
+
var backdropStyle = {
|
|
1244
|
+
position: "fixed",
|
|
1245
|
+
inset: 0,
|
|
1246
|
+
backgroundColor: "rgba(0,0,0,0.3)",
|
|
1247
|
+
zIndex: 1e5
|
|
1248
|
+
};
|
|
1249
|
+
var modalStyle = {
|
|
1250
|
+
position: "fixed",
|
|
1251
|
+
top: "50%",
|
|
1252
|
+
left: "50%",
|
|
1253
|
+
transform: "translate(-50%, -50%)",
|
|
1254
|
+
zIndex: 100001,
|
|
1255
|
+
width: "min(640px, 90vw)",
|
|
1256
|
+
maxHeight: "80vh",
|
|
1257
|
+
backgroundColor: "#fff",
|
|
1258
|
+
borderRadius: 12,
|
|
1259
|
+
boxShadow: "0 8px 30px rgba(0,0,0,0.2)",
|
|
1260
|
+
display: "flex",
|
|
1261
|
+
flexDirection: "column",
|
|
1262
|
+
overflow: "hidden",
|
|
1263
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
1264
|
+
};
|
|
1265
|
+
var modalHeaderStyle = {
|
|
1266
|
+
display: "flex",
|
|
1267
|
+
justifyContent: "space-between",
|
|
1268
|
+
alignItems: "flex-start",
|
|
1269
|
+
padding: "16px 20px",
|
|
1270
|
+
borderBottom: "1px solid #e5e7eb"
|
|
1271
|
+
};
|
|
1272
|
+
var closeBtnStyle = {
|
|
1273
|
+
background: "none",
|
|
1274
|
+
border: "none",
|
|
1275
|
+
fontSize: 22,
|
|
1276
|
+
color: "#6b7280",
|
|
1277
|
+
cursor: "pointer",
|
|
1278
|
+
padding: "0 4px",
|
|
1279
|
+
lineHeight: 1
|
|
1280
|
+
};
|
|
1281
|
+
var sectionStyle = {
|
|
1282
|
+
padding: "12px 20px",
|
|
1283
|
+
overflow: "auto",
|
|
1284
|
+
flex: 1
|
|
1285
|
+
};
|
|
1286
|
+
var sectionTitleStyle = {
|
|
1287
|
+
fontSize: 11,
|
|
1288
|
+
fontWeight: 700,
|
|
1289
|
+
textTransform: "uppercase",
|
|
1290
|
+
letterSpacing: "0.05em",
|
|
1291
|
+
color: "#6b7280",
|
|
1292
|
+
marginBottom: 8
|
|
1293
|
+
};
|
|
1294
|
+
var previewTableStyle = {
|
|
1295
|
+
width: "100%",
|
|
1296
|
+
borderCollapse: "collapse",
|
|
1297
|
+
fontSize: 12
|
|
1298
|
+
};
|
|
1299
|
+
var previewThStyle = {
|
|
1300
|
+
padding: "4px 8px",
|
|
1301
|
+
textAlign: "left",
|
|
1302
|
+
fontWeight: 600,
|
|
1303
|
+
color: "#374151",
|
|
1304
|
+
backgroundColor: "#f9fafb",
|
|
1305
|
+
borderBottom: "1px solid #e5e7eb",
|
|
1306
|
+
whiteSpace: "nowrap"
|
|
1307
|
+
};
|
|
1308
|
+
var previewTdStyle = {
|
|
1309
|
+
padding: "4px 8px",
|
|
1310
|
+
color: "#6b7280",
|
|
1311
|
+
borderBottom: "1px solid #f3f4f6",
|
|
1312
|
+
whiteSpace: "nowrap",
|
|
1313
|
+
maxWidth: 150,
|
|
1314
|
+
overflow: "hidden",
|
|
1315
|
+
textOverflow: "ellipsis"
|
|
1316
|
+
};
|
|
1317
|
+
var mappingThStyle = {
|
|
1318
|
+
padding: "6px 8px",
|
|
1319
|
+
textAlign: "left",
|
|
1320
|
+
fontWeight: 600,
|
|
1321
|
+
fontSize: 11,
|
|
1322
|
+
color: "#6b7280",
|
|
1323
|
+
borderBottom: "1px solid #e5e7eb"
|
|
1324
|
+
};
|
|
1325
|
+
var mappingTdStyle = {
|
|
1326
|
+
padding: "6px 8px",
|
|
1327
|
+
borderBottom: "1px solid #f3f4f6",
|
|
1328
|
+
verticalAlign: "middle"
|
|
1329
|
+
};
|
|
1330
|
+
var selectStyle2 = {
|
|
1331
|
+
width: "100%",
|
|
1332
|
+
padding: "4px 6px",
|
|
1333
|
+
fontSize: 12,
|
|
1334
|
+
border: "1px solid #d1d5db",
|
|
1335
|
+
borderRadius: 4,
|
|
1336
|
+
backgroundColor: "#fff",
|
|
1337
|
+
color: "#111827"
|
|
1338
|
+
};
|
|
1339
|
+
var generateBtnStyle = {
|
|
1340
|
+
width: "100%",
|
|
1341
|
+
padding: "10px 16px",
|
|
1342
|
+
fontSize: 14,
|
|
1343
|
+
fontWeight: 600,
|
|
1344
|
+
color: "#fff",
|
|
1345
|
+
backgroundColor: "#3b82f6",
|
|
1346
|
+
border: "none",
|
|
1347
|
+
borderRadius: 8,
|
|
1348
|
+
cursor: "pointer"
|
|
1349
|
+
};
|
|
808
1350
|
|
|
809
1351
|
exports.AdminDashboard = AdminDashboard;
|
|
810
1352
|
exports.DataCatalog = DataCatalog;
|
|
1353
|
+
exports.DataInspector = DataInspector;
|
|
1354
|
+
exports.Inspectable = Inspectable;
|
|
811
1355
|
exports.MetricPicker = MetricPicker;
|
|
812
1356
|
exports.ResultsTable = ResultsTable;
|
|
1357
|
+
exports.generateMigrationPrompt = generateMigrationPrompt;
|
|
1358
|
+
exports.matchFields = matchFields;
|
|
813
1359
|
//# sourceMappingURL=components.cjs.map
|
|
814
1360
|
//# sourceMappingURL=components.cjs.map
|