strapi-content-embeddings 0.1.5 → 0.1.6

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.
@@ -2,10 +2,10 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useFetchClient, Layouts, useNotification, Page } from "@strapi/strapi/admin";
3
3
  import { Link, useNavigate, NavLink, useParams, Routes, Route } from "react-router-dom";
4
4
  import { useRef, useState, useEffect, useCallback, useMemo } from "react";
5
- import { EmptyStateLayout, Button, Tr, Box, Table, Thead, Th, Typography, VisuallyHidden, Tbody, Td, Flex, IconButton, Modal, TextInput, Link as Link$1, Accordion, Main, Loader, Field, Textarea, Grid, Dialog } from "@strapi/design-system";
5
+ import { EmptyStateLayout, Button, Tr, Box, Table, Thead, Th, Typography, VisuallyHidden, Tbody, Td, Flex, IconButton, Modal, TextInput, Link as Link$1, Accordion, Main, Loader, Pagination, PreviousLink, PageLink, NextLink, Field, Textarea, Badge, Grid, Dialog } from "@strapi/design-system";
6
6
  import { Plus, ArrowRight, Search, ArrowLeft, Cross, Check, Pencil, Trash } from "@strapi/icons";
7
7
  import qs from "qs";
8
- import { P as PLUGIN_ID, R as RobotIcon, M as MarkdownEditor } from "./index-B3j0IFUi.mjs";
8
+ import { P as PLUGIN_ID, R as RobotIcon, M as MarkdownEditor } from "./index-CIpGvEcJ.mjs";
9
9
  import styled from "styled-components";
10
10
  import ReactMarkdown from "react-markdown";
11
11
  import { useIntl } from "react-intl";
@@ -98,7 +98,7 @@ function EmbeddingsTable({ data }) {
98
98
  const handleRowClick = (documentId) => {
99
99
  navigate(`/plugins/${PLUGIN_ID}/embeddings/${documentId}`);
100
100
  };
101
- return /* @__PURE__ */ jsx(Box, { padding: 8, background: "neutral100", children: /* @__PURE__ */ jsxs(Table, { colCount: 5, rowCount: data.length + 1, children: [
101
+ return /* @__PURE__ */ jsx(Box, { padding: 0, background: "neutral100", children: /* @__PURE__ */ jsxs(Table, { colCount: 5, rowCount: data.length + 1, children: [
102
102
  /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
103
103
  /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "ID" }) }),
104
104
  /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Title" }) }),
@@ -462,6 +462,7 @@ function ChatModal() {
462
462
  ] }) })
463
463
  ] });
464
464
  }
465
+ const PAGE_SIZE = 10;
465
466
  function debounce(func, wait) {
466
467
  let timeout;
467
468
  return (...args) => {
@@ -475,16 +476,20 @@ function HomePage() {
475
476
  const [embeddings, setEmbeddings] = useState(null);
476
477
  const [search, setSearch] = useState("");
477
478
  const [isLoading, setIsLoading] = useState(true);
478
- const buildQuery = (searchTerm) => qs.stringify({
479
+ const [currentPage, setCurrentPage] = useState(1);
480
+ const totalPages = embeddings ? Math.ceil(embeddings.totalCount / PAGE_SIZE) : 0;
481
+ const buildQuery = (searchTerm, page) => qs.stringify({
482
+ page,
483
+ pageSize: PAGE_SIZE,
479
484
  filters: searchTerm ? {
480
485
  $or: [{ title: { $containsi: searchTerm } }, { content: { $containsi: searchTerm } }]
481
486
  } : void 0
482
487
  });
483
488
  const fetchData = useCallback(
484
- async (searchTerm) => {
489
+ async (searchTerm, page) => {
485
490
  setIsLoading(true);
486
491
  try {
487
- const response = await get(`/${PLUGIN_ID}/embeddings/find?${buildQuery(searchTerm)}`);
492
+ const response = await get(`/${PLUGIN_ID}/embeddings/find?${buildQuery(searchTerm, page)}`);
488
493
  setEmbeddings(response.data);
489
494
  } catch (error) {
490
495
  console.error("Failed to fetch embeddings:", error);
@@ -497,8 +502,11 @@ function HomePage() {
497
502
  );
498
503
  const debouncedFetch = useMemo(() => debounce(fetchData, 500), [fetchData]);
499
504
  useEffect(() => {
500
- debouncedFetch(search);
501
- }, [search, debouncedFetch]);
505
+ debouncedFetch(search, currentPage);
506
+ }, [search, currentPage, debouncedFetch]);
507
+ useEffect(() => {
508
+ setCurrentPage(1);
509
+ }, [search]);
502
510
  const handleSearchChange = (e) => {
503
511
  setSearch(e.target.value);
504
512
  };
@@ -532,12 +540,72 @@ function HomePage() {
532
540
  '"'
533
541
  ] });
534
542
  };
543
+ const shouldShowPagination = embeddings && embeddings.totalCount > 0 && totalPages > 1;
544
+ const getVisiblePages = () => {
545
+ const pages = [];
546
+ const maxVisible = 5;
547
+ let start = Math.max(1, currentPage - Math.floor(maxVisible / 2));
548
+ const end = Math.min(totalPages, start + maxVisible - 1);
549
+ if (end - start + 1 < maxVisible) {
550
+ start = Math.max(1, end - maxVisible + 1);
551
+ }
552
+ for (let i = start; i <= end; i++) {
553
+ pages.push(i);
554
+ }
555
+ return pages;
556
+ };
557
+ const renderPagination = () => {
558
+ if (!shouldShowPagination || !embeddings) {
559
+ return null;
560
+ }
561
+ const startItem = (currentPage - 1) * PAGE_SIZE + 1;
562
+ const endItem = Math.min(currentPage * PAGE_SIZE, embeddings.totalCount);
563
+ const visiblePages = getVisiblePages();
564
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 3, paddingTop: 6, children: [
565
+ /* @__PURE__ */ jsxs(Pagination, { activePage: currentPage, pageCount: totalPages, children: [
566
+ /* @__PURE__ */ jsx(
567
+ PreviousLink,
568
+ {
569
+ onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
570
+ disabled: currentPage === 1,
571
+ children: "Previous"
572
+ }
573
+ ),
574
+ visiblePages.map((page) => /* @__PURE__ */ jsx(
575
+ PageLink,
576
+ {
577
+ number: page,
578
+ onClick: () => setCurrentPage(page),
579
+ children: page
580
+ },
581
+ page
582
+ )),
583
+ /* @__PURE__ */ jsx(
584
+ NextLink,
585
+ {
586
+ onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
587
+ disabled: currentPage === totalPages,
588
+ children: "Next"
589
+ }
590
+ )
591
+ ] }),
592
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
593
+ "Showing ",
594
+ startItem,
595
+ " to ",
596
+ endItem,
597
+ " of ",
598
+ embeddings.totalCount,
599
+ " entries"
600
+ ] })
601
+ ] });
602
+ };
535
603
  return /* @__PURE__ */ jsxs(Main, { children: [
536
604
  /* @__PURE__ */ jsx(
537
605
  Layouts.Header,
538
606
  {
539
607
  title: "Content Embeddings",
540
- subtitle: `${embeddings?.count || 0} results found`,
608
+ subtitle: `${embeddings?.totalCount || 0} embeddings total`,
541
609
  primaryAction: /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(Plus, {}), onClick: handleCreateNew, children: "Create new embedding" })
542
610
  }
543
611
  ),
@@ -552,7 +620,8 @@ function HomePage() {
552
620
  startAction: /* @__PURE__ */ jsx(Search, {})
553
621
  }
554
622
  ) }),
555
- renderEmbeddingsContent()
623
+ renderEmbeddingsContent(),
624
+ renderPagination()
556
625
  ] }),
557
626
  /* @__PURE__ */ jsx(ChatModal, {})
558
627
  ] });
@@ -742,6 +811,23 @@ const StyledTypography = styled(Typography)`
742
811
  display: block;
743
812
  margin-bottom: 1rem;
744
813
  `;
814
+ const ChunkTab = styled.div`
815
+ padding: 0.5rem 1rem;
816
+ cursor: pointer;
817
+ border-bottom: 2px solid ${({ $isActive }) => $isActive ? "#4945ff" : "transparent"};
818
+ color: ${({ $isActive }) => $isActive ? "#4945ff" : "inherit"};
819
+ font-weight: ${({ $isActive }) => $isActive ? "600" : "400"};
820
+ white-space: nowrap;
821
+
822
+ &:hover {
823
+ color: #4945ff;
824
+ }
825
+ `;
826
+ const ChunkTabsContainer = styled(Flex)`
827
+ border-bottom: 1px solid #dcdce4;
828
+ overflow-x: auto;
829
+ margin-bottom: 1rem;
830
+ `;
745
831
  function Metadata({ data }) {
746
832
  const metadata = {
747
833
  id: data.documentId,
@@ -798,6 +884,8 @@ function EmbeddingDetails() {
798
884
  const { del, get, put } = useFetchClient();
799
885
  const { toggleNotification } = useNotification();
800
886
  const [data, setData] = useState(null);
887
+ const [chunks, setChunks] = useState([]);
888
+ const [activeChunkIndex, setActiveChunkIndex] = useState(0);
801
889
  const [isLoading, setIsLoading] = useState(true);
802
890
  const [isDeleting, setIsDeleting] = useState(false);
803
891
  const [isEditing, setIsEditing] = useState(false);
@@ -805,6 +893,8 @@ function EmbeddingDetails() {
805
893
  const [editTitle, setEditTitle] = useState("");
806
894
  const [editContent, setEditContent] = useState("");
807
895
  const [editMetadata, setEditMetadata] = useState("");
896
+ const isChunkedDocument = chunks.length > 1;
897
+ const activeChunk = isChunkedDocument ? chunks[activeChunkIndex] : data;
808
898
  useEffect(() => {
809
899
  async function fetchData() {
810
900
  if (!id) return;
@@ -812,9 +902,31 @@ function EmbeddingDetails() {
812
902
  const response = await get(`/${PLUGIN_ID}/embeddings/find/${id}`);
813
903
  const embeddingData = response.data;
814
904
  setData(embeddingData);
815
- setEditTitle(embeddingData.title || "");
816
- setEditContent(embeddingData.content || "");
817
- setEditMetadata(embeddingData.metadata ? JSON.stringify(embeddingData.metadata, null, 2) : "");
905
+ const chunksResponse = await get(`/${PLUGIN_ID}/embeddings/related-chunks/${id}`);
906
+ const relatedChunks = chunksResponse.data?.data || [];
907
+ if (relatedChunks.length > 1) {
908
+ const sortedChunks = relatedChunks.sort((a, b) => {
909
+ const aIndex = a.metadata?.chunkIndex ?? 0;
910
+ const bIndex = b.metadata?.chunkIndex ?? 0;
911
+ return aIndex - bIndex;
912
+ });
913
+ setChunks(sortedChunks);
914
+ const currentIndex = sortedChunks.findIndex(
915
+ (chunk) => chunk.documentId === id
916
+ );
917
+ if (currentIndex >= 0) {
918
+ setActiveChunkIndex(currentIndex);
919
+ }
920
+ const firstChunk = sortedChunks[currentIndex >= 0 ? currentIndex : 0];
921
+ setEditTitle(firstChunk.title || "");
922
+ setEditContent(firstChunk.content || "");
923
+ setEditMetadata(firstChunk.metadata ? JSON.stringify(firstChunk.metadata, null, 2) : "");
924
+ } else {
925
+ setChunks([embeddingData]);
926
+ setEditTitle(embeddingData.title || "");
927
+ setEditContent(embeddingData.content || "");
928
+ setEditMetadata(embeddingData.metadata ? JSON.stringify(embeddingData.metadata, null, 2) : "");
929
+ }
818
930
  } catch (error) {
819
931
  console.error("Failed to fetch embedding:", error);
820
932
  } finally {
@@ -823,11 +935,24 @@ function EmbeddingDetails() {
823
935
  }
824
936
  fetchData();
825
937
  }, [id, get]);
938
+ useEffect(() => {
939
+ if (activeChunk && !isEditing) {
940
+ setEditTitle(activeChunk.title || "");
941
+ setEditContent(activeChunk.content || "");
942
+ setEditMetadata(activeChunk.metadata ? JSON.stringify(activeChunk.metadata, null, 2) : "");
943
+ }
944
+ }, [activeChunkIndex, activeChunk, isEditing]);
826
945
  const handleDelete = async () => {
827
- if (!id || isDeleting) return;
946
+ if (!activeChunk || isDeleting) return;
828
947
  setIsDeleting(true);
829
948
  try {
830
- await del(`/${PLUGIN_ID}/embeddings/delete-embedding/${id}`);
949
+ if (isChunkedDocument) {
950
+ for (const chunk of chunks) {
951
+ await del(`/${PLUGIN_ID}/embeddings/delete-embedding/${chunk.documentId}`);
952
+ }
953
+ } else {
954
+ await del(`/${PLUGIN_ID}/embeddings/delete-embedding/${activeChunk.documentId}`);
955
+ }
831
956
  navigate(`/plugins/${PLUGIN_ID}`);
832
957
  } catch (error) {
833
958
  console.error("Failed to delete embedding:", error);
@@ -835,18 +960,23 @@ function EmbeddingDetails() {
835
960
  }
836
961
  };
837
962
  const handleStartEdit = () => {
838
- if (data) {
839
- setEditTitle(data.title || "");
840
- setEditContent(data.content || "");
841
- setEditMetadata(data.metadata ? JSON.stringify(data.metadata, null, 2) : "");
963
+ if (activeChunk) {
964
+ setEditTitle(activeChunk.title || "");
965
+ setEditContent(activeChunk.content || "");
966
+ setEditMetadata(activeChunk.metadata ? JSON.stringify(activeChunk.metadata, null, 2) : "");
842
967
  }
843
968
  setIsEditing(true);
844
969
  };
845
970
  const handleCancelEdit = () => {
846
971
  setIsEditing(false);
972
+ if (activeChunk) {
973
+ setEditTitle(activeChunk.title || "");
974
+ setEditContent(activeChunk.content || "");
975
+ setEditMetadata(activeChunk.metadata ? JSON.stringify(activeChunk.metadata, null, 2) : "");
976
+ }
847
977
  };
848
978
  const handleSave = async () => {
849
- if (!id || isSaving) return;
979
+ if (!activeChunk || isSaving) return;
850
980
  let parsedMetadata = null;
851
981
  if (editMetadata.trim()) {
852
982
  try {
@@ -861,18 +991,26 @@ function EmbeddingDetails() {
861
991
  }
862
992
  setIsSaving(true);
863
993
  try {
864
- const response = await put(`/${PLUGIN_ID}/embeddings/update-embedding/${id}`, {
994
+ const response = await put(`/${PLUGIN_ID}/embeddings/update-embedding/${activeChunk.documentId}`, {
865
995
  data: {
866
996
  title: editTitle.trim(),
867
997
  content: editContent.trim(),
868
998
  metadata: parsedMetadata
869
999
  }
870
1000
  });
871
- setData(response.data);
1001
+ const updatedData = response.data;
1002
+ if (isChunkedDocument) {
1003
+ const newChunks = [...chunks];
1004
+ newChunks[activeChunkIndex] = updatedData;
1005
+ setChunks(newChunks);
1006
+ } else {
1007
+ setData(updatedData);
1008
+ setChunks([updatedData]);
1009
+ }
872
1010
  setIsEditing(false);
873
1011
  toggleNotification({
874
1012
  type: "success",
875
- message: "Embedding updated successfully"
1013
+ message: "Chunk updated successfully"
876
1014
  });
877
1015
  } catch (error) {
878
1016
  console.error("Failed to update embedding:", error);
@@ -884,6 +1022,20 @@ function EmbeddingDetails() {
884
1022
  setIsSaving(false);
885
1023
  }
886
1024
  };
1025
+ const handleChunkSelect = (index) => {
1026
+ if (isEditing) {
1027
+ const confirmed = globalThis.confirm("You have unsaved changes. Discard them?");
1028
+ if (!confirmed) return;
1029
+ setIsEditing(false);
1030
+ }
1031
+ setActiveChunkIndex(index);
1032
+ };
1033
+ const getOriginalTitle = () => {
1034
+ if (isChunkedDocument && chunks[0]?.metadata) {
1035
+ return chunks[0].metadata.originalTitle || chunks[0].title?.replace(/\s*\[Part \d+\/\d+\]$/, "");
1036
+ }
1037
+ return data?.title || "Embedding Details";
1038
+ };
887
1039
  if (isLoading) {
888
1040
  return /* @__PURE__ */ jsxs(Main, { children: [
889
1041
  /* @__PURE__ */ jsx(
@@ -896,7 +1048,7 @@ function EmbeddingDetails() {
896
1048
  /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsx(Loader, { children: "Loading embedding details..." }) }) })
897
1049
  ] });
898
1050
  }
899
- if (!data) {
1051
+ if (!data || !activeChunk) {
900
1052
  return /* @__PURE__ */ jsxs(Main, { children: [
901
1053
  /* @__PURE__ */ jsx(
902
1054
  Layouts.Header,
@@ -908,68 +1060,103 @@ function EmbeddingDetails() {
908
1060
  /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Box, { padding: 8, textAlign: "center", children: /* @__PURE__ */ jsx(Typography, { children: "The requested embedding could not be found." }) }) })
909
1061
  ] });
910
1062
  }
1063
+ const headerTitle = isEditing ? `Edit: ${activeChunk.title}` : isChunkedDocument ? getOriginalTitle() : data.title || "Embedding Details";
1064
+ const headerSubtitle = isChunkedDocument ? `Chunked Document (${chunks.length} parts)` : `Embedding ID: ${data.embeddingId || "N/A"}`;
911
1065
  return /* @__PURE__ */ jsxs(Main, { children: [
912
1066
  /* @__PURE__ */ jsx(
913
1067
  Layouts.Header,
914
1068
  {
915
- title: isEditing ? "Edit Embedding" : data.title || "Embedding Details",
916
- subtitle: `Embedding ID: ${data.embeddingId || "N/A"}`,
1069
+ title: headerTitle,
1070
+ subtitle: headerSubtitle,
917
1071
  primaryAction: isEditing ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
918
1072
  /* @__PURE__ */ jsx(Button, { variant: "tertiary", startIcon: /* @__PURE__ */ jsx(Cross, {}), onClick: handleCancelEdit, children: "Cancel" }),
919
- /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(Check, {}), onClick: handleSave, loading: isSaving, children: isSaving ? "Saving..." : "Save" })
1073
+ /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(Check, {}), onClick: handleSave, loading: isSaving, children: isSaving ? "Saving..." : "Save Chunk" })
920
1074
  ] }) : /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
921
- /* @__PURE__ */ jsx(Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsx(Pencil, {}), onClick: handleStartEdit, children: "Edit" }),
1075
+ /* @__PURE__ */ jsxs(Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsx(Pencil, {}), onClick: handleStartEdit, children: [
1076
+ "Edit ",
1077
+ isChunkedDocument ? "Chunk" : ""
1078
+ ] }),
922
1079
  /* @__PURE__ */ jsx(ConfirmDeleteEmbedding, { onConfirm: handleDelete, isLoading: isDeleting })
923
1080
  ] }),
924
1081
  navigationAction: /* @__PURE__ */ jsx(BackLink, { to: `/plugins/${PLUGIN_ID}` })
925
1082
  }
926
1083
  ),
927
- /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(Box, { padding: 8, children: isEditing ? /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
928
- /* @__PURE__ */ jsx(Grid.Item, { col: 8, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", hasRadius: true, children: [
929
- /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
930
- /* @__PURE__ */ jsx(Field.Label, { children: "Title" }),
1084
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Box, { padding: 8, children: [
1085
+ isChunkedDocument && /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Box, { background: "neutral0", padding: 4, hasRadius: true, children: [
1086
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 3, children: [
1087
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", children: "Document Chunks" }),
1088
+ /* @__PURE__ */ jsxs(Badge, { children: [
1089
+ chunks.length,
1090
+ " parts"
1091
+ ] })
1092
+ ] }),
1093
+ /* @__PURE__ */ jsx(ChunkTabsContainer, { gap: 0, children: chunks.map((chunk, index) => /* @__PURE__ */ jsxs(
1094
+ ChunkTab,
1095
+ {
1096
+ $isActive: index === activeChunkIndex,
1097
+ onClick: () => handleChunkSelect(index),
1098
+ children: [
1099
+ "Part ",
1100
+ index + 1,
1101
+ index === activeChunkIndex && isEditing && " (editing)"
1102
+ ]
1103
+ },
1104
+ chunk.documentId
1105
+ )) })
1106
+ ] }) }),
1107
+ isEditing ? /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
1108
+ /* @__PURE__ */ jsx(Grid.Item, { col: 8, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", hasRadius: true, children: [
1109
+ /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
1110
+ /* @__PURE__ */ jsx(Field.Label, { children: "Title" }),
1111
+ /* @__PURE__ */ jsx(
1112
+ TextInput,
1113
+ {
1114
+ value: editTitle,
1115
+ onChange: (e) => setEditTitle(e.target.value)
1116
+ }
1117
+ )
1118
+ ] }) }),
1119
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 4, children: [
1120
+ /* @__PURE__ */ jsxs(Field.Root, { children: [
1121
+ /* @__PURE__ */ jsx(Field.Label, { children: "Content" }),
1122
+ /* @__PURE__ */ jsx(Field.Hint, { children: "Changes to content will regenerate the embedding vector" })
1123
+ ] }),
1124
+ /* @__PURE__ */ jsx(
1125
+ MarkdownEditor,
1126
+ {
1127
+ content: editContent,
1128
+ onChange: setEditContent,
1129
+ height: 300
1130
+ }
1131
+ )
1132
+ ] })
1133
+ ] }) }) }),
1134
+ /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsx(Box, { padding: 4, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
1135
+ /* @__PURE__ */ jsx(Field.Label, { children: "Metadata (JSON)" }),
1136
+ /* @__PURE__ */ jsx(Field.Hint, { children: "Optional custom metadata" }),
931
1137
  /* @__PURE__ */ jsx(
932
- TextInput,
1138
+ Textarea,
933
1139
  {
934
- value: editTitle,
935
- onChange: (e) => setEditTitle(e.target.value)
1140
+ value: editMetadata,
1141
+ onChange: (e) => setEditMetadata(e.target.value),
1142
+ placeholder: '{"key": "value"}'
936
1143
  }
937
1144
  )
938
- ] }) }),
939
- /* @__PURE__ */ jsxs(Box, { marginBottom: 4, children: [
940
- /* @__PURE__ */ jsxs(Field.Root, { children: [
941
- /* @__PURE__ */ jsx(Field.Label, { children: "Content" }),
942
- /* @__PURE__ */ jsx(Field.Hint, { children: "Changes to content will regenerate the embedding vector" })
1145
+ ] }) }) }) }) })
1146
+ ] }) : /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
1147
+ /* @__PURE__ */ jsx(Grid.Item, { col: 8, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", hasRadius: true, children: [
1148
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 3, children: [
1149
+ /* @__PURE__ */ jsx(StyledTypography, { variant: "beta", style: { margin: 0 }, children: isChunkedDocument ? `Part ${activeChunkIndex + 1} Content` : "Embedding Content" }),
1150
+ isChunkedDocument && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
1151
+ activeChunk.content?.length || 0,
1152
+ " characters"
1153
+ ] })
943
1154
  ] }),
944
- /* @__PURE__ */ jsx(
945
- MarkdownEditor,
946
- {
947
- content: editContent,
948
- onChange: setEditContent,
949
- height: 300
950
- }
951
- )
952
- ] })
953
- ] }) }) }),
954
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsx(Box, { padding: 4, background: "neutral0", hasRadius: true, children: /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Field.Root, { children: [
955
- /* @__PURE__ */ jsx(Field.Label, { children: "Metadata (JSON)" }),
956
- /* @__PURE__ */ jsx(Field.Hint, { children: "Optional custom metadata" }),
957
- /* @__PURE__ */ jsx(
958
- Textarea,
959
- {
960
- value: editMetadata,
961
- onChange: (e) => setEditMetadata(e.target.value),
962
- placeholder: '{"key": "value"}'
963
- }
964
- )
965
- ] }) }) }) }) })
966
- ] }) : /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
967
- /* @__PURE__ */ jsx(Grid.Item, { col: 8, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", hasRadius: true, children: [
968
- /* @__PURE__ */ jsx(StyledTypography, { variant: "beta", children: "Embedding Content" }),
969
- data.content ? /* @__PURE__ */ jsx(Markdown, { children: data.content }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "No content" })
970
- ] }) }) }),
971
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsx(Metadata, { data }) }) })
972
- ] }) }) })
1155
+ activeChunk.content ? /* @__PURE__ */ jsx(Markdown, { children: activeChunk.content }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "No content" })
1156
+ ] }) }) }),
1157
+ /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsx(Box, { background: "neutral100", padding: 1, hasRadius: true, children: /* @__PURE__ */ jsx(Metadata, { data: activeChunk }) }) })
1158
+ ] })
1159
+ ] }) })
973
1160
  ] });
974
1161
  }
975
1162
  const App = () => {
@@ -983,4 +1170,3 @@ const App = () => {
983
1170
  export {
984
1171
  App
985
1172
  };
986
- //# sourceMappingURL=App-j180lztd.mjs.map